在管線中指定作業

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

注意

在 Microsoft Team Foundation Server (TFS) 2018 和舊版中,組建和發行管線稱為定義、執行稱為組建服務連線稱為服務端點階段稱為環境,而作業稱為階段

您可以將管線組織成作業。 每個管線至少有一個作業。 作業是一系列以單位循序執行的步驟。 換句話說,作業是可以排程執行之最小工作單位。

您可以將組建或發行管線組織成作業。 每個管線至少有一個作業。 作業是一系列以單位循序執行的步驟。 換句話說,作業是可以排程執行之最小工作單位。

注意

您必須安裝 TFS 2018.2,才能在建置程式中使用作業。 在 TFS 2018 RTM 中,您可以在發行部署程式中使用作業。

定義單一作業

在最簡單的案例中,管線具有單一作業。 在此情況下,除非您使用範本,否則您不需要明確使用 job 關鍵字。 您可以直接指定 YAML 檔案中的步驟。

此 YAML 檔案具有在裝載Microsoft代理程式上執行的作業,並輸出 Hello world

pool:
  vmImage: 'ubuntu-latest'
steps:
- bash: echo "Hello world"

您可能想要在該作業上指定其他屬性。 在此情況下,您可以使用 job 關鍵字。

jobs:
- job: myJob
  timeoutInMinutes: 10
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - bash: echo "Hello world"

您的管線可能會有多個作業。 在此情況下,請使用 jobs 關鍵字。

jobs:
- job: A
  steps:
  - bash: echo "A"

- job: B
  steps:
  - bash: echo "B"

您的管線可能會有多個階段,每個階段都有多個作業。 在此情況下,請使用 stages 關鍵字。

stages:
- stage: A
  jobs:
  - job: A1
  - job: A2

- stage: B
  jobs:
  - job: B1
  - job: B2

指定作業的完整語法為:

- job: string  # name of the job, A-Z, a-z, 0-9, and underscore
  displayName: string  # friendly name to display in the UI
  dependsOn: string | [ string ]
  condition: string
  strategy:
    parallel: # parallel strategy
    matrix: # matrix strategy
    maxParallel: number # maximum number simultaneous matrix legs to run
    # note: `parallel` and `matrix` are mutually exclusive
    # you may specify one or the other; including both is an error
    # `maxParallel` is only valid with `matrix`
  continueOnError: boolean  # 'true' if future jobs should run even if this job fails; defaults to 'false'
  pool: pool # agent pool
  workspace:
    clean: outputs | resources | all # what to clean up before the job runs
  container: containerReference # container to run this job inside
  timeoutInMinutes: number # how long to run the job before automatically cancelling
  cancelTimeoutInMinutes: number # how much time to give 'run always even if cancelled tasks' before killing them
  variables: { string: string } | [ variable | variableReference ] 
  steps: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
  services: { string: string | container } # container resources to run as a service container

指定作業的完整語法為:

- job: string  # name of the job, A-Z, a-z, 0-9, and underscore
  displayName: string  # friendly name to display in the UI
  dependsOn: string | [ string ]
  condition: string
  strategy:
    parallel: # parallel strategy
    matrix: # matrix strategy
    maxParallel: number # maximum number simultaneous matrix legs to run
    # note: `parallel` and `matrix` are mutually exclusive
    # you may specify one or the other; including both is an error
    # `maxParallel` is only valid with `matrix`
  continueOnError: boolean  # 'true' if future jobs should run even if this job fails; defaults to 'false'
  pool: pool # agent pool
  workspace:
    clean: outputs | resources | all # what to clean up before the job runs
  container: containerReference # container to run this job inside
  timeoutInMinutes: number # how long to run the job before automatically cancelling
  cancelTimeoutInMinutes: number # how much time to give 'run always even if cancelled tasks' before killing them
  variables: { string: string } | [ variable | variableReference ] 
  steps: [ script | bash | pwsh | powershell | checkout | task | templateReference ]
  services: { string: string | container } # container resources to run as a service container
  uses: # Any resources (repos or pools) required by this job that are not already referenced
    repositories: [ string ] # Repository references to Azure Git repositories
    pools: [ string ] # Pool names, typically when using a matrix strategy for the job

如果作業的主要目的是要部署應用程式 (,而不是建置或測試應用程式) ,您可以使用稱為 部署作業的特殊作業類型。

