jamesfredley commented on code in PR #15677:
URL: https://github.com/apache/grails-core/pull/15677#discussion_r3320822036


##########
.github/workflows/release.yml:
##########
@@ -203,6 +219,40 @@ jobs:
           publishToSonatype
           aggregateChecksums
           aggregatePublishedArtifacts
+          -PskipMicronautProjects
+      - name: "☕️ Switch to JDK 25 for Micronaut publish"
+        # Micronaut 5 platform GA targets JVM 25 bytecode, so the island
+        # artifacts (grails-micronaut, grails-micronaut-bom) must be built and
+        # staged from a JDK 25 runner. This is a NEW reproducibility pin -
+        # keep $JAVA_VERSION_MICRONAUT synced with the secondary JDK in
+        # etc/bin/Dockerfile so verifiers can reproduce the resulting JARs.
+        uses: actions/setup-java@v4
+        with:
+          distribution: liberica
+          java-version: ${{ env.JAVA_VERSION_MICRONAUT }}
+      - name: "📤 Publish Grails-Micronaut to Staging Repository"
+        env:
+          NEXUS_PUBLISH_USERNAME: ${{ secrets.NEXUS_STAGE_DEPLOYER_USER }}
+          NEXUS_PUBLISH_PASSWORD: ${{ secrets.NEXUS_STAGE_DEPLOYER_PW }}
+          NEXUS_PUBLISH_URL: ${{ vars.STAGING_URL }}
+          NEXUS_PUBLISH_STAGING_PROFILE_ID: ${{ secrets.STAGING_PROFILE_ID }}
+          NEXUS_PUBLISH_DESCRIPTION: '${{ env.REPO_NAME }}:${{ env.VERSION }}'
+          SIGNING_KEY: ${{ secrets.GPG_KEY_ID }}
+        run: >
+          ./gradlew
+          -x initializeSonatypeStagingRepository
+          findSonatypeStagingRepository
+          :grails-micronaut:publishToSonatype
+          :grails-micronaut-bom:publishToSonatype

Review Comment:
   Good catch - fixed in 92f8cf0ad3.
   
   The two island artifacts (`grails-micronaut`, `grails-micronaut-bom`) are 
now appended to the combined `CHECKSUMS.txt` / `PUBLISHED_ARTIFACTS.txt` in the 
"Combine checksums" and "Combine published artifacts" steps, reading the 
per-project files that `publishedChecksums` / `savePublishedArtifacts` emit as 
finalizers of the JDK 25 `publishToSonatype` step.
   
   I deliberately did *not* add `aggregateChecksums` / 
`aggregatePublishedArtifacts` to the JDK 25 step as suggested. The build 
compiles with `options.release` and no Gradle toolchain (see 
`build-logic/.../CompilePlugin.groovy`), so re-running those tasks on the JDK 
25 runner would invalidate and recompile the non-island projects against a JDK 
25 compiler, producing different (non-reproducible) bytecode than the JDK 21 
artifacts that were already signed and staged. Appending the island's 
already-generated checksum/artifact files avoids touching the JDK 21 outputs 
entirely while still making the final manifests complete.
   



