Всё уже придумано, просто настрой под себя и пользуйся.
Всем привет, я Дмитрий Валеев — DevOps инженер в команде разработки фреймворка для тестирования устройств на заводах Аквариус. И это моя первая маленькая статья на Хабр:)
В любом проекте настаёт день «икс», когда вы понимаете, что необходимо внедрять какое‑либо версионирование. Вот и в нашем случае настал такой момент. Вариант с хэш‑коммитами казался просто хаосом и нужно было привести вид компонент в порядок
Введение
Какпоказывает практика, часто версионирование просто игнорируется. Но любой, кто так или иначе пытался организовать свою разработку (в том числе пет‑проекты), приходил к мысли о его необходимости.
В этой статье описан очень простой подход к автоматизации присвоения версий и написания патч‑ноутов для проектов. Семантическое версионирование, а также соглашение о коммитах с открытой спецификацией и документаций поможет не придумывать новые стандарты.
Сразу обозначу, в качестве VCS (Version Control System) выбран «GitLab». Поэтому почти всё описанное взаимодействие в статье будет происходить с данным инструментом.
Структура версий
-
1 – Major версия
Мажорная версия изменяется только в случае обратно несовместимых изменений
-
2 – Minor версия
Минорная версия изменяется только в случае добавления нового функционала БЕЗ обратно несовместимых изменений
-
3 – Патч версия
Патч версия изменяется в случае выпуска каких-либо исправлений, незначительных улучшений
-
dev – Название prerelease/разрабатываемых состояний проекта
-
4 – Номер билда/коммита для пререлиз состояний версии
«-dev.4» используется в любых видах пререлиз веток (Например: alpha; beta; dev; rc…).
Спецификация по написанию коммитов
Спецификации по написанию коммитов — это предмет договоренности внутри вашей команды. Она может быть изменена любым удобным способом. Однако, существует так называемая договоренность о коммитах (conventional commits), рекомендую ознакомиться с ней, хотя бы как с базовым примером того, как это может выглядеть.
Перейдём к краткому описанию правил коммитов:
-
Эти коммиты изменят патч версию:
fix: something
fix(PROJECT-999): fix something
-
Эти коммиты изменят минорную версию:
feat: something
feat(ui): Add something
-
Этот коммит изменит мажорную версию:
feat!: something
BREAKING CHANGE: something
«BREAKING CHANGE» находится именно в сноске коммит месседжа. Восклицательный знак в данном случае предупреждает о наличии «BREAKING CHANGE» в сноске коммита. Так выглядит в гитлабе:
Можно использовать и другие типы коммитов. Все, кроме вышеописанных, не влияют на изменение версии релиза (здесь описаны лишь некоторые):
-
ci: Изменения в наших конфигурационных файлах и скриптах CI.
-
docs: Изменения документации.
-
refactor: Рефакторинг кода, не затрагивающий баг‑фиксы и не добавляющий функциональность.
-
style: Изменения, которые не влияют на смысл кода (пробелы, форматирование, отсутствие точек с запятой и т. д.).
-
test: Добавление недостающих или исправление существующих тестов.
Рекомендую ознакомиться с одним из таких соглашений по ссылкам: на английском и на русском.
Инструмент “Semantic-release”
Напишем своё или возьмём уже готовое?
Рекомендую обратить внимание на инструмент semantic-release. Это решение на базе проекта с открытым кодом, написанное на node.js, позволяющее без особых проблем писать CHANGELOG, создавать теги или релизы, вносить любые автоматизированные изменения в репозиторий от имени бота с выпуском новой версии. И всё это без участия человека.
Решение также помогает поддерживать legacy. Например:
-
Заморозили старую версию 1.X.X, но вносим в неё необходимые фиксы и патчи в legacy ветке.
-
Ведем версию 2.X.X в master ветке.
-
Для обеих версий доступны dev ветки/каналы для разработки.
Ещё один плюс данного инструмента — наличие в арсенале разнообразных плагинов. Например: changelog, docker, exec и т. д., которые открывают возможность создавать GitLab/GitHub Release вместе с тегом, автоматизировать ваши собственные изменения при выпуске версии и многое другое.
Как работает semantic-release
При каждом коммите инструмент анализирует его содержимое и существующие версии. На основе этого анализа принимается решение — выпускать новую версию или нет. (См. спецификацию по написанию коммитов)
Каждая новая версия автоматически создаёт тег.
А так выглядят коммиты самого бота с выпуском тега:
Как изменяются версии пре-релиз веток (на примере “dev”)
При внесении изменений в dev‑ветку версия изменяется в зависимости от целевого коммита.
То есть, если мы ведем dev ветку с версии 1.0.0, у нас есть 2 коммита «feat» и 3 «fix» в любом порядке, то текущая версия в dev будет 1.1.0-dev.5. Неважно, сколько новых фич или фиксов было добавлено в dev, изменение версии отражает, что было добавлено хотя бы одно улучшение. Оно же показывает, какого рода были самые критичные изменения. Для наглядности картинка ниже:
Как добавить semantic-release к себе в проект
Не буду переписывать инструкцию, а просто оставлю ссылку на удобную документацию от разработчиков и покажу один из вариантов настройки:
1. Соберем контейнер для раннера и положим туда semantic-release с нужными плагинами
Как пример базовой сборки:
FROM node:18.14.2-alpine3.17 COPY certs/. /etc/ssl/certs/. RUN apk --no-cache add curl; \ apk --no-cache add git; \ apk --no-cache add ca-certificates && \ update-ca-certificates -v RUN npm config set prefix /usr/local; \ npm install -g @semantic-release/gitlab@v10.0.1; \ npm install -g @semantic-release/exec; \ npm install -g @semantic-release/git; \ npm install -g @semantic-release/changelog; \ npm install -g semantic-release ENTRYPOINT [""] CMD [""]
2. Создадим бота в GitLab и токен для него с правами api, write_repository. Это нужно для того, чтобы бот мог коммитить в репозиторий автоматические изменения.
3. Передадим токен через ci/cd variables. Можете добавить сразу в группу репозиториев.
4. Напишем базовую джобу
a. Если не используете ci templates:
stages: - semantic-release release-job: image: *your_registry*/semantic_release:latest stage: semantic-release only: refs: # Release branch - master # Pre-release branch - dev script: - npx semantic-release tags: - *your_tag*
b. Если пользуетесь ci templates:
.release-job: stage: semantic-release image: *your_registry*/semantic_release:latest only: refs: # Release branch - master # Pre-release branch - dev script: - npx semantic-release tags: - *your_tag* artifacts: reports: dotenv: release_version.env
.gitlab-ci.yml в проекте:
include: project: path/to/your/templates file: path/to/your/template.yml stages: - semantic-release semantic-release:pypi: extends: .release-job stage: semantic-release
5. Добавим в репозиторий .releaserc.json
{ "plugins": [ "@semantic-release/commit-analyzer", "@semantic-release/release-notes-generator", ["@semantic-release/exec",{ "prepareCmd": "if [ -f .release.override ]; then echo \"Detected .release.override\" && VERSION=${nextRelease.version} && source .release.override; else sed -i \"s/__version__ *= *.*/__version__ = \\\"${nextRelease.version}\\\"/\" ./setup.py; fi", "publishCmd": "echo NEW_VERSION=${nextRelease.version} >> release_version.env" }], ["@semantic-release/changelog",{ "changelogFile": "CHANGELOG.md" }], ["@semantic-release/git", { "assets": ["CHANGELOG.md", "setup.py"], "message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" } ] ], "branches": [ "master", {"name": "dev", "prerelease": true} ], "tagFormat": "v${version}" }
Здесь, например, мы можем внести любое автоматическое изменение в prepareCmd, а в assets указать файлы, которые будут участвовать в коммите бота. На выходе мы будем иметь коммит и тег от бота, с уже измененными файлами.
Автоматизация CHANGELOG(-а)
Вернемся к данному коммиту:
fix(PROJECT-999): fix something
В скобках, согласно соглашению, указывается изменяемая компонента кода. И это очень удобный подход, но мы решили указывать в скобках решаемую задачу из таск-менеджера (их может быть и несколько через пробел). Таким образом, мы получили более богатый авто-генерируемый changelog и повысили общую читаемость. Вот пример:
Опять же, changelog пишется автоматически, если мы оставляем в assets «CHANGELOG.md», а также устанавливаем и добавляем необходимый плагин (см. настройку semantic‑release пункт 5).
Самый простой сценарий использования
-
Коммит разработчика в формате semver.
-
Автоматическое вычисление версии с помощью semantic-release.
-
Автоматическое изменение файла setup.py и CHANGELOG.md.
-
Сборка и последующая доставка пакета.
-
Коммит/выпуск тега (релиза) с уже измененной версией.
В заключении
Семантическое версионирование вполне вяжется с подходом к разработке gitflow. Мы можем вести все пререлиз ветки с версиями.
Большинство наших репозиториев и компонент версионируется именно в таком формате, на них также завязаны job(-ы) по сборкам и публикации/деплою. Всё это избавляет нас от большого объема ручной работы и прививает в команде единый стандарт написания коммитов.
В действительности такая автоматизация настраивается очень быстро и не требует трудоемких операций. Попробуйте 🙂
ссылка на оригинал статьи https://habr.com/ru/articles/844394/
Добавить комментарий