como posso usar o IF ELSE em variáveis ​​do pipeline do yaml do DevOps com grupo de variáveis?

8

Estou tentando atribuir um dos 2 valores a uma variável, além do grupo de variáveis, e não consigo encontrar a referência de como usar o IF ELSE.

Basicamente, preciso converter essa lógica de jerkins no DevOps do Azure.

Jenkins

if (branch = 'master') { 
   env = 'a'
} else if (branch = 'dev'){
    env ='b'
}

Eu encontrei uma referência da seguinte, mas essa parece funcionar se a seção de variáveis ​​não tiver grupos de variáveis.

https://stackoverflow.com/a/57532526/5862540

Mas no meu pipeline, eu já tenho um grupo de variáveis ​​para segredos, então tenho que usar a convenção de nome / valor e o exemplo não funciona com erros como expected a mappingou A mapping was not expectedouUnexpected value 'env'

variables:
- group: my-global
- name: env
  value:
    ${{ if eq(variables['Build.SourceBranchName'], 'master') }}: 
      env: a
    ${{ if eq(variables['Build.SourceBranchName'], 'dev') }}: 
      env: b

ou

variables:
- group: my-global
- name: env
  value:
    ${{ if eq(variables['Build.SourceBranchName'], 'master') }}: a
    ${{ if eq(variables['Build.SourceBranchName'], 'dev') }}: b

kevmando
fonte
Uma solução alternativa que tenho agora é copiar as variáveis ​​secion com expressão em todos os trabalhos em que preciso. Mas gostaria de simplificar a variável global.
kevmando

Respostas:

1

Eu acho que por enquanto você precisará usar uma tarefa para personalizar com name/valuevariáveis ​​de sintaxe e valores de variáveis ​​condicionais. Parece que a estrutura do objeto para name/valuesintaxe interrompe a análise de expressões, como você apontou.

Para mim, a seguir é uma implementação razoavelmente limpa e, se você quiser abstraí-la do pipeline, parece que um modelo simples para seus muitos pipelines usar deve satisfazer o desejo de um local "global" central.

variables:
  - group: FakeVarGroup
  - name: env
    value: dev

steps:
  - powershell: |
      if ($env:Build_SourceBranchName -eq 'master') {
        Write-Host ##vso[task.setvariable variable=env;isOutput=true]a
        return
      } else {
        Write-Host ##vso[task.setvariable variable=env;isOutput=true]b
      }      
    displayName: "Set Env Value"
Josh Gust
fonte
Obrigado pela sugestão. Acho que já vi uma solução semelhante daqui, mas não tentei, porque espero que exista uma solução mais simples sem adicionar uma etapa. Também pedi suporte à Microsoft, portanto, se eles não tiverem solução, tentarei isso.
Kevmando
Eu havia trocado e-mails com o suporte da MS e eles acabaram sugerindo essa solução alternativa e me pediram para inserir sugestões de recursos para a comunidade de desenvolvedores da MS. Então, vou marcar isso como resposta agora.
kevmando
0

Até onde eu sei, a melhor maneira de criar uma ramificação condicional é usar "trigger" em sua YAML, em vez de implementar "if-else" complexo. Também é muito mais seguro, e você tem controles mais explícitos nos gatilhos de ramificação, em vez de confiar nas variáveis ​​de IC.

Exemplo:

# specific branch build 
jobs:
- job: buildmaster
  pool:
    vmImage: 'vs2017-win2016'
  trigger:
    - master

  steps:
  - script: |
      echo "trigger for master branch"

- job: buildfeature
  pool:
    vmImage: 'vs2017-win2016'
  trigger:
    - feature

  steps:
  - script: |
      echo "trigger for feature branch"

Para ter gatilho com inclusão e exclusão de ramificações, você pode usar uma sintaxe mais complexa de gatilho com inclusão e exclusão de ramificações.

Exemplo:

# specific branch build
trigger:
  branches:
    include:
    - master
    - releases/*
    exclude:
    - releases/1.*

A documentação oficial dos Pipelines do Azure DevOps triggerno YAML é: Documentação do acionador do Azure Pipelines YAML

ATUALIZAÇÃO 1 :

Reposto meu comentário aqui com notas adicionais: Eu estava pensando em ter pipelines diferentes, porque a complexidade do malabarismo entre variáveis ​​de IC não é mais sustentável do que ter várias tarefas em um YAML com gatilhos. Ter vários empregos com gatilhos também está nos forçando a ter uma distinção e provisão claras no gerenciamento de filiais. Os gatilhos e inclusões de ramificações condicionais são usados ​​há um ano pela minha equipe devido a essas vantagens de manutenção.

Sinta-se à vontade para discordar, mas, para mim, ter uma lógica incorporada em qualquer script e em todas as etapas para verificar qual ramificação está atualmente em sessão e executar outras ações é mais como soluções ad-hoc. E isso deu a minha equipe e a mim problemas de manutenção antes.

Especialmente se a lógica incorporada tende a crescer verificando outras ramificações, a complexidade é mais complexa depois do que ter separações claras entre ramificações. Além disso, se o arquivo YAML for mantido por muito tempo, ele deverá ter disposições e roteiros claros em diferentes ramificações. A redundância é inevitável, mas a intenção de separar uma lógica específica pagará mais a longo prazo pela manutenção.

É por isso que também enfatizo inclusões e exclusões de ramos na minha resposta :)

Eriawan Kusumawardhono
fonte
Obrigado pela sugestão, mas meu pipeline também já usou gatilhos para fins diferentes. (Para ser honesto, o recurso de gatilho parece menos flexível, além de ser comparado ao Jenkins. Difícil de implementar as condições, como o cancelamento da compilação pr / branch duplicada etc.) Também haverá muitas linhas redundantes, se for necessário. repita os mesmos trabalhos novamente apenas para alterar um único valor por filial. (Eu também pode solução alternativa para as seções das variáveis de repetição, o que seria menos código redundante.)
kevmando
Talvez eu precise pensar fora da caixa de 'jenkins', já que não é Jenkins, mas a equipe não gosta de ter um novo pipeline sem nenhuma vantagem aparente.
Kevmando
Novo pipeline? Não. O YAML está em um arquivo, portanto, pode ser usado em um pipeline que pode atender a muitos ramos,
Eriawan Kusumawardhono 13/11/19
O que eu quis dizer como novo pipeline é que o novo fluxo de trabalho funciona diferente do fluxo de trabalho anterior. Não está relacionado com este tópico, mas com mais opções de acionador, uma vez que foi mencionado aqui.
Kevmando #
O OP não está perguntando como acionar uma compilação com base em um valor da ramificação. A pergunta feita foi como condicionar um valor variável com base no contexto em que o pipeline é acionado. Sua solução, quando aplicada à pergunta real, força o OP a criar 2 pipelines 1) trigger = master & env = a 2) trigger = dev & env = b.
Josh Gust