Указание заданий в конвейере

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 содержит задание, которое выполняется в агенте, размещенном в Майкрософт , и выводит 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, рекомендуется вместо этого использовать задание развертывания. Задание развертывания имеет ряд преимуществ. Например, вы можете выполнить развертывание в среде, которая включает такие преимущества, как возможность просматривать журнал развернутых объектов.

YAML не поддерживается в TFS.

Типы заданий

Задания могут быть разных типов в зависимости от того, где они выполняются.

  • Задания пула агентов выполняются агентом в пуле агентов.
  • Задания сервера выполняются на сервере Azure DevOps Server.
  • Задания контейнера выполняются в контейнере с помощью агента в пуле агентов. Дополнительные сведения о выборе контейнеров см. в разделе Определение заданий контейнеров.
  • Задания пула агентов выполняются агентом в пуле агентов.
  • Задания сервера выполняются на сервере Azure DevOps Server.
  • Задания пула агентов выполняются на агенте в пуле агентов. Эти задания доступны в конвейерах сборки и выпуска.
  • Задания сервера выполняются в TFS. Эти задания доступны в конвейерах сборки и выпуска.
  • Задания группы развертывания выполняются на компьютерах в группе развертывания. Эти задания доступны только в конвейерах выпуска.

Задания пула агентов

Это наиболее распространенный тип заданий, которые выполняются на агенте в пуле агентов.

  • При использовании размещенных агентов Майкрософт каждое задание в конвейере получает новый агент.
  • Используйте требования с локальными агентами, чтобы указать, какие возможности должны быть у агента для выполнения задания. Вы можете получить один и тот же агент для последовательных заданий в зависимости от того, есть ли в пуле агентов несколько агентов, соответствующих требованиям конвейера. Если в пуле есть только один агент, который соответствует требованиям конвейера, конвейер будет ожидать, пока этот агент не станет доступным.

Примечание

Требования и возможности предназначены для использования с локальными агентами, чтобы задания можно было сопоставить с агентом, отвечающим требованиям задания. При использовании агентов, размещенных в Майкрософт, вы выбираете образ агента, соответствующий требованиям задания, поэтому, хотя можно добавить возможности в агент, размещенный в Майкрософт, вам не нужно использовать возможности с агентами, размещенными в Майкрософт.

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

YAML не поддерживается в TFS.

Узнайте больше о возможностях агента.

Задания сервера

