gradle-release icon indicating copy to clipboard operation
gradle-release copied to clipboard

Adapt version in beforeReleaseBuild

Open christiangroth opened this issue 3 years ago • 1 comments

Hey guys,

first of all thanks for the great plugin, so far I solved a lot of scenarios using it! :)

Right now I'm trying to derive the new project version depending on our release notes. What I want to achieve is the following:

  • If a breaking release note snippet exists, inc project version by major bump before release
  • If a feature release note snippet exists, inc project version by minor bump before release

So what I did was quite simple:

  • added a new task updateProjectVersion implementing the logic described above. Setting the new project version means two things though:
    • update new version in gradle.properties
    • set project.version = newVersion
  • set beforeReleaseBuild.dependsOn(updateProjectVersion)
  • of course you need to set failOnCommitNeeded = false due to changes to gradle.properties by updateProjectVersion

What I see is that the tast is executed correctly and gradle.properties file is also correct and committed correctly. But lets look at an example with current version 0.1.1-SNAPSHOT and creating a feature release.

  • pre tag commit is [Gradle Release Plugin] - pre tag commit: '0.1.1' and contains changes in gradle.properties to version=0.2.0
  • new version commit is [Gradle Release Plugin] - new version commit: '0.1.2-SNAPSHOT' and contains changes in gradle.properties to version=0.1.2-SNAPSHOT

So I assume that the release plugin does not get the updated gradle project version. Any ideas/hints/help on this? I did not quite find the code pointer in the release plugin for a possible fix. I would have assumed that setting the project.version value before the release task will be reflected during the release task.

christiangroth avatar Jun 24 '21 06:06 christiangroth

for the sake of completeness I'll also provide the sources of my task. It is included in a custom plugin, so not all private methods may be available, but hopefully all you need in this case.

    private fun Project.registerUpdateProjectVersion() {
        tasks.register(updateProjectVersion) {
            it.group = releasenotesGroupName

            it.doLast {
                val extensions = listOf(extension.de, extension.en)
                val updateNotices = extensions.flatMap { extension ->
                    extension.collectSnippets(project.projectDir, ReleasenoteSnippetType.UPDATENOTICE)
                }
                if (updateNotices.isNotEmpty()) {
                    logger.info("detected update notice release notes snippets, configuring major version bump")
                    project.updateVersion(project.versionAsSemver().incMajor())
                    return@doLast
                }

                val features = extensions.flatMap { extension ->
                    extension.collectSnippets(project.projectDir, ReleasenoteSnippetType.FEATURE)
                }
                if (features.isNotEmpty()) {
                    logger.info("detected feature release notes snippets, configuring minor version bump")
                    project.updateVersion(project.versionAsSemver().incMinor())
                    return@doLast
                }

                // we do not need to do anything for bugfixes / patch level changes
                // (we also did never commit changes to gradle.properties in these cases)
                logger.info("all existing release note snippets (if any) lead to patch level bump only")
            }
        }.let { updateProjectVersionTask ->
            afterEvaluate {
                tasks.findByPath(beforeReleaseBuildTaskName)?.let { beforeReleaseBuildTask ->
                    logger.info("Task '${beforeReleaseBuildTask.path}' found, will depend on ${updateProjectVersionTask.name}")
                    beforeReleaseBuildTask.dependsOn(updateProjectVersionTask)
                }
            }
        }
    }

    private fun Project.versionAsSemver() = Semver(project.version.toString())

    private fun Project.updateVersion(newVersion: Semver) {
        project.version = newVersion

        val properties = Properties()
        properties.load(project.propertiesFile().inputStream())
        properties.setProperty("version", newVersion.toString())
        properties.store(project.propertiesFile().outputStream(), null);
    }

    private fun Project.propertiesFile() = rootDir.resolve("gradle.properties")

christiangroth avatar Jun 24 '21 06:06 christiangroth