Azure管道条件变量和持久变量

时间:2020-02-18 18:58:07

标签: azure-devops azure-pipelines

我正在尝试设置一个Azure管道,该管道根据正在构建的分支自动更新版本号。给定一个master分支,一个develop分支以及一个{major.minor.patch.build}形式的版本,我想实现以下目标:

每当master触发管道时:

  • patch递增1
  • build重置为0

每当develop触发管道时:

  • build递增1

一个示例,我假设在假定1.0.0.0的起始版本的情况下多次运行后,版本号看起来像什么:

  • develop上运行1:1.0.0.1
  • develop上运行2:1.0.0.2
  • master上运行3:1.0.1.0
  • master上运行4:1.0.2.0
  • develop上运行5:1.0.2.1
  • develop上运行6:1.0.2.2
  • master上运行7:1.0.3.0

我的第一个想法是为patchbuild值使用计数器,但是似乎没有办法有条件地增加它们或重置计数器。我的下一个想法是使用几个基于分支有条件地执行的脚本任务,例如:

    #Update build
    - powershell: echo "##vso[task.setvariable variable=version.build;isOutput=true]$(version.build + 1)"
      condition: eq(variables['Build.SourceBranch'], 'refs/heads/develop')

    #Reset build number
    - powershell: echo "##vso[task.setvariable variable=version.build;isOutput=true]0"
      condition: eq(variables['Build.SourceBranch'], 'refs/heads/master')

    #Update patch
    - powershell: echo "##vso[task.setvariable variable=version.patch;isOutput=true]$(version.patch + 1)"
      condition: eq(variables['Build.SourceBranch'], 'refs/heads/master')

但是,这种方法不能在每次运行中都保持不变(更不用说$(version.patch + 1)了。我找不到有关如何以这种方式实际增加变量的任何信息)。我的最后一个想法是在存储库中使用一个版本文件并使用它,但我真的不想走那条路。

是否有办法使用管道来实现我正在寻找的目标?或者我试图尝试以这种方式吠叫错误的树吗?

编辑 我应该在问题中提到,这时我已经建立了一个管道程序,该程序可以构建我的应用程序,但是对版本控制却不起作用。目前,我正在寻找一种动态更新一些持久变量/值(特别是patchbuild)的方法。

2 个答案:

答案 0 :(得分:3)

因此,有一个可用的计数器变量可以处理what you want中的某些变量。

使用它,我可以使其部分适应您所追求的。

trigger:
- master

pool:
  vmImage: 'ubuntu-latest'

variables:
  major: 1
  minor: 0
  # define b as a counter with the prefix as variable a, and seed as 100.
  #patch: $[counter(variables['major'], 1)]

  ${{ if eq( variables['Build.SourceBranchName'], 'master') }}:
    patch: $[counter(variables['major'], 1)]
    build: 0

  ${{ if eq( variables['Build.SourceBranchName'], 'develop') }}:
    build: $[counter(variables['major'], 1)]
    #patch: ?


name: $(major).$(minor).$(patch).$(build)

steps:
    - bash: echo $(major).$(minor).$(patch).$(build)

但是据我所知,当在开发环境中运行构建时,没有一种很好的方法来获取当前的$(patch)计数器变量。旁注我想知道如何到达custom counter values。您可能会使用该API,并从上次运行中获取Buildnumber并提取补丁号并重复使用,但这会导致您提出这个问题。

有没有一种方法可以使用管道实现我正在寻找的东西? 吠叫试图这样做的错误树吗?

我想改变您的方法。如果您正在使用powershell或yaml设计自定义版本控制方案,那时候我会说版本控制对于使用GitVersion或其他等效版本来说已经足够重要了。有一个学习曲线可以入门,但是GitVersion模式中默认的默认设置之一可能会满足您的目的。

有一个管道task here,如果您将版本添加到管道中,它将为您处理版本。

- task: GitVersion@5
  inputs:
    runtime: 'core'
    configFilePath: 'GitVersion.yml'

最好提供GitVersion.yml,这是用于执行版本控制的方案或指令集。

您可以安装chocolatey package以便在本地进行实验。如果您在存储库的根目录中run GitVersion init会带您经过一些版本控制选项,并为您创建GitVersion.yml。

mode: Mainline
branches:
  master:
    tag: ''
    regex: master
    increment: minor
  develop:
    tag: ''
    regex: develop
    increment: patch
ignore:
  sha: []
merge-message-formats: {}

以上面的股票主线模式为例:

enter image description here

答案 1 :(得分:2)

我有一个解决方法,可以通过Restful api实现这一目标。

例如,您想将上述版本标签添加到构建中。您可以先使用get tag api获取上一版本的标签。然后,您可以使用脚本更新版本,并使用更新的标记对其进行更新。您可以在powershell任务中参考以下脚本。

# first get previous build id

$url = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/build/builds?definitions={pipeline Id}&`$top=2&api-version=5.1"

$result = Invoke-RestMethod -Uri $url -Headers @{authorization = "Bearer $(System.AccessToken)"} -Method get

$builds = $result.value
$bid = $builds[1].id

# get the build tag with get build tag api

$urltag ="$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/build/builds/$bid/tags?api-version=5.1"

$tagResult = Invoke-RestMethod -Uri $urltag -Headers @{authorization = "Bearer $(System.AccessToken)"} -Method get

# get the tag and update it

if($tagResult.value)
{
   $tagarr = [regex]::split($result.value, '\.')
   $patch = $tagarr[2]
   $build = $tagarr[3]
   $tag=""
   if("$(Build.SourceBranch)" -eq "refs/heads/master")
   {
      $patch = [int]$patch + 1
      # update the variables version.patch and version.build with below scripts, so that it can be referenced in the following tasks.
      #echo "##vso[task.setvariable variable=version.patch;isOutput=true]$patch"
      #echo "##vso[task.setvariable variable=version.build;isOutput=true]0"

     $tag = "$(version.major).$(version.minor).$patch.0"    
   }  
   if("$(Build.SourceBranch)" -eq "refs/heads/dev")
   {
      $build= [int]$build+ 1
      #echo "##vso[task.setvariable variable=version.patch;isOutput=true]$patch"
      #echo "##vso[task.setvariable variable=version.build;isOutput=true]$build"
      $tag = "$(version.major).$(version.minor).$patch.$build"  
   }

 #add $tag to current build.
  $urltagupdate = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/tags/$($tag)?api-version=5.1"

  Invoke-RestMethod -Uri $urltagupdate -Headers @{authorization = "Bearer $(System.AccessToken)"} -Method put

}else 
{
  #if the build is run for the first time and the tag is not exist.
  #you can omit this part by manually creating a initial tag for the build.

  $tag = ""
  if("$(Build.SourceBranchName)" -eq "refs/heads/master")
  {
    $tag = "1.0.1.0"
  }
  if("$(Build.SourceBranchName)" -eq "refs/heads/dev") 
  {
    $tag="1.0.0.1"
  }

 #add $tag to current build.

  $urltagupdate = "$(System.TeamFoundationCollectionUri)$(System.TeamProject)/_apis/build/builds/$(Build.BuildId)/tags/$($tag)?api-version=5.1"

  Invoke-RestMethod -Uri $urltagupdate -Headers @{authorization = "Bearer $(System.AccessToken)"} -Method put

}

以上是构建标记的示例。如果要标记回购分支,可以使用refs tag api

主要思想是通过api获取先前的标记,并在powershell任务中根据version.patch更新version.buildbuild.sourcebranch