Condições do gasoduto
Serviços de DevOps do Azure | Azure DevOps Server 2022 - Azure DevOps Server 2019
Este artigo descreve as condições sob as quais um estágio, trabalho ou etapa do Azure Pipelines é executado e como especificar condições diferentes. Para obter mais contexto sobre estágios, trabalhos e etapas, consulte Conceitos-chave para Pipelines do Azure.
Por padrão, um trabalho ou estágio é executado se não depender de nenhum outro trabalho ou estágio, ou se todas as suas dependências forem concluídas e bem-sucedidas. Este requisito aplica-se não só às dependências diretas, mas também às suas dependências indiretas, calculadas recursivamente.
Por padrão, uma etapa é executada se nada em seu trabalho ainda falhou e a etapa imediatamente anterior foi concluída.
Você pode substituir ou personalizar esse comportamento forçando um estágio, trabalho ou etapa a ser executado, mesmo que uma dependência anterior falhe, ou especificando uma condição personalizada.
Nota
Este artigo discute os recursos de pipeline YAML. Para pipelines clássicos, você pode especificar algumas condições sob as quais tarefas ou trabalhos são executados nas Opções de controle de cada tarefa e nas opções adicionais para um trabalho em um pipeline de versão.
Condições em que um estágio, trabalho ou etapa é executado
Na definição de pipeline YAML, você pode especificar as seguintes condições sob as quais um estágio, trabalho ou etapa é executado:
Somente quando todas as dependências diretas e indiretas anteriores com o mesmo pool de agentes forem bem-sucedidas. Se você tiver pools de agentes diferentes, esses estágios ou trabalhos serão executados simultaneamente. Esta condição é o padrão se nenhuma condição estiver definida no YAML.
Mesmo que uma dependência anterior falhe, a menos que a execução seja cancelada. Use
succeededOrFailed()
no YAML para esta condição.Mesmo que uma dependência anterior falhe e mesmo que a execução seja cancelada. Use
always()
no YAML para esta condição.Apenas quando uma dependência anterior falha. Use
failed()
no YAML para esta condição.
- Condições personalizadas.
Por padrão, estágios, trabalhos e etapas são executados se todas as dependências diretas e indiretas forem bem-sucedidas. Esse status é o mesmo que especificar condition: succeeded()
. Para obter mais informações, consulte Função de status bem-sucedida.
Ao especificar uma condition
propriedade para um estágio, trabalho ou etapa, você substitui o padrão condition: succeeded()
. Especificar suas próprias condições pode fazer com que seu estágio, trabalho ou etapa seja executado mesmo se a compilação for cancelada. Certifique-se de que as condições que você escreve levam em conta o estado do estágio ou trabalho pai.
O exemplo YAML a seguir mostra as always()
condições e failed()
. A etapa no primeiro trabalho é executada mesmo se as dependências falharem ou a compilação for cancelada. O segundo trabalho é executado somente se o primeiro trabalho falhar.
jobs:
- job: Foo
steps:
- script: echo Hello!
condition: always() # this step runs, even if the build is canceled
- job: Bar
dependsOn: Foo
condition: failed() # this job runs only if Foo fails
Você também pode definir e usar variáveis em condições. O exemplo a seguir define e usa uma isMain
variável para designar main
como .Build.SourceBranch
variables:
isMain: $[eq(variables['Build.SourceBranch'], 'refs/heads/main')]
stages:
- stage: A
jobs:
- job: A1
steps:
- script: echo Hello Stage A!
- stage: B
condition: and(succeeded(), eq(variables.isMain, true))
jobs:
- job: B1
steps:
- script: echo Hello Stage B!
- script: echo $(isMain)
Importante
As condições são avaliadas para determinar se se deve iniciar um estágio, trabalho ou etapa. Portanto, nada computado em tempo de execução dentro dessa unidade de trabalho está disponível. Por exemplo, se você tiver um trabalho que define uma variável usando uma expressão de tempo de execução com $[ ]
sintaxe, não poderá usar essa variável em uma condição personalizada nesse trabalho.
Condições personalizadas
Se as condições internas não atenderem às suas necessidades, você poderá especificar condições personalizadas. Você escreve condições como expressões em definições de pipeline YAML.
O agente avalia a expressão começando com a função mais interna e prosseguindo para fora. O resultado final é um valor booleano que determina se a tarefa, o trabalho ou o estágio deve ou não ser executado. Para obter um guia completo sobre a sintaxe, consulte Expressões.
Se qualquer uma das suas condições permitir que a tarefa seja executada mesmo depois que a compilação for cancelada, especifique um valor razoável para cancelar o tempo limite para que essas tarefas tenham tempo suficiente para serem concluídas depois que o usuário cancelar uma execução.
Resultados da condição quando uma compilação é cancelada
Cancelar uma compilação não significa que todos os seus estágios, trabalhos ou etapas parem de ser executados. Quais estágios, trabalhos ou etapas param de ser executados dependem das condições especificadas e em que ponto da execução do pipeline você cancelou a compilação. Se o pai de um estágio, trabalho ou etapa for ignorado, a tarefa não será executada, independentemente de suas condições.
Um estágio, trabalho ou etapa é executado sempre que suas condições avaliam a true
. Se a sua condição não levar em conta o estado do pai da tarefa, a tarefa poderá ser executada mesmo que o pai seja cancelado. Para controlar se estágios, trabalhos ou etapas com condições são executados quando uma compilação é cancelada, certifique-se de incluir uma função de verificação de status do trabalho em suas condições.
Os exemplos a seguir mostram os resultados de várias condições definidas em estágios, trabalhos ou etapas quando a compilação é cancelada.
Exemplo de estágio 1
No pipeline a seguir, por padrão stage2
dependeria de stage1
, mas stage2
tem um condition
conjunto para ser executado sempre que a ramificação de origem for main
, independentemente do stage1
status.
Se você enfileirar uma compilação na main
ramificação e cancelá-la enquanto stage1
estiver em execução, stage2
ainda será executado, porque eq(variables['Build.SourceBranch'], 'refs/heads/main')
avalia como true
.
stages:
- stage: stage1
jobs:
- job: A
steps:
- script: echo 1; sleep 30
- stage: stage2
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
jobs:
- job: B
steps:
- script: echo 2
Exemplo de estágio 2
No pipeline a seguir, stage2
depende por stage1
padrão. Job B
in stage2
tem um condition
conjunto. Se você enfileirar uma compilação na main
ramificação e cancelá-la enquanto stage1
estiver em execução, stage2
ela não será executada, mesmo que ela contenha um trabalho cuja condição seja avaliada como true
.
O motivo é porque stage2
tem o padrão condition: succeeded()
, que avalia até false
quando stage1
é cancelado. Portanto, stage2
é ignorado, e nenhum de seus trabalhos é executado.
stages:
- stage: stage1
jobs:
- job: A
steps:
- script: echo 1; sleep 30
- stage: stage2
jobs:
- job: B
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
steps:
- script: echo 2
Exemplo de estágio 3
No pipeline a seguir, por padrão stage2
, depende de stage1
, e a etapa dentro do trabalho B
tem um condition
conjunto.
Se você enfileirar uma compilação na main
ramificação e cancelá-la enquanto stage1
estiver em execução, stage2
ela não será executada, mesmo que ela contenha uma etapa no trabalho B
cuja condição seja avaliada como true
. O motivo é porque stage2
é ignorado em resposta ao stage1
cancelamento.
stages:
- stage: stage1
jobs:
- job: A
steps:
- script: echo 1; sleep 30
- stage: stage2
jobs:
- job: B
steps:
- script: echo 2
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
Exemplo de trabalho 1
No pipeline YAML a seguir, o trabalho B
depende do trabalho A
por padrão, mas o trabalho B
tem um condition
conjunto para ser executado sempre que a ramificação de origem for main
. Se você enfileirar uma compilação na ramificação e cancelá-la enquanto o trabalho A
estiver em execução, o main
trabalho B
ainda será executado, porque eq(variables['Build.SourceBranch'], 'refs/heads/main')
avalia como true
.
jobs:
- job: A
steps:
- script: sleep 30
- job: B
dependsOn: A
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
steps:
- script: echo step 2.1
Se você quiser que o trabalho B
seja executado somente quando o trabalho A
for bem-sucedido e a fonte de compilação for a main
ramificação, você condition
deve ser and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
.
Exemplo de trabalho 2
No pipeline a seguir, o trabalho B
depende do trabalho A
por padrão. Se você enfileirar uma compilação na ramificação e cancelá-la enquanto o main
trabalho A
estiver em execução, o trabalho B
não será executado, mesmo que sua etapa tenha um condition
que avalia como true
.
O motivo é porque o trabalho B
tem o padrão condition: succeeded()
, que avalia quando o false
trabalho A
é cancelado. Portanto, o trabalho B
é ignorado e nenhuma de suas etapas é executada.
jobs:
- job: A
steps:
- script: sleep 30
- job: B
dependsOn: A
steps:
- script: echo step 2.1
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main', succeeded())
Exemplo de passo
Você também pode ter condições sobre os degraus.
No pipeline a seguir, a etapa 2.3 tem um condition
conjunto para ser executado sempre que a ramificação de origem for main
. Se você enfileirar uma compilação na ramificação e cancelá-la enquanto as etapas 2.1 ou 2.2 estiverem em execução, a main
etapa 2.3 ainda será executada, porque eq(variables['Build.SourceBranch'], 'refs/heads/main')
avalia como true
.
steps:
- script: echo step 2.1
- script: echo step 2.2; sleep 30
- script: echo step 2.3
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
Configurações de condição
A tabela a seguir mostra configurações de exemplo condition
para produzir vários resultados.
Nota
Release.Artifacts.{artifact-alias}.SourceBranch
é equivalente a Build.SourceBranch
.
Resultado desejado | Exemplo de configuração de condição |
---|---|
Execute se a ramificação de origem for principal, mesmo que o estágio, trabalho ou etapa pai ou anterior tenha falhado ou sido cancelado. | eq(variables['Build.SourceBranch'], 'refs/heads/main') |
Execute se a ramificação de origem for principal e o estágio, trabalho ou etapa pai ou anterior tiver êxito. | and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main')) |
Execute se a ramificação de origem não for principal e o estágio, trabalho ou etapa pai ou anterior tiver êxito. | and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main')) |
Executar para ramificações de tópico de usuário, se o estágio, trabalho ou etapa pai ou anterior tiver sido bem-sucedido. | and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/')) |
Executar para compilações de integração contínua (CI), se o estágio, trabalho ou etapa pai ou anterior tiver sido bem-sucedido. | and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI')) |
Execute se a compilação foi acionada por uma política de ramificação para uma solicitação pull e o estágio, trabalho ou etapa pai ou anterior falhou. | and(failed(), eq(variables['Build.Reason'], 'PullRequest')) |
Executar para uma compilação agendada, mesmo que o estágio, trabalho ou etapa pai ou anterior tenha falhado ou sido cancelado. | eq(variables['Build.Reason'], 'Schedule') |
Execute se uma variável estiver definida como true, mesmo que o estágio, trabalho ou etapa pai ou anterior tenha falhado ou sido cancelado. | eq(variables['System.debug'], true) |
Nota
Você pode definir uma condição para ser executada se uma variável for nula (cadeia de caracteres vazia). Como todas as variáveis são tratadas como cadeias de caracteres no Azure Pipelines, uma cadeia de caracteres vazia é equivalente ao null
seguinte pipeline:
variables:
- name: testEmpty
value: ''
jobs:
- job: A
steps:
- script: echo testEmpty is blank
condition: eq(variables.testEmpty, '')
Parâmetros em condições
A expansão do parâmetro acontece antes que as condições sejam consideradas. Portanto, quando você declara um parâmetro no mesmo pipeline como uma condição, você pode incorporar o parâmetro dentro da condição. O script no YAML a seguir é executado porque parameters.doThing
é verdadeiro.
parameters:
- name: doThing
default: true
type: boolean
steps:
- script: echo I did a thing
condition: and(succeeded(), ${{ eq(parameters.doThing, true) }})
O condition
pipeline anterior combina duas funções: succeeded()
e ${{ eq(parameters.doThing, true) }}
. A succeeded()
função verifica se a etapa anterior foi bem-sucedida. A succeeded()
função retorna true
porque não houve nenhuma etapa anterior.
A ${{ eq(parameters.doThing, true) }}
função verifica se o doThing
parâmetro é igual a true
. Como o valor padrão para doThing
é true
, a condição retorna true
por padrão, a menos que o pipeline defina um valor diferente.
Parâmetros do modelo em condições
Ao passar um parâmetro para um modelo, você precisa definir o valor do parâmetro em seu modelo ou usar templateContext para passar o parâmetro para o modelo.
Por exemplo, o seguinte arquivo de parameters.yml declara o parâmetro e o doThing
valor padrão:
# parameters.yml
parameters:
- name: doThing
default: true # value passed to the condition
type: boolean
jobs:
- job: B
steps:
- script: echo I did a thing
condition: ${{ eq(parameters.doThing, true) }}
O código de pipeline faz referência ao modelo parameters.yml . A saída do pipeline é I did a thing
porque o parâmetro doThing
é true.
# azure-pipeline.yml
parameters:
- name: doThing
default: true
type: boolean
trigger:
- none
extends:
template: parameters.yml
Para obter mais exemplos de parâmetros de modelo, consulte a Referência de uso de modelo.
Variáveis de saída de trabalho usadas em condições de trabalho subsequentes
Você pode disponibilizar uma variável para trabalhos futuros e especificá-la em uma condição. As variáveis disponíveis para trabalhos futuros devem ser marcadas como variáveis de saída de vários trabalhos usando isOutput=true
, como no código a seguir:
jobs:
- job: Foo
steps:
- bash: |
echo "This is job Foo."
echo "##vso[task.setvariable variable=doThing;isOutput=true]Yes" #set variable doThing to Yes
name: DetermineResult
- job: Bar
dependsOn: Foo
condition: eq(dependencies.Foo.outputs['DetermineResult.doThing'], 'Yes') #map doThing and check the value
steps:
- script: echo "Job Foo ran and doThing is Yes."
Variáveis criadas em uma etapa usada em condições de etapa subsequentes
Você pode criar uma variável que está disponível para etapas futuras a serem especificadas em uma condição. As variáveis criadas a partir de etapas estão disponíveis para etapas futuras por padrão e não precisam ser marcadas como variáveis de saída de vários trabalhos.
Há algumas coisas importantes a observar sobre as variáveis de escopo que são criadas a partir de etapas.
- As variáveis criadas em uma etapa em um trabalho têm como escopo as etapas no mesmo trabalho.
- As variáveis criadas em uma etapa estão disponíveis nas etapas subsequentes somente como variáveis de ambiente.
- As variáveis criadas em uma etapa não podem ser usadas na etapa que as define.
O exemplo a seguir mostra a criação de uma variável de pipeline em uma etapa e o uso da variável na condição e no script de uma etapa subsequente.
steps:
# This step creates a new pipeline variable: doThing. This variable is available to subsequent steps.
- bash: |
echo "##vso[task.setvariable variable=doThing]Yes"
displayName: Step 1
# This step is able to use doThing, so it uses doThing in its condition
- script: |
# Access the variable from Step 1 as an environment variable.
echo "Value of doThing (as DOTHING env var): $DOTHING."
displayName: Step 2
condition: and(succeeded(), eq(variables['doThing'], 'Yes')) # or and(succeeded(), eq(variables.doThing, 'Yes'))
FAQ
Como poderei acionar um trabalho se um trabalho anterior tiver sido concluído com problemas?
Você pode usar o resultado do trabalho anterior em uma condição. Por exemplo, no YAML a seguir, a condição eq(dependencies.A.result,'SucceededWithIssues')
permite que o trabalho B
seja executado porque o trabalho A
foi bem-sucedido com problemas.
jobs:
- job: A
displayName: Job A
continueOnError: true # next job starts even if this one fails
steps:
- script: echo Job A ran
- script: exit 1
- job: B
dependsOn: A
condition: eq(dependencies.A.result,'SucceededWithIssues') # targets the result of the previous job
displayName: Job B
steps:
- script: echo Job B ran
Eu cancelei minha compilação, mas ela ainda está em execução. Porquê?
Você pode enfrentar esse problema se uma condição configurada em um estágio não incluir uma função de verificação de status do trabalho. Para resolver o problema, adicione uma função de verificação de status do trabalho à condição.
Se você cancelar um trabalho enquanto ele estiver no estágio de fila, mas não estiver em execução, todo o trabalho será cancelado, incluindo todos os outros estágios. Para obter mais informações, consulte Resultados da condição quando uma compilação é cancelada anteriormente neste artigo.