O que shipit-skill — Pipeline de lançamento em uma passada faz?
Transforme um repositório existente de "funciona" para publicado + listado + comercializável. Quatro fases, cada uma com um critério de saída rigoroso. Pular uma fase só é permitido se seu critério de saída já estiver atendido.
Filosofia: olhe antes de construir. Verifique o que já existe e o que o ecosistema exige primeiro — da mesma forma que você aconselharia qualquer usuário a não reinventar a roda.
Fase 0 — Reconhecimento (30s, sempre)
Execute estas verificações antes de tocar em qualquer coisa:
- Estado do repositório —
git status,git remote -v,git logrecente. - Registro do pacote — o nome está disponível? (
pip index versions <nome>,npm view <nome>, CDN do registro). Nomes colidem com frequência; nomes com escopo no npm (@org/pkg) evitam regras de typosquatting. - Projetos similares — pesquise no GitHub por concorrentes diretos. Se existir um, anote a diferenciação explicitamente; não construa uma cópia idêntica.
- As "lacunas" nos critérios de saída — CI? Dockerfile? GitHub Release? listado no Glama / diretórios awesome? material promocional atual? Crie uma checklist do que está faltando. Essa checklist orienta o restante.
Saída: um relatório de lacunas curto + plano. Obtenha confirmação antes da Fase 1 se as lacunas forem grandes.
Fase 1 — Linha de base de engenharia
Critério de saída: CI verde no branch padrão, metadados do pacote corretos, Dockerfile presente (se for um servidor MCP/CLI).
- CI: adicione GitHub Actions. Python: matrix sobre versões suportadas, mas atente para
extras que exigem um interpretador mais recente (ex.:
mcp>=2.0precisa de Python 3.10+ — roda a base em 3.9, extras em 3.12). Sempre inclua lint + testes + um job de handshake MCP em container se um servidor for distribuído. - Dockerfile: necessário para Glama e usuários de container. Para servidores MCP stdio:
imagem base + instalar o pacote +
CMD [o-comando-do-servidor]. Construa a partir do código fonte (COPY src) a menos que o pacote publicado esteja verificado como bom — uma versão desatualizada no PyPI/npm quebrará silenciosamente a introspecção. .dockerignore: mantenha a imagem mínima (sem.git, testes, material promocional, docs).- Versão a partir dos metadados: a
serverInfo.versiondo MCP e o--versionda CLI devem ler a versão do pacote, não uma string fixa. - Piso de dependência: se seu código usa uma API nova do SDK, defina o piso da
dependência (
mcp>=2.0), não deixe>=1.0— pip/npm resolvem para a versão mais recente e quebram instalações novas.
Verifique: pip install .[extras] / npm install limpo em um venv temporário, depois execute
o handshake MCP (initialize + tools/list) contra o container.
Fase 2 — Publicação
Critério de saída: pacote no registro, GitHub Release com tag + notas, instalação em ambiente limpo verificada.
- Bump de versão → artefatos de build (
python -m build/npm pack). - Tag + GitHub Release: título
vX.Y.Z, notas com Mudanças / Instalação / O-que-corrige. Deixegh release createanexar a partir da tag. - Publicação no registro:
- PyPI: precisa de um token (granular, escopo para o pacote, permissão Upload).
Se o token estiver malformado, o PyPI retorna
403 Invalid or non-existent authentication information— strings no formato UUID estão erradas; tokens reais do PyPI começam compypi-.twine uploadcom--username __token__. - npm: nomes com escopo precisam que a organização exista; token granular com bypass-2FA
para automação;
--//registry.npmjs.org/:_authTokeninline evita escrever credenciais em disco.
- PyPI: precisa de um token (granular, escopo para o pacote, permissão Upload).
Se o token estiver malformado, o PyPI retorna
- Verificação de instalação limpa (não negociável): crie um venv/diretório limpo, instale a partir do registro, importe o módulo / execute a CLI / faça o handshake MCP. Isso detecta bugs de empacotamento do tipo "funciona na minha máquina".
- Armadilhas:
- O CDN do npm serve 404s em cache por minutos após a primeira publicação — não entre em pânico, limpe o cache com um parâmetro de consulta.
File already existsao repetir geralmente significa que a primeira tentativa foi bem-sucedida.- Deriva de lockfile: renomear pacotes → sempre execute
npm installpara regenerar o lock ounpm cifalhará no CI.
Fase 3 — Listagens em diretórios
Critério de saída: listado no Glama com um badge de pontuação e PR awesome aberto (ou mesclado).
- Glama (
glama.ai/mcp/servers): usuário submete via navegador (GitHub OAuth — não pode ser automatizado). Antes de submeter: Dockerfile deve existir e passar na introspecção (veja Fase 1). Após submeter: a página leva minutos a horas para aparecer — faça polling dehttps://glama.ai/mcp/servers/<owner>/<repo>e/badges/score.svg. Adicione o badge ao README do repositório assim que estiver ativo:[](https://glama.ai/mcp/servers/owner/repo) - awesome-mcp-servers (e listas curadas similares): PRs são triados por bots.
Formato conforme a convenção atual da lista (badge + lang + escopo + SO + comando de instalação).
Mantenedores agora exigem o badge do Glama na entrada — submeta o Glama primeiro. Adicione
🤖🤖🤖ao título do PR para optar pelo fast-track de agentes. Fork → branch a partir do main upstream mais recente → adicione entrada → PR. Se um PR anterior foi fechado por inatividade, force-push no branch ou recrie-o. - Outros diretórios (Smithery, PulseMCP, mcp.so…): Smithery lê um
smithery.yamlna raiz do repositório (comando de inicialização stdio + esquema de env opcional).
Fase 4 — Material promocional
Critério de saída: versões/links/números de PR nos docs promocionais correspondem à realidade; postagens por plataforma estão prontas para copiar e colar (usuário posta manualmente — sem automação falsa).
- Mantenha
promo/com arquivos por plataforma (V2EX, 知乎, Reddit, X, comunidade). - Verificação de atualização (execute sempre que versões/PRs mudarem): grep nos arquivos promo por números de versão antigos, links de PR mortos, URLs de release desatualizados. Atualize ou marque como desatualizado.
- Disciplina de fatos: verifique cada número/afirmação antes de postar — execute a ferramenta novamente e compare a saída. Alegações erradas são destruídas nos comentários (ex.: uma alegação "sem LICENSE" que na verdade é uma peculiaridade dos metadados do GitHub).
- Mantenha comandos de instalação sem pin (
pip install pkg) para que o material promocional não desatualize.
Referência rápida da CLI (shipit-skill)
Execute estes comandos para mover um repositório pelas fases. Tudo é apenas impressão por
padrão; as variantes com efeitos colaterais são opt-in via --execute.
| Comando | O que faz | Automático / impressão |
|---|---|---|
doctor [--json] | auto-verificação do ambiente: gh autenticado, tokens configurados, árvore limpa no main | imprime; sai com 1 se houver lacunas |
preflight [--dir .] [--version X.Y.Z] [--json] | relatório de lacunas de prontidão para lançamento | imprime |
init <dir> --server <srv> --pkg <pkg> [--force] [--dry-run] | scaffolding de CI/Dockerfile/smithery.yaml/promo | escreve arquivos |
ci --lang python [--server srv] [--write path] [--release] | emite ci.yml; --release emite release.yml | imprime / escreve |
| `bump patch | minor | major |
release --lang python --pkg <pkg> [--repo o/r] [--execute] | gate doctor → bump→build→publicar→tag→gh release→verificação promo. Tag/Release só são criados após a publicação ser bem-sucedida; falha na publicação reverte o commit; reexecuções pulam tags/releases existentes; notas do CHANGELOG | imprime / executa |
publish --lang python --pkg <pkg> [--server srv] [--execute] | upload para registro (token da env PYPI_TOKEN/NPM_TOKEN) + verificação de instalação limpa | imprime / executa |
check-promo --dir promo --version X.Y.Z [--prs id=state,...] [--no-links] [--report] [--fix] | versões desatualizadas / PRs desconhecidos / links quebrados; --report emite JSON; --fix reescreve versões desatualizadas + marca PRs desconhecidos | imprime / JSON / corrige |
check-glama --repo o/r [--poll N] [--add-badge] [--json] | aguarda listagem no Glama; --add-badge escreve o badge no README assim que estiver ativo; --json estruturado | imprime / escreve |
awesome-pr --upstream o/r --repo o/r --fork o/r --branch b [--execute --category C --description D --install I] | receita de PR, ou realmente fork→editar→push→gh pr create | imprime / executa |
Tokens: nunca armazenados em disco. publish/release --execute lê PYPI_TOKEN
ou NPM_TOKEN do ambiente; peça ao usuário e passe inline.
Limite de automação
| Etapa | Quem executa |
|---|---|
| Arquivos CI, Dockerfile, metadados, correções de código | Agente |
| Artefatos de build, verificação de instalação limpa | Agente |
| Publicação no registro (PyPI/npm) | Agente, com um token fornecido pelo usuário |
| Submissão via navegador no Glama | Usuário (OAuth) |
| Criação de PR no awesome/outros | Agente |
| Postagem em plataformas | Usuário |
Nunca invente credenciais; peça o token explicitamente e use-o inline, nunca o escreva em um arquivo.
Cicatrizes do mundo real (de shipping wheel-hub + zspace-cli)
mcp>=1.0em extras + novo SDK → instalações novas quebram. Defina pisos.- Python 3.9 não consegue instalar
mcp>=2.0; a matrix do CI deve separar base vs extras. - YAML block scalar + python heredoc inline = workflow quebrado. Use um arquivo de script.
- O objeto
Serverdo MCP 2.x não temlist_tools— use decoradores@server.tool(). - A introspecção do Glama precisa que o stdin fique aberto por um instante (
sleep 1) em testes smoke. - Formatos de token PyPI:
pypi-...real, UUID = errado. - O typosquatting do npm bloqueia
wheel-hubao lado dewheelhub; nomes com escopo funcionam. .dockerignoreausente → imagens gigantes / segredos no contexto de build.