Pular para o conteúdo principal

Workflow de Release — SDK

Guia end-to-end para alterar pacotes @cactus-agents/*, publicar novas versões e atualizar os consumidores.

O modelo em uma frase

Um commit conventional mergeado na main do front-cactus-core publica sozinho. Não existe PR de versão, não existe branch changeset-release/main, não existe gate humano entre o merge e o changeset publish. O CI deriva o bump lendo as mensagens de commit, gera o changeset, versiona e publica.

front-cactus-core (SDK) front-web-base (consumidor)
┌───────────────────────────────────┐ ┌──────────────────────────┐
│ 1. Alterar código + testar │ │ │
│ 2. Commit conventional │ │ │
│ 3. Merge na main │ │ │
│ │ │ │ │
│ ▼ ci-release.yml │ │ │
│ ┌───────────────────────────────┐ │ │ │
│ │ job `ci` lint/check/ │ │ │ │
│ │ build/test │ │ │ │
│ │ job `changeset` lê os commits │ │ │ │
│ │ → gera e │ │ │ │
│ │ commita o │ │ │ │
│ │ changeset na │ │ │ │
│ │ PRÓPRIA main │ │ │ │
│ │ job `release` changeset │ │ │ │
│ │ version + │ │───────▶│ 4. pnpm update │
│ │ publish │ │ │ 5. Testar + commit │
│ └───────────────────────────────┘ │ │ │
└───────────────────────────────────┘ └──────────────────────────┘

Regra de ouro: sempre publicar o SDK primeiro, depois atualizar consumidores.

:::caution O que mudou em relação a versões antigas desta doc

  • Os workflows ci.yml e release.yml não existem mais — foram unificados em .github/workflows/ci-release.yml.
  • changesets/action@v1 não é usado. Não há PR chore: version packages para revisar e mergear.
  • O script pnpm run release existe no package.json, mas o workflow não o chama — ele roda changeset version e changeset publish separadamente e reaproveita o artifact de build do job ci. :::

Passo a passo

1. Alterar e testar

cd front-cactus-core
# fazer alterações nos pacotes
pnpm build
pnpm test

O hook pre-push do core já roda pnpm lint && pnpm check && pnpm build && pnpm test antes de deixar você empurrar.

2. Commitar com o tipo certo (isto decide o bump)

O job changeset faz o parse das mensagens de commit do range empurrado e deriva um único bump para todos os pacotes afetados:

Mensagem do commitBump resultante
qualquer tipo com ! antes do : (ex: feat!:, fix(api)!:)major
feat:minor
fix:, refactor:, perf:, revert:patch
chore:, ci:, docs:, test:, style:, build:nenhum — não gera release

Detalhes que importam na prática:

  • major vence tudo; minor vence patch. O bump é o maior encontrado no range.
  • feat, fix, refactor, perf e revert entram no resumo do changeset (o que aparece no CHANGELOG). Se o push tiver apenas commits não-releasable (chore/ci/docs/…), o job registra Only non-releasable commits — skipping e nada é publicado.
  • Commits cuja mensagem começa com Merge são ignorados no parse.
  • Os pacotes afetados são inferridos do diff: todo arquivo em packages/<dir>/ cujo packages/<dir>/package.json existe entra no frontmatter do changeset. Se o diff não toca nenhum pacote, nada é publicado.

:::tip Como forçar um bump diferente do que o tipo do commit implica Crie o changeset à mão e inclua o .changeset/*.md no mesmo push. O job changeset detecta changesets já presentes no range e pula a auto-geração — o seu arquivo é o que vale.

pnpm changeset # seleciona pacotes, escolhe patch/minor/major, escreve o resumo
git add .changeset/ packages/
git commit -m "feat: descrição da mudança"
git push origin main

:::

Quando usar cada bump

TipoQuando usarExemplo
patchBug fix, melhoria interna sem mudar APICorrigir header faltando
minorNova funcionalidade, novo export (backwards compatible)Adicionar um novo hook exportado
majorBreaking change — assinatura mudou, export removidoRenomear um factory exportado
dica

Para 0.x.y, semver trata minor como potentially breaking. Na prática, usamos minor para features novas e patch para fixes.

3. Mergear na main

ci-release.yml dispara em pull_request (só o job ci) e em push na main (os três jobs). Ao mergear:

  1. cipnpm install --frozen-lockfilelintcheckbuildtest, e sobe packages/*/dist como artifact build-dist. Este job é pulado para os commits do próprio bot (chore: version packages e chore: add changeset), evitando loop de CI.
  2. changeset — analisa os commits, gera .changeset/auto-<sha-curto>.md, commita como chore: add changeset for <sha> e empurra direto na main.
  3. release — se há changesets pendentes: pnpm exec changeset version, commita chore: version packages, empurra direto na main, e roda pnpm exec changeset publish. O Summary do run lista as tags publicadas.

