diff --git a/.asf.yaml b/.asf.yaml index 41f2c9edf..cb2d7819a 100644 --- a/.asf.yaml +++ b/.asf.yaml @@ -14,3 +14,10 @@ github: - id: jdaugherty type: User wait_timer: 0 + close: + required_reviewers: + - id: grails-committers + type: Team + - id: jdaugherty + type: User + wait_timer: 0 diff --git a/.github/scripts/releaseDistributions.sh b/.github/scripts/releaseDistributions.sh new file mode 100755 index 000000000..4931ed997 --- /dev/null +++ b/.github/scripts/releaseDistributions.sh @@ -0,0 +1,83 @@ +#!/bin/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. +# + +# ./releaseDistributions.sh + +set -euo pipefail + +if [[ $# -ne 3 ]]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +RELEASE_TAG="$1" +RELEASE_VERSION="${RELEASE_TAG#v}" +SVN_USER="$2" +SVN_PASS="$3" +RELEASE_ROOT="https://dist.apache.org/repos/dist/release/incubator/grails/spring-security" +DEV_ROOT="https://dist.apache.org/repos/dist/dev/incubator/grails/spring-security" + +if [[ -z "${RELEASE_TAG}" ]]; then + echo "❌ ERROR: Release Tag must not be empty." >&2 + exit 1 +fi +if [[ -z "${SVN_USER}" ]]; then + echo "❌ ERROR: Username must not be empty." >&2 + exit 1 +fi +if [[ -z "${SVN_PASS}" ]]; then + echo "❌ ERROR: Password must not be empty." >&2 + exit 1 +fi + +svn_flags=(--non-interactive --trust-server-cert --username "${SVN_USER}" --password "${SVN_PASS}") + +svn_exists() { + local url="$1" + svn ls "${svn_flags[@]}" --depth=empty "${url}" >/dev/null 2>&1 +} + +old_release_folder="$(svn ls "${svn_flags[@]}" "${RELEASE_ROOT}" | awk -F/ 'NF{print $1; exit}')" +if [[ -n "${old_release_folder}" ]]; then + PRIOR_RELEASE_URL="${RELEASE_ROOT}/${old_release_folder}" + echo "đŸ—‘ī¸ Deleting old release folder: ${PRIOR_RELEASE_URL}" + svn rm "${svn_flags[@]}" -m "Remove previous release ${old_release_folder}" "${PRIOR_RELEASE_URL}" + echo "✅ Deleted old release folder" +else + echo "â„šī¸ No existing release subfolder found under ${RELEASE_ROOT}" +fi + +DEV_VERSION_URL="$DEV_ROOT/${RELEASE_VERSION}" +RELEASE_VERSION_URL="$RELEASE_ROOT/${RELEASE_VERSION}" + +if ! svn_exists "${DEV_VERSION_URL}"; then + echo "❌ ERROR: dev folder for ${RELEASE_VERSION} does not exist at: ${DEV_VERSION_URL}" >&2 + exit 2 +fi + +if svn_exists "${RELEASE_VERSION_URL}"; then + echo "❌ ERROR: release folder for ${RELEASE_VERSION} already exists at: ${RELEASE_VERSION_URL}" >&2 + exit 3 +fi + +echo "🚀 Promoting ${DEV_VERSION_URL} -> ${RELEASE_VERSION_URL}" +svn mv "${svn_flags[@]}" -m "Promote Apache Grails (incubating) ${RELEASE_VERSION} from dev to release" "${DEV_VERSION_URL}" "${RELEASE_VERSION_URL}" +echo "✅ Promoted" diff --git a/.github/scripts/releaseJarFiles.sh b/.github/scripts/releaseJarFiles.sh new file mode 100755 index 000000000..8421782d7 --- /dev/null +++ b/.github/scripts/releaseJarFiles.sh @@ -0,0 +1,141 @@ +#!/bin/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. +# + +# ./releaseJarFiles.sh + +set -euo pipefail + +if [[ $# -ne 3 ]]; then + echo "Usage: $0 " >&2 + exit 1 +fi + +NEXUS_URL="https://repository.apache.org" +STAGING_DESCRIPTION="$1" +NEXUS_USER="$2" +NEXUS_PASS="$3" + +if [[ -z "${STAGING_DESCRIPTION}" ]]; then + echo "ERROR: Staging Description must not be empty." >&2 + exit 1 +fi +if [[ -z "${NEXUS_USER}" ]]; then + echo "ERROR: Username must not be empty." >&2 + exit 1 +fi +if [[ -z "${NEXUS_PASS}" ]]; then + echo "ERROR: Password must not be empty." >&2 + exit 1 +fi + +nexusApi() { + local request_method="$1"; shift + local path="$1"; shift + curl -fsS -u "${NEXUS_USER}:${NEXUS_PASS}" \ + -H 'Accept: application/json' \ + -H 'Content-Type: application/json' \ + -X "${request_method}" "${NEXUS_URL}/service/local/${path}" "$@" +} + +wait_for_promotion() { + local repoId="$1" + local timeout_s="${2:-600}" # default 10 minutes + local interval_s="${3:-3}" + local started + started="$(date +%s)" + + echo "Waiting for release promotion to complete (timeout ${timeout_s}s)â€Ļ" + + while :; do + # 1) If any ERROR appears in activity, fail fast + act="$(nexusApi GET "/staging/repository/${repoId}/activity" || true)" + if [[ -n "$act" ]]; then + err_count="$(jq -r '[.. | objects? | select(has("severity")) | select(.severity=="ERROR")] | length' <<<"$act" 2>/dev/null || echo 0)" + if [[ "$err_count" != "0" ]]; then + echo "ERROR: Staging activity contains failure(s). Aborting." >&2 + # Optionally dump recent relevant lines: + jq -r '.. | objects? | select(has("severity")) | "\(.severity): \(.name // "event") - \(.message // "")"' <<<"$act" || true + return 1 + fi + fi + + # 2) Check transitioning flag — when false after promote, action is done + trans="$(nexusApi GET '/staging/profile_repositories' \ + | jq -r --arg r "$repoId" '.data[]? | select(.repositoryId==$r) | .transitioning' 2>/dev/null || echo "true")" + + if [[ "$trans" == "false" ]]; then + # sanity: make sure we actually saw some "release/promote" activity; otherwise keep waiting a bit + if [[ -n "$act" ]]; then + # did we see any promote/release-ish step? + saw_promote="$(jq -r ' + [ .. | objects? | .name? // empty | ascii_downcase + | select(test("release|promote|finish")) ] | length' <<<"$act" 2>/dev/null || echo 0)" + if [[ "$saw_promote" -gt 0 ]]; then + echo "Promotion appears complete." + return 0 + fi + fi + fi + + # timeout? + now="$(date +%s)" + if (( now - started >= timeout_s )); then + echo "ERROR: Timed out waiting for promotion to complete." >&2 + # Show a short summary to aid debugging + if [[ -n "$act" ]]; then + echo "--- Recent activity snapshot ---" + jq -r '.. | objects? | select(has("severity") or has("name")) | "\(.severity // "")\t\(.name // "")\t\(.message // "")"' <<<"$act" | tail -n 20 || true + fi + return 1 + fi + + sleep "$interval_s" + done +} + +repos_json="$(nexusApi GET '/staging/profile_repositories')" +repoId="$(jq -r --arg d "${STAGING_DESCRIPTION}" '.data[] | select(.description==$d) | .repositoryId' <<<"${repos_json}")" +profileId="$(jq -r --arg d "${STAGING_DESCRIPTION}" '.data[] | select(.description==$d) | .profileId' <<<"${repos_json}")" +state="$(jq -r --arg d "${STAGING_DESCRIPTION}" '.data[] | select(.description==$d) | .type' <<<"${repos_json}")" + +if [[ -z "${repoId}" || -z "${profileId}" ]]; then + echo "ERROR: No staged repository found with description: ${STAGING_DESCRIPTION}" >&2 + exit 2 +fi +echo "Found staged repo: ${repoId} (profile: ${profileId}, state: ${state})" +if [[ "${state}" == "open" ]]; then + echo "ERROR: Staged Repo is not closed: ${STAGING_DESCRIPTION}" >&2 + exit 3 +fi + +if [[ "${state}" == "closed" ]]; then + echo "Promoting (release) ${repoId}â€Ļ" + nexusApi POST "/staging/profiles/${profileId}/promote" \ + --data "$(jq -n --arg r "${repoId}" --arg d "${STAGING_DESCRIPTION}" '{data:{stagedRepositoryId:$r,description:$d}}')" +fi + +wait_for_promotion "$repoId" 600 3 + +echo "Dropping staging repository ${repoId}â€Ļ" +nexusApi POST "/staging/profiles/${profileId}/drop" \ + --data "$(jq -n --arg r "$repoId" --arg d "${STAGING_DESCRIPTION}" '{data:{stagedRepositoryId:$r,description:$d}}')" + +echo "Done. Released ${repoId}." \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bbc2c88ea..e758346cb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,8 +32,8 @@ jobs: runs-on: ubuntu-24.04 outputs: release_version: ${{ steps.release_version.outputs.value }} - extract_repository_name: ${{ steps.extract_repository_name.outputs.repository_name }} commit_hash: ${{ steps.commit_hash.outputs.value }} + extract_repository_name: ${{ steps.extract_repository_name.outputs.repository_name }} steps: - name: "📝 Store the current release version" id: release_version @@ -132,11 +132,11 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} source: # to ensure we never publish any build artifacts, run the source distribution as a separate build workflow - name: "Source Distribution" + name: "Create Source Distribution" needs: publish permissions: contents: write - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - name: "đŸ“Ĩ Checkout repository" uses: actions/checkout@v4 @@ -151,28 +151,28 @@ jobs: rm -f ${{ needs.publish.outputs.extract_repository_name }}/gradlew rm -f ${{ needs.publish.outputs.extract_repository_name }}/gradlew.bat rm -f ${{ needs.publish.outputs.extract_repository_name }}/.asf.yaml - - name: "Download CHECKSUMS.txt and rename to CHECKSUMS" + - name: "đŸ“Ĩ Download CHECKSUMS.txt and rename to CHECKSUMS" + working-directory: '${{ needs.publish.outputs.extract_repository_name }}' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - cd ${{ needs.publish.outputs.extract_repository_name }} release_url=$(gh release view v${{ needs.publish.outputs.release_version }} --json assets --repo ${{ github.repository }} --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" + - name: "đŸ“Ĩ Download PUBLISHED_ARTIFACTS.txt and rename to PUBLISHED_ARTIFACTS" + working-directory: '${{ needs.publish.outputs.extract_repository_name }}' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - cd ${{ needs.publish.outputs.extract_repository_name }} release_url=$(gh release view v${{ needs.publish.outputs.release_version }} --json assets --repo ${{ github.repository }} --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" + - name: "đŸ“Ĩ Download BUILD_DATE.txt and rename to BUILD_DATE" + working-directory: '${{ needs.publish.outputs.extract_repository_name }}' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - cd ${{ needs.publish.outputs.extract_repository_name }} release_url=$(gh release view v${{ needs.publish.outputs.release_version }} --json assets --repo ${{ github.repository }} --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" + - name: "📅 Ensure source files use common date" run: | SOURCE_DATE_EPOCH=$(cat ${{ needs.publish.outputs.extract_repository_name }}/BUILD_DATE) find . -depth \( -type f -o -type d \) -exec touch -d "@${SOURCE_DATE_EPOCH}" {} + @@ -202,28 +202,41 @@ jobs: apache-${{ needs.publish.outputs.extract_repository_name }}-${{ needs.publish.outputs.release_version }}-incubating-src.zip apache-${{ needs.publish.outputs.extract_repository_name }}-${{ needs.publish.outputs.release_version }}-incubating-src.zip.sha512 apache-${{ needs.publish.outputs.extract_repository_name }}-${{ needs.publish.outputs.release_version }}-incubating-src.zip.asc - - name: "Remove CHECKSUMS.txt asset from release" + - name: "đŸ—‘ī¸ Remove CHECKSUMS.txt asset from release" + working-directory: '${{ needs.publish.outputs.extract_repository_name }}' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -e - cd ${{ needs.publish.outputs.extract_repository_name }} - gh release --repo ${{ github.repository }} delete-asset v${{ needs.publish.outputs.release_version }} CHECKSUMS.txt --yes - - name: "Remove BUILD_DATE.txt asset from release" + gh release delete-asset \ + v${{ needs.publish.outputs.release_version }} \ + CHECKSUMS.txt \ + --repo ${{ github.repository }} \ + --yes + - name: "đŸ—‘ī¸ Remove BUILD_DATE.txt asset from release" + working-directory: '${{ needs.publish.outputs.extract_repository_name }}' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -e - cd ${{ needs.publish.outputs.extract_repository_name }} - gh release --repo ${{ github.repository }} delete-asset v${{ needs.publish.outputs.release_version }} BUILD_DATE.txt --yes - - name: "Remove PUBLISHED_ARTIFACTS.txt asset from release" + gh release delete-asset \ + v${{ needs.publish.outputs.release_version }} \ + BUILD_DATE.txt \ + --repo ${{ github.repository }} \ + --yes + - name: "đŸ—‘ī¸ Remove PUBLISHED_ARTIFACTS.txt asset from release" + working-directory: '${{ needs.publish.outputs.extract_repository_name }}' env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | set -e - cd ${{ needs.publish.outputs.extract_repository_name }} - gh release --repo ${{ github.repository }} delete-asset v${{ needs.publish.outputs.release_version }} PUBLISHED_ARTIFACTS.txt --yes + gh release delete-asset \ + v${{ needs.publish.outputs.release_version }} \ + PUBLISHED_ARTIFACTS.txt \ + --repo ${{ github.repository }} \ + --yes upload: + name: "Upload Source Distribution" needs: [ publish, source ] runs-on: ubuntu-24.04 permissions: @@ -232,11 +245,11 @@ jobs: SVN_USERNAME: ${{ secrets.SVC_DIST_GRAILS_USERNAME }} SVN_PASSWORD: ${{ secrets.SVC_DIST_GRAILS_PASSWORD }} steps: - - name: "Output Agent IP" # in the event RAO blocks this agent, this can be used to debug it + - 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: "Setup SVN and Tools" + - name: "âš™ī¸ Setup SVN and Tools" run: sudo apt-get install -y subversion subversion-tools tree gettext-base - - name: "Ensure grails dev folder exists" + - name: "👀 Ensure grails dev folder exists" run: | set -e @@ -248,7 +261,7 @@ jobs: mkdir https://dist.apache.org/repos/dist/dev/incubator/grails \ -m "Create 'grails' dev folder" fi - - name: "Ensure grails spring-security folder exists" + - name: "👀 Ensure grails spring-security folder exists" run: | set -e @@ -260,10 +273,10 @@ jobs: mkdir https://dist.apache.org/repos/dist/dev/incubator/grails/spring-security \ -m "Create 'grails spring-security' dev folder" fi - - name: "Checkout dev repo" + - name: "đŸ“Ĩ Checkout dev repo" run: | svn checkout --username "$SVN_USERNAME" --password "$SVN_PASSWORD" --non-interactive https://dist.apache.org/repos/dist/dev/incubator/grails/spring-security dev-repo - - name: "Remove existing dev version" + - name: "đŸ—‘ī¸ Remove existing dev version" run: | export VERSION="${{ needs.publish.outputs.release_version }}" cd dev-repo @@ -273,7 +286,7 @@ jobs: else echo "No existing dev version $VERSION to remove" fi - - name: "Fetch source distributions" + - name: "đŸ“Ĩ Fetch source distributions" run: | export TAG="v${{ needs.publish.outputs.release_version }}" export VERSION="${{ needs.publish.outputs.release_version }}" @@ -295,12 +308,12 @@ jobs: svn add $VERSION --force svn commit -m "Upload grails distribution files for $VERSION" --username "$SVN_USERNAME" --password "$SVN_PASSWORD" --non-interactive pwd - - name: "Store Distribution SVN revision" + - name: "💾 Store Distribution SVN revision in a file" run: | export VERSION="${{ needs.publish.outputs.release_version }}" cd dev-repo svn info $VERSION > "DIST_SVN_REVISION.txt" - - name: "Upload Distribution SVN revision" + - name: "📤 Upload the Distribution SVN revision file" uses: softprops/action-gh-release@v2 with: files: dev-repo/DIST_SVN_REVISION.txt @@ -311,28 +324,31 @@ jobs: with: token: ${{ secrets.GITHUB_TOKEN }} ref: v${{ needs.publish.outputs.release_version }} - path: "${{ needs.publish.outputs.extract_repository_name }}" - - name: 'Initial Vote Email' + path: ${{ needs.publish.outputs.extract_repository_name }} + - name: "📧 Print Grails Vote Email" env: VERSION: ${{ needs.publish.outputs.release_version }} VERSION_COMMIT_ID: ${{ needs.publish.outputs.commit_hash }} run: | export DIST_SVN_REVISION=$(awk '/Last Changed Rev:/ {print $4}' dev-repo/DIST_SVN_REVISION.txt) - + + echo "::group::Grails PPMC Vote Email" echo "*************************************************" echo "Subject: [VOTE] Release Apache Grails (incubating) Spring Security Plugin ${VERSION}" echo "*************************************************" echo "Body:" echo "*************************************************" cat ${{ needs.publish.outputs.extract_repository_name }}/.github/vote_templates/staged.txt | envsubst - echo "*************************************************" - - name: 'Groovy Vote Email' + echo "*************************************************" + echo "::endgroup::" + - name: '📧 Print Groovy Vote Email' env: VERSION: ${{ needs.publish.outputs.release_version }} VERSION_COMMIT_ID: ${{ needs.publish.outputs.commit_hash }} run: | export DIST_SVN_REVISION=$(awk '/Last Changed Rev:/ {print $4}' dev-repo/DIST_SVN_REVISION.txt) - + + echo "::group::Grails PPMC Vote Email" echo "*************************************************" echo "Subject: [VOTE] Approval of Apache Grails (incubating) Spring Security Plugin ${VERSION} release by Groovy PMC" echo "*************************************************" @@ -340,26 +356,49 @@ jobs: echo "*************************************************" cat ${{ needs.publish.outputs.extract_repository_name }}/.github/vote_templates/groovy_pmc.txt | envsubst echo "*************************************************" - - name: 'Announcement Email' - env: - VERSION: ${{ needs.publish.outputs.release_version }} - VERSION_COMMIT_ID: ${{ needs.publish.outputs.commit_hash }} - PREVIOUS_VERSION: 'TODO_PREVIOUS_VERSION' + echo "::endgroup::" + release: + environment: release + name: 'VOTE SUCCEEDED - Release Artifacts' + needs: [ publish, source, upload ] + 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: "Setup SVN and Tools" + run: sudo apt-get install -y subversion subversion-tools tree gettext-base + - name: "đŸ—ŗ Grails PPMC Vote Confirmation - MANUAL" run: | - export DIST_SVN_REVISION=$(awk '/Last Changed Rev:/ {print $4}' dev-repo/DIST_SVN_REVISION.txt) - - echo "*************************************************" - echo "Subject: [ANNOUNCE] Apache Grails (incubating) Spring Security Plugin ${VERSION}" - echo "*************************************************" - echo "Body:" - echo "*************************************************" - cat ${{ needs.publish.outputs.extract_repository_name }}/.github/vote_templates/announce.txt | envsubst - echo "*************************************************" + echo "::group::Manual Confirmation" + echo "🔎 This step is a placeholder that the vote confirmation on dev@grails.apache.org completed successfully." + echo "::endgroup::" + - name: "đŸ—ŗ Groovy PMC Vote Confirmation - MANUAL" + run: | + echo "::group::Manual Confirmation" + echo "🔎 This step is a placeholder that the vote confirmation on dev@grails.apache.org completed successfully." + echo "::endgroup::" + - name: "🚀 Release JAR files - MANUAL" + run: | + echo "::group::Manual Jar Promotion" + echo "Run .github/scripts/releaseJarFiles.sh 'v${{ needs.publish.outputs.release_version }}' '${{ needs.publish.outputs.extract_repository_name }}:${{ needs.publish.outputs.release_version }}' ASF_USER ASF_PASS" + echo "::endgroup::" + - name: "🚀 Release distribution artifacts - MANUAL" + run: | + echo "::group::Manual ASF Artifact Promotion" + echo "Run github/scripts/releaseDistributions.sh 'v${{ needs.publish.outputs.release_version }}' ASF_USER ASF_PASS" + echo "::endgroup::" + - name: "✅ Update ASF Reporter - MANUAL" + run: | + echo "::group::Manual ASF Reporter Update" + TODAY=$(date +"%Y-%m-%d") + echo "Check email & update https://reporter.apache.org to mark the release ${{ needs.publish.outputs.release_version }} as complete as of ${TODAY}" + echo "Note: this is a place holder; currently this is not possible since Groovy sponsors us instead of the incubator PMC" + echo "::endgroup::" docs: environment: docs - name: "Publish Documentation" - needs: [publish, source, upload] - runs-on: ubuntu-latest + 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 @@ -391,11 +430,11 @@ jobs: GRADLE_PUBLISH_RELEASE: 'true' SOURCE_FOLDER: build/docs VERSION: ${{ needs.publish.outputs.release_version }} - release: - name: "Close Release" + close: + name: "VOTE SUCCEEDED - Close Release" environment: release - needs: [ publish, source, upload, docs ] - runs-on: ubuntu-latest + 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 @@ -418,3 +457,25 @@ jobs: develocity-access-key: ${{ secrets.GRAILS_DEVELOCITY_ACCESS_KEY }} - name: "âš™ī¸ Run post-release" uses: apache/grails-github-actions/post-release@asf + - name: '🌎 Create Blog Post - MANUAL' + run: | + echo "::group::Blog Post Creation - MANUAL" + echo "Publish a blog post on https://grails.apache.org/blog/ about the new release ${{ needs.publish.outputs.release_version }} using the repo https://github.com/apache/grails-static-website" + echo "::endgroup::" + - name: 'Announcement Email' + env: + VERSION: ${{ needs.publish.outputs.release_version }} + VERSION_COMMIT_ID: ${{ needs.publish.outputs.commit_hash }} + PREVIOUS_VERSION: 'TODO_PREVIOUS_VERSION' + run: | + export DIST_SVN_REVISION=$(awk '/Last Changed Rev:/ {print $4}' dev-repo/DIST_SVN_REVISION.txt) + + echo "::group::Announcement Email" + echo "*************************************************" + echo "Subject: [ANNOUNCE] Apache Grails (incubating) Spring Security Plugin ${VERSION}" + echo "*************************************************" + echo "Body:" + echo "*************************************************" + cat ${{ needs.publish.outputs.extract_repository_name }}/.github/vote_templates/announce.txt | envsubst + echo "*************************************************" + echo "::endgroup::"