Bundling with Gulp in TeamCity

Like most, our front end developers write CSS in LESS or SASS and then use Gulp to compile the result. This is great but up until recently both the compiled and source style files would end up in our source control repository.

While this isn’t a major issue it was more of an annoyance factor when doing a merge that the compiled file would need to be merged as well as the source files. Any conflicts in bundled/minified files also can become problematic to solve. As well as this it also just seems wrong to have both files in a repo, effectively duplicating the file. After all we wouldn’t put compiled dll’s into a repo with their source.

Our solution was to get the build server to start running the gulp tasks to produce the bundled files.

Step 1 – Install Node on the build server

To start we need NodeJS installed on the build server. This allows extensions to be installed via NPM (Node Package Manager), it’s a similar thing to NuGet,

nodejs-install-4

Step 2 – Install the TeamCity plugin for NodeJS

To add built steps for Node and Gulp we need to install a plugin to make them available. Lucking there is one that does such a thing here https://github.com/jonnyzzz/TeamCity.Node

The actual build of the plugin you can download from Jetbrains team city here https://teamcity.jetbrains.com/viewType.html?buildTypeId=bt434. Just login as guest and then download the latest zip from the artifacts of the last build.

To install the plug you need to copy the zip to Team City’s plugin folder. For me this was C:\ProgramData\JetBrains\TeamCity\plugins, if your having trouble finding your’s just go to Administration > Global Settings in Team City and it will tell you the data directory. The plugin folder will be in there.

Restart the TeamCity server and the plugin should now show under Administration > Plugins List

NodeJS Plugin

Step 3 – Add a NPM Setup build step

NPM Build Step

The NPM step with a command of install will pick up dependencies and get the files.

Step 4 – Add a Gulp build step

Gulp Build Step

In your gulp step add the path to the gulp file and the tasks in your gulp file that need to be run. I’m using a gulp file that our front end devs had already created for the solution that contained as task for bundling css and another for bundling js.

Step 5 – Including bundled files in a MSBuild

As the bundled files are no longer included in our Visual Studio solution it also means that they arn’t included in the set of files which will be included in a publish when MSBuild runs.

To overcome this update the .csproj file with a Target with BeforeTargets set to BeforeBuild and list your bundled files as content. In my example I’m included the whole Content\bundles folder

<Target Name="BundlesBeforeBuild" BeforeTargets="BeforeBuild">
    <ItemGroup>
      <Content Include="Content\bundles\**" />
    </ItemGroup>
  </Target>

Adding Build Statuses to Pull Requests with TeamCity and GitHub

I’m always looking for ways to improve our build server setup and improve our overall efficiency. So a recent change I’ve made is to get Team City to start building pull requests and pushing the resulting status back to GitHub.

This improves our dev flow by eliminating the need to do any testing on a pull request if we can already see it will fail a build. Previously someone doing a code review would only find out once they’ve checked out the change and built it locally, or even worse after approving the request and then breaking the build.

Pull Request Build Status

What’s particularly good with this setup, is it’s testing the resulting merge rather than just the branch being merged in.

Team City Setup

As this is covering a different scenario to our normal build processes which are focused on preparing a build version to be deployed, I set this up as a second build configuration on our projects.

Version Control Settings Root (VCS Root)

The VCS Root needs to be configured to fetch each pull request that is creating in GitHub. To do this, you will need to add a Branch specification which will tell Team City to monitor additional branches rather than just the default branch specified.

Branch Specification

I’m using the branch specification +:refs/pull/(*/merge) .

This syntax is telling Team City to monitor references to pull for pull request, the * refers to any pull request, and the merge indicates that we only want to resulting merge of the pull request.

When you create a pull request in GitHub, this merge reference is automatically created for what the resulting merge would look like.

In the projects list, builds will now get labels indicating what they were for:

Pull Requests on dashboard

Build Steps

I created my build configurations by duplicating the existing ones we have that take care of creating builds to be passed onto Octopus Deploy for release. If you do this, it’s important to remember to disable all the steps you no longer need.

Build Steps

The less steps you have the quicker your build will run and the quicker the pull request will be updated with a status. Ideally you want the process to finish before someone starts doing a code review! Steps like running Inspections may prove counter productive if the builds are never finished on time.

Triggers

