在指令碼中設定變數

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

當您在管線中使用PowerShell和Bash腳本時,通常很適合用來設定變數,然後在未來的工作中使用。 新設定的變數無法在相同的工作中使用。

當您想要執行工作不支援的工作時,例如呼叫自定義 REST API 和剖析回應,腳本非常適合使用。

您將使用task.setvariable記錄命令在 PowerShellBash 腳稿中設定變數。

注意

部署作業會針對輸出變數使用不同的語法。 若要深入瞭解部署作業中輸出變數的支援,請參閱 部署作業

若要在管線中搭配條件使用變數,請參閱 指定條件

關於 task.setvariable

當您使用 task.setvariable新增變數時,下列工作可以使用宏語法 $(myVar)的變數。 根據預設,變數僅適用於相同作業中的工作。 如果您新增 參數 isoutput,則呼叫變數變更的語法。 請參閱 設定輸出變數以用於相同的作業

使用值foo設定 變數myVar

- bash: |
    echo "##vso[task.setvariable variable=myVar;]foo"

讀取變數 myVar

- bash: |
    echo "You can use macro syntax for variables: $(myVar)"

設定變數屬性

此命令 task.setvariable 包含屬性,用來將變數設定為秘密、做為輸出變數,以及設定為唯讀。 可用的屬性包括:

  • variable = 變數名稱 (必要)
  • issecret = 布林值 (選擇性,預設值為 false)
  • isoutput = 布林值 (選擇性,預設值為 false)
  • isreadonly = 布林值 (選擇性,預設值為 false)

若要在下一個階段中使用 變數,請將 isoutput 屬性設定為 true。 若要參考設定為 true 的 isoutput 變數,您將包含工作名稱。 例如: $(TaskName.myVar)

當您將變數設定為唯讀時,下游工作就無法覆寫變數。 將 isreadonly 設定為 true。 將變數設定為唯讀可藉由讓該變數不可變來增強安全性。

將變數設定為秘密

當 設定為 true 時 issecret ,變數的值將會儲存為秘密,並從記錄中遮罩。

注意

Azure Pipelines 會在將數據發出至管線記錄時,努力遮罩秘密,因此您可能會在未設定為秘密的輸出和記錄中看到其他變數和數據遮罩。

設定祕密變數 mySecretVal

- bash: |
    echo "##vso[task.setvariable variable=mySecretVal;issecret=true]secretvalue"

取得秘密變數 mySecretVal

- bash: |
    echo "##vso[task.setvariable variable=mySecretVal;issecret=true]secretvalue"
- bash: |
    echo $(mySecretVal)

bash 中的秘密變數輸出。

bash 變數輸出的螢幕快照。

輸出變數層級

有四種不同類型的輸出變數具有不同的語法:

  • 未使用 參數的相同作業中設定的isoutput輸出變數。 若要參考這些變數,您將使用宏語法。 範例:$(myVar)
  • 使用 參數在相同作業中設定的isoutput輸出變數。 若要參考這些變數,您將包含工作名稱。 範例:$(myTask.myVar)
  • 未來作業中設定的輸出變數。 若要參考這些變數,您將使用dependency語法參考 區段中的 variables 變數。
  • 輸出變數會在未來階段設定。 若要參考這些變數,您將使用stageDependencies語法參考 區段中的 variables 變數。

設定輸出變數以用於相同的作業

當您在相同的作業中使用輸出變數時,不需要使用 isoutput 屬性。 根據預設,變數將可供相同作業內的下游步驟使用。 不過,如果您新增 isoutput 屬性,則必須參考具有工作名稱的變數。

這裡的文稿會設定相同的作業輸出變數 myJobVar ,而不使用 指定 isoutput 和 設定 myOutputJobVarisoutput=true

jobs:
- job: A
  steps:
  - bash: |
     echo "##vso[task.setvariable variable=myJobVar]this is the same job"
  - bash: |
     echo "##vso[task.setvariable variable=myOutputJobVar;isoutput=true]this is the same job too"
    name: setOutput

此文稿會取得相同的作業變數 myJobVarmyOutputJobVar。 請注意,新增一次 isoutput=true 參考輸出變數的語法變更。

jobs:
- job: A
  steps:
  - bash: |
     echo "##vso[task.setvariable variable=myJobVar]this is the same job"
  - bash: |
     echo "##vso[task.setvariable variable=myOutputJobVar;isoutput=true]this is the same job too"
    name: setOutput
  - bash: |
     echo $(myJobVar) 
  - bash: |
     echo $(setOutput.myOutputJobVar)

設定輸出變數以供未來作業使用

