Pular para o conteúdo principal

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 arAdicionar environment
Criar uma brand nova / entender o modelo de forkAdicionar brand/fork
Registrar uma conta Cloudflare novaAdicionar conta CF
Saber o nome de uma secret ou variávelReferência de secrets
Entender as camadas de cache e o purge do deployCache, zonas e purge
Ver o pipeline step-by-step e o inventário de workflowsInfraestrutura → 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 o front-ops, e chama o reusable uma vez por environment.
  • O reusable (deploy.yml no front-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 em config/docs/environments/ + 2 em config/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

CampoDefaultDescriçã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_urlorigin_domainURL pública usada em purge, warm-up, probe de build e summary.
public_domainvazioDomí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_zonederivado do origin_domainZona apex para o purge SSR. Ver Cache & Purge.
languagept-brVira BRAND_LANGUAGE no build.
tenantnome do environmentTag SSM front-web-warmup=<tenant> usada pelo warm collector.

Rollout e branch

CampoDefaultDescrição
auto_deployfalsetrue → deploy automático no push do default_branch.
default_branchmainBranch oficial deployada deste env.
deploy_protection.required_teamOrg team que pode dar deploy manual. Ver Proteção de deploy.

Cache SSR e warmer (opt-in avançado)

CampoDefaultDescrição
ssr_cache.html_ttl60TTL do doc HTML no cache de resposta SSR.
ssr_cache.data_ttl60TTL das respostas .data.
ssr_cache.kv_ttl180TTL do snapshot KV do doc SSR.
ssr_cache.data_browser_ttl0TTL de browser para .data. 0 = o middleware omite o header (inerte).
ssr_swr_enabledfalseSWR manual no edge: serve o doc stale (X-Cache: HIT-STALE) e revalida em background.
shared_public_doc_for_authfalseFase 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.enabledfalseLiga o Cron Trigger de cache warmer dentro do brand worker.
cache_warmer.pathsvazioRotas que o warmer aquece.
cache_warmer.originvazioOrigin 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

CampoDefaultDescrição
deploy_entry_workerfalsePublica também <worker_name>-entry a partir de wrangler.entry.toml. Apontar o domínio para o -entry é passo manual separado.
run_warm_cutoverfalseCutover 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_purgefalsePula o purge pós-deploy. Usado em env atrás de CF Access, onde o endpoint de purge é inalcançável do runner.
skip_asset_verifyfalsePula 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.

TriggerO que é deployado
push (auto-deploy)O commit empurrado. A matriz só inclui envs cujo default_branch == github.ref_name e auto_deploy: true.
workflow_dispatchHEAD SHA do default_branch no repo caller, resolvido via GitHub API em runtime.
pull_requestNenhum 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_dispatchpush 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.

duas teams em uso:

Team slugRegra de uso
rulesets-groups-front-deployers-cactus-agents-front-web-base-readerProdução normal do web-base — a maioria das envs gateadas
rulesets-groups-superadmin-cactus-agents-front-web-base-adminTier 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 (campo repo:);
  • o environment não existe (environments/<env>/deploy.yml ausente);
  • mais de uma brand declara o mesmo repo: (conflito);
  • worker_name não está definido no env;
  • origin_domain não está definido;
  • cf_account não está definido (nem no env, nem no default da brand);
  • cf_account tem formato inválido (não são 2-4 letras maiúsculas);
  • as org secrets FRONT_{cf_account}_CF_ACCOUNT_ID / _CF_API_TOKEN não existem;
  • a política de cache resolvida fica vazia ou perde um recurso no merge;
  • o verify HTTP dos assets R2 falha (exit 2 do sync-assets-r2.mjs);
  • version split confirmado no Worker (o novo deploy foi, mas outra versão segue servindo tráfego);
  • o probe de buildId no hostname não converge para o BUILD_ID deste deploy;
  • o collector SSM não retorna Success em todas as invocações (só com run_warm_cutover: true).