From e4316992960f335ceec1a31b747705b69bec9a95 Mon Sep 17 00:00:00 2001 From: Knut Wannheden Date: Wed, 11 Mar 2026 09:48:25 +0100 Subject: [PATCH] Fix npm and NuGet version mismatch across CI jobs The npm-publish workflow runs as a separate job with a fresh checkout, so it lost the version determined during build/release. For releases like v8.75.3, this caused npm to publish 8.76.0-20260311-003608 instead. - Accept npm_version from upstream workflow and pass it as Gradle property - Add npmVersion Gradle property support to rewrite-javascript build - Fix rewrite-csharp to read version.txt before generating a fresh timestamp (same fix Python/JS already had from 750bc71067) - Pass npm_version from build/release job outputs in ci.yml and publish.yml --- .github/workflows/ci.yml | 1 + .github/workflows/npm-publish.yml | 6 ++++++ .github/workflows/publish.yml | 1 + rewrite-csharp/build.gradle.kts | 19 +++++++++++++++---- rewrite-javascript/build.gradle.kts | 11 +++++++---- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d09dd4a1921..375d648370d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,6 +42,7 @@ jobs: java_version: | 25 21 + npm_version: ${{ needs.build.outputs.npm_version }} secrets: gradle_enterprise_access_key: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} npm_token: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/npm-publish.yml b/.github/workflows/npm-publish.yml index 8607a4adac0..9c487ce889b 100644 --- a/.github/workflows/npm-publish.yml +++ b/.github/workflows/npm-publish.yml @@ -14,6 +14,11 @@ on: type: boolean required: false default: false + npm_version: + description: Exact npm package version to publish (passed from build/release job) + type: string + required: false + default: '' secrets: gradle_enterprise_access_key: required: false @@ -64,6 +69,7 @@ jobs: ./gradlew ${{ env.GRADLE_SWITCHES }} :rewrite-javascript:npmPack ${{ inputs.releasing && '-Preleasing' || '' }} + ${{ inputs.npm_version && format('-PnpmVersion={0}', inputs.npm_version) || '' }} - name: npm publish run: | diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7cab842d402..586f839134a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -35,6 +35,7 @@ jobs: 25 21 releasing: true + npm_version: ${{ needs.release.outputs.npm_version }} secrets: gradle_enterprise_access_key: ${{ secrets.GRADLE_ENTERPRISE_ACCESS_KEY }} npm_token: ${{ secrets.NPM_TOKEN }} diff --git a/rewrite-csharp/build.gradle.kts b/rewrite-csharp/build.gradle.kts index e2195fa1cf4..513f6199b8d 100644 --- a/rewrite-csharp/build.gradle.kts +++ b/rewrite-csharp/build.gradle.kts @@ -121,10 +121,21 @@ tasks.withType { // Generate a NuGet-compatible version // Snapshots use pre-release suffix with timestamp: 8.73.0-snapshot.20260110143252 // Releases use clean version: 8.73.0 -val nugetVersion: String = project.version.toString().replace( - "-SNAPSHOT", - "-snapshot.${LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))}" -) +// Read from version.txt first (written by a prior `build` invocation) to ensure the +// version published to NuGet matches what's baked into the JAR. +val nugetVersionTxt = file("src/main/resources/META-INF/rewrite-csharp-version.txt") +val nugetVersion: String = if (System.getenv("CI") != null) { + nugetVersionTxt.takeIf { it.exists() }?.readText()?.trim()?.takeIf { it.isNotEmpty() } + ?: project.version.toString().replace( + "-SNAPSHOT", + "-snapshot.${LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))}" + ) +} else { + project.version.toString().replace( + "-SNAPSHOT", + "-snapshot.${LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))}" + ) +} val generateVersionTxt by tasks.registering { group = "csharp" diff --git a/rewrite-javascript/build.gradle.kts b/rewrite-javascript/build.gradle.kts index c54ddfeca83..b041babc601 100644 --- a/rewrite-javascript/build.gradle.kts +++ b/rewrite-javascript/build.gradle.kts @@ -55,11 +55,14 @@ extensions.configure { nodeProjectDir.set(projectDir.resolve("rewrite")) } -// Read the version from the version.txt written on disk by a prior build, or generate a fresh -// timestamped version. This ensures the second Gradle invocation (`snapshot publish`) publishes -// the same version that the first invocation (`build`) baked into the JAR. +// Determine the npm package version. Priority: +// 1. Gradle property `npmVersion` (set by CI workflows to pass the version across jobs) +// 2. version.txt on disk (written by a prior `build` invocation in the same job) +// 3. Generate a fresh timestamped version from project.version val versionTxt = file("src/main/resources/META-INF/rewrite-javascript-version.txt") -val datedSnapshotVersion: String = if (System.getenv("CI") != null) { +val datedSnapshotVersion: String = if (project.hasProperty("npmVersion")) { + project.property("npmVersion").toString() +} else if (System.getenv("CI") != null) { versionTxt.takeIf { it.exists() }?.readText()?.trim()?.takeIf { it.isNotEmpty() } ?: project.version.toString().replace( "SNAPSHOT",