:::info Por que o CI empurra direto na main Os jobs changeset e release fazem checkout com o PAT FRONT_GH_ACTIONS_TOKEN justamente para bypassar a branch protection da main — é o que permite o fluxo sem PR intermediária. O HUSKY: "0" nesses steps desliga os hooks locais nos commits do bot. A publicação usa NODE_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }} (o core publica no próprio escopo, então o token default basta). :::

4. Atualizar consumidores

No front-web-base:

cd front-web-base

# Atualiza todos os pacotes do escopo de uma vez
pnpm update "@cactus-agents/*" --latest

# Verificar
pnpm quality # lint + check + check:dev-vars + typecheck + test
pnpm dev # testar fluxos principais

# Commit
git add pnpm-lock.yaml package.json
git commit -m "chore: bump @cactus-agents/* para as versões novas"

Do workspace front-dev, o atalho equivalente é feca update (default: @cactus-agents/*, interativo).

:::caution Nem todo @cactus-agents/* vem do core @cactus-agents/sports-rogue é uma dependência real do base mas não é publicada pelo front-cactus-core — ela vem de outro lugar. Não assuma que um release do core cobre todos os pacotes do escopo. :::

Desenvolvimento local (sem publicar)

Para iterar entre SDK e base sem passar pelo ciclo de publish, não precisa linkar nada manualmente. Se o front-cactus-core está clonado ao lado do front-web-base, o Vite / Vitest / tsc do base leem @cactus-agents/* direto do src/*.ts do core via aliases configurados em vite.config.ts, vitest.config.ts e tsconfig.json (paths source-first, com fallback para node_modules quando o core não está clonado).

# Editar o fonte no SDK
# front-cactus-core/packages/accounts/src/...

# Rodar no base — mudanças aparecem via HMR sub-segundo
cd front-web-base
pnpm dev

pnpm typecheck e pnpm test também usam o mesmo resolver — nada quebra entre editar o core e validar no base.

Validar contra o pacote publicado antes de abrir PR

O pre-push do base já faz isso por você: ele roda pnpm typecheck:ci (tsconfig.ci.json, que resolve de node_modules) e CACTUS_FORCE_REGISTRY=1 pnpm vitest run --changed. Se você depende de código do core que ainda não foi publicado e bumpado no package.json, o push falha aqui — de propósito.

Para checar antes disso, à mão:

cd front-web-base
pnpm dev --registry # força resolução pelo node_modules (registry)
# ou: CACTUS_FORCE_REGISTRY=1 pnpm dev

Se falhar em --registry mas passar em pnpm dev normal, a mudança no base depende de código do core que ainda não foi released — publique o core primeiro.

:::caution Nunca commite file: ou link: no package.json O package.json no git sempre mantém as versões do registry. Os aliases source-direct são puramente de tempo de resolução — não alteram node_modules nem o lockfile. :::

Troubleshooting

Nada foi publicado depois do merge

Ordem de checagem no run do ci-release.yml:

  1. O job ci foi pulado? Então a mensagem do commit contém chore: version packages ou chore: add changeset — é um commit do bot, comportamento esperado.
  2. O step Analyze conventional commits disse Only non-releasable commits (chore/ci/docs) — skipping? O tipo do commit não é releasable. Faça um commit fix:/feat: ou adicione um changeset manual.
  3. O step Detect affected packages disse No packages affected? O diff não tocou nenhum diretório em packages/.
  4. O job release disse has_changesets=false? Não havia .changeset/*.md pendente — cai nos casos 2 ou 3.

Pacote não encontrado após publish

O GitHub Packages pode levar alguns segundos para propagar:

pnpm store prune
pnpm install --force

403 Forbidden no CI do consumidor

O PAT de leitura (GH_PACKAGES_TOKEN) pode ter expirado. Ver GitHub Packages para renovação.

Versão bumpou "errado" (patch onde eu queria minor)

O bump vem do tipo do commit, não da sua intenção. refactor: gera patch mesmo que a mudança adicione um export novo. Use feat: ou um changeset manual (ver passo 2).

Pacotes que não existem mais

@cactus-agents/auth, @cactus-agents/user e @cactus-agents/wallet foram removidos — os diretórios em packages/ são cascas vazias e foram unificados em @cactus-agents/accounts. Qualquer comando ou import que os referencie falha. @cactus-agents/mocks ainda existe publicado, mas está deprecado (stubs vazios, substituído por integrações reais de API) e foi removido do package.json do front-web-base — o base não depende mais dele. Não o readicione.

A lista viva de pacotes publicados é repos/front-cactus-core/packages/ — consulte lá em vez de confiar em uma lista congelada.