| name: Release | |
| on: | |
| release: | |
| types: [published] | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| JAVA_DISTRIBUTION: liberica | |
| JAVA_VERSION: 17.0.15 | |
| PROJECT_DESC: These GitHub actions assist with automating common publishing tasks in Grails projects. | |
| PROJECT_NAME: Apache Grails GitHub Actions | |
| REPO_NAME: ${{ github.event.repository.name }} | |
| REPO_SLUG: ${{ github.repository }} | |
| SVN_FOLDER: actions | |
| TAG: ${{ github.event.release.tag_name }} | |
| TARGET_BRANCH: ${{ github.event.release.target_commitish }} | |
| VERSION: will be computed in each job | |
| concurrency: | |
| group: release-pipeline-${{ github.event.release.target_commitish }} | |
| cancel-in-progress: false | |
| jobs: | |
| test: | |
| name: 'Tests' | |
| runs-on: ubuntu-22.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@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| ref: ${{ env.TAG }} | |
| path: ${{ env.REPO_NAME }} | |
| token: ${{ secrets.GITHUB_TOKEN }} # This should not be needed as ${{ github.token }} is the default, but there have been issues with it. | |
| - name: "☕️ Setup JDK" | |
| uses: actions/setup-java@77dd5b2ce225ea11469928ac317850245a74ae78 # v6.2.0 | |
| with: | |
| distribution: ${{ env.JAVA_DISTRIBUTION }} | |
| java-version: ${{ env.JAVA_VERSION }} | |
| - name: "🐘 Setup Gradle" | |
| uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.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: "🔨 Test project" | |
| working-directory: '${{ env.REPO_NAME }}/tests' | |
| run: > | |
| ./gradlew test | |
| --continue --stacktrace | |
| --rerun-tasks | |
| source: | |
| name: "Source Distribution" | |
| needs: test | |
| permissions: | |
| contents: write | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: "📝 Establish release version" | |
| run: echo "VERSION=${TAG#v}" >> "$GITHUB_ENV" | |
| - name: "📥 Checkout repository" | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| ref: ${{ env.TAG }} | |
| path: ${{ env.REPO_NAME }} | |
| 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 | |
| working-directory: ${{ env.REPO_NAME }} | |
| run: echo "SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)" >> "$GITHUB_ENV" | |
| - name: "Generate Build Date file" | |
| working-directory: ${{ env.REPO_NAME }} | |
| run: echo "$SOURCE_DATE_EPOCH" >> BUILD_DATE | |
| - name: "🗑️ Remove unnecessary files" | |
| working-directory: ${{ env.REPO_NAME }} | |
| run: | | |
| rm -f tests/gradle/wrapper/gradle-wrapper.jar | |
| rm -f tests/gradle/wrapper/gradle-wrapper.properties | |
| rm -f tests/gradlew | |
| rm -f tests/gradlew.bat | |
| rm -f .asf.yaml | |
| - name: "📅 Ensure source files use common date" | |
| run: 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@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 | |
| 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 | |
| upload: | |
| name: "Upload Distributions to dist.apache.org" | |
| needs: [ test, source ] | |
| runs-on: ubuntu-22.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@efb35369e0ad2afab669f228072c1b0d510eae64 # v3.0.3 | |
| with: | |
| tag_name: ${{ env.TAG }} | |
| files: dev-repo/DIST_SVN_REVISION.txt | |
| - name: "📥 Checkout repository" | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| path: ${{ env.REPO_NAME }} | |
| ref: ${{ env.TAG }} | |
| - name: "📧 Print Grails Vote Email" | |
| env: | |
| VERSION_COMMIT_ID: ${{ github.sha }} | |
| 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: [ test, source, upload ] | |
| runs-on: ubuntu-22.04 | |
| steps: | |
| - name: "📝 Establish release version" | |
| run: echo "VERSION=${TAG#v}" >> "$GITHUB_ENV" | |
| - name: "📥 Checkout repository" | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| ref: ${{ env.TAG }} | |
| - name: "🗳 MANUAL - Grails PMC Vote Confirmation" | |
| 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 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::" | |
| - 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 ${{ needs.test.outputs.release_version }} using the repo https://github.com/apache/grails-static-website" | |
| echo "::endgroup::" | |
| - name: "📧 MANUAL - Send Announcement Email" | |
| env: | |
| PREVIOUS_VERSION: 'TODO_PREVIOUS_VERSION' | |
| 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::" | |
| - name: "🌎 MANUAL - Update Version on Grails Website" | |
| run: | | |
| echo "::group::Update Version on Grails Website" | |
| echo "Update the released version [${VERSION}] on the Grails Website" | |
| echo "https://github.com/apache/grails-static-website/actions/workflows/release-companion.yml" | |
| echo "::endgroup::" |