TeamCity - Run Build

Octopus.Script exported 2020-11-03 by harrisonmeister belongs to ‘TeamCity’ category.

Trigger a specific Team City build from an Octopus Deploy process and wait for the result. The step will fail if the build fails.

Parameters

When steps based on the template are included in a project’s deployment process, the parameters below can be set.

BuildConfigurationId

tcrb_TeamCityBuildConfigurationId =

The Id of the build configuration to trigger.

TeamCityUrl

tcrb_TeamCityUrl =

The URL of the Team City server. E.g. http://teamcity.example.com

TeamCityUsername

tcrb_TeamCityUsername =

The username to use for accessing TeamCity.

TeamCityPassword

tcrb_TeamCityPassword =

The password for the TeamCity user.

TeamCityInterval

tcrb_TeamCityInterval = 5

Number of seconds to wait between each check of the build’s state.

BuildParameters

tcrb_BuildParams =

Line-delimited list of parameters to add to the build in the form = and can be contained in quotes. E.g. param1=param_value1 env.param2=“env_param2” system.param3=sys_param2

Script body

Steps based on this template will execute the following PowerShell script.

# Set TLS 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12

$teamCityBuildConfigId = $OctopusParameters['tcrb_TeamCityBuildConfigurationId']
$teamCityUrl = $OctopusParameters['tcrb_TeamCityUrl']
$teamCityUsername = $OctopusParameters['tcrb_TeamCityUsername']
$teamCityPassword = $OctopusParameters['tcrb_TeamCityPassword']
$teamCityInterval = [int]::Parse($OctopusParameters['tcrb_TeamCityInterval'])
$teamCityBuildParams = $OctopusParameters['tcrb_BuildParams']

function Start-TeamCityBuild($Url, $Username, $Password, $BuildConfigId, $BuildParams) {
    $endpoint = "${Url}/httpAuth/app/rest/buildQueue"
    $content = "<build><buildType id=`"${BuildConfigId}`" /><properties>"
    if (-not [String]::IsNullOrEmpty($BuildParams)) {
        foreach ($param in (ConvertFrom-Csv -Delimiter '=' -Header Name,Value -InputObject $BuildParams)) {
            $name = $param.Name.Replace('"', '&quot;')
            $value = $param.Value.Replace('"', '&quot;')
            $content += "<property name=`"${name}`" value=`"${value}`" />"
        }
    }
    $content += "</properties></build>"    
    $encodedContent = [System.Text.Encoding]::UTF8.GetBytes($content)

    Write-Host "Triggering build with Id ${BuildConfigId} in TeamCity. Server: ${Url}"

    $req = [System.Net.WebRequest]::Create($endpoint)
    $req.Credentials = New-Object System.Net.NetworkCredential($Username, $Password)
    $req.Method = "POST"
    $req.ContentType = "application/xml"

    $req.ContentLength = $encodedContent.length
    $requestStream = $req.GetRequestStream()
    $requestStream.Write($encodedContent, 0, $encodedContent.length)
    $requestStream.Close()

    $resp = $req.GetResponse()
    $reader = New-Object System.IO.StreamReader($resp.GetResponseStream())
    $result = [xml]$reader.ReadToEnd()
    $buildUrl = $result.build.webUrl

    Write-Host $buildUrl
    Write-Host "================================================================================"

    return $result
}

function Get-TeamCityBuildState($Url, $Username, $Password, $BuildInfo) {
    $href = $BuildInfo.href
    $buildId = $BuildInfo.id
    $endpoint = "${Url}${href}"

    Write-Host "Getting state of build ${buildId} in TeamCity. Server: ${Url}"

    $req = [System.Net.WebRequest]::Create($endpoint)
    $req.Credentials = New-Object System.Net.NetworkCredential($Username, $Password)
    $req.Method = "GET"

    $resp = $req.GetResponse()
    $reader = New-Object System.IO.StreamReader($resp.GetResponseStream())
    return [xml]$reader.ReadToEnd();
}

