axion-release-plugin
axion-release-plugin copied to clipboard
[Question] Increment build number using Conventional Commits messages
Hi,
Thanks for the hard work on this plugin.
I'm currently trying to implement this plugin on our mono repo multi project. However one of our requirements is to increment the builds using commit messages, following the conventional commits (https://www.conventionalcommits.org/en/v1.0.0/) is this something that your plugin can support in any way?
Thanks
The easiest "hack" I could think of would be to write a Gradle task that analyzes the HEAD commit of the checked out workspace. If it would find the information that it should create a release, this could trigger the createRelease or release Gradle task as a finalizer or dependOn dependency to your custom task. This would be a hack because this check would have to run during configuration time, for each Gradle invocation.
If done on task execution time, one would have to do some trickery, like trying to disable the finalized task when the result is negative. Something like (untested)
task maybeRelease {
def releaseTask = tasks.findByName("release")
finalizedBy releaseTask
doLast {
// check the SCM
releaseTask.enabled = true / false
}
}
Hi @realdadfish, thanks for your answer. That gave me an idea.
after reading the documentation I created the following:
plugin configuration:
scmVersion { tag { prefix = 'b2x' versionSeparator = '@' } monorepos { projectDirs = project.subprojects.collect({ p -> p.name }) } branchVersionIncrementer = [ "master": { c -> shouldIncrement(c) } ] }
`Object shouldIncrement(Object c) {
println("Current Version: $c.currentVersion")
def lastCommitMessage = getLastCommit().trim();
println("Last commit was -> $lastCommitMessage")
def conventionalCommitsPattern = "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test)(\\([a-z ]+\\))?: [\\w ]+"
if (lastCommitMessage =~ conventionalCommitsPattern) {
println("The last commit was a valid commit message.\nInferring the new version.")
def major = "BREAKING CHANGE"
def minor = "^(feat)(\\([a-z ]+\\))?: [\\w ]+"
def patch = "^(fix)(\\([a-z ]+\\))?: [\\w ]+"
if (lastCommitMessage =~ major) {
println("Inferred a new MAJOR version.")
return c.currentVersion.incrementMajorVersion()
} else if (lastCommitMessage =~ minor) {
println("Inferred a new MINOR version.")
return c.currentVersion.incrementMinorVersion()
} else if (lastCommitMessage =~ patch) {
println("Inferred a new PATCH version.")
return c.currentVersion.incrementPatchVersion()
}
}
println("No new version needed.")
return c.currentVersion
}
private String getLastCommit() { return runCommands("git", "log", "master", "--format=%B", "-n", "1") }
private String runCommands(String... commands) { def process = new ProcessBuilder(commands).redirectErrorStream(true).start() process.waitFor() def result = '' process.inputStream.eachLine { result += it + '\n' } def errorResult = process.exitValue() == 0 if (!errorResult) { throw new IllegalStateException(result) } return result }`
This is creating the correct version on the Gradle output. However I'm seeing 2 different issues now.
- I can't remove the -SNAPSHOT even when I'm on master branch. 👎
- I'm getting this strange error when I do ./gradlew release
pl.allegro.tech.build.axion.release.ReleaseFailedException (no error message)
Don't know about the second issue, but the first issue can be solved by using the tools at hand:
val versionConfig = project.extensions.getByType(VersionConfig::class.java)
val context = GradleAwareContext.create(project, versionConfig)
val versionService = context.versionService()
val currentVersion = versionService.getVersion(context.rules()).toString()
currentVersion will then be the version without -SNAPSHOT applied to it.
Where should this code go?
I've wrote a custom Gradle plugin that internally applies the axion plugin and has custom tasks. You can put this into a doLast {} block of your current task (convert to Groovy, of course).