Templates do Azure Pipelines para MuleSoft: um fluxo de entrega, muitas aplicações
Referência: azure-devops-mulesoft-pipelines (templates, ADRs) · mulesoft-orders-api (consumidor)
Um time com trinta aplicações Mule não deveria ter trinta cópias do mesmo pipeline. Quando o processo de entrega muda — uma checagem nova, um ambiente novo, uma correção como a do artigo anterior — ele deve mudar num lugar só, e cada aplicação escolhe quando adotar a mudança. Os templates do Azure Pipelines permitem isso, desde que o repositório esteja organizado para isso.
Dois repositórios
- Repositório de templates — o processo de entrega. Versionado com tags (
v1.0.0,v1.0.1,v1.1.0). - Repositório da aplicação — a app Mule e um
azure-pipelines.ymlde dez linhas que estende uma versão com tag dos templates.
resources:
repositories:
- repository: templates
type: github
endpoint: github.com_brunosouzas
name: brunosouzas/azure-devops-mulesoft-pipelines
ref: refs/tags/v1.1.0
extends:
template: templates/stages/gitflow.yml@templates
parameters:
nextVersionBump: minor
Fixar numa tag é a parte importante. Uma mudança nos templates nunca altera o pipeline de uma aplicação até ela mudar o ref. Durante este projeto, o job de release foi corrigido na v1.0.1 e um smoke test entrou na v1.1.0; a aplicação adotou cada uma por um pull request normal.
Usar extends, e não template: dentro de stages:, é proposital: a aplicação não consegue acrescentar passos antes ou depois do fluxo governado, o que importa quando os templates carregam controles que todo mundo precisa rodar.
Organização dos templates
templates/
stages/gitflow.yml ponto de entrada: quais stages rodam, a partir do branch
jobs/ci.yml build e empacotamento
jobs/publish-snapshot.yml develop → Exchange
jobs/release.yml Maven release na main
jobs/deploy.yml deploy de uma versão do Exchange no CloudHub 2.0
steps/setup-maven.yml Java 17, cache do Maven, settings.xml
docs/adr/ os motivos de cada escolha
Stages decidem quando, jobs decidem o quê, steps são as peças reutilizáveis. Decisões que ficariam na cabeça de alguém — por que o release roda na main, por que nada é reconstruído por ambiente — viram ADRs ao lado do código.
Segredos sem secure files
O Maven precisa de credenciais para o Exchange. Uma abordagem comum guarda um settings.xml inteiro como secure file. Os templates geram o arquivo durante a execução, a partir de um variable group:
- bash: |
cat > "${SETTINGS_PATH}" <<XML
<settings>
<servers>
<server>
<id>anypoint-exchange-v3</id>
<username>~~~Client~~~</username>
<password>${ANYPOINT_CLIENT_ID}~?~${ANYPOINT_CLIENT_SECRET}</password>
</server>
</servers>
</settings>
XML
env:
ANYPOINT_CLIENT_ID: $(ANYPOINT_CLIENT_ID)
ANYPOINT_CLIENT_SECRET: $(ANYPOINT_CLIENT_SECRET)
~~~Client~~~ com clientId~?~clientSecret é a forma de o Exchange aceitar um Connected App no lugar de um usuário. O Connected App precisa de Exchange Contributor, dos escopos de deploy do Runtime Manager e de acesso a cada ambiente de destino. O segredo fica no variable group vg-00-anypoint-platform, marcado como secreto, então aparece mascarado nos logs — e variáveis secretas precisam ser mapeadas explicitamente em env, como acima.
Por que o MUnit não está neste pipeline
O MUnit roda no runtime Enterprise do Mule, que o Maven baixa do repositório Enterprise da MuleSoft. O acesso vem com a assinatura de cliente, e as credenciais pertencem a esse cliente.
Este é um projeto pessoal e público. Eu poderia ter usado as credenciais de um empregador — protegidas num secure file, ninguém as veria —, mas isso seria usar a licença dele fora do negócio dele. Então o pipeline faz o build com -DskipMunitTests, o MUnit roda localmente antes de cada pull request (mvn clean test, seis testes, 100% de cobertura) e o template de PR pede essa verificação. Num pipeline de empresa, a mudança são duas linhas: fornecer as credenciais do repositório Enterprise e tirar a flag. O ADR 4 registra a decisão.
Vale confirmar que o resto funciona sem essas credenciais. Empacotar a app com um settings.xml vazio e um repositório Maven local vazio dá certo: só o MUnit precisa do repositório Enterprise.
Uma falha enganosa do MUnit
Ao escrever os testes locais, a suíte se recusou a subir. O primeiro erro do log era:
[global.xml:15]: Connection is not secure. Should use `HTTPS`
Isso é um aviso das validações do conector HTTP, e aparece também em projetos saudáveis. O erro real estava na linha seguinte: um teste chamado create-order, com o mesmo nome de um flow. Os testes MUnit compartilham o namespace global da aplicação. Com prefixo nos nomes dos testes (test-create-order), a suíte roda.
Projeto privado, evidência pública
A Microsoft não permite mais que esta organização crie projetos públicos no Azure DevOps, então o projeto é privado. A evidência continua pública: cada execução é reportada ao GitHub como um check no commit ou no pull request, e os badges de status no README podem ser lidos sem login.
Checklist
- O pipeline de cada aplicação é um
extendsenxuto de uma versão com tag dos templates? - Os templates podem mudar sem alterar silenciosamente todas as aplicações?
- As credenciais são geradas durante a execução, a partir de variáveis secretas mapeadas explicitamente em
env? - As decisões por trás dos templates estão escritas ao lado deles?