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])
-```
+
-```
-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,
-```
+
### 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
+
+
+
+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.
+
+
+
### 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