Communitygithub.com

SSBrouhard/npm-package-release-hardening

Uma skill de agente que endurece pacotes npm antes da publicação pública — detecta segredos enviados, incompatibilidades de runtime e lixo no tarball. Funciona em qualquer agente compatível com skills.

O que é npm-package-release-hardening?

Esta skill automatiza o processo de verificação e endurecimento de pacotes npm antes da publicação pública. Ela verifica o contrato do pacote no `package.json`, a compatibilidade do runtime mínimo do Node.js, e realiza uma revisão completa do tarball com `npm pack --dry-run` para garantir que apenas artefatos publicáveis estejam incluídos. A skill também configura uma linha de base de segurança no GitHub, incluindo CI/CD, Dependabot, proteção de branch e hardening de repositório remoto via CLI do GitHub. É útil para desenvolvedores que desejam garantir que seus pacotes sejam seguros, inspecionáveis e honestos antes de publicar, suportando npm, pnpm e yarn.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add SSBrouhard/npm-package-release-hardening

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

Endurecimento de Lançamento de Pacotes npm

Objetivo

Levar um pacote npm de "funciona localmente" para "honesto, inspecionável e seguro para publicar". Priorizar verificação real sobre impressões: conteúdo do tarball do pacote, contrato de runtime, CI, configurações do GitHub e higiene de atualização de dependências.

Comece Aqui

  1. Confirme o repositório exato:
pwd
git status --short --branch
git remote -v
  1. Inspecione a superfície do pacote:
cat package.json
ls -la
find .github -maxdepth 3 -type f -print 2>/dev/null
  1. Detecte o gerenciador de pacotes a partir dos lockfiles:
  • package-lock.json -> npm
  • pnpm-lock.yaml -> pnpm
  • yarn.lock -> yarn

Use os comandos npm abaixo como padrão, mas traduza para o gerenciador de pacotes detectado quando necessário.

Contrato do Pacote

Faça o package.json dizer a verdade:

  • name: o alvo de publicação é intencional e disponível
  • version: versão de publicação pretendida atual
  • description, keywords: úteis o suficiente para pesquisa no registro
  • license: presente e corresponde ao LICENSE
  • repository, homepage, bugs: apontam para o repositório público. Se a URL do repositório público ainda não for final, sinalize-as como um TODO explícito de pré-publicação, em vez de omiti-las silenciosamente
  • type, exports, main, bin: correspondem ao que os usuários importarão ou executarão
  • files: limita o tarball a artefatos publicáveis
  • engines.node: runtime mínimo que o pacote realmente suporta
  • prepublishOnly ou equivalente: impede a publicação de saída de build desatualizada

Para pacotes CLI, confirme que o alvo de bin está construído, executável onde relevante e testado superficialmente através do comando que os usuários executarão.

Regra do Piso de Runtime

O engine do Node é uma promessa, não uma decoração.

  • Se engines.node diz >=20, o CI deve testar o Node 20.
  • Mantenha @types/node na mesma linha principal da versão de runtime mínima suportada.
  • Prefira fixar exatamente @types/node no patch mais recente dessa linha de runtime.
  • Não mescle bumps principais de @types/node acima do piso de runtime, a menos que você também eleve engines.node.
  • engines.node é consultivo: o npm apenas avisa e não bloqueia a instalação a menos que o usuário defina engine-strict, então o CI na versão do piso é o que realmente impõe a promessa.

Por quê: os tipos do Node são apenas para desenvolvimento, mas eles mudam o que o TypeScript permite. @types/node@26 pode permitir que o código compile enquanto usa APIs que falham para usuários no Node 20.

Comandos de Verificação

Para projetos npm:

npm ci
npm run build --if-present
npm test --if-present
npm audit --omit=dev
npm pack --dry-run

Para pnpm/yarn, use os comandos equivalentes de install/build/test/audit/pack. Se o suporte a audit diferir, diga isso em vez de fingir.

Para CLIs, execute também pelo menos um teste de fumaça de fora para dentro:

node dist/path/to/cli.js --help
npm pack --dry-run

Se prático, instale o .tgz empacotado em um diretório temporário e execute o binário exatamente como um usuário faria.

Revisão do Tarball

npm pack --dry-run é a superfície de verdade do registro. Verifique se:

  • inclui saída construída
  • inclui README.md e LICENSE
  • exclui apenas lixo de código-fonte, arquivos temporários, testes, documentos privados, fixtures, bancos de dados locais, segredos
  • o tamanho do pacote é razoável
  • o caminho bin da CLI aparece no tarball

Se files estiver faltando, adicione-o. Não confie em .gitignore como política de publicação.

Linha de Base do GitHub

Adicione ou verifique:

  • .github/workflows/ci.yml
  • .github/dependabot.yml
  • .github/CODEOWNERS
  • .github/pull_request_template.md
  • SECURITY.md

Use versões principais atuais suportadas para ações de propriedade do GitHub. Se o Actions avisar que um runtime de ação está obsoleto, atualize a ação principal após o CI passar.

O CI geralmente deve incluir:

permissions:
  contents: read

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    steps:
      - uses: actions/checkout@CURRENT_MAJOR
      - uses: actions/setup-node@CURRENT_MAJOR
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm run build --if-present
      - run: npm test --if-present

Ajuste node-version para o runtime mínimo suportado do pacote e substitua cada @CURRENT_MAJOR pela tag principal atual da ação (por exemplo actions/checkout@v4) — fixe em uma versão real, nunca confirme o placeholder.

