Especificar condições

Azure DevOps Services | Azure DevOps Server 2020 | Azure DevOps Server | 2019 TFS 2018

Você pode especificar as condições sob as quais cada estágio, trabalho ou etapa é executado. Por padrão, um trabalho ou estágio será executado se ele não depender de nenhum outro trabalho ou estágio, ou se todos os trabalhos ou estágios dos quais ele depende foram concluídos e bem-sucedidos. Por padrão, uma etapa será executada se nada em seu trabalho tiver falhado ainda e a etapa imediatamente anterior à sua conclusão. Você pode personalizar esse comportamento forçando um estágio, trabalho ou etapa a ser executado mesmo se uma dependência anterior falhar ou especificando uma condição personalizada.

Observação

Em Microsoft Team Foundation Server (TFS) 2018 e versões anteriores, pipelines de build e lançamento são chamados de definições, execuções são chamadas de builds, conexões de serviço são chamadas de pontos de extremidade de serviço, estágios são chamados de ambientes e trabalhos são chamados de fases.

Você pode especificar condições sob as quais uma etapa, trabalho ou estágio será executado.

  • Somente quando todas as dependências anteriores com o mesmo pool de agentes tiverem sido bem-sucedidas. Se você tiver pools de agentes diferentes, esses estágios ou trabalhos serão executados simultaneamente. Esse será o padrão se não houver uma condição definida no YAML.

  • Mesmo que uma dependência anterior tenha falhado, a menos que a execução tenha sido cancelada. Use succeededOrFailed() no YAML para essa condição.

  • Mesmo que uma dependência anterior tenha falhado, mesmo que a execução tenha sido cancelada. Use always() no YAML para essa condição.

  • Somente quando uma dependência anterior tiver falhado. Use failed() no YAML para essa condição.

  • Condições personalizadas

Por padrão, etapas, trabalhos e estágios são executados se todas as etapas/trabalhos anteriores tiverem sido bem-sucedidos. É como se você tivesse especificado "condição: êxito()" (consulte funções de status do trabalho).

jobs:
- job: Foo

  steps:
  - script: echo Hello!
    condition: always() # this step will always run, even if the pipeline is canceled

- job: Bar
  dependsOn: Foo
  condition: failed() # this job will only run if Foo fails

Você também pode usar variáveis em condições.

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)

As condições são avaliadas para decidir se devem iniciar um estágio, um trabalho ou uma etapa. Isso significa que nada calculado no runtime dentro dessa unidade de trabalho estará disponível. Por exemplo, se você tiver um trabalho que define uma variável usando uma expressão de runtime usando $[ ] sintaxe, não poderá usar essa variável em sua condição personalizada.

O YAML ainda não tem suporte no TFS.

Habilitar uma condição personalizada

Se as condições internas não atenderem às suas necessidades, você poderá especificar condições personalizadas.

As condições são gravadas como expressões em pipelines YAML. O agente avalia a expressão começando com a função mais interna e trabalha sua saída. O resultado final é um valor booliano que determina se a tarefa, o trabalho ou o estágio devem ser executados ou não. Consulte o tópico de expressões para obter um guia completo sobre a sintaxe.

Alguma de suas condições possibilita que a tarefa seja executada mesmo depois que o build for cancelado por um usuário? Nesse caso, especifique um valor razoável para cancelar o tempo limite para que esses tipos de tarefas tenham tempo suficiente para serem concluídas depois que o usuário cancelar uma execução.

Exemplos

Executar para o branch principal, se tiver êxito

and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))

Executar se o branch não for principal, se tiver êxito

and(succeeded(), ne(variables['Build.SourceBranch'], 'refs/heads/main'))

Executar para branches de tópico do usuário, se tiver êxito

and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/heads/users/'))

Executar para builds de CI (integração contínua) se tiver êxito

and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'))

Executar se o build for executado por uma política de branch para uma solicitação de pull, se estiver falhando

and(failed(), eq(variables['Build.Reason'], 'PullRequest'))

Execute se o build estiver agendado, mesmo se estiver falhando, mesmo se for cancelado

and(always(), eq(variables['Build.Reason'], 'Schedule'))

Lançamento. Artifacts. {artifact-alias}. SourceBranch é equivalente a Build.SourceBranch.

Executar se uma variável for definida como true

condition: eq(variables['System.debug'], 'true')

Executar se uma variável for nula (cadeia de caracteres vazia)

Como todas as variáveis são tratadas como cadeias de caracteres em Azure Pipelines, uma cadeia de caracteres vazia é equivalente a null neste pipeline.

