Плагин создан для релиза библиотек и артефактов (не обязательно jar) не привязан к конкретному языку программирована/платформе, может быть использован как инструмент для релиза java библиотек, так и спецификаций в формате OpenApi.
Перед использованием этого плагина нужно принять несколько договоренностей:
- проект использует git в качестве системы контроля версий
- версия проекта находится в файле
gradle.properties
в корне репозитория, в форматеversion=x.y.z-SNAPSHOT
- решение о релизе принимается вызывающим (ci-cd/разработчиком), т.е. плагин не проверят в какой ветке вы находитесь, был ли уже релиз с такой версий и т.д.
Существует несколько основных задачи
preRelease
- задача убирает изversion
которая находится вgradle.properties
постфикс-SNAPSHOT
, если в проекте естьCHANGELOG.md
следующая версия берется оттуда, самCHANGELOG.md
обновляется исходя из заполненных маркеров, делается коммит и добавляется tag в git с новой версийrelease
- задача перед которой поочередно выполняются задачи для релиза определенные пользователем через расширениеreleaseSettings
затем увеличивается patch версия вgradle.properties
и к ней добавляется постфикс-SNAPSHOT
если в проекте естьCHANGELOG.md
добавляется маркеры для описания следующих версий, делается commit и push с новой версиейcheckChangelog
- задача проверяет правильно ли заполнено описание следующего релиза вCHANGELOG.md
Задачи preRelease
и release
должны выполнятся в 2 разных gradle процессах, это важно т.к. только на момент инициализации gradle берет версию из gradle.properties
, далее другие плагина на нее ориентируются в фазе afterEvaluate, т.е. по ходу выполнения gradle задач изменить версию проекта поменять нельзя.
Вызывающий сам определяет нужен ли релиз исходя из последнего коммита, это сделано потому, что в gradle нет хороших механизмов прервать выполнения текущих задач и оставить gradle сборку успешной. В общем виде пример конфигурации для jenkins pipeline для мастер ветки:
...
stage('release') {
when {
expression {
return !sh(script: "git log -1 --pretty=%B", returnStdout: true).trim().startsWith("[Gradle Release Plugin]")
}
}
steps {
sh './gradlew preRelease'
sh './gradlew release'
}
}
...
releaseSettings {
/**
* Перечень задач которые будут выполнены в момент релиза
*/
releaseTasks = ['build', 'buildDeb', 'uploadDebToNexus']
/**
* Перечень задач которые нужно выполнить до релиза,
* версию и changelog будущего артефакта можно получить через `ReleaseInfoStorage(project.buildDir)`
*/
preReleaseTasks = ['updateArtifactBeforeRelease']
/**
* Путь до приватного ssh ключа для дотсупа в git, если задан будет использоваться
*/
pathToGitPrivateSshKey = null
/**
* Passphrase для приватного ssh ключа. По умолчанию не задана, имеет смысл совместно с pathToGitPrivateSshKey
*/
sshKeyPassphrase = null
/**
* Имя юзера, от которого будет производиться коммит в git. Обязательная настройка.
*/
gitUsername = 'user'
/**
* Email юзера, от которого будет производиться коммит в git. Обязательная настройка.
*/
gitEmail = 'user@mail.ru'
/**
* Требовать наличия файла CHANGELOG.md в корне проекта
*/
changelogRequired = true
}
Задачи описанные в preReleaseTasks
будут выполнени после обновления версии в gradle.properties
и ротации CHANGELOG.md
но до коммита всех изменений в git c сообщением [Gradle Release Plugin] - pre tag commit
версию и changelog текущего артефакта можно получить через ArtifactVersionProvider(project)
Некоторые артифакты требуют правок в момент поднятии версии, например спецификация в формате OpenAPI v3. Версии такой спецификации хранится в секции info:version внутри yml файла.
Для того что бы поддержать возможность правки артифакдо в момент поднятия версии но до первого комита добавлена секция preReleaseTasks
Поддерживается 2 варианта работы:
- Если в проекте нет
CHANGELOG.md
, то значение релизной версии берется изversion
вgradle.properties
путем отбрасывания постфикса-SNAPSHOT
, после релиза поднимается patch версия и к ней добавляется-SNAPSHOT
новое значение записывается вgradle.properties
- Если в проекте есть
CHANGELOG.md
, то значение релизной версии берется из маркера### NEXT_VERSION_TYPE=???
путем вычисления на основе предыдущей версии изCHANGELOG.md
(если это первый релиз и вCHANGELOG.md
нет информации о предыдущей версии, релизная версия будет0.0.1
или0.1.0
или1.0.0
соответственно) , после релиза поднимается patch версия и к ней добавляется-SNAPSHOT
, новое значение записывается вgradle.properties
-
От мастера отведена
feature
ветка, разработчик собирается внести измененияgradle.properties version=1.0.1-SNAPSHOT
CHANGELOG.md ### NEXT_VERSION_TYPE=MAJOR|MINOR|PATCH ### NEXT_VERSION_DESCRIPTION_BEGIN ### NEXT_VERSION_DESCRIPTION_END ## [1.0.0]() (30-05-1992) some description
-
Разработчик внес изменения в проект, сделал пулл реквест
gradle.properties version=1.0.1-SNAPSHOT
CHANGELOG.md ### NEXT_VERSION_TYPE=MINOR ### NEXT_VERSION_DESCRIPTION_BEGIN * Добавлен функционал Х ### NEXT_VERSION_DESCRIPTION_END ## [1.0.0]() (30-05-1992) some description
в
NEXT_VERSION_TYPE
указалMINOR
т.к. был добавлен новый функционал, описал сделанные изменения вNEXT_VERSION_DESCRIPTION
Внимание! Если в
NEXT_VERSION_TYPE
указаноMAJOR
, и версия не 1.0.0, то вNEXT_VERSION_DESCRIPTION
изменения необходимо описывать в формате breaking changes. Желательно также указывать, что требуется сделать, чтобы перейти на мажорную версию. Пример:CHANGELOG.md ### NEXT_VERSION_TYPE=MAJOR ### NEXT_VERSION_DESCRIPTION_BEGIN * **breaking changes** Добавлен функционал Y. Метод Foo#doSomething стал принимать новый параметр типа Boolean. ### NEXT_VERSION_DESCRIPTION_END ## [1.0.0]() (30-05-1992) some description
-
Пулл реквест замержен в master начинается сборка релиза, после
preRelese
состояние такоеgradle.properties version=1.1.0
CHANGELOG.md ## [1.1.0]() (30-12-2018) Добавлен функционал Х ## [1.0.0]() (30-05-1992) some description
дата
30-12-2018
вычисляется на основе текущего дня, все задачи, описанные вreleaseTasks
будут выполнены сейчас -
После релиза изменения будут запушены в гит
gradle.properties version=1.1.1-SNAPSHOT
CHANGELOG.md ### NEXT_VERSION_TYPE=MAJOR|MINOR|PATCH ### NEXT_VERSION_DESCRIPTION_BEGIN ### NEXT_VERSION_DESCRIPTION_END ## [1.1.0]() (30-12-2018) Добавлен функционал Х ## [1.0.0]() (30-05-1992) some description
в гит добавлен тег и 2 коммита
* 38bcac4 - (HEAD) [Gradle Release Plugin] - new version commit: '1.1.1-SNAPSHOT'. * 1de1fa5 - (tag: refs/tags/1.1.0) [Gradle Release Plugin] - pre tag commit: '1.1.0'.
Если в проекте есть файл CHANGELOG.md и настройка расширения плагина addPullRequestLinkToChangelog=true
(по-умолчанию true
), то при релизе рядом с вычесленной версией артефакта в файле CHANGELOG.md
будет добавлена ссылка на pull request, инициировавший релиз. Ссылка выглядит следующим образом:
CHANGELOG.md
### NEXT_VERSION_TYPE=MAJOR|MINOR|PATCH
### NEXT_VERSION_DESCRIPTION_BEGIN
### NEXT_VERSION_DESCRIPTION_END
## [1.0.0](https://github.com/yoomoney/artifact-release-plugin/pull/3) (30-05-1992)
some description
Ссылка добавляется на последний вмердженный pull request. Если в процессе получения ссылки возникла какая-либо ошибка, то это не повлияет на релизный процесс, просто ссылка будет отсуствовать.
Пулл-реквесты могут искаться в GitHub или в Bitbucket, что задается настройкой pullRequestInfoProvider Пример конфигурации для github:
releaseSettings {
addPullRequestLinkToChangelog = true
pullRequestInfoProvider = "GitHub"
githubAccessToken = 'token' //обязательный параметр для pullRequestInfoProvider = "GitHub"
}
Пример конфигурации для bitbucket:
releaseSettings {
addPullRequestLinkToChangelog = true
pullRequestInfoProvider = "Bitbucket"
bitbucketApiToken = 'apiToken' //обязательный параметр для pullRequestInfoProvider = "Bitbucket"
}