Parser SemVer

Analizar cadenas de versión semántica

Entendiendo Versionado semántico
TL;DR

El Versionado Semántico (SemVer) usa MAJOR.MINOR.PATCH donde cada número indica el tipo de cambio: ruptura, funcionalidad o corrección de errores. Es el estándar universal de versionado para software.

¿Qué es el Versionado Semántico?

El Versionado Semántico (SemVer) es una convención de versionado que asigna significado a cada número en una cadena de versión. En lugar de números de versión arbitrarios, SemVer codifica la naturaleza de los cambios directamente en la versión, haciendo posible que tanto humanos como máquinas comprendan qué cambió entre dos releases.

La idea central se resume en una sola frase de la especificación: “Dado un número de versión MAJOR.MINOR.PATCH, incremente la versión MAJOR cuando realice cambios de API incompatibles, la versión MINOR cuando agregue funcionalidad de manera compatible con versiones anteriores, y la versión PATCH cuando realice correcciones de errores compatibles con versiones anteriores.”

SemVer es la base de la gestión moderna de dependencias. Los gestores de paquetes como npm, Cargo, Composer y NuGet se apoyan en SemVer para resolver automáticamente versiones compatibles, evitando que las aplicaciones incorporen accidentalmente cambios incompatibles mientras siguen recibiendo correcciones de errores y nuevas funcionalidades.

Los tres números explicados

Toda versión semántica consta de tres enteros no negativos separados por puntos:

MAJOR.MINOR.PATCH
ComponenteCuándo incrementarEjemplo
MAJORCambios incompatibles en la API pública1.0.0 a 2.0.0 — función renombrada, endpoint eliminado
MINORNuevas funcionalidades compatibles con versiones anteriores1.0.0 a 1.1.0 — nuevo endpoint de API agregado
PATCHCorrecciones de errores compatibles con versiones anteriores1.0.0 a 1.0.1 — error de cálculo corregido

Cuando se incrementa un número de mayor prioridad, todos los números inferiores se reinician a cero. Incrementar MAJOR reinicia MINOR y PATCH. Incrementar MINOR reinicia solo PATCH.

AntesTipo de cambioDespuésExplicación
1.4.2Cambio incompatible2.0.0Incremento MAJOR, MINOR y PATCH se reinician
1.4.2Nueva funcionalidad1.5.0Incremento MINOR, PATCH se reinicia
1.4.2Corrección de error1.4.3Solo incremento PATCH
SemVer String Structure — 1.2.3-beta.1+build.456 A diagram showing the SemVer string 1.2.3-beta.1+build.456 decomposed into five labeled segments: MAJOR (1), MINOR (2), PATCH (3), pre-release (beta.1), and build metadata (build.456). 1 . 2 . 3 - beta.1 + build.456 MAJOR Breaking changes MINOR New features PATCH Bug fixes Pre-release Unstable identifier (after hyphen) Build Metadata Ignored in precedence (after plus sign) Precedence: 1.0.0-alpha < 1.0.0-beta < 1.0.0 < 1.0.1 < 1.1.0 < 2.0.0 Pre-release versions have lower precedence than the associated normal version

Pre-release y metadatos de build

SemVer admite dos extensiones opcionales que se añaden al núcleo MAJOR.MINOR.PATCH:

Identificadores de pre-release

Una versión de pre-release se denota añadiendo un guión y una serie de identificadores separados por puntos después de la versión PATCH:

1.0.0-alpha
1.0.0-alpha.1
1.0.0-beta.2
1.0.0-rc.1

Las versiones de pre-release indican que la versión es inestable y puede no satisfacer los requisitos de compatibilidad de la versión normal. Tienen menor precedencia que la versión normal asociada: 1.0.0-alpha < 1.0.0.

Los identificadores de pre-release se comparan de izquierda a derecha. Los identificadores numéricos se comparan como enteros; los identificadores alfanuméricos se comparan léxicamente. Los identificadores numéricos siempre tienen menor precedencia que los alfanuméricos. Esto significa que 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-rc.1.

