【问题标题】:Share variables across stages in Azure DevOps Pipelines在 Azure DevOps Pipelines 中跨阶段共享变量
【发布时间】:2019-08-13 21:37:28
【问题描述】:

我试图弄清楚如何在我的脚本中跨 ADO 管道共享自定义变量。下面是我的脚本,有 2 个阶段。

我将curProjVersion 设置为输出变量并尝试从不同的阶段访问它。我做得对吗?

stages:
- stage: Build
  displayName: Build stage
  jobs:
  - job: VersionCheck
    pool:
      vmImage: 'ubuntu-latest'
    displayName: Version Check
    continueOnError: false
    steps:

      - script: |
          echo "##vso[task.setvariable variable=curProjVersion;isOutput=true]1.4.5"
        name: setCurProjVersion
        displayName: "Collect Application Version ID"

- stage: Deploy
  displayName: Deploy stage
  dependsOn: Build
  variables:
    curProjVersion1: $[ dependencies.Build.VersionCheck.outputs['setCurProjVersion.curProjVersion'] ]
  jobs:
  - job: 
    steps: 
      - script: |
          echo $(curProjVersion1)

【问题讨论】:

    标签: azure azure-devops azure-pipelines


    【解决方案1】:

    更新:

    跨阶段共享变量功能现已在Sprint 168 发布。

    请使用以下格式访问前一阶段的输出变量:

    stageDependencies.{stageName}.{jobName}.outputs['{stepName}.{variableName}'] 
    

    原文:

    在 Azure DevOps Pipelines 中跨阶段共享变量

    恐怕不支持共享在一个阶段定义的变量并将其传递到另一个阶段。

    这是我们计划添加的功能,但到目前为止,它还不支持。你可以关注这个Github issue,很多人和你有同样的需求。你可以跟踪它。

    到目前为止,我们只支持设置multi-job output variable,但这仅支持 YAML。对于经典编辑器,没有任何计划在发布中添加此功能。

    为了变通,您可以在阶段之前预定义变量。但一件重要的事情是,如果你在一个阶段改变它的价值。新值无法传递到下一阶段。具有新值的变量的生命周期只存在于stage中。

    【讨论】:

    • 它适用于工作,但不适用于部署工作 - 有机会看看吗?
    • 最初记录的语法不适用于舞台条件。正确的语法(对于阶段条件)是stageDependencies.{stageName}.outputs['{jobName}.{stepName}.{variableName}']。请参阅github issue on cross-stage variables 了解更多信息。
    • 我有多个模板链接到主管道 yml。每个模板都包含一个阶段和至少一个作业。在这种情况下我注意到的一件事是阶段依赖项只会读取先前模板中的输出变量
    • 条件见:link
    【解决方案2】:

    在舞台级别condition 中没有提到stageDependencies 的重要内容。它在工作中是可行的,但不是直接在舞台上(至少目前是这样)。

    stages:
    - stage: A
      jobs:
      - job: JA
        steps:
        - script: |
            echo "This is job Foo."
            echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes" #The variable doThing is set to true
          name: DetermineResult
        - script: echo $(DetermineResult.doThing)
          name: echovar
      - job: JA_2
        dependsOn: JA
        condition: eq(dependencies.JA.outputs['DetermineResult.doThing'], 'Yes')
        steps:
        - script: |
            echo "This is job Bar."
    
    #stage B runs if DetermineResult task set doThing variable n stage A
    - stage: B
      dependsOn: A
      jobs:
      - job: JB
        condition: eq(stageDependencies.A.JA.outputs['DetermineResult.doThing'], 'Yes') #map doThing and check if true
        variables:
          varFromStageA: $[ stageDependencies.A.JA.outputs['DetermineResult.doThing'] ]
        steps:
        - bash: echo "Hello world stage B first job"
        - script: echo $(varFromStageA)
    

    【讨论】:

    • 这似乎不再起作用,因为引用应该是$[ stageDependencies.A.JA.outputs['JA.DetermineResult.doThing'] ]
    【解决方案3】:

    作业现在可以访问之前阶段的变量

    输出变量仍由作业内部的步骤生成。阶段不是引用dependencies.jobName.outputs['stepName.variableName'],而是引用stageDependencies.stageName.jobName.outputs['stepName.variableName']

    https://docs.microsoft.com/en-us/azure/devops/release-notes/2020/sprint-168-update#azure-pipelines-1

    【讨论】:

      【解决方案4】:

      自 2020 年 5 月 4 日起可用

      Jobs can access output variables from previous stages:

      现在可以在基于 YAML 的管道中跨阶段使用输出变量。这可以帮助您将有用的信息从一个阶段传递到下一个阶段,例如通过/不通过决策或生成的输出的 ID。前一阶段的结果(状态)及其作业也是可用的。

      输出变量仍由作业内部的步骤生成。阶段不是引用dependencies.jobName.outputs['stepName.variableName'],而是引用stageDependencies.stageName.jobName.outputs['stepName.variableName']

      注意

      默认情况下,管道中的每个阶段都依赖于 YAML 文件中它之前的阶段。因此,每个阶段都可以使用前一阶段的输出变量。您可以更改依赖关系图,这也将更改可用的输出变量。例如,如果第 3 阶段需要第 1 阶段的变量,则需要声明对第 1 阶段的显式依赖。

      【讨论】:

      • 您从文档中复制的注释帮助了我。我的依赖不起作用,但我没有在前一阶段添加显式依赖
      【解决方案5】:

      对于阶段条件,在带有代理版本 2.153.1 的 Azure DevOps 版本 Dev17.M153.5 上,以下工作:

      stages:
      - stage: A
        jobs:
        - job: JA
          steps:
          - script: |
              echo "This is job Foo."
              echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes" #The variable doThing is set to 'Yes'
            name: DetermineResult
      
      #stage B runs if DetermineResult task set doThing variable on stage A
      - stage: B
        dependsOn: A
        condition: eq(dependencies.A.outputs['JA.DetermineResult.doThing'], 'Yes')
        jobs:
        - job: JB
          steps:
          - bash: echo "Hello world stage B first job"
      
      

      注意:舞台上的属性布局与工作不同:

      dependencies.{stage name}.outputs['{job name}.{script name}.{variable name}']

      注意:带有“stageDependencies”的表达式失败并显示以下错误消息:

      加载 YAML 构建管道时出错。无法识别的值:“stageDependencies”。位于表达式中的位置 XX:and(always(), eq(stageDependencies.A.outputs['JA.DetermineResult.doThing'], 'Yes'))。如需更多帮助,请参考https://go.microsoft.com/fwlink/?linkid=842996

      奖金

      请参阅以下文档了解如何访问相关阶段的状态link

      【讨论】:

      • 以上描述仍然适用于带有代理版本 2.191.1 的 Azure DevOps 服务器版本 2020 更新 1.1(Windows 和 Linux 代理也是如此)
      • 对我来说工作得很好,Azure DevOps(云)/自托管 Linux 代理。警告!!!如本答案所述,请确保使用name: DetermineResult 而不是displayName: DetermineResult。只是浪费了 30 分钟,直到我弄清楚...
      【解决方案6】:

      对于看到此问题的任何人的更新,它似乎在阶段之间传递变量has been implemented and should be released in the next couple of weeks

      【讨论】:

        【解决方案7】:

        您可以定义一个全局变量并使用 Powershell 将阶段变量的值分配给全局变量。

        Write-Output ("##vso[task.setvariable variable=globalVar;]$stageVar")
        

        全局变量既可以在 yaml 本身中定义,也可以在变量组中定义。 用空值初始化 var。

        例如yaml

          variables:
            globalVar: ''
        

        【讨论】:

        • 谢谢!我试试这个。
        • 嘿@zooes 这对你有用吗?我在 GitHub 上发现了这个讨论,似乎唯一的方法是将其保存到 AKV,或者在某处使用数据库/文件 github.com/microsoft/azure-pipelines-tasks/issues/4743
        • @bla9x - 不,它不起作用,因为看起来 MS-ADO 不允许您跨阶段共享变量。你是对的,共享它的唯一方法是 AKV/DB/File。
        • 它为每个作业创建快照。所以globalVar 在一个阶段与globalvar 在不同的工作中是不同的。因此,您可以使用此机制在所有阶段的所有作业中传递相同的值,但不能将值从一个传递到另一个。为此,您应该使用output variable,它可用于跨阶段共享价值(在撰写此评论时)。
        【解决方案8】:

        您可以在定义触发器之后和定义阶段之前定义变量

        trigger:
        - master
          variables:
            VarA: aaaaa
            VarB: bbbbb
        stages:
        - stage: Build  
          jobs:
          - job: Build
            pool:
              vmImage: 'vs2017-win2016'
        

        【讨论】:

        • 查看文档,var 声明位于文件顶部的根级别。当我将它添加到触发器时,我的 vscode 扩展会抛出错误Unexpected property variables
        猜你喜欢
        • 1970-01-01
        • 2021-03-20
        • 2020-10-22
        • 2021-09-12
        • 1970-01-01
        • 2020-07-27
        • 2020-08-13
        • 2022-10-24
        • 2021-01-05
        相关资源
        最近更新 更多