Справочник по использованию шаблона
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'])
даже если 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: 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