Metadatos de build

Los metadatos de build se añaden usando un signo más después de la versión (o después de la etiqueta de pre-release si está presente):

1.0.0+20240315
1.0.0-beta.1+build.456

Los metadatos de build se ignoran completamente al determinar la precedencia de versiones. Dos versiones que difieren solo en metadatos de build se consideran iguales: 1.0.0+build.1 == 1.0.0+build.2. Los metadatos de build se usan típicamente para registrar información como hashes de commits, marcas de tiempo de compilación o identificadores de pipelines de CI.

Versión 0.x.y — Desarrollo inicial

La especificación SemVer establece una excepción especial para versiones con un MAJOR de 0:

La versión mayor cero (0.y.z) es para desarrollo inicial. CUALQUIER COSA PUEDE cambiar en cualquier momento. La API pública NO DEBERÍA considerarse estable.

Esto significa que durante la fase 0.x.y, no hay garantías. Un salto de 0.2.3 a 0.3.0 puede incluir cambios incompatibles. Un salto de 0.2.3 a 0.2.4 puede introducir nuevas funcionalidades. Las reglas normales solo tienen efecto pleno una vez que el proyecto alcanza 1.0.0.

Esta distinción es importante para la gestión de dependencias. Los gestores de paquetes tratan los rangos 0.x.y con más cautela. Por ejemplo, en npm, ^0.2.3 resuelve a >=0.2.3 <0.3.0 en lugar de >=0.2.3 <1.0.0: el operador caret se vuelve más estricto para tener en cuenta la inestabilidad de los releases pre-1.0.

Reglas de precedencia de versiones

SemVer define un ordenamiento claro para las versiones:

  1. MAJOR, MINOR, PATCH se comparan numéricamente de izquierda a derecha: 1.9.0 < 1.10.0 < 2.0.0
  2. Las versiones de pre-release tienen menor precedencia que la versión normal: 1.0.0-alpha < 1.0.0
  3. Los identificadores de pre-release se comparan de izquierda a derecha: numérico < alfanumérico, numérico por valor, alfanumérico léxicamente
  4. Los metadatos de build se ignoran completamente para la precedencia

Este ordenamiento permite a los gestores de paquetes ordenar, comparar y seleccionar la versión más apropiada automáticamente.

Casos de uso comunes

  • npm / Node.js: Todo paquete npm usa SemVer. El campo de dependencias de package.json espera rangos SemVer (^1.2.3, ~1.2.3)
  • Rust / Cargo: Cargo aplica estrictamente SemVer para todos los crates publicados en crates.io
  • PHP / Composer: Composer usa SemVer para la resolución de dependencias de paquetes PHP
  • Versionado de API: Las API REST y GraphQL usan versiones MAJOR (v1, v2) para señalar cambios incompatibles en los endpoints
  • Herramientas CLI: Las herramientas de línea de comandos siguen SemVer para comunicar la compatibilidad retroactiva de flags, salidas y comportamiento
  • Bibliotecas y frameworks: React, Vue, Angular, Django, Rails: todos usan SemVer para guiar las decisiones de actualización

Prueba estos ejemplos

SemVer válido Válido

Una versión semántica estándar con MAJOR=1, MINOR=2, PATCH=3. Este es el formato SemVer válido más simple: tres enteros no negativos separados por puntos.

1.2.3
SemVer válido con pre-release y build Válido

Una cadena SemVer completamente cualificada. La etiqueta de pre-release 'alpha.1' sigue a un guión e indica una versión inestable. Los metadatos de build 'build.123' siguen a un signo más y se ignoran durante la comparación de precedencia de versiones.

1.2.3-alpha.1+build.123
Inválido — Falta PATCH Inválido

SemVer requiere estrictamente los tres componentes: MAJOR.MINOR.PATCH. La versión '1.2' carece del número PATCH y no cumple con la especificación SemVer.

1.2