Pular para o conteúdo principal

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)

WorkflowTriggerO que faz
ci.ymlPush em main, PRsLint → Check → Build → Test
release.ymlPush em main (com changesets pendentes)Build → Changesets (cria PR ou publica)

front-web-base (Template) e forks

WorkflowTriggerO que faz
ci-deploy.ymlPush/PR (main, stage, dev, performance, sports e variantes *-), workflow_dispatchquality (lint/check/typecheck/test) + config-lint (PRs) + resolve-matrix + deploy (chama reusable do front-ops)
list-environments.ymlworkflow_dispatchViewer read-only da topologia de envs declarada no front-ops
lighthouse.yml(auditoria)Auditoria Lighthouse
delete-merged-branch.ymlBranch mergeadaLimpeza 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)

WorkflowTriggerO que faz
deploy.ymlworkflow_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.ymlworkflow_callDeploy do front-cactus-docs
deploy-affiliates.ymlworkflow_callDeploy do cactus-affiliates
manual-cache-purge.ymlworkflow_dispatchPurge manual de cache

Modelo de deploy

O deploy segue um modelo caller + reusable workflow (detalhes completos em Deploy → Visão Geral):

  1. O caller ci-deploy.yml roda o quality gate, resolve a matriz de envs lendo o front-ops, e chama cactus-agents/front-ops/.github/workflows/deploy.yml@main uma vez por environment.
  2. O reusable no front-ops acha a brand cujo repo: bate com o caller e lê config/brands/<brand>/environments/<env>/deploy.yml (com fallbacks de brand.yml::defaults).
  3. Resolve worker_name, cf_account, cf_zone e demais campos.
  4. Resolve as credenciais Cloudflare a partir do cf_account (ver Multi-account Cloudflare).
  5. 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

  1. O campo cf_account define um prefixo (2-4 letras maiúsculas) que mapeia para org secrets
  2. O workflow usa o prefixo para resolver as credenciais: FRONT_{PREFIXO}_CF_ACCOUNT_ID e FRONT_{PREFIXO}_CF_API_TOKEN
  3. As credenciais são mascaradas nos logs via ::add-mask::

Contas disponíveis

NomePrefixoSecrets
CactusCTFRONT_CT_CF_ACCOUNT_ID, FRONT_CT_CF_API_TOKEN
BluetecBTFRONT_BT_CF_ACCOUNT_ID, FRONT_BT_CF_API_TOKEN
TesteTSFRONT_TS_CF_ACCOUNT_ID, FRONT_TS_CF_API_TOKEN

Adicionando uma nova conta CF

  1. Criar org secrets: FRONT_{PREFIX}_CF_ACCOUNT_ID e FRONT_{PREFIX}_CF_API_TOKEN
  2. Adicionar as linhas de env nos steps de resolução do workflow deploy.yml no front-ops
  3. Usar cf_account: {PREFIX} em environments/<env>/deploy.yml ou brand.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 release que 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

SecretEscopo do PATUso
GH_PACKAGES_TOKENread:packagesInstalar @cactus-agents/* no CI dos forks (job quality)
FRONT_GH_ACTIONS_TOKENrepo, read:packages, read:orgCheckout do front-ops (config de brands) + install de pacotes durante deploy + resolução do HEAD SHA + authorization gate de deploy_protection

Cloudflare (multi-account)

SecretContaUso
FRONT_CT_CF_ACCOUNT_IDCactusAccount ID
FRONT_CT_CF_API_TOKENCactusAPI Token (Workers Edit + Zone Read + Cache Purge)
FRONT_BT_CF_ACCOUNT_IDBluetecAccount ID
FRONT_BT_CF_API_TOKENBluetecAPI Token
FRONT_TS_CF_ACCOUNT_IDTesteAccount ID
FRONT_TS_CF_API_TOKENTesteAPI 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 (job quality: lint, test, typecheck). Scope mínimo: read:packages
  • FRONT_GH_ACTIONS_TOKEN — usado pelo reusable workflow de deploy. Precisa de repo (checkout do front-ops privado), read:packages (instalar pacotes) e read: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:

  1. Ir em GitHub → cactus-agents → Settings → Secrets and variables → Actions
  2. Editar cada secret relevante (FRONT_{XX}_CF_*, FRONT_GH_ACTIONS_TOKEN, GH_PACKAGES_TOKEN)
  3. 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:

  1. Ir no Cloudflare Dashboard → conta correspondente → My Profile → API Tokens
  2. Editar o token referente à conta (FRONT_{XX}_CF_API_TOKEN)
  3. 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):

  1. Criar a brand e o primeiro env no front-ops: config/brands/<brand>/brand.yml (com repo:) e config/brands/<brand>/environments/<env>/deploy.yml (com cf_account)
  2. Org secrets (GitHub): editar cada secret relevante e adicionar o novo repo à lista de acesso:
    • GH_PACKAGES_TOKEN — para o CI (job quality)
    • FRONT_GH_ACTIONS_TOKEN — para o deploy
    • FRONT_{XX}_CF_ACCOUNT_ID e FRONT_{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_*
  3. 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
  4. Subir o Worker e configurar as vars/secrets (API_BASE_URL, CF_WORKER_KEY, etc.) — ver Deploy → Adicionar environment
  5. Push em main (ou dispatch manual) → workflows rodam