This is an automated email from the ASF dual-hosted git repository.

pingtimeout pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/polaris.git


The following commit(s) were added to refs/heads/main by this push:
     new 4bdb7d03f Add cancel release candidate workflow (#3321)
4bdb7d03f is described below

commit 4bdb7d03f69617bf288e773db08f2bd68c5d0b61
Author: Pierre Laporte <[email protected]>
AuthorDate: Wed Dec 24 17:49:44 2025 +0100

    Add cancel release candidate workflow (#3321)
    
    This commit fixes #3080
---
 .github/workflows/release-4-publish-release.yml    |   6 +-
 .../release-X-cancel-release-candidate.yml         | 247 +++++++++++++++++++++
 .../release-guides/semi-automated-release-guide.md |  45 ++--
 .../release-guides/github-workflow-X-detail.png    | Bin 0 -> 85886 bytes
 .../img/release-guides/github-workflow-X.png       | Bin 0 -> 197617 bytes
 5 files changed, 277 insertions(+), 21 deletions(-)

diff --git a/.github/workflows/release-4-publish-release.yml 
b/.github/workflows/release-4-publish-release.yml
index 36a0042fb..6048af104 100644
--- a/.github/workflows/release-4-publish-release.yml
+++ b/.github/workflows/release-4-publish-release.yml
@@ -83,11 +83,6 @@ jobs:
           sudo apt-get update
           sudo apt-get install -y subversion
 
-          echo "## Input Parameters" >> $GITHUB_STEP_SUMMARY
-          echo "| Parameter | Value |" >> $GITHUB_STEP_SUMMARY
-          echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY
-          echo "| Staging Repository ID | \`${staging_repo_id}\` |" >> 
$GITHUB_STEP_SUMMARY
-
       - name: Auto-determine release parameters from branch and Git state
         run: |
           source "${LIBS_DIR}/_version.sh"
@@ -179,6 +174,7 @@ jobs:
           | RC tag to promote | \`${rc_tag}\` |
           | Final release tag | \`${final_release_tag}\` |
           | Release branch | \`${current_branch}\` |
+          | Staging Repository ID | \`${staging_repo_id}\` |
           EOT
 
       - name: Copy distribution from SVN dev to release space
diff --git a/.github/workflows/release-X-cancel-release-candidate.yml 
b/.github/workflows/release-X-cancel-release-candidate.yml
new file mode 100644
index 000000000..417636574
--- /dev/null
+++ b/.github/workflows/release-X-cancel-release-candidate.yml
@@ -0,0 +1,247 @@
+#
+# 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
+#
+#   http://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.
+#
+
+# Note: This workflow uses "X" instead of a number because it's an exceptional
+# workflow. It may be run after the third workflow has been run for a given RC.
+name: Release - X - Cancel Release Candidate After Vote Failure
+
+on:
+  workflow_dispatch:
+    inputs:
+      dry_run:
+        description: 'Dry run mode (check to enable, uncheck to perform actual 
operations)'
+        required: false
+        type: boolean
+        default: true
+      staging_repository_id:
+        description: 'Nexus staging repository ID to drop (e.g., 
orgapachepolaris-1234)'
+        required: true
+        type: string
+
+jobs:
+  cancel-release-candidate:
+    name: Release - X - Cancel Release Candidate After Vote Failure
+    runs-on: ubuntu-latest
+    permissions:
+      contents: read
+
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
+        with:
+          fetch-depth: 0
+
+      - name: Setup test environment
+        uses: ./.github/actions/setup-test-env
+
+      - name: Set up environment variables
+        run: |
+          echo "RELEASEY_DIR=$(pwd)/releasey" >> $GITHUB_ENV
+          echo "LIBS_DIR=$(pwd)/releasey/libs" >> $GITHUB_ENV
+
+          echo "## Mode" >> $GITHUB_STEP_SUMMARY
+          if [[ "${{ github.event.inputs.dry_run }}" == "true" ]]; then
+            echo "DRY_RUN=1" >> $GITHUB_ENV
+            echo "‼️ DRY_RUN mode enabled - No actual changes will be made" >> 
$GITHUB_STEP_SUMMARY
+          else
+            echo "DRY_RUN=0" >> $GITHUB_ENV
+            echo "DRY_RUN mode disabled - Performing actual operations" >> 
$GITHUB_STEP_SUMMARY
+          fi
+
+          # Validate staging repository ID parameter
+          staging_repo_id="${{ github.event.inputs.staging_repository_id }}"
+          if [[ -z "${staging_repo_id}" ]]; then
+            echo "❌ Staging repository ID is required but not provided." >> 
$GITHUB_STEP_SUMMARY
+            exit 1
+          fi
+          echo "STAGING_REPOSITORY_ID=${staging_repo_id}" >> $GITHUB_ENV
+
+      - name: Install Subversion
+        run: |
+          sudo apt-get update
+          sudo apt-get install -y subversion
+
+      - name: Validate and extract version from RC tag
+        run: |
+          source "${LIBS_DIR}/_version.sh"
+
+          echo "## Parameters" >> $GITHUB_STEP_SUMMARY
+
+          # Extract the ref name from github.ref
+          # github.ref format: refs/heads/branch-name or refs/tags/tag-name
+          ref="${{ github.ref }}"
+
+          if [[ "${ref}" =~ ^refs/tags/(.+)$ ]]; then
+            # Running from a tag
+            git_tag="${BASH_REMATCH[1]}"
+          else
+            echo "❌ Workflow must be run from a release candidate tag, not a 
branch." >> $GITHUB_STEP_SUMMARY
+            echo "" >> $GITHUB_STEP_SUMMARY
+            echo "Current ref: \`${ref}\`" >> $GITHUB_STEP_SUMMARY
+            echo "" >> $GITHUB_STEP_SUMMARY
+            echo "Please select a release candidate tag (e.g., 
\`apache-polaris-1.0.0-incubating-rc0\`) from the 'Use workflow from' dropdown 
in the GitHub UI." >> $GITHUB_STEP_SUMMARY
+            exit 1
+          fi
+
+          # Validate git tag format and extract version components
+          if ! validate_and_extract_git_tag_version "${git_tag}"; then
+            echo "❌ Invalid git tag format: \`${git_tag}\`. Expected format: 
apache-polaris-x.y.z-incubating-rcN." >> $GITHUB_STEP_SUMMARY
+            exit 1
+          fi
+
+          # Export variables for next steps
+          echo "git_tag=${git_tag}" >> $GITHUB_ENV
+          echo "version_without_rc=${version_without_rc}" >> $GITHUB_ENV
+          echo "rc_number=${rc_number}" >> $GITHUB_ENV
+
+          cat <<EOT >> $GITHUB_STEP_SUMMARY
+          | Parameter | Value |
+          | --- | --- |
+          | Git tag | \`${git_tag}\` |
+          | Version | \`${version_without_rc}\` |
+          | RC number | \`${rc_number}\` |
+          | Staging Repository ID | \`${STAGING_REPOSITORY_ID}\` |
+          EOT
+
+      - name: Drop Apache Nexus staging repository
+        env:
+          NEXUS_USERNAME: ${{ secrets.APACHE_USERNAME }}
+          NEXUS_PASSWORD: ${{ secrets.APACHE_PASSWORD }}
+        run: |
+          echo "::add-mask::$NEXUS_PASSWORD"
+
+          source "${LIBS_DIR}/_exec.sh"
+
+          # Drop the staging repository using Nexus REST API
+          # The Gradle nexus-publish plugin doesn't provide a drop task, so we 
use the REST API directly
+          nexus_url="https://repository.apache.org/service/local";
+          drop_url="${nexus_url}/staging/bulk/drop"
+
+          # Create the JSON payload for dropping the repository
+          drop_payload=$(cat <<EOF
+          {
+            "data": {
+              "stagedRepositoryIds": ["${STAGING_REPOSITORY_ID}"],
+              "description": "Dropping release candidate after vote failure"
+            }
+          }
+          EOF
+          )
+
+          # Execute the drop request
+          if [[ ${DRY_RUN:-1} -ne 1 ]]; then
+            echo "Executing: Dropping staging repository 
${STAGING_REPOSITORY_ID}"
+            response=$(curl -s -w "\n%{http_code}" --max-time 60 -X POST \
+              -u "${NEXUS_USERNAME}:${NEXUS_PASSWORD}" \
+              -H "Content-Type: application/json" \
+              -d "${drop_payload}" \
+              "${drop_url}")
+
+            http_code=$(echo "$response" | tail -n1)
+            response_body=$(echo "$response" | sed '$d')
+
+            if [[ "$http_code" -ge 200 && "$http_code" -lt 300 ]]; then
+              echo "✅ Successfully dropped staging repository 
${STAGING_REPOSITORY_ID}"
+            else
+              echo "❌ Failed to drop staging repository. HTTP status: 
${http_code}"
+              echo "Response: ${response_body}"
+              exit 1
+            fi
+          else
+            echo "Dry-run, WOULD execute: curl -X POST --max-time 60 -u 
\${NEXUS_USERNAME}:\${NEXUS_PASSWORD} -H 'Content-Type: application/json' -d 
'${drop_payload}' ${drop_url}"
+          fi
+
+          cat <<EOT >> $GITHUB_STEP_SUMMARY
+          ## Nexus Staging Repository
+          ✅ Staging repository \`${STAGING_REPOSITORY_ID}\` dropped 
successfully
+          EOT
+
+      - name: Delete artifacts from Apache dist dev repository
+        env:
+          SVN_USERNAME: ${{ secrets.APACHE_USERNAME }}
+          SVN_PASSWORD: ${{ secrets.APACHE_PASSWORD }}
+        run: |
+          echo "::add-mask::$SVN_PASSWORD"
+
+          source "${LIBS_DIR}/_constants.sh"
+          source "${LIBS_DIR}/_exec.sh"
+
+          # Define URLs for artifacts and Helm chart in dist dev
+          
dev_artifacts_url="${APACHE_DIST_URL}/dev/incubator/polaris/${version_without_rc}"
+          
dev_helm_url="${APACHE_DIST_URL}/dev/incubator/polaris/helm-chart/${version_without_rc}"
+
+          # Check if artifacts directory exists and delete it
+          if svn ls --username "$SVN_USERNAME" --password "$SVN_PASSWORD" 
--non-interactive "${dev_artifacts_url}" >/dev/null 2>&1; then
+            exec_process svn rm --username "$SVN_USERNAME" --password 
"$SVN_PASSWORD" --non-interactive \
+              "${dev_artifacts_url}" \
+              -m "Cancel Apache Polaris ${version_without_rc} RC${rc_number}"
+            echo "✅ Deleted artifacts from ${dev_artifacts_url}" >> 
$GITHUB_STEP_SUMMARY
+          else
+            echo "⚠️ Artifacts directory not found at ${dev_artifacts_url}" >> 
$GITHUB_STEP_SUMMARY
+          fi
+
+          # Check if Helm chart directory exists and delete it
+          if svn ls --username "$SVN_USERNAME" --password "$SVN_PASSWORD" 
--non-interactive "${dev_helm_url}" >/dev/null 2>&1; then
+            exec_process svn rm --username "$SVN_USERNAME" --password 
"$SVN_PASSWORD" --non-interactive \
+              "${dev_helm_url}" \
+              -m "Cancel Apache Polaris Helm chart ${version_without_rc} 
RC${rc_number}"
+            echo "✅ Deleted Helm chart from ${dev_helm_url}" >> 
$GITHUB_STEP_SUMMARY
+          else
+            echo "⚠️ Helm chart directory not found at ${dev_helm_url}" >> 
$GITHUB_STEP_SUMMARY
+          fi
+
+          cat <<EOT >> $GITHUB_STEP_SUMMARY
+          ## Distribution Cleanup
+          Artifacts and Helm chart removed from dist dev repository
+          EOT
+
+      - name: Generate vote failure email
+        run: |
+          source "${LIBS_DIR}/_version.sh"
+
+          cat <<EOT >> $GITHUB_STEP_SUMMARY
+          # Vote Failure Email
+
+          ## Subject
+          [RESULT][VOTE] Release Apache Polaris ${version_without_rc} 
(rc${rc_number})
+
+          ## Body
+          Hello everyone,
+
+          Thanks to all who participated in the vote for Release Apache 
Polaris ${version_without_rc} (rc${rc_number}).
+
+          The vote failed due to [REASON - TO BE FILLED BY RELEASE MANAGER].
+
+          A new release candidate will be proposed soon once the issues are 
addressed.
+
+          Thanks,
+          EOT
+
+          cat <<EOT >> $GITHUB_STEP_SUMMARY
+
+          ## Summary
+          🔄 Release candidate cancellation completed:
+
+          | Component | Status |
+          | --- | --- |
+          | Nexus staging repository | ✅ Dropped |
+          | Distribution artifacts (dist dev) | ✅ Deleted |
+          | Helm chart (dist dev) | ✅ Deleted |
+          EOT
+
diff --git 
a/site/content/community/release-guides/semi-automated-release-guide.md 
b/site/content/community/release-guides/semi-automated-release-guide.md
index 5d85832ee..f44c844c1 100644
--- a/site/content/community/release-guides/semi-automated-release-guide.md
+++ b/site/content/community/release-guides/semi-automated-release-guide.md
@@ -30,6 +30,8 @@ params:
 ## Overview
 The steps performed in the [Manual Release Guide](../manual-release-guide/) 
have been automated to a large extent. This semi-automated release guide 
outlines the workflows that can be used to perform a release with little manual 
intervention.
 
+_Note that all screenshots in this page are for illustration purposes only. 
The actual repository name, version numbers, etc. may be different._
+
 ## Dry-run mode
 Each of the Github Workflows that have been developed comes with a `dry-run` 
mode. It is enabled ticking the `Dry run mode` checkbox before starting the 
workflow. When enabled, the workflow will not perform any destructive action 
(e.g. tag creation, branch deletion, etc.) but instead print out the commands 
that would have been executed.
 
@@ -98,7 +100,7 @@ If the first release candidate is rejected, additional code 
changes may be neede
 
 Each code change that should be added to the release branch must be 
cherry-picked from the main branch and proposed in a dedicated pull request. 
The pull request must be reviewed and approved before being merged. This step 
is mandatory so that Github runs the CI checks. The subsequent workflows will 
verify that those checks passed.
 
-Once the pull requests have been merged, run the second workflow again to 
create a new RC tag. The workflow will automatically determine the next RC 
number.
+Once the pull requests have been merged, run the [`Release - 2 - Update 
version and Changelog for Release 
Candidate`](https://github.com/apache/polaris/actions/workflows/release-2-update-release-candidate.yml)
 workflow again to create a new RC tag. The workflow will automatically 
determine the next RC number.
 
 ## Build and publish release artifacts
 The third Github workflow to run is [`Release - 3 - Build and publish release 
artifacts`](https://github.com/apache/polaris/actions/workflows/release-3-build-and-publish-artifacts.yml).
 This workflow will:
@@ -173,23 +175,19 @@ The next steps depend on the vote result.
 
 ## Close the vote thread
 ### If the vote failed
-When a release candidate is rejected, reply with the vote result:
+If the vote failed, run the Github workflow [`Release - X - Cancel Release 
Candidate After Vote 
Failure`](https://github.com/apache/polaris/actions/workflows/release-X-cancel-release-candidate.yml).
 This workflow will:
+* Drop the Apache Nexus staging repository
+* Delete the release artifacts (including Helm Chart) from the Apache dist dev 
repository
+* Prepare an e-mail template to notify the community of the vote result
 
-```
-[RESULT][VOTE] Release Apache Polaris [major].[minor].[patch] (rc[N])
-```
+![Screenshot of the cancel RC workflow for 
1.3.0-incubating](/img/release-guides/github-workflow-X.png "Screenshot of the 
cancel RC workflow for 1.3.0-incubating")
 
-```
-Hello everyone,
-
-Thanks to all who participated in the vote for Release Apache Polaris 
[major].[minor].[patch] (rc[N]).
+The run details page contains a recap of the main information, with all the 
steps that were executed.
+It also contains the e-mail template to notify the community of the vote 
result.
+Ensure to replace the `[REASON - TO BE FILLED BY RELEASE MANAGER]` placeholder 
with the actual reason for the vote failure.
+Then send the e-mail to the Polaris dev mailing list.
 
-The vote failed due to [reason].
-
-A new release candidate will be proposed soon once the issues are addressed.
-
-Thanks,
-```
+![Screenshot of a detailed run of the cancel RC workflow for 
1.3.0-incubating](/img/release-guides/github-workflow-X-detail.png "Screenshot 
of a detailed run of the cancel RC workflow for 1.3.0-incubating")
 
 ### If the vote passed
 When the release candidate vote passes, send a new e-mail with the vote result:
@@ -274,7 +272,8 @@ The next steps depend on the vote result.
 
 ## Close the vote thread on the Incubator general mailing list
 ### If the vote failed
-When a release candidate is rejected, reply in the same thread with the vote 
result.
+When a release candidate is rejected during the IPMC vote, you need to send 
two e-mails to inform the community of the vote result.
+First, reply in the same thread (in the general Incubator mailing list) with 
the vote result.
 
 ```
 Hello everyone,
@@ -286,6 +285,20 @@ The vote failed due to [reason].
 Thanks,
 ```
 
+Then, run the Github workflow [`Release - X - Cancel Release Candidate After 
Vote 
Failure`](https://github.com/apache/polaris/actions/workflows/release-X-cancel-release-candidate.yml).
 This workflow will:
+* Drop the Apache Nexus staging repository
+* Delete the release artifacts (including Helm Chart) from the Apache dist dev 
repository
+* Prepare an e-mail template to notify the community of the vote result
+
+![Screenshot of the cancel RC workflow for 
1.3.0-incubating](/img/release-guides/github-workflow-X.png "Screenshot of the 
cancel RC workflow for 1.3.0-incubating")
+
+The run details page contains a recap of the main information, with all the 
steps that were executed.
+It also contains the e-mail template to notify the community of the vote 
result.
+Ensure to replace the `[REASON - TO BE FILLED BY RELEASE MANAGER]` placeholder 
with the actual reason for the vote failure.
+Then send the e-mail to the Polaris dev mailing list.
+
+![Screenshot of a detailed run of the cancel RC workflow for 
1.3.0-incubating](/img/release-guides/github-workflow-X-detail.png "Screenshot 
of a detailed run of the cancel RC workflow for 1.3.0-incubating")
+
 ### If the vote passed
 When the release candidate vote passes, send a new e-mail with the vote result:
 
diff --git a/site/static/img/release-guides/github-workflow-X-detail.png 
b/site/static/img/release-guides/github-workflow-X-detail.png
new file mode 100644
index 000000000..13ee5b177
Binary files /dev/null and 
b/site/static/img/release-guides/github-workflow-X-detail.png differ
diff --git a/site/static/img/release-guides/github-workflow-X.png 
b/site/static/img/release-guides/github-workflow-X.png
new file mode 100644
index 000000000..47e7381d0
Binary files /dev/null and 
b/site/static/img/release-guides/github-workflow-X.png differ

Reply via email to