Поделиться через


Справочник по использованию шаблона

Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019

Шаблоны позволяют определять повторное использование содержимого, логики и параметров в конвейерах YAML. Для эффективной работы с шаблонами необходимо иметь базовое представление о основных понятиях Azure Pipelines, таких как этапы, шаги и задания.

Шаблоны помогут ускорить разработку. Например, в шаблоне можно выполнить ряд одних и тех же задач, а затем включить шаблон несколько раз в разные этапы конвейера YAML.

Шаблоны также помогают защитить конвейер. Когда шаблон управляет допустимым в конвейере, шаблон определяет логику, которую должен следовать другой файл. Например, вы можете захотеть ограничить, какие задачи разрешено выполнять. В этом сценарии можно использовать шаблон, чтобы предотвратить успешное выполнение задачи, которая нарушает политики безопасности организации.

Существует два типа шаблонов: включает и расширяет.

  • Включает шаблоны , позволяющие вставлять повторно используемый контент с помощью шаблона. Если шаблон используется для включения содержимого, он работает как директива include во многих языках программирования. Содержимое из шаблона вставляется в конвейер или шаблон, который включает его.
  • расширяющие шаблоны позволяют управлять тем, что разрешено в конвейере. Когда шаблон расширений управляет тем, что разрешено в конвейере, шаблон определяет логику, которой должен следовать конвейер. Например, шаблон расширения можно использовать в контексте расширения конвейера для выполнения этапов или заданий.

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

Введенные ограничения

Шаблоны и выражения шаблонов могут привести к значительному увеличению размера и сложности конвейера. Чтобы предотвратить рост запуска, Azure Pipelines накладывает следующие ограничения:

  • Не более 100 отдельных файлов YAML можно включить (прямо или косвенно)
  • Допускается не более 20 уровней вложенности шаблонов (шаблонов, включающих другие шаблоны)
  • При анализе YAML не более 10 мб памяти (на практике это обычно составляет от 600 КБ до 2 МБ из YAML на диске в зависимости от используемых функций).

Используйте шаблоны, чтобы определить логику один раз, а затем повторно использовать ее несколько раз. Шаблоны объединяют содержимое нескольких файлов YAML в один конвейер. Параметры можно передать в шаблон из родительского конвейера.

Расширение из шаблона

Чтобы повысить безопасность, можно применить применение конвейера из определенного шаблона. Файл start.yml определяет параметр buildSteps, который затем используется в конвейере azure-pipelines.yml. В start.yml, если buildStep передан с шагом скрипта, то его отклоняют, и сборка в конвейере завершается сбоем. При расширении из шаблона можно повысить безопасность, добавив необходимое утверждение шаблона.

# File: start.yml
parameters:
- name: buildSteps # the name of the parameter is buildSteps
  type: stepList # data type is StepList
  default: [] # default value of buildSteps
stages:
- stage: secure_buildstage
  pool:
    vmImage: windows-latest
  jobs:
  - job: secure_buildjob
    steps:
    - script: echo This happens before code 
      displayName: 'Base: Pre-build'
    - script: echo Building
      displayName: 'Base: Build'

    - ${{ each step in parameters.buildSteps }}:
      - ${{ each pair in step }}:
          ${{ if ne(pair.value, 'CmdLine@2') }}:
            ${{ pair.key }}: ${{ pair.value }}       
          ${{ if eq(pair.value, 'CmdLine@2') }}: 
            # Step is rejected by raising a YAML syntax error: Unexpected value 'CmdLine@2'
            '${{ pair.value }}': error         

    - script: echo This happens after code
      displayName: 'Base: Signing'
# File: azure-pipelines.yml
trigger:
- main

extends:
  template: start.yml
  parameters:
    buildSteps:  
      - bash: echo Test #Passes
        displayName: succeed
      - bash: echo "Test"
        displayName: succeed
      # Step is rejected by raising a YAML syntax error: Unexpected value 'CmdLine@2'
      - task: CmdLine@2
        inputs:
          script: echo "Script Test"
      # Step is rejected by raising a YAML syntax error: Unexpected value 'CmdLine@2'
      - script: echo "Script Test"

Расширение из шаблона с ресурсами

