CI/CD — GitHub Actions
Todos os repositórios da org cactus-agents usam GitHub Actions para CI e deploy.
:::tip Documentação dedicada de deploy O fluxo de deploy (modelo caller+reusable, branch governance, multi-account) e os passo a passo de adicionar environment / brand / conta CF vivem na seção Deploy. Este doc é um panorama de CI/CD da org. :::
Workflows por repositório
front-cactus-core (SDK)
| Workflow | Trigger | O que faz |
|---|---|---|
ci.yml | Push em main, PRs | Lint → Check → Build → Test |
release.yml | Push em main (com changesets pendentes) | Build → Changesets (cria PR ou publica) |
front-web-base (Template) e forks
| Workflow | Trigger | O que faz |
|---|---|---|
ci-deploy.yml | Push/PR (main, stage, dev, performance, sports e variantes *-), workflow_dispatch | quality (lint/check/typecheck/test) + config-lint (PRs) + resolve-matrix + deploy (chama reusable do front-ops) |
list-environments.yml | workflow_dispatch | Viewer read-only da topologia de envs declarada no front-ops |
lighthouse.yml | (auditoria) | Auditoria Lighthouse |
delete-merged-branch.yml | Branch mergeada | Limpeza de branches |
:::info Workflow único
O CI e o deploy do front-web-base ficam no mesmo arquivo ci-deploy.yml
(não há quality.yml/deploy.yml separados). O job quality roda em todo
trigger; o deploy só fora de PR e quando a matriz resolve algum env.
:::
front-ops (Deploy centralizado)
| Workflow | Trigger | O que faz |
|---|---|---|
deploy.yml | workflow_call (chamado pelos forks) | Valida config por brand/repo → resolve CF account/zona → checkout fork → build → deploy no Cloudflare Workers → purge + warm-up |
deploy-docs.yml | workflow_call | Deploy do front-cactus-docs |
deploy-affiliates.yml | workflow_call | Deploy do cactus-affiliates |
manual-cache-purge.yml | workflow_dispatch | Purge manual de cache |
Modelo de deploy
O deploy segue um modelo caller + reusable workflow (detalhes completos em Deploy → Visão Geral):
- O caller
ci-deploy.ymlroda o quality gate, resolve a matriz de envs lendo ofront-ops, e chamacactus-agents/front-ops/.github/workflows/deploy.yml@mainuma vez por environment. - O reusable no
front-opsacha a brand cujorepo:bate com o caller e lêconfig/brands/<brand>/environments/<env>/deploy.yml(com fallbacks debrand.yml::defaults). - Resolve
worker_name,cf_account,cf_zonee demais campos. - Resolve as credenciais Cloudflare a partir do
cf_account(ver Multi-account Cloudflare). - Faz checkout do fork, instala dependências, builda e deploya — depois purga cache e faz warm-up.
Estrutura atual no front-ops (uma brand = um repo; um env = uma pasta):
config/
cache/defaults.yml # política de cache global
brands/<brand>/
brand.yml # identidade + defaults (declara `repo:`)
cache.yml # overrides de cache da brand (opcional)
environments/<env>/
deploy.yml # config do env (fonte de verdade)
cache.yml # overrides de cache do env (opcional)
:::caution Mudou desde versões antigas desta doc
Não existe mais repos.yml. Cada environment é uma pasta própria com deploy.yml.
O caller também não passa um input ref — o branch deployado é sempre o
default_branch declarado no front-ops (ver
branch governance).
:::
# ci-deploy.yml no caller — job que chama o reusable
deploy:
name: ${{ matrix.environment }}
needs: [quality, resolve-matrix]
if: needs.resolve-matrix.outputs.deploy_needed == 'true'
strategy:
fail-fast: false
matrix:
include: ${{ fromJson(needs.resolve-matrix.outputs.matrix) }}
uses: cactus-agents/front-ops/.github/workflows/deploy.yml@main
with:
environment: ${{ matrix.environment }}
secrets: inherit
O fork não contém lógica de resolução de worker name, tokens do Cloudflare ou pipeline de build/deploy.
Multi-account Cloudflare
O deploy suporta múltiplas contas Cloudflare. Cada environment pode apontar para uma conta CF diferente usando o campo cf_account no environments/<env>/deploy.yml (ou como default em brand.yml).
Como funciona
- O campo
cf_accountdefine um prefixo (2-4 letras maiúsculas) que mapeia para org secrets - O workflow usa o prefixo para resolver as credenciais:
FRONT_{PREFIXO}_CF_ACCOUNT_IDeFRONT_{PREFIXO}_CF_API_TOKEN - As credenciais são mascaradas nos logs via
::add-mask::
Contas disponíveis
| Nome | Prefixo | Secrets |
|---|---|---|
| Cactus | CT | FRONT_CT_CF_ACCOUNT_ID, FRONT_CT_CF_API_TOKEN |
| Bluetec | BT | FRONT_BT_CF_ACCOUNT_ID, FRONT_BT_CF_API_TOKEN |
| Teste | TS | FRONT_TS_CF_ACCOUNT_ID, FRONT_TS_CF_API_TOKEN |
Adicionando uma nova conta CF
- Criar org secrets:
FRONT_{PREFIX}_CF_ACCOUNT_IDeFRONT_{PREFIX}_CF_API_TOKEN - Adicionar as linhas de env nos steps de resolução do workflow
deploy.ymlnofront-ops - Usar
cf_account: {PREFIX}emenvironments/<env>/deploy.ymloubrand.yml
Passo a passo completo (permissions do token, R2, purge): Deploy → Adicionar conta CF.
Changesets (front-cactus-core)
O monorepo SDK usa @changesets/cli para versionamento e publicação automática dos pacotes @cactus-agents/*.
Fluxo
1. Dev cria changeset local: pnpm changeset
2. Push em main com changeset → Actions cria PR "chore: version packages"
3. Merge do PR → Actions publica no GitHub Packages
Criando um changeset
cd front-cactus-core
pnpm changeset
# Selecionar pacotes alterados
# Escolher bump type (patch / minor / major)
# Escrever descrição da mudança
O changeset é um arquivo .md em .changeset/ que deve ser commitado junto com a alteração.
Publicação
O workflow release.yml usa changesets/action@v1:
- Se existem changesets pendentes → cria/atualiza o PR "chore: version packages"
- Se o PR for mergeado (sem changesets pendentes) → executa
pnpm run releaseque builda e publica
A publicação usa NODE_AUTH_TOKEN com GITHUB_TOKEN do próprio repositório (o core publica pacotes no seu próprio escopo, então o token padrão funciona).
Secrets
Org-level secrets (compartilhados por todos os repos)
GitHub
| Secret | Escopo do PAT | Uso |
|---|---|---|
GH_PACKAGES_TOKEN | read:packages | Instalar @cactus-agents/* no CI dos forks (job quality) |
FRONT_GH_ACTIONS_TOKEN | repo, read:packages, read:org | Checkout do front-ops (config de brands) + install de pacotes durante deploy + resolução do HEAD SHA + authorization gate de deploy_protection |
Cloudflare (multi-account)
| Secret | Conta | Uso |
|---|---|---|
FRONT_CT_CF_ACCOUNT_ID | Cactus | Account ID |
FRONT_CT_CF_API_TOKEN | Cactus | API Token (Workers Edit + Zone Read + Cache Purge) |
FRONT_BT_CF_ACCOUNT_ID | Bluetec | Account ID |
FRONT_BT_CF_API_TOKEN | Bluetec | API Token |
FRONT_TS_CF_ACCOUNT_ID | Teste | Account ID |
FRONT_TS_CF_API_TOKEN | Teste | API Token |
Além desses, há secrets opcionais por conta consumidos no purge e sync de
assets (FRONT_{XX}_CF_WORKER_KEY, FRONT_{XX}_CACHE_PURGE_SECRET,
FRONT_{XX}_R2_ASSETS_ACCESS_KEY, FRONT_{XX}_R2_ASSETS_SECRET). Quando ausentes,
o pipeline emite warning e pula a etapa. Lista completa: Deploy → Referência de
secrets.
Convenção de nomenclatura: FRONT_{PREFIXO}_CF_ACCOUNT_ID e FRONT_{PREFIXO}_CF_API_TOKEN. Para adicionar uma nova conta, ver Adicionando uma nova conta CF.
Separação de responsabilidades:
GH_PACKAGES_TOKEN— usado apenas no CI dos forks (jobquality: lint, test, typecheck). Scope mínimo:read:packagesFRONT_GH_ACTIONS_TOKEN— usado pelo reusable workflow de deploy. Precisa derepo(checkout do front-ops privado),read:packages(instalar pacotes) eread:org(gate de team)FRONT_{XX}_CF_*— tokens do Cloudflare, usados apenas no step de deploy. Cada par identifica uma conta CF diferente
Acesso das org secrets
As org secrets têm acesso restrito a repositórios selecionados (não são "all repositories" por segurança). Ao criar um novo fork/repo:
- Ir em GitHub → cactus-agents → Settings → Secrets and variables → Actions
- Editar cada secret relevante (
FRONT_{XX}_CF_*,FRONT_GH_ACTIONS_TOKEN,GH_PACKAGES_TOKEN) - Na seção Repository access, adicionar o novo repositório à lista
Sem isso, o workflow do novo repo não terá acesso às secrets e o deploy/CI falhará.
CF API Tokens — Escopo de zonas
Cada API Token de CF é configurado com escopo restrito por zona (domínio) para segurança. Configuração do token:
- Account Resources: Include → conta específica (ex: "Cactus Performance")
- Zone Resources: Include → Specific zone → domínios autorizados
Ao criar uma nova brand com um domínio novo:
- Ir no Cloudflare Dashboard → conta correspondente → My Profile → API Tokens
- Editar o token referente à conta (
FRONT_{XX}_CF_API_TOKEN) - Em Zone Resources, clicar em + Add more e incluir a nova zona/domínio
Sem isso, o deploy para o novo domínio falhará com erro de permissão.
Permissões dos workflows
Os workflows devem declarar o bloco permissions explicitamente:
jobs:
quality:
runs-on: ubuntu-latest
permissions:
contents: read
packages: read
Sem esse bloco, o GITHUB_TOKEN recebe permissões padrão que podem não incluir packages: read.
Adicionando CI/CD a um novo fork
Ao criar um fork de front-web-base, os workflows já vêm incluídos. Checklist
resumido (passo a passo completo em Deploy → Adicionar brand/fork):
- Criar a brand e o primeiro env no
front-ops:config/brands/<brand>/brand.yml(comrepo:) econfig/brands/<brand>/environments/<env>/deploy.yml(comcf_account) - Org secrets (GitHub): editar cada secret relevante e adicionar o novo repo à lista de acesso:
GH_PACKAGES_TOKEN— para o CI (jobquality)FRONT_GH_ACTIONS_TOKEN— para o deployFRONT_{XX}_CF_ACCOUNT_IDeFRONT_{XX}_CF_API_TOKEN— para a conta CF da brand- (se aplicável)
FRONT_{XX}_CACHE_PURGE_SECRET,FRONT_{XX}_CF_WORKER_KEY,FRONT_{XX}_R2_ASSETS_*
- CF API Token: se a brand usa um domínio novo, editar o token da conta CF correspondente para incluir a nova zona/domínio em Zone Resources
- Subir o Worker e configurar as vars/secrets (
API_BASE_URL,CF_WORKER_KEY, etc.) — ver Deploy → Adicionar environment - Push em
main(ou dispatch manual) → workflows rodam