Especificar condições

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

Pode especificar as condições em que cada fase, trabalho ou passo corre. Por defeito, um trabalho ou estágio funciona se não depender de qualquer outro trabalho ou estágio, ou se todos os trabalhos ou fases de que depende tiverem concluído e sucedido. Por defeito, um passo corre se nada no seu trabalho ainda falhou e o passo imediatamente anterior a ter terminado. Você pode personalizar este comportamento forçando um estágio, trabalho ou passo para correr mesmo que uma dependência anterior falhe ou especificando uma condição personalizada.

Nota

No Microsoft Team Foundation Server (TFS) 2018 e nas versões anteriores, os oleodutos de construção e libertação são chamados definições, as corridas são chamadas de construções, as ligações de serviço são chamadas pontos finais de serviço, as fases são chamadas de ambientes, e os empregos são chamados de fases.

Pode especificar as condições em que um passo, trabalho ou estágio serão executados.

  • Só quando todas as dependências anteriores com o mesmo grupo de agentes foram bem sucedidas. Se tiver piscinas de agentes diferentes, essas fases ou empregos serão executados simultaneamente. Este é 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 corrida tenha sido cancelada. Utilização succeededOrFailed() no YAML para esta condição.

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

  • Só quando uma dependência anterior falhou. Utilização failed() no YAML para esta condição.

  • Condições personalizadas

Por defeito, as etapas, os postos de trabalho e as etapas funcionam se todos os passos/postos de trabalho anteriores tiverem sido bem sucedidos. É como se tivesse especificado "condição: bem sucedida".

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

Também pode utilizar 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 iniciam uma fase, trabalho ou passo. Isto significa que nada calculado no tempo de funcionação dentro dessa unidade de trabalho estará disponível. Por exemplo, se tiver um trabalho que define uma variável usando uma expressão de tempo de execução usando $[ ] sintaxe, não pode usar essa variável na sua condição personalizada.

A YAML ainda não está apoiada na TFS.

Ativar uma condição personalizada

Se as condições incorporadas não satisfaçam as suas necessidades, então pode especificar as condições personalizadas.

As condições são escritas como expressões nos oleodutos YAML. O agente avalia a expressão começando com a função mais interna e trabalha para sair. O resultado final é um valor booleano que determina se a tarefa, o trabalho ou o estágio devem ou não funcionar. Consulte o tópico das expressões para obter um guia completo da sintaxe.

Alguma das suas condições permite que a tarefa seja executada mesmo depois de a construção ser cancelada por um utilizador? Em caso afirmativo, especifique um valor razoável para cancelar o tempo limite de modo a que este tipo de tarefas tenha tempo suficiente para completar após o utilizador cancelar uma execução.

Exemplos

Correr para o ramo principal, se tiver sucesso

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

Corra se o ramo não for principal, se tiver sucesso

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

Corra para os ramos de tópicos de utilizador, se tiver sucesso

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

Executar para integração contínua (CI) constrói se for bem sucedido

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

Executar se a construção é gerida por uma política de filial para um pedido de puxar, se falhar

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

Corra se a construção estiver programada, mesmo que falhe, mesmo que cancelada

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

Release.Artifacts. {artefacto-alias}. SourceBranch é equivalente a Build.SourceBranch.

Executar se uma variável é definida como verdadeira

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

Executar se uma variável for nula (corda vazia)

Uma vez que todas as variáveis são tratadas como cordas em Gasodutos Azure, uma corda vazia é equivalente a null neste oleoduto.

variables:
- name: testEmpty
  value: ''

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

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

Quando declara um parâmetro no mesmo oleoduto de que tem uma condição, a expansão dos parâmetros ocorre antes de as condições serem consideradas. Neste caso, pode incorporar parâmetros dentro das condições. O script neste ficheiro YAML será executado porque parameters.doThing é verdade.

parameters:
- name: doThing
  default: true
  type: boolean

steps:
- script: echo I did a thing
  condition: and(succeeded(), eq('${{ parameters.doThing }}', 'true'))

No entanto, quando se passa um parâmetro para um modelo, o parâmetro não terá um valor quando a condição for avaliada. Como resultado, se definir o valor do parâmetro tanto no modelo como nos ficheiros YAML do pipeline, o valor do modelo será utilizado na 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 deste oleoduto é I did a thing porque o parâmetro doThing é verdadeiro.

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

Pode disponibilizar uma variável para empregos futuros e especificá-la em condições. As variáveis disponíveis para empregos futuros devem ser marcadas como variáveis de produção multi-emprego utilizando 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."

Use a variável de gasoduto criada a partir de um passo em uma condição em um passo subsequente

Pode disponibilizar uma variável para passos futuros e especificá-la em condições. Por padrão, as variáveis criadas a partir de um passo estão disponíveis para etapas futuras e não precisam de ser marcadas como variáveis de saída multi-trabalho utilizando isOutput=true.

Há algumas coisas importantes a notar sobre a abordagem acima e scoping:

  • As variáveis criadas num passo num trabalho serão adidas aos passos no mesmo trabalho.
  • As variáveis criadas num passo só estarão disponíveis em etapas subsequentes como variáveis ambientais.
  • As variáveis criadas num passo não podem ser usadas no passo que as define.

Abaixo está um exemplo de criação de uma variável de pipeline em um passo e usar a variável em uma condição e script 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'))

FAQ

Tenho um passo condicional que corre mesmo quando um trabalho é cancelado. O meu passo condicional afeta um trabalho que cancelei na fila?

N.º Se cancelares um trabalho enquanto está na fila, todo o trabalho está cancelado, incluindo passos condicional.

Tenho um passo condicional que deve ser executado mesmo quando a implantação for cancelada. Como devo proceder para especificar isto?

Se definiu os oleodutos utilizando um ficheiro YAML, então este é suportado. Este cenário ainda não é suportado para os oleodutos de libertação.

Como posso desencadear um emprego se um trabalho anterior foi bem sucedido com problemas?

Pode usar o resultado do trabalho anterior. Por exemplo, neste ficheiro YAML, a condição eq(dependencies.A.result,'SucceededWithIssues') permite que o trabalho seja executado porque Job A conseguiu 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 um passo condicional que corre mesmo quando um trabalho é cancelado. Como devo proceder para consegue cancelar todos os empregos ao mesmo tempo?

Você vai experimentar este problema se a condição configurada no palco não incluir uma função de verificação do estado do trabalho. Para resolver o problema, adicione uma função de verificação do estado do trabalho à condição. Se cancelar um trabalho enquanto está na fila, todo o trabalho é cancelado, incluindo todas as outras fases, com esta função configurada. Para mais informações, consulte as funções de estado 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'