function Invoke-TeamCityBuild ($Url, $Username, $Password, $BuildConfigId, $Interval, $BuildParams) {
    $build = Start-TeamCityBuild -Url $Url -Username $Username -Password $Password -BuildConfigId $BuildConfigId -BuildParams $teamCityBuildParams
    $buildInfo = $build.build

    while ($true) {
        $buildState = Get-TeamCityBuildState -Url $teamCityUrl -Username $teamCityUsername -Password $teamCityPassword -BuildInfo $buildInfo
        Write-Host $buildState.build.state
        if ($buildState.build.state -eq 'finished') {
            return $buildState.build
        }
        
        Start-Sleep -Seconds $Interval
    }
}

$buildResult = Invoke-TeamCityBuild -Url $teamCityUrl -Username $teamCityUsername -Password $teamCityPassword -BuildConfigId $teamCityBuildConfigId -Interval $teamCityInterval -BuildParams $teamCityBuildParams
$message = $buildResult.statusText
Write-Host "================================================================================"
Write-Host $buildResult.webUrl
if ($buildResult.status -eq 'FAILURE') {
    Write-Host "Build failed: ${message}"
    exit 1
}
elseif ($message -eq 'Canceled') {
    Write-Host "Build canceled: ${message}"
    exit 2
}
else {
    Write-Host "Build successful: ${message}"
    exit 0
}

Provided under the Apache License version 2.0.

Report an issue

To use this template in Octopus Deploy, copy the JSON below and paste it into the Library → Step templates → Import dialog.

