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.

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
quality.ymlPush em main, PRsLint → Check → Typecheck → Test
deploy.ymlPush em main, workflow_dispatchChama reusable workflow do front-ops → Build → Deploy (Cloudflare Workers)

front-ops (Deploy centralizado)

WorkflowTriggerO que faz
deploy.ymlworkflow_call (chamado pelos forks)Valida config por brand/repo → Resolve CF account → Checkout fork → Build → Deploy no Cloudflare Workers

Modelo de deploy

O deploy segue um modelo caller + reusable workflow:

  1. O fork tem um deploy.yml mínimo que chama cactus-agents/front-ops/.github/workflows/deploy.yml@main
  2. O reusable workflow no front-opsconfig/brands/*/{brand.yml,repos.yml} e valida o repo chamador
  3. Resolve o worker_name, cf_account e demais campos para o environment solicitado (com defaults da brand)
  4. Resolve as credenciais Cloudflare corretas baseado no cf_account (ver Multi-account Cloudflare)
  5. Faz checkout do código do fork, instala dependências, builda e deploya

Estrutura atual no front-ops:

config/brands/
<brand>/
brand.yml # defaults (default_branch, language, auto_deploy, cf_account)
repos.yml # repos permitidos e environments por repo (cada um com cf_account)
# deploy.yml no fork (caller) — o fork só tem isso
jobs:
deploy:
uses: cactus-agents/front-ops/.github/workflows/deploy.yml@main
with:
environment: ${{ inputs.environment || 'production' }}
ref: ${{ inputs.ref || github.sha }}
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 repos.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 2 linhas de env no step Resolve CF credentials do workflow deploy.yml no front-ops
  3. Usar cf_account: {PREFIX} no repos.yml ou brand.yml

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 (quality.yml)
FRONT_GH_ACTIONS_TOKENrepo, read:packagesCheckout do front-ops (config de brands) + install de pacotes durante deploy

Cloudflare (multi-account)

SecretContaUso
FRONT_CT_CF_ACCOUNT_IDCactusAccount ID
FRONT_CT_CF_API_TOKENCactusAPI Token (Workers Edit)
FRONT_BT_CF_ACCOUNT_IDBluetecAccount ID
FRONT_BT_CF_API_TOKENBluetecAPI Token (Workers Edit)
FRONT_TS_CF_ACCOUNT_IDTesteAccount ID
FRONT_TS_CF_API_TOKENTesteAPI Token (Workers Edit)

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 (lint, test, typecheck). Scope mínimo: read:packages
  • FRONT_GH_ACTIONS_TOKEN — usado pelo reusable workflow de deploy. Precisa de repo (para checkout do front-ops privado) e read:packages (para instalar pacotes)
  • 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:

  1. Cadastrar o repo em front-ops/config/brands/<brand>/repos.yml com cf_account definido
  2. Org secrets (GitHub): editar cada secret relevante e adicionar o novo repo à lista de acesso:
    • GH_PACKAGES_TOKEN — para o CI (quality.yml)
    • FRONT_GH_ACTIONS_TOKEN — para o deploy
    • FRONT_{XX}_CF_ACCOUNT_ID e FRONT_{XX}_CF_API_TOKEN — para a conta CF da brand
  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. Push em main → workflows rodam automaticamente