SEAD Club

Конвенції Версіювання

Вступ

Цей документ описує конвенції версіонування, що прийняті Клубом інженерії програмного забезпечення та розробки при Державному університеті інформаційних та комунікаційних технологій. Ці конвенції базуються на стандартних практиках версіонування в мові програмування Rust. Семантичне версіонування 2.0.0

Огляд

Заданому номеру версії MAJOR.MINOR.PATCH, збільште:

  1. MAJOR - версію при внесенні несумісних змін API

  2. MINOR - версію при додаванні функціоналу сумісним способом з попередніми версіями

  3. PATCH - версію при виправленні помилок, сумісних з попередніми версіями

Додаткові мітки для передвищення та метаданих збірки доступні як розширення формату MAJOR.MINOR.PATCH.

Вступ

У світі управління програмним забезпеченням існує місце, відоме як “пекло залежностей”. Чим більше росте ваша система та чим більше пакетів ви інтегруєте в своє програмне забезпечення, тим більше ймовірності опинитися, одного дня, в цьому ярі діску.

У системах з численними залежностями випуск нових версій пакетів може швидко перетворитися на кошмар. Якщо вказані занадто жорсткі вимоги до залежностей, ви ризикуєте застрягти на версії (неможливість оновлення пакету без випуску нових версій кожного залежного пакету). Якщо вимоги до залежностей вказані занадто вільно, вас невідмінно укусить “проміскуючість версій” (припущення сумісності з більшою кількістю майбутніх версій, ніж це розумно). Ви опиняєтеся в пеклі залежностей, коли блокування версії та/або проміскуючість версій ускладнюють легке та безпечне рухання вашого проекту вперед.

Як рішення цього проблеми, був запропонований простий набір правил і вимог, які визначають, як присвоюються та збільшуються номери версій. Ці правила базуються на, але не обмежуються передісторією широко вживаних загальних практик в області як закритого, так і відкритого програмного забезпечення. Для того, щоб ця система працювала, спочатку потрібно оголосити публічний API. Це може бути документацією або забезпечуватися кодом. В будь-якому випадку важливо, щоб це API було чітким і точним. Після ідентифікації вашого публічного API, зміни в ньому повинні бути комуніковані з конкретними збільшеннями вашого номера версії. Розгляньте формат версії X.Y.Z (Основне.Мінорне.Патч). Виправлення помилок, які не впливають на API, збільшують версію патча, додавання/зміни API, сумісні з попередніми версіями, збільшують версію мінора, а зміни API, що несумісні з попередніми версіями, збільшують версію основного.

Цей набір правил був названий “Семантичне версіонування”. За цією схемою номери версій та спосіб їх зміни вказують на зміст коду та те, що було змінено від одної версії до іншої.

Специфікація семантичного версіонування (SemVer)

