由于在使用TFVC时TFS中不可能有一个单独的构建定义来处理多个分支中的相同代码,因此我们必须为分支维护多个构建定义。
现在我们已经扩展了CI / CD管道以进行自动发布部署。由于我们有多个分支,因此我们还有多个构建定义,现在我们也有多个版本定义。
使用TFS 2017.1,现在可以在版本定义中定义多个持续部署触发器(工件源)。如果成功构建了与这些工件源关联的其中一个构建定义,则可以自动创建和部署新版本。 为了能够摆脱多个版本定义,有必要确定实际触发创建新版本及其部署的构建。
可以在发布定义中使用许多变量,但遗憾的是,似乎无法获得实际触发发布的构建/工件(请参阅https://www.visualstudio.com/en-us/docs/build/concepts/definitions/release/variables#primary-artifact-variables)。
如何确定触发发布的构建定义/工件?
答案 0 :(得分:2)
我有同样的问题。我希望有一种更直接的方法来查找相应构建的触发“{Artifact alias}”,但我发现确定哪个构建触发了发布的唯一方法是获取以下环境变量: $ env :RELEASE_RELEASEDESCRIPTION 强> 此变量具有以下计算值: “触发”+ {工件别名} + BuildId +“。” 希望这可以帮助 最好的祝福 斯特凡
答案 1 :(得分:1)
在TFS 2017 Update1的发布定义中,如果您将多个构建定义绑定到它,并为发布定义中的每个工件添加持续部署触发器。然后,每次构建成功时都会触发您的发布定义。
要了解哪个版本触发了您的版本,您可以参考版本摘要页。
答案 2 :(得分:1)
可以使用标记的环境变量。
使用此片段,您可以获取并打印所有环境变量。屏幕截图显示了执行此代码段的结果。
# Get all release environment variables
$environmentVars = get-childitem -path env:*
# Show each environment variable
foreach($var in $environmentVars){
$keyname = $var.Key
$keyvalue = $var.Value
Write-Verbose "${keyname}: $keyvalue" -Verbose
}
答案 3 :(得分:0)
我有相同的要求(获取触发构建的工件的路径),但是建议的解决方案对我不起作用-$ env:RELEASE_RELEASEDESCRIPTION为空。
原因: 这是因为发布是手动触发的。我们无法在这些版本中进行自动部署,因为大多数版本未部署,因此必须手动触发部署。但是,我缺少的一点是,虽然我们不希望自动触发构建中的任何 Environments ,但是可以自动创建 Release
解决方案: 一旦理解了这一点,并在Release定义中的每个工件上启用了CI触发器,但将所有Environment触发器都保留为“仅限手动”,则现在填充$ env:RELEASE_RELEASEDESCRIPTION,并且由“ stephgou”提出的方法会起作用。
如果TFS对此有更好的解决方案,那就太好了,因为解析描述绝对不好!最终,我们需要DropLocation,因此也需要将其添加为变量。
这是我的PowerShell脚本,用于从描述中获取DropLocation,这可能对某人有用:
#*================================================================================
#* Summary: This is a workaround for a TFS Limitation.
#* Determines the Drop Location of a vNext build, as it is NOT provided in a variable for us!
#*
#* Output: values will be available in the following Build Step variables:
#* $(TriggeringBuildID)
#* $(TriggeringBuildNumber)
#* $(TriggeringBuildUri)
#* $(DropLocation)
#* Or, in a script:
#* $env:TRIGGERINGBUILDID
#* $env:TRIGGERINGBUILDNUMBER
#* $env:TRIGGERINGBUILDURL
#* $env:DROPLOCATION
#*================================================================================
Param (
[string] $DeploymentScript = "_internalDeployment\DeployBuild_vNext.ps1"
)
$tfsServer=$env:SYSTEM_TEAMFOUNDATIONSERVERURI
$teamProject = $env:SYSTEM_TEAMPROJECT
# Default these, but as we may have multiple build artifacts associated with the release, need to get the triggering build ID if possible.
$script:buildID = $env:BUILD_BUILDID
$script:buildNumber = $env:BUILD_BUILDNUMBER
$script:buildURI = $env:BUILD_BUILDURI
Write "buildID = $script:buildID"
Write "buildNumber = $script:buildNumber"
Write "buildURI = $script:buildURI"
$ReleaseDescription = $env:RELEASE_RELEASEDESCRIPTION
if( $ReleaseDescription -and $ReleaseDescription.Length -gt 16 )
{
Write "$ReleaseDescription = [$ReleaseDescription], Determining the Triggering Build."
# This is a work-around for the fact TFS Release does not have any variables for the triggering build ID\Number (only has the Primary Artifact).
# Hack is to get it from the Release's description, which is populated with trigger information IF it has CI-Trigger enabled.
$buildChanged = $false
# Parse the ReleaseDescription. Expected format: "Triggered by <ArtifactAlias> <BuildNumber>."
# TODO a better way to do this? ... regex.
$a,$b,$c,$d = $ReleaseDescription.split(' ')
$TriggeringBuildNumber = $d.Remove($d.Length-1)
Write "TriggeringBuildNumber = $TriggeringBuildNumber"
if( $TriggeringBuildNumber -ne $script:buildNumber )
{
# Get the BuildId:
$uri = "$tfsServer/$teamProject/_apis/build/builds?api-version=4.1&buildNumber=$TriggeringBuildNumber"
Write "Invoking Method : GET $uri"
$Build = Invoke-RestMethod -Method Get -UseDefaultCredentials -Uri "$uri"
if( $Build[0] -and $Build.value -and $Build.value.Count -eq 1 -and $Build.value[0].id -ne 0)
{
$script:BuildId = $Build.value[0].id
$script:buildNumber = $TriggeringBuildNumber # = $Build.value[0].buildNumber
$script:buildURI = $Build.value[0].url
Write "Build Found - ID is $BuildId."
$buildChanged = $true
}
else
{
throw "Build not found"
}
}
if( $buildChanged )
{
Write "buildID changed to $script:buildID"
Write "buildNumber changed to $script:buildNumber"
Write "buildURI changed to $script:buildURI"
}
}
else
{
# Allow for manually triggered build (but it has to be the primary artifact for this to work)
$TriggeringBuildNumber = $script:buildNumber
}
# Determine the DropLocation from the BuildId.
# This is a work-around for the fact TFS Release does not have a variable for the DropLocation.
$BuildId = $script:buildID
Write "Get the DropLocation for buildId = $BuildId"
$DropLocation = ""
$DropLocationRoot = ""
# Get the build's artifacts
$uri = "$tfsServer/$teamProject/_apis/build/builds/$BuildId/artifacts?api-version=4.1"
Write "Invoking Method : GET $uri"
$artifacts = Invoke-RestMethod -Method Get -UseDefaultCredentials -Uri "$uri"
# Find the drop location (filepath)
foreach( $artifact in $artifacts.value )
{
if( $artifact.name -eq $TriggeringBuildNumber -and $artifact.resource -and $artifact.resource.type -eq "filepath" -and $artifact.resource.data )
{
$DropLocationRoot = $artifact.resource.data
Write "Artifact Found - DropLocationRoot is $DropLocationRoot."
Break
}
}
if( $DropLocationRoot -eq "" )
{
throw "DropLocation not found."
}
$DropLocation = "$DropLocationRoot\$TriggeringBuildNumber"
Write "DropLocation = $DropLocation"
if( Test-Path $DropLocation )
{
Write "Yay! - Drop folder Found at $DropLocation. :-)"
$DeploymentScript = "$DropLocation\$DeploymentScript"
if( Test-Path $DeploymentScript )
{
Write "... and Yay, the Deployment Script was Found at $DeploymentScript. :-)"
}
else
{
throw "... but whoops! - Deployment Script was NOT Found. :-("
}
}
else
{
throw "whoops! - DropLocation [$DropLocation] does not exist. :-("
}
# Pass the values back out via $env vars.
# Note: tried using the below to reset the standard TFS System Variables, but it doesn't seem to take effect:
#Write-Host "##vso[task.setvariable variable=BUILD_BUILDID]$script:buildID"
#Write-Host "##vso[task.setvariable variable=BUILD_BUILDNUMBER]$script:buildNumber"
#Write-Host "##vso[task.setvariable variable=BUILD_BUILDURI]$script:buildURI"
Write-Host "##vso[task.setvariable variable=TRIGGERINGBUILDID]$script:buildID"
Write-Host "##vso[task.setvariable variable=TRIGGERINGBUILDNUMBER]$script:buildNumber"
Write-Host "##vso[task.setvariable variable=TRIGGERINGBUILDURI]$script:buildURI"
Write-Host "##vso[task.setvariable variable=DROPLOCATION]$DropLocation"