指定管線中的作業

Azure Pipelines |Azure DevOps Server 2020 |Azure DevOps Server 2019 |TFS 2018 |TFS 2017

注意

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

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

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

注意

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

您可以將發行管線組織成工作。 每個發行管線至少都有一項作業。 在此版本的 TFS 中,組建管線不支援作業。

注意

您必須安裝 Update 2,才能在 TFS 2017 的發行管線中使用工作。 組建管線中的作業可在 Azure Pipelines、TFS 2018.2 和更新版本中使用。

定義單一作業

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

這個 YAML 檔具有在 Microsoft 裝載的 代理程式 和輸出上執行的作業

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 ,但建議您改為使用 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

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

jobs:
- job: string
  pool: server

TFS 中尚不支援 YAML。

相依性

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

注意

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

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

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 裝載的代理程式上, (6 小時的360分鐘) 公用專案和公用存放庫
  • 在具有私人專案或私人存放庫的 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 裝載的代理程式為目標的工作,對其執行的時間長度會有 額外的限制

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

多工設定

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

  • 多重設定組建: 您可以平行建立多個設定。 例如,您可以針對和平臺上的和設定建立 Visual C++ 應用程式 debugreleasex86x64 。 若要深入瞭解,請參閱Visual Studio 組建-多個平臺的多個設定。

  • 多重設定部署: 例如,您可以平行執行多個部署,例如到不同的地理區域。

  • 多重設定測試: 您可以平行執行多個設定測試。

  • 即使多重設定變數是空的,多重設定一律會產生至少一項作業。

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 將接受包含 stringified JSON 物件的運行時程表達式。 展開時,該 JSON 物件必須符合 matrixing 語法。 在下列範例中,我們已將 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.JobPositionInPhase ,並 System.TotalJobsInPhase 適當地設定的值。

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) 不會在兩個連續執行之間清除和以外的任何子目錄。 如此一來,您就可以執行累加的組建和部署,但前提是這些工作都是為了利用而執行。 您可以使用作業的設定來覆寫此行為 workspace

重要

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

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

當您指定其中一個 clean 選項時,它們會解讀如下:

  • outputsBuild.BinariesDirectory 先刪除再執行新的作業。
  • resourcesBuild.SourcesDirectory 先刪除再執行新的作業。
  • all:先刪除整個 Pipeline.Workspace 目錄,再執行新的作業。
  jobs:
  - deployment: deploy
    pool:
      vmImage: 'ubuntu-latest'
    workspace:
      clean: all
    environment: staging

注意

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

除了工作區清除以外,您也可以設定 [管線設定] UI 中的 [ 清除 ] 設定來進行清除。 當 清除 設定為 true 時,相當於 針對管線中的每個 簽出 步驟指定。 若要設定 清除 設定:

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

    Edit triggers.

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

    Clean setting.

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。

後續步驟