← Blog

GitFlow para MuleSoft: regras de branch que o pipeline entende

Projeto de referência: mulesoft-orders-api (aplicação) e azure-devops-mulesoft-pipelines (templates de pipeline). Todo o fluxo descrito nesta série rodou de ponta a ponta, de um branch de feature até produção no CloudHub 2.0.

Um modelo de branches só é útil se todo mundo — pessoas e pipelines — o lê da mesma forma. Esta série monta um fluxo de entrega para aplicações Mule no Azure DevOps em que o nome do branch é a instrução: um push no develop faz deploy em test, e um merge na main gera um release e o promove para uat e produção. Este primeiro artigo apresenta o modelo e os motivos dele.

Por que GitFlow, e quando não usar

Vincent Driessen descreveu o GitFlow em 2010. Em 2020, ele acrescentou uma nota ao texto original: times que entregam continuamente uma única versão, como a maioria das aplicações web, se dão melhor com algo mais simples, como trunk-based development. A nota é justa, e é a primeira coisa a verificar antes de adotar o GitFlow.

Trabalho de integração muitas vezes não se parece com uma aplicação web:

  • Os releases são agendados e dependem de mudanças de outros times entrando em produção ao mesmo tempo.
  • O código passa por vários ambientes, normalmente com uma aprovação antes de produção.
  • Às vezes é preciso corrigir produção enquanto o próximo release ainda está em teste.

O GitFlow foi feito exatamente para isso: separa “o que está em produção” de “o que está sendo preparado” e dá ao hotfix um caminho próprio. Se as suas aplicações Mule vão para produção várias vezes por dia atrás de feature flags, prefira trunk-based — o restante da série continua valendo, com regras de branch mais simples.

Os branches

Branch Criado a partir de Vai para O que o pipeline faz
feature/<ticket>-<desc> develop develop (PR) Build
develop — — Build, publica x.y.z-SNAPSHOT no Exchange, deploy em test
release/x.y.z develop main (PR) Build
main — — Build, Maven release (tag vx.y.z), deploy em uat, deploy em prod após aprovação
hotfix/x.y.z main main (PR) Build

Depois que um release ou hotfix chega à main, um PR de volta main → develop leva a correção e a mudança de versão para o develop.

Duas regras mantêm isso sob controle:

  1. Ninguém edita versão à mão. O develop sempre tem -SNAPSHOT. O pipeline de release remove o sufixo, cria a tag e passa para o próximo -SNAPSHOT (o próximo artigo mostra como).
  2. Ao criar release/x.y.z, suba o develop para o próximo -SNAPSHOT minor na mesma mudança. Senão, os snapshots publicados a partir do develop têm a mesma versão do release em estabilização.

Transformando nome de branch em comportamento

O arquivo de pipeline da aplicação é pequeno de propósito. Todo o resto fica num repositório de templates compartilhado, fixado numa tag:

trigger:
  branches:
    include: [develop, main, feature/*, release/*, hotfix/*]

pr:
  branches:
    include: [develop, main]

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

O template decide quais stages rodam a partir do Build.SourceBranch. O stage de release, por exemplo:

- stage: release
  displayName: Release
  dependsOn: ci
  condition: and(succeeded(),
                 eq(variables['Build.SourceBranch'], 'refs/heads/main'),
                 ne(variables['Build.Reason'], 'PullRequest'))

Um pull request para a main roda só o build, mesmo tendo a main como destino; quem gera o release é o commit de merge.

Uma armadilha: filtros por caminho

A primeira versão do gatilho ignorava mudanças de documentação:

trigger:
  paths:
    exclude: ['*.md', docs/*]

Parece inofensivo. Até o primeiro release — cuja única mudança no branch de release era o CHANGELOG.md — ser mergeado na main e nada acontecer. O filtro vale também para o commit de merge, então a main nunca foi liberada. Filtro por caminho e GitFlow não combinam: todo merge na main precisa rodar, não importa o que ele muda. A correção saiu como o primeiro hotfix do projeto.

Protegendo os branches

main e develop só devem mudar por pull request com build verde. No GitHub (rulesets estão disponíveis no plano gratuito para repositórios públicos):

  • aplique ao branch padrão e ao develop;
  • exija pull request e bloqueie force push e exclusão;
  • exija o status check do pipeline.

Há um porém: o Maven release faz push de dois commits e uma tag direto na main. Quem roda o release precisa poder contornar a regra. O segundo artigo explica as opções; em resumo, esse bypass deve ser o mais estreito que a sua ferramenta permitir.

Checklist

  • Os seus releases precisam mesmo de vários ambientes e aprovações? Se não, considere trunk-based.
  • Dá para saber, pelo nome do branch, o que o pipeline vai fazer com ele?
  • O develop sobe de versão quando um branch de release é criado?
  • Todo merge na main dispara o pipeline, independentemente dos arquivos alterados?
  • Há um back-merge depois de cada release e hotfix?