Sunday, January 29, 2012

Continuous Delivery with psake and TeamCity - Environment Configuration Management

Happy New Year! I’ll start of the year by adding another post to the series about continuous delivery with psake and TeamCity. So far 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
  5. Continuous Delivery with psake and TeamCity - Creating a pipeline with artifact dependencies
  6. Continuous Delivery with psake and TeamCity - Visualizing a pipeline

Today we’ll look at how to take care of configuration settings when we are deploying to different environments.

Let’s say that we have set up three environments; “CI”, “Test” and “Acceptance Test”:


Each of these environments need to have specific settings, for example which server to deploy a database to.

Powershell has the concept of dot sourcing. Basically it lets you include a PowerShell script from within another script and then you get access to all those variables and methods you defined in the script you included. We’ll use this feature to load an environment specific file into our build script based on an environment parameter that we pass into the build.

Modify the build script called build.ps1 from the previous post  and add the highlighted line to the properties section:

properties {
    $base_dir = resolve-path .\..
    $build_dir = "$base_dir\build"
    $properties_dir = "$build_dir\properties"
    $source_dir = "$base_dir\src"
    $build_artifacts_dir = "$base_dir\build_artifacts"
    $tools_dir = "$base_dir\tools"
    $config = "Debug"
    $test_dir = "$build_artifacts_dir\$config\tests"
    . "$properties_dir\$env.ps1"

Next we’ll add three environment specific files to the path “.\build\properties”:

# ci.ps1
$database_server = "Server 1"
# test.ps1
$database_server = "Server 2"
# acceptance_test.ps1
$database_server = "Server 3"

One of these files will be loaded when we pass in the env parameter to the build script from TeamCity.

Copy the Test build configuration and call it Acceptance Test. Remember to republish the artifacts downloaded in the Test build configuration and make Acceptance Test dependent on the last pinned build of Test:


Change the Powershell build step (see picture below) in TeamCity and add


-parameters @{env='ci'} to the CI build configuration,
-parameters @{env='test'} to the Test build configuration and
-parameters @{env='acceptance_test'} to the Acceptance Test build configuration.

Let’s modify the deploy task in build.ps1 and print out some information about the environment:

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

and also add the following to the compile task:

Write-Output "Integrating database changes for $env at $database_server"

to simulate that we integrate database changes. Since we defined the variable database_server in the environment specific files we can now access it in the build file.

We should now be able to verify in the build log that we have “deployed” to our specified server:


We can also see that builds flow between the different environments and be able to see which build is deployed to which environment:


As always, download the code from GitHub.

No comments:

Post a Comment