部署作業的語法如下:

- deployment: string        # instead of job keyword, use deployment keyword
  pool:
    name: string
    demands: string | [ string ]
  environment: string
  strategy:
    runOnce:
      deploy:
        steps:
        - script: echo Hi!

雖然您可以在 中 job 新增部署工作的步驟,但建議您改用 部署作業。 部署作業有幾個優點。 例如,您可以部署到環境,其中包括優點,例如能夠查看您已部署專案的歷程記錄。

TFS 不支援 YAML。

作業類型

作業可以是不同類型的作業,視其執行位置而定。

  • 代理程式集區作業執行於代理程式集區中的代理程式上。
  • 伺服器作業執行於 Azure DevOps Server 上。
  • 容器作業 會在代理程式組件區中代理程式的容器中執行。 如需選擇容器的詳細資訊,請參閱 定義容器作業
  • 代理程式集區作業執行於代理程式集區中的代理程式上。
  • 伺服器作業執行於 Azure DevOps Server 上。
  • 代理程式組件區作業 會在代理程式組件區的代理程式上執行。 這些作業可在組建和發行管線中使用。
  • 伺服器作業 會在 TFS 上執行。 這些作業可在組建和發行管線中使用。
  • 部署群組作業執行於部署群組中的機器上。 這些作業僅適用于發行管線。

代理程式集區作業

這些是最常見的作業類型,而且會在代理程式組件區的代理程式上執行。

  • 使用Microsoft裝載的代理程式時,管線中的每個作業都會取得全新的代理程式。
  • 搭配自我裝載代理程式使用 需求 ,以指定代理程式必須執行作業的功能。 您可以針對連續作業取得相同的代理程式,視代理程式組件區中是否有一個以上的代理程式符合管線的需求而定。 如果您的集區中只有一個符合管線需求的代理程式,管線會等到此代理程式可供使用。

注意

需求和功能是設計來搭配自我裝載代理程式使用,讓作業可以與符合作業需求的代理程式相符。 使用Microsoft裝載的代理程式時,您可以為符合作業需求的代理程式選取映射,因此雖然可以將功能新增至Microsoft裝載的代理程式,但不需要搭配Microsoft裝載的代理程式使用功能。

pool:
  name: myPrivateAgents    # your job runs on an agent in this pool
  demands: agent.os -equals Windows_NT    # the agent must have this capability to run the job
steps:
- script: echo hello world

或多個需求:

pool:
  name: myPrivateAgents
  demands:
  - agent.os -equals Darwin
  - anotherCapability -equals somethingElse
steps:
- script: echo hello world

TFS 不支援 YAML。

深入瞭解 代理程式功能

伺服器作業

伺服器作業中的工作會藉由協調並在伺服器上執行, (Azure Pipelines 或 TFS) 。 伺服器作業不需要代理程式或任何目的電腦。 目前伺服器作業只支援一些工作。

無代理程式作業支援的工作

目前,無代理程式作業僅支援下列工作:

因為工作是可延伸的,所以您可以使用擴充功能來新增更多無代理程式工作。 無代理程式作業的預設逾時為 60 分鐘。

指定伺服器作業的完整語法為:

jobs:
- job: string
  timeoutInMinutes: number
  cancelTimeoutInMinutes: number
  strategy:
    maxParallel: number
    matrix: { string: { string: string } }

  pool: server # note: the value 'server' is a reserved keyword which indicates this is an agentless job

您也可以使用簡化的語法:

jobs:
- job: string
  pool: server # note: the value 'server' is a reserved keyword which indicates this is an agentless job

TFS 不支援 YAML。

相依性

當您在單一階段中定義多個作業時,可以指定它們之間的相依性。 管線至少必須包含一個沒有相依性的作業。

注意

每個代理程式一次只能執行一個作業。 若要平行執行多個作業,您必須設定多個代理程式。 您也需要足夠的 平行作業

定義多個作業及其相依性的語法如下:

jobs:
- job: string
  dependsOn: string
  condition: string

循序建置的範例作業:

jobs:
- job: Debug
  steps:
  - script: echo hello from the Debug build
- job: Release
  dependsOn: Debug
  steps:
  - script: echo hello from the Release build

以平行方式建置 (無相依性的範例作業) :

jobs:
- job: Windows
  pool:
    vmImage: 'windows-latest'
  steps:
  - script: echo hello from Windows
