Publicación de paquetes npm turborepo, trusted publisher, pnpm
Source: Dev.to
Hace una semana me di a la tarea de actualizar mi monorepo personal (aún seguimos trabajando en él).
Dentro de todas las tareas, la de publicar paquetes fue de las más complicadas, y aquí explico por qué puede resultar complejo.
Old way
Mi proceso anterior era bastante simple:
- Entrar a npmjs.
- Generar un token de acceso.
- Agregar el token a tu proceso de publicación.
- Crear la variable de entorno
NPM_TOKENy elGITHUB_TOKENpara semantic‑release.
¡Y listo!
Sin embargo, npmjs cambió sus políticas de seguridad y ahora sugiere usar trusted publishing, que emplea OpenID Connect en lugar de un token tradicional.
Configuración de Trusted Publishing
1. Publicar el paquete al menos una vez
Antes de crear la configuración del trusted publisher en npmjs, el paquete debe existir en el registro.
Si vas a publicar un paquete nuevo, haz una publicación manual (por ejemplo pnpm publish --tag dummy) o usa la herramienta setup-npm-trusted-publish.
2. Añadir el trusted publisher
Accede a la sección de configuración de tu paquete:
https://www.npmjs.com/package//access- o
https://www.npmjs.com/package///access
Luego, agrega los datos de tu trusted publisher (GitHub o GitLab).
Debería aparecer algo similar a esto:
Campos a rellenar
- Organización o usuario
- Repositorio
- Nombre del archivo de tu workflow (incluyendo extensión). Nota: debe estar dentro de
.github/workflows.

En mi caso:
- Organización:
dezkareid - Repositorio:
dezkareid - Archivo workflow:
ci-packages.yml
¡Listo! La configuración está completa y ahora podemos pasar a nuestro workflow.
Configuración de Trusted Publishing en GitHub Actions
1. Permisos del job
Necesitamos habilitar el permiso id-token para que GitHub pueda obtener un token OIDC:
permissions:
id-token: write
Si además usamos semantic‑release para crear tags, generar changelogs y publicar en GitHub, necesitaremos permisos adicionales:
permissions:
contents: write
issues: write
pull-requests: write
id-token: write
2. Ejemplo de workflow
El repositorio de semantic‑release incluye un ejemplo de configuración para GitHub Actions.
3. Configuración de semantic-release
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md"]
}
],
"@semantic-release/github"
]
}
Problemas encontrados en un monorepo con pnpm
Arquitectura monorepo + pnpm
- Ubicación del proyecto: En un monorepo debemos apuntar al workspace que corresponde al paquete que queremos publicar.
- Autenticación con pnpm: pnpm maneja los workspaces de forma distinta a npm, lo que provocó errores de autenticación.
Errores concretos
-
Nombre del archivo del workflow incorrecto
No había añadido correctamente el nombre del archivo en la configuración de trusted publishing, por lo que npm no encontraba la configuración OIDC. -
Variables de entorno filtradas por Turborepo
El comandoreleasese ejecutaba a través de turborepo, que filtra variables de entorno. Solucioné el problema estableciendo el directorio de trabajo (working-directory) al folder del paquete y ejecutandosemantic-releasedirectamente. -
Plugin
@semantic-release/npmno funciona con pnpm
El plugin asume npm como gestor de paquetes. Con pnpm la autenticación fallaba. La solución fue usar el plugin especializado:npm i -D @anolilab/semantic-release-pnpm
Configuración final de semantic-release
{
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@anolilab/semantic-release-pnpm",
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md"]
}
],
"@semantic-release/github"
]
}
Con estos ajustes, la publicación de paquetes desde un monorepo gestionado con pnpm y usando trusted publishing funciona sin problemas. ¡Happy releasing!
semantic-release configuration
{
"plugins": [
[
"@semantic-release/commit-analyzer",
{
"preset": "conventionalcommits",
"releaseRules": [
{ "type": "feat", "release": "minor" },
{ "type": "fix", "release": "patch" },
{ "type": "perf", "release": "patch" },
{ "type": "refactor", "release": "patch" },
{ "type": "docs", "release": false },
{ "type": "style", "release": false },
{ "type": "chore", "release": false },
{ "type": "test", "release": false }
]
}
],
"@semantic-release/github"
],
"extends": "semantic-release-monorepo"
}
Y con esto ahora ya puedo publicar paquetes nuevamente usando mi stack preferido. Te dejo mi workflow para que puedas observarlo y, si te sirve, lo puedas replicar :D
