Deploy — Visão Geral
Índice da seção de deploy: como o front-web-base é buildado e publicado no
Cloudflare Workers, e onde encontrar cada coisa.
:::tip Quero adicionar um setup novo agora Vá direto para o passo a passo: Adicionar um novo environment. :::
Por onde começar
| Quero… | Página |
|---|---|
| Colocar um environment novo no ar | Adicionar environment |
| Criar uma brand nova / entender o modelo de fork | Adicionar brand/fork |
| Registrar uma conta Cloudflare nova | Adicionar conta CF |
| Saber o nome de uma secret ou variável | Referência de secrets |
| Entender as camadas de cache e o purge do deploy | Cache, zonas e purge |
| Ver o pipeline step-by-step e o inventário de workflows | Infraestrutura → CI/CD |
| Operar cache em incidente (playbooks) | Infraestrutura → Cache operations |
Modelo: caller + reusable workflow
O deploy segue o padrão caller + reusable workflow, com o front-ops como
única fonte de verdade:
┌──────────────────────────────┐ ┌──────────────────────────────────┐
│ front-web-base (caller) │ │ front-ops (single source) │
│ .github/workflows/ │ │ config/brands/web-base/ │
│ ci-deploy.yml │ │ brand.yml │
│ • quality │ ──────▶ │ cache.yml │
│ • config-lint (PR) │ chama │ environments/<env>/deploy.yml │
│ • resolve-matrix │ │ config/cache/*.yml │
│ • deploy (matrix) │ │ .github/workflows/deploy.yml │
└──────────────────────────────┘ └──────────────────────────────────┘
- O caller (
ci-deploy.yml) roda o quality gate, resolve a matriz de deploy lendo ofront-ops, e chama o reusable uma vez por environment. - O reusable (
deploy.ymlnofront-ops) resolve a config da brand/env, as credenciais Cloudflare, faz checkout do código do caller, builda e publica.
O caller não contém lógica de resolução de worker_name, tokens Cloudflare,
política de cache ou pipeline de build/deploy.
O detalhamento dos jobs, dos 33 steps do reusable, do config-lint, do entry
worker e do warm cutover está em
Infraestrutura → CI/CD — fonte única, para não
divergir desta página.
:::caution Não existe input ref
O reusable workflow tem um único input: environment. O branch deployado é
sempre o default_branch declarado no front-ops (ver
Branch governance).
:::
Estrutura de config no front-ops
Convenção: uma brand = um repo. Cada environment é uma pasta com seu próprio
deploy.yml.
front-ops/config/
├── cache/
│ ├── defaults.yml # política de cache global (todas as brands)
│ ├── generation.yml # token de cache generation da frota
│ ├── service-api-defaults.yml # política do proxy front-service-api
│ └── monitor-routes.yml # rotas do purge-monitor
└── brands/
├── web-base/ # brand (kebab-case)
│ ├── brand.yml # identidade + defaults (declara `repo:`)
│ ├── cache.yml # overrides de cache da brand (opcional)
│ └── environments/
│ ├── prod-7k-bet-br/
│ │ └── deploy.yml # config do env (fonte de verdade)
│ └── <env>/
│ ├── deploy.yml
│ └── cache.yml # overrides de cache do env (opcional)
Existe uma brand hoje: web-base. A lista viva é
front-ops/config/brands/ — consulte lá.
:::info Contando environments — diga sempre qual denominador Dois números circulam, e os dois estão certos contra bases diferentes:
- 28 brand environments = todos em
config/brands/web-base/environments/. É este o número usado quando se fala de "envs de deploy do front". - 33 diretórios de environment no
front-ops= os 28 acima + 3 emconfig/docs/environments/+ 2 emconfig/affiliates/environments/.
Esta seção fala sempre dos 28 brand environments. Como os números mudam, a
contagem viva é ls -d repos/front-ops/config/brands/*/environments/*/ | wc -l.
:::
O nome da pasta do environment é o id do environment (o que aparece no
dropdown de workflow_dispatch e no scan de auto-deploy).
brand.yml
brand: web-base
repo: cactus-agents/front-web-base # declara qual repo pertence à brand
defaults:
default_branch: main
language: pt-br
auto_deploy: false
Referência de campos do deploy.yml da env
Exemplo mínimo:
worker_name: front-web-7k-bet-br # nome do Worker no Cloudflare (NUNCA vem de input)
cf_account: CT # prefixo da conta CF (2-4 letras maiúsculas)
auto_deploy: false # true = deploy automático no push do default_branch
default_branch: main # branch oficial deste env
language: pt-br
origin_domain: 7k.bet.br # domínio servido / origin
worker_url: 7k.bet.br # URL pública do worker
cf_zone: 7k.bet.br # zona CF apex p/ purge (ver Cache & Purge)
# Opcional — restringe quem pode dar deploy manual (workflow_dispatch)
deploy_protection:
required_team: rulesets-groups-front-deployers-cactus-agents-front-web-base-reader
Campos ausentes caem no fallback de brand.yml::defaults e, por fim, em defaults
embutidos no workflow.
Identidade e roteamento
| Campo | Default | Descrição |
|---|---|---|
worker_name | — (obrigatório) | Nome do Worker no Cloudflare. Resolvido só do config, nunca de input externo. |
cf_account | — (obrigatório, env ou default da brand) | Prefixo da conta CF: CT, BT, TS. |
origin_domain | — (obrigatório) | Domínio do origin / brand-key. |
worker_url | origin_domain | URL pública usada em purge, warm-up, probe de build e summary. |
public_domain | vazio | Domínio público canônico para SEO quando difere do origin_domain (caso bet7k.cl: público em bet7k.cl, plataforma keyed em cl.bet7k.com). Vazio = o front usa o ORIGIN_DOMAIN em robots/canonical. Não derive do worker_url — envs de stage viriam indexáveis. |
cf_zone | derivado do origin_domain | Zona apex para o purge SSR. Ver Cache & Purge. |
language | pt-br | Vira BRAND_LANGUAGE no build. |
tenant | nome do environment | Tag SSM front-web-warmup=<tenant> usada pelo warm collector. |
Rollout e branch
| Campo | Default | Descrição |
|---|---|---|
auto_deploy | false | true → deploy automático no push do default_branch. |
default_branch | main | Branch oficial deployada deste env. |
deploy_protection.required_team | — | Org team que pode dar deploy manual. Ver Proteção de deploy. |
Cache SSR e warmer (opt-in avançado)
| Campo | Default | Descrição |
|---|---|---|
ssr_cache.html_ttl | 60 | TTL do doc HTML no cache de resposta SSR. |
ssr_cache.data_ttl | 60 | TTL das respostas .data. |
ssr_cache.kv_ttl | 180 | TTL do snapshot KV do doc SSR. |
ssr_cache.data_browser_ttl | 0 | TTL de browser para .data. 0 = o middleware omite o header (inerte). |
ssr_swr_enabled | false | SWR manual no edge: serve o doc stale (X-Cache: HIT-STALE) e revalida em background. |
shared_public_doc_for_auth | false | Fase 2 do SSR streaming: usuário logado em rota pública recebe o doc anônimo cacheado e reidrata a auth no client. |
cache_warmer.enabled | false | Liga o Cron Trigger de cache warmer dentro do brand worker. |
cache_warmer.paths | vazio | Rotas que o warmer aquece. |
cache_warmer.origin | vazio | Origin do warmer. Vazio = cai no ORIGIN_DOMAIN. |
:::info Esses valores são sempre emitidos no [vars], mesmo com o default
O deploy usa wrangler deploy --keep-vars. Se o pipeline omitisse uma chave,
o valor antigo ficaria pinado no Worker para sempre. Por isso ele emite
false/0/60 explicitamente em vez de não escrever a linha.
:::
Infra opt-in e escapes
| Campo | Default | Descrição |
|---|---|---|
deploy_entry_worker | false | Publica também <worker_name>-entry a partir de wrangler.entry.toml. Apontar o domínio para o -entry é passo manual separado. |
run_warm_cutover | false | Cutover pós-warm: collector AWS SSM → bump de CACHE_GENERATION_SECRET → purge-all multi-camada. Requer o entry já deployado e a secret AWS_WARMUP_ROLE_ARN. |
skip_post_deploy_purge | false | Pula o purge pós-deploy. Usado em env atrás de CF Access, onde o endpoint de purge é inalcançável do runner. |
skip_asset_verify | false | Pula a verificação HTTP 200 dos assets sincronizados no R2 (também um caso de CF Access). Upload e integridade no R2 continuam. |
Mecânica de deploy_entry_worker e run_warm_cutover em
CI/CD.
Branch governance
O branch deployado para um env é sempre o default_branch declarado no
front-ops. Não há override manual de ref em lugar nenhum.
| Trigger | O que é deployado |
|---|---|
push (auto-deploy) | O commit empurrado. A matriz só inclui envs cujo default_branch == github.ref_name e auto_deploy: true. |
workflow_dispatch | HEAD SHA do default_branch no repo caller, resolvido via GitHub API em runtime. |
pull_request | Nenhum deploy (só quality + config-lint). |
Os globs de branch aceitos pelo caller são exatamente main, main-*, stage,
stage-*, sports e sports-*.
:::info Sobre o "Use workflow from" da UI do GitHub
A UI nativa de workflow_dispatch sempre mostra um dropdown "Use workflow
from". Esse controle não tem efeito no código deployado — ele só escolhe
qual versão do YAML do workflow roda.
:::
Rollback
Não há UI para deployar um SHA arbitrário. Para reverter, reverta no branch oficial:
git -C repos/front-web-base checkout <default_branch>
git -C repos/front-web-base revert <commit-ruim>
git -C repos/front-web-base push # dispara auto-deploy, ou dispare manual
Proteção de deploy
deploy_protection.required_team restringe apenas workflow_dispatch —
push nunca é gateado. O gate vive no job check, então uma reprovação aparece
como check ❌ → deploy skipped, com o erro
Actor '<x>' is NOT in '@cactus-agents/<team>'. Requer read:org no
FRONT_GH_ACTIONS_TOKEN.
Há duas teams em uso:
| Team slug | Regra de uso |
|---|---|
rulesets-groups-front-deployers-cactus-agents-front-web-base-reader | Produção normal do web-base — a maioria das envs gateadas |
rulesets-groups-superadmin-cactus-agents-front-web-base-admin | Tier mais alto: os flagships da família 7k |
Para ver quais envs usam cada team hoje (nem todas as envs são gateadas):
grep -rn -A2 deploy_protection repos/front-ops/config/brands/
:::info Fonte cruzada
O workspace mantém docs/agents/shared/deploy-protection.md com a mesma
topologia. Se editar uma, confira a outra.
:::
Multi-account Cloudflare
Cada environment pode apontar para uma conta CF diferente via cf_account (CT,
BT, TS). Mecânica e como adicionar prefixo novo:
Adicionar conta CF e
CI/CD → Multi-account.
Regras de bloqueio de deploy
O reusable workflow falha o deploy quando:
- o repo caller não é declarado por nenhum
brand.yml(camporepo:); - o environment não existe (
environments/<env>/deploy.ymlausente); - mais de uma brand declara o mesmo
repo:(conflito); worker_namenão está definido no env;origin_domainnão está definido;cf_accountnão está definido (nem no env, nem no default da brand);cf_accounttem formato inválido (não são 2-4 letras maiúsculas);- as org secrets
FRONT_{cf_account}_CF_ACCOUNT_ID/_CF_API_TOKENnão existem; - a política de cache resolvida fica vazia ou perde um recurso no merge;
- o verify HTTP dos assets R2 falha (
exit 2dosync-assets-r2.mjs); - há version split confirmado no Worker (o novo deploy foi, mas outra versão segue servindo tráfego);
- o probe de
buildIdno hostname não converge para oBUILD_IDdeste deploy; - o collector SSM não retorna
Successem todas as invocações (só comrun_warm_cutover: true).