Pular para conteúdo

0027 — CI/CD 100% GitHub Actions

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-09-12 · Decidido em: 2026-08-31

Contexto

O CI/CD dos apps rodava em dois lugares: o gate/docs/release no runner Forgejo self-hosted (dind + fábrica de imagens ci-images, 0003) e o build/deploy no GitHub Actions (0022 / 0026). O runner Forgejo:

  • roda na VM de produção — a fábrica dind empilha imagem eterna e o CI concorre CPU/RAM com os apps: é o gatilho do freeze/thrash do host (backlog itens 134/138);
  • não resolve actions de marketplace (subosito/flutter-action → 404), forçando git clone manual do SDK Flutter e a fábrica só pra assar toolchain;
  • exige infra frágil (socket dind, insecure-registries, Traefik afrouxado p/ push multi-GB).

Migrando o compute de CI pro GitHub, actions/setup-java + gradle/actions/setup-gradle + subosito/flutter-action cobrem a toolchain, o Testcontainers roda no docker nativo do runner, e a fábrica + o runner + o dind saem da VM de produção. Três pilotos provaram, com gate verde: webstorm-ecom (Java native), int-sascar (Java jar-only), onpetro-bi (Flutter web).

Decisão

O CI/CD dos apps é 100% GitHub Actions, num pipeline.yml único por repo. A fábrica ci-images/0003 é aposentada para CI; o runner Forgejo + dind desligam ao fim da migração.

  • pipeline.yml único, à la carte (templates/pipeline.yml): funde ci.yml + docs.yml + release.yml (Forgejo) + build-deploy*.yml (GitHub) — decide → gate / docs / build_jar|native|web / release-check / deploy. Blocos opt-in por app.json build.targets; 3 variantes provadas (Java jar, Java native, Flutter web).

Correção 2026-10-01: o release-check deixou de ser job e virou o último step do gate (só na tag), e o smoke virou o último step do deploy: o GitHub cobra cada job arredondado ao minuto, e os dois duram segundos. O docs espera o gate e, no push de tag, só publica com ele verde. Detalhe em ci-testes. - Toolchain pelas actions, não pela fábrica: setup-java@v5 (temurin 25) + setup-gradle@v4 (Java); subosito/flutter-action@v2 (Flutter). A versão vem do app.json/.fvmrc direto pra a action — sem container:, sem matriz-baseline.json. Testcontainers no docker nativo do runner (cai o hack dind). - Deploy inalterado — control-plane (0026), POST /api/ci/deploy, para todas as variantes, inclusive web. A ponte SSH não entra no pipeline.yml. - Aviso de falha = notificação nativa do GitHub (email ao autor do commit num run falho — o webhook Telegram da org Forgejo sai com o CI; sem step no YAML). Secrets DOCS_S3_* (e afins) = secret POR REPO no GitHub (a conta é user-wide, não org — cada repo cadastra os seus).

Correção 2026-09-02: na tag, o decide liga só os alvos do trailer Deploy: (sem trailer, o build.targets), e push só de doc na master republica a versão vigente — regra em ci-testes.

Fronteira precisa — "0% Forgejo NO CI", não "0% Forgejo". O Forgejo permanece git origin (+ push-mirror gustavoxadm/<repo> que o CI lê), web-edit de Markdown por não-devs, e host de Release-artefato de app cliente offline (ex. integrador-client — a Release é o marco de distribuição; roda no runner GitHub mas POSTa à API do Forgejo). Só o compute de CI (runner + dind + fábrica) sai. Efeito na 0003: o núcleo "imagens por stack+versão" é superseded para CI (a fábrica não serve mais o gate). Efeito na 0026: o web consolida-se como target do control-plane no pipeline.yml.

Alternativas descartadas

  • Manter o híbrido (gate no Forgejo, build no GitHub). Preserva o gatilho do freeze do host e a fábrica só pra assar toolchain, com dind frágil. Preterido — a raiz é o compute na VM de produção.
  • Dois/três templates (um por variante). Duplicam gate/docs/deploy e driftam entre irmãos (a classe de bug dos backlog 84/95/150/153). Preterido — 1 template, blocos opt-in.
  • Deletar a fábrica/páginas no silêncio. A ci-images resolveu problemas reais (Gradle assado, marketplace-404); vira superseded documentado (a 0003 passa a obsoleto), não deleção.

Consequências

  • templates/pipeline.yml rastreado no manifesto; os 4 templates velhos (ci.yml, docs.yml, release.yml, build-deploy*.yml) ficam rastreados como legado até 0 apps no runner Forgejo — aí saem. Cada app migra pelo playbook (publicar-docs / ci-testes).

Correção 2026-09-12: a condição de saída se cumpriu — os templates velhos saíram do kit. - has_actions=false no Forgejo é passo OBRIGATÓRIO da migração: deletar .forgejo/workflows/ não zera o Forgejo (ele lê .github/ também) → PATCH has_actions=false via API (token repo-admin). - matriz-baseline.json morre com a fábrica: a homologação de versão de stack deixa de ser gate; a versão é declaração do app.json (toolchain), validada pela action no run. O gate do pré-flight /xadm-release que cruzava com a baseline sai. - O central migra junto (o build-site.yml deste repo vai pro GitHub; ci-images.yml sai), rumo a 0 apps no runner → runner + dind + fábrica desligam (ação de infra que esta decisão habilita). - Aviso de falha usa a notificação nativa do GitHub (email ao autor) — sem step no YAML, sem secret; o Telegram (webhook da org Forgejo) foi abandonado no CI. - Encaixe constitucional: o gate de CI por stack vive em ci-testes (§5 delega); a norma de entrega/deploy na §9 (control-plane) segue de pé.