Вы также можете использовать extends для расширения из шаблона в конвейере Azure, который содержит ресурсы.

# File: azure-pipelines.yml
trigger:
- none

extends:
  template: resource-template.yml
# File: resource-template.yml
resources:
  pipelines:
  - pipeline: my-pipeline 
    source: sourcePipeline

steps:
- script: echo "Testing resource template"

Вставка шаблона

Вы можете скопировать содержимое из одного YAML и повторно использовать его в другом YAML. Копирование содержимого из одного YAML в другое сохраняет необходимость вручную включать одну логику в нескольких местах. Шаблон include-npm-steps.yml файла содержит шаги, которые повторно используются.azure-pipelines.yml

Примечание.

Файлы шаблонов должны существовать в файловой системе в начале выполнения конвейера. Вы не можете ссылаться на шаблоны в артефакте.

# File: templates/include-npm-steps.yml

steps:
- script: npm install
- script: yarn install
- script: npm run compile
# File: azure-pipelines.yml

jobs:
- job: Linux
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - template: templates/include-npm-steps.yml  # Template reference
- job: Windows
  pool:
    vmImage: 'windows-latest'
  steps:
  - template: templates/include-npm-steps.yml  # Template reference

Повторное использование шага

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

# File: templates/npm-steps.yml
steps:
- script: npm install
- script: npm test
# File: azure-pipelines.yml

jobs:
- job: Linux
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - template: templates/npm-steps.yml  # Template reference

- job: macOS
  pool:
    vmImage: 'macOS-latest'
  steps:
  - template: templates/npm-steps.yml  # Template reference

- job: Windows
  pool:
    vmImage: 'windows-latest'
  steps:
  - script: echo This script runs before the template's steps, only on Windows.
  - template: templates/npm-steps.yml  # Template reference
  - script: echo This step runs after the template's steps.

Повторное использование задания

Как и шаги, задания можно повторно использовать с помощью шаблонов.

# File: templates/jobs.yml
jobs:
- job: Ubuntu
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - bash: echo "Hello Ubuntu"

- job: Windows
  pool:
    vmImage: 'windows-latest'
  steps:
  - bash: echo "Hello Windows"
# File: azure-pipelines.yml

jobs:
- template: templates/jobs.yml  # Template reference

При работе с несколькими заданиями не забудьте удалить имя задания в файле шаблона, чтобы избежать конфликта.

# File: templates/jobs.yml
jobs:
- job: 
  pool:
    vmImage: 'ubuntu-latest'
  steps:
  - bash: echo "Hello Ubuntu"

- job:
  pool:
    vmImage: 'windows-latest'
  steps:
  - bash: echo "Hello Windows"
# File: azure-pipelines.yml

jobs:
- template: templates/jobs.yml  # Template reference
- template: templates/jobs.yml  # Template reference
- template: templates/jobs.yml  # Template reference

Повторное использование этапа

Этапы также можно повторно использовать с помощью шаблонов.

# File: templates/stages1.yml
stages:
- stage: Angular
  jobs:
  - job: angularinstall
    steps:
    - script: npm install angular
# File: templates/stages2.yml
stages:
- stage: Build
  jobs:
  - job: build
    steps:
    - script: npm run build
# File: azure-pipelines.yml
trigger:
- main

pool:
  vmImage: 'ubuntu-latest'

stages:
- stage: Install
  jobs: 
  - job: npminstall
    steps:
    - task: Npm@1
      inputs:
        command: 'install'
- template: templates/stages1.yml # Template reference
- template: templates/stages2.yml # Template reference

Шаблоны заданий, этапов и шагов с параметрами

В следующих шаблонах:

  • templates/npm-with-params.yml определяет два параметра: name и vmImage создает задание с параметром name для имени задания и параметра vmImage для образа виртуальной машины.
  • Конвейер (azure-pipelines.yml) ссылается на шаблон три раза, каждый из которых имеет разные значения параметров, ссылающиеся на имена операционной системы и образов виртуальной машины.
  • Встроенный конвейер выполняется на другом образе виртуальной машины и называется в соответствии с указанной ОС. Каждое задание выполняет действия установки npm и тестов npm.
# File: templates/npm-with-params.yml

parameters:
- name: name  # defaults for any parameters that aren't specified
  default: ''