{
  "Id": "a7fa3e51-14aa-4bb9-8686-781adc9bf93e",
  "Name": "TeamCity - Run Build",
  "Description": "Trigger a specific Team City build from an Octopus Deploy process and wait for the result. The step will fail if the build fails.",
  "Version": 3,
  "ExportedAt": "2020-11-03T09:42:34.506Z",
  "ActionType": "Octopus.Script",
  "Author": "harrisonmeister",
  "Packages": [],
  "Parameters": [
    {
      "Name": "tcrb_TeamCityBuildConfigurationId",
      "Label": "BuildConfigurationId",
      "HelpText": "The Id of the build configuration to trigger.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Name": "tcrb_TeamCityUrl",
      "Label": "TeamCityUrl",
      "HelpText": "The URL of the Team City server.\nE.g. `http://teamcity.example.com`",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Name": "tcrb_TeamCityUsername",
      "Label": "TeamCityUsername",
      "HelpText": "The username to use for accessing TeamCity.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Name": "tcrb_TeamCityPassword",
      "Label": "TeamCityPassword",
      "HelpText": "The password for the TeamCity user.",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "Sensitive"
      }
    },
    {
      "Name": "tcrb_TeamCityInterval",
      "Label": "TeamCityInterval",
      "HelpText": "Number of seconds to wait between each check of the build's state.",
      "DefaultValue": "5",
      "DisplaySettings": {
        "Octopus.ControlType": "SingleLineText"
      }
    },
    {
      "Name": "tcrb_BuildParams",
      "Label": "BuildParameters",
      "HelpText": "Line-delimited list of parameters to add to the build in the form <name>=<value>\n<name> and <value> can be contained in quotes.\nE.g.\nparam1=param_value1\nenv.param2=\"env_param2\"\nsystem.param3=sys_param2",
      "DefaultValue": "",
      "DisplaySettings": {
        "Octopus.ControlType": "MultiLineText"
      }
    }
  ],
  "Properties": {
    "Octopus.Action.Script.Syntax": "PowerShell",
    "Octopus.Action.Script.ScriptBody": "# Set TLS 1.2\n[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12\n\n$teamCityBuildConfigId = $OctopusParameters['tcrb_TeamCityBuildConfigurationId']\n$teamCityUrl = $OctopusParameters['tcrb_TeamCityUrl']\n$teamCityUsername = $OctopusParameters['tcrb_TeamCityUsername']\n$teamCityPassword = $OctopusParameters['tcrb_TeamCityPassword']\n$teamCityInterval = [int]::Parse($OctopusParameters['tcrb_TeamCityInterval'])\n$teamCityBuildParams = $OctopusParameters['tcrb_BuildParams']\n\nfunction Start-TeamCityBuild($Url, $Username, $Password, $BuildConfigId, $BuildParams) {\n    $endpoint = \"${Url}/httpAuth/app/rest/buildQueue\"\n    $content = \"<build><buildType id=`\"${BuildConfigId}`\" /><properties>\"\n    if (-not [String]::IsNullOrEmpty($BuildParams)) {\n        foreach ($param in (ConvertFrom-Csv -Delimiter '=' -Header Name,Value -InputObject $BuildParams)) {\n            $name = $param.Name.Replace('\"', '&quot;')\n            $value = $param.Value.Replace('\"', '&quot;')\n            $content += \"<property name=`\"${name}`\" value=`\"${value}`\" />\"\n        }\n    }\n    $content += \"</properties></build>\"    \n    $encodedContent = [System.Text.Encoding]::UTF8.GetBytes($content)\n\n    Write-Host \"Triggering build with Id ${BuildConfigId} in TeamCity. Server: ${Url}\"\n\n    $req = [System.Net.WebRequest]::Create($endpoint)\n    $req.Credentials = New-Object System.Net.NetworkCredential($Username, $Password)\n    $req.Method = \"POST\"\n    $req.ContentType = \"application/xml\"\n\n    $req.ContentLength = $encodedContent.length\n    $requestStream = $req.GetRequestStream()\n    $requestStream.Write($encodedContent, 0, $encodedContent.length)\n    $requestStream.Close()\n\n    $resp = $req.GetResponse()\n    $reader = New-Object System.IO.StreamReader($resp.GetResponseStream())\n    $result = [xml]$reader.ReadToEnd()\n    $buildUrl = $result.build.webUrl\n\n    Write-Host $buildUrl\n    Write-Host \"================================================================================\"\n\n    return $result\n}\n\nfunction Get-TeamCityBuildState($Url, $Username, $Password, $BuildInfo) {\n    $href = $BuildInfo.href\n    $buildId = $BuildInfo.id\n    $endpoint = \"${Url}${href}\"\n\n    Write-Host \"Getting state of build ${buildId} in TeamCity. Server: ${Url}\"\n\n    $req = [System.Net.WebRequest]::Create($endpoint)\n    $req.Credentials = New-Object System.Net.NetworkCredential($Username, $Password)\n    $req.Method = \"GET\"\n\n    $resp = $req.GetResponse()\n    $reader = New-Object System.IO.StreamReader($resp.GetResponseStream())\n    return [xml]$reader.ReadToEnd();\n}\n\nfunction Invoke-TeamCityBuild ($Url, $Username, $Password, $BuildConfigId, $Interval, $BuildParams) {\n    $build = Start-TeamCityBuild -Url $Url -Username $Username -Password $Password -BuildConfigId $BuildConfigId -BuildParams $teamCityBuildParams\n    $buildInfo = $build.build\n\n    while ($true) {\n        $buildState = Get-TeamCityBuildState -Url $teamCityUrl -Username $teamCityUsername -Password $teamCityPassword -BuildInfo $buildInfo\n        Write-Host $buildState.build.state\n        if ($buildState.build.state -eq 'finished') {\n            return $buildState.build\n        }\n        \n        Start-Sleep -Seconds $Interval\n    }\n}\n\n$buildResult = Invoke-TeamCityBuild -Url $teamCityUrl -Username $teamCityUsername -Password $teamCityPassword -BuildConfigId $teamCityBuildConfigId -Interval $teamCityInterval -BuildParams $teamCityBuildParams\n$message = $buildResult.statusText\nWrite-Host \"================================================================================\"\nWrite-Host $buildResult.webUrl\nif ($buildResult.status -eq 'FAILURE') {\n    Write-Host \"Build failed: ${message}\"\n    exit 1\n}\nelseif ($message -eq 'Canceled') {\n    Write-Host \"Build canceled: ${message}\"\n    exit 2\n}\nelse {\n    Write-Host \"Build successful: ${message}\"\n    exit 0\n}\n",
    "Octopus.Action.Script.ScriptSource": "Inline",
    "Octopus.Action.Script.ScriptFileName": null
  },
  "Category": "TeamCity",
  "HistoryUrl": "https://github.com/OctopusDeploy/Library/commits/master/step-templates//opt/buildagent/work/75443764cd38076d/step-templates/teamcity-run-build.json",
  "Website": "/step-templates/a7fa3e51-14aa-4bb9-8686-781adc9bf93e",
  "Logo": "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",
  "$Meta": {
    "Type": "ActionTemplate"
  }
}

History

Page updated on Tuesday, November 3, 2020