diff --git a/buildSrc/src/main/kotlin/datadog/gradle/plugin/version/TracerVersionPlugin.kt b/buildSrc/src/main/kotlin/datadog/gradle/plugin/version/TracerVersionPlugin.kt index 4cd8669c389..6e7c094829c 100644 --- a/buildSrc/src/main/kotlin/datadog/gradle/plugin/version/TracerVersionPlugin.kt +++ b/buildSrc/src/main/kotlin/datadog/gradle/plugin/version/TracerVersionPlugin.kt @@ -5,6 +5,7 @@ import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.logging.Logging import org.gradle.api.model.ObjectFactory +import org.gradle.api.provider.Provider import org.gradle.api.provider.ProviderFactory import org.gradle.kotlin.dsl.property import java.io.File @@ -48,7 +49,7 @@ class TracerVersionPlugin @Inject constructor( // Not a git repository extension.defaultVersion.get() } else { - val currentBranchProvider = gitCurrentBranchProvider(repoWorkingDirectory) + val currentBranchProvider = currentBranchProvider(repoWorkingDirectory) providerFactory.zip( currentBranchProvider.flatMap { currentBranch -> // Use --first-parent only on release branches so they stay anchored to their own @@ -80,6 +81,18 @@ class TracerVersionPlugin @Inject constructor( return buildVersion } + private fun currentBranchProvider( + repoWorkingDirectory: File + ): Provider = + gitCurrentBranchProvider(repoWorkingDirectory).zip( + providerFactory.environmentVariable("CI_COMMIT_BRANCH").orElse("") + ) { gitBranch, ciBranch -> + // GitLab checks out a detached HEAD, where git reports "HEAD" instead of the branch name. + // Pipelines that don't set CI_COMMIT_BRANCH to the release branch itself (merge requests, + // merge queue working branches) still get the next minor version. + if (gitBranch == "HEAD" && ciBranch.isNotBlank()) ciBranch else gitBranch + } + private fun gitCurrentBranchProvider( repoWorkingDirectory: File ) = providerFactory.of(GitCommandValueSource::class.java) { diff --git a/buildSrc/src/test/kotlin/datadog/gradle/plugin/version/TracerVersionIntegrationTest.kt b/buildSrc/src/test/kotlin/datadog/gradle/plugin/version/TracerVersionIntegrationTest.kt index eb909d71862..7cda763d57a 100644 --- a/buildSrc/src/test/kotlin/datadog/gradle/plugin/version/TracerVersionIntegrationTest.kt +++ b/buildSrc/src/test/kotlin/datadog/gradle/plugin/version/TracerVersionIntegrationTest.kt @@ -127,6 +127,61 @@ class TracerVersionIntegrationTest : VersionPluginsFixture() { ) } + @Test + fun `should increment patch on release branch checked out as detached HEAD in GitLab`() { + assertTracerVersion( + expectedVersion = "1.52.2-SNAPSHOT", + // GitLab checks out the pipeline commit as a detached HEAD and exposes the branch name in CI_COMMIT_BRANCH + env = mapOf("CI_COMMIT_BRANCH" to "release/v1.52.x"), + beforeGradle = { + initGitRepo() + exec("git", "tag", "v1.52.0", "-m", "") + exec("git", "switch", "-c", "release/v1.52.x") + writeSettings("// Committed change ", append = true) + exec("git", "commit", "-am", "Another commit") + exec("git", "tag", "v1.52.1", "-m", "") + writeSettings("// Another committed change ", append = true) + exec("git", "commit", "-am", "Another commit") + exec("git", "switch", "--detach") + }, + ) + } + + @Test + fun `should use exact version on tag checked out as detached HEAD in GitLab`() { + assertTracerVersion( + expectedVersion = "1.52.1", + // GitLab tag pipelines set CI_COMMIT_TAG, not CI_COMMIT_BRANCH + unsetEnv = setOf("CI_COMMIT_BRANCH"), + beforeGradle = { + initGitRepo() + exec("git", "tag", "v1.52.0", "-m", "") + exec("git", "switch", "-c", "release/v1.52.x") + writeSettings("// Committed change ", append = true) + exec("git", "commit", "-am", "Another commit") + exec("git", "tag", "v1.52.1", "-m", "") + exec("git", "switch", "--detach", "v1.52.1") + }, + ) + } + + @Test + fun `should increment minor on detached HEAD without CI_COMMIT_BRANCH`() { + assertTracerVersion( + expectedVersion = "1.53.0-SNAPSHOT", + // Merge request pipelines, local detached checkouts and other CIs don't set CI_COMMIT_BRANCH + unsetEnv = setOf("CI_COMMIT_BRANCH"), + beforeGradle = { + initGitRepo() + exec("git", "tag", "v1.52.0", "-m", "") + exec("git", "switch", "-c", "release/v1.52.x") + writeSettings("// Committed change ", append = true) + exec("git", "commit", "-am", "Another commit") + exec("git", "switch", "--detach") + }, + ) + } + @Test fun `should compute version on worktrees`(@TempDir workTreeDir: File) { assertTracerVersion( @@ -191,6 +246,8 @@ class TracerVersionIntegrationTest : VersionPluginsFixture() { private fun assertTracerVersion( expectedVersion: String, workingDirectory: File = projectDir, + env: Map = emptyMap(), + unsetEnv: Set = emptySet(), beforeGradle: VersionPluginsFixture.() -> Unit = {}, ) { writeSettings( @@ -215,7 +272,13 @@ class TracerVersionIntegrationTest : VersionPluginsFixture() { beforeGradle() - val buildResult = run("printVersion", "--quiet", gradleProjectDir = workingDirectory) + val buildResult = run( + "printVersion", + "--quiet", + env = env, + unsetEnv = unsetEnv, + gradleProjectDir = workingDirectory + ) assertThat(buildResult.output.lines().first()).isEqualTo(expectedVersion) }