Ключові слова «ПОВИНЕН», «НЕ ПОВИНЕН», «ПОТРІБНО», “НЕ СЛІД”, “РЕКОМЕНДОВАНО”, “МОЖЕ” та “НЕОБОВ’ЯЗКОВО” в цьому документі мають бути інтерпретується, як описано в RFC 2119

  1. Програмне забезпечення, яке використовує Семантичне версіонування, ПОВИННО оголошувати публічний API. Це API може бути оголошене в коді або існувати виключно в документації. Безперервність його виконання, ЦЕМІ повинно бути чітким і всебічним.

  2. Звичайний номер версії ПОВИННО мати форму X.Y.Z, де X, Y та Z є невід’ємні цілі числа і НЕ МОЖЕ містити ведучих нулів. X - це основна версія, Y - версія мінора, а Z - версія патча. Кожен елемент ПОВИННО збільшуватися числово. Наприклад: 1.9.0 -> 1.10.0 -> 1.11.0.

  3. Після випуску версійного пакета, зміст цієї версії ПОВИННО НЕ МОЖЕ бути змінений. Будь-які зміни ПОВИННО бути випущені як нова версія.

  4. Основна версія нуль (0.y.z) використовується для початкового розроблення. Все МОЖЕ змінитися в будь-який час. Публічне API НЕ ПОВИННО вважатися стійким.

  5. Версія 1.0.0 визначає публічне API. Спосіб, яким збільшується номер версії після цього випуску, залежить від цього публічного API та того, як воно змінюється.

  6. Патч-версія Z (x.y.Z | x > 0) ПОВИННО бути збільшена, якщо вводяться тільки сумісні з попередніми виправлення помилок. Виправлення помилок визначається як внутрішня зміна, яка виправляє невірну поведінку.

  7. Версія мінора Y (x.Y.z | x > 0) ПОВИННО бути збільшена, якщо вводиться новий сумісний з попередніми функціонал для публічного API. Вона ПОВИННО також бути збільшена, якщо будь-який функціонал публічного API позначено як застарілий. Вона МОЖЕ бути збільшена, якщо в приватному коді вводяться значущі нові функціонал чи поліпшення. Вона МОЖЕ включати зміни рівня патча. Патч-версія ПОВИННО бути скинута на 0, коли збільшується версія мінора.

  8. Основна версія X (X.y.z | X > 0) ПОВИННО бути збільшена, якщо вводяться несумісні з попередніми зміни до публічного API. Вона МОЖЕ також включати зміни рівня мінора та патча. Патч та мінор версії ПОВИННО бути скинуті на 0, коли збільшується основна версія.

  9. Попередню версію МОЖНА позначити, додавши дефіс і серію ідентифікаторів, розділених крапками, які відразу слідують за номером патча. Ідентифікатори ПОВИННІ містити лише ASCII-буквено-цифрові символи та дефіси [0-9A-Za-z-]. Ідентифікатори НЕ МОЖУ бути порожніми. Числові ідентифікатори НЕ МОЖУ містити ведучих нулів. Попередні версії мають менший пріоритет, ніж пов’язана нормальна версія. Попередня версія вказує на те, що версія є нестабільною і може не відповідати задуманим вимогам сумісності, як вказано в пов’язаній нормальній версії. Приклади: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92, 1.0.0-x-y-z.--.

  10. Метадані збірки МОЖНА позначити, додавши знак плюса та серію ідентифікаторів, розділених крапками, які відразу слідують за номером патча чи попередньої версії. Ідентифікатори ПОВИННІ містити лише ASCII-буквено-цифрові символи та дефіси [0-9A-Za-z-]. Ідентифікатори НЕ МОЖУ бути порожніми. Метадані збірки ПОВИННІ бути ігноровані при визначенні пріоритету версії. Таким чином, дві версії, які відрізняються лише метаданими збірки, мають однаковий пріоритет. Приклади: 1.0.0-alpha+001, 1.0.0+20130313144700, 1.0.0-beta+exp.sha.5114f85, 1.0.0+21AF26D3----117B344092BD.

  11. Пріоритет вказує на те, як версії порівнюються між собою при впорядкуванні.

    1. Пріоритет МАЄ бути розрахований шляхом розділення версії на основні, додаткові, патч і ідентифікатори попередньої версії в цьому порядку (метадані збірки не враховуються при визначенні пріоритету).

    2. Пріоритет визначається першою різницею при порівнянні кожного з цих ідентифікаторів зліва направо наступним чином: основні, додаткові і патч-версії завжди порівнюються числово.

      Приклад: 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1.

    3. Коли основні, додаткові і патч-версії рівні, пріоритет попередньої версії нижчий за пріоритет звичайної версії:

      Приклад: 1.0.0-alpha < 1.0.0.

    4. Пріоритет для двох попередніх версій з однаковими основними, додатковими і патч-версіями МАЄ бути визначений порівнянням кожного ідентифікатора, розділеного крапкою, зліва направо, доки не буде знайдена різниця наступним чином:

      1. Ідентифікатори, що складаються тільки з цифр, порівнюються числово.

      2. Ідентифікатори з буквами або дефісами порівнюються лексикографічно за порядком ASCII-сортування.

      3. Числові ідентифікатори завжди мають нижчий пріоритет, ніж нечислові ідентифікатори.

      4. Більший набір полів попередньої версії має вищий пріоритет, ніж менший, якщо всі попередні ідентифікатори рівні.

      Приклад: 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0.

