Crochet
J'ai rencontré l'un des problèmes de CI / CD les plus frustrants lors de la publication d'un paquet d'un monorepo pnpm moderne.
Tout semblait correct.
Le workflow est passé. OIDC a été détecté. Changesets a fonctionné. Le paquet existait déjà sur npm.
Et pourtant, la publication a continué à échouer avec ceci:
E404 Not Found - PUT https://registry.npmjs.org/@pycolors%2ftokens - Not foundAvant cela, je frappais aussi :
EOTP This operation requires a one-time password from your authenticator.Le pire ?
Les erreurs étaient trompeuses.
Le vrai problème n'était pas le paquet lui-même.
C'était la migration de l'héritage NPM_TOKEN publishing to npm Trusted Publishing (OIDC) avec des actions GitHub.
Voici la configuration complète prête à la production qui l'a finalement réparée.
Contexte
Cela s'est produit lors de la publication de paquets dans l'écosystème PyColors :
- Next.js 15
- pnpm espaces de travail
- Turborepo
- Changesets
- GitHub Actions
- npm Publication de confiance
- TypeScript
- Node.js 22
Le monorepo contient plusieurs paquets :
@pycolors/ui
@pycolors/tokens
@pycolors/eslint-config
@pycolors/typescript-configLe pipeline de publication publie automatiquement les paquets non publiés sur npm à l'aide de Changesets.
Le problème
Le flux de travail original utilisait un token npm classique :
env:
NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}"— a a marché pendant un moment.
Puis npm a commencé à échouer avec:
EOTP This operation requires a one-time password from your authenticator.Je suis passé à npm Trusted Publishing avec OIDC.
GitHub Actions a alors détecté OIDC correctement :
No NPM_TOKEN found, but OIDC is available - using npm trusted publishingMais la publication a échoué :
E404 Not Found - PUT https://registry.npmjs.org/@pycolors%2ftokens - Not foundLe paquet existait déjà sur npm :
npm view @pycolors/tokens version
# 1.1.0Version locale :
{
"name": "@pycolors/tokens",
"version": "1.2.0"
}Alors pourquoi npm a dit que le paquet n'était "pas trouvé"?
Pourquoi cette erreur est si confuse
Ce n'est pas un 404 normal.
Avec npm Trusted Publishing, npm renvoie parfois :
E404lorsque la chaîne d'authentification OIDC est invalide.
Cela signifie :
- Nom de fichier de flux de travail incorrect
- Version Node/npm non prise en charge
- Désadéquation de Trusted Publisher
- workflow non autorisé
- paquet non lié correctement
Le message d'erreur masque la cause réelle.
Cela rend le débogage douloureux.
Cause racine
En fait j'avais Plusieurs problèmes en même temps.
1. Nom du fichier de flux de travail de l'éditeur de confiance incorrect
J'ai initialement configuré :
.github/workflows/release.ymlMais npm attend:
release.ymlUniquement le nom du fichier.
Pas le chemin complet.
2. Node.js / npm Version Trop vieille
Trusted Publishing nécessite un outillage récent.
J'utilisais :
node-version: 20npm Trusted Publishing se comporte de manière incohérente avec les anciennes versions de npm.
Après la mise à niveau:
node-version: 22.14.0et:
- run: npm install -g npm@latestTout a commencé à fonctionner correctement.
3. Le workflow GitHub a été ignoré
Mon .gitignore contenait ceci :
.github/
**/.github/Ce qui signifiait :
- Les workflows n'ont pas été versionnés
- Les modifications n'ont pas été suivies
- Les workflows ont été déployés de manière incohérente
C'est une idée terrible pour l'infrastructure SaaS moderne.
4. Trusted Publisher a été configuré sur le mauvais référentiel
Celui-ci est subtil.
Les métadonnées de mon dépôt de paquets pointaient vers :
"repository": {
"url": "https://github.com/pycolors-io/pycolors-tokens"
}Mais le flux de publication réel s'exécute à partir de:
pycolors-io/pycolorsTrusted Publishing doit pointer vers le référentiel qui exécute le flux de travail.
Pas le dépôt miroir.
La solution
Voici la configuration finale prête pour la production.
Étape 1 - Configurer npm Trusted Publishing
Sur npm:
@pycolors/tokens
→ Settings
→ Trusted PublisherAjouter :
Organization or user: pycolors-io
Repository: pycolors
Workflow filename: release.yml
Environment: leave empty
Allowed actions: Allow npm publishImportant :
Workflow filename = release.ymlNON:
.github/workflows/release.ymlÉtape 2 - Supprimer Legacy NPM_TOKEN Publishing
Supprimez tout ceci :
NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}"Supprimer également :
- name: "Test npm auth"
run: npm whoamiOIDC n'utilise pas de tokens npm.
Étape 3 - Activer les autorisations OIDC
Votre workflow doit contenir :
permissions:
contents: write
pull-requests: write
id-token: writeLa permission critique est :
id-token: writeSans elle, l’OIDC ne peut pas fonctionner.
Étape 4 - Mettre à niveau Node.js et npm
Cette partie compte plus que la plupart des développeurs ne le réalisent.
Utiliser Node.js 22+ :
- name: "Setup Node"
uses: actions/setup-node@v4
with:
node-version: 22.14.0
registry-url: "https://registry.npmjs.org"
cache: "pnpm"Mettez immédiatement à jour npm:
- name: "Upgrade npm"
run: npm install -g npm@latestÉtape 5 - Utiliser les Changesets avec OIDC
Étape finale de publication :
- name: "Version or Publish (Changesets)"
uses: changesets/action@v1
with:
version: "pnpm -w changeset version"
publish: "pnpm -w changeset publish"
title: "chore(release): version packages"
commit: "chore(release): version packages"
env:
GITHUB_TOKEN: "${{ steps.app-token.outputs.token }}"Aucun token npm nécessaire.
Workflow de travail final
permissions:
contents: write
pull-requests: write
id-token: write
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
with:
run_install: false
- uses: actions/setup-node@v4
with:
node-version: 22.14.0
registry-url: "https://registry.npmjs.org"
cache: "pnpm"
- run: npm install -g npm@latest
- run: pnpm install --frozen-lockfile
- run: pnpm -w build
- uses: changesets/action@v1
with:
version: "pnpm -w changeset version"
publish: "pnpm -w changeset publish"Avant / Après
Avant
- Défaillances OTP
- Broken CI édition
- tokens npm manuels
- Erreurs E404 trompeuses
- Risques de sécurité
- Suivi des workflows incohérents
Après
- Zéro token npm
- Publication entièrement automatisée
- Authentification OIDC moderne
- Pipeline d'actions GitHub sécurisé
- Sorties monorepo prêtes à la production
- Des infrastructures plus propres
Enseignements tirés
1. npm Les erreurs peuvent être extrêmement trompeuses
Celui-ci :
E404 Not FoundEn fait, cela ne voulait pas dire que le paquet manquait.
Cela signifiait que la chaîne d'autorisation de l'OIDC n'était pas valide.
2. CI / CD moderne nécessite des versions modernes Node / npm
Beaucoup de développeurs mettent à niveau les frameworks mais oublient l'outillage d'infrastructure.
npm Trusted Publishing évolue rapidement.
Les anciennes versions de npm peuvent échouer de manière étrange.
3. .github/ Devrait généralement être versionné
Ignorer les workflows GitHub est un anti-modèle pour les équipes SaaS modernes.
Votre pipeline CI/CD fait partie de votre infrastructure produit.
Traitez-le comme un code de production.
4. Les miroirs Monorepo ajoutent de la complexité
Lorsque vous utilisez des miroirs publics :
pycolors-tokens
pycolors-uiVous devez clairement séparer :
- métadonnées du référentiel
- référentiel de publication réel
- Source d'exécution CI
Sinon, l'authentification devient confuse.
SaaS / Builder Insight
Ce problème est exactement la raison pour laquelle la maturité de l’infrastructure est importante dans les produits SaaS.
La plupart des développeurs pensent que l'expédition plus rapide signifie seulement:
- Vitesse de l'interface utilisateur
- Codage plus rapide
- AI tooling
Mais la fiabilité opérationnelle est tout aussi importante.
Les pipelines brisés détruisent l'élan.
Une pile SaaS moderne n’est pas seulement :
- Next.js
- Tailwind
- Prisma
- Stripe
C'est aussi :
- CI/CD reproductible
- Publication automatisée
- distribution de colis sécurisée
- workflows monorepo évolutifs
Les équipes qui expédient régulièrement sont les équipes qui réduisent les frictions d'infrastructure tôt.
Chemin de mise à niveau
Au fur et à mesure que votre écosystème SaaS grandit :
- plusieurs paquets
- systèmes de conception
- starters
- modèles
- configs partagées
L'automatisation devient critique.
C'est exactement pourquoi les starters SaaS prêts à la production sont importants.
La différence entre :
"it works locally"et:
"this scales operationally"C’est là qu’intervient le véritable levier d’ingénierie.
PyColors se concentre fortement sur ce calque :
- monorepos prêt à la production
- CI/CD moderne
- architecture de paquetage évolutive
- Défaillances de l'infrastructure SaaS
- flux de travail des développeurs premium
Parce que le transport maritime ne suffit pas.
Vous devez maintenir l'expédition fiable.