conventional commits y algunas herramientas de apoyo

¿ qué es conventional commits ?

CommitLint es una herramienta que ayuda a adoptar una convención para escribir commits de forma estandarizada. esta convención se llama Conventional Commits y esta relacionada con un estándar a la hora de versionar artefactos llamada Semantic Versioning.

La especificación de Conventional Commits es una convención sobre cómo escribir los mensajes de commits (específicamente el título del commit). Además nos provee de un conjunto sencillo de reglas para crear un CHANGELOG de commits explícito; lo que hace más fácil escribir herramientas encima del historial. Esta convención encaja con SemVer, al describir en los mensajes de los commits las funcionalidades, parches y cambios de ruptura hechos.

El mensaje del commit debe ser estructurado de la siguiente manera:

1
2
3
4
5
<tipo>(ámbito opcional): <descripción>

[cuerpo opcional]

[nota(s) al pie opcional(es)]

Por ejemplo:

1
2
3
4
5
fix(api): se corrige validacion de email

Se agregan nuevos dominios a la validación del correo

Issue #2

Los tipos que más se utilizan en Conventional Commits son los siguientes:

  • feat: Se agrega una nueva característica
  • fix: Se corrige algún problema
  • chore: Se modifican archivos que rodean el código fuente (configuraciones, cambios de versión)
  • refactor: Refactorización del código
  • docs: se agrega o modifica documentación
  • test: Se agrega o modifican tests

Los tipos relevantes a la hora de generar valor en el CHANGELOG son los feat y los fix, en base a esos tipos se construye de forma automática la bitácora de cambios relevantes (útil al usar standard-version, leer mas adelante)

Instalar commitlint

1
yarn add -D @commitlint/{cli,config-conventional} 

Si estas usando commonsjs debes cambiar el export default por module.exports. debes revisar el atributo type dentro del archivo package.json.

Ejecuta el siguiente comando para crear el archivo commitlint.config.js

1
$ echo "export default { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js

O agregar este archivo en la raíz del proyecto:

1
2
3
export default { 
extends: ['@commitlint/config-conventional']
};

Demás esta decir que puedes extender la configuración y acomodarla a tus necesidades, sólo considerar que las herramientas que se basan en estas convenciones también deberás adaptarlas y en otros casos es posible que no te sirvan.

husky

Husky es una herramienta que permite gestionar de forma simple git-hooks y que nos permite que cada vez que hagamos un commit, por ejemplo, corra los test unitarios o que nos revise si el commit message cumple con la convención de conventional commits (que es nuestro caso).

1
2
3
4
5
yarn add -D husky 
yarn husky init

npm pkg set scripts.commitlint="commitlint --edit"
echo "yarn commitlint \${1}" > .husky/commit-msg

El ultimo comando (el echo), genera un archivo cuyo contenido es la ejecución de commitlint y será ubicado en el directorio de los hooks de husky.

Nota: Cuando ejecutas el comando yarn husky init este te genera un directorio llamando .husky y dentro quedará un archivo llamado pre-commit con el siguiente contenido:

1
yarn test

Esto quiere decir que antes de que se realice el commit, husky ejecurata el comando yarn test y si este comando sale sin problemas, se efectuará el commit, en caso contrario los archivos no serán agregados al historial.

standard version

Otra herramienta que nos puede ayudar a mejorar la forma en que realizamos los releases, es una utilidad llamada standard-version (es algo vieja pero funciona perfectamente). Según su propia descripción:

Una utilidad para el versionamiento usando semver y generación de CHANGELOG potenciados por conventional commits.

1
yarn add -D standard-version

Una vez agregada la librería se debe agregar un comando en la sección de scripts en el package.json (sólo para mayor comodidad).

1
2
3
4
5
"scripts": {
...
"release": "standard-version",
"pre-release": "standard-version --dry-run"
}

Con eso ya puedes usar los comandos release y pre-release, el primero para concretar el release y el segundo es para ver como quedará de forma verbosa pero sin afectar el repositorio. Por ejemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$ yarn pre-release

