Software developers spend all their creative energy on productive work. There is absolutely zero release overhead because all software is released automatically.
Encourage and help software developers set up their releases to be fully automated.
Our Gradle plugin shipkit-auto-version
deducts the version for the Gradle project to streamline continuous delivery.
You drop a version.properties
file to your repo with content like version=1.0.*
.
The plugin will resolve the *
part of the version based on the latest release tag and the number of commits.
This way you can set up the project for continuous delivery and release every merged pull request with nicely incremented version.
No more infamous "version bump" commits in every release!
shipkit-auto-version
plugin is tiny and has a single dependency on jSemver.
It is a safe dependency because it is tiny, has no dependencies, and it is final (no code changes since 2015 - it wraps semver protocol that had no changes since 2013).
Do you want to automate changelog generation?
Check out shipkit-changelog plugin that neatly integrate with shipkit-auto-version
plugin.
- https://github.com/shipkit/shipkit-demo (great example/reference project)
- https://github.com/shipkit/shipkit-changelog
- https://github.com/shipkit/shipkit-auto-version (this project)
- https://github.com/linkedin/ambry
- https://github.com/mockito/mockito-scala
- https://github.com/mockito/mockito-testng
- Apply
org.shipkit.shipkit-auto-version
to the root project. Use the highest version available in the Gradle Plugin Portal
plugins {
id "org.shipkit.shipkit-auto-version" version "x.y.z"
}
- Create
version.properties
file and drop it to your project root. The contents should contain the version spec, and optionally, the tag prefix.
version=1.0.*
You may optionally specify the tag prefix, our default is "v" for tags like "v1.2.3".
To use "no prefix" convention (e.g. tags like "1.2.3") please use an empty value: tagPrefix=
version=1.0.*
#tag prefix is optional, the default is "v", empty value means no prefix
tagPrefix=release-
-
For your CI, make sure that all tags are fetched (see the next section)
-
Prosper! When running Gradle the plugin will resolve
*
part of the version and set this value on the Gradle's project.
CI systems are often configured by default to perform Git fetch with minimum amount of commits/tags. However, our plugin needs tags in order to generate the release notes. When using GH actions, please configure your checkout action to fetch the entire history. Based on our tests in Mockito project, the checkout of the entire Mockito history (dating 2008) has negligible performance implication (adds ~2 secs to the checkout).
- uses: actions/checkout@v2 # docs: https://github.com/actions/checkout
with:
fetch-depth: '0' # will fetch the entire history
This plugin exposes an 'ext' property shipkit-auto-version.previous-version
that can be used to get access to the previous version.
Example:
println project.ext.'shipkit-auto-version.previous-version'
Shipkit Auto Version exposes also shipkit-auto-version.previous-tag
'ext' property that gives access to the previous
version's tag. It allows to get previous revision in convenient way (eg. for generating changelog with Shipkit Changelog
plugin as in example below).
Example:
tasks.named("generateChangelog") {
previousRevision = project.ext.'shipkit-auto-version.previous-tag'
//...
}
It is sometimes useful to manually specify the version when building / publishing (e.g. to publish a -SNAPSHOT
locally). This can be done by setting the gradle project version on the command line with the -Pversion
flag, e.g. ./gradlew publishToMavenLocal -Pversion=1.0.0-SNAPSHOT
.
When the plugin is applied to the project it will:
-
load the version spec from
version.properties
- if the gradle project already has a set version (e.g. from the command line), use that version
- if no file or wrong format fail
- if the spec does not contain the wildcard '*', we just use the version "as is" and return
- if the spec has wildcard '*' patch version, we resolve the wildcard value from tags and commits:
-
run
git tag
- look for typical "version" tags in Git output (e.g. "v1.0.0", "v2.5.100")
- identifies the latest (newest) version matching version spec
- compares the version with the version spec:
case | spec | latest tag | -Pversion | # of commits | result | description |
---|---|---|---|---|---|---|
a | 1.0.* | v1.0.5 | 0 | 1.0.5 | zero new commits | |
b | 1.0.* | v1.0.5 | 2 | 1.0.7 | two new commits | |
c | 1.0.* | v1.0.5 | 5 (2 merge + 1) | 1.0.8 | two merge commits and new one on top | |
d | 1.1.* | v1.0.5 | 5 | 1.1.0 | first x.y.0 version | |
e | 2.0.* | v1.0.5 | 5 | 2.0.0 | first z.0.0 version | |
f | 1.*.5 | error | unsupported format | |||
g | 1.0.* | v1.0.5 | 1.0.10-SNAPSHOT | [any] | 1.0.10-SNAPSHOT | version overridden from CLI argument |
-
in case a),b) we are resolving the wildcard based on # of commits on top of the tag
- run
git log
to identify # of commits - add commit count to the patch version value from the latest tag
- viola! we got the version to use!
- run
-
in case c) we have following situation (
git log
output):- 64e7eb517 Commit without a PR
- 2994de4df Merge pull request #123 from mockito/gradle-wrapper-validation
- 67bd4e96c Adds Gradle Wrapper Validation
- 64e7eb517 Merge pull request #99 from mockito/ongoing-stubbing
- dd8b07887 Add OngoingStubbing
- 084e8af18 (tag: v1.0.5) Merge pull request #88 from mockito/mockito-88
On top of v1.0.5 tag there are 5 commits, i.e. 2 merge commits (
64e7eb517
and2994de4df
) and 1 new commit (64e7eb517
) without Pull Request on top. The patch version will be8
i.e. 5 plus a sum of those two numbers. -
in case d),e) use '0' as patch version
-
in case g) the user manually specified the version on the command line
There are other plugins out there that are similar:
- Below plugins are great, but they (mostly) require to push a tag to make a release. Our plugin can release every change.
- https://github.com/ajoberstar/reckon
- https://github.com/allegro/axion-release-plugin
- https://github.com/cinnober/semver-git
- https://github.com/nemerosa/versioning
- Below plugin can release every change, but the resulting version is not as nice (e.g.
1.0.0+3bb4161
). The plugin has many features and thus is much more complex than our plugin.
Use the plugin that works best for you and push every change to production!
Discussion about this use case: mockito/shipkit#395
This project loves contributions! For more info how to work with this project check out the contributing section in the sibling plugin shipkit-changelog.