Adicionar um novo environment (setup)
Guia passo a passo para colocar um novo environment (setup) no ar — desde a
config versionada no front-ops até subir o Worker e configurar as variáveis
externas no Cloudflare.
Um "environment" aqui é um deploy alvo: uma combinação de Worker + domínio +
branch + conta CF. Exemplos reais: prod-7k-bet-br, state77-com,
stage-7k-bet-br-cactusgaming-tech, sports-cl-bet7k-com-cactusgaming-tech.
:::info Pré-requisitos
- A brand já existe em
front-ops/config/brands/<brand>/comrepo:apontando para o repo certo. Se ainda não existe, faça primeiro o Adicionar brand/fork. - A conta Cloudflare (
cf_account) já está cadastrada. Se for uma conta nova, faça primeiro o Adicionar conta CF. - Você tem acesso ao Cloudflare Dashboard da conta alvo e permissão para editar as org secrets no GitHub (ou alguém que tenha). :::
Visão geral das 5 partes
1. front-ops → criar environments/<env>/deploy.yml
2. front-web-base → adicionar <env> no dropdown do ci-deploy.yml
3. Cloudflare → subir o Worker (1º deploy) e configurar vars/secrets
4. GitHub/CF → garantir acesso das org secrets + zona no token
5. Validar → dispatch manual e conferir
A ordem importa: o passo 3 precisa estar pronto antes do deploy automatizado
conseguir ler API_BASE_URL dos bindings do Worker.
Parte 1 — front-ops: criar o environment
Crie a pasta e o deploy.yml do novo env:
front-ops/config/brands/web-base/environments/<env>/deploy.yml
O nome da pasta <env> é o id do environment — é o que vai no dropdown e no
scan de auto-deploy. Use kebab-case.
Exemplo: environment de produção
# config/brands/web-base/environments/prod-minha-marca-com/deploy.yml
worker_name: front-web-minha-marca-com
cf_account: CT
auto_deploy: false
default_branch: main
language: pt-br
origin_domain: minha-marca.com
worker_url: minha-marca.com
cf_zone: minha-marca.com
# Produção: trava deploy manual no time de deployers
deploy_protection:
required_team: rulesets-groups-front-deployers-cactus-agents-front-web-base-reader
Exemplo: environment de staging (subdomínio)
# config/brands/web-base/environments/stage-minha-marca-cactusgaming-tech/deploy.yml
worker_name: front-web-stage-minha-marca-cactusgaming-tech
cf_account: CT
auto_deploy: true
default_branch: stage
language: pt-br
origin_domain: minha-marca.com
# worker_url é um subdomínio; cf_zone aponta para a zona apex real onde o
# worker é servido (senão o purge SSR pós-deploy não encontra a zona).
worker_url: stage-minha-marca.cactusgaming.tech
cf_zone: cactusgaming.tech
:::caution cf_zone em subdomínios
Quando worker_url/origin_domain é um subdomínio de uma zona diferente,
declare cf_zone explicitamente apontando para a zona apex que existe na
Cloudflare. Sem isso, o purge SSR pós-deploy é pulado silenciosamente. Detalhes em
Cache & Purge.
:::
Regras de preenchimento
| Decisão | Como escolher |
|---|---|
auto_deploy | true para stage que deploya automático no push do branch; false para prod (deploy manual controlado). |
default_branch | O branch que será deployado neste env. Tem que casar com um dos globs do caller (ver abaixo). |
cf_account | A conta CF onde o domínio vive (CT/BT/TS). Tem que bater com a zona no token. |
cf_zone | Apex zone na CF. Apex (marca.com) resolve sozinho; subdomínio precisa explícito. |
deploy_protection | Só em produção / envs sensíveis. Três teams em uso — ver Proteção de deploy. |
Branch nova
Os arrays on.push.branches e on.pull_request.branches do ci-deploy.yml são
idênticos e têm 6 valores — é neles que o GitHub casa:
main main-* stage stage-* sports sports-*
O comentário acima dos arrays resume isso como "namespaces suportados: main*,
stage* e sports*" — mesma coisa, escrita como 3 namespaces. Os arrays são a
forma autoritativa; é o que você edita e o que o config-lint cobra.
Se o default_branch não casar com nenhum dos 6, adicione o glob nos dois
arrays. O config-lint falha a PR se faltar cobertura.
:::danger Não recoloque dev* nem performance*
Esses dois prefixos foram removidos de propósito em 2026-08-10, junto com as
7 envs que os usavam (grupos dev, performance, react-c4ctus,
stage-cache, stage-spa; na mesma mudança 7wins-cc saiu de dev-7wins para
main-7wins). O ci-deploy.yml carrega o aviso in-file: recolocar o glob sem
criar a env correspondente no front-ops faz o config-lint passar a acusar
branch sem env. Se você precisa de um namespace novo, crie a env primeiro.
:::
Opt-in avançado
O deploy.yml aceita bem mais que os campos acima: TTLs do cache SSR
(ssr_cache.*), SWR no edge (ssr_swr_enabled), doc anônimo compartilhado
(shared_public_doc_for_auth), cache warmer no worker (cache_warmer.*), domínio
público de SEO (public_domain), entry worker (deploy_entry_worker), cutover
pós-warm (run_warm_cutover), e os escapes de CF Access
(skip_post_deploy_purge, skip_asset_verify).
Tudo isso é opcional e tem default seguro. A referência completa, com default de
cada campo, está em
Visão Geral → referência de campos do deploy.yml.
Um exemplo vivo que usa a maior parte deles:
config/brands/web-base/environments/stage-cl-bet7k-com-cactusgaming-tech/deploy.yml.
Parte 2 — front-web-base: registrar no dropdown
O caller ci-deploy.yml tem uma lista estática de environments no dropdown de
workflow_dispatch. Edite
front-web-base/.github/workflows/ci-deploy.yml e adicione o novo <env> em
on.workflow_dispatch.inputs.environment.options (mantenha ordenado para
facilitar o diff):
on:
workflow_dispatch:
inputs:
environment:
description: "Target environment"
type: choice
default: react-casateste-com
options:
- ...
- prod-minha-marca-com # ← novo
- stage-minha-marca-cactusgaming-tech # ← novo
- ...
O que o config-lint cobra (e com que severidade)
O job não é um "drift quebra a PR" uniforme — as duas direções são tratadas diferente, de propósito:
| Situação | Resultado |
|---|---|
Dropdown tem env que não existe no front-ops | Erro sempre — um dispatch dela quebraria |
Env do front-ops falta no dropdown, PR com base main | Erro |
Env do front-ops falta no dropdown, PR com outra base branch | Warning — envs novas nascem na main e as branches longas herdam no próximo sync |
brand.yml::repo não é o repo caller | Erro (checagem de ownership da brand) |
Algum default_branch do ops não casa com nenhum glob de branch | Erro |
:::info Por que duplicar a lista?
A lista no dropdown é estática porque o GitHub não resolve choice options em
runtime. O front-ops continua sendo a fonte de verdade — o config-lint apenas
garante que o dropdown não fique dessincronizado.
Nota lateral: o dropdown do manual-cache-purge.yml no front-ops tem o
mesmo problema, mas lá existe automação — o workflow sync-purge-options.yml
abre uma PR regenerando as options. No caller isso é manual.
:::
Parte 3 — Cloudflare: subir o Worker e configurar variáveis
Esta é a parte "externa". O Worker precisa existir e ter API_BASE_URL nos
bindings antes do primeiro deploy automatizado, porque o reusable workflow lê
API_BASE_URL dos bindings do Worker já existente (step
Resolve API_BASE_URL and CF_WORKER_KEY). Num Worker que nunca subiu esse binding
não existe e o build sai sem a URL.
3.1 — Primeiro deploy (criar o Worker)
O Worker é criado no primeiro wrangler deploy --name <worker_name>. Há duas
formas:
Opção A — pelo pipeline (recomendado): dispare o deploy manual uma primeira
vez (Parte 5). Como API_BASE_URL ainda não existe nos bindings, esse primeiro
build sai sem ela (::warning::API_BASE_URL not found in Cloudflare bindings) —
isso é esperado. Depois configure as vars (3.2) e rode o deploy de novo.
Opção B — manualmente, localmente: a partir do front-web-base, com as
credenciais da conta CF:
CLOUDFLARE_ACCOUNT_ID=<account-id-da-conta> \
CLOUDFLARE_API_TOKEN=<token-da-conta> \
npx wrangler deploy --name front-web-minha-marca-com
3.2 — Configurar variáveis e secrets no Worker
No Cloudflare Dashboard → Workers & Pages → <worker_name> → Settings →
Variables and Secrets (ou via wrangler), configure:
Plain text vars
| Variável | Obrigatória | Descrição |
|---|---|---|
API_BASE_URL | ✅ | URL base da API/BFF. Lida pelo pipeline para injetar no build |
BRAND_COUNTRY | ✅ | BRA, CHL, MEX, PER, NGA, etc. |
BRAND_CURRENCY | ✅ | BRL, CLP, MXN, PEN, NGN, etc. |
BRAND_TIMEZONE | recomendado | Timezone da marca (server-only). Ex: America/Sao_Paulo |
CASSINO_MODE | opcional | legacy (default) ou api_new |
FORCE_SPORTBOOK | opcional | first/altenar/betby/rogue |
STICKER_API_URL | opcional | URL do BFF de sticker-album (gamification) |
TURNSTILE_SITE_KEY / RECAPTCHA_SITE_KEY | opcional | Site keys públicas de captcha |
Secrets
| Secret | Obrigatório | Descrição |
|---|---|---|
CF_WORKER_KEY | recomendado | Chave Worker→BFF em runtime (header cf-worker-key, WAF bypass) |
SMARTICO_SALT_KEY | se usa gamification Smartico | Salt para hash de auth Smartico |
SPORTS_ROGUE_API_KEY | se FORCE_SPORTBOOK=rogue | Header x-api-key server-to-server p/ tokens do sportbook Rogue |
:::danger CF_WORKER_KEY no Worker NÃO alimenta o build
O pipeline resolve CF_WORKER_KEY só da org secret
FRONT_{XX}_CF_WORKER_KEY — não existe fallback para o binding do Worker. As duas
configurações são independentes e ambas são necessárias:
- org secret
FRONT_{XX}_CF_WORKER_KEY→ é o que entra no build; - secret do Worker
CF_WORKER_KEY→ é o que o Worker usa em runtime.
Configurar só no Worker produz um build com a chave vazia, sem nenhum erro no run. Ver Referência de secrets. :::
:::caution Não confunda as três pontas
BRAND_LANGUAGE,ORIGIN_DOMAIN,GITHUB_SHA,API_BASE_URLeCF_WORKER_KEYsão injetados no build pelo front-ops — não são vars do Worker (excetoAPI_BASE_URL, que o pipeline lê de lá).BUILD_ID,BUILD_TS,WORKER_NAME,CACHE_GENERATION,PUBLIC_DOMAIN, osSSR_CACHE_*, osCACHE_WARMER_*,SSR_SWR_ENABLED,SHARED_PUBLIC_DOC_FOR_AUTH,PLATFORM_CACHE_POLICY_JSON,CACHE_NAMESPACEe o bindingPLATFORM_CACHE_KVsão injetados pelo front-ops via patch dowrangler.toml— não configure à mão (são sobrescritos a cada deploy).- O resto (
BRAND_*, secrets Smartico/Rogue,CF_WORKER_KEY) é seu. :::
A lista completa está em Referência de secrets e no doc do template Environment Variables.
3.3 — DNS / rota do domínio
- No Cloudflare, o domínio precisa estar na conta (
cf_account) como zona. - Configure o Worker Route ou Custom Domain apontando o hostname
(
worker_url) para o<worker_name>.
:::info Env atrás de CF Access
Se o env vai ficar atrás do Cloudflare Access (padrão dos stage-*), o runner do
GitHub não alcança o hostname. Nesse caso setar skip_post_deploy_purge: true e
skip_asset_verify: true no deploy.yml evita falhas espúrias — o probe de
buildId também vira warning nesses envs.
:::
Parte 4 — Acesso de secrets e zona do token
-
Org secrets (GitHub → cactus-agents → Settings → Secrets and variables → Actions): o repo precisa estar no Repository access de cada secret relevante. Se a brand/repo já deployava antes, isso já está OK; confira apenas se está usando uma
cf_accountnova. -
CF API Token — Zone Resources: o
FRONT_{cf_account}_CF_API_TOKENprecisa incluir a zona apex (cf_zone) em Zone Resources. Sem isso, o purge SSR pós-deploy retorna 401/403. Ver Adicionar conta CF e Cache & Purge.
Parte 5 — Validar o deploy
Conferir a topologia
No GitHub Actions do front-web-base, dispare o workflow List environments
(somente leitura) — ele renderiza uma tabela por branch com URL, conta CF e
status de auto-deploy. Confirme que seu env aparece.
Disparar o deploy manual
Actions → CI/CD → Run workflow:
- Use workflow from: pode deixar o default — não afeta o código deployado.
- Target environment: selecione o novo
<env>.
O reusable resolve o HEAD do default_branch, builda e publica. Acompanhe o
Summary do run (brand, env, conta CF, URL, ref, cache).
Auto-deploy (se auto_deploy: true)
Um push no default_branch dispara o deploy automaticamente. A matriz só inclui
envs cujo default_branch == branch empurrado e auto_deploy: true.
Checklist final
-
front-ops/.../environments/<env>/deploy.ymlcriado e mergeado emmain -
<env>adicionado no dropdown doci-deploy.yml(PR passou noconfig-lint) -
default_branchcasa com um dos globs (main*,stage*,sports*) - Worker existe na CF com
API_BASE_URLnos bindings - Org secret
FRONT_{XX}_CF_WORKER_KEYexiste (é dela que o build lê a chave) - Secret
CF_WORKER_KEYconfigurada no Worker (uso em runtime) - Demais vars/secrets do Worker configuradas conforme a brand
- DNS/route do
worker_urlapontando para o Worker - Org secrets dão acesso ao repo; token CF cobre a zona (
cf_zone) - Deploy manual rodou verde; site carrega; cache/purge sem warnings críticos
Troubleshooting
| Sintoma | Causa provável | Correção |
|---|---|---|
::warning::API_BASE_URL not found in Cloudflare bindings | Worker não tem API_BASE_URL nos bindings | Configurar API_BASE_URL no Worker (Parte 3.2) e redeployar |
Build sobe com CF_WORKER_KEY vazio, sem erro | Chave configurada só no Worker, não como org secret | Criar FRONT_{XX}_CF_WORKER_KEY na org |
Environment '<env>' not found | deploy.yml ausente ou nome de pasta diferente do dropdown | Conferir nome da pasta vs option do dropdown |
config-lint falha na PR | Dropdown com env inexistente no ops, ou base main sem alguma env, ou glob de branch sem cobertura | Ler a mensagem: ::error:: diz qual das três |
cf_account ... is invalid | cf_account não é 2-4 letras maiúsculas | Usar CT/BT/TS |
CF credentials not found for account | Org secrets da conta ausentes / sem acesso ao repo | Criar/dar acesso a FRONT_{XX}_CF_ACCOUNT_ID e _CF_API_TOKEN |
SSR cache purge skipped / 401 no purge | cf_zone errado ou zona fora do Zone Resources do token | Declarar cf_zone apex e incluir a zona no token |
Could not resolve HEAD SHA of '<branch>' | default_branch não existe no repo, ou token sem acesso | Criar o branch / revisar FRONT_GH_ACTIONS_TOKEN |
Actor ... is NOT in '@cactus-agents/<team>' | deploy_protection ativo e usuário fora do team | Pedir entrada no team ou disparar por quem é membro |
Verify HTTP dos assets falha (exit 2) e aborta o deploy | Env atrás de CF Access — o GET redireciona/403 | Setar skip_asset_verify: true no deploy.yml do env |
Job falha em Verify single-version deployment | Version split preso no Worker | npx wrangler versions deploy <version-id> --percentage 100 |