- job: macOS
  pool:
    vmImage: 'macOS-latest'
  steps:
  - script: echo hello from macOS
- job: Linux
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - script: echo hello from Linux

展開的範例:

jobs:
- job: InitialJob
  steps:
  - script: echo hello from initial job
- job: SubsequentA
  dependsOn: InitialJob
  steps:
  - script: echo hello from subsequent A
- job: SubsequentB
  dependsOn: InitialJob
  steps:
  - script: echo hello from subsequent B

風扇的範例:

jobs:
- job: InitialA
  steps:
  - script: echo hello from initial A
- job: InitialB
  steps:
  - script: echo hello from initial B
- job: Subsequent
  dependsOn:
  - InitialA
  - InitialB
  steps:
  - script: echo hello from subsequent

TFS 不支援 YAML。

條件

您可以指定每個作業據以執行的條件。 根據預設,如果作業不相依于任何其他作業,或它相依的所有作業都已完成且成功,則會執行作業。 您可以強制作業執行此行為,即使先前的作業失敗或指定自訂條件也一樣。

根據執行上一個作業的狀態來執行作業的範例:

jobs:
- job: A
  steps:
  - script: exit 1

- job: B
  dependsOn: A
  condition: failed()
  steps:
  - script: echo this will run when A fails

- job: C
  dependsOn:
  - A
  - B
  condition: succeeded('B')
  steps:
  - script: echo this will run when B runs and succeeds

使用 自訂條件的範例:

jobs:
- job: A
  steps:
  - script: echo hello

- job: B
  dependsOn: A
  condition: and(succeeded(), eq(variables['build.sourceBranch'], 'refs/heads/master'))
  steps:
  - script: echo this only runs for master

您可以根據上一個作業中設定的輸出變數值來指定作業執行。 在此情況下,您只能使用直接相依作業中設定的變數:

jobs:
- job: A
  steps:
  - script: "echo ##vso[task.setvariable variable=skipsubsequent;isOutput=true]false"
    name: printvar

- job: B
  condition: and(succeeded(), ne(dependencies.A.outputs['printvar.skipsubsequent'], 'true'))
  dependsOn: A
  steps:
  - script: echo hello from B

TFS 不支援 YAML。

逾時

為了避免在作業沒有回應或等候太長時佔用資源,最好設定允許工作執行多久的限制。 使用作業逾時設定來指定執行作業的分鐘數限制。 將值設定為 表示作業可以執行:

  • 永遠在自我裝載代理程式上
  • 在具有公用專案和公用存放庫的Microsoft裝載代理程式的 360 分鐘 (6 小時)
  • 在具有私人專案或私人存放庫的Microsoft裝載代理程式上, (60 分鐘,除非為) 支付額外的容量

當作業開始執行時,逾時期間就會開始。 它不包含作業排入佇列或正在等候代理程式的時間。

timeoutInMinutes允許設定作業執行時間的限制。 未指定時,預設值為 60 分鐘。 指定時 0 ,會使用上述限制上限 () 。

cancelTimeoutInMinutes允許在部署工作設定為在先前的工作失敗時,為繼續執行作業取消時間設定限制。 未指定時,預設值為 5 分鐘。 此值的範圍應介於 135790 分鐘之間。

jobs:
- job: Test
  timeoutInMinutes: 10 # how long to run the job before automatically cancelling
  cancelTimeoutInMinutes: 2 # how much time to give 'run always even if cancelled tasks' before stopping them

TFS 不支援 YAML。

以Microsoft裝載代理程式為目標的作業會限制其執行時間長度。

您也可以個別設定每個工作的逾時 - 請參閱 工作控制選項

多作業組態

從您撰寫的單一作業中,您可以平行在多個代理程式上執行多個作業。 部分範例包括:

  • 多組態組建: 您可以平行建置多個組態。 例如,您可以針對 和 平臺上的 和 releasex64x86 建置 Visual C++ 應用程式 debug 。 若要深入瞭解,請參閱 Visual Studio Build - 多個平臺的多個組態

  • 多組態部署: 例如,您可以平行執行多個部署至不同的地理區域。

  • 多重組態測試: 您可以平行執行多個組態。

  • 多組態一律會產生至少一個作業,即使多組態變數是空的。

