Release do produto
Como o Brabo, que vive em vários repositórios
viralabs-dev/brabo*, publica uma versão do produto (AT-704, EP-033). Cada repositório tem a versão dele; o produto tem a dele, nobrabo. Todos recomeçam em1.0.0. Esta página é a visão de conjunto; o detalhe das imagens e da assinatura está em Cadeia de suprimentos do CI.
As três etapas
- Cada repositório carimba a própria tag. A cada push em
devemain, o workflowtag-release.ymldo repositório chama otag-release.ymlreutilizável dobrabo-ci, pinado por SHA. O reutilizável calcula a versão pela função da branch (breaking/sobe o MAJOR,feature/o MINOR, o resto o PATCH) e empurra a tag com o token do GitHub App do bot (BRABO_APP_ID/BRABO_APP_PRIVATE_KEY, secrets da organização). É um token de App, e não oGITHUB_TOKEN, porque só ele faz a tag disparar o workflow de publicação. - Os repositórios de imagem publicam. Na tag final,
brabo-api,brabo-engine,brabo-web,brabo-brokerebrabo-infra(a imagem de backup) constroem a imagem, escaneiam com o Trivy antes de assinar, assinam por digest com o cosign keyless e verificam a assinatura no mesmo run. Anexam à Release deles oimagem.json({imagem, tag, digest}), que é o contrato com o produto. Obrabo-runnernão publica imagem: anexa os binários e umchecksums.txtassinado pelobuild-runner-binaries.ymldele. - O
brabomonta a release do produto. Orelease.ymllê ocomponentes.json(a tag de cada componente), baixa oimagem.jsonde cada Release, monta oimages.json(scripts/ci/montar-images.ts), escaneia as imagens por digest com o Trivy, juntainstall.she os assetsbrabo-install-*e assina umchecksums.txt(cosign keyless, identidade dorelease.ymldobrabo). É esse manifesto que oinstall.shconfere. O binário do runner é conferido à parte, contra ochecksums.txtassinado dobrabo-runnerna tag que ocomponentes.jsonfixa em.runner.tag.
flowchart LR
subgraph apps["Repositórios de imagem e runner"]
A["brabo-api / engine / web / broker / infra"]
R["brabo-runner"]
end
CI["brabo-ci<br/>tag-release (token do App)"]
CI -->|"carimba vX.Y.Z"| A
CI -->|"carimba vX.Y.Z"| R
A -->|"build, Trivy, cosign por digest<br/>imagem.json na Release"| IMG[("ghcr.io/viralabs-dev/brabo-*")]
R -->|"binários + checksums.txt assinado"| RB[("Release do brabo-runner")]
CI -->|"carimba vX.Y.Z"| B["brabo"]
B -->|"componentes.json + imagem.json de cada app<br/>images.json, Trivy por digest<br/>assina checksums.txt"| REL[("Release do produto")]
REL --> INST["install.sh"]
INST -->|"binário do runner, cosign contra build-runner-binaries.yml"| RB
INST -->|"imagens por digest"| IMG
O portão
A variável de repositório PRODUTO_RELEASE_LIGADA=true no brabo é a única chave que carimba a tag
e publica a Release do produto. Com ela desligada, tag-release.yml e o release.yml não rodam
(salvo o ensaio abaixo). Quem liga é o dono.
Ensaio. workflow_dispatch do release.yml num ramo, com o campo tag vazio, monta e confere
tudo o que for possível, mas não assina nem publica, e roda mesmo com o portão desligado. Sem a
Release de cada componente, as imagens não são montadas e o Trivy e a verificação das imagens ficam
para a primeira tag.
O que componentes.json fixa
| Campo | Para quê |
|---|---|
infra |
repositório e ref de onde vêm o compose, o .trivyignore.yaml e o trivy-do-release.ts |
imagens.<alvo> |
repositório, tag e imagem de cada componente de imagem; o imagem.json precisa bater |
runner |
repositório e tag do brabo-runner; o install.sh baixa o binário dali (RUNNER_TAG, conferido por scripts/dev/install-runner-release.spec.ts) |
Subir um componente é editar a tag aqui, num PR, e o produto sai com ela na próxima tag. Cinco de
cinco imagens ou nenhuma: Release de produto com componente sem imagem.json é recusada.
Decisões que ainda não estão tomadas
TODO(humano): quem decide, e em que ordem, o momento de ligar
PRODUTO_RELEASE_LIGADAe carimbar as primeiras tagsv1.0.0dos repositórios (a ordem importa: obraboprecisa que as Releases dos componentes existam antes da dele).
TODO(humano): o
componentes.jsoné editado à mão; falta decidir se um bot o atualiza quando um componente carimba tag nova ou se continua sendo decisão de PR.
Hotfix de um componente
O hotfix é PATCH pela escada normal (decisão do dono, AT-728); não se usa hotfix/ direto na main.
- O componente corrige pela própria
dev→maine ganhavX.Y.Z+1. - Uma PR no
brabosobe a tag do componente nocomponentes.json. - A promoção do
brabosai como patch do produto.