variables:
- name: testEmpty
  value: ''

jobs:
  - job: A
    steps:
    - script: echo testEmpty is blank
    condition: eq(variables.testEmpty, '')

Usar um parâmetro de modelo como parte de uma condição

Quando você declara um parâmetro no mesmo pipeline que você tem uma condição, a expansão do parâmetro ocorre antes que as condições sejam consideradas. Nesse caso, você pode inserir parâmetros dentro das condições. O script neste arquivo YAML será 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'))

No entanto, quando você passa um parâmetro para um modelo, o parâmetro não terá um valor quando a condição for avaliada. Como resultado, se você definir o valor do parâmetro nos arquivos YAML do modelo e do pipeline, o valor do modelo será usado em sua condiçã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: and(succeeded(), eq('${{ parameters.doThing }}', 'true'))
# azure-pipeline.yml
parameters:
- name: doThing
  default: true 
  type: boolean

trigger:
- none

extends:
  template: parameters.yml

A saída desse pipeline ocorre I did a thing porque o parâmetro doThing é verdadeiro.

Usar a variável de saída de um trabalho em uma condição em um trabalho subsequente

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.

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."

Usar a variável de pipeline criada a partir de uma etapa em uma condição em uma etapa subsequente

Você pode disponibilizar uma variável para etapas futuras e especificá-la em uma condição. Por padrão, as variáveis criadas a partir de uma etapa estão disponíveis para etapas futuras e não precisam ser marcadas como variáveis de saída de vários trabalhos usando isOutput=true.

Há algumas coisas importantes a serem observadas em relação à abordagem e ao escopo acima:

  • As variáveis criadas em uma etapa em um trabalho terão como escopo as etapas no mesmo trabalho.
  • As variáveis criadas em uma etapa só estarão disponíveis nas etapas subsequentes como variáveis de ambiente.
  • As variáveis criadas em uma etapa não podem ser usadas na etapa que as define.

Veja abaixo um exemplo de como criar uma variável de pipeline em uma etapa e usar a variável na condição e no script de uma etapa subsequente.

steps:

# This step creates a new pipeline variable: doThing. This variable will be available to subsquent steps.
- bash: |
    echo "##vso[task.setvariable variable=doThing]Yes"
  displayName: Step 1

# This step is able to use doThing, so it uses it in its condition
- script: |
    # You can 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'))

Perguntas frequentes

Tenho uma etapa condicional que é executada mesmo quando um trabalho é cancelado. Minha etapa condicional afeta um trabalho que cancelei na fila?

Não. Se você cancelar um trabalho enquanto ele estiver na fila, todo o trabalho será cancelado, incluindo etapas condicionais.

Tenho uma etapa condicional que deve ser executada mesmo quando a implantação for cancelada. Como fazer especificar isso?

Se você definiu os pipelines usando um arquivo YAML, isso terá suporte. Esse cenário ainda não tem suporte para pipelines de lançamento.

Como posso disparar um trabalho se um trabalho anterior teve êxito com problemas?

Você pode usar o resultado do trabalho anterior. Por exemplo, neste arquivo YAML, a condição eq(dependencies.A.result,'SucceededWithIssues') permite que o trabalho 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

Tenho uma etapa condicional que é executada mesmo quando um trabalho é cancelado. Como fazer conseguir cancelar todos os trabalhos de uma só vez?

Você terá esse problema se a condição configurada no 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 na fila, todo o trabalho será cancelado, incluindo todos os outros estágios, com essa função configurada. Para obter mais informações, consulte as funções de status do trabalho.

stages:
- stage: Stage1
  displayName: Stage 1
  dependsOn: []
  condition: and(contains(variables['build.sourceBranch'], 'refs/heads/main'), succeeded())
  jobs:
  - job: ShowVariables
    displayName: Show variables
    steps:
    - task: CmdLine@2
      displayName: Show variables
      inputs:
        script: 'printenv'

- stage: Stage2
  displayName: stage 2
  dependsOn: Stage1
  condition: contains(variables['build.sourceBranch'], 'refs/heads/main')
  jobs:
  - job: ShowVariables
    displayName: Show variables 2
    steps:
    - task: CmdLine@2
      displayName: Show variables 2
      inputs:
        script: 'printenv'
          
- stage: Stage3
  displayName: stage 3
  dependsOn: Stage2
  condition: and(contains(variables['build.sourceBranch'], 'refs/heads/main'), succeeded())
  jobs:
  - job: ShowVariables
    displayName: Show variables 3
    steps:
    - task: CmdLine@2
      displayName: Show variables 3
      inputs:
        script: 'printenv'