gradle-release-plugin automates release procedure for gradle based projects.
It can automatically create new release branches and tag releases.
New release is created by updating version in project root gradle.properties
file.
In this file plugin updates version
property in format version=x.y.z
.
Plugin uses auto incremented version number.
Then commits this update in distinct revision tagged by this version number.
- Gradle Release Plugin
- Short hints
- Plugin tasks
- Add plugin to gradle project build script
- Plugin usage in project with multiple release branches
- Multiple release branches git flow
- Masterless git flow
- Single production branch git flow
- Well known issues
Publish minor change in release branch with createRelease
command for project with multiple release branches
Create and merge minor fix or feature into release branch release/1.3
with git.
└─master
└─release
└─1.3 <-- (current branch)
└─1.4
tag 1.3.0
tag 1.3.1
tag 1.4.0
Now you are ready to create new release with gradle-release-plugin.
Since last tag for 1.3 was 1.3.1, then new tag will be 1.3.2.
git checkout release/1.3
gradle createRelease
└─release
└─1.3 <-- (current branch)
└─1.4
tag 1.3.0
tag 1.3.1
tag 1.3.2 (new tag)
tag 1.4.0
Publish minor change in release branch with createRelease
command for project with single release branch
Create and merge minor fix or feature into release branch production
with git.
└─production <-- (current branch)
tag 1.3.0
tag 1.3.1
tag 1.4.0
Now you are ready to create new release with gradle-release-plugin.
Since last tag is 1.4.0, then new tag will be 1.4.1.
git checkout production
gradle createRelease
└ production <-- (current branch)
Create new major version branch with gradle-release-plugin.
└ release
└ 1.3 <-- (current branch)
git checkout release/1.3
gradle createReleaseBranch
git push
└ release
└ 1.3
└ 1.4 <-- (current branch)
Now you have new branch release/1.4
.
You can create feature branches based on release/1.4
and start developing new features.
All plugin tasks work with git repository.
In order to ensure actual state of local repository they try to fetch data from remote repository.
If remote repository requires authentication, plugin tasks will try to resolve credentials.
User can provide credentials via:
- gradle properties:
-Pru.fix.gradle.release.login=<git.login>
-Pru.fix.gradle.release.password=<git.password>
- system properties:
-Dru.fix.gradle.release.login=<git.login>
-Dru.fix.gradle.release.password=<git.password>
- ssh key in user home directory
- If plugin could not authenticate via properties or ssh key it will prompt user for login and password in interactive mode via console.
Creates new branch in local git repository.
By default current branch will be used as a base branch and target branch name will be in format /release/x.y
.
During execution, command asks user to specify major and minor version in x.y
format.
Plugin will look for existing release branches and suggest user a new version by default.
# ----- before -----
└─master <-- current branch
└─release
└─1.0
└─1.1
└─feature
└─my-new-future
gradle createReleaseBranch
> 1.2
# ----- after -----
└─master
└─release
└─1.0
└─1.1
└─1.2 <-- current branch
└─feature
└─my-new-future
ReleaseExtension configuration:
- not required
Optional properties:
- ru.fix.gradle.release.login: String - login for remote git repository
- ru.fix.gradle.release.password: String - password for remote git repository
- ru.fix.gradle.release.createDefaultReleaseBranch: Boolean - if true, then createReleaseBranch will work in non interactive mode and will use major version suggested by default without asking user for confirmation. Used in CI. By default is false.
Searches for existing tags in repository.
Select tags with names matching version template x.y.z
.
Finds latest version among them.
Calculates new version by incrementing latest tag version by 1.
Stores new version in gradle.properties
file in format version=x.y.z+1
.
Commit gradle.properties
file with new tag name x.y.z+1
into repository.
User should run createRelease task on one of release branches release/x.y
.
ReleaseExtension configuration:
- releaseBranchPrefix - prefix for release branch name, by default -
/release/
- commitMessageTemplate - by default
Release v{VERSION}
- tagNameTemplate - by default
{VERSION}
- templateVersionMarker - by default
{VERSION}
- nextReleaseVersionDeterminationSchema - by default MAJOR_MINOR_FROM_BRANCH_NAME_PATCH_FROM_TAG.
Other possible option MAJOR_MINOR_PATCH_FROM_TAG
Optional properties:
- ru.fix.gradle.release.login: String - login for remote git repository
- ru.fix.gradle.release.password: String - password for remote git repository
- ru.fix.gradle.release.checkoutTag: Boolean - whether to left repository with checkouted tag or with checkouted release branch. Useful for pipelines. By default createRelease will left repository pointing to release branch.
- ru.fix.gradle.release.releaseMajorMinorVersion: String - which Major and Minor version to select for release. E.g.
1.2
specify that release should be created based onrelease/1.2
branch. In case of nextReleaseVersionDeterminationSchema MAJOR_MINOR_PATCH_FROM_TAG then current branch will be used, plugin will use Major and Minor version part from given property and Patch version part will calculate based on existing tags. By default current branch will be used in order to create release.
# ----- before -----
└─master
└─release
└─1.0
└─1.1 <-- current branch
└─2.0
tag 1.0.0
tag 1.1.0
tag 1.1.1
tag 2.0.0
gradle createRelease
# ----- after -----
└─master
└─release
└─1.0
└─1.1 <-- current branch
└─2.0
tag 1.0.0
tag 1.1.0
tag 1.1.1
tag 1.1.2 (new tag with updated version in gradle.properties file)
tag 2.0.0
Plugin by default tries to push changes by itself if ssh key or other credentials provided.
You have to push new tags manually only if plugin fails to resolve credentials.
git push --tags
import org.gradle.kotlin.dsl.*
import ru.fix.gradle.release.plugin.release.ReleaseExtension
buildscript{
dependencies {
classpath("ru.fix:gradle-release-plugin:$version")
}
}
apply {
plugin("ru.fix.gradle.release")
}
//not required for default configuration
configure<ReleaseExtension> {
releaseBranchPrefix = "release/"
}
buildscript {
dependencies {
classpath "ru.fix:gradle-release-plugin:$version"
}
}
plugins {
id "java"
}
apply plugin : "ru.fix.gradle.release"
//not required for default configuration
'ru.fix.gradle.release' {
releaseBranchPrefix = "release/"
}
Manually create branch /master
with latest version of project.
└─master <-
Create new release branch with gradle plugin gradle createReleaseBranch
and specify version 1.0
.
gradle createReleaseBranch
> 1.0
└─master
└─releases
└─release
└─1.0 <--
This will create new branch /master
-> /release/1.0
Checkout branch /release/1.1
Apply changes in your code.
Create new tag with updated gradle.properties by running gradle createRelease
task.
gradle createRelease
└─master
└─release
└─1.0 <--
tag 1.0.0 (new tag)
This will create new tag 1.0.0
This tag will contain single change: updated gradle.properties file with content:
version=1.0.0
Now CI can checkout tag 1.0.0
, build and publish your project with gradle clean build publish
command.
You can merge new changes to /release/1.0
release branch and create new tagged release that contains this changes:
gradle createRelease
will create new tag 1.0.1
.
gradle createRelease
└─master
└─release
└─1.0 <--
tag 1.0.0
tag 1.0.1 (new tag)
If you decided to publish new major version based on /master
branch you should:
Checkout /master
branch with git
git checkout master
Then create new release branch with gradle createReleaseBranch
and specify version 1.1
.
This will create new branch /master
-> /release/1.1
# ----- before -----
└─master <--
└─release
└─1.0
gradle createReleaseBreanch
# ----- after -----
└─master
└─release
└─1.0
└─1.1 <--
tag 1.0.0
tag 1.0.1
- Latest stable functionality is located in
/master
branch - New features are created in
/feature/feature-name
branches - Maintainable releases is located in
/release/x.y
branches - Project version is specified in root file
gradle.properties
, fieldversion=x.y.z
- Version in
gradle.properties
file in all branches is committed asx.y-SNAPSHOT
. This will prevent conflicts during merge requests between feature branches/feature/*
, release branches/release/x.y
and/master
branch - During release new tag is being created that holds single commit that modifies
gradle.properties
file and specify particularversion=x.y.z
property inside the file. Tag name contain release number.
Suppose that we already have last version of project in /master
branch, and release /release/1.2
- New branch is created based on
/master
. Branch name is/release/1.3
. Plugin taskcreateReleaseBranch
could be used for that purpose. - New branch
/release/1.3
is stabilized, changes are added to this branch through Merge Requests. - When branch
/release/1.3
is ready, user launches CI build server release task and specify given branch/release/1.3
- CI build server task checkout
/release/1.3
branch, then executes gradle commandgradle createRelease
- Or user can launch this command manually on local repository.
- gradle plugin searches in local git repository for all tags that matches
1.3.*
template, if there is no such tag found then default1.3.0
will be used. If tags found then max tag will be incremented, e.g. if plugin find1.3.7
then new tag name will be1.3.8
- In file
gradle.properties
version
property is replaced from1.3-SNAPSHOT
to1.3.8
gradle.properties
is being committed with new tag name1.3.8
You can maintain repository without master branch.
And create new release branches from previous release branches.
For example, with createReleaseBranch
you can create release branch release/1.1
based on currently selected branch release/1.0
.
# ----- before -----
└─release
└─1.0 <--
gradle createReleaseBreanch
# ----- after -----
└─release
└─1.0
└─1.1 <--
Masterless flow works in the same way as multiple release branches git flow. The only exception is that you do not need to merge all changes to master branch all the time. And you do not need to start new release branches from master.
# ----- before -----
└─feature
└─my-feature
└─production
tag 1.0.0
tag 1.0.1
- Latest stable functionality is located in
/master
branch - New features are created in
/feature/feature-name
branches - There is one maintainable release located at
/production
blanche - Project version is specified in root file
gradle.properties
, fieldversion=x.y.z
- Version in
gradle.properties
file in all branches is committed asx.y-SNAPSHOT
. - During release new tag is being created that holds single commit that modifies
gradle.properties
file and specify particularversion=x.y.z
property inside the file. Tag name contain release number.
Configure gradle-release-plugin to use single production branch schema.
configure<ReleaseExtension> {
nextReleaseVersionDeterminationSchema = MAJOR_MINOR_PATCH_FROM_TAG
}
Suppose that we already have last version of project in `/production
- CI build server task checkout
/production
branch, then executes gradle commandgradle createRelease
- Or user can launch this command manually on local repository.
- gradle plugin searches in local git repository for all tags that matches
*.*.*
template, if there is no such tag found then default1.0.0
will be used. If tags found then max tag will be incremented, e.g. if plugin find last tag1.3.7
then new tag name will be1.3.8
- In file
gradle.properties
version
property is replaced from1.3-SNAPSHOT
to1.3.8
gradle.properties
is being committed with new tag name1.3.8
createRelease
task can only make minor increment. User have to manually create tag2.0.0
in order to make major version update. Or use can specify major and minor version part explicitly through property-Pru.fix.gradle.release.releaseMajorMinorVersion=2.0
gradle createRelease -Pru.fix.gradle.release.releaseMajorMinorVersion=2.0
JSchException: Auth fail
Git commands works from console, but gradle-release-plugin tasks fails with JSchException: Auth fail.
- gradle-release-plugin uses JGit to access git repository.
It tries to work through ssh-agent.
If you are using ssh authentication and received Auth fail exception, then this may be due to the fact that your ssh key is not added properly to the ssh-agent. To add a key to a ssh agent in Linux, use the ssh-add command. - Recent versions of OpenSSH (7.8 and newer) generate keys in new OpenSSH format by default. JSch does not support this key format.
You can use ssh-keygen to convert the key to the classic OpenSSH format:ssh-keygen -p -f file -m pem -P passphrase -N passphrase
.
https://stackoverflow.com/a/53783283
Or you can try to generate new key withssh-keygen -t rsa -m PEM
and update this key on your git remote repositoy.
#6