- name: vmImage
  default: ''

jobs:
- job: ${{ parameters.name }}
  pool: 
    vmImage: ${{ parameters.vmImage }}
  steps:
  - script: npm install
  - script: npm test

При использовании шаблона в конвейере укажите значения параметров шаблона.

# File: azure-pipelines.yml

jobs:
- template: templates/npm-with-params.yml  # Template reference
  parameters:
    name: Linux
    vmImage: 'ubuntu-latest'

- template: templates/npm-with-params.yml  # Template reference
  parameters:
    name: macOS
    vmImage: 'macOS-latest'

- template: templates/npm-with-params.yml  # Template reference
  parameters:
    name: Windows
    vmImage: 'windows-latest'

Шаблоны этапов с несколькими параметрами

В следующих шаблонах:

  • Шаблон stage-template.yml определяет четыре параметра: stageName, jobNamevmImage, и scriptPathвсе строки типа. Шаблон создает этап с помощью stageName параметра для задания имени этапа, определяет задание с jobNameи включает шаг для запуска скрипта.
  • Конвейер, azure-pipeline.ymlа затем динамически определяют этапы и задания с помощью параметров и запуска задания, выполняющего скрипт, build-script.sh.
# stage-template.yml

parameters:
  - name: stageName
    type: string
  - name: jobName
    type: string
  - name: vmImage
    type: string
  - name: scriptPath
    type: string

stages:
  - stage: ${{ parameters.stageName }}
    jobs:
      - job: ${{ parameters.jobName }}
        pool:
          vmImage: ${{ parameters.vmImage }}
        steps:
          - script: ./${{ parameters.scriptPath }}
# azure-pipelines.yml
trigger:
- main

stages:
- template: stage-template.yml
  parameters:
    stageName: 'BuildStage'
    jobName: 'BuildJob'
    scriptPath: 'build-script.sh' # replace with script in your repository
    vmImage: 'ubuntu-latest'

Шаблоны с шагами и параметрами

Также можно использовать параметры с шаблонами шагов или этапов.

В следующих шаблонах:

  • Шаблон (templates/steps-with-params.yml) определяет параметр с именем runExtendedTests по умолчанию со значением false.
  • Конвейер (azure-pipelines.yml) выполняется npm test и npm test --extended потому, что runExtendedTests параметр имеет значение true.
# File: templates/steps-with-params.yml

parameters:
- name: 'runExtendedTests'  # defaults for any parameters that aren't specified
  type: boolean
  default: false

steps:
- script: npm test
- ${{ if eq(parameters.runExtendedTests, true) }}:
  - script: npm test --extended

При использовании шаблона в конвейере укажите значения параметров шаблона.

# File: azure-pipelines.yml

steps:
- script: npm install

- template: templates/steps-with-params.yml  # Template reference
  parameters:
    runExtendedTests: 'true'

Примечание.

Скалярные параметры без указанного типа обрабатываются как строки. Например, возвращается, eq(true, parameters['myparam']) даже если true параметр является словомmyparam, если false оно не сделано myparamявным booleanобразом. Непустые строки привязываются к true логическому контексту. Это выражение может быть перезаписано для явного сравнения строк: eq(parameters['myparam'], 'true')

Параметры не ограничиваются скалярными строками. См. список типов данных. Например, используя object тип:

# azure-pipelines.yml
jobs:
- template: process.yml
  parameters:
    pool:   # this parameter is called `pool`
      vmImage: ubuntu-latest  # and it's a mapping rather than a string


# process.yml
parameters:
- name: 'pool'
  type: object
  default: {}

jobs:
- job: build
  pool: ${{ parameters.pool }}

Повторное использование переменной

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

В этом примере переменная favoriteVeggie включена в azure-pipelines.yml.

# File: vars.yml
variables:
  favoriteVeggie: 'brussels sprouts'
# File: azure-pipelines.yml

variables:
- template: vars.yml  # Template reference

steps:
- script: echo My favorite vegetable is ${{ variables.favoriteVeggie }}.

Шаблоны переменных с параметром

Параметры можно передавать в переменные с помощью шаблонов. В этом примере параметр передается DIRECTORY переменной RELEASE_COMMAND .