Приклади

Інкремент Основної Версії

1// Перед важливими змінами
2pub const VERSION: &str = "1.0.0";
3
4// Після важливих змін
5pub const VERSION: &str = "2.0.0";

Інкремент Додаткової Версії

1// Перед додаванням нового функціоналу
2pub const VERSION: &str = "1.2.0";
3
4// Після додавання нового функціоналу
5pub const VERSION: &str = "1.3.0";

Інкремент Патч Версії

1// Перед виправленням помилки
2pub const VERSION: &str = "1.2.3";
3
4// Після виправлення помилки
5pub const VERSION: &str = "1.2.4";

Версія Попередньої Версії

1// Перед стабільним випуском
2pub const VERSION: &str = "1.2.3-alpha.1";

Метадані Збірки

1// З метаданими збірки
2pub const VERSION: &str = "1.2.3+20130313144700";

Чому використовувати Семантичне Версіонування?

Це не нова або революційна ідея. Фактично, ви, можливо, вже робите щось схоже до цього. Проблема в тому, що “схоже” недостатньо. Без відповідності якій-небудь формальній специфікації номерів версій фактично є непридатними для управління залежностями. Давши ім’я і чітке визначення вищезазначеним ідеям, стає легко сповістити ваші наміри користувачам вашого програмного забезпечення. Як тільки ці наміри стають зрозумілими, можна кінцево створити гнучкі (але не занадто гнучкі) специфікації залежностей.

Простий приклад покаже, як Семантичне Версіонування може зробити пекло залежностей річчю минулого. Припустимо, є бібліотека під назвою “Firetruck.” Вона вимагає пакету з Семантичним Версіонуванням під назвою “Ladder.” На момент створення Firetruck, Ladder має версію 3.1.0. Оскільки Firetruck використовує певний функціонал, який був вперше представлений у версії 3.1.0, ви можете безпечно вказати залежність від Ladder як більше або рівне 3.1.0, але менше 4.0.0. Тепер, коли доступні версії Ladder 3.1.1 і 3.2.0, ви можете випустити їх до вашої системи управління пакетами і знати, що вони будуть сумісні з існуючим залежним програмним забезпеченням.

Як відповідальний розробник, вам, звісно, захочеться перевірити, що будь-які оновлення пакетів працюють так, як оголошено. Реальний світ - це брудне місце; ми не можемо нічого з цим зробити, крім як бути бджолиним. Те, що ви можете зробити, - це дозволити Семантичному Версіонуванню забезпечити вам розумний спосіб випуску та оновлення пакетів без необхідності створювати нові версії залежних пакетів, що економить вам час і клопіт.

Якщо все це звучить бажаним, все, що вам потрібно зробити для початку використання Семантичного Версіонування - це заявити, що ви це робите, і потім слідувати правилам. Посилайтеся на цей веб-сайт у своєму README, щоб інші знали правила і могли скористатися ними.

Часті питання (FAQ)

Як мені поводитися з версіями під час початкового етапу розробки 0.y.z?

Найпростіше - розпочніть свій початковий випуск розробки з 0.1.0 і збільшуйте мінорну версію для кожного наступного випуску.

Як я можу зрозуміти, коли випускати версію 1.0.0?

Якщо ваше програмне забезпечення використовується в експлуатації, ймовірно, воно вже має версію 1.0.0. Якщо у вас є стабільний API, в якому користувачі вже залежать, ви повинні бути на версії 1.0.0. Якщо ви сильно турбуєтеся про зворотню сумісність, ви вже маєте бути на версії 1.0.0.

Це не сприяє швидкому розвитку і швидкій ітерації?

Основна версія нуль - це все про швидкий розвиток. Якщо ви змінюєте API щодня, ви повинні залишатися на версії 0.y.z або на окремій гілці розробки, працюючи над наступною основною версією.

Якщо навіть найменші зворотно-несумісні зміни у вузькому API вимагають інкремента основної версії, чи не буду я дуже швидко на версії 42.0.0?