Having a build running automatically for your releases can be a drain on server resources, particularly if you never have any intention of actually doing a deploy for most of them. For this reason our builds are set to manual.

However for statuses to be of any use, they’re going to need to be running automatically so that the status is ready for the code reviewer, so we need to add a VCS Trigger.

Triggers

Build Features

To get Team City to start posting status updates back to GitHub we need to add a build feature. If your on a version of TeamCity prior between 7.1 and 10 then there is a plugin you can grab here https://github.com/jonnyzzz/TeamCity.GitHub. If your on a newer version of TeamCity. i.e. 10+ then the build feature is now built in and is called Commit status publisher. The built in version also has support for Bitbucket, Gerrit, GitLab, JetBrains Upsource and Visual Studio Team Services.

Add the build feature and fill in the config settings.

CommitStatusPublisher.PNG

And that’s it. Your pull requests will now automatically build and have the status sent back to GitHub.

Pull Status Pass.PNG

Not only will you be able to see this status in GitHub, you’ll also be able to click a details link to see the build. Useful in the event that it’s failed and you want to see why.

 

The importance of build numbers

If I were to make a prediction, I would say that build numbers are something that are rarely treated as being important in the agency world of web development. That’s not to say milestone releases aren’t given names like “Phase 2”, “August Release” or a major feature name, but every build / release of a project in between, I’d sense largely have build numbers either ignored or never created.

It’s also easy to see why, after all it’s not like we’re producing software that’s going out to the masses to be installed. The solution is essentially just ending up having 1 install on a set of servers. When a new version is built, that replaces everything that came before it and if a bug is found we generally roll forward and fix the bug rather than ever reverting back.

Why use build numbers?

So when we’re constantly coding and improving applications in an agile world why should we care about and use build numbers?

To put it quite simply its just an easy way to identify a snapshot of code that could have actually have been built and then released to a server. This becomes hugely useful in scenarios such as:

  • A bug being reported by an end user
  • An issue being identified by some performance monitoring
  • An issue being picked up in some functionality further on from the site. e.g. in an integration

Without build numbers the only way to react to these scenarios is to look at commit dates in source control or manual release notes that may have been created to try and work out where an issue may have been created and what changed at that time. If the issue had subsequently been fixed you also can’t really give a version description when it was fixed other than a rough date.

Other advantages of build numbers can include:

  • Being able to reference a specific version that has been pen tested
  • Referencing a version that’s been tested with integrations
  • Having approval to release a specific version rather than just the latest on master
  • Anywhere you want to have a conversation referencing releases

Build numbers for deploys

The first step to use build numbers and with the rise in CI, possibly the one thing most people are doing is to start creating build numbers via a build server. By using any type of build server you will end up with build numbers. This instantly gives you a way to know when a build was created and what commits were new within the build.

Start involving an automated deployment setup either using your build server or with other tools like Octopus Deploy and you will now start to get a record of when each build was deployed to each server.

feature-1

Now you have an easy way to not only reference what build was on each environment and when through the deploy history, but also a way to see what went into a build through the build servers change log.

Tag builds in source control

Being able to see the changes that went into each build on your build server is all very good, but it’s still not an ideal situation for finding the exact code version a build relates to.

Thankfully if your using Team City it’s really easy to set it up to create a tag in your source control with each build number. Simply go to the build features section of your projects configuration and add a feature called “VCS Labeling”. This is a step that happens post build in the background and will create a tag in source control including the build number. It has lots of other configuration options, so if you need different tag formats for different branches its got you covered.

If your using GitHub once this is turned on you will be able to see a list of all the tags in the releases section.

GitHub Releases Screen

Update Assembly info

Being able to identify a build in source control and view a history of what should have been on a server at a particular time is all very good, but its also a good idea to be able to easily identify a build for a published version of code. That way just by looking at the code on a server you can tell which build version it is, and not rely on your deployment tool to be correct.

If your using Team City this also also made super simple through a build feature called “Assembly info patcher”. When using this the build number will automatically get patched in without having to edit AssemblyInfo.cs.

Conclusion

By following these tips you will now be able to identify a version by looking at the published code, see a history of when each version was not only built but also released to each envrionment and also have an easy way to find the exact source for that build.

The build number can then be used in any conversations around when a bug was introduced and also be referenced in release notes so everyone can keep track of what versions included what fix’s in a simple to understand format.