Integrating Gulp and Bower with Visual Studio Online Hosted Builds

In previous posts, I talked about using Gulp to manage client side builds and using Bower as a package manager for client side packages.

Shane Courtrille asked me if I could do a follow up post showing how to integrate these concepts with a build hosted on Visual Studio Online. It took me some time and a long list of failures to get this working, but here it is.

Build Server Requirements

In order to successfully use Gulp and Bower on your build server, you will need both Node and Git installed. Luckily, the hosted Visual Studio Online build controllers already have these tools installed. If you are hosting your own build server, you will need to install node.js and Git on the server. When installing these tools, make sure you login to the server as the same user that executes the build process.

Adding a PreBuild Script to Visual Studio Build

The next step is to ensure that we call the default gulp task before attempting to compile our application with msbuild. Using the gulp file from the blog post on using Bower, calling the default gulp task will ensure that all bower packages are installed and all our JavaScript and CSS bundles are created and copied to the expected locations.

Gulp requires a number of node packages to be installed. Before we can call gulp, we need to call npm install to ensure that those packages have been downloaded locally on the build controller.

The easiest way to do this is to create a simple PowerShell script that is executed as a Pre Build step for our Visual Studio build. Pre Build Steps are only available if GitTemplate.12.xaml as your build process template.

I added a PreBuild.ps1 script to the root folder for my solution and added that file as my Pre-build script path.

Push-Location "BowerInVS2013"
& npm install
& gulp default
Pop-Location

In theory, that’s all we needed to do. Unfortunately, theory and practice are rarely aligned…especially when working with Visual Studio builds.

When I tried to run this build in Visual Studio Online, I got the following error:

Error: ENOENT, stat 'C:\Users\buildguest\AppData\Roaming\npm'

For some reason, the buildguests user that runs the build on Visual Studio online has trouble with the call to npm install. A quick workaround for this is to create the missing npm folder if it does not exist.

$appdatafolder = [Environment]::GetFolderPath('ApplicationData')
$npmfolder = $appdatafolder + "\npm"
if(!(Test-Path -Path $npmfolder)){
    New-Item -Path $npmfolder -ItemType Directory 
}
Push-Location "BowerInVS2013"
& npm install
& gulp default

Pop-Location

This brings us to my next failure: Gulp is not installed globally on the hosted build controller so the call to gulp default failed.

To solve this I added added a gulp script to my npm package file (package.json). This gives me a convenient way to call gulp via npm.

{
"name": "BowerInVS2013",
"version": "1.0.0",
"private": true,
"devDependencies": {
"del": "^1.1.1",
"gulp": "^3.8.10",
"gulp-bower": "0.0.7",
"gulp-concat": "^2.4.2",
"gulp-copy": "0.0.2",
"gulp-minify-css": "^0.3.11",
"gulp-sourcemaps": "^1.3.0",
"gulp-uglify": "^1.0.2"
},
"scripts": {
"gulp": "./node_modules/.bin/gulp"
}
}

The updated PreBuild.ps1 script looks like this:

$appdatafolder = [Environment]::GetFolderPath('ApplicationData')
$npmfolder = $appdatafolder + "\npm"
if(!(Test-Path -Path $npmfolder)){
    New-Item -Path $npmfolder -ItemType Directory 
}
Push-Location "BowerInVS2013"
& npm install
& npm gulp
Pop-Location

We still get one warning from npm and I’m not sure how to fix it.

npm WARN deprecated deflate-crc32-stream@0.1.2: module has been merged into crc32-stream

This warning seems to be a known issue with node on Windows and in this case it seems to be safe to ignore it. The compiled output from the build contains everything that we expect.

Conclusion

With a few minor workarounds, we are able to get Bower and Gulp working with the Visual Studio Online hosted build controllers.