accidental

Preventing accidental deployments in TeamCity

One-click deployments are exactly that – one click of the “Run” button, and the magic happens. But, if you have a particularly busy project list in TeamCity, you will find yourself constantly double checking which “Run” button you are pressing, for fear of accidently running a deployment into production. It’s an unfortunate consequence of making things too easy – one little misclick can become a big mistake.

In this post I will show you how to reduce the risk of accidently running a production deployment in TeamCity by introducing a simple safety switch into the build process. At the end, upon pressing the “Run” button you will be presented with a prompt that looks something like this:

oneclickteamcity

The prompt includes a checkbox asking you to confirm that you really want to run the build. If you check it – the build will run as it normally would. If you don’t – it will fail. Effectively turning a one-click deployment into a three-click deployment, with the added benefit of no added training or documentation to other users of your build server.

Step 1

Add a new build step to your build configuration – it should be the very first step that is run. In this example I’ll make it of type Powershell – you can use other script based build types (Gradle, command line, etc.), the script will simply verify if the user has checked the confirm checkbox before the build runs.

Give the build step a name like “Deployment Confirmation”.

Set the Script option to Source code and enter the following into the Script source box:

write-host "##teamcity[message text='Starting confirmation validation...']"
if("%env.Confirm%" -eq "false") {
	write-host "##teamcity[message text='Confirmation validation FAILED' errorDetails='This is a production deployment. The confirm checkbox must be checked to proceed with the deploy process.' status='ERROR']"
	throw "Confirmation validation FAILED"
} else {
	​write-host "##teamcity[message text='Confirmation validation SUCCESSFUL']"
}​

The script basically checks the value of the build parameter %env.Confirm% that is set by the checkbox in the build prompt. If it’s false (unchecked), throw an exception that will kill the rest of the build process. If it is true, don’t do anything, and the build will continue as usual.

The rest of the fields in this build step can be left with their default values. Now would also be a good time to make sure any subsequent steps in your build configuration are set to execute “Only if all previous steps were successful”.

Step 2

Add an environment variable to your build parameters. Name it env.Confirm (make sure if matches the name in the script above) and set the default value to false. Press the “Edit…” button to create a new variable specification. You will be presented with a form with the following fields:

  • Label – this is the text that appears to the left of the checkbox. I set it to something like “This is a production deployment”.
  • Description – this is the text that appears beneath the checkbox. I set it to something like “Are you sure?”.
  • Display – set this to “Prompt”, we want TeamCity to prompt for this value whenever a build is requested.
  • Type – set this to “Checkbox” with the checked value being true and unchecked value being false.

That’s it! From now on when you click the “Run” button, you should get the prompt above. Also note that the build log will contain the message output from the script above so that it becomes very clear why a build failed if someone doesn’t click the confirm checkbox.

One Catch

The only catch I have found with this approach is that despite the default value of our checkbox being set to false, TeamCity has a “feature” that stores the last value of the checkbox in some session state (cookies, session storage, etc.). So if you run a build, enable the checkbox, and five minutes later try to run the build again, the checkbox will already be checked for you. It seems only after twenty minutes or so, or however long it takes for your session to expire, will it reset back to the correct behaviour.

This isn’t a big deal, even if the checkbox is pre-enabled due to this “feature” in TeamCity, the prompt will still appear, so you’re still turning a one-click deployment into a two-click deployment.