Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change value in app.config within TeamCity

Within the Visual Studio solution that contains all our unit tests we have some text files. These text files are checked based on some results generated by our unit tests.

In order to load the files we have an app.config with:

 <appSettings>
    <add key="BaseTestDataPath" value="D:\MyPath\MySolution\" />
 </appSettings>

Within TeamCity on each build run I want to:

Change the BaseTestsDataPath to the specific work path of the agent eg.

C:\TeamCity\buildAgent\work\1ca1a73fe3dadf57\MySolution\

I know the physical layout within the agent work folder so what I need to know is:

  • How to change the app.config file prior to the Nunit run against the solution in my build steps for TeamCity
like image 596
TheEdge Avatar asked Dec 01 '22 16:12

TheEdge


1 Answers

There are a couple of approaches to this.

Just choose one of the following scripts, add it to your source control and setup a PowerShell build runner in your build configuration to run the script passing in the required parameters, before you run the NUnit step. If you choose option two then you'll also need to consider the transform dll.

AppSettingReplace.ps1

If you only want to change a single value you can achieve this with some simple PowerShell that will load up the config file into an xml document, iterate the app settings and change the one that matches.

# -----------------------------------------------
# Config Transform
# -----------------------------------------------
#
# Ver   Who                     When      What
# 1.0   Evolve Software Ltd     13-05-16  Initial Version

# Script Input Parameters
param (
    [ValidateNotNullOrEmpty()]
    [string] $ConfigurationFile = $(throw "-ConfigurationFile is mandatory, please provide a value."),
    [ValidateNotNullOrEmpty()]
    [string] $ApplicationSetting = $(throw "-ApplicationSetting is mandatory, please provide a value."),
    [ValidateNotNullOrEmpty()]
    [string] $ApplicationSettingValue = $(throw "-ApplicationSettingValue is mandatory, please provide a value.")
)

function Main() 
{
    $CurrentScriptVersion = "1.0"

    Write-Host "================== Config Transform - Version"$CurrentScriptVersion": START =================="

    # Log input variables passed in
    Log-Variables
    Write-Host

    try {
        $xml = [xml](get-content($ConfigurationFile))
        $conf = $xml.configuration
        $conf.appSettings.add | foreach { if ($_.key -eq $ApplicationSetting) { $_.value = $ApplicationSettingValue } }
        $xml.Save($ConfigurationFile)
    } 
    catch [System.Exception] {
        Write-Output $_
        Exit 1
    }

    Write-Host "================== Config Transform - Version"$CurrentScriptVersion": END =================="
}

function Log-Variables
{
    Write-Host "ConfigurationFile: " $ConfigurationFile
    Write-Host "ApplicationSetting: " $ApplicationSetting
    Write-Host "ApplicationSettingValue: " $ApplicationSettingValue
    Write-Host "Computername:" (gc env:computername)
}

Main

Usage

AppSettingReplace.ps1 "D:\MyPath\app.config" "BaseTestDataPath" "%teamcity.build.workingDir%"


XdtConfigTransform.ps1

The alternative approach to this is to provide full config transformation support using XDT - This does require Microsoft.Web.XmlTransform.dll to end up on the server somehow (which I normally put into source control).

The following script will transform one config file with another one.

# -----------------------------------------------
# Xdt Config Transform
# -----------------------------------------------
#
# Ver   Who                     When      What
# 1.0   Evolve Software Ltd     14-05-16  Initial Version

# Script Input Parameters
param (
    [ValidateNotNullOrEmpty()]
    [string] $ConfigurationFile = $(throw "-ConfigurationFile is mandatory, please provide a value."),
    [ValidateNotNullOrEmpty()]
    [string] $TransformFile = $(throw "-TransformFile is mandatory, please provide a value."),
    [ValidateNotNullOrEmpty()]
    [string] $LibraryPath = $(throw "-LibraryPath is mandatory, please provide a value.")
)

function Main() 
{
    $CurrentScriptVersion = "1.0"

    Write-Host "================== Xdt Config Transform - Version"$CurrentScriptVersion": START =================="

    # Log input variables passed in
    Log-Variables
    Write-Host

    if (!$ConfigurationFile -or !(Test-Path -path $ConfigurationFile -PathType Leaf)) {
        throw "File not found. $ConfigurationFile";
        Exit 1
    }
    if (!$TransformFile -or !(Test-Path -path $TransformFile -PathType Leaf)) {
        throw "File not found. $TransformFile";
        Exit 1
    }

    try {

        Add-Type -LiteralPath "$LibraryPath\Microsoft.Web.XmlTransform.dll"
        $xml = New-Object Microsoft.Web.XmlTransform.XmlTransformableDocument;
        $xml.PreserveWhitespace = $true
        $xml.Load($ConfigurationFile);

        $xmlTransform = New-Object Microsoft.Web.XmlTransform.XmlTransformation($TransformFile);
        if ($xmlTransform.Apply($xml) -eq $false)
        {
            throw "Transformation failed."
        }
        $xml.Save($ConfigurationFile)
    } 
    catch [System.Exception] {
        Write-Output $_
        Exit 1
    }

    Write-Host "================== Xdt Config Transform - Version"$CurrentScriptVersion": END =================="
}

function Log-Variables
{
    Write-Host "ConfigurationFile: " $ConfigurationFile
    Write-Host "TransformFile: " $TransformFile
    Write-Host "LibraryPath: " $LibraryPath
    Write-Host "Computername:" (gc env:computername)
}

Main

Usage

XdtConfigTransform.ps1 "D:\MyPath\app.config" "D:\MyPath\app.transform.config" "%teamcity.build.workingDir%\Library"

Note: The last parameter is the path to the directory that contains Microsoft.Web.XmlTransform.dll

Github Repository - teamcity-config-transform

Hope this helps

like image 91
Evolve Software Ltd Avatar answered Dec 05 '22 13:12

Evolve Software Ltd