Uso de tipos de modelo &
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
Os modelos permitem definir o conteúdo reutilizável, a lógica e os parâmetros. Os modelos funcionam de duas maneiras. É possível inserir conteúdo reutilizável com um modelo ou usar um modelo para controlar o que é permitido em um pipeline. A segunda abordagem é útil para criar pipelines seguros com modelos.
Se um modelo for usado para incluir conteúdo, ele funcionará como uma diretiva include em muitas linguagens de programação. O conteúdo de um arquivo é inserido em outro arquivo. Quando um modelo controla o que é permitido em um pipeline, o modelo define a lógica que outro arquivo deve seguir.
Use modelos para definir sua lógica uma vez e reutilizá-la várias vezes. Os modelos combinam o conteúdo de vários arquivos YAML em um único pipeline. Você pode passar parâmetros para um modelo do pipeline pai.
Parâmetros
Você pode especificar parâmetros e seus tipos de dados em um modelo e referenciar esses parâmetros em um pipeline. Com templateContext, você também pode passar propriedades para estágios, etapas e trabalhos que são usados como parâmetros em um modelo.
Você também pode usar parâmetros fora dos modelos. Você só pode usar literais para valores padrão de parâmetro.
Passando parâmetros
Os parâmetros devem conter um nome e um tipo de dados. Em azure-pipelines.yml
, quando o parâmetro yesNo
é definido como um valor booliano, o build é bem-sucedido. Quando yesNo
é definido como uma cadeia de caracteres como apples
, o build falha.
# File: simple-param.yml
parameters:
- name: yesNo # name of the parameter; required
type: boolean # data type of the parameter; required
default: false
steps:
- script: echo ${{ parameters.yesNo }}
# File: azure-pipelines.yml
trigger:
- main
extends:
template: simple-param.yml
parameters:
yesNo: false # set to a non-boolean value to have the build fail
Parâmetros para selecionar um modelo em runtime
Você pode chamar modelos diferentes de um YAML de pipeline dependendo de uma condição. Neste exemplo, o experimental.yml
YAML será executado quando o parâmetro experimentalTemplate
for true.
#azure-pipeline.yml
parameters:
- name: experimentalTemplate
displayName: 'Use experimental build process?'
type: boolean
default: false
steps:
- ${{ if eq(parameters.experimentalTemplate, true) }}:
- template: experimental.yml
- ${{ if not(eq(parameters.experimentalTemplate, true)) }}:
- template: stable.yml
Tipos de dados de parâmetro
Tipo de dados | Observações |
---|---|
string |
string |
number |
pode ser restrito a values: , caso contrário, qualquer cadeia de caracteres semelhante a número é aceita |
boolean |
true ou false |
object |
qualquer estrutura YAML |
step |
uma única etapa |
stepList |
sequência de etapas |
job |
um único trabalho |
jobList |
sequência de trabalhos |
deployment |
um único trabalho de implantação |
deploymentList |
sequência de trabalhos de implantação |
stage |
um único estágio |
stageList |
sequência de estágios |
Os tipos de dados step, stepList, job, jobList, deployment, deploymentList, stage e stageList usam o formato de esquema YAML padrão. Este exemplo inclui cadeia de caracteres, número, booliano, objeto, etapa e stepList.
parameters:
- name: myString
type: string
default: a string
- name: myMultiString
type: string
default: default
values:
- default
- ubuntu
- name: myNumber
type: number
default: 2
values:
- 1
- 2
- 4
- 8
- 16
- name: myBoolean
type: boolean
default: true
- name: myObject
type: object
default:
foo: FOO
bar: BAR
things:
- one
- two
- three
nested:
one: apple
two: pear
count: 3
- name: myStep
type: step
default:
script: echo my step
- name: mySteplist
type: stepList
default:
- script: echo step one
- script: echo step two
trigger: none
jobs:
- job: stepList
steps: ${{ parameters.mySteplist }}
- job: myStep
steps:
- ${{ parameters.myStep }}
Você pode iterar por meio de um objeto e imprimir cada cadeia de caracteres no objeto .
parameters:
- name: listOfStrings
type: object
default:
- one
- two
steps:
- ${{ each value in parameters.listOfStrings }}:
- script: echo ${{ value }}
Além disso, você pode iterar por meio de elementos aninhados em um objeto .
parameters:
- name: listOfFruits
type: object
default:
- fruitName: 'apple'
colors: ['red','green']
- fruitName: 'lemon'
colors: ['yellow']
steps:
- ${{ each fruit in parameters.listOfFruits }} :
- ${{ each fruitColor in fruit.colors}} :
- script: echo ${{ fruit.fruitName}} ${{ fruitColor }}
Estender de um modelo
Para aumentar a segurança, você pode impor que um pipeline se estenda de um modelo específico. O arquivo start.yml
define o parâmetro buildSteps
, que é usado no pipeline azure-pipelines.yml
.
No start.yml
, se um buildStep
for passado com uma etapa de script, ele será rejeitado e o build do pipeline falhará.
Ao estender de um modelo, você pode aumentar a segurança adicionando uma aprovação de modelo necessária.
# 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"
Estender de um modelo com recursos
Você também pode usar extends
para estender de um modelo em seu pipeline do Azure que contém recursos.
# 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"
Usar templateContext para passar propriedades para modelos
Você pode usar templateContext
para passar propriedades adicionais para estágios, etapas e trabalhos que são usados como parâmetros em um modelo. Especificamente, você pode especificar templateContext
dentro do tipo de dados de jobList
parâmetro , deploymentList
ou stageList
.
Você pode usar templateContext
para facilitar a configuração de ambientes ao processar cada trabalho. Ao agrupar um trabalho e seu objeto de propriedades de ambiente, templateContext
você pode ajudar você a ter um YAML mais mantenedível e mais fácil de entender.
Neste exemplo, o parâmetro testSet
em testing-template.yml
tem o tipo jobList
de dados . O modelo testing-template.yml
cria uma nova variável testJob
usando cada palavra-chave. Em seguida, o modelo faz referência ao testJob.templateContext.expectedHTTPResponseCode
, que é definido em azure-pipeline.yml
e passado para o modelo.
Quando o código de resposta é 200, o modelo faz uma solicitação REST. Quando o código de resposta é 500, o modelo gera todas as variáveis de ambiente para depuração.
templateContext
pode conter propriedades.
#testing-template.yml
parameters:
- name: testSet
type: jobList
jobs:
- ${{ each testJob in parameters.testSet }}:
- ${{ if eq(testJob.templateContext.expectedHTTPResponseCode, 200) }}:
- job:
steps:
- powershell: 'Invoke-RestMethod -Uri https://blogs.msdn.microsoft.com/powershell/feed/ | Format-Table -Property Title, pubDate'
- ${{ testJob.steps }}
- ${{ if eq(testJob.templateContext.expectedHTTPResponseCode, 500) }}:
- job:
steps:
- powershell: 'Get-ChildItem -Path Env:\'
- ${{ testJob.steps }}
#azure-pipeline.yml
trigger: none
pool:
vmImage: ubuntu-latest
extends:
template: testing-template.yml
parameters:
testSet:
- job: positive_test
templateContext:
expectedHTTPResponseCode: 200
steps:
- script: echo "Run positive test"
- job: negative_test
templateContext:
expectedHTTPResponseCode: 500
steps:
- script: echo "Run negative test"
Inserir um modelo
Você pode copiar o conteúdo de um YAML e reutilizá-lo em um YAML diferente. Copiar conteúdo de um YAML para outro evita que você precise incluir manualmente a mesma lógica em vários lugares. O include-npm-steps.yml
modelo de arquivo contém etapas reutilizados em azure-pipelines.yml
.
Observação
Os arquivos de modelo precisam existir no sistema de arquivos no início de uma execução de pipeline. Você não pode referenciar modelos em um artefato.
# 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
Reutilização da etapa
Você pode inserir um modelo para reutilizar uma ou mais etapas em vários trabalhos. Além das etapas do modelo, cada trabalho pode definir mais etapas.
# 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.
Reutilização do trabalho
Assim como as etapas, os trabalhos podem ser reutilizados com modelos.
# 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
Ao trabalhar com vários trabalhos, lembre-se de remover o nome do trabalho no arquivo de modelo, para evitar conflitos
# 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
Reutilização de estágio
Estágios também podem ser reutilizados com modelos.
# 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: templates/stages2.yml
Modelos de trabalho, estágio e etapa com parâmetros
# 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
Ao consumir o modelo em seu pipeline, especifique valores para os parâmetros de modelo.
# 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'
Você também pode usar parâmetros com modelos de etapa ou estágio. Por exemplo, etapas com parâmetros:
# 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
Ao consumir o modelo em seu pipeline, especifique valores para os parâmetros de modelo.
# File: azure-pipelines.yml
steps:
- script: npm install
- template: templates/steps-with-params.yml # Template reference
parameters:
runExtendedTests: 'true'
Observação
Parâmetros escalares sem um tipo especificado são tratados como cadeias de caracteres.
Por exemplo, eq(true, parameters['myparam'])
retornará true
, mesmo que o myparam
parâmetro seja a palavra false
, se myparam
não for explicitamente feito boolean
.
Cadeias de caracteres não vazias são convertidas true
em em um contexto booliano.
Essa expressão pode ser reescrita para comparar explicitamente cadeias de caracteres: eq(parameters['myparam'], 'true')
.
Os parâmetros não estão limitados a cadeias de caracteres escalares.
Consulte a lista de tipos de dados.
Por exemplo, usando o object
tipo :
# 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 }}
Reutilização de variável
As variáveis podem ser definidas em um YAML e incluídas em outro modelo. Isso pode ser útil se você quiser armazenar todas as variáveis em um arquivo. Se você estiver usando um modelo para incluir variáveis em um pipeline, o modelo incluído só poderá ser usado para definir variáveis. Você pode usar etapas e lógica mais complexa ao estender de um modelo. Use parâmetros em vez de variáveis quando quiser restringir o tipo.
Neste exemplo, a variável favoriteVeggie
está incluída em 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 }}.
Modelos de variáveis com parâmetro
Você pode passar parâmetros para variáveis com modelos. Neste exemplo, você está passando o DIRECTORY
parâmetro para uma RELEASE_COMMAND
variável.
# 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}'
Ao consumir o modelo em seu pipeline, especifique valores para os parâmetros de modelo.
# 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
Caminhos de modelo de referência
Os caminhos de modelo devem ser relativos ao arquivo que faz a inclusão. Aqui está um exemplo de hierarquia aninhada.
|
+-- fileA.yml
|
+-- dir1/
|
+-- fileB.yml
|
+-- dir2/
|
+-- fileC.yml
Em seguida, em fileA.yml
, você pode referenciar fileB.yml
e fileC.yml
assim.
steps:
- template: dir1/fileB.yml
- template: dir1/dir2/fileC.yml
Se fileC.yml
for seu ponto de partida, você poderá incluir fileA.yml
e fileB.yml
curtir isso.
steps:
- template: ../../fileA.yml
- template: ../fileB.yml
Quando fileB.yml
é o ponto de partida, você pode incluir fileA.yml
e fileC.yml
assim.
steps:
- template: ../fileA.yml
- template: dir2/fileC.yml
Usar outros repositórios
Você pode manter seus modelos em outros repositórios. Por exemplo, suponha que você tenha um pipeline principal que deseja que todos os pipelines de aplicativo usem. Você pode colocar o modelo em um repositório principal e, em seguida, fazer referência a ele de cada um dos seus repositórios de aplicativos:
# Repo: Contoso/BuildTemplates
# File: common.yml
parameters:
- name: 'vmImage'
default: 'ubuntu 16.04'
type: string
jobs:
- job: Build
pool:
vmImage: ${{ parameters.vmImage }}
steps:
- script: npm install
- script: npm test
Agora você pode reutilizar esse modelo em vários pipelines.
Use a resources
especificação para fornecer o local do repositório principal.
Quando você se referir ao repositório principal, use @
e o nome que você deu a ele em 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'
Para type: github
, name
é <identity>/<repo>
como nos exemplos acima.
Para type: git
(Azure Repos), name
é <project>/<repo>
.
Se esse projeto estiver em uma organização separada do Azure DevOps, você precisará configurar uma conexão de serviço do tipo Azure Repos/Team Foundation Server
com acesso ao projeto e incluí-la no YAML:
resources:
repositories:
- repository: templates
name: Contoso/BuildTemplates
endpoint: myServiceConnection # Azure DevOps service connection
jobs:
- template: common.yml@templates
Os repositórios são resolvidos apenas uma vez, quando o pipeline é iniciado. Depois disso, o mesmo recurso é usado durante o pipeline. Somente os arquivos de modelo são usados. Depois que os modelos forem totalmente expandidos, o pipeline final será executado como se tivesse sido definido inteiramente no repositório de origem. Isso significa que você não pode usar scripts do repositório de modelos em seu pipeline.
Se você quiser usar uma versão fixa específica do modelo, certifique-se de fixar em um ref
.
Os refs
são branches (refs/heads/<name>
) ou marcas (refs/tags/<name>
).
Se você quiser fixar uma confirmação específica, primeiro crie uma marca apontando para essa confirmação e, em seguida, fixe nessa marca.
Observação
Se nenhum ref
for especificado, o pipeline usará por padrão refs/heads/main
.
Você também pode usar @self
para se referir ao repositório em que o pipeline original foi encontrado.
Isso é conveniente para uso em extends
modelos se você quiser fazer referência ao conteúdo no repositório do pipeline de extensão.
Por exemplo:
# 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: []
Expressões de modelo
Use expressões de modelo para especificar como os valores são resolvidos dinamicamente durante a inicialização do pipeline.
Encapsule sua expressão de modelo dentro desta sintaxe: ${{ }}
.
As expressões de modelo podem expandir parâmetros de modelo e também variáveis.
Você pode usar parâmetros para influenciar como um modelo é expandido.
O parameters
objeto funciona como o variables
objeto em uma expressão. Somente variáveis predefinidas podem ser usadas em expressões de modelo.
Observação
As expressões são expandidas apenas para stages
, jobs
, steps
e containers
(dentro resources
de ).
Você não pode, por exemplo, usar uma expressão dentro trigger
ou um recurso como repositories
.
Além disso, no Azure DevOps 2020 RTW, você não pode usar expressões de modelo dentro containers
de .
Por exemplo, você define um modelo:
# File: steps/msbuild.yml
parameters:
- name: 'solution'
default: '**/*.sln'
type: string
steps:
- task: msbuild@1
inputs:
solution: ${{ parameters['solution'] }} # index syntax
- task: vstest@2
inputs:
solution: ${{ parameters.solution }} # property dereference syntax
Em seguida, você faz referência ao modelo e passa o parâmetro opcional solution
para ele:
# File: azure-pipelines.yml
steps:
- template: steps/msbuild.yml
parameters:
solution: my.sln
Contexto
Em uma expressão de modelo, você tem acesso ao parameters
contexto que contém os valores dos parâmetros passados.
Além disso, você tem acesso ao variables
contexto que contém todas as variáveis especificadas no arquivo YAML, além de muitas das variáveis predefinidas (indicadas em cada variável nesse tópico).
É importante ressaltar que ele não tem variáveis de runtime, como aquelas armazenadas no pipeline ou fornecidas quando você inicia uma execução.
A expansão do modelo ocorre no início da execução, portanto, essas variáveis não estão disponíveis.
Parâmetros obrigatórios
Você pode adicionar uma etapa de validação no início do modelo para marcar para os parâmetros necessários.
Aqui está um exemplo que verifica o parâmetro usando Bash solution
(que permite que ele funcione em qualquer plataforma):
# File: steps/msbuild.yml
parameters:
- name: 'solution'
default: ''
type: string
steps:
- bash: |
if [ -z "$SOLUTION" ]; then
echo "##vso[task.logissue type=error;]Missing template parameter \"solution\""
echo "##vso[task.complete result=Failed;]"
fi
env:
SOLUTION: ${{ parameters.solution }}
displayName: Check for required parameters
- task: msbuild@1
inputs:
solution: ${{ parameters.solution }}
- task: vstest@2
inputs:
solution: ${{ parameters.solution }}
Para mostrar que o modelo falhará se ele não tiver o parâmetro necessário:
# File: azure-pipelines.yml
# This will fail since it doesn't set the "solution" parameter to anything,
# so the template will use its default of an empty string
steps:
- template: steps/msbuild.yml
Funções de expressão de modelo
Você pode usar funções gerais em seus modelos. Você também pode usar algumas funções de expressão de modelo.
format
- Substituição de token de cadeia de caracteres simples
- Parâmetros mínimos: 2. Parâmetros máximos: N
- Exemplo:
${{ format('{0} Build', parameters.os) }}
→'Windows Build'
coalesce
- É avaliado como o primeiro argumento de cadeia de caracteres não vazia e não nula
- Parâmetros mínimos: 2. Parâmetros máximos: N
- Exemplo:
parameters:
- name: 'restoreProjects'
default: ''
type: string
- name: 'buildProjects'
default: ''
type: string
steps:
- script: echo ${{ coalesce(parameters.foo, parameters.bar, 'Nothing to see') }}
Inserção
Você pode usar expressões de modelo para alterar a estrutura de um pipeline YAML. Por exemplo, para inserir em uma sequência:
# File: jobs/build.yml
parameters:
- name: 'preBuild'
type: stepList
default: []
- name: 'preTest'
type: stepList
default: []
- name: 'preSign'
type: stepList
default: []
jobs:
- job: Build
pool:
vmImage: 'windows-latest'
steps:
- script: cred-scan
- ${{ parameters.preBuild }}
- task: msbuild@1
- ${{ parameters.preTest }}
- task: vstest@2
- ${{ parameters.preSign }}
- script: sign
# File: .vsts.ci.yml
jobs:
- template: jobs/build.yml
parameters:
preBuild:
- script: echo hello from pre-build
preTest:
- script: echo hello from pre-test
Quando uma matriz é inserida em uma matriz, a matriz aninhada é nivelada.
Para inserir em um mapeamento, use a propriedade ${{ insert }}
especial .
# Default values
parameters:
- name: 'additionalVariables'
type: object
default: {}
jobs:
- job: build
variables:
configuration: debug
arch: x86
${{ insert }}: ${{ parameters.additionalVariables }}
steps:
- task: msbuild@1
- task: vstest@2
jobs:
- template: jobs/build.yml
parameters:
additionalVariables:
TEST_SUITE: L0,L1
Inserção condicional
Se você quiser inserir condicionalmente em uma sequência ou mapeamento em um modelo, use inserções e avaliação de expressão. Você também pode usar if
instruções fora dos modelos , desde que use a sintaxe de modelo.
Por exemplo, para inserir em uma sequência em um modelo:
# File: steps/build.yml
parameters:
- name: 'toolset'
default: msbuild
type: string
values:
- msbuild
- dotnet
steps:
# msbuild
- ${{ if eq(parameters.toolset, 'msbuild') }}:
- task: msbuild@1
- task: vstest@2
# dotnet
- ${{ if eq(parameters.toolset, 'dotnet') }}:
- task: dotnet@1
inputs:
command: build
- task: dotnet@1
inputs:
command: test
# File: azure-pipelines.yml
steps:
- template: steps/build.yml
parameters:
toolset: dotnet
Por exemplo, para inserir em um mapeamento em um modelo:
# File: steps/build.yml
parameters:
- name: 'debug'
type: boolean
default: false
steps:
- script: tool
env:
${{ if eq(parameters.debug, true) }}:
TOOL_DEBUG: true
TOOL_DEBUG_DIR: _dbg
steps:
- template: steps/build.yml
parameters:
debug: true
Você também pode usar a inserção condicional para variáveis. Neste exemplo, start
sempre imprime e this is a test
apenas imprime quando a variável é test
igual a foo
.
variables:
- name: foo
value: test
pool:
vmImage: 'ubuntu-latest'
steps:
- script: echo "start" # always runs
- ${{ if eq(variables.foo, 'test') }}:
- script: echo "this is a test" # runs when foo=test
Inserção iterativa
A each
diretiva permite a inserção iterativa com base em uma sequência YAML (matriz) ou mapeamento (pares chave-valor).
Por exemplo, você pode encapsular as etapas de cada trabalho com outras pré e pós-etapas:
# job.yml
parameters:
- name: 'jobs'
type: jobList
default: []
jobs:
- ${{ each job in parameters.jobs }}: # Each job
- ${{ each pair in job }}: # Insert all properties other than "steps"
${{ if ne(pair.key, 'steps') }}:
${{ pair.key }}: ${{ pair.value }}
steps: # Wrap the steps
- task: SetupMyBuildTools@1 # Pre steps
- ${{ job.steps }} # Users steps
- task: PublishMyTelemetry@1 # Post steps
condition: always()
# azure-pipelines.yml
jobs:
- template: job.yml
parameters:
jobs:
- job: A
steps:
- script: echo This will get sandwiched between SetupMyBuildTools and PublishMyTelemetry.
- job: B
steps:
- script: echo So will this!
Você também pode manipular as propriedades do que estiver iterando. Por exemplo, para adicionar mais dependências:
# job.yml
parameters:
- name: 'jobs'
type: jobList
default: []
jobs:
- job: SomeSpecialTool # Run your special tool in its own job first
steps:
- task: RunSpecialTool@1
- ${{ each job in parameters.jobs }}: # Then do each job
- ${{ each pair in job }}: # Insert all properties other than "dependsOn"
${{ if ne(pair.key, 'dependsOn') }}:
${{ pair.key }}: ${{ pair.value }}
dependsOn: # Inject dependency
- SomeSpecialTool
- ${{ if job.dependsOn }}:
- ${{ job.dependsOn }}
# azure-pipelines.yml
jobs:
- template: job.yml
parameters:
jobs:
- job: A
steps:
- script: echo This job depends on SomeSpecialTool, even though it's not explicitly shown here.
- job: B
dependsOn:
- A
steps:
- script: echo This job depends on both Job A and on SomeSpecialTool.
Escape de um valor
Se você precisar escapar de um valor que contém ${{
literalmente , em seguida, encapsule o valor em uma cadeia de caracteres de expressão. Por exemplo, ${{ 'my${{value' }}
ou ${{ 'my${{value with a '' single quote too' }}
Limites impostos
Modelos e expressões de modelo podem causar um crescimento explosivo do tamanho e da complexidade de um pipeline. Para ajudar a evitar o crescimento descontrolado, o Azure Pipelines impõe os seguintes limites:
- Não mais de 100 arquivos YAML separados podem ser incluídos (direta ou indiretamente)
- Não mais do que 20 níveis de aninhamento de modelos (modelos incluindo outros modelos)
- Não mais do que 10 megabytes de memória consumidos durante a análise do YAML (na prática, isso normalmente está entre 600 KB e 2 MB de YAML no disco, dependendo dos recursos específicos usados)
Parâmetros de modelo
Você pode passar parâmetros para modelos.
A parameters
seção define quais parâmetros estão disponíveis no modelo e seus valores padrão.
Os modelos são expandidos pouco antes da execução do pipeline para que os valores cercados por ${{ }}
sejam substituídos pelos parâmetros recebidos do pipeline delimitador. Como resultado, somente variáveis predefinidas podem ser usadas em parâmetros.
Para usar parâmetros em vários pipelines, confira como criar um grupo de variáveis.
Modelos de trabalho, estágio e etapa com parâmetros
# File: templates/npm-with-params.yml
parameters:
name: '' # defaults for any parameters that aren't specified
vmImage: ''
jobs:
- job: ${{ parameters.name }}
pool:
vmImage: ${{ parameters.vmImage }}
steps:
- script: npm install
- script: npm test
Ao consumir o modelo em seu pipeline, especifique valores para os parâmetros de modelo.
# 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-10.13'
- template: templates/npm-with-params.yml # Template reference
parameters:
name: Windows
vmImage: 'windows-latest'
Você também pode usar parâmetros com modelos de etapa ou estágio. Por exemplo, etapas com parâmetros:
# File: templates/steps-with-params.yml
parameters:
runExtendedTests: 'false' # defaults for any parameters that aren't specified
steps:
- script: npm test
- ${{ if eq(parameters.runExtendedTests, 'true') }}:
- script: npm test --extended
Ao consumir o modelo em seu pipeline, especifique valores para os parâmetros de modelo.
# File: azure-pipelines.yml
steps:
- script: npm install
- template: templates/steps-with-params.yml # Template reference
parameters:
runExtendedTests: 'true'
Observação
Parâmetros escalares são sempre tratados como cadeias de caracteres.
Por exemplo, eq(parameters['myparam'], true)
quase sempre retornará true
, mesmo que o myparam
parâmetro seja a palavra false
.
Cadeias de caracteres não vazias são convertidas true
em em um contexto booliano.
Essa expressão pode ser reescrita para comparar explicitamente cadeias de caracteres: eq(parameters['myparam'], 'true')
.
Os parâmetros não estão limitados a cadeias de caracteres escalares. Desde que o local em que o parâmetro se expanda espere um mapeamento, o parâmetro pode ser um mapeamento. Da mesma forma, as sequências podem ser passadas onde as sequências são esperadas. Por exemplo:
# 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:
pool: {}
jobs:
- job: build
pool: ${{ parameters.pool }}
Usando outros repositórios
Você pode manter seus modelos em outros repositórios. Por exemplo, suponha que você tenha um pipeline principal que deseja que todos os pipelines de aplicativo usem. Você pode colocar o modelo em um repositório principal e, em seguida, fazer referência a ele de cada um dos repositórios do aplicativo:
# Repo: Contoso/BuildTemplates
# File: common.yml
parameters:
vmImage: 'ubuntu 16.04'
jobs:
- job: Build
pool:
vmImage: ${{ parameters.vmImage }}
steps:
- script: npm install
- script: npm test
Agora você pode reutilizar esse modelo em vários pipelines.
Use a resources
especificação para fornecer o local do repositório principal.
Quando você se referir ao repositório principal, use @
e o nome que você deu a ele em 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'
Para type: github
, name
é <identity>/<repo>
como nos exemplos acima.
Para type: git
(Azure Repos), name
é <project>/<repo>
.
O projeto deve estar na mesma organização; Não há suporte para referências entre organizações.
Os repositórios são resolvidos apenas uma vez, quando o pipeline é iniciado. Depois disso, o mesmo recurso é usado durante o pipeline. Somente os arquivos de modelo são usados. Depois que os modelos forem totalmente expandidos, o pipeline final será executado como se tivesse sido definido inteiramente no repositório de origem. Isso significa que você não pode usar scripts do repositório de modelos em seu pipeline.
Se você quiser usar uma versão fixa específica do modelo, certifique-se de fixar em um ref. Refs são branches (refs/heads/<name>
) ou marcas (refs/tags/<name>
).
Se você quiser fixar um commit específico, primeiro crie uma marca apontando para essa confirmação e fixe nessa marca.
Expressões
Use expressões de modelo para especificar como os valores são resolvidos dinamicamente durante a inicialização do pipeline.
Encapsule sua expressão de modelo dentro dessa sintaxe: ${{ }}
.
As expressões de modelo podem expandir parâmetros de modelo e também variáveis.
Você pode usar parâmetros para influenciar como um modelo é expandido.
O parameters
objeto funciona como o variables
objeto em uma expressão.
Por exemplo, você define um modelo:
# File: steps/msbuild.yml
parameters:
solution: '**/*.sln'
steps:
- task: msbuild@1
inputs:
solution: ${{ parameters['solution'] }} # index syntax
- task: vstest@2
inputs:
solution: ${{ parameters.solution }} # property dereference syntax
Em seguida, você faz referência ao modelo e passa o parâmetro opcional solution
para ele:
# File: azure-pipelines.yml
steps:
- template: steps/msbuild.yml
parameters:
solution: my.sln
Contexto
Dentro de uma expressão de modelo, você tem acesso ao parameters
contexto , que contém os valores dos parâmetros passados.
Além disso, você tem acesso ao variables
contexto , que contém todas as variáveis especificadas no arquivo YAML mais as variáveis do sistema.
É importante ressaltar que ele não tem variáveis de runtime, como aquelas armazenadas no pipeline ou fornecidas quando você inicia uma execução.
A expansão do modelo ocorre no início da execução, portanto, essas variáveis não estão disponíveis.
Parâmetros obrigatórios
Você pode adicionar uma etapa de validação no início do modelo para marcar para os parâmetros necessários.
Aqui está um exemplo que verifica o parâmetro usando Bash solution
(que permite que ele funcione em qualquer plataforma):
# File: steps/msbuild.yml
parameters:
solution: ''
steps:
- bash: |
if [ -z "$SOLUTION" ]; then
echo "##vso[task.logissue type=error;]Missing template parameter \"solution\""
echo "##vso[task.complete result=Failed;]"
fi
env:
SOLUTION: ${{ parameters.solution }}
displayName: Check for required parameters
- task: msbuild@1
inputs:
solution: ${{ parameters.solution }}
- task: vstest@2
inputs:
solution: ${{ parameters.solution }}
Para mostrar que o modelo falhará se ele não tiver o parâmetro necessário:
# File: azure-pipelines.yml
# This will fail since it doesn't set the "solution" parameter to anything,
# so the template will use its default of an empty string
steps:
- template: steps/msbuild.yml
Funções de expressão de modelo
Você pode usar funções gerais em seus modelos. Você também pode usar algumas funções de expressão de modelo.
format
- Substituição de token de cadeia de caracteres simples
- Parâmetros mínimos: 2. Parâmetros máximos: N
- Exemplo:
${{ format('{0} Build', parameters.os) }}
→'Windows Build'
coalesce
- É avaliado como o primeiro argumento de cadeia de caracteres não nula e não nulo
- Parâmetros mínimos: 2. Parâmetros máximos: N
- Exemplo:
parameters:
restoreProjects: ''
buildProjects: ''
steps:
- script: echo ${{ coalesce(parameters.foo, parameters.bar, 'Nothing to see') }}
Inserção
Você pode usar expressões de modelo para alterar a estrutura de um pipeline YAML. Por exemplo, para inserir em uma sequência:
# File: jobs/build.yml
parameters:
preBuild: []
preTest: []
preSign: []
jobs:
- job: Build
pool:
vmImage: 'windows-latest'
steps:
- script: cred-scan
- ${{ parameters.preBuild }}
- task: msbuild@1
- ${{ parameters.preTest }}
- task: vstest@2
- ${{ parameters.preSign }}
- script: sign
# File: .vsts.ci.yml
jobs:
- template: jobs/build.yml
parameters:
preBuild:
- script: echo hello from pre-build
preTest:
- script: echo hello from pre-test
Quando uma matriz é inserida em uma matriz, a matriz aninhada é nivelada.
Para inserir em um mapeamento, use a propriedade ${{ insert }}
especial .
# Default values
parameters:
additionalVariables: {}
jobs:
- job: build
variables:
configuration: debug
arch: x86
${{ insert }}: ${{ parameters.additionalVariables }}
steps:
- task: msbuild@1
- task: vstest@2
jobs:
- template: jobs/build.yml
parameters:
additionalVariables:
TEST_SUITE: L0,L1
Inserção condicional
Se você quiser inserir condicionalmente em uma sequência ou mapeamento, use inserções e avaliação de expressão.
Por exemplo, para inserir em uma sequência:
# File: steps/build.yml
parameters:
toolset: msbuild
steps:
# msbuild
- ${{ if eq(parameters.toolset, 'msbuild') }}:
- task: msbuild@1
- task: vstest@2
# dotnet
- ${{ if eq(parameters.toolset, 'dotnet') }}:
- task: dotnet@1
inputs:
command: build
- task: dotnet@1
inputs:
command: test
# File: azure-pipelines.yml
steps:
- template: steps/build.yml
parameters:
toolset: dotnet
Por exemplo, para inserir em um mapeamento:
# File: steps/build.yml
parameters:
debug: false
steps:
- script: tool
env:
${{ if eq(parameters.debug, 'true') }}:
TOOL_DEBUG: true
TOOL_DEBUG_DIR: _dbg
steps:
- template: steps/build.yml
parameters:
debug: true
Inserção iterativa
A each
diretiva permite a inserção iterativa com base em uma sequência yaml (matriz) ou mapeamento (pares chave-valor).
Por exemplo, você pode encapsular as etapas de cada trabalho com pré e pós-etapas extras:
# job.yml
parameters:
jobs: []
jobs:
- ${{ each job in parameters.jobs }}: # Each job
- ${{ each pair in job }}: # Insert all properties other than "steps"
${{ if ne(pair.key, 'steps') }}:
${{ pair.key }}: ${{ pair.value }}
steps: # Wrap the steps
- task: SetupMyBuildTools@1 # Pre steps
- ${{ job.steps }} # Users steps
- task: PublishMyTelemetry@1 # Post steps
condition: always()
# azure-pipelines.yml
jobs:
- template: job.yml
parameters:
jobs:
- job: A
steps:
- script: echo This will get sandwiched between SetupMyBuildTools and PublishMyTelemetry.
- job: B
steps:
- script: echo So will this!
Você também pode manipular as propriedades do que estiver iterando. Por exemplo, para adicionar mais dependências:
# job.yml
parameters:
jobs: []
jobs:
- job: SomeSpecialTool # Run your special tool in its own job first
steps:
- task: RunSpecialTool@1
- ${{ each job in parameters.jobs }}: # Then do each job
- ${{ each pair in job }}: # Insert all properties other than "dependsOn"
${{ if ne(pair.key, 'dependsOn') }}:
${{ pair.key }}: ${{ pair.value }}
dependsOn: # Inject dependency
- SomeSpecialTool
- ${{ if job.dependsOn }}:
- ${{ job.dependsOn }}
# azure-pipelines.yml
jobs:
- template: job.yml
parameters:
jobs:
- job: A
steps:
- script: echo This job depends on SomeSpecialTool, even though it's not explicitly shown here.
- job: B
dependsOn:
- A
steps:
- script: echo This job depends on both Job A and on SomeSpecialTool.
Escape
Se você precisar escapar de um valor que contém ${{
literalmente , em seguida, encapsule o valor em uma cadeia de caracteres de expressão. Por exemplo, ${{ 'my${{value' }}
ou ${{ 'my${{value with a '' single quote too' }}
Limites
Modelos e expressões de modelo podem causar um crescimento explosivo do tamanho e da complexidade de um pipeline. Para ajudar a evitar o crescimento descontrolado, o Azure Pipelines impõe os seguintes limites:
- Não mais de 50 arquivos YAML separados podem ser incluídos (direta ou indiretamente)
- Não mais do que 10 megabytes de memória consumidos durante a análise do YAML (na prática, isso normalmente está entre 600 KB e 2 MB de YAML no disco, dependendo dos recursos específicos usados)
- Não são permitidos mais de 2.000 caracteres por expressão de modelo
Perguntas frequentes
Como posso usar variáveis dentro de modelos?
Há momentos em que pode ser útil definir parâmetros para valores com base em variáveis. Os parâmetros são expandidos no início do processamento de uma execução de pipeline para que nem todas as variáveis estejam disponíveis. Para ver quais variáveis predefinidas estão disponíveis em modelos, confira Usar variáveis predefinidas.
Neste exemplo, as variáveis Build.SourceBranch
predefinidas e Build.Reason
são usadas em condições em 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