【问题标题】:Azure DevOps pipelines: Read variable after updating its value in a previous taskAzure DevOps 管道:在上一个任务中更新其值后读取变量
【发布时间】:2021-04-28 02:58:17
【问题描述】:

我的管道中有两个任务 - 第一个是powershell-based task from the marketplace。它使用日志命令(例如Write-Host '##vso[task.setvariable variable=test]abc')更新构建变量,该命令在构建运行中持续存在。您可以在 Azure DevOps 中构建的“变量”部分查看它及其值。

第二个任务是powershell 任务,它使用前一个任务中设置的变量的值,并使用它的值执行操作。它使用 powershell 环境语法,例如$env:TEST.

我遇到的问题是,即使第一个任务正确更新了变量,powershell 任务似乎仍然获得 old 值(就像第一个任务运行之前一样)。

我需要做什么才能让我的 powershell 任务正确读取变量的 new 值?

另外,这是我的 powershell 任务的实际代码(我正在尝试使用 AutoVersion 任务设置的版本变量标记最新的 git 提交,正如你可能知道的那样):

  - powershell: |
      git tag $env:AUTOVERSION
      git push origin $env:AUTOVERSION
    workingDirectory: $(Build.SourcesDirectory)
    displayName: 'Tag Sources'

【问题讨论】:

  • 第二个任务你试过$(test)吗?
  • 是的,我也试过[Environment]::GetEnvironmentVariable("test")。显然这里发生了一些可疑的事情......
  • 我添加了我为第二个任务运行的实际代码的示例。
  • 我添加了一个非常通用的答案来说明环境变量与输出变量的工作方式。

标签: powershell azure-devops-pipelines


【解决方案1】:

好的。让我们打开它。

使用##vso[task.setvariable... 时,您有两种创建变量的选项(忘记本次讨论的秘密)-isOutput=true,而不是。如果isOutput=true,则将其添加到作业的输出中(通过其作业和步骤名称)。如果没有,则将其设置为同一作业中后续步骤的环境变量。

没有isOutput=true,其他作业或阶段无法使用。如果 或 没有它,则该变量在您处于将其写入控制台的任务之外之前不可用(因为变量是通过抓取控制台输出来处理的)。

尝试从以下内容创建管道 - 它展示了如何使用输出与环境变量,如何在同一作业中的步骤之间以及作业之间进行通信:

jobs:
  - job: Job1
    steps:
      - pwsh: |
          
          # isOutput=true makes the variable name accessible via StepName.VarName macro syntax
          Write-Host "##vso[task.setvariable variable=SomeVar;isOutput=true]Hello (output), job 1, step 1"

          # not using isOutput=true makes the variable accessible from the environment
          Write-Host "##vso[task.setvariable variable=SomeEnvVar]Hello (environment), job 1, step 1"
        name: Step1
      - pwsh: |

          Write-Host "##vso[task.setvariable variable=SomeVar;isOutput=true]Hello (output), job 1, step 2"
         
          # This works because Step1.SomeVar has isOutput=true
          Write-Host "Job1Step1OutputVar is $(Step1.SomeVar)"
          
          # The next would fail the step because it doesn't have isOutput=true
          # Write-Host "Job1Step1EnvVar is $(Step1.SomeEnvVar)"
          
          # This works because SomeEnvVar is not declared isOutput=true
          Write-Host "Job1Step1EnvVar is $($Env:SomeEnvVar)"

          # This fails silently (step succeeeds, no value) because SomeVar is declared isOutput=true
          Write-Host "Job1Step1OutputVarAsEnvVar is $($Env:SomeVar)"

        name: Step2
  - job: Job2
    # Prevent the job from running in parallel with Job1
    dependsOn: Job1 
    # you have to map other jobs' outputs into your job with variables
    variables: 
      Job1Step1Var: $[dependencies.Job1.outputs['Step1.SomeVar']]
      Job1Step2Var: $[dependencies.Job1.outputs['Step2.SomeVar']]
    steps:
      - pwsh: |
          Write-Host "##vso[task.setvariable variable=SomeVar;isOutput=true]Hello (output), job 2, step 1"
        name: Step1
      - pwsh: |
          Write-Host "##vso[task.setvariable variable=SomeVar;isOutput=true]Hello (output), job 2, step 2"
          Write-Host "Job1Step1Var is $(Job1Step1Var)"
          Write-Host "Job1Step2Var is $(Job1Step2Var)"
          Write-Host "Job2Step1Var is $(Step1.SomeVar)"
        name: Step2
  - job: Job3
    dependsOn: 
      # Even though Job1 is a dependency of Job2, we have to declare it here to access its output!
      - Job1 
      - Job2
    # you have to map other jobs' outputs into your job with variables
    variables: 
      Job1Step1Var: $[dependencies.Job1.outputs['Step1.SomeVar']]
      Job1Step2Var: $[dependencies.Job1.outputs['Step2.SomeVar']]
      Job2Step1Var: $[dependencies.Job2.outputs['Step1.SomeVar']]
      Job2Step2Var: $[dependencies.Job2.outputs['Step2.SomeVar']]
    steps:
      - pwsh: Write-Host "##vso[task.setvariable variable=SomeVar]Hello (environment), job 3, step 1"
        name: Step1
      - pwsh: |
          Write-Host "Job1Step1Var is $(Job1Step1Var)"
          Write-Host "Job1Step2Var is $(Job1Step2Var)"
          Write-Host "Job2Step1Var is $(Job2Step1Var)"
          Write-Host "Job2Step2Var is $(Job2Step2Var)"
          Write-Host "Job3Step1Var is $($Env:SomeVar)"
        name: Step2 

【讨论】:

  • 谢谢,我已经设法通过 API 检索变量来解决这个问题,就像“AutoVersion”任务一样。感觉有点复杂,但确实有效。
猜你喜欢
  • 2021-11-23
  • 1970-01-01
  • 2019-07-15
  • 2020-07-28
  • 1970-01-01
  • 1970-01-01
  • 2019-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多