Substituting JavaScript variables using Octopus Deploy

Octopus Deploy has fantastic native support for substituting configuration variables in .NET applications, using the “substitute variables in files” feature, and the ability to run XML config transforms. Combining these two approaches using the “One transform + Variable replacement” approach is my favoured approach to configuring ASP.NET applications.

But what about web applications that are front-end focussed such as Single Page Apps, or those which have no .NET back end code to configure? A web app I was working on recently contained a ‘global variable’ JavaScript file (variables.js), containing a single variable which acted as a pointer to an API endpoint.

servicesUrl = ""

When the app is deployed out across CI, QA and Production environments, I wanted this variable to be substituted by Octopus for a variable. So I duly configured my web deployment step to perform an additional substitution in the variables.js file, and replaced the line above to include the Octopus variable syntax. So far, so good. However, I also wanted to be able to run the app locally without having to constantly change the variables.js file. So here was my next iteration:

servicesUrl = "http://#{WebsiteName.DataServices}/"
if (~servicesUrl.indexOf("#{"))
    servicesUrl = "http://services.test.endpoint.url/";

Unfortunately, I then hit upon an issue in Octostache (the variable substitution engine in Octopus) whereby you can’t use the ‘#’ symbol in files unless it does actually relate to a variable you want to be substituted. You can’t even include a hash in a comment without Octostache throwing an error like:

Octostache returned the following error: `Parsing failure: unexpected '#'; expected end of input (Line n, Column n); recently consumed: xxxxxxxxxx

So, in the end I had to use a bit of JavaScript string encoding in order to parse for the ‘un-substituted’ variable placeholder, and fallback to a default URL. Here’s what worked for me – noting that “%23%7B” is the encoded version of “#{“…

// During Octopus deployment, variable values in this file using Octopus hash-syntax will be replaced
servicesUrl = "http://#{WebsiteName.DataServices}/"
// For local development, the string above won't be replaced. The following block provides a default fallback URL
// In a file being ran through Octopus variable substitution, you have to avoid using the 'hash' symbol anywhere
// (other than a "real" Octopus variable, of course). Otherwise Octopus throws a wobbly.
if (~encodeURIComponent(servicesUrl).indexOf("%23%7B"))
    servicesUrl = "http://services.test.endpoint.url";



Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s