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.ymlerelease.ymlnão existem mais — foram unificados em.github/workflows/ci-release.yml. changesets/action@v1não é usado. Não há PRchore: version packagespara revisar e mergear.- O script
pnpm run releaseexiste nopackage.json, mas o workflow não o chama — ele rodachangeset versionechangeset publishseparadamente e reaproveita o artifact de build do jobci. :::
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 commit | Bump 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:
majorvence tudo;minorvencepatch. O bump é o maior encontrado no range.- Só
feat,fix,refactor,perferevertentram no resumo do changeset (o que aparece no CHANGELOG). Se o push tiver apenas commits não-releasable (chore/ci/docs/…), o job registraOnly non-releasable commits — skippinge nada é publicado. - Commits cuja mensagem começa com
Mergesão ignorados no parse. - Os pacotes afetados são inferridos do diff: todo arquivo em
packages/<dir>/cujopackages/<dir>/package.jsonexiste 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
| Tipo | Quando usar | Exemplo |
|---|---|---|
| patch | Bug fix, melhoria interna sem mudar API | Corrigir header faltando |
| minor | Nova funcionalidade, novo export (backwards compatible) | Adicionar um novo hook exportado |
| major | Breaking change — assinatura mudou, export removido | Renomear um factory exportado |
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:
ci—pnpm install --frozen-lockfile→lint→check→build→test, e sobepackages/*/distcomo artifactbuild-dist. Este job é pulado para os commits do próprio bot (chore: version packagesechore: add changeset), evitando loop de CI.changeset— analisa os commits, gera.changeset/auto-<sha-curto>.md, commita comochore: add changeset for <sha>e empurra direto namain.release— se há changesets pendentes:pnpm exec changeset version, commitachore: version packages, empurra direto namain, e rodapnpm 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 só 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:
- O job
cifoi pulado? Então a mensagem do commit contémchore: version packagesouchore: add changeset— é um commit do bot, comportamento esperado. - O step Analyze conventional commits disse
Only non-releasable commits (chore/ci/docs) — skipping? O tipo do commit não é releasable. Faça um commitfix:/feat:ou adicione um changeset manual. - O step Detect affected packages disse
No packages affected? O diff não tocou nenhum diretório empackages/. - O job
releasedissehas_changesets=false? Não havia.changeset/*.mdpendente — 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.