Открыть сервис

Семантическое версионирование

Семантическое версионирование (SemVer, от англ. Semantic Versioning) — это формальная система правил присвоения и увеличения номеров версий программного обеспечения, предназначенная для передачи смысла изменений между разработчиками и пользователями. Основная цель семантического версионирования — устранение неоднозначности при обновлении зависимостей, позволяя автоматически определять совместимость версий на основе их номера. Спецификация была предложена Томом Престон-Вернером в 2013 году и получила широкое распространение в экосистемах пакетных менеджеров (npm, Cargo, Packagist, NuGet и других).

История

Проблема управления версиями существовала задолго до появления SemVer. В ранних проектах номера версий часто присваивались произвольно, что приводило к конфликтам зависимостей и «аду зависимостей» (dependency hell). В 2013 году Том Престон-Вернер, работая над проектом npm, опубликовал черновик спецификации SemVer 2.0.0, который быстро стал де-факто стандартом в сообществе JavaScript и затем распространился на другие языки и платформы. В 2014 году спецификация была доработана до версии 2.0.0-rc1, а окончательная версия 2.0.0 вышла в 2015 году. С тех пор SemVer поддерживается сообществом через репозиторий на GitHub.

Основные правила

Спецификация SemVer 2.0.0 определяет формат номера версии как MAJOR.MINOR.PATCH (основная.дополнительная.исправление), где каждый компонент увеличивается в строго определённых случаях:

  • MAJOR (основная версия) — увеличивается при внесении несовместимых изменений в API. Пример: переход с 1.x.x на 2.0.0 означает, что код, написанный для версии 1.x, может перестать работать.
  • MINOR (дополнительная версия) — увеличивается при добавлении новой функциональности, которая сохраняет обратную совместимость с предыдущими версиями. Также может включать пометку о том, что API устарел (deprecated).
  • PATCH (исправление) — увеличивается при внесении исправлений ошибок (bug fixes), которые не нарушают обратную совместимость.

Пре-релизные и метаданные

Кроме трёх основных чисел, версия может содержать суффиксы:

  • Пре-релизная метка (pre-release) — добавляется через дефис после PATCH (например, 1.0.0-alpha.1, 2.0.0-rc.2). Такие версии имеют меньший приоритет, чем обычные, и не считаются стабильными.
  • Метаданные сборки (build metadata) — добавляются через плюс (например, 1.0.0+build.123). Они игнорируются при сравнении версий и служат только для идентификации конкретной сборки.

Диапазоны и операторы

В экосистемах пакетных менеджеров принято задавать диапазоны допустимых версий зависимостей с помощью операторов:

  • Каретка (^) — разрешает обновления, не изменяющие первую ненулевую цифру слева. Например, ^1.2.3 допускает версии от 1.2.3 до 2.0.0 (не включая). ^0.2.3 допускает от 0.2.3 до 0.3.0.
  • Тильда (~) — разрешает обновления только в пределах указанного уровня. Например, ~1.2.3 допускает от 1.2.3 до 1.3.0.
  • Точные версии1.2.3 — только эта версия.
  • Диапазоны>=1.2.3 <2.0.0.

Применение

Пакетные менеджеры

SemVer является основой для работы большинства современных пакетных менеджеров:

  • npm (Node.js) — использует SemVer для всех публикуемых пакетов.
  • Cargo (Rust) — требует SemVer для версий пакетов в реестре crates.io.
  • Packagist (PHP) — использует SemVer для пакетов Composer.
  • NuGet (.NET) — поддерживает SemVer 2.0.0 начиная с NuGet 4.3.0.
  • PyPI (Python) — использует собственную схему, но многие проекты следуют SemVer.

Автоматизация и CI/CD

SemVer позволяет автоматизировать процесс публикации новых версий. Например, инструменты вроде semantic-release анализируют коммиты (по соглашению Conventional Commits) и автоматически увеличивают MAJOR, MINOR или PATCH в зависимости от типа изменений. Это снижает риск человеческой ошибки и ускоряет релизный цикл.

Критика и альтернативы

Несмотря на широкое распространение, SemVer имеет ряд недостатков:

  • Сложность соблюдения — точное определение, является ли изменение обратно совместимым, требует глубокого понимания API. На практике разработчики часто ошибаются, нарушая обещания SemVer.
  • Раздувание MAJOR-версий — частые несовместимые изменения приводят к быстрому росту основной версии (например, 10.0.0, 11.0.0), что может вводить в заблуждение.
  • Неприменимость к некоторым проектам — для библиотек с нестабильным API (например, на ранних стадиях разработки) SemVer неэффективен. В таких случаях рекомендуется использовать версию 0.x.x, где любые изменения считаются несовместимыми.

Альтернативные схемы

  • CalVer (Calendar Versioning) — версия привязывается к дате выпуска (например, 2024.03.15). Используется в Ubuntu, Python, Blender.
  • ZeroVer — версия всегда начинается с 0 (например, 0.1.0, 0.2.0), что означает, что проект не гарантирует стабильности API. Применяется в экспериментальных проектах.
  • RomVer (Romantic Versioning) — неформальная схема, где версия выбирается произвольно, без строгих правил.

Интересные факты

  • Спецификация SemVer 2.0.0 занимает всего около 10 страниц текста и доступна на официальном сайте semver.org.
  • В 2016 году проект npm столкнулся с проблемой «левого сдвига» (left-pad), когда удаление небольшого пакета сломало тысячи проектов. Это привело к усилению требований к стабильности версий.
  • Некоторые крупные проекты, такие как Kubernetes и Docker, используют SemVer, но с собственными расширениями (например, Kubernetes добавляет суффикс -beta).

Источники

  • Preston-Werner, T. (2013). Semantic Versioning 2.0.0. semver.org.
  • npm Documentation. (2023). About semantic versioning.
  • Cargo Documentation. (2024). Specifying dependencies.
  • NuGet Documentation. (2023). Semantic Versioning 2.0.0.
  • Спецификация Conventional Commits 1.0.0. (2020).

BFOmetr — база данных и аналитика по компаниям России.

На главную BFOmetr →