Задачи в задании сервера оркестрируются и выполняются на сервере (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

YAML не поддерживается в TFS.

Зависимости

При определении нескольких заданий на одном этапе можно указать зависимости между ними. Конвейеры должны содержать по крайней мере одно задание без зависимостей. По умолчанию задания конвейера YAML Azure DevOps будут выполняться параллельно, если dependsOn не задано значение .

Примечание

Каждый агент может выполнять только одно задание одновременно. Для параллельного выполнения нескольких заданий необходимо настроить несколько агентов. Вам также требуется достаточное количество параллельных заданий.

Синтаксис для определения нескольких заданий и их зависимостей:

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

YAML не поддерживается в TFS.

Условия

Вы можете указать условия для выполнения каждого задания. По умолчанию задание выполняется, если оно не зависит от какого-либо другого задания или если все задания, от которых оно зависит, завершились и успешно завершились. Это поведение можно настроить путем принудительного выполнения задания, даже если предыдущее задание завершается сбоем, или путем указания настраиваемого условия.

Пример запуска задания на основе состояния выполнения предыдущего задания:

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/main'))
  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

YAML не поддерживается в TFS.

Истекшее время ожидания

Чтобы не занимать ресурсы, когда задание не отвечает или слишком долго ожидается, рекомендуется установить ограничение на продолжительность выполнения задания. Используйте параметр времени ожидания задания, чтобы указать ограничение в минутах для выполнения задания. Установка нулевого значения означает, что задание может выполняться:

  • Навсегда на локальных агентах
  • В течение 360 минут (6 часов) на размещенных в Майкрософт агентах с общедоступным проектом и общедоступный репозиторий
  • В течение 60 минут на размещенных в Майкрософт агентах с частным проектом или частным репозиторием (если не оплачивается дополнительная емкость )

Время ожидания начинается с запуска задания. Он не включает время постановки задания в очередь или ожидания агента.

Позволяет timeoutInMinutes установить ограничение на время выполнения задания. Если значение не указано, значение по умолчанию составляет 60 минут. При 0 указании используется максимальное ограничение (описано выше).

Позволяет cancelTimeoutInMinutes установить ограничение на время отмены задания, когда задача развертывания будет продолжать выполняться в случае сбоя предыдущей задачи. Если значение не указано, значение по умолчанию — 5 минут. Значение должно находиться в диапазоне от 1 до 35790 минут.

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

YAML не поддерживается в TFS.

Задания, предназначенные для агентов, размещенных в Майкрософт, имеют дополнительные ограничения на срок их выполнения.

Вы также можете задать время ожидания для каждой задачи по отдельности. См. раздел Параметры управления задачами.

Настройка нескольких заданий

Из одного задания, который вы создаете, можно параллельно выполнять несколько заданий на нескольких агентах. Некоторые примеры:

  • Сборки с несколькими конфигурациями: Вы можете создавать несколько конфигураций параллельно. Например, можно создать приложение Visual C++ для debug конфигураций и release на x86 платформах и x64 . Дополнительные сведения см. в статье Сборка Visual Studio — несколько конфигураций для нескольких платформ.

  • Развертывания с несколькими конфигурациями: Параллельно можно выполнять несколько развертываний, например в разных географических регионах.

  • Тестирование с несколькими конфигурациями: Вы можете запустить параллельное тестирование нескольких конфигураций.

  • С несколькими конфигурациями всегда создается по крайней мере одно задание, даже если переменная с несколькими конфигурациями пуста.

Стратегия matrix позволяет многократно отправлять задание с разными наборами переменных. Тег maxParallel ограничивает количество параллелизма. Следующее задание будет отправлено три раза с заданными значениями Location и Browser. Однако одновременно будут выполняться только два задания.

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

YAML не поддерживается в TFS.

Фрагментирование

Задание агента можно использовать для параллельного выполнения набора тестов. Например, можно запустить большой набор из 1000 тестов на одном агенте. Кроме того, можно использовать два агента и параллельно выполнять 500 тестов для каждого из них.

Чтобы использовать срезы, задачи в задании должны быть достаточно умными, чтобы понять, к какому срезу они относятся.

Тестовая задача Visual Studio является одной из таких задач, которая поддерживает тестовые срезы. Если установлено несколько агентов, можно указать, как задача Тестирования Visual Studio будет выполняться параллельно на этих агентах.

Стратегия parallel позволяет многократно дублировать задание. Переменные System.JobPositionInPhase и System.TotalJobsInPhase добавляются в каждое задание. Затем переменные можно использовать в скриптах для разделения работы между заданиями. См. раздел Параллельное и несколько выполнений с помощью заданий агента.

Следующее задание будет отправлено пять раз со значениями System.JobPositionInPhase и System.TotalJobsInPhase соответствующим образом задано.

jobs:
- job: Test
  strategy:
    parallel: 5

YAML не поддерживается в TFS.

Переменные задания

Если вы используете 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"

YAML не поддерживается в TFS.

Сведения об использовании условия см. в разделе Указание условий.

Рабочая область

При запуске задания пула агентов создается рабочая область на агенте. Рабочая область — это каталог, в котором она скачивает источник, выполняет шаги и создает выходные данные. На каталог рабочей области можно ссылаться в задании с помощью Pipeline.Workspace переменной . В этом разделе создаются различные подкаталоги:

При запуске задания пула агентов создается рабочая область на агенте. Рабочая область — это каталог, в котором она скачивает источник, выполняет шаги и создает выходные данные. На каталог рабочей области можно ссылаться в задании с помощью Agent.BuildDirectory переменной . В этом разделе создаются различные подкаталоги:

  • Build.SourcesDirectory — это место, где задачи скачивает исходный код приложения.
  • Build.ArtifactStagingDirectory — это место, где задачи загружают артефакты, необходимые для конвейера, или передают артефакты перед их публикацией.
  • Build.BinariesDirectory — это место, где задачи записывают свои выходные данные.
  • Common.TestResultsDirectory — это место, где задачи отправляют свои результаты тестирования.

И $(Build.ArtifactStagingDirectory)$(Common.TestResultsDirectory) всегда удаляются и повторно создаются перед каждой сборкой.

При запуске конвейера в локальном агенте по умолчанию ни один из подкаталогов, кроме $(Build.ArtifactStagingDirectory) и $(Common.TestResultsDirectory) , не очищается между двумя последовательными запусками. В результате можно выполнять добавочные сборки и развертывания при условии, что для использования этих задач реализованы задачи. Это поведение можно переопределить с помощью workspace параметра в задании.

Важно!

Параметры очистки рабочей области применимы только для локальных агентов. При использовании агентов, размещенных в Майкрософт, задания всегда выполняются в новом агенте.

- 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

Примечание

В зависимости от возможностей агента и требований конвейера каждое задание может быть перенаправлено в другой агент в локальном пуле. В результате вы можете получить новый агент для последующих запусков конвейера (или этапов или заданий в том же конвейере), поэтому отсутствие очистки не гарантирует, что последующие запуски, задания или этапы смогут получить доступ к выходным данным предыдущих запусков, заданий или этапов. Вы можете настроить возможности агента и требования конвейера, чтобы указать, какие агенты используются для запуска задания конвейера, но если в пуле нет только одного агента, удовлетворяющего требованиям, нет никакой гарантии, что последующие задания будут использовать тот же агент, что и предыдущие задания. Дополнительные сведения см. в разделе Указание требований.

Помимо очистки рабочей области можно также настроить очистку, настроив параметр Очистить в пользовательском интерфейсе параметров конвейера. Если параметр Clean имеет значение true, которое также является значением по умолчанию, это эквивалентно указанию для каждого шага оформленияclean: true в конвейере. Если вы укажете clean: true, перед получением git reset --hard HEAD git выполните git clean -ffdx команду . Чтобы настроить параметр Clean, выполните следующие действия.

  1. Измените конвейер, выберите ..., а затем — Триггеры.

    Изменить триггеры.

  2. Выберите YAML, Получить источники и настройте нужный параметр Очистка . Значение по умолчанию — true.

    Параметр очистки.

YAML не поддерживается в TFS.

Скачивание артефакта

В этом примере yaml-файла публикуется артефакт WebSite , а затем он загружается в $(Pipeline.Workspace). Задание Deploy запускается только в том случае, если задание сборки выполнено успешно.

# 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()

YAML не поддерживается в TFS.

Сведения об использовании dependsOn и условия см. в разделе Указание условий.

Доступ к токену OAuth

Вы можете разрешить скриптам, выполняемым в задании, доступ к текущему маркеру безопасности Azure Pipelines или TFS OAuth. Маркер можно использовать для проверки подлинности в REST API Azure Pipelines.

Маркер 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)

YAML не поддерживается в TFS.

Что дальше?