yarn run v1.22.19
$ standard-version --dry-run
✔ bumping version in package.json from 1.0.0 to 1.1.0
✔ created CHANGELOG.md
✔ outputting changes to CHANGELOG.md

---
## 1.1.0 (2024-04-22)


### Features

* se agrega busqueda de app por su id
* se agrega funcion para eliminar aplicacion
* se agrega persistencia (find,delete,create) de app
* se agrega persistencia de eventos por app
* se agrega validacion de esquema para applicacion
* se agregan controladores para aplicaciones y logs


### Bug Fixes

* **ci:** se corrige nombre de la imagen mongodb
* **ci:** se corrige script para test, falta instalar deps
* se corrigen test unitarios
* se incluye close connection
---

✔ committing package.json and CHANGELOG.md
✔ tagging release v1.1.0
ℹ Run `git push --follow-tags origin develop` to publish

Nótese que el comando de pre-release nos indica exactamente lo que hará el comando release, donde hay que resaltar la linea bumping version in package.json from 1.0.0 to 1.1.0 que indica, en función de commits messages, califican para cambio de minor (feat agregados) o patch (fix agregados). Por ejemplo… si entre versiones solo tienes commits messages con fix cuando hagas el release, lo hara modificando el dígito del patch, por otro lado, si agregas un nuevo feature (feat) te modificará el minor en la versión.

Si requieres hacer un versionamiento manual debes ejecutar el siguiente comando:

1
yarn release --releas-as 1.1.1

Con eso fuerzas a que la versión sea la que indicas como argumento.

GitFlow

Si usas git-flow como modelo de ramas, te sugiero configurar standard-version para que no realice el tag una vez que hagas el release, de esta forma le delegas dicha función a git-flow. Les dejo el archivo de configuración que se llama .versionrc y debe estar ubicado en la raíz del proyecto:

1
2
3
4
5
{
"skip": {
"tag": true
}
}

Con esta configuración, puedes lanzar los comandos de release en la rama hotfix o release y luego finalizas las rama con git-flow.

Palabras al cierre

Espero les sirva este pequeño post sobre herramientas de desarrollo que utilizo en el día a día y sus configuraciones.

Les dejo los links de las referencias:

Cambio de casa, adiós Octopress bienvenido Jekyll

Estoy de mudanza de blog, adiós Octopress bienvenido Jekyll.

Una de las razones que me empujó a cambiarme de sistema de blog, es que Octopress esta sacando la versión 3 desde el 15 de enero del 2015, esta algo abandonado (ver los commits).

La pregunta era… ¿ hacia donde migro ?

Octopress se basa en Jekyll y la organización de los artículos es básicamente la misma. Pero no todo es tan fácil. Octopress tiene un conjunto de plugins que facilitan y ayudan a embellecer los artículos, por ejemplo, para destacar código fuente, citas, imágenes y video.

Jekyll de alguna u otra forma también tiene plugins para lo mismo, el problema es que hay que modificar todos los artículos donde fueron usados los plugins de Octopress y modificarlos al gusto de Jekyll.

Siguiente problema, elegir un lindo (?) tema para el blog, después de un largo recorrido buscando, encontré Minimal Mistakes, bien lindo, personalizable, con gran capacidad de extender y todas esa funcionalidades que a los developers nos enamoran (pero que jamás usamos al 100%). De todas formas, la instalación de este tema no fue sencillo, demasiadas configuraciones y cosas que no andan a la primera y la documentación, que es bien buena, no dice las cosas clave.

Algunas características de Jekyll son:

  • Posee muchos plugins
  • Esta escrito en ruby (puaj)
  • Tiene varios mecanismos de importación desde otros blogs.
  • El contenido se genera a partir de documentos escritos en markdown
  • Como el contenido es texto, estos se pueden mantener fácilmente en git

Si ve errores, considere que el blog esta en rodaje y sea amable… reporte el bug.