Cómo automatizar la subida de versiones a NPM

Nicolás Ignacio Gómez Espejo
6 min readNov 6, 2017

--

Este tutorial es la cuarta y última parte de una serie de tutoriales que explican cómo crear un paquete NPM, con medallas y actualizaciones automáticas.

Hasta ahora hemos visto:

  1. Cómo crear tu primer módulo NPM
  2. Cómo agregar la medalla “build” a tu módulo NPM.
  3. Cómo agregar la medalla “dependencies” a tu módulo NPM.

Ahora veremos “Cómo automatizar la subida de versiones a NPM”.

Pequeño repaso de subida de versiones a NPM

El proceso para subir una nueva versión de tu módulo a NPM es más o menos así:

  1. Haces cambios en el código
  2. Actualizas la versión del package.json
  3. Subes código a tu rama principal, y etiquetas los cambios con un tag (generalmente, igual a la versión que colocaste en package.json).
  4. Publicas en npm (npm publish).

Todo esto = 😫 😫 😫 😫 😫

¿Cómo optimizamos este proceso?

Con herramientas que nos facilitan la vida!

Básicamente automatizaremos 2 cosas:

  1. Automatización de tags
  2. Automatización de npm publish

Paso 1: Automatización de tags

Para utilizar esta técnica de automatización de tags hay que tener claro 2 cosas: “versionamiento semántico” y “especificación convencional de commits”.

a) Versionamiento semántico

Puedes ver la especificación en la página principal: http://semver.org/lang/es/

El “versionamiento semántico”, es una convención para nombrar las versiones de nuestro software.

En el mundo de la gestión de software existe el temor de caer en algún momento en el llamado “infierno de las dependencias”. Mientras más grande crece tu sistema y mientras más paquetes integras en tu software, más probable es que te encuentres, un día, en este pozo de la desesperación.

El objetivo principal de la convención es eliminar el dolor de cabeza del versionamiento de las dependencias de un software.

Ayuda a responder dudas como las que siguen:

  • ¿Podré actualizar de la versión 1.2.3 a la 1.2.4?
  • ¿Podré actualiza de la 1.2.3 a la 1.3.0?
  • ¿Podré actualizarla de la 1.2.3 a la 2.0.0?

Bajo este esquema, los números de versión y la forma en que cambian entregan significado del código que está detrás y lo que fue modificado de una versión a otra.

Y ayuda a darle significado a los cambios que vamos subiendo.

En resumen, la convención es así: la versión debe tener el formato X.Y.Z (los 3 números positivos) donde:

  • Z: corresponde a la versión PATCH, y “debe ser incrementada cuando se introducen solo arreglos compatibles con la versión anterior”. Ejemplo: Resolución de bugs 🐛
  • Y: corresponde a la versión MINOR, y “DEBE ser incrementada si se introduce nueva funcionalidad compatible con la versión anterior”. Ejemplo: nuevo método a una clase.
  • X: corresponde a la versión MAYOR, y “DEBE ser incrementada si cualquier cambio no compatible con la versión anterior es introducida a la API pública”. Ejemplo: el más conocido y nefasto… Angular 1.x a Angular 2.x 😂

En base a esto, para responder las preguntas anteriores, si estamos hablando de una librería que usa versionamiento semántico:

  • ¿Podré actualizar de la versión 1.2.3 a la 1.2.4? → Sí, no debería haber problemas e incluso deberías ir actualizando, ya que incluye correcciones a problemas.
  • ¿Podré actualiza de la 1.2.3 a la 1.3.0? → Sí, no debería haber problemas e incluso podrás utilizar las nuevas funcionalidades que agregaron.
  • ¿Podré actualizarla de la 1.2.3 a la 2.0.0? → No, ya que hay cambios que pueden afectar tu código. Para asegurarte, debes revisar los cambios de versiones para ver si hay algún cambio que te afecta.

b) Especificación convencional de commits

Puedes ver el manifesto en https://conventionalcommits.org/

Básicamente, dice que debes estructurar los mensajes de commits de la siguiente forma:

<type>[optional scope]: <description>

[optional body]

[optional footer]

type y description son obligatorios. Los posibles valores de type son:

  • fix: commit que soluciona un bug del código → relacionado a PATCH de SemVer.
  • feat: commit agrega una feature al código → relacionado a MINOR de SemVer.
  • BREAKING CHANGE: commit que tiene un cambio que hace que el código anterior sea incompatible con el nuevo → relacionado a MAJOR de SemVer.

c) Automatizando los tags de nuestro repositorio

Si sigues las reglas de la especificación convencional de commits, puedes tener el versionamiento total de tu repositorio automatizado, gracias al package standard-version 👌

Para agregarlo, simplemente instala con

npm i --save-dev standard-version

Y luego modifica tu package.json agregando lo siguiente:

{
"scripts": {
"release": "standard-version"
}
}

Y ahora creamos nuestro primer release:

npm run release -- --first-release
git push --follow-tags origin master; npm publish

A modo de prueba, hice un cambio en el README.md con el siguiente mensaje de commit:

fix: updated README.md

Luego

npm run release
git push --follow-tags origin master; npm publish

Y mágicamente…

Así que, mientras sigas la convención de commits y utilices npm run release antes de subir las versiones, todo debería andar de maravilla.

Paso 2: automatización de publicación en NPM

Sí, lo anterior puede parecer un poco denso… pero te prometo que esto será más digerible 😃

Gracias a TravisCI, cada vez que haya un build exitoso, podremos publicar automáticamente la versión en NPM.

Para esto, debemos:

a) Actualizar .travis.yml

Aquí agregamos la sección deploy:

  • provider: indicar donde queremos subir el código cuando haya un build exitoso. En este caso a npm
  • email: credenciales de NPM. Travis permite tener variables de entorno (por ejemplo, $NPM_EMAIL), para que así no tengas que colocar tu correo de NPM en el código del repositorio 👌
  • api_key: API_KEY de NPM. Aquí también utilicé una variable de entorno.
  • on: para indicar cuando queremos que se suba el código a npm. No queremos que se suba siempre… sólo cuando hay nuevos tags en el repositorio.

b) Agregar variables de entorno a nuestra cuenta de Travis

En Travis, entra a la pestaña de Settings de tu proyecto, la cual debería ser

https://travis-ci.org/username/repo/settings

Donde username es tu nombre de usuario de Github y repo es el nombre de tu repositorio.

Aquí podemos ver la sección de “Environment Variables”

NPM_EMAIL

Simplemente agrega tu correo de npm.

NPM_TOKEN

Ejecuta

cat ~/.npmrc

Deberías ver algo como

//registry.npmjs.org/:_authToken=XXXXX

XXXXX es el valor que debes colocar para NPM_TOKEN.

c) Subir cambios y ver la magia

Ahora subiré la actualización a mi archivo .travis.yml como nueva versión:

git add .
git commit -m "feat: updated travis with deploy configuration"
npm run release
git push --follow-tags origin master

Y “mágicamente” en NPM vemos la nueva versión 🎉:

TL;DR

  • Usar package standard-version para automatizar la gestión de tags de tu repositorio → ver commits de ejemplo.
  • Configurar travis para que haga un deploy automático a NPM cuando subas nuevos releases a tu repositorio → ver commits de ejemplo.

Palabras finales

Espero que te haya gustado esta serie de tutoriales y que hayas logrado el objetivo: aprender a crear un módulo NPM fácil de gestionar y de actualizar! 🎉

--

--