Справочник по использованию шаблона
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
,jobName
vmImage
, и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'])
даже если myparam
параметр является словомfalse
, если myparam
оно не сделано boolean
явным true
образом.
Непустые строки привязываются к 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: github
этого name
используется <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