Це питання відповідального розвитку та передбачення. Несумісні зміни не повинні бути вводитися легко в програмне забезпечення, яке має багато залежного коду. Вартість, яку потрібно витратити для оновлення, може бути значною. Необхідність збільшувати основні версії для випуску несумісних змін означає, що ви ретельно обдумаєте вплив ваших змін і оціните відношення витрат/користі залучених.

Документувати весь вузький API - це занадто багато роботи!

Це ваша відповідальність як професійного розробника належним чином документувати програмне забезпечення, яке призначено для використання іншими. Управління складністю програмного проекту є великою частиною забезпечення ефективності проекту, і це важко робити, якщо ніхто не знає, як використовувати ваше програмне забезпечення або які методи безпечно викликати. У довгостроковій перспективі Семантичне Версіонування і настоювання на чітко визначений вузький API може допомогти утримувати все і всіх в робочому стані.

Що робити, якщо я випадково випустив несумісні зміни в публічному API як мінорну версію?

Як тільки ви розумієте, що порушено специфікацію Семантичного Версіонування, виправте проблему та випустіть нову мінорну версію, яка виправляє проблему і відновлює зворотню сумісність. Навіть у цьому випадку неприпустимо змінювати версії. Якщо це відповідно, задокументуйте проблемну версію та повідомте своїх користувачів про проблему, щоб вони були обізнані з проблемною версією.

Що робити, якщо я оновлюю власні залежності без зміни публічного API?

Це вважається сумісним, оскільки це не впливає на публічне API. Програмне забезпечення, яке явно залежить від тих самих залежностей, що й ваш пакет, повинно мати свої власні специфіка

ції залежностей, і автор помітить будь-які конфлікти. Визначення того, чи це патч-рівень чи мінімальний рівень модифікації, залежить від того, чи ви оновили ваші залежності для виправлення багу чи введення нового функціоналу. Зазвичай ми очікуємо додатковий код для останнього випадку, у якому, очевидно, це інкремент рівня мінімум.

Що робити, якщо я непроцільно змінив публічне API так, що це не відповідає зміні номера версії (тобто код неправильно вводить значущі зміни в патч-релізі)?

Використовуйте свій здоровий глузд. Якщо у вас є велика аудиторія, яку дуже сильно вразить зміна поведінки назад до того, що публічне API передбачало, тоді можливо, найкраще випустити основну версію, навіть якщо виправлення можна було б строгим патч-релізом. Пам’ятайте, що Семантичне Версіонування все про передачу значення тим, як змінюється номер версії. Якщо ці зміни важливі для ваших користувачів, використовуйте номер версії, щоб повідомити їх.

Як мені поводитися зі зстарюючою функціональністю?

Застарювання існуючої функціональності - це звичайна частина розробки програмного забезпечення і часто є необхідним для руху вперед. Коли ви застарюєте частину свого вузького API, вам слід зробити дві речі: (1) оновити свою документацію, щоб повідомити користувачів про зміну, (2) випустити новий мінорний випуск зі зстарюванням на місці. Перш ніж повністю вилучити функціональність у новому основному випуску, повинен бути принаймні один мінорний випуск, що містить застарювання, так щоб користувачі могли плавно перейти до нового API.

Чи існує обмеження розміру рядка версії у SemVer?

Ні, але використовуйте здоровий глузд. Строка версії завдовжки 255 символів, наприклад, ймовірно, зайвий. Також конкретні системи можуть накладати свої власні обмеження на розмір рядка.

Чи є “v1.2.3” семантичною версією?

Ні, “v1.2.3” не є семантичною версією. Однак префіксування семантичної версії з “v” - це загальний спосіб (на англійській мові) вказати, що це номер версії. Скорочення “version” до “v” часто використовується в контролі версій. Наприклад: git tag v1.2.3 -m "Release version 1.2.3", в цьому випадку “v1.2.3” - це тег ім’я, а семантична версія - “1.2.3”.

Про

Специфікацію Семантичного Версіонування спочатку написав Том Престон-Вернер Винахідник Gravatar та співзасновник GitHub.

Ліцензія

Creative Commons ― CC BY 3.0

Першоджерело: https://semver.org/

#текст   #документація   #довідка   #посібник  

Відповісти на цей запис електронною поштою ↪