# File: templates/package-release-with-params.yml

parameters:
- name: DIRECTORY 
  type: string
  default: "." # defaults for any parameters that specified with "." (current directory)

variables:
- name: RELEASE_COMMAND
  value: grep version ${{ parameters.DIRECTORY }}/package.json | awk -F \" '{print $4}'  

При использовании шаблона в конвейере укажите значения параметров шаблона.

# File: azure-pipelines.yml

variables: # Global variables
  - template: package-release-with-params.yml # Template reference
    parameters:
      DIRECTORY: "azure/checker"

pool:
  vmImage: 'ubuntu-latest'

stages:
- stage: Release_Stage 
  displayName: Release Version
  variables: # Stage variables
  - template: package-release-with-params.yml  # Template reference
    parameters:
      DIRECTORY: "azure/todo-list"
  jobs: 
  - job: A
    steps: 
    - bash: $(RELEASE_COMMAND) #output release command

Расширение от шаблона и использование шаблона включения с переменными

Один из распространенных сценариев заключается в наличии конвейера с этапами разработки, тестирования и производства, который использует как включающий шаблон для переменных, так и шаблон расширения для этапов и заданий.

В следующем примере variables-template.yml определяет набор переменных виртуальной машины, которые затем используются в azure-pipeline.yml.

# variables-template.yml

variables:
- name: devVmImage
  value: 'ubuntu-latest'
- name: testVmImage
  value: 'ubuntu-latest'
- name: prodVmImage
  value: 'ubuntu-latest'

Следующий файл stage-template.yml определяет конфигурацию для повторно используемых этапов с тремя параметрами (name, vmImage, ) stepsи заданием с именем Build.

# stage-template.yml
parameters:
- name: name
  type: string
  default: ''
- name: vmImage
  type: string
  default: ''
- name: steps
  type: stepList
  default: []

stages:
- stage: ${{ parameters.name }}
  jobs:
  - job: Build
    pool:
      vmImage: ${{ parameters.vmImage }}
    steps: ${{ parameters.steps }}

Следующий конвейер, azure-pipelines.ymlимпортирует переменные из variables-template.yml, а затем использует stage-template.yml шаблон для каждого этапа. Каждый этап (Dev, Test, Prod) определяется с одним и тем же шаблоном, но с разными параметрами, что приводит к согласованности между этапами, позволяя настраивать. Этап "Prod" включает переменную среды в качестве примера того, что вы можете использовать для проверки подлинности. Дополнительные сведения об определении параметров см. в разделе "Параметры шаблона".

# azure-pipelines.yml
trigger:
- main

variables:
- template: variables-template.yml

stages:
- template: stage-template.yml
  parameters:
    name: Dev
    vmImage: ${{ variables.devVmImage }}
    steps:
      - script: echo "Building in Dev"
- template: stage-template.yml
  parameters:
    name: Test
    vmImage: ${{ variables.testVmImage }}
    steps:
      - script: echo "Testing in Test"
- template: stage-template.yml
  parameters:
    name: Prod
    vmImage: ${{ variables.prodVmImage }}
    steps:
      - script: echo "Deploying to Prod"
        env:
          SYSTEM_ACCESSTOKEN: $(System.AccessToken)

Пути к шаблону ссылок

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

Чтобы использовать абсолютный путь, путь шаблона должен начинаться с /. Все остальные пути считаются относительными.

Ниже приведен пример вложенной иерархии.

|
+-- fileA.yml
|
+-- dir1/
     |
     +-- fileB.yml
     |
     +-- dir2/
          |
          +-- fileC.yml

Затем вы fileA.yml можете ссылаться fileB.yml и fileC.yml вроде этого.

steps:
- template: dir1/fileB.yml
- template: dir1/dir2/fileC.yml

Если fileC.yml это ваша отправная точка, вы можете включить fileA.yml и fileB.yml , как это.

steps:
- template: ../../fileA.yml
- template: ../fileB.yml

Когда fileB.yml вы начинаете свою точку, вы можете включить fileA.yml и fileC.yml , как это.

steps:
- template: ../fileA.yml
- template: dir2/fileC.yml

Кроме того, fileB.yml можно ссылаться на fileA.yml абсолютные пути и fileC.yml использовать такие пути.

