sdd-release
Fecha uma frente de trabalho e a leva para produção com UM ponto de aprovação: verifica sozinha o que vai subir (sintaxe, testes, segredo no diff, base desatualizada), mostra uma vez o que exatamente vai para produção e se o push publica sozinho, e só depois do OK do usuário commita, integra, publica e confere. Use de dentro da pasta da frente quando o usuário disser 'release', 'publicar', 'subir para produção', 'fechar a frente' ou 'integrar'. É a outra ponta da skill sdd-new-session.
How do I install this agent skill?
npx skills add https://github.com/robertodiasduarte/sdd-starter --skill sdd-releaseIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The skill is a release automation tool designed with security in mind, incorporating features like secret scanning and change integrity checks. It reads project files and executes local development commands (tests, syntax checks) to facilitate code integration and deployment, which presents a technical surface for indirect prompt injection from repository content.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
What does this agent skill do?
Release — fechar a frente com um OK
Na primeira resposta desta skill, comece com esta linha, uma vez só:
sdd-release v1.2.0 · out/2026 · versão atual: https://github.com/robertodiasduarte/sdd-starter/releases/latest
Verificar o que vai subir, mostrar uma vez o que vai para produção e — só depois do OK — integrar e publicar.
As duas regras que governam esta skill
- Não pergunte o que dá para descobrir. Investigue e decida; pergunte só o ambíguo, com recomendação. No fim, liste o que assumiu ("assumi X porque Y").
- Simples não é sem rede de proteção. Um passo a mais custa trinta segundos; uma publicação errada custa o fim de semana. O que se corta é burocracia (changelog elaborado, versionamento novo, relatório longo). Nunca o que impede publicar algo quebrado, e nunca o momento em que o usuário vê e aprova o que vai subir.
Regra de todo comando que fala com o remoto
fetch, push, pull, ls-remote e remote show rodam sem pedir senha: GIT_TERMINAL_PROMPT=0 git …
no bash/zsh; no PowerShell, $env:GIT_TERMINAL_PROMPT=0; git …. Sem isso, um remoto que exige login faz o
git pedir a senha no terminal, e você fica esperando uma resposta que o usuário não vê — com o OK já dado.
Ao usuário, mostre só a forma do shell em uso. Se um desses comandos ficar parado, olhe se o editor
(VS Code, Cursor) abriu uma janela de login do GitHub — ela é um jeito legítimo de logar e não é desligada.
Passo 0 — Onde estou
- Rode
git rev-parse --show-toplevelegit branch --show-current. Se não for um repositório git, ou se a branch atual for a principal, pare e diga: esta skill roda de dentro da pasta de uma frente (criada pelasdd-new-sessionou porgit worktree add). - O checkout principal é o primeiro caminho de
git worktree list --porcelain. Se existir<checkout principal>/sdd/ambiente.md, leia e use (branch principal, cenário, testes, deploy).
Passo 1 — Descubra o que faltar (sem perguntar)
Só o que sdd/ambiente.md não disser:
GIT_TERMINAL_PROMPT=0 git remote show origin
git log --oneline -20
git tag --list
ls .github/workflows/
E leia: README.md, package.json (seção scripts), Makefile, .github/workflows/*, CLAUDE.md,
AGENTS.md.
- Branch principal — a "HEAD branch" do remoto.
- Como o código chega em produção — a descoberta mais importante. Seja honesto:
- Deploy automático: um workflow dispara em push na principal ⇒ o push É o deploy.
- Deploy manual: há um comando de publicação (
npm run deploy,make deploy, um script). - Nenhum: o repositório só guarda código ⇒ "release" = integrar na principal, sem fingir que publicou.
- Testes (
npm test,pytest, um job de CI) e checagem de sintaxe para os arquivos tocados (node --check,php -l,python -m py_compile,tsc --noEmit). - Versionamento (tags
v*,versionnopackage.json,CHANGELOG.md). Se não houver nada disso, não invente: projeto sem versão não ganha versão junto com a release. - Cenário (o mesmo da
sdd-new-session): commits diretos na principal ⇒ A, Trunk-Based (termina em push na principal); merges de PR ⇒ B, GitHub Flow (termina em PR para a principal); tags de versão e branchesrelease/*ouhotfix/*⇒ C, GitFlow (termina em PR paradevelop) — o mesmo critério dasdd-new-session. Na dúvida entre A e B, A. Se existirdevelopno remoto mas o critério de C não fechar, não decida sozinha: a última linha do bloco do OK vira "Posso publicar na<recomendada>? (respondadevelopoumainpara trocar)" — continua sendo uma pergunta só. O destino respondido vira o<alvo>da Fase 3:develop⇒ a frente segue o caminho do cenário C (push da branch + PR paradevelop), nunca o push direto na principal. - Branch de integração — onde esta frente entra: a principal nos cenários A e B,
developno C. Daqui em diante,<alvo>é ela. Comparar ou integrar uma frente do cenário C contra a principal levaria para produção o que ainda está em desenvolvimento.
Grave o que descobriu em sdd/ambiente.md do checkout principal (chaves deploy, testes, sintaxe,
versionamento, banco), criando o arquivo no formato da sdd-new-session se ele não existir. A chave
banco normalmente já foi gravada pela sdd-build ao aplicar a migration (ferramenta · projeto nome e ref ·
como aplicar · como provar); projeto sem banco ⇒ - banco: nenhum.
Fase 1 — Verificar (sozinha, sem perguntar)
Tudo aqui é local e reversível. Nesta ordem, parando na primeira falha:
- Identidade do git.
git config user.nameegit config user.email— os dois preenchidos. Faltou algum? Pare aqui, com os comandosgit config --global user.name "Seu Nome"egit config --global user.email "voce@exemplo.com": o commit da Fase 3 falharia depois do OK, e o usuário teria aprovado algo que não sobe. - O que exatamente vai subir — inclusive o que ainda não foi commitado:
git status --short --untracked-files=all— arquivos modificados e novos (??, um por arquivo, nunca a pasta inteira agrupada) em relação ao último commit. Esta é a lista do commit da Fase 3, inclusive um arquivo que foi commitado e depois desfeito na pasta (ele some do resumo abaixo, mas precisa entrar no commit para o desfazer valer).git diff --stat $(git merge-base origin/<alvo> HEAD)— compara a base da frente com a pasta de trabalho: cobre os commits da frente e as mudanças ainda não commitadas.- Não use só
git diff origin/<principal>...HEAD: ele ignora o que não foi commitado, e numa frente sem commit mostraria um resumo vazio — o usuário aprovaria algo diferente do que sobe. - Arquivo que não pertence a esta frente? Pare e mostre — não decida sozinha o que fica de fora.
Exceção que não é da frente e nunca entra no commit: pastas de skills não versionadas
(
.claude/skills/…,.agents/skills/…) — asdd-new-sessionas copia para a frente funcionar. - Algo staged com versão diferente da pasta (o mesmo arquivo em
git diff --cached --name-onlye emgit diff --name-only)? Pare e mostre: qual das duas versões sobe é decisão do usuário, e nenhuma das duas pode ser descartada sem ele ver. - Impressão digital do que vai subir — guarde
git rev-parse HEAD(fixa o histórico que o push vai enviar), o resultado degit diff <base> | shasum, o degit diff --cached | shasum(o que já está staged) e oshasumde cada arquivo novo (??) — no PowerShell,Get-FileHash—, onde<base>é$(git merge-base origin/<alvo> HEAD). É o que o OK aprova; a Fase 3 confere antes de commitar. Um commit reescrito depois do OK muda oHEADmesmo que o conteúdo final seja igual.
- Migration e banco andam juntos. Se o que vai subir (o diff e os arquivos novos do item 1) tem
*.sqlou algo emmigrations/, a migration precisa constar aplicada: a chave- banco:emsdd/ambiente.mde a seção## Migrations aplicadasdo BUILD_REPORT da frente, com aquele arquivo (ou "já aplicada em <data>"). Falta um dos dois? Pare aqui, antes do bloco do OK, dizendo qual lado falta e o caminho: a migration se aplica pelo passo 11 dasdd-build(descobre o projeto, confirma nome e ref, aplica, prova por leitura e grava os dois registros). O inverso também para: migration registrada como aplicada sem o.sqlno que sobe (o arquivo ficou de fora do commit) ⇒git adddo arquivo e rode asdd-releasede novo. Publicar código que chama uma coluna que o banco não tem, ou um banco que mudou sem o arquivo no repositório, são os dois jeitos de git e banco divergirem. - Sintaxe dos arquivos tocados, com a ferramenta do Passo 1.
- Testes, se existirem. Vermelho para tudo: aprovar um diff com teste quebrado transforma o OK em carimbo.
- Segredo vazando — em tudo o que vai subir, não no repositório inteiro: o diff dos arquivos
modificados e o conteúdo inteiro de cada arquivo novo (
??dogit status), que não aparece nogit diffmas será commitado. Procure chave de API, token, senha,.envsendo versionado por engano: atribuições comoAPI_KEY=,SECRET=,PASSWORD=,TOKEN=com valor literal, prefixos de chave de provedor e blocosPRIVATE KEY. E também no histórico da frente (git log -p <base>..HEAD): uma chave que entrou num commit e saiu no seguinte some do diff agregado, mas o push envia os dois commits. Achou no histórico? Pare: reescrever histórico é decisão do usuário, nunca desta skill. Uma chave publicada não se despublica, nem apagando o commit depois. - A base andou?
GIT_TERMINAL_PROMPT=0 git fetch origin <alvo>egit rev-list --count HEAD..origin/<alvo>. Não integre agora: umgit mergeaqui criaria commit antes do OK (e recusaria a pasta com mudanças não commitadas). Só registre: "a base andou N commits" vai no bloco do OK, e a Fase 3 integra a base atualizada e roda os testes de novo antes de qualquer push.
Se qualquer item falhar: pare, diga qual falhou, com arquivo e motivo, e não siga. Não conserte sozinha
e não peça OK "mesmo assim". Nessa resposta não mencione o bloco do OK nem a pergunta "Posso publicar",
nem como passo futuro: termine com o que precisa ser corrigido e "depois, rode a sdd-release de novo".
Quem lê a pergunta no fim da resposta entende que o OK está sendo pedido.
Fase 2 — O único ponto de parada
Mostre um bloco só, neste formato (preencha; não acrescente perguntas):
**O que sobe**
<saída do --stat da Fase 1> + arquivos novos, pelo nome
**O que muda em produção:** <uma frase, em português — "muda o cálculo do relatório mensal da tela
inicial", não "altera handler.js">
**O push publica sozinho?** <sim, o workflow X publica ao receber o push na main | não: <por quê>>
**O deploy espera os testes?** <sim — os testes rodam no mesmo job, antes da publicação (ou: o job de
publicação tem `needs:` no de testes) | não — o workflow X publica sem esperar os testes do Y: um teste
vermelho não impede a publicação | não se aplica: o push não publica>
**Banco:** <migration `<arquivo>` aplicada em `<projeto nome (ref)>` em <data> | sem migração nesta frente>
**Verificações:** sintaxe <ok|pulada: motivo> · testes <ok|pulados: motivo> · segredo <nenhum, no
diff e nos arquivos novos> · base <atualizada | andou N commits: será integrada e testada de novo antes do push>
<só se não houver revisor humano:> Antes de responder, vale pedir à IA uma revisão do próprio código:
"isso quebra algo que já funcionava, expõe alguma senha, tem erro óbvio?"
**Posso publicar?** ← ou "Posso publicar na <alvo>?", no único caso do destino ambíguo (Passo 1)
- Verificação ausente dita como ausente é informação; em silêncio, é falsa segurança.
- "Banco:" vem dos dois registros conferidos no item 2 da Fase 1 (
- banco:dosdd/ambiente.mde## Migrations aplicadasdo BUILD_REPORT) — é afirmação, não pergunta. Frente sem.sqlescreve "sem migração nesta frente". - "O deploy espera os testes?" se descobre lendo
.github/workflows/*: os testes estão no mesmo job, antes do passo que publica, ou o job que publica temneeds:apontando para o de testes? Um step de teste comcontinue-on-error: true,|| trueou que termina sempre emexit 0não segura nada — conta como "não". É afirmação, não pergunta: você preenche, o usuário não responde. - A única pergunta do bloco é a última linha, "Posso publicar?" (ou "Posso publicar na
<alvo>?", se o destino ficou ambíguo no Passo 1). As linhas com?antes dela são rótulos que você preenche. A sugestão de revisão é uma frase, não uma pergunta — transformá-la em "quer que eu revise antes?" cria um segundo ponto de parada, e duas paradas viram carimbo. - Se algo ficou ambíguo (qual arquivo pertence à frente), diga dentro deste mesmo bloco, antes da última linha — nunca pare duas vezes.
- Sem o OK, termine aqui: nada de commit, merge ou push.
Fase 3 — Publicar (só depois do OK)
- A pasta ainda é a que foi aprovada? Recalcule a impressão digital da Fase 1. Diferente ⇒ algo mudou depois do OK: pare, mostre o que mudou e peça um OK novo — nunca commite o que não foi visto.
- Commit com os arquivos nomeados um a um — exatamente os da lista do
git statusda Fase 1, nenhum outro. Não resete o índice (apagaria versão staged que não está na pasta). Depois dogit add,git diff --cached --name-onlytem de ser exatamente essa lista — se aparecer outro arquivo staged, pare antes do commit. Depois do commit,git status --shortvazio — exceto as pastas de skills não versionadas, que ficam de fora de propósito. Nuncagit add -A, nuncagit add -u: com duas frentes abertas na mesma máquina, eles arrastam o trabalho da outra. - Base atualizada, testada de novo. Se a base andou:
GIT_TERMINAL_PROMPT=0 git fetch origin <alvo>,git merge origin/<alvo>na frente, e rode os testes de novo. Conflito ou teste vermelho: pare antes de qualquer push, diga o que quebrou — nada foi publicado. - Integrar pelo cenário, sempre a partir da frente:
- A (Trunk-Based,
<alvo>= principal):GIT_TERMINAL_PROMPT=0 git push origin HEAD:<principal>. O push sai da frente, que contém exatamente o que foi aprovado mais a base remota — nunca do checkout principal, onde um commit local que ninguém aprovou iria junto. Recusado porque a base andou (non-fast-forward/fetch first)? Volte ao item 3 (nunca force). Recusado por permissão (403,Permission denied,could not read Username) ou por branch protegida (protected branch,GH006)? Pare e diga o que conferir, nesta ordem:gh auth status(está logado, e com a conta certa?); o seu papel no repositório (publicar exige permissão de escrita); e se a principal é protegida — aí o caminho é o do cenário B (push da branch + PR), não insistir no push direto. - B (GitHub Flow):
GIT_TERMINAL_PROMPT=0 git push -u origin <branch-da-frente>e abra o PR para a principal (gh pr create, se houvergh; sem ele, o próprio push acima imprime o link para abrir o PR no navegador) — e pare aí. A integração é o merge do PR, depois da revisão. - C (GitFlow):
GIT_TERMINAL_PROMPT=0 git push -u origin <branch-da-frente>e abra o PR paradevelop(mesmo caminho do B, com ou semgh) — e pare aí. A frente não vai direto para a principal.
- A (Trunk-Based,
- Deploy manual, se houver, só a partir da principal já integrada e atualizada — nunca da branch da
frente não publicada. O deploy roda numa árvore idêntica ao que foi publicado: no cenário A, a
própria frente logo depois do push aceito — confira
git status --porcelainvazio egit rev-parse HEADigual agit rev-parse origin/<principal>(apósGIT_TERMINAL_PROMPT=0 git fetch); se não bater, pare. Nunca do checkout principal, que pode ter mudança local ou commit que ninguém aprovou. Nos cenários B e C, entregue o comando de deploy para rodar depois que o PR for integrado; não o execute antes. (Com deploy automático, o próprio push na principal já publica.) - Confirme que funcionou — pelo commit que você publicou, não pelo último run. Não diga "publicado"
porque o comando não deu erro. Com deploy por workflow e
ghdisponível:gh run list --commit <SHA publicado> --branch <principal> --json databaseId,status,conclusion,workflowName,event(igual no PowerShell). Olhe o run do workflow que publica, na principal (event=push, ouworkflow_dispatchquando foi o redisparo manual do item abaixo) — não o mais recente da lista geral (com dois pushes seguidos, é de outro commit) nem um run do mesmo SHA em outra branch ou de PR, que pode ter pulado o deploy.completed+success⇒ "No ar: o deploy do seu commit<sha curto>terminou (run N)".queuedouin_progress⇒ espere e olhe de novo; ainda não está no ar.- Lista vazia ⇒ o GitHub ainda não registrou o run: espere alguns segundos e consulte de novo; vazia depois de ~2 min ⇒ diga que não achou o run do commit — nunca "nada a verificar". Nos cenários B e C, o SHA que chega à principal é o do merge do PR: consulte por ele.
cancelled⇒ com fila, um push mais novo pode ter substituído o seu.GIT_TERMINAL_PROMPT=0 git fetch origin <principal>, depoisgh run list --workflow <arquivo do workflow> --branch <principal> --limit 20 --json databaseId,headSha,status,conclusion,createdAt. Só vale um runsuccesscriado depois do seu e de um commit que contém o seu (git merge-base --is-ancestor <seu SHA> <SHA dele>sai 0) ⇒ "Seu commit<sha>foi incluído no deploy de<sha dele>(run N)". Sai 1 = aquele run não contém o seu commit (procure outro ou espere); qualquer outro código (commit não encontrado) = "não consegui confirmar" — nunca "não foi incluído".failure⇒ diga o que falhou. Para repetir o deploy, nuncagh run rerunde um run antigo: com fila, ele roda depois do push mais novo e copia código velho por cima. Redispare na ponta (gh workflow run <arquivo> --ref <principal>, se o workflow aceita disparo manual) ou com um push novo.- Verde não prova teste: se o step de teste tem
continue-on-error,|| trueou termina sempre emexit 0, diga "o deploy terminou, mas o workflow não roda testes antes de publicar" — sem ✅. Há URL? Veja se responde. Semghou sem como confirmar? Diga isso: "publicado, sem verificação automática disponível" é honesto; "✅ tudo certo" sem ter olhado, não é.
- Checkout principal e limpeza, entregues como comandos (de dentro da worktree ela não consegue se
remover): no checkout principal,
GIT_TERMINAL_PROMPT=0 git pull --ff-only— se recusar, a principal local tem commits que não foram publicados, e isso é dito, não resolvido por você; depoisgit worktree remove "<pasta>"(com aspas: o caminho pode ter espaço) egit branch -d <branch>(o-dminúsculo só apaga o que já foi integrado). Nos cenários B e C, a limpeza vem depois do merge do PR.
Resposta final em três linhas: o que subiu, onde está, o que falta.
O que NÃO entra nesta skill (e por quê)
- Changelog elaborado — se o projeto já tem
CHANGELOG.md, uma linha. Se não tem, não crie. - Versionamento novo — projeto que não versiona hoje não começa a versionar aqui.
- Relatório final longo — três linhas.
- Nunca
--force, em nenhuma hipótese. Push recusado significa que a base andou: busque e integre, nunca force por cima do trabalho de outra pessoa (ou do seu de ontem). - Nunca um segundo ponto de parada — duas paradas viram carimbo: a pessoa para de ler.
Por que cada regra existe
- O OK vem antes do push: com deploy automático, depois do push não há "antes" para onde voltar.
- O
git addnomeia arquivos: com duas frentes abertas, o-Apublica a que nem terminou. - A base é conferida antes e integrada depois do OK: se outra frente entrou primeiro, os testes passaram contra um estado que já não existe — mas integrar antes do OK criaria um commit que ninguém aprovou. Por isso: medir na Fase 1, integrar e testar de novo na Fase 3, antes do push.
- O push sai da frente, não do checkout principal: lá pode haver commit local que não passou pelo OK.
- O resumo cobre o não commitado: o commit acontece depois do OK, então o que se aprova tem de incluir o que ainda está só na pasta.
- A identidade é conferida antes do OK: o commit só acontece na Fase 3; sem nome e e-mail ele falha depois que o usuário já aprovou.
- Migration no commit e migration aplicada andam juntas: o push publica o código, não o banco. Sem a conferência, um deploy automático põe no ar código que chama uma coluna que não existe — e o bloco do OK teria dito "o push publica sozinho? sim" como se isso bastasse.
- O deploy é conferido pelo SHA: com dois pushes seguidos, o "último run" é de outro commit, e um run verde de outro commit não diz nada sobre o seu.
- Nunca
gh run rerunde deploy antigo: o rerun usa o commit daquele run — com fila, ele roda depois do push mais novo e publica código velho por cima. - A skill roda de dentro da frente e não consegue remover a própria worktree no fim — a limpeza é do checkout principal.
Parte do SDD Starter by RDD — https://github.com/robertodiasduarte/sdd-starter
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/robertodiasduarte/sdd-starter/sdd-release">View sdd-release on skillZs</a>