Tuesday, February 7, 2012

Continuous Delivery with psake and TeamCity - Time for Some Refactoring

Refactoring is not just something you do with code. It’s also something you do with the build scripts and build process. Today we will split up our build script in nested builds and do some changes to how we pass on the build number to the next build configuration in the pipeline.

My previous installments in this series:

  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
  5. Continuous Delivery with psake and TeamCity - Creating a pipeline with artifact dependencies
  6. Continuous Delivery with psake and TeamCity - Visualizing a pipeline
  7. Continuous Delivery with psake and TeamCity - Environment Configuration Management

First up, I want to change how I pass in the task to run and the environment to the build script. It looked something like this for the CI configuration:

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

See how ci gets passed in, both for the task and the env parameter. I want to change this so the build script gets these values from TeamCity through Configuration Parameters. By doing that it’s a little bit easier to see and change these values. Let’s define some configuration parameters. Go to Build Parameters and add this:

image

Change the PowerShell build step to:

&  {$host.UI.RawUI.BufferSize = new-object System.Management.Automation.Host.Size(512,50); .\tools\psake\psake .\build\build.ps1 %task% -parameters @{env='%environment%'}}

TeamCity let’s you access the parameters that you have defined by typing %parameter_name%. Do the same changes for the Test and Acceptance Test build configuration.

Next we’ll do something similar to pass in the build number from CI to Test and Acceptance Test. When you set up a dependent build you get access to all the build parameters passed and set by the build a build configuration is dependent on. So if C is dependent on B and B is dependent on A, C gets access to both A’s and B’s build parameters. So the build number of CI gets passed to Test and Acceptance Test as %dep.bt2.build.number% where bt2 is the build configuration id of CI. For Test and Acceptance Test add the following build parameter:

image

and change the PowerShell build step to:

&  {$host.UI.RawUI.BufferSize = new-object System.Management.Automation.Host.Size(512,50); .\tools\psake\psake .\build\build.ps1 %task% -parameters @{env='%environment%'; build_number='%build_number%'}}

The final thing I want to change how we call the task deploy and set_build_number. Both these tasks are relevant only to deployment so we’ll move them to a separate file called deploy.ps1:

$framework = '4.0'

include .\..\tools\psake\teamcity.ps1

task default -depends deploy

task deploy -depends set_build_number{
    Write-Output "deploying to $env => database is deployed to $database_server"
}

task set_build_number {
    TeamCity-SetBuildNumber $build_number
}

and then we’ll add a new deploy task in build.ps1 which calls the the deploy build script so that we get nested builds, a feature in psake. Here we also pass along all the parameters and properties so that the nested build can access the same variables:

task deploy {
    invoke-psake .\deploy.ps1 -properties $properties -parameters $parameters
}

Remember to always refactor your build scripts and build process. It’s just as important as code refactorings :)

Download the bits from GitHub.

No comments:

Post a Comment