blob: 09b2808ae4a72eba4a3e400872f45985b6d7b806 [file]
# 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.
name: "Release"
on:
release:
types: [published]
permissions: {}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GRAILS_PUBLISH_RELEASE: true
JAVA_DISTRIBUTION: liberica
JAVA_VERSION: 17.0.17 # this must be a specific version for reproducible builds, keep it synced with .sdkmanrc
PROJECT_DESC: >
The Grails Redis plugin integrates Redis with Grails to
provide high-performance caching.
PROJECT_NAME: Apache Grails Redis Plugin
REPO_NAME: ${{ github.event.repository.name }}
REPO_SLUG: ${{ github.repository }}
SVN_FOLDER: redis
TAG: ${{ github.event.release.tag_name }}
VERSION: will be computed in each job
jobs:
publish:
name: "Stage Jar Files"
permissions:
contents: write # to stage distributions to the GitHub release page
issues: write # to modify milestones
runs-on: ubuntu-24.04
steps:
- name: "🌐 Output Agent IP" # in the event RAO blocks this agent, this can be used to debug it
run: curl -s https://api.ipify.org
- name: "📝 Establish release version"
run: echo "VERSION=${TAG#v}" >> "$GITHUB_ENV"
- name: "📥 Checkout repository"
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ env.TAG }}
token: ${{ secrets.GITHUB_TOKEN }} # This should not be needed as ${{ github.token }} is the default, but there have been issues with it.
- name: "📅 Store common build date" # to ensure a reproducible build
run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV"
- name: "📅 Ensure source files use common date"
run: find . -depth \( -type f -o -type d \) -exec touch -d "@${SOURCE_DATE_EPOCH}" {} +
- name: "🔐 Set up GPG"
run: |
echo "${{ secrets.GRAILS_GPG_KEY }}" | gpg --batch --import
gpg --list-keys
env:
GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }}
- name: "☕️ Setup JDK"
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: ${{ env.JAVA_DISTRIBUTION }}
java-version: ${{ env.JAVA_VERSION }}
- name: "🐘 Setup Gradle"
uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
with:
cache-provider: basic # 'basic' uses the MIT-licensed, open-source cache provider; the default 'enhanced' provider (v6+) is proprietary (Gradle commercial Terms of Use)
develocity-access-key: ${{ secrets.GRAILS_DEVELOCITY_ACCESS_KEY }}
- name: "⚙️ Run pre-release"
uses: apache/grails-github-actions/pre-release@asf
env:
RELEASE_VERSION: ${{ env.VERSION }}
- name: "✨ Create 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 initializeSonatypeStagingRepository
- name: "📤 Publish 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 findSonatypeStagingRepository
publishToSonatype
aggregateChecksums
aggregatePublishedArtifacts
-x initializeSonatypeStagingRepository
- name: "✅ Close 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 findSonatypeStagingRepository
closeSonatypeStagingRepository
-x initializeSonatypeStagingRepository
- name: "📅 Generate build date file"
run: echo "$SOURCE_DATE_EPOCH" >> build/BUILD_DATE.txt
- name: "📤 Upload build date, checksums and published artifacts files"
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
with:
tag_name: ${{ env.TAG }}
files: |
build/BUILD_DATE.txt
build/CHECKSUMS.txt
build/PUBLISHED_ARTIFACTS.txt
source:
# to ensure we never publish any build artifacts, run the source distribution as a separate build workflow
name: "Source Distribution"
needs: publish
permissions:
contents: write
runs-on: ubuntu-24.04
steps:
- name: "📝 Establish release version"
run: echo "VERSION=${TAG#v}" >> "$GITHUB_ENV"
- name: "📥 Checkout repository"
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: ${{ env.REPO_NAME }}
ref: ${{ env.TAG }}
token: ${{ secrets.GITHUB_TOKEN }} # This should not be needed as ${{ github.token }} is the default, but there have been issues with it.
- name: "🗑️ Remove unnecessary files"
working-directory: ${{ env.REPO_NAME }}
run: |
rm -f gradle/wrapper/gradle-wrapper.jar
rm -f gradle/wrapper/gradle-wrapper.properties
rm -f gradlew
rm -f gradlew.bat
rm -f .asf.yaml
- name: "📥 Download CHECKSUMS.txt and rename to CHECKSUMS"
working-directory: ${{ env.REPO_NAME }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
release_url=$(gh release view "$TAG" --json assets --repo "$REPO_SLUG" --jq '.assets[] | select(.name == "CHECKSUMS.txt") | .url')
curl -f -L -H "Authorization: token $GH_TOKEN" -o CHECKSUMS "$release_url"
- name: "📥 Download PUBLISHED_ARTIFACTS.txt and rename to PUBLISHED_ARTIFACTS"
working-directory: ${{ env.REPO_NAME }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
release_url=$(gh release view "$TAG" --json assets --repo "$REPO_SLUG" --jq '.assets[] | select(.name == "PUBLISHED_ARTIFACTS.txt") | .url')
curl -f -L -H "Authorization: token $GH_TOKEN" -o PUBLISHED_ARTIFACTS "$release_url"
- name: "📥 Download BUILD_DATE.txt and rename to BUILD_DATE"
working-directory: ${{ env.REPO_NAME }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
release_url=$(gh release view "$TAG" --json assets --repo "$REPO_SLUG" --jq '.assets[] | select(.name == "BUILD_DATE.txt") | .url')
curl -f -L -H "Authorization: token $GH_TOKEN" -o BUILD_DATE "$release_url"
- name: "📅 Ensure source files use common date"
run: |
SOURCE_DATE_EPOCH=$(cat ${REPO_NAME}/BUILD_DATE)
find . -depth \( -type f -o -type d \) -exec touch -d "@${SOURCE_DATE_EPOCH}" {} +
- name: "📦 Create source distribution ZIP"
run: |
zip -r \
"apache-${REPO_NAME}-${VERSION}-src.zip" \
"$REPO_NAME" \
-x "${REPO_NAME}/.git/*" \
-x "${REPO_NAME}/.github/*"
- name: "🔐 Set up GPG"
run: |
echo "${{ secrets.GRAILS_GPG_KEY }}" | gpg --batch --import
gpg --list-keys
env:
GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }}
- name: "🔏 Sign source distribution ZIP"
env:
GPG_KEY_ID: ${{ secrets.GPG_KEY_ID }}
run: |
gpg \
--default-key "$GPG_KEY_ID" \
--batch \
--yes \
--pinentry-mode loopback \
--armor \
--detach-sign "apache-${REPO_NAME}-${VERSION}-src.zip"
- name: "📦 Create source distribution checksum"
run: |
sha512sum "./apache-${REPO_NAME}-${VERSION}-src.zip" \
> "apache-${REPO_NAME}-${VERSION}-src.zip.sha512"
cat "./apache-${REPO_NAME}-${VERSION}-src.zip.sha512"
- name: "🚀 Upload ZIP and Signature to GitHub Release"
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
with:
tag_name: ${{ env.TAG }}
files: |
apache-${{ env.REPO_NAME }}-${{ env.VERSION }}-src.zip
apache-${{ env.REPO_NAME }}-${{ env.VERSION }}-src.zip.sha512
apache-${{ env.REPO_NAME }}-${{ env.VERSION }}-src.zip.asc
- name: "🗑️ Remove CHECKSUMS.txt asset from release"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -e
gh release delete-asset \
"$TAG" \
CHECKSUMS.txt \
--repo "$REPO_SLUG" \
--yes
- name: "🗑️ Remove BUILD_DATE.txt asset from release"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -e
gh release delete-asset \
"$TAG" \
BUILD_DATE.txt \
--repo "$REPO_SLUG" \
--yes
- name: "🗑️ Remove PUBLISHED_ARTIFACTS.txt asset from release"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -e
gh release delete-asset \
"$TAG" \
PUBLISHED_ARTIFACTS.txt \
--repo "$REPO_SLUG" \
--yes
upload:
name: "Upload Source Distribution"
needs: [ publish, source ]
runs-on: ubuntu-24.04
permissions:
contents: write
env:
SVN_USERNAME: ${{ secrets.SVC_DIST_GRAILS_USERNAME }}
SVN_PASSWORD: ${{ secrets.SVC_DIST_GRAILS_PASSWORD }}
steps:
- name: "📝 Establish release version"
run: echo "VERSION=${TAG#v}" >> "$GITHUB_ENV"
- name: "⚙️ Setup SVN and Tools"
run: sudo apt-get install -y subversion subversion-tools tree gettext-base
- name: "👀 Ensure grails dev folder exists"
run: |
set -e
if svn ls https://dist.apache.org/repos/dist/dev/grails --username "$SVN_USERNAME" --password "$SVN_PASSWORD" --non-interactive; then
echo "Dev Folder [grails] already exists — skipping creation"
else
echo "Dev Folder [grails] does not exist, creating"
svnmucc --username "$SVN_USERNAME" --password "$SVN_PASSWORD" --non-interactive \
mkdir https://dist.apache.org/repos/dist/dev/grails \
-m "Create 'grails' dev folder"
fi
- name: "👀 Ensure grails ${{ env.SVN_FOLDER }} folder exists"
run: |
set -e
if svn ls "https://dist.apache.org/repos/dist/dev/grails/${SVN_FOLDER}" --username "$SVN_USERNAME" --password "$SVN_PASSWORD" --non-interactive; then
echo "Dev Folder [grails/${SVN_FOLDER}] already exists — skipping creation"
else
echo "Dev Folder [grails/${SVN_FOLDER}] does not exist, creating"
svnmucc --username "$SVN_USERNAME" --password "$SVN_PASSWORD" --non-interactive \
mkdir "https://dist.apache.org/repos/dist/dev/grails/${SVN_FOLDER}" \
-m "Create 'grails ${SVN_FOLDER}' dev folder"
fi
- name: "📥 Checkout dev repo"
run: |
svn checkout --username "$SVN_USERNAME" --password "$SVN_PASSWORD" --non-interactive "https://dist.apache.org/repos/dist/dev/grails/${SVN_FOLDER}" dev-repo
- name: "🗑️ Remove existing dev version"
run: |
cd dev-repo
if [ -d "$VERSION" ]; then
svn delete "$VERSION"
svn commit -m "Remove grails ${SVN_FOLDER} dev version ${VERSION}" --username "$SVN_USERNAME" --password "$SVN_PASSWORD" --non-interactive
else
echo "No existing dev version ${VERSION} to remove"
fi
- name: "📥 Fetch source distributions"
run: |
cd dev-repo
mkdir -p "${VERSION}/sources"
cd "${VERSION}/sources"
curl -f -LO "https://github.com/${REPO_SLUG}/releases/download/${TAG}/apache-${REPO_NAME}-${VERSION}-src.zip"
curl -f -LO "https://github.com/${REPO_SLUG}/releases/download/${TAG}/apache-${REPO_NAME}-${VERSION}-src.zip.sha512"
curl -f -LO "https://github.com/${REPO_SLUG}/releases/download/${TAG}/apache-${REPO_NAME}-${VERSION}-src.zip.asc"
echo "Downloaded the following files:"
ls -l
- name: "🚀 Upload distributions"
run: |
cd dev-repo
echo "Adding the following files to SVN:"
tree
svn add "$VERSION" --force
svn commit -m "Upload ${PROJECT_NAME} distribution files for ${VERSION}" --username "$SVN_USERNAME" --password "$SVN_PASSWORD" --non-interactive
pwd
- name: "💾 Store Distribution SVN revision in a file"
run: |
cd dev-repo
svn info "$VERSION" > "DIST_SVN_REVISION.txt"
- name: "📤 Upload the Distribution SVN revision file"
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
with:
tag_name: ${{ env.TAG }}
files: dev-repo/DIST_SVN_REVISION.txt
- name: "📥 Checkout repository"
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
path: ${{ env.REPO_NAME }}
ref: ${{ env.TAG }}
- name: "📝 Fetch new sha for the release tag after pre-prelease commit"
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
ref_json=$(gh api "repos/${REPO_SLUG}/git/ref/tags/${TAG}")
type=$(jq -r '.object.type' <<<"$ref_json")
sha=$(jq -r '.object.sha' <<<"$ref_json")
if [ "$type" = "tag" ]; then
sha=$(gh api "repos/${REPO_SLUG}/git/tags/${sha}" --jq '.object.sha')
fi
echo "Found sha: $sha"
echo "SHA=${sha}" >> "$GITHUB_ENV"
- name: "📧 Print Grails Vote Email"
run: |
export DIST_SVN_REVISION=$(awk '/Last Changed Rev:/ {print $4}' dev-repo/DIST_SVN_REVISION.txt)
echo "::group::Grails PMC Vote Email"
echo ""
echo "TO:"
echo "*************************************************"
echo "dev@grails.apache.org"
echo "*************************************************"
echo ""
echo "Subject:"
echo "*************************************************"
echo "[VOTE] Release ${PROJECT_NAME} ${VERSION}"
echo "*************************************************"
echo "Body:"
echo "*************************************************"
cat ${REPO_NAME}/.github/vote_templates/staged.txt | envsubst
echo "*************************************************"
echo "::endgroup::"
release:
environment: release
name: 'VOTE SUCCEEDED - Release Artifacts'
needs: [ publish, source, upload ]
runs-on: ubuntu-24.04
steps:
- name: "📝 Establish release version"
run: echo "VERSION=${TAG#v}" >> "$GITHUB_ENV"
- name: "📥 Checkout repository"
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ env.TAG }}
- name: "⚙️ Setup SVN and Tools"
run: sudo apt-get install -y subversion subversion-tools tree gettext-base
- name: "🗳 MANUAL - Confirm Grails PMC Vote succeeded"
run: |
echo "::group::Manual Confirmation"
echo "🔎 Make sure that the vote confirmation on dev@grails.apache.org completed successfully before proceeding."
echo "::endgroup::"
- name: "✉️ MANUAL - Send Vote Result Email"
run: |
echo "::group::Manual Vote Result Email"
echo ""
echo "Send a new email or reply to the original vote email by changing the subject."
echo ""
echo "TO:"
echo "*************************************************"
echo "dev@grails.apache.org"
echo "*************************************************"
echo ""
echo "Subject:"
echo "*************************************************"
echo "[RESULT][VOTE] ${PROJECT_NAME} ${VERSION}"
echo "*************************************************"
echo ""
echo "Body:"
echo "*************************************************"
cat .github/vote_templates/vote_succeeded.txt | envsubst
echo "*************************************************"
echo "::endgroup::"
- name: "🚀 MANUAL - Release JAR files"
run: |
echo "::group::Manual Jar Promotion"
echo "Run .github/scripts/releaseJarFiles.sh ${REPO_NAME}:${VERSION} <ASF_USER>"
echo "::endgroup::"
- name: "🚀 MANUAL - Release distribution artifacts"
run: |
echo "::group::Manual ASF Artifact Promotion"
echo "Run .github/scripts/releaseDistributions.sh ${TAG} ${SVN_FOLDER} <ASF_USER>"
echo "::endgroup::"
- name: "✅ MANUAL - Update ASF Reporter"
run: |
echo "::group::Manual ASF Reporter Update"
TODAY=$(date +"%Y-%m-%d")
echo "Check email from no-reply@reporter.apache.org & update https://reporter.apache.org/addrelease.html?grails to add ${SVN_FOLDER^^}-${VERSION} as complete as of ${TODAY}"
echo "::endgroup::"
docs:
environment: docs
name: "VOTE SUCCEEDED - Publish Documentation"
needs: [publish, source, upload] # TODO Once we have confirmed `release` won't fail, add it as a dependency here
runs-on: ubuntu-24.04
permissions:
contents: write # required for gradle.properties revert
issues: write # required for milestone closing
steps:
- name: "📝 Establish release version"
run: echo "VERSION=${TAG#v}" >> "$GITHUB_ENV"
- name: "📥 Checkout repository"
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ env.TAG }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: "📅 Ensure Common Build Date" # to ensure a reproducible build
run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV"
- name: "☕️ Setup JDK"
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: ${{ env.JAVA_DISTRIBUTION }}
java-version: ${{ env.JAVA_VERSION }}
- name: "🐘 Setup Gradle"
uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
with:
cache-provider: basic # 'basic' uses the MIT-licensed, open-source cache provider; the default 'enhanced' provider (v6+) is proprietary (Gradle commercial Terms of Use)
develocity-access-key: ${{ secrets.GRAILS_DEVELOCITY_ACCESS_KEY }}
- name: "🔨 Build Documentation"
run: ./gradlew :grails-redis:groovydoc
- name: "🚀 Publish to Github Pages"
uses: apache/grails-github-actions/deploy-github-pages@asf
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GRADLE_PUBLISH_RELEASE: 'true'
SOURCE_FOLDER: plugin/build/docs
close:
name: "VOTE SUCCEEDED - Close Release"
environment: release
needs: [ publish, source, upload, docs ] # TODO Once we have confirmed `release` won't fail, add it as a dependency here
runs-on: ubuntu-24.04
permissions:
contents: write # required for gradle.properties revert
issues: write # required for milestone closing
pull-requests: write # to open PR
actions: write # in case there are pending changes to release.yml in the target branch
steps:
- name: "📝 Establish release version"
run: echo "VERSION=${TAG#v}" >> "$GITHUB_ENV"
- name: "📥 Checkout repository"
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ env.TAG }}
token: ${{ secrets.GITHUB_TOKEN }}
- name: "☕️ Setup JDK"
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
with:
distribution: ${{ env.JAVA_DISTRIBUTION }}
java-version: ${{ env.JAVA_VERSION }}
- name: "🐘 Setup Gradle"
uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.0
with:
cache-provider: basic # 'basic' uses the MIT-licensed, open-source cache provider; the default 'enhanced' provider (v6+) is proprietary (Gradle commercial Terms of Use)
develocity-access-key: ${{ secrets.GRAILS_DEVELOCITY_ACCESS_KEY }}
- name: "⚙️ Run post-release"
uses: apache/grails-github-actions/post-release@asf
- name: '🌎 MANUAL - Create Blog Post'
run: |
echo "::group::Blog Post Creation - MANUAL"
echo "Publish a blog post on https://grails.apache.org/blog/ about the new release [${VERSION}] using the repo https://github.com/apache/grails-static-website"
echo "::endgroup::"
- name: "📧 MANUAL - Send Announcement Email"
run: |
echo "::group::Announcement Email"
echo ""
echo "TO:"
echo "*************************************************"
echo "announce@apache.org, dev@grails.apache.org, users@grails.apache.org"
echo "*************************************************"
echo ""
echo "Subject:"
echo "*************************************************"
echo "[ANNOUNCE] ${PROJECT_NAME} ${VERSION}"
echo "*************************************************"
echo ""
echo "Body:"
echo "*************************************************"
cat .github/vote_templates/announce.txt | envsubst
echo "*************************************************"
echo "::endgroup::"