This post is part of a series of articles on the new TFS Build vNext System.
So as I talked about before it looks like the main way we will be able to customise our builds is to simply add a powershell script task to the build. We can create custom tasks if we like but for most build activities it will be enough to just add a powershell script. So lets say we have a set of unit tests that run against a database and we need to drop and recreate the database before the unit tests run. Here’s a simple example of how to wire in a script that does just that. First the powershell script.
param ( [string] $databaseServer, [string] $databaseName, [string] $databaseUser, [string] $databasePassword ) cls Write-Output "This is an example of using a predefined variable in your script. BUILD_SOURCESDIRECTORY: $Env:BUILD_SOURCESDIRECTORY" Write-Output "Dropping and recreating database $databaseName on server $databaseServer" Write-Output "Importing sqlps module" Import-Module sqlps Write-Output "Dropping and recreating database $databaseName" $scriptPath = split-path -parent $MyInvocation.MyCommand.Definition $sqlScript = join-path $scriptpath 'ReCreateDatabase.sql' Invoke-SQLCMD -ServerInstance $databaseServer -Database 'master' -InputFile $sqlScript -Username $databaseUser -Password $databasePassword Write-Output "Updating database $databaseName" $sqlScript = join-path $scriptpath 'UpdateDatabase.sql' Invoke-SQLCMD -ServerInstance $databaseServer -Database $databaseName -InputFile $sqlScript -Username $databaseUser -Password $databasePassword
Nothing complicated here I just run two sql scripts, one to drop and recreate my database, the next to create the schema objects and add some data. Check your script into source control and then add a new powershell task to the build workflow
Simply drag and drop the script to set it to run before the unit tests run and then set the script filename to point to the script you just checked into source control.
That’s basically it – but the script does take some parameters as input. As I’ve said before the variable system is much simpler than the old xaml system. Under the old xaml system adding variables to a build definition was a little unintuitive, now we have a simple UI. On the variables tab I can simply add new variables that tell the build where my database is and how to connect to it
As you can see I can even encrypt any sensitive data which is an improvement on xaml builds where it was often the case to store passwords etc in plain text in the build definition. Finally I update my powershell task Arguments setting to look like this
-databaseServer $(DatabaseServer) -databaseName $(DatabaseName) -databaseUser $(DatabaseUser) -databasePassword $(DatabasePassword)
You can see that the way to access user defined variables is by using the syntax $(variablename). This works from within the build definition but not necessarily from within your scripts, if you want to use the variable from within a script then pass it in as an argument. There are a whole list of out of the box variables you can use in your scripts. If you want to use one of these variables from within your scripts then reference them by using $Env:Environment Variable Name e.g. you can see in my example script the line
Write-Output "This is an example of using a predefined variable in your script. BUILD_SOURCESDIRECTORY: $Env:BUILD_SOURCESDIRECTORY"
If you want to use one of these variables from within the build definition then reference them using the variable name e.g. $(Build.SourcesDirectory)