diff --git a/.github/workflows/release-4-publish-release.yml b/.github/workflows/release-4-publish-release.yml index 36a0042fb0..6048af1049 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 0000000000..417636574c --- /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 <> $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 <> $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 <> $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 <> $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 <> $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 5d85832ee2..f44c844c19 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 0000000000..13ee5b177f 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 0000000000..47e7381d09 Binary files /dev/null and b/site/static/img/release-guides/github-workflow-X.png differ