steps:
- template: /fileA.yml
- template: /dir1/dir2/fileC.yml

Использование других репозиториев

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

# Repo: Contoso/BuildTemplates
# File: common.yml
parameters:
- name: 'vmImage'
  default: 'ubuntu-22.04'
  type: string

jobs:
- job: Build
  pool:
    vmImage: ${{ parameters.vmImage }}
  steps:
  - script: npm install
  - script: npm test

Теперь этот шаблон можно повторно использовать в нескольких конвейерах. Используйте спецификацию resources , чтобы указать расположение основного репозитория. Если вы ссылаетесь на основной репозиторий, используйте @ и имя, в который вы предоставили его resources.

# Repo: Contoso/LinuxProduct
# File: azure-pipelines.yml
resources:
  repositories:
    - repository: templates
      type: github
      name: Contoso/BuildTemplates

jobs:
- template: common.yml@templates  # Template reference
# Repo: Contoso/WindowsProduct
# File: azure-pipelines.yml
resources:
  repositories:
    - repository: templates
      type: github
      name: Contoso/BuildTemplates
      ref: refs/tags/v1.0 # optional ref to pin to

jobs:
- template: common.yml@templates  # Template reference
  parameters:
    vmImage: 'windows-latest'

Для type: githubname — это <identity>/<repo>, как показано в предыдущем примере. Для type: git (Azure Repos) name используется <project>/<repo>. Если этот проект находится в отдельной организации Azure DevOps, необходимо настроить подключение службы типа Azure Repos/Team Foundation Server с доступом к проекту и включить его в YAML:

resources:
  repositories:
  - repository: templates
    name: Contoso/BuildTemplates
    endpoint: myServiceConnection # Azure DevOps service connection
jobs:
- template: common.yml@templates

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

Если вы хотите использовать определенную исправленную версию шаблона, обязательно закрепите ее ref. Являются refs ветвями (refs/heads/<name>) или тегами (refs/tags/<name>). Если вы хотите закрепить определенную фиксацию, сначала создайте тег, указывающий на эту фиксацию, а затем закрепление этого тега.

Примечание.

Если ref не указано, конвейер по умолчанию использует refs/heads/main.

Вы также можете закрепить определенную фиксацию в Git со значением SHA для ресурса репозитория. Значение SHA — это хэш контрольной суммы 40 символов, который однозначно идентифицирует фиксацию.

resources:
  repositories:
    - repository: templates
      type: git
      name: Contoso/BuildTemplates
      ref: 1234567890abcdef1234567890abcdef12345678

Вы также можете использовать @self для ссылки на репозиторий, где найден исходный конвейер. Это удобно для использования в extends шаблонах, если вы хотите вернуться к содержимому в репозитории расширения конвейера. Например:

# Repo: Contoso/Central
# File: template.yml
jobs:
- job: PreBuild
  steps: []

  # Template reference to the repo where this template was
  # included from - consumers of the template are expected
  # to provide a "BuildJobs.yml"
- template: BuildJobs.yml@self

- job: PostBuild
  steps: []
# Repo: Contoso/MyProduct
# File: azure-pipelines.yml
resources:
  repositories:
    - repository: templates
      type: git
      name: Contoso/Central

extends:
  template: template.yml@templates
# Repo: Contoso/MyProduct
# File: BuildJobs.yml
jobs:
- job: Build
  steps: []

Вопросы и ответы

Как использовать переменные в шаблонах?

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

В этом примере предопределенные переменные Build.SourceBranch и Build.Reason используются в условиях в template.yml.

# File: azure-pipelines.yml
trigger:
- main

extends:
  template: template.yml
# File: template.yml
steps:
- script: echo Build.SourceBranch = $(Build.SourceBranch) # outputs refs/heads/main
- script: echo Build.Reason = $(Build.Reason) # outputs IndividualCI
- ${{ if eq(variables['Build.SourceBranch'], 'refs/heads/main') }}: 
  - script: echo I run only if Build.SourceBranch = refs/heads/main 
- ${{ if eq(variables['Build.Reason'], 'IndividualCI') }}: 
  - script: echo I run only if Build.Reason = IndividualCI 
- script: echo I run after the conditions