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

Материал из llmdocs — справочник разработчика
Портал: Git, CI/CD, DevOps
Семантическое версионирование
АвторТом Престон-Вернер
Текущая версия спецификации2.0.0 (2013)
ФорматMAJOR.MINOR.PATCH[-предрелиз][+сборка]
Лицензия спецификацииCC BY 3.0
Используетсяnpm, Cargo, Go-модули, Helm, многие библиотеки
Альтернативыкалендарное версионирование (CalVer), PEP 440 в Python
Сайтsemver.org

Семантическое версионирование (англ. Semantic Versioning, SemVer) — соглашение о том, как присваивать номера версиям программ, чтобы номер сам говорил о характере изменений. Версия записывается как MAJOR.MINOR.PATCH, например 2.7.1: рост первой цифры означает несовместимые изменения, второй — новые возможности без поломок, третьей — только исправления ошибок.[1] Благодаря этому пакетные менеджеры могут автоматически обновлять зависимости в безопасных пределах, а пользователь библиотеки заранее знает, чего ждать от обновления.

История

Спецификацию написал Том Престон-Вернер, сооснователь GitHub, обобщив сложившуюся практику открытых проектов. Версия 2.0.0, действующая до сих пор, опубликована в 2013 году на сайте semver.org. Соглашение было принято экосистемами npm, Cargo, Go-модулей, Composer, Helm и многими другими.

Правила

Обязательное условие — у проекта есть публичный API: документированный интерфейс, относительно которого и определяется совместимость. Дальше:[1]

Что изменилось Какую часть увеличить Пример
Несовместимое изменение API MAJOR, остальные обнуляются 1.4.2 → 2.0.0
Новая возможность, обратно совместимая MINOR, PATCH обнуляется 1.4.2 → 1.5.0
Исправление ошибки без изменения API PATCH 1.4.2 → 1.4.3

Ещё несколько важных пунктов:

  • Опубликованная версия неизменна: исправление выпускается новым номером, а не перезаписью старого.
  • Версии 0.y.z — начальная разработка: API нестабилен, и ломать его можно в любой момент. Версия 1.0.0 объявляет публичный API стабильным.
  • Предрелизы записываются через дефис: 2.0.0-alpha, 2.0.0-beta.2, 2.0.0-rc.1. Они младше соответствующего релиза: 2.0.0-rc.1 < 2.0.0.
  • Метаданные сборки — через плюс: 1.0.0+20261109.sha.5114f85. При сравнении версий они игнорируются.
  • Сравнение покомпонентное и числовое: 1.10.0 > 1.9.0, а предрелизные метки сравниваются по частям — alpha.2 < alpha.10 < beta.

Диапазоны версий

Пакетные менеджеры используют SemVer, чтобы описывать допустимые обновления:[2]

Запись (npm) Разрешает Смысл
^1.4.2 >=1.4.2 <2.0.0 любые совместимые обновления
~1.4.2 >=1.4.2 <1.5.0 только исправления
1.4.2 ровно эту версию полная фиксация
^0.4.2 >=0.4.2 <0.5.0 в нулевой версии MINOR считается «мажорным»

В Cargo запись "1.4.2" по умолчанию означает то же, что ^1.4.2.[3] В Go несовместимая версия модуля получает новый путь импорта с суффиксом: example.com/lib/v2 — так две мажорные версии могут жить в одной программе.[4] Python использует собственную схему PEP 440, которая совместима с SemVer по форме, но допускает и другие варианты (1.0.post1, 2.0rc1); оператор ~= в ней похож на тильду npm.[7]

Диапазоны дают гибкость, но для воспроизводимых сборок точные версии фиксируются в lock-файлах (package-lock.json, Cargo.lock, uv.lock), которые хранят в репозитории.

Автоматизация

Соглашение Conventional Commits структурирует сообщения коммитов: fix: соответствует PATCH, feat: — MINOR, а BREAKING CHANGE: в теле или ! после типа (feat!:) — MAJOR.[5] Инструменты semantic-release, release-please и changesets по истории коммитов сами вычисляют следующую версию, пишут журнал изменений и публикуют релиз из GitHub Actions или другой CI-системы.

feat(api): добавить фильтр по дате       → 1.5.0
fix: не падать на пустом ответе          → 1.5.1
feat!: удалить устаревший метод /v1/list → 2.0.0

Номер версии обычно ставят и Git-тегом: git tag -a v1.5.1 -m "Release 1.5.1".

Ограничения и критика

  • Совместимость — суждение человека. Изменение поведения, исправление ошибки, на которую кто-то полагался, или поднятие минимальной версии языка формально могут оказаться «ломающими». Отсюда шутка, что любое изменение для кого-то мажорное.
  • «Вечный ноль». Многие популярные проекты годами живут в 0.x, обходя обязательства SemVer.
  • Неприменимость к продуктам без API. Для приложений и операционных систем часто удобнее календарное версионирование (CalVer): Ubuntu 24.04, pip 25.1, JetBrains 2025.2 — номер говорит о дате, а не о совместимости.[6]

Несмотря на это, SemVer остаётся общим языком между авторами библиотек и их пользователями, и его соблюдение — признак зрелого проекта.

См. также

Источники

  1. Semantic Versioning 2.0.0
  2. npm Docs — About semantic versioning
  3. Cargo Book — SemVer Compatibility
  4. Go Modules Reference — Major version suffixes
  5. Conventional Commits 1.0.0
  6. Calendar Versioning
  7. PEP 440 — Version Identification and Dependency Specification