This is an automated email from the ASF dual-hosted git repository.
jdaugherty pushed a commit to branch 8.0.x
in repository https://gitbox.apache.org/repos/asf/grails-core.git
The following commit(s) were added to refs/heads/8.0.x by this push:
new 89ff899024 Improve the verification process
89ff899024 is described below
commit 89ff89902466cfff707fd01b3ca3a960e1209a69
Author: James Daugherty <[email protected]>
AuthorDate: Sun Jul 12 13:42:51 2026 -0400
Improve the verification process
---
.github/workflows/release-verify.yml | 34 +++++++++-
etc/bin/verify.sh | 123 +++++++++++++++++++++++++++++++----
2 files changed, 142 insertions(+), 15 deletions(-)
diff --git a/.github/workflows/release-verify.yml
b/.github/workflows/release-verify.yml
index e2e7f5a172..34027e88b4 100644
--- a/.github/workflows/release-verify.yml
+++ b/.github/workflows/release-verify.yml
@@ -17,7 +17,7 @@
# published release tag. The job fails if any verification step fails.
# This replaces the local Docker-based flow (etc/bin/Dockerfile) for CI use;
# the container remains useful for reproducing this environment locally.
-name: "Release Verification"
+name: "Release - Verify Troubleshooting"
on:
workflow_dispatch:
@@ -66,11 +66,43 @@ jobs:
echo "Using Java ${JAVA_VERSION} (${JAVA_DISTRIBUTION})"
echo "java-version=${JAVA_VERSION}" >> "${GITHUB_OUTPUT}"
echo "java-distribution=${JAVA_DISTRIBUTION}" >> "${GITHUB_OUTPUT}"
+ - name: "☕️ Determine Micronaut-island Java version from release.yml"
+ # the reproducible-build check recompiles the Grails-Micronaut island
+ # (grails-micronaut, grails-micronaut-bom) under JDK 25; read the
pinned
+ # version from release.yml ($JAVA_VERSION_MICRONAUT) instead of
duplicating it
+ id: micronaut-java
+ working-directory: project
+ run: |
+ MICRONAUT_JAVA=$(grep -E '^\s*JAVA_VERSION_MICRONAUT:'
.github/workflows/release.yml \
+ | head -n1 | sed -E
's/.*JAVA_VERSION_MICRONAUT:[[:space:]]*([0-9][0-9.]*).*/\1/')
+ if [ -z "${MICRONAUT_JAVA}" ]; then
+ echo "❌ Could not determine JAVA_VERSION_MICRONAUT from
release.yml" >&2
+ exit 1
+ fi
+ echo "Using Micronaut-island Java ${MICRONAUT_JAVA} (liberica)"
+ echo "java-version=${MICRONAUT_JAVA}" >> "${GITHUB_OUTPUT}"
+ - name: "☕️ Setup JDK 25 (Micronaut island)"
+ # installed first so the primary JDK below wins as the default
JAVA_HOME;
+ # setup-java still exports JAVA_HOME_25_X64 for the reproducible-build
check
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #
v5.2.0
+ with:
+ distribution: liberica
+ java-version: ${{ steps.micronaut-java.outputs.java-version }}
- name: "☕️ Setup JDK"
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 #
v5.2.0
with:
distribution: ${{ steps.sdkmanrc.outputs.java-distribution }}
java-version: ${{ steps.sdkmanrc.outputs.java-version }}
+ - name: "☕️ Export JDK 25 home for the reproducible-build check"
+ # verify-reproducible.sh switches JAVA_HOME to ${JDK_25_HOME} for the
+ # Micronaut island pass; mirror the container's ENV JDK_25_HOME here
+ run: |
+ if [ -z "${JAVA_HOME_25_X64:-}" ]; then
+ echo "❌ Expected JAVA_HOME_25_X64 to be exported by setup-java" >&2
+ exit 1
+ fi
+ echo "JDK_25_HOME=${JAVA_HOME_25_X64}" >> "${GITHUB_ENV}"
+ "${JAVA_HOME_25_X64}/bin/java" -version
- name: "🐘 Setup Gradle"
uses:
gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
with:
diff --git a/etc/bin/verify.sh b/etc/bin/verify.sh
index 8136324462..1094ac177f 100755
--- a/etc/bin/verify.sh
+++ b/etc/bin/verify.sh
@@ -33,40 +33,117 @@ CWD=$(pwd)
VERSION=${RELEASE_TAG#v}
export PREFERRED_GRAILS_VERSION=${VERSION}
+# Tracks soft (non-aborting) verification failures so the run can still print
the
+# remaining steps but exit non-zero at the end (which fails the CI workflow).
+VERIFY_FAILED=0
+
cleanup() {
echo "❌ Verification failed. ❌"
}
trap cleanup ERR
-echo "Verifying KEYS file ..."
+# Wrap each verification step in a GitHub Actions log group so it is
individually
+# collapsible in the workflow log. Outside of Actions these emit a plain
heading,
+# so the script reads the same locally and in the container.
+group_start() {
+ if [ "${GITHUB_ACTIONS:-}" = "true" ]; then
+ echo "::group::$1"
+ else
+ echo "$1"
+ fi
+}
+group_end() {
+ if [ "${GITHUB_ACTIONS:-}" = "true" ]; then
+ echo "::endgroup::"
+ fi
+}
+
+# Fail fast on anything the verification scripts depend on but do not install
+# themselves, so a misconfigured environment is reported up front instead of
+# halfway through a long run.
+preflight() {
+ local missing=0
+ local tool
+
+ for tool in java gpg curl unzip groovy; do
+ if ! command -v "${tool}" > /dev/null 2>&1; then
+ echo "❌ Required tool not found on \$PATH: ${tool}"
+ missing=1
+ fi
+ done
+
+ if ! command -v gradlew > /dev/null 2>&1 && ! command -v gradle > /dev/null
2>&1; then
+ echo "❌ Neither gradlew nor gradle found on \$PATH."
+ missing=1
+ fi
+
+ # verify-reproducible.sh recompiles the Grails-Micronaut island under JDK 25,
+ # which must be provided out-of-band via JDK_25_HOME (see release.yml
+ # JAVA_VERSION_MICRONAUT). Validate it here so the run fails before
downloading.
+ if [ -z "${JDK_25_HOME:-}" ]; then
+ echo "❌ JDK_25_HOME is not set; the reproducible-build check needs a
separate Liberica JDK 25 install."
+ echo " Install the JDK matching JAVA_VERSION_MICRONAUT in
.github/workflows/release.yml"
+ echo " and export JDK_25_HOME=/path/to/jdk before running this script."
+ missing=1
+ elif [ ! -x "${JDK_25_HOME}/bin/java" ]; then
+ echo "❌ JDK_25_HOME=${JDK_25_HOME} does not contain an executable
bin/java."
+ missing=1
+ else
+ local jdk25_version
+ jdk25_version=$("${JDK_25_HOME}/bin/java" -version 2>&1 | head -n1)
+ if ! printf '%s' "${jdk25_version}" | grep -q 'version "25'; then
+ echo "❌ JDK_25_HOME=${JDK_25_HOME} is not a JDK 25 (reports:
${jdk25_version})."
+ missing=1
+ fi
+ fi
+
+ if [ "${missing}" -ne 0 ]; then
+ echo "❌ Preflight checks failed. Resolve the issues above before running
verification."
+ exit 1
+ fi
+}
+
+group_start "Running preflight checks ..."
+preflight
+group_end
+echo "✅ Preflight checks passed"
+
+group_start "Verifying KEYS file ..."
"${SCRIPT_DIR}/verify-keys.sh" "${DOWNLOAD_LOCATION}"
+group_end
echo "✅ KEYS Verified"
-echo "Downloading Artifacts ..."
+group_start "Downloading Artifacts ..."
"${SCRIPT_DIR}/download-release-artifacts.sh" "${RELEASE_TAG}"
"${DOWNLOAD_LOCATION}"
+group_end
echo "✅ Artifacts Downloaded"
-echo "Verifying Source Distribution ..."
+group_start "Verifying Source Distribution ..."
"${SCRIPT_DIR}/verify-source-distribution.sh" "${RELEASE_TAG}"
"${DOWNLOAD_LOCATION}"
+group_end
echo "✅ Source Distribution Verified"
-echo "Verifying Wrapper Distribution ..."
+group_start "Verifying Wrapper Distribution ..."
"${SCRIPT_DIR}/verify-wrapper-distribution.sh" "${RELEASE_TAG}"
"${DOWNLOAD_LOCATION}"
+group_end
echo "✅ Wrapper Distribution Verified"
-echo "Verifying CLI Distribution ..."
+group_start "Verifying CLI Distribution ..."
"${SCRIPT_DIR}/verify-cli-distribution.sh" "${RELEASE_TAG}"
"${DOWNLOAD_LOCATION}"
+group_end
echo "✅ CLI Distribution Verified"
-echo "Verifying JAR Artifacts ..."
+group_start "Verifying JAR Artifacts ..."
"${SCRIPT_DIR}/verify-jar-artifacts.sh" "${RELEASE_TAG}" "${DOWNLOAD_LOCATION}"
+group_end
echo "✅ JAR Artifacts Verified"
-echo "Using Java at ..."
+group_start "Using Java at ..."
which java
java -version
+group_end
-echo "Determining Gradle on PATH ..."
+group_start "Determining Gradle on PATH ..."
if GRADLE_CMD="$(command -v gradlew 2>/dev/null)"; then
: # found the wrapper on PATH
elif GRADLE_CMD="$(command -v gradle 2>/dev/null)"; then
@@ -75,28 +152,41 @@ else
echo "❌ ERROR: Neither gradlew nor gradle found on \$PATH." >&2
exit 1
fi
+group_end
echo "✅ Using Gradle command: ${GRADLE_CMD}"
-echo "Bootstrap Gradle ..."
+group_start "Bootstrap Gradle ..."
cd "${DOWNLOAD_LOCATION}/grails/gradle-bootstrap"
${GRADLE_CMD}
+group_end
echo "✅ Gradle Bootstrapped"
-echo "Applying License Audit ..."
+group_start "Applying License Audit ..."
cd "${DOWNLOAD_LOCATION}/grails"
./gradlew rat
+group_end
echo "✅ RAT passed"
-echo "Validating Dependency Versions ..."
+group_start "Validating Dependency Versions ..."
cd "${DOWNLOAD_LOCATION}/grails"
./gradlew validateDependencyVersions
+group_end
echo "✅ Dependency Versions Validated"
-echo "Verifying Reproducible Build ..."
-set +e # because we have known issues here
+group_start "Verifying Reproducible Build ..."
+# Do not abort here: capture the status so a failure is reported as a tracked
+# failure at the end of the run rather than skipping the remaining output.
+set +e
"${SCRIPT_DIR}/verify-reproducible.sh" "${DOWNLOAD_LOCATION}"
+REPRODUCIBLE_STATUS=$?
set -e
-echo "✅ Reproducible Build Verified"
+group_end
+if [ "${REPRODUCIBLE_STATUS}" -eq 0 ]; then
+ echo "✅ Reproducible Build Verified"
+else
+ echo "❌ Reproducible Build verification failed (exit ${REPRODUCIBLE_STATUS})"
+ VERIFY_FAILED=1
+fi
echo "Manual verification steps:"
echo
@@ -115,4 +205,9 @@ echo " 2.1 | Run './grailsw help' inside any of the app
directories above."
echo " 2.2 | Confirm that scaffolding commands (e.g. 'generate-*') are
listed."
echo " This verifies that dynamic command resolution is working
correctly."
echo
+
+if [ "${VERIFY_FAILED}" -ne 0 ]; then
+ echo "❌❌❌ Automated verification FAILED. See the failed steps above. ❌❌❌"
+ exit 1
+fi
echo "✅✅✅ Automatic verification finished. See above instructions for
remaining manual testing."