From 004588e71b280901364752cfd07934dffff5729f Mon Sep 17 00:00:00 2001 From: Simon Templer Date: Sat, 30 Mar 2024 00:57:08 +0100 Subject: [PATCH] feat: verify if tag(s) represent release version --- README.md | 7 +++-- .../gradle/version/VersionExtension.groovy | 20 +++++++++++++ .../gradle/version/VersionPlugin.groovy | 28 ++++++++++++------- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 73c92a5..b25dcc1 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,10 @@ The plugin works based on the following assumptions: 3. If the git repository is not clean or HEAD does not point to a tag, the project version is a SNAPSHOT version that increases the minor version compared to the last release version 4. If no release version is configured or the version file is missing, the project version is `1.0.0-SNAPSHOT` -If the environment variable `RELEASE` is set to `true`, the release version is used, even if the repository is not clean or there is no tag. -This is intended for use cases where the release version was set, but the repository is dirty or no tag was created. +For a tag to be recognized it needs to match the configured release version, optionally with the prefix `v`, for example `1.0.0` or `v1.0.0`. + +If the environment variable `RELEASE` is set to `true`, the release version is used, even if the repository is not clean. +This is intended for use cases where the release version was set, but the repository is expected to be dirty, e.g. due to other CI tasks. +A cleaner method is avoid the repository being dirty, e.g. by adding additional files that are created during the release process to `.gitignore` if possible. By default the version file is assumed to be the file `version.txt` in the root project. diff --git a/src/main/groovy/to/wetransform/gradle/version/VersionExtension.groovy b/src/main/groovy/to/wetransform/gradle/version/VersionExtension.groovy index 71645a8..8290a26 100644 --- a/src/main/groovy/to/wetransform/gradle/version/VersionExtension.groovy +++ b/src/main/groovy/to/wetransform/gradle/version/VersionExtension.groovy @@ -1,5 +1,6 @@ package to.wetransform.gradle.version +import java.util.function.BiPredicate import org.gradle.api.Project class VersionExtension { @@ -9,8 +10,27 @@ class VersionExtension { this.gitDir = project.rootProject.projectDir } + /** + * Location of the file that holds the last release version, if it exists. + */ File versionFile + /** + * Location of the git repository to check. + */ File gitDir + /** + * Test to verify if a tag is a version tag and if the version matches the provided release version. + */ + BiPredicate verifyTag = { tag, version -> + def matcher = tag =~ /^v?((\d+)\.(\d+)\.(\d+))$/ + if (matcher) { + matcher[0][1] == version + } + else { + false + } + } + } diff --git a/src/main/groovy/to/wetransform/gradle/version/VersionPlugin.groovy b/src/main/groovy/to/wetransform/gradle/version/VersionPlugin.groovy index 7436b87..c3a6dda 100644 --- a/src/main/groovy/to/wetransform/gradle/version/VersionPlugin.groovy +++ b/src/main/groovy/to/wetransform/gradle/version/VersionPlugin.groovy @@ -1,5 +1,6 @@ package to.wetransform.gradle.version; +import java.util.function.BiPredicate import org.gradle.api.Plugin; import org.gradle.api.Project; @@ -53,12 +54,14 @@ class VersionPlugin implements Plugin { if(it.version != Project.DEFAULT_VERSION) { throw new IllegalStateException("Version may not be configured if version plugin is applied") } else { - it.version = determineVersion(it, it.versionConfig.versionFile, it.versionConfig.gitDir) + it.version = determineVersion( + it, it.versionConfig.versionFile, it.versionConfig.gitDir, it.versionConfig.verifyTag + ) } } } - String determineVersion(Project project, File versionFile, File gitDir) { + String determineVersion(Project project, File versionFile, File gitDir, BiPredicate verifyTag) { // read version from file def releaseVersion = null if (versionFile.exists()) { @@ -79,11 +82,6 @@ class VersionPlugin implements Plugin { return '1.0.0-SNAPSHOT' } - if ('true'.equalsIgnoreCase(System.getenv('RELEASE'))) { - // force release version (e.g if repo is dirty during release in CI) - return releaseVersion - } - def dirty = false def tagOnCurrentCommit = false def grgit @@ -97,12 +95,22 @@ class VersionPlugin implements Plugin { dirty = !grgit.status().isClean() def currentCommit = grgit.head().id tagOnCurrentCommit = grgit.tag.list().findAll { tag -> - tag.commit.id == currentCommit + tag.commit.id == currentCommit && verifyTag.test(tag.name, releaseVersion) + } + } + + if ('true'.equalsIgnoreCase(System.getenv('RELEASE'))) { + // force release version if repo is dirty (e.g. during release in CI) + // but still verify tag + if (tagOnCurrentCommit) { + return releaseVersion + } + else { + throw new IllegalStateException("There is no matching tag for the configured release version $releaseVersion") } } + if (tagOnCurrentCommit && !dirty) { - //TODO check tags? - //XXX for now assume tag represents release project.logger.info("Current commit is tagged and repository clean, using release version specified in file: $releaseVersion") releaseVersion }