¿Qué hace Commitlint?
Valida mensajes de confirmación (commits) según el formato de Commits Convencionales utilizando la configuración y reglas de commitlint.
Cuándo Usar Esta Habilidad
Usa esta habilidad cuando:
- Estés configurando commitlint en un repositorio
- Estés configurando reglas de commitlint y configuraciones compartibles
- Estés integrando commitlint con enganches (hooks) de pre-commit o pipelines de CI/CD
- Estés extrayendo reglas de la configuración de commitlint para generar indicaciones (prompts) para LLM que generen mensajes de commit
- Valides mensajes de confirmación mediante programación
- Soluciones problemas de configuración o validación de commitlint
- Necesites comprender la sintaxis de las reglas y los niveles de severidad de commitlint
- Detectes archivos de configuración de commitlint en un repositorio
Capacidades Principales
Detección de Configuración
Commitlint usa cosmiconfig para encontrar archivos de configuración en este orden de prioridad:
Archivos de configuración dedicados:
.commitlintrc
.commitlintrc.json
.commitlintrc.yaml
.commitlintrc.yml
.commitlintrc.js
.commitlintrc.cjs
.commitlintrc.mjs
.commitlintrc.ts
.commitlintrc.cts
commitlint.config.js
commitlint.config.cjs
commitlint.config.mjs
commitlint.config.ts
commitlint.config.cts
Archivos package:
package.jsoncon el campocommitlintpackage.yaml(PNPM) con el campocommitlint
Formatos de Configuración
JavaScript Módulos ES (Recomendado):
// commitlint.config.js o commitlint.config.mjs
export default {
extends: ['@commitlint/config-conventional'],
};
TypeScript:
// commitlint.config.ts
import type { UserConfig } from '@commitlint/types';
import { RuleConfigSeverity } from '@commitlint/types';
const config: UserConfig = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [RuleConfigSeverity.Error, 'always', ['feat', 'fix', 'docs']],
},
};
export default config;
JSON:
{
"extends": ["@commitlint/config-conventional"]
}
YAML:
extends:
- "@commitlint/config-conventional"
Configuración de Reglas
Las reglas se configuran como arreglos: [nivel, aplicabilidad, valor]
Niveles de Severidad:
| Nivel | Significado | Enumeración de TypeScript |
|---|---|---|
| 0 | Deshabilitado | RuleConfigSeverity.Disabled |
| 1 | Advertencia | RuleConfigSeverity.Warning |
| 2 | Error | RuleConfigSeverity.Error |
Aplicabilidad:
'always'- La regla debe coincidir'never'- La regla no debe coincidir
Ejemplos de reglas:
rules: {
// Error si el tipo no está en la enumeración
'type-enum': [2, 'always', ['feat', 'fix', 'docs', 'style', 'refactor', 'perf', 'test', 'build', 'ci', 'chore', 'revert']],
// Error si el tipo está vacío
'type-empty': [2, 'never'],
// Error si el asunto está vacío
'subject-empty': [2, 'never'],
// Error si el encabezado supera los 100 caracteres
'header-max-length': [2, 'always', 100],
// Error si el asunto termina con punto
'subject-full-stop': [2, 'never', '.'],
// Advertencia si el cuerpo no tiene una línea en blanco al inicio
'body-leading-blank': [1, 'always'],
}
Configuraciones Comunes
@commitlint/config-conventional
La configuración compartible más utilizada. Reglas predeterminadas con nivel de error:
| Regla | Configuración | Ejemplo Correcto | Ejemplo Incorrecto |
|---|---|---|---|
type-enum | ['build', 'chore', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'revert', 'style', 'test'] | fix: message | foo: message |
type-case | 'lowerCase' | fix: message | FIX: message |
type-empty | never | fix: message | : message |
subject-case | never + ['sentence-case', 'start-case', 'pascal-case', 'upper-case'] | fix: some message | fix: Some Message |
subject-empty | never | fix: message | fix: |
subject-full-stop | never, '.' | fix: message | fix: message. |
header-max-length | 100 | Encabezado corto | Encabezado > 100 car. |
body-leading-blank | always (advertencia) | Línea en blanco antes del cuerpo | Sin línea en blanco |
body-max-line-length | 100 | Líneas <= 100 caracteres | Línea > 100 caracteres |
footer-leading-blank | always (advertencia) | Línea en blanco antes del pie | Sin línea en blanco |
footer-max-line-length | 100 | Líneas <= 100 caracteres | Línea > 100 caracteres |
Esquema de Configuración Completo
// commitlint.config.js
export default {
// Extender configuraciones compartibles (resueltas mediante resolución de node)
extends: ['@commitlint/config-conventional'],
// Ajuste preestablecido del analizador sintáctico para mensajes de commit
parserPreset: 'conventional-changelog-atom',
// Formateador de salida
formatter: '@commitlint/format',
// Reglas personalizadas (anulan reglas heredadas)
rules: {
'type-enum': [2, 'always', ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore']],
},
// Funciones que devuelven true para ignorar commits específicos
// Se combinan con los ignorados predeterminados (merge, revertir, versiones semver)
ignores: [(commit) => commit.includes('WIP')],
// Si se deben usar los patrones de ignorado predeterminados
// Patrones predeterminados: 'Merge pull request', 'Revert X', 'v1.2.3', etc.
defaultIgnores: true,
// URL de ayuda personalizada mostrada en caso de error
helpUrl: 'https://example.com/commit-guidelines',
// Configuración del indicador (para @commitlint/cz-commitlint)
prompt: {
messages: {},
questions: {
type: {
description: 'Selecciona el tipo de cambio:',
},
},
},
};
Uso en CLI
Instalación
# npm
npm install -D @commitlint/cli @commitlint/config-conventional
# yarn
yarn add -D @commitlint/cli @commitlint/config-conventional
# pnpm
pnpm add -D @commitlint/cli @commitlint/config-conventional
Comandos Comunes
# Validar el último commit
npx commitlint --last
# Validar un rango de commits
npx commitlint --from HEAD~5
# Validar desde un commit específico
npx commitlint --from abc1234
# Validar mensaje desde la entrada estándar
printf "feat: add feature" | npx commitlint
# Validar mensaje desde un archivo
npx commitlint < .git/COMMIT_EDITMSG
# Validar con bandera de edición (lee .git/COMMIT_EDITMSG)
npx commitlint --edit
# Validar con ruta de configuración personalizada
npx commitlint --config ./custom-commitlint.config.js
# Imprimir configuración resuelta
npx commitlint --print-config
# Modo estricto (las advertencias se convierten en código de salida 2)
npx commitlint --last --strict
Códigos de Salida
| Código | Significado |
|---|---|
| 0 | Éxito (sin errores) |
| 1 | Errores de validación encontrados |
| 2 | Advertencias encontradas (solo modo estricto) |
| 3 | Errores encontrados (modo estricto) |
| 9 | Archivo de configuración faltante (con bandera -g) |
Referencia de Reglas
Reglas de Tipo
| Regla | Condición | Aplicabilidad Predeterminada |
|---|---|---|
type-enum | type se encuentra en el valor | always |
type-case | type está en mayúsculas/minúsculas según value | always, 'lower-case' |
type-empty | type está vacío | never |
type-max-length | type tiene value o menos caracteres | always, Infinity |
type-min-length | type tiene value o más caracteres | always, 0 |
Reglas de Asunto
| Regla | Condición | Aplicabilidad Predeterminada |
|---|---|---|
subject-case | subject está en mayúsculas/minúsculas según value | always |
subject-empty | subject está vacío | never |
subject-full-stop | subject termina con value | never, '.' |
subject-max-length | subject tiene value o menos caracteres | always, Infinity |
subject-min-length | subject tiene value o más caracteres | always, 0 |
subject-exclamation-mark | subject tiene signo de exclamación antes de : | never |
Reglas de Ámbito
| Regla | Condición | Aplicabilidad Predeterminada |
|---|---|---|
scope-enum | scope se encuentra en el valor | always, [] |
scope-case | scope está en mayúsculas/minúsculas según value | always, 'lower-case' |
scope-empty | scope está vacío | never |
scope-max-length | scope tiene value o menos caracteres | always, Infinity |
scope-min-length | scope tiene value o más caracteres | always, 0 |
Reglas de Encabezado
| Regla | Condición | Aplicabilidad Predeterminada |
|---|---|---|
header-case | header está en mayúsculas/minúsculas según value | always, 'lower-case' |
header-full-stop | header termina con value | never, '.' |
header-max-length | header tiene value o menos caracteres | always, 72 |
header-min-length | header tiene value o más caracteres | always, 0 |
header-trim | header no tiene espacios iniciales ni finales | always |
Reglas de Cuerpo
| Regla | Condición | Aplicabilidad Predeterminada |
|---|---|---|
body-leading-blank | body comienza con una línea en blanco | always |
body-empty | body está vacío | never |
body-max-length | body tiene value o menos caracteres | always, Infinity |
body-max-line-length | Las líneas de body tienen value o menos caracteres (excluyendo URLs) | always, Infinity |
body-min-length | body tiene value o más caracteres | always, 0 |
body-case | body está en mayúsculas/minúsculas según value | always, 'lower-case' |
body-full-stop | body termina con value | never, '.' |
Reglas de Pie
| Regla | Condición | Aplicabilidad Predeterminada |
|---|---|---|
footer-leading-blank | footer comienza con una línea en blanco | always |
footer-empty | footer está vacío | never |
footer-max-length | footer tiene value o menos caracteres | always, Infinity |
footer-max-line-length | Las líneas de footer tienen value o menos caracteres | always, Infinity |
footer-min-length | footer tiene value o más caracteres | always, 0 |
Valores de Mayúsculas/Minúsculas
Para reglas que verifican mayúsculas/minúsculas (*-case):
[
'lower-case', // minúsculas
'upper-case', // MAYÚSCULAS
'camel-case', // camelCase
'kebab-case', // kebab-case
'pascal-case', // PascalCase
'sentence-case', // Sentence case
'snake-case', // snake_case
'start-case', // Start Case
]
Uso Programático
Cargar Configuración
import load from '@commitlint/load';
async function getCommitlintConfig() {
const config = await load();
console.log(config.rules);
return config;
}
Validar Mensaje
import load from '@commitlint/load';
import lint from '@commitlint/lint';
async function validateMessage(message) {
const config = await load();
const result = await lint(message, config.rules);
return {
valid: result.valid,
errors: result.errors,
warnings: result.warnings,
};
}
Patrones de Integración con LLMs
Extraer Reglas para Generación de Indicaciones
Genera restricciones amigables para LLM a partir de la configuración de commitlint:
def extract_rules_for_prompt(config: dict) -> str:
"""Extrae reglas de commitlint en un formato amigable para LLM."""
rules = config.get("rules", {})
prompt_parts = []
# Extraer type-enum si está presente
if "type-enum" in rules:
level, applicability, types = rules["type-enum"]
if level > 0 and applicability == "always":
prompt_parts.append(f"Tipos de commit permitidos: {', '.join(types)}")
# Extraer scope-enum si está presente
if "scope-enum" in rules:
level, applicability, scopes = rules["scope-enum"]
if level > 0 and applicability == "always":
prompt_parts.append(f"Ámbitos de commit permitidos: {', '.join(scopes)}")
# Extraer header-max-length si está presente
if "header-max-length" in rules:
level, applicability, max_len = rules["header-max-length"]
if level > 0:
prompt_parts.append(f"Longitud máxima del encabezado del commit: {max_len} caracteres")
# Extraer subject-case si está presente
if "subject-case" in rules:
level, applicability, cases = rules["subject-case"]
if level > 0 and applicability == "never":
prompt_parts.append(f"Casos de asunto no permitidos: {', '.join(cases)}")
return "\n".join(prompt_parts)
Generar Mensajes de Commit (Indicación para LLM)
Ejemplo de indicación para que un LLM genere mensajes de commit:
Genera un mensaje de commit en el formato Conventional Commits.
Reglas del proyecto:
- Tipos de commit: feat, fix, docs, style, refactor, test, chore
- Longitud máxima del encabezado: 100 caracteres
- El asunto no debe terminar con punto
- Se requiere línea en blanco antes del cuerpo del commit
Contexto de los cambios:
- Archivos modificados: src/utils.ts, src/index.ts
- Descripción: Implementar la autenticación de usuarios
example
Parsear Mensajes de Commit
import re
def parse_conventional_commit(message: str) -> dict:
"""Analiza un mensaje de commit convencional en sus partes."""
pattern = r'^(?P<type>\w+)(?:\((?P<scope>[\w-]+)\))?(?P<breaking>!)?:\s*(?P<subject>.+)$'
match = re.match(pattern, message, re.MULTILINE)
if not match:
return {"valid": False}
return {
"valid": True,
"type": match.group("type"),
"scope": match.group("scope"),
"breaking": match.group("breaking") is not None,
"subject": match.group("subject"),
}
Mejores Prácticas
- Usa la extensión @commitlint/config-conventional como punto de partida y personaliza las reglas según las necesidades de tu equipo.
- Configura las reglas con un nivel de error (2) para reglas críticas como
type-enum,type-empty,subject-emptyyheader-max-length. - Usa el nivel de advertencia (1) para reglas sugeridas como
body-leading-blankyfooter-leading-blank. - Deshabilita las reglas con nivel 0 que no se apliquen a tu proyecto o limiten la productividad del equipo.
- Integra commitlint con enganches de pre-commit o pipelines de CI para detectar mensajes no conformes temprano en el proceso de desarrollo.
- Documenta tus reglas personalizadas en el README del repositorio para que los miembros del equipo las conozcan.
- Usa el comando
--print-configpara depurar la configuración resuelta antes de aplicar cambios complejos. - Define una
helpUrlpersonalizada para enlazar a la documentación de las convenciones de commit de tu equipo.
Solución de Problemas
Mensajes de Error Comunes
Error: Config file not found
- Asegúrate de que exista un archivo de configuración de commitlint en el directorio raíz del proyecto.
- Usa
--configpara especificar una ruta personalizada.
Error: Unknown rule: my-rule
- Verifica que el nombre de la regla esté escrito correctamente.
- Las reglas personalizadas requieren un plugin.
Error: Type must be one of [...]
- El tipo del commit no está en la lista
type-enum. - Verifica los tipos permitidos en tu configuración.
Advertencia: body must have leading blank line
- El cuerpo del commit debe comenzar con una línea en blanco.
- Agrega una línea vacía entre el encabezado y el cuerpo.
Depuración
# Verificar configuración
npx commitlint --print-config
# Forzar re-resolución del paquete de configuración
npx commitlint --last --verbose
# Verificar existencia del archivo de configuración
ls -la commitlint.config.* .commitlintrc*