Wednesday, November 2, 2011

Continuous Delivery with psake and TeamCity - Creating a pipeline with artifact dependencies

In my last post we learned how to publish artifacts from a build that we can use to create a continuous delivery pipeline. So far in this series we’ve covered:

  1. Creating a Local Build With psake, Part 1: Compiling
  2. Creating a Local Build with psake, Part 2: Testing
  3. Continuous Delivery with psake and TeamCity - Reusing the Local Build to Create a CI Build
  4. Continuous Delivery with psake and TeamCity - Preparing for a pipeline

Today we’ll create a build that has an artifact dependency on the CI build that we’ve already setup. This let’s us reuse the artifacts that we published in CI so that we don’t have to compile our solution once again. First, we’ll have to create a deploy task in our build script so that we can simulate a deployment. Edit build/build.ps1 and add this task:

task deploy {
    Write-Output "deploying to test!"

Let’s create a build configuration called "Deploy to Test” where we will use our newly created task and simulate a deployment to a test environment. Add a Poweshell Build Step with script source:

&  {$host.UI.RawUI.BufferSize = new-object System.Management.Automation.Host.Size(512,50); .\tools\psake\psake .\build\build.ps1 deploy}

This tells TeamCity to run psake with the specified deploy task. Next we’ll have to setup the dependency between the “Deploy to Test”-configuration and the “CI”-configuration. Go to the Dependency tab in TeamCity and click Add new artifact dependency. This brings up the following dialog where you can specify the properties of the dependency:


Here I have specified that I want to get the artifacts from the last successful build of CI and that I want to download the file and extract it to the folder build_artifacts. You can read more about this configuration and wildcards here.

By now you might think that we're ready for running the build. However, running it would fail. The reason for this is that TeamCity wouldn’t find psake or our build script. We have to have a strategy for getting the build scripts and tools. One option is to publish them to the artifact repository from the CI build and download them from there. Another option is to download the build scripts and tools from source control. With the latter option you could potentially try to deploy new deployment items, say a web service, from a build that hasn’t got it yet. In other words, you have to be very careful if you update the build script because you always get the latest version, whereas the binaries you get from the artifact repository could be older and not contain what the build script expects. With the former option you have to go through every step in the pipeline to get an update of the build script. Say you find out that you have an error in the build script regarding deployment to production. To fix it you have to go through every step in the pipeline. This is time consuming and it also means that you cannot deploy the original build to production. You now how to deploy the new version. At my current client I have taken the former approach, but based on my experiences I would personally recommend that you download the build scripts and tools from source control. This makes it a lot easier to fix errors and do refactoring.

Back to TeamCity, attach the VCS root that is used in CI to the build configuration under Version Control Settings, click edit checkout rules and add this:


The first line says that TeamCity should exclude everything from the checkout. The next two lines add the build folder and tools folder respectively. If we save and run our build now you should get something similar to.


To add additional steps to the pipeline you could just publish the same downloaded binaries to the artifacts repository and make the next deployment dependent on “Deploy to Test”. Let’s say the next step is deployment to staging. Then you could say that the build that is deployed test has to be verified by QA before it’s deployed to staging by setting up a dependency where you get the last pinned build from “Deploy to Test”. This feature in TeamCity is extremely useful for adding build verification to the process.

Next time I will show you how to label the deployment builds with the build number from CI. See ya!

Download the source code from GitHub.


  1. Veldig imponerende bloggposter i det siste. Jeg blir ikke overrasket om dette fremragende arbeidet henger sammen med at du har en svært stimulerende partner?