matrix 策略可讓作業分派多次,並設定不同的變數集。 標記 maxParallel 會限制平行處理原則的數量。 下列作業會分派三次,並指定 [位置] 和 [瀏覽器] 的值。 不過,只有兩個作業會同時執行。

jobs:
- job: Test
  strategy:
    maxParallel: 2
    matrix: 
      US_IE:
        Location: US
        Browser: IE
      US_Chrome:
        Location: US
        Browser: Chrome
      Europe_Chrome:
        Location: Europe
        Browser: Chrome

注意

矩陣組態名稱 (如 US_IE 上述) 必須只包含 A-Z、a-z) 、數位和底線 _ () 的基本拉丁 (字母字母。 這些名稱必須以字母開頭。 此外,它們必須是 100 個字元或更少。

您也可以使用 輸出變數 來產生矩陣。 如果您需要使用腳本來產生矩陣,這很有用。

matrix 將接受包含字串化 JSON 物件的運行時程表達式。 展開時,該 JSON 物件必須符合矩陣語法。 在下列範例中,我們已硬式編碼 JSON 字串,但可由指令碼語言或命令列程式產生。

jobs:
- job: generator
  steps:
  - bash: echo "##vso[task.setVariable variable=legs;isOutput=true]{'a':{'myvar':'A'}, 'b':{'myvar':'B'}}"
    name: mtrx
  # This expands to the matrix
  #   a:
  #     myvar: A
  #   b:
  #     myvar: B
- job: runner
  dependsOn: generator
  strategy:
    matrix: $[ dependencies.generator.outputs['mtrx.legs'] ]
  steps:
  - script: echo $(myvar) # echos A or B depending on which leg is running

TFS 不支援 YAML。

切片

代理程式作業可用來平行執行一組測試。 例如,您可以在單一代理程式上執行 1000 個測試的大型套件。 或者,您可以使用兩個代理程式,並在每一個代理程式上平行執行 500 個測試。

若要利用配量,作業中的工作應該夠聰明,才能瞭解其所屬的配量。

Visual Studio 測試工作是支援測試配量的工作之一。 如果您已安裝多個代理程式,您可以指定 Visual Studio 測試工作如何在這些代理程式上平行執行。

parallel 策略可讓作業重複多次。 變數 System.JobPositionInPhaseSystem.TotalJobsInPhase 會新增至每個作業。 然後,您可以在腳本內使用變數,將工作分割成作業。 請參閱 使用代理程式作業進行平行和多重執行

下列作業將會分派五次,並適當地設定 和 System.TotalJobsInPhase 的值 System.JobPositionInPhase

jobs:
- job: Test
  strategy:
    parallel: 5

TFS 不支援 YAML。

作業變數

如果您使用 YAML,可以在作業上指定變數。 您可以使用宏語法 $ (variableName) ,或使用階段變數在腳本中存取變數,將變數傳遞至工作輸入。

以下是在作業中定義變數並在工作中使用這些變數的範例。

variables:
  mySimpleVar: simple var value
  "my.dotted.var": dotted var value
  "my var with spaces": var with spaces value

steps:
- script: echo Input macro = $(mySimpleVar). Env var = %MYSIMPLEVAR%
  condition: eq(variables['agent.os'], 'Windows_NT')
- script: echo Input macro = $(mySimpleVar). Env var = $MYSIMPLEVAR
  condition: in(variables['agent.os'], 'Darwin', 'Linux')
- bash: echo Input macro = $(my.dotted.var). Env var = $MY_DOTTED_VAR
- powershell: Write-Host "Input macro = $(my var with spaces). Env var = $env:MY_VAR_WITH_SPACES"

TFS 不支援 YAML。

如需使用 條件的相關資訊,請參閱 指定條件

工作區

當您執行代理程式組件區作業時,它會在代理程式上建立工作區。 工作區是下載來源、執行步驟並產生輸出的目錄。 工作區目錄可以使用 變數在作業 Pipeline.Workspace 中參考。 在此下,會建立各種子目錄:

當您執行代理程式組件區作業時,它會在代理程式上建立工作區。 工作區是下載來源、執行步驟並產生輸出的目錄。 工作區目錄可以使用 變數在作業 Agent.BuildDirectory 中參考。 在此下,會建立各種子目錄:

  • Build.SourcesDirectory 是工作下載應用程式原始程式碼的位置。
  • Build.ArtifactStagingDirectory 是工作在發佈之前下載管線或上傳成品所需的成品的位置。
  • Build.BinariesDirectory 是工作寫入其輸出的位置。
  • Common.TestResultsDirectory 是工作上傳其測試結果的位置。

$(Build.ArtifactStagingDirectory)$(Common.TestResultsDirectory) 一律會在每次建置之前刪除並重新建立。

當您在自我裝載代理程式上執行管線時,預設不會在兩個連續執行之間清除 和 $(Common.TestResultsDirectory) 以外的 $(Build.ArtifactStagingDirectory) 子目錄。 因此,您可以執行累加建置和部署,前提是已實作工作以使用該工作。 您可以使用作業上的 設定來覆寫此行為 workspace

重要

工作區清除選項僅適用于自我裝載代理程式。 使用Microsoft裝載的代理程式時,作業一律會在新的代理程式上執行。

- job: myJob
  workspace:
    clean: outputs | resources | all # what to clean up before the job runs

當您指定其中一個選項時 clean ,這些選項會解譯如下:

  • outputs:在執行新作業之前先刪除 Build.BinariesDirectory
  • resources:在執行新作業之前先刪除 Build.SourcesDirectory
  • all:在執行新作業之前,請先刪除整個 Pipeline.Workspace 目錄。
  jobs:
  - deployment: MyDeploy
    pool:
      vmImage: 'ubuntu-latest'
    workspace:
      clean: all
    environment: staging

注意

根據您的代理程式功能和管線需求,每個作業都可以路由傳送至自我裝載集區中的不同代理程式。 因此,您可能會為相同管線) (或階段或作業取得後續管線執行的新代理程式,因此 保證後續執行、作業或階段能夠存取先前執行、作業或階段的輸出。 您可以設定代理程式功能和管線需求來指定用來執行管線作業的代理程式,但除非集區中只有符合需求的單一代理程式,否則不保證後續作業會使用與先前作業相同的代理程式。 如需詳細資訊,請參閱 指定需求

除了工作區清除之外,您也可以在管線設定 UI 中設定 [清除 ] 設定來設定清除。 當 [清除] 設定為 true時,這也是其預設值,相當於指定 clean: true 管線中的每個 簽出 步驟。 當您指定 clean: true 時,會在 Git 擷取之前執行 git clean -ffdx ,後面接著 git reset --hard HEAD 執行 。 若要設定 [清除] 設定:

  1. 編輯您的管線,選擇 ...,然後選取 [觸發程式]。

    編輯觸發程式。

  2. 選取 [YAML]、[ 取得來源],然後設定您想要的 [清除 ] 設定。 預設值為 True

    清除設定。

TFS 不支援 YAML。

成品下載

這個範例 YAML 檔案會發佈成品 WebSite ,然後將成品下載至 $(Pipeline.Workspace) 。 只有在建置作業成功時,部署作業才會執行。

# test and upload my code as an artifact named WebSite
jobs:
- job: Build
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - script: npm test
  - task: PublishBuildArtifacts@1
    inputs:
      pathtoPublish: '$(System.DefaultWorkingDirectory)'
      artifactName: WebSite

# download the artifact and deploy it only if the build job succeeded
- job: Deploy
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - checkout: none #skip checking out the default repository resource
  - task: DownloadBuildArtifacts@0
    displayName: 'Download Build Artifacts'
    inputs:
      artifactName: WebSite
      downloadPath: $(System.DefaultWorkingDirectory)

  dependsOn: Build
  condition: succeeded()

TFS 不支援 YAML。

如需使用 dependsOn條件的相關資訊,請參閱 指定條件

OAuth 權杖的存取權

您可以允許在作業中執行的腳本存取目前的 Azure Pipelines 或 TFS OAuth 安全性權杖。 權杖可用來向 Azure Pipelines REST API 進行驗證。

OAuth 權杖一律可供 YAML 管線使用。 它必須使用 明確地對應至工作或步驟 env 。 以下為範例:

steps:
- powershell: |
    $url = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/build/definitions/$($env:SYSTEM_DEFINITIONID)?api-version=4.1-preview"
    Write-Host "URL: $url"
    $pipeline = Invoke-RestMethod -Uri $url -Headers @{
      Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
    }
    Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"
  env:
    SYSTEM_ACCESSTOKEN: $(system.accesstoken)

TFS 不支援 YAML。

後續步驟