當您跨作業使用輸出變數時,您會使用 dependencies來參考它們。 未來作業或階段中存取輸出變數的語法會根據變數的 setter 與取用者之間的關聯性而有所不同。 瞭解相依性中的每個案例。

首先,設定輸出變數 myOutputVar

jobs:
- job: A
  steps:
  - bash: |
     echo "##vso[task.setvariable variable=myOutputVar;isoutput=true]this is from job A"
    name: passOutput

接下來,在未來的作業中存取 myOutputVar ,並將變數輸出為 myVarFromJobA。 若要使用 dependencies,您必須使用設定輸出變數的過去作業名稱,在未來的作業上設定 dependsOn 屬性。

jobs:
- job: A
  steps:
  - bash: |
     echo "##vso[task.setvariable variable=myOutputVar;isoutput=true]this is from job A"
    name: passOutput
- job: B
  dependsOn: A
  variables:
    myVarFromJobA: $[ dependencies.A.outputs['passOutput.myOutputVar'] ]  
  steps:
  - bash: |
     echo $(myVarFromJobA)

設定輸出變數以供未來階段使用

輸出變數可以跨管線中的階段使用。 您可以使用輸出變數,將產生的輸出標識碼等實用資訊從一個階段傳遞至下一個階段。

當您使用 isoutput 屬性設定變數時,可以使用工作名稱和 stageDependencies 語法在後續階段參考該變數。 深入瞭解相 依性

輸出變數只能在下一個下游階段中使用。 如果多個階段使用相同的輸出變數,請使用 dependsOn 條件。

首先,設定輸出變數 myStageVal

steps:
  - bash: echo "##vso[task.setvariable variable=myStageVal;isOutput=true]this is a stage output variable"
    name: MyOutputVar

然後,在未來的階段中,將輸出變數 myStageVal 對應至階段、作業或工作範圍變數,例如 myStageAVar。 請注意,對應語法會使用運行時間表達式$[],並使用階段名稱 (A) 和作業名稱 (A1) 追蹤輸出變數的路徑stageDependencies,以完整限定變數。

stages:
- stage: A
  jobs:
  - job: A1
    steps:
     - bash: echo "##vso[task.setvariable variable=myStageVal;isOutput=true]this is a stage output variable"
       name: MyOutputVar
- stage: B
  dependsOn: A
  jobs:
  - job: B1
    variables:
      myStageAVar: $[stageDependencies.A.A1.outputs['MyOutputVar.myStageVal']]
    steps:
      - bash: echo $(myStageAVar)

如果您的值包含換行符,您可以逸出它們,而且代理程式會自動將其取消逸出:

steps:
- bash: |
    escape_data() {
      local data=$1
      data="${data//'%'/'%AZP25'}"
      data="${data//$'\n'/'%0A'}"
      data="${data//$'\r'/'%0D'}"
      echo "$data"
    }
    echo "##vso[task.setvariable variable=myStageVal;isOutput=true]$(escape_data $'foo\nbar')"
  name: MyOutputVar

常見問題集

我的輸出變數未轉譯。 發生什麼問題?

輸出變數可能不會出現幾個原因。

  • 使用 isoutput 所設定的輸出變數無法在相同的作業中使用,而是只能在下游作業中使用。
  • 根據您使用的變數語法而定,設定輸出變數值的變數可能無法在運行時間使用。 例如,具有宏語法 ($(var)) 的變數會在工作執行之前進行處理。 相反地,具有範本語法的變數會在運行時間處理($[variables.var])。 設定輸出變數時,您通常會想要使用運行時間語法。 如需變數語法的詳細資訊,請參閱 定義變數
  • 表達式中可能會有額外的空格。 如果您的變數未轉譯,請檢查周圍 isOutput=true是否有額外的空格。

您可以針對管線作業或階段的輸出進行疑難解答 dependencies ,方法是新增相依性的變數,然後列印該變數。 例如,在此管線作業 A 中,會設定輸出變數 MyTask。 第二個作業 (B) 取決於工作 A。 新的變數會 deps 保存作業相依性的 JSON 表示法。 作業 B 中的第二個步驟會使用PowerShell列印出來 deps ,讓您可以查看作業相依性。

trigger:
- '*'

pool:
  vmImage: 'ubuntu-latest'
 
jobs:
- job: A
  steps:
    - script: |
        echo "##vso[task.setvariable variable=MyTask;isOutput=true]theoutputval"
      name: ProduceVar  
- job: B
  dependsOn: A
  variables:
    varFromA: $[ dependencies.A.outputs['ProduceVar.MyTask'] ]
    deps: $[convertToJson(dependencies)] # create a variable with the job dependencies
  steps:
  - script: echo $(varFromA) # 
  - powershell: Write-Host "$(deps)"