##########
grails-data-graphql/plugin/src/main/groovy/org/grails/gorm/graphql/plugin/testing/GraphQLSpec.groovy:
##########
@@ -56,59 +65,90 @@ trait GraphQLSpec {
     @TupleConstructor
     static class GraphQLRequestHelper {
 
-        RxHttpClient rest
+        private static final MediaType APPLICATION_GRAPHQL = 
MediaType.parseMediaType('application/graphql')
+        private static final JsonSlurper SLURPER = new JsonSlurper()
 
-        HttpResponse<Map> graphql(String requestBody) {
-            rest.exchange(HttpRequest.POST('/graphql', 
requestBody).contentType('application/graphql'), Map)
-                    .firstOrError().blockingGet()
+        RestClient rest

Review Comment:
   Added a "Testing and JSON Serialization" warning to the grails-data-graphql 
guide (`grails-data-graphql/docs/src/main/docs/guide/otherNotes.adoc`) in 
92f8cf0ad3.
   
   It documents that `GraphQLSpec` serializes request bodies and parses 
responses with Groovy's `JsonOutput` / `JsonSlurper` rather than the 
application's configured object mapper, so a customized object mapper 
(non-default date formats, property naming strategies, custom serializers) can 
render production responses differently from what the trait asserts on. The 
note recommends asserting against the raw response body and verifying the 
object mapper configuration separately when serialization details matter.
   



##########
etc/bin/verify-reproducible.sh:
##########
@@ -58,13 +58,36 @@ else
 fi
 
 killall -e java || true
+
+# JDK 21 (default) pass: grails-gradle composite (no Micronaut island), root
+# (Micronaut island skipped), grails-forge composite (transitively pulls in
+# the root build via includeBuild('..'), island skipped there too).
 cd grails-gradle
 ./gradlew publishToMavenLocal --rerun-tasks -PskipTests --no-build-cache
 cd ..
-./gradlew publishToMavenLocal --rerun-tasks -PskipTests --no-build-cache
+./gradlew publishToMavenLocal --rerun-tasks -PskipTests --no-build-cache 
-PskipMicronautProjects
 cd grails-forge
-./gradlew publishToMavenLocal --rerun-tasks -PskipTests --no-build-cache
+./gradlew publishToMavenLocal --rerun-tasks -PskipTests --no-build-cache 
-PskipMicronautProjects

Review Comment:
   Correct - the Forge build itself has no Micronaut island projects. The flag 
is needed because `grails-forge/settings.gradle:75` does `includeBuild('..')`, 
which pulls the root grails-core build (which *does* contain the island) into 
the Forge composite. Project properties passed on the command line propagate 
into included builds, so without `-PskipMicronautProjects` the island would be 
configured/resolved on JDK 21 and fail (Micronaut 5 GA targets JVM 25 
bytecode). The inline comment directly above this block documents the 
rationale. Leaving the flag in place.
   



##########
etc/bin/verify-reproducible.sh:
##########
@@ -58,13 +58,36 @@ else
 fi
 
 killall -e java || true
+
+# JDK 21 (default) pass: grails-gradle composite (no Micronaut island), root
+# (Micronaut island skipped), grails-forge composite (transitively pulls in
+# the root build via includeBuild('..'), island skipped there too).
 cd grails-gradle
 ./gradlew publishToMavenLocal --rerun-tasks -PskipTests --no-build-cache
 cd ..
-./gradlew publishToMavenLocal --rerun-tasks -PskipTests --no-build-cache
+./gradlew publishToMavenLocal --rerun-tasks -PskipTests --no-build-cache 
-PskipMicronautProjects
 cd grails-forge
-./gradlew publishToMavenLocal --rerun-tasks -PskipTests --no-build-cache
+./gradlew publishToMavenLocal --rerun-tasks -PskipTests --no-build-cache 
-PskipMicronautProjects
 cd ..
+
+# JDK 25 pass: the Grails-Micronaut "island" only (grails-micronaut,
+# grails-micronaut-bom). Micronaut 5 platform GA targets JVM 25 bytecode so
+# these two artifacts cannot be reproduced on JDK 21. The verification
+# container provides ${JDK_25_HOME}; for local verification outside the
+# container, install Liberica JDK matching $JAVA_VERSION_MICRONAUT in
+# release.yml and export JDK_25_HOME before running this script.
+if [[ -z "${JDK_25_HOME:-}" ]]; then
+  echo "❌ JDK_25_HOME is not set; the Grails-Micronaut island requires a 
separate Liberica JDK 25 install."
+  echo "   In the verification container this is set automatically. Outside 
the container, install Liberica JDK"
+  echo "   matching JAVA_VERSION_MICRONAUT in .github/workflows/release.yml 
and export JDK_25_HOME=/path/to/jdk."
+  exit 1
+fi
+killall -e java || true

Review Comment:
   Done in 92f8cf0ad3 - added `--no-daemon` to every gradle invocation in both 
`etc/bin/verify-reproducible.sh` and `etc/bin/test-reproducible-builds.sh`.
   



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to