This is an automated email from the ASF dual-hosted git repository.
jdaugherty pushed a commit to branch 7.0.x
in repository https://gitbox.apache.org/repos/asf/grails-core.git
The following commit(s) were added to refs/heads/7.0.x by this push:
new d8634a206d [skip ci] reworking verify steps end-to-end
d8634a206d is described below
commit d8634a206d26f00db7b1c95e5aec568cd00ebca8
Author: James Daugherty <[email protected]>
AuthorDate: Fri May 30 18:21:33 2025 -0400
[skip ci] reworking verify steps end-to-end
---
.github/workflows/release-source-distribution.yml | 7 +++
RELEASE.md | 13 ++++-
etc/bin/download-release-artifacts.sh | 9 ---
etc/bin/verify-jar-artifacts.sh | 10 ++--
etc/bin/verify-reproducible.sh | 30 +++++-----
etc/bin/verify-source-distribution.sh | 2 +-
etc/bin/verify.sh | 68 +++++++++++++++++++++++
7 files changed, 106 insertions(+), 33 deletions(-)
diff --git a/.github/workflows/release-source-distribution.yml
b/.github/workflows/release-source-distribution.yml
index 9e7c877760..fa078e900d 100644
--- a/.github/workflows/release-source-distribution.yml
+++ b/.github/workflows/release-source-distribution.yml
@@ -58,6 +58,13 @@ jobs:
cd grails
release_url=$(gh release view ${{ github.ref_name }} --json assets
--repo apache/grails-core --jq '.assets[] | select(.name ==
"PUBLISHED_ARTIFACTS.txt") | .url')
curl -L -H "Authorization: token $GH_TOKEN" -o PUBLISHED_ARTIFACTS
"$release_url"
+ - name: "Download BUILD_DATE.txt and rename to BUILD_DATE"
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ cd grails
+ release_url=$(gh release view ${{ github.ref_name }} --json assets
--repo apache/grails-core --jq '.assets[] | select(.name == "BUILD_DATE.txt") |
.url')
+ curl -L -H "Authorization: token $GH_TOKEN" -o BUILD_DATE
"$release_url"
- name: "📦 Create source distribution ZIP"
run: |
version="${{ github.ref_name }}"
diff --git a/RELEASE.md b/RELEASE.md
index fe9a8a2140..b613982aff 100644
--- a/RELEASE.md
+++ b/RELEASE.md
@@ -58,9 +58,18 @@ During the staging step, we must create a source
distribution & stage any binary
* upload the grails-wrapper binary distribution to
https://dist.apache.org/repos/dist/dev/grails/VERSION/distribution
* upload the grails binary distribution to
https://dist.apache.org/repos/dist/dev/grails/VERSION/distribution (note: this
is the sdkman artifact)
-## 2. Verifying Artifacts are Authenticate
+## 2. Verifying Artifacts are Authentic
-Prior to releasing a vote, we need to verify the staged artifacts. Follow the
below steps to verify each staged artifact.
+Prior to releasing a vote, we need to verify the staged artifacts. The below
sections detail all of the necessary steps to ensure the source & binary
distributions are authentic and have not been changed. To verify all of these
at once, use the script:
+
+```bash
+ verify.sh <staging repo id> <release tag> <download location>
+```
+
+For Example:
+```bash
+ verify.sh orgapachegrails-1030 v7.0.0-M4 /tmp/grails-verify
+```
### Download the Staged Artifacts
diff --git a/etc/bin/download-release-artifacts.sh
b/etc/bin/download-release-artifacts.sh
index e46c570b10..d759e5fdb5 100755
--- a/etc/bin/download-release-artifacts.sh
+++ b/etc/bin/download-release-artifacts.sh
@@ -46,12 +46,3 @@ curl -L -o
"${DOWNLOAD_LOCATION}/apache-grails-wrapper-$VERSION-incubating-bin.z
curl -L -o "${DOWNLOAD_LOCATION}/apache-grails-$VERSION-incubating-bin.zip"
"https://github.com/apache/grails-forge/releases/download/$RELEASE_TAG/apache-grails-$VERSION-incubating-bin.zip"
curl -L -o
"${DOWNLOAD_LOCATION}/apache-grails-$VERSION-incubating-bin.zip.asc"
"https://github.com/apache/grails-forge/releases/download/$RELEASE_TAG/apache-grails-$VERSION-incubating-bin.zip.asc"
curl -L -o
"${DOWNLOAD_LOCATION}/apache-grails-$VERSION-incubating-bin.zip.sha512"
"https://github.com/apache/grails-forge/releases/download/$RELEASE_TAG/apache-grails-$VERSION-incubating-bin.zip.sha512"
-
-# checksums
-curl -L -o "${DOWNLOAD_LOCATION}/CHECKSUMS.txt"
"https://github.com/apache/grails-core/releases/download/$RELEASE_TAG/CHECKSUMS.txt"
-
-# published artifacts
-curl -L -o "${DOWNLOAD_LOCATION}/PUBLISHED_ARTIFACTS.txt"
"https://github.com/apache/grails-core/releases/download/$RELEASE_TAG/PUBLISHED_ARTIFACTS.txt"
-
-# build date for reproducible build testing
-curl -L -o "${DOWNLOAD_LOCATION}/BUILD_DATE.txt"
"https://github.com/apache/grails-core/releases/download/$RELEASE_TAG/BUILD_DATE.txt"
\ No newline at end of file
diff --git a/etc/bin/verify-jar-artifacts.sh b/etc/bin/verify-jar-artifacts.sh
index b2a05b3e5e..61c8e3d61a 100755
--- a/etc/bin/verify-jar-artifacts.sh
+++ b/etc/bin/verify-jar-artifacts.sh
@@ -32,9 +32,8 @@ fi
VERSION=${RELEASE_TAG#v}
-ARTIFACTS_FILE="${DOWNLOAD_LOCATION}/PUBLISHED_ARTIFACTS"
-CHECKSUMS_FILE="${DOWNLOAD_LOCATION}/CHECKSUMS"
-BUILD_DATE_FILE="${DOWNLOAD_LOCATION}/BUILD_DATE.txt"
+ARTIFACTS_FILE="${DOWNLOAD_LOCATION}/grails/PUBLISHED_ARTIFACTS"
+CHECKSUMS_FILE="${DOWNLOAD_LOCATION}/grails/CHECKSUMS"
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
if [ ! -f "${ARTIFACTS_FILE}" ]; then
@@ -61,9 +60,8 @@ gpg --homedir "${GRAILS_GPG_HOME}" --import
"${SCRIPT_DIR}/../../KEYS"
REPO_BASE_URL="https://repository.apache.org/content/repositories/${STAGING_REPO_ID}"
-# cp the artifacts file to the expected location for reproducible build check
-cp "${ARTIFACTS_FILE}" etc/bin/results/
-cp "${BUILD_DATE_FILE}" etc/bin/results/
+# switch to the extracted Grails source directory
+cd grails
# Create a temporary directory to work in
WORK_DIR='etc/bin/results/published_artifacts'
diff --git a/etc/bin/verify-reproducible.sh b/etc/bin/verify-reproducible.sh
index e14cac99ae..5a972a83c6 100755
--- a/etc/bin/verify-reproducible.sh
+++ b/etc/bin/verify-reproducible.sh
@@ -25,28 +25,28 @@ SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )"
&> /dev/null && pwd )
CWD=$(pwd)
-cd "${DOWNLOAD_LOCATION}"
+cd "${DOWNLOAD_LOCATION}/grails"
-mkdir -p "${DOWNLOAD_LOCATION}/results"
-if [[ -f "${DOWNLOAD_LOCATION}/results/PUBLISHED_ARTIFACTS" ]]; then
+mkdir -p "${DOWNLOAD_LOCATION}/grails/etc/bin/results"
+if [[ -f "${DOWNLOAD_LOCATION}/grails/PUBLISHED_ARTIFACTS" ]]; then
echo "✅ File 'PUBLISHED_ARTIFACTS' exists."
else
- echo "❌ File 'PUBLISHED_ARTIFACTS' not found. Please place the
PUBLISHED_ARTIFACTS distribution file under
${DOWNLOAD_LOCATION}/results/PUBLISHED_ARTIFACTS..."
+ echo "❌ File 'PUBLISHED_ARTIFACTS' not found. Grails Source Distributions
should have a PUBLISHED_ARTIFACTS file at the root..."
exit 1
fi
-if [[ -f "${DOWNLOAD_LOCATION}/results/BUILD_DATE.txt" ]]; then
- echo "✅ File 'BUILD_DATE.txt' exists."
+if [[ -f "${DOWNLOAD_LOCATION}/grails/BUILD_DATE" ]]; then
+ echo "✅ File 'BUILD_DATE' exists."
else
- echo "❌ File 'BUILD_DATE.txt' not found. Please place the BUILD_DATE.txt
distribution file under ${DOWNLOAD_LOCATION}/results/BUILD_DATE.txt..."
+ echo "❌ File 'BUILD_DATE' not found. Grails Source Distributions should have
a BUILD_DATE file at the root..."
exit 1
fi
-export SOURCE_DATE_EPOCH=$(cat "${DOWNLOAD_LOCATION}/results/BUILD_DATE.txt")
+export SOURCE_DATE_EPOCH=$(cat "${DOWNLOAD_LOCATION}/grails/BUILD_DATE")
-if [[ -d "${DOWNLOAD_LOCATION}/results/published" ]]; then
+if [[ -d "${DOWNLOAD_LOCATION}/grails/etc/bin/results/published" ]]; then
echo "✅ Directory 'published' exists."
else
- echo "❌ Directory 'published' not found. Please place the PUBLISHED jar
files under ${DOWNLOAD_LOCATION}/results/published..."
+ echo "❌ Directory 'published' not found. Please place the PUBLISHED jar
files under ${DOWNLOAD_LOCATION}/grails/etc/bin/results/published..."
exit 1
fi
@@ -55,14 +55,14 @@ cd grails-gradle
./gradlew build --rerun-tasks -PskipTests --no-build-cache
cd ..
./gradlew build --rerun-tasks -PskipTests --no-build-cache
-"${SCRIPT_DIR}/generate-build-artifact-hashes.groovy" >
"${DOWNLOAD_LOCATION}/results/second.txt"
-mkdir -p "${DOWNLOAD_LOCATION}/results/second"
-find . -path ./etc -prune -o -type f -path '*/build/libs/*.jar' -exec cp -t
"${DOWNLOAD_LOCATION}/results/second/" -- {} +
+"${SCRIPT_DIR}/generate-build-artifact-hashes.groovy" >
"${DOWNLOAD_LOCATION}/grails/etc/bin/results/second.txt"
+mkdir -p "${DOWNLOAD_LOCATION}/grails/etc/bin/results/second"
+find . -path ./etc -prune -o -type f -path '*/build/libs/*.jar' -exec cp -t
"${DOWNLOAD_LOCATION}/grails/etc/bin/results/second/" -- {} +
-cd "${DOWNLOAD_LOCATION}/results"
+cd "${DOWNLOAD_LOCATION}/grails/etc/bin/results"
# diff -u PUBLISHED_ARTIFACTS second.txt
-DIFF_RESULTS=$(comm -3 <(cut -d' ' -f1 PUBLISHED_ARTIFACTS | sort) <(sort
second.txt) | cut -d' ' -f1 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | uniq
| sort)
+DIFF_RESULTS=$(comm -3 <(cut -d' ' -f1 ../../../PUBLISHED_ARTIFACTS | sort)
<(sort second.txt) | cut -d' ' -f1 | sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
| uniq | sort)
echo "Differing artifacts:"
echo "$DIFF_RESULTS" > diff.txt
cat diff.txt
diff --git a/etc/bin/verify-source-distribution.sh
b/etc/bin/verify-source-distribution.sh
index c05827f456..461e54dcce 100755
--- a/etc/bin/verify-source-distribution.sh
+++ b/etc/bin/verify-source-distribution.sh
@@ -64,7 +64,7 @@ if [ ! -d "${SRC_DIR}" ]; then
fi
echo "Checking for required files existence..."
-REQUIRED_FILES=("LICENSE" "NOTICE" "README.md" "CONTRIBUTING.md"
"PUBLISHED_ARTIFACTS" "CHECKSUMS")
+REQUIRED_FILES=("LICENSE" "NOTICE" "README.md" "CONTRIBUTING.md"
"PUBLISHED_ARTIFACTS" "CHECKSUMS" "BUILD_DATE")
for FILE in "${REQUIRED_FILES[@]}"; do
if [ ! -f "${SRC_DIR}/$FILE" ]; then
diff --git a/etc/bin/verify.sh b/etc/bin/verify.sh
new file mode 100755
index 0000000000..9ca25eaa14
--- /dev/null
+++ b/etc/bin/verify.sh
@@ -0,0 +1,68 @@
+#!/usr/bin/env bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+set -euo pipefail
+
+STAGING_REPO_ID=$1
+RELEASE_TAG=$2
+DOWNLOAD_LOCATION="${3:-downloads}"
+DOWNLOAD_LOCATION=$(realpath "${DOWNLOAD_LOCATION}")
+
+if [ -z "${STAGING_REPO_ID}" ] || [ -z "${RELEASE_TAG}" ]; then
+ echo "Usage: $0 [staging-repo-id] [release-tag] <optional download location>"
+ exit 1
+fi
+
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+CWD=$(pwd)
+
+cleanup() {
+ echo "❌ Verification failed. ❌"
+}
+trap cleanup ERR
+
+echo "Downloading Artifacts ..."
+"${SCRIPT_DIR}/download-release-artifacts.sh" "${RELEASE_TAG}"
"${DOWNLOAD_LOCATION}"
+echo "✅ Artifacts Downloaded"
+
+echo "Verifying Source Distribution ..."
+"${SCRIPT_DIR}/verify-source-distribution.sh" "${RELEASE_TAG}"
"${DOWNLOAD_LOCATION}"
+echo "✅ Source Distribution Verified"
+
+echo "Verifying Wrapper Distribution ..."
+"${SCRIPT_DIR}/verify-wrapper-distribution.sh" "${RELEASE_TAG}"
"${DOWNLOAD_LOCATION}"
+echo "✅ Wrapper Distribution Verified"
+
+echo "Verifying CLI Distribution ..."
+"${SCRIPT_DIR}/verify-cli-distribution.sh" "${RELEASE_TAG}"
"${DOWNLOAD_LOCATION}"
+echo "✅ CLI Distribution Verified"
+
+echo "Verifying JAR Artifacts ..."
+"${SCRIPT_DIR}/verify-jar-artifacts.sh" "${STAGING_REPO_ID}" "${RELEASE_TAG}"
"${DOWNLOAD_LOCATION}"
+echo "✅ JAR Artifacts Verified"
+
+echo "Bootstrapping Gradle..."
+cd "${DOWNLOAD_LOCATION}/grails"
+gradle wrapper
+cd grails-gradle
+gradle wrapper
+cd "${CWD}"
+
+echo "Testing for Reproducible Build ..."
+echo " ... Manually"