Utilização de tipos de modelo &
Serviços do Azure DevOps | Azure DevOps Server 2022 - Azure DevOps Server 2019
Os modelos permitem definir conteúdo reutilizável, lógica e parâmetros. Os modelos funcionam de duas formas. Pode inserir conteúdo reutilizável com um modelo ou pode utilizar um modelo para controlar o que é permitido num pipeline. A segunda abordagem é útil para criar pipelines seguros com modelos.
Se um modelo for utilizado para incluir conteúdo, funciona como uma diretiva de inclusão em muitas linguagens de programação. O conteúdo de um ficheiro é inserido noutro ficheiro. Quando um modelo controla o que é permitido num pipeline, o modelo define a lógica que outro ficheiro tem de seguir.
Utilize modelos para definir a lógica uma vez e, em seguida, reutilizá-la várias vezes. Os modelos combinam o conteúdo de múltiplos ficheiros YAML num único pipeline. Pode transmitir parâmetros para um modelo a partir do pipeline principal.
Parâmetros
Pode especificar parâmetros e os respetivos tipos de dados num modelo e referenciar esses parâmetros num pipeline. Com templateContext, também pode transmitir propriedades para fases, passos e trabalhos que são utilizados como parâmetros num modelo.
Também pode utilizar parâmetros fora dos modelos. Só pode utilizar literais para valores predefinidos de parâmetros.
Transmitir parâmetros
Os parâmetros têm de conter um nome e um tipo de dados. Em azure-pipelines.yml
, quando o parâmetro yesNo
é definido como um valor booleano, a compilação é bem-sucedida. Quando yesNo
está definida para uma cadeia, como apples
, a compilação 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 no runtime
Pode chamar modelos diferentes a partir de um YAML de pipeline, consoante uma condição. Neste exemplo, o experimental.yml
YAML será executado quando o parâmetro experimentalTemplate
for verdadeiro.
#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âmetros
Tipo de dados | Notas |
---|---|
string |
string |
number |
pode ser restringido a values: , caso contrário, qualquer cadeia de carateres semelhante a um número é aceite |
boolean |
true ou false |
object |
qualquer estrutura YAML |
step |
um único passo |
stepList |
sequência de passos |
job |
uma única tarefa |
jobList |
sequência de tarefas |
deployment |
uma única tarefa de implementação |
deploymentList |
sequência de tarefas de implementação |
stage |
uma única fase |
stageList |
sequência de fases |
Todos os tipos de dados stepList, job, jobList, deployment, deploymentList, stage e stageList utilizam o formato de esquema YAML padrão. Este exemplo inclui cadeia, número, booleano, objeto, passo 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 }}
Pode iterar através de um objeto e imprimir cada cadeia no objeto.
parameters:
- name: listOfStrings
type: object
default:
- one
- two
steps:
- ${{ each value in parameters.listOfStrings }}:
- script: echo ${{ value }}
Além disso, pode iterar através de elementos aninhados dentro de 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 }}
Expandir a partir de um modelo
Para aumentar a segurança, pode impor que um pipeline se expanda a partir de um modelo específico. O ficheiro start.yml
define o parâmetro buildSteps
, que é depois utilizado no pipeline azure-pipelines.yml
.
No start.yml
, se um buildStep
for transmitido com um passo de script, será rejeitado e a compilação do pipeline falhará.
Ao expandir a partir de um modelo, pode aumentar a segurança ao adicionar 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"
Expandir a partir de um modelo com recursos
Também pode utilizar extends
para expandir a partir de um modelo no 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"
Utilizar templateContext para transmitir propriedades a modelos
Pode utilizar templateContext
para transmitir propriedades adicionais para fases, passos e trabalhos que são utilizados como parâmetros num modelo. Especificamente, pode especificar templateContext
no jobList
tipo de dados , deploymentList
ou stageList
parâmetro.
Pode utilizar templateContext
para facilitar a configuração de ambientes ao processar cada tarefa. Ao agrupar uma tarefa e o respetivo objeto de propriedades de ambiente, templateContext
pode ajudá-lo a ter um YAML mais fácil de manter e compreender.
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
com a palavra-chave cada. Em seguida, o modelo referencia o testJob.templateContext.expectedHTTPResponseCode
, que é definido e azure-pipeline.yml
passado para o modelo.
Quando o código de resposta é 200, o modelo faz um pedido REST. Quando o código de resposta é 500, o modelo produz 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
Pode copiar conteúdo de um YAML e reutilizá-lo num YAML diferente. Copiar conteúdo de um YAML para outro impede-o de ter de incluir manualmente a mesma lógica em vários locais. O include-npm-steps.yml
modelo de ficheiro contém passos que são reutilizados no azure-pipelines.yml
.
Nota
Os ficheiros de modelo têm de existir no sistema de ficheiros no início de uma execução de pipeline. Não pode referenciar modelos num artefacto.
# 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 de passos
Pode inserir um modelo para reutilizar um ou mais passos em várias tarefas. Além dos passos do modelo, cada tarefa pode definir mais passos.
# 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 da tarefa
Tal como os passos, as tarefas podem ser reutilizadas 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árias tarefas, lembre-se de remover o nome da tarefa no ficheiro de modelo, de modo a 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 fase
As fases também podem ser reutilizadas 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 tarefas, fases e passos 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
Quando consumir o modelo no pipeline, especifique valores para os parâmetros do 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'
Também pode utilizar parâmetros com modelos de fase ou passo. Por exemplo, passos 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
Quando consumir o modelo no pipeline, especifique valores para os parâmetros do modelo.
# File: azure-pipelines.yml
steps:
- script: npm install
- template: templates/steps-with-params.yml # Template reference
parameters:
runExtendedTests: 'true'
Nota
Os parâmetros escalares sem um tipo especificado são tratados como cadeias.
Por exemplo, eq(true, parameters['myparam'])
irá devolver true
, mesmo que o myparam
parâmetro seja a palavra false
, se myparam
não for explicitamente efetuada boolean
.
As cadeias não vazias são convertidas true
num contexto booleano.
Essa expressão pode ser reescrita para comparar explicitamente cadeias: eq(parameters['myparam'], 'true')
.
Os parâmetros não estão limitados a cadeias escalares.
Veja a lista de tipos de dados.
Por exemplo, com 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 variável
As variáveis podem ser definidas num YAML e incluídas noutro modelo. Isto pode ser útil se quiser armazenar todas as suas variáveis num único ficheiro. Se estiver a utilizar um modelo para incluir variáveis num pipeline, o modelo incluído só pode ser utilizado para definir variáveis. Pode utilizar passos e lógica mais complexa ao expandir a partir de um modelo. Utilize 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
Pode transmitir parâmetros para variáveis com modelos. Neste exemplo, está a transmitir 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}'
Quando consumir o modelo no pipeline, especifique valores para os parâmetros do 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 dos modelos devem ser relativos ao ficheiro que faz a inclusão. Eis um exemplo de hierarquia aninhada.
|
+-- fileA.yml
|
+-- dir1/
|
+-- fileB.yml
|
+-- dir2/
|
+-- fileC.yml
Em seguida, fileA.yml
pode referenciar fileB.yml
e fileC.yml
desta forma.
steps:
- template: dir1/fileB.yml
- template: dir1/dir2/fileC.yml
Se fileC.yml
for o seu ponto de partida, pode incluir fileA.yml
e fileB.yml
desta forma.
steps:
- template: ../../fileA.yml
- template: ../fileB.yml
Quando fileB.yml
é o seu ponto de partida, pode incluir fileA.yml
e fileC.yml
assim.
steps:
- template: ../fileA.yml
- template: dir2/fileC.yml
Utilizar outros repositórios
Pode manter os seus modelos noutros repositórios. Por exemplo, suponha que tem um pipeline principal que pretende que todos os pipelines da sua aplicação utilizem. Pode colocar o modelo num repositório principal e, em seguida, fazer referência ao mesmo a partir de cada um dos repositórios de aplicações:
# 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 pode reutilizar este modelo em vários pipelines.
Utilize a resources
especificação para fornecer a localização do repositório principal.
Quando se referir ao repositório principal, utilize @
e o nome que deu 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
(Repositórios do Azure), name
é <project>/<repo>
.
Se esse projeto estiver numa organização separada do Azure DevOps, terá de configurar uma ligaçã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, é utilizado o mesmo recurso durante o pipeline. Apenas os ficheiros de modelo são utilizados. Assim que os modelos estiverem totalmente expandidos, o pipeline final é executado como se tivesse sido definido inteiramente no repositório de origem. Isto significa que não pode utilizar scripts do repositório de modelos no seu pipeline.
Se quiser utilizar uma versão fixa específica do modelo, certifique-se de que afixa a um ref
.
São refs
ramos (refs/heads/<name>
) ou etiquetas (refs/tags/<name>
).
Se quiser afixar uma consolidação específica, crie primeiro uma etiqueta que aponte para essa consolidação e, em seguida, afixe a essa etiqueta.
Nota
Se não ref
for especificado, o pipeline terá a predefinição de utilizar refs/heads/main
.
Também pode utilizar @self
para fazer referência ao repositório onde o pipeline original foi encontrado.
Isto é conveniente para utilização em extends
modelos se quiser voltar a consultar conteúdos no repositório do pipeline de expansã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
Utilize expressões de modelo para especificar como os valores são resolvidos dinamicamente durante a inicialização do pipeline.
Coloque a expressão do modelo dentro desta sintaxe: ${{ }}
.
As expressões de modelo podem expandir parâmetros de modelo e também variáveis.
Pode utilizar parâmetros para influenciar a forma como um modelo é expandido.
O parameters
objeto funciona como o variables
objeto numa expressão. Apenas as variáveis predefinidas podem ser utilizadas em expressões de modelo.
Nota
As expressões só são expandidas para stages
, jobs
, steps
e containers
(dentro resources
de ).
Não pode, por exemplo, utilizar uma expressão dentro trigger
ou um recurso como repositories
.
Além disso, no Azure DevOps 2020 RTW, não pode utilizar expressões de modelo dentro containers
do .
Por exemplo, 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, referencia o modelo e transmite-lhe o parâmetro opcional solution
:
# File: azure-pipelines.yml
steps:
- template: steps/msbuild.yml
parameters:
solution: my.sln
Contexto
Numa expressão de modelo, tem acesso ao parameters
contexto que contém os valores dos parâmetros transmitidos.
Além disso, tem acesso ao variables
contexto que contém todas as variáveis especificadas no ficheiro YAML e muitas das variáveis predefinidas (indicadas em cada variável nesse tópico).
Importante, não tem variáveis de runtime, como as armazenadas no pipeline ou fornecidas quando inicia uma execução.
A expansão do modelo ocorre no início da execução, pelo que essas variáveis não estão disponíveis.
Parâmetros necessários
Pode adicionar um passo de validação no início do modelo para verificar se existem os parâmetros necessários.
Eis um exemplo que verifica o parâmetro com o solution
Bash (que lhe permite trabalhar 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 falha se 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
Pode utilizar funções gerais nos seus modelos. Também pode utilizar algumas funções de expressão de modelo.
formato
- Substituição de token de cadeia simples
- Parâmetros min: 2. Parâmetros máximos: N
- Exemplo:
${{ format('{0} Build', parameters.os) }}
→'Windows Build'
coalesce
- É avaliado como o primeiro argumento de cadeia não vazio e não nulo
- Parâmetros min: 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
Pode utilizar expressões de modelo para alterar a estrutura de um pipeline YAML. Por exemplo, para inserir numa 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 numa matriz, a matriz aninhada é achatada.
Para inserir num mapeamento, utilize 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 quiser inserir condicionalmente numa sequência ou mapeamento num modelo, utilize inserções e avaliação de expressões. Também pode utilizar if
instruções fora dos modelos , desde que utilize a sintaxe do modelo.
Por exemplo, para inserir numa sequência num 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 num mapeamento num 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
Também pode utilizar a inserção condicional para variáveis. Neste exemplo, start
imprime sempre e this is a test
só imprime quando a foo
variável é igual a test
.
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 numa sequência YAML (matriz) ou mapeamento (pares chave-valor).
Por exemplo, pode moldar os passos de cada tarefa com outros pré e pós-passos:
# 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!
Também pode manipular as propriedades do que estiver a iterar. 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.
Escapar a um valor
Se precisar de escapar a um valor que contém ${{
literalmente , embrulhe o valor numa cadeia de expressão. Por exemplo, ${{ 'my${{value' }}
ou ${{ 'my${{value with a '' single quote too' }}
Limites impostos
Os modelos e as expressões de modelos podem causar um crescimento explosivo do tamanho e complexidade de um pipeline. Para ajudar a evitar o crescimento em fuga, o Azure Pipelines impõe os seguintes limites:
- Não podem ser incluídos mais de 100 ficheiros YAML separados (direta ou indiretamente)
- Não podem existir mais de 20 níveis de aninhamento de modelos (modelos, incluindo outros modelos)
- Não são consumidos mais de 10 megabytes de memória ao analisar o YAML (na prática, isto é normalmente entre 600 KB e 2 MB de YAML no disco, dependendo das funcionalidades específicas utilizadas)
Parâmetros do modelo
Pode transmitir parâmetros para modelos.
A parameters
secção define que parâmetros estão disponíveis no modelo e os respetivos valores predefinidos.
Os modelos são expandidos pouco antes da execução do pipeline para que os valores rodeados sejam ${{ }}
substituídos pelos parâmetros que recebe do pipeline de colocação em curso. Como resultado, apenas as variáveis predefinidas podem ser utilizadas em parâmetros.
Para utilizar parâmetros em vários pipelines, veja como criar um grupo de variáveis.
Modelos de tarefas, fases e passos 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
Quando consumir o modelo no pipeline, especifique valores para os parâmetros do 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'
Também pode utilizar parâmetros com modelos de fase ou passo. Por exemplo, passos 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
Quando consumir o modelo no pipeline, especifique valores para os parâmetros do modelo.
# File: azure-pipelines.yml
steps:
- script: npm install
- template: templates/steps-with-params.yml # Template reference
parameters:
runExtendedTests: 'true'
Nota
Os parâmetros escalares são sempre tratados como cadeias.
Por exemplo, eq(parameters['myparam'], true)
devolverá quase sempre true
, mesmo que o myparam
parâmetro seja a palavra false
.
As cadeias não vazias são convertidas true
num contexto booleano.
Essa expressão pode ser reescrita para comparar explicitamente cadeias: eq(parameters['myparam'], 'true')
.
Os parâmetros não estão limitados a cadeias escalares. Desde que o local onde o parâmetro se expanda espere um mapeamento, o parâmetro pode ser um mapeamento. Da mesma forma, as sequências podem ser transmitidas 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 }}
Utilizar outros repositórios
Pode manter os seus modelos noutros repositórios. Por exemplo, suponha que tem um pipeline principal que pretende que todos os pipelines de aplicação utilizem. Pode colocar o modelo num repositório principal e, em seguida, fazer referência ao mesmo a partir de cada um dos seus repositórios de aplicações:
# 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 pode reutilizar este modelo em vários pipelines.
Utilize a resources
especificação para fornecer a localização do repositório principal.
Quando fizer referência ao repositório principal, utilize @
e o nome que atribuiu 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
(Repositórios do Azure), name
é <project>/<repo>
.
O projeto tem de estar na mesma organização; As referências entre organizações não são suportadas.
Os repositórios são resolvidos apenas uma vez, quando o pipeline é iniciado. Depois disso, é utilizado o mesmo recurso durante o pipeline. Só são utilizados os ficheiros de modelo. Assim que os modelos estiverem totalmente expandidos, o pipeline final é executado como se estivesse totalmente definido no repositório de origem. Isto significa que não pode utilizar scripts do repositório de modelos no seu pipeline.
Se quiser utilizar uma versão fixa específica do modelo, certifique-se de que afixa a um ref. Os refs são ramos (refs/heads/<name>
) ou etiquetas (refs/tags/<name>
).
Se quiser afixar uma consolidação específica, crie primeiro uma etiqueta que aponte para essa consolidação e, em seguida, afixe a essa etiqueta.
Expressions (Expressões)
Utilize expressões de modelo para especificar a forma como os valores são resolvidos dinamicamente durante a inicialização do pipeline.
Coloque a expressão do modelo dentro desta sintaxe: ${{ }}
.
As expressões de modelo podem expandir parâmetros de modelo e também variáveis.
Pode utilizar parâmetros para influenciar a forma como um modelo é expandido.
O parameters
objeto funciona como o variables
objeto numa expressão.
Por exemplo, 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, referencia o modelo e transmite-lhe o parâmetro opcional solution
:
# File: azure-pipelines.yml
steps:
- template: steps/msbuild.yml
parameters:
solution: my.sln
Contexto
Numa expressão de modelo, tem acesso ao parameters
contexto, que contém os valores dos parâmetros transmitidos.
Além disso, tem acesso ao variables
contexto, que contém todas as variáveis especificadas no ficheiro YAML e as variáveis de sistema.
É importante que não tenha variáveis de runtime, como as que estão armazenadas no pipeline ou fornecidas quando inicia uma execução.
A expansão do modelo ocorre no início da execução, pelo que essas variáveis não estão disponíveis.
Parâmetros necessários
Pode adicionar um passo de validação no início do modelo para verificar os parâmetros de que precisa.
Eis um exemplo que verifica o parâmetro com o solution
Bash (que lhe permite trabalhar 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 falha se 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
Pode utilizar funções gerais nos seus modelos. Também pode utilizar algumas funções de expressão de modelo.
formato
- Substituição de token de cadeia simples
- Parâmetros min: 2. Parâmetros máximos: N
- Exemplo:
${{ format('{0} Build', parameters.os) }}
→'Windows Build'
coalesce
- É avaliado como o primeiro argumento de cadeia não nulo e não nulo
- Parâmetros min: 2. Parâmetros máximos: N
- Exemplo:
parameters:
restoreProjects: ''
buildProjects: ''
steps:
- script: echo ${{ coalesce(parameters.foo, parameters.bar, 'Nothing to see') }}
Inserção
Pode utilizar expressões de modelo para alterar a estrutura de um pipeline YAML. Por exemplo, para inserir numa 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 numa matriz, a matriz aninhada é aplanada.
Para inserir num mapeamento, utilize 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 quiser inserir condicionalmente numa sequência ou mapeamento, utilize inserções e avaliação de expressões.
Por exemplo, para inserir numa 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 num 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 numa sequência YAML (matriz) ou mapeamento (pares chave-valor).
Por exemplo, pode encapsular os passos de cada tarefa com pré e pós-passos adicionais:
# 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!
Também pode manipular as propriedades do que estiver a iterar. 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.
A fugir
Se precisar de escapar a um valor que contém ${{
literalmente , embrulhe o valor numa cadeia de expressão. Por exemplo, ${{ 'my${{value' }}
ou ${{ 'my${{value with a '' single quote too' }}
Limites
Os modelos e as expressões de modelos podem causar um crescimento explosivo do tamanho e complexidade de um pipeline. Para ajudar a evitar o crescimento em execução, o Azure Pipelines impõe os seguintes limites:
- Não podem ser incluídos mais de 50 ficheiros YAML separados (direta ou indiretamente)
- Não existem mais de 10 megabytes de memória consumida ao analisar o YAML (na prática, isto é normalmente entre 600 KB e 2 MB de YAML no disco, dependendo das funcionalidades específicas utilizadas)
- Não são permitidos mais de 2000 carateres por expressão de modelo
FAQ
Como posso utilizar variáveis em modelos?
Por vezes, pode ser útil definir parâmetros como valores baseados em variáveis. Os parâmetros são expandidos no início do processamento de uma execução de pipeline, pelo que nem todas as variáveis estarão disponíveis. Para ver que variáveis predefinidas estão disponíveis nos modelos, veja Utilizar variáveis predefinidas.
Neste exemplo, as variáveis predefinidas e Build.Reason
são utilizadas Build.SourceBranch
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