Linha de Base do Dependabot

Configure ambas as atualizações de pacote e GitHub Actions:

version: 2
updates:
  - package-ecosystem: npm
    directory: /
    schedule:
      interval: weekly
    open-pull-requests-limit: 5
    commit-message:
      prefix: deps
      include: scope

  - package-ecosystem: github-actions
    directory: /
    schedule:
      interval: weekly
    open-pull-requests-limit: 5
    commit-message:
      prefix: deps
      include: scope

Quando o Dependabot abrir PRs imediatamente após a configuração, trate isso como prova de que a configuração está ativa. Trie os PRs; não mescle cegamente todas as verificações verdes.

Triagem do Dependabot

Use esta regra prática:

  • Patch/menor de dependência de runtime: mesclar se as verificações passarem e as notas de versão forem irrelevantes.
  • Maior de dependência de runtime: inspecionar notas de versão e testar superficialmente o comportamento real do pacote.
  • Maior de ferramenta de desenvolvimento: mesclar se build/test/pack passarem e não alterar o contrato de runtime.
  • @types/node acima do piso de runtime: fechar ou substituir por uma fixação no piso de runtime.
  • Maior de GitHub Actions: mesclar se o CI passar e remover avisos de depreciação.

Se dois PRs entrarem em conflito em um arquivo de configuração pequeno, mescle um e atualize o outro, ou aplique o segundo diretamente com um comentário claro explicando que foi substituído.

Endurecimento Remoto do GitHub

Aplique o que o repositório/conta suportar e, em seguida, verifique as configurações reais com gh ou leituras da API.

Configurações úteis:

gh repo edit OWNER/REPO \
  --delete-branch-on-merge \
  --enable-squash-merge \
  --enable-merge-commit=false \
  --enable-rebase-merge=false \
  --allow-update-branch

gh api --method PUT repos/OWNER/REPO/vulnerability-alerts --silent
gh api --method PUT repos/OWNER/REPO/automated-security-fixes --silent
gh api --method PUT repos/OWNER/REPO/actions/permissions/workflow \
  -f default_workflow_permissions=read \
  -F can_approve_pull_request_reviews=false --silent

Para listas de permissões de Actions, prefira ações de propriedade do GitHub apenas quando o workflow usar apenas ações de propriedade do GitHub. Se ações de terceiros forem necessárias, permita explicitamente o menor conjunto.

Repositórios públicos geralmente desbloqueiam mais controles de segurança. Repositórios privados em planos gratuitos podem bloquear:

  • proteção de branch ou conjuntos de regras
  • varredura de código
  • varredura de segredos
  • proteção de push

Diga claramente os bloqueadores. Não relate controles indisponíveis como habilitados.

Proteção de Branch

Quando disponível, proteja o branch padrão com:

  • exigir pull request antes de mesclar
  • exigir verificações de status de CI
  • exigir que branches estejam atualizados se isso se adequar ao projeto
  • exigir resolução de conversa
  • bloquear pushes forçados
  • bloquear deleções
  • exigir histórico linear se estiver usando apenas squash merges

Após ativar a proteção, pare de fazer push direto para main a menos que o usuário peça explicitamente e entenda o desvio.

Ferramentas de PR Bloqueado

Se estiver usando uma ferramenta automatizada de revisão/bloqueio, certifique-se de que o remoto tenha um branch padrão/base antes de pedir ao bloqueio para criar um PR. Novos remotos vazios geralmente precisam de um push inicial para main primeiro; caso contrário, o bloqueio pode validar e enviar um branch de funcionalidade, mas falhar na criação do PR porque não há uma ref base.

Lista de Verificação para Publicação

Antes de npm publish:

  • npm whoami mostra a conta pretendida
  • npm view NOME_DO_PACOTE name version confirma o estado do nome
  • CI verde no commit que está sendo publicado
  • npm pack --dry-run foi revisado
  • Exemplos de instalação/uso do README correspondem ao comportamento real
  • repository, homepage e bugs resolvem para o repositório público real (ou são explicitamente sinalizados como TODO se a URL não for final)
  • Nenhum alerta de segurança/Dependabot que bloqueie o lançamento permanece
  • O aumento de versão é intencional, marcado no git (git tag vX.Y.Z && git push --tags) e refletido em um CHANGELOG ou lançamento do GitHub
  • Pacotes com escopo (@scope/nome) publicam com --access public (pacotes com escopo padrão são restritos/privados)

Para contas que usam autenticação web/passkey/2FA:

npm publish --auth-type=web

Prefira publicar do CI com proveniência para um link de cadeia de suprimentos verificável. A proveniência requer um pacote público, um CI suportado como GitHub Actions e permissão id-token: write no job:

npm publish --provenance --access public

Após a publicação:

npm view NOME_DO_PACOTE version
npm view NOME_DO_PACOTE bin files engines repository --json
npx -y NOME_DO_PACOTE --help

Se publicado com proveniência, confirme que o registro mostra a atestação de proveniência / "Built and signed" na página do pacote.

Resposta Final

Relate apenas o que foi realmente verificado:

  • verificações de pacote executadas
  • resultado do tarball
  • decisões de PR de dependência
  • commits/PRs criados ou mesclados
  • configurações do GitHub confirmadas
  • controles bloqueados pelo plano/visibilidade
  • tag de lançamento e status de proveniência, se publicado
  • comando de publicação ou verificação pós-publicação se ainda de propriedade do usuário

Habilidades Relacionadas