You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@opendal.apache.org by xu...@apache.org on 2026/09/07 09:45:25 UTC
(opendal) 01/01: fix(ci): dispatch weekly RC builds and notify release managers
This is an automated email from the ASF dual-hosted git repository.
Xuanwo pushed a commit to branch xuanwo/weekly-release-handoff
in repository https://gitbox.apache.org/repos/asf/opendal.git
commit 93119984c8eeeab24354f2bfe0107b02a2495382
Author: Xuanwo <gi...@xuanwo.io>
AuthorDate: Mon Sep 7 17:45:07 2026 +0800
fix(ci): dispatch weekly RC builds and notify release managers
---
.github/workflows/docs.yml | 8 +++-
.github/workflows/release_ruby.yml | 5 ++-
.github/workflows/weekly_release.yml | 80 ++++++++++++++++++++++++++++++++++++
website/community/release/weekly.md | 22 ++++++++--
4 files changed, 107 insertions(+), 8 deletions(-)
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
index c1e8396e7b..cf0e1a59a3 100644
--- a/.github/workflows/docs.yml
+++ b/.github/workflows/docs.yml
@@ -37,6 +37,10 @@ on:
paths: *paths
workflow_dispatch:
inputs:
+ deploy-nightlies:
+ description: "Deploy built documentation to nightlies"
+ type: boolean
+ default: true
release_version:
description: "Release tag to deploy to nightlies"
required: true
@@ -642,7 +646,7 @@ jobs:
OPENDAL_WEBSITE_NOT_LATEST: true
- name: Deploy to nightlies for tagged version
- if: ${{ (startsWith(github.ref, 'refs/tags/') && !contains(github.ref, 'rc')) || github.event_name == 'workflow_dispatch' }}
+ if: ${{ (github.event_name != 'workflow_dispatch' && startsWith(github.ref, 'refs/tags/') && !contains(github.ref, 'rc')) || (github.event_name == 'workflow_dispatch' && inputs.deploy-nightlies) }}
shell: bash
env:
NIGHTLIES_RSYNC_HOST: ${{ secrets.NIGHTLIES_RSYNC_HOST }}
@@ -670,7 +674,7 @@ jobs:
OPENDAL_WEBSITE_BASE_URL: /opendal/opendal-docs-stable/
- name: Deploy to nightlies for stable version
- if: ${{ (startsWith(github.ref, 'refs/tags/') && !contains(github.ref, 'rc')) || github.event_name == 'workflow_dispatch' }}
+ if: ${{ (github.event_name != 'workflow_dispatch' && startsWith(github.ref, 'refs/tags/') && !contains(github.ref, 'rc')) || (github.event_name == 'workflow_dispatch' && inputs.deploy-nightlies) }}
shell: bash
env:
NIGHTLIES_RSYNC_HOST: ${{ secrets.NIGHTLIES_RSYNC_HOST }}
diff --git a/.github/workflows/release_ruby.yml b/.github/workflows/release_ruby.yml
index a88ce0d461..2e9134d4ad 100644
--- a/.github/workflows/release_ruby.yml
+++ b/.github/workflows/release_ruby.yml
@@ -34,7 +34,8 @@ on:
# a release process. For now, we can rely on artifacts for testing pre-releases.
# In the future, we could consider a GitHub private registry for pre-releases.
#
- # omits `workflow_dispatch` to tighten this release workflow.
+ # Manual dispatch supports candidate builds only; publishing still requires a tag push.
+ workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
@@ -196,7 +197,7 @@ jobs:
publish:
# RC tags only build artifacts for release verification. RubyGems does not
# provide a staging registry, so publish only from the final release tag.
- if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-')
+ if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-')
needs: [build, smoke-test, build-native]
runs-on: ubuntu-latest
diff --git a/.github/workflows/weekly_release.yml b/.github/workflows/weekly_release.yml
index d5fdeb266a..47a87eacec 100644
--- a/.github/workflows/weekly_release.yml
+++ b/.github/workflows/weekly_release.yml
@@ -118,3 +118,83 @@ jobs:
rc: ${{ needs.prepare.outputs.rc }}
secrets:
GPG_SECRET_KEY: ${{ secrets.GPG_SECRET_KEY }}
+
+ builds:
+ needs: prepare
+ runs-on: ubuntu-latest
+ permissions:
+ actions: write
+ contents: read
+ steps:
+ - name: Dispatch existing RC workflows
+ env:
+ GH_TOKEN: ${{ github.token }}
+ RC: ${{ needs.prepare.outputs.rc }}
+ SHA: ${{ needs.prepare.outputs.sha }}
+ run: |
+ # GITHUB_TOKEN pushes do not trigger the existing tag workflows.
+ for workflow in ci_bindings_{c,cpp,d,dart,dotnet,go,haskell,java,lua,nodejs,ocaml,php,ruby,swift,zig}.yml release_{dart,dotnet,java,nodejs,python,ruby,rust}.yml docs.yml; do
+ # Reuse runs already accepted before a partial dispatch failure.
+ count=$(gh run list --repo apache/opendal --workflow "$workflow" --commit "$SHA" --event workflow_dispatch --limit 1 --json databaseId --jq length)
+ if [ "$count" -gt 0 ]; then continue; fi
+ args=()
+ case "$workflow" in
+ release_nodejs.yml) args=(-f nodejs-publish=false -f nodejs-publish-dry-run=false) ;;
+ release_dotnet.yml) args=(-f release_type=none) ;;
+ docs.yml) args=(-f release_version="v$RC" -f deploy-nightlies=false) ;;
+ esac
+ gh workflow run "$workflow" --repo apache/opendal --ref "v$RC" "${args[@]}"
+ done
+
+ notify:
+ needs: [prepare, compose, builds]
+ runs-on: ubuntu-latest
+ permissions:
+ discussions: write
+ contents: read
+ steps:
+ - name: Announce staged candidate for RM verification
+ env:
+ GH_TOKEN: ${{ github.token }}
+ RC: ${{ needs.prepare.outputs.rc }}
+ SHA: ${{ needs.prepare.outputs.sha }}
+ run: |
+ title="Source candidate ready: $RC"
+ # GraphQL variables must reach the API without shell expansion.
+ # shellcheck disable=SC2016
+ gh api graphql --paginate --slurp -f query='
+ query($endCursor: String) {
+ repository(owner: "apache", name: "opendal") {
+ id
+ discussionCategories(first: 100) { nodes { id name } }
+ discussions(first: 100, after: $endCursor) {
+ nodes { title url }
+ pageInfo { hasNextPage endCursor }
+ }
+ }
+ }' > "$RUNNER_TEMP/discussions.json"
+ existing=$(jq -r --arg title "$title" '[.[].data.repository.discussions.nodes[] | select(.title == $title) | .url][0] // empty' "$RUNNER_TEMP/discussions.json")
+ if [ -n "$existing" ]; then
+ echo "$existing" >> "$GITHUB_STEP_SUMMARY"
+ exit 0
+ fi
+ repository=$(jq -er '.[0].data.repository.id' "$RUNNER_TEMP/discussions.json")
+ category=$(jq -er '.[0].data.repository.discussionCategories.nodes[] | select(.name == "General") | .id' "$RUNNER_TEMP/discussions.json")
+ cat > "$RUNNER_TEMP/candidate-notice.md" <<EOF
+ Source candidate **$RC** has been built, signed and uploaded to ATR.
+
+ - [ATR candidate](https://releases.apache.org/compose/opendal/$RC)
+ - [RC tag](https://github.com/apache/opendal/releases/tag/v$RC), commit: \`$SHA\`
+ - [Source build and signed artifacts](https://github.com/apache/opendal/actions/runs/$GITHUB_RUN_ID)
+ - [RC builds and binding checks](https://github.com/apache/opendal/actions?query=branch%3Av$RC)
+
+ RC build workflows have been dispatched; this notice does not mean they have passed.
+ Release manager: check their results and staging outputs, inspect ATR checks, and independently verify the candidate before starting the formal vote. This Discussion is a preparation notice, not a vote.
+ EOF
+ # shellcheck disable=SC2016
+ gh api graphql -f query='
+ mutation($repository: ID!, $category: ID!, $title: String!, $body: String!) {
+ createDiscussion(input: {repositoryId: $repository, categoryId: $category, title: $title, body: $body}) {
+ discussion { url }
+ }
+ }' -f repository="$repository" -f category="$category" -f title="$title" -F body=@"$RUNNER_TEMP/candidate-notice.md" --jq '.data.createDiscussion.discussion.url' >> "$GITHUB_STEP_SUMMARY"
diff --git a/website/community/release/weekly.md b/website/community/release/weekly.md
index d605b961ec..2f10b22cf4 100644
--- a/website/community/release/weekly.md
+++ b/website/community/release/weekly.md
@@ -47,10 +47,24 @@ retains its caller's identity. The actor initiating a manual run or owning the
schedule must have the required ASF-linked project permissions. An RM should
maintain the cron expression, which determines the scheduled actor.
-The workflow ends at ATR compose. It does not start votes, announce releases,
-create final tags, synchronize main or publish language packages. These remain
-steps in the existing release procedure. Keep the candidate branch and signed
-artifacts until that procedure is complete.
+After pushing the RC tag, the workflow explicitly dispatches the existing tag
+builds, binding checks and documentation workflow against that tag. GitHub does
+not trigger downstream push workflows for tags created with `GITHUB_TOKEN`.
+These dispatches retain the RC behavior: Java stages to Nexus, Python uses
+TestPyPI, NodeJS performs a publish dry run, Ruby and .NET retain artifacts, and
+Rust does not publish. Documentation retains RC staging without deploying to
+nightlies. A retry skips workflows already dispatched for the candidate commit;
+rerun failed downstream jobs from their own runs.
+
+After ATR upload and dispatch succeed, the workflow posts a candidate preparation
+notice in GitHub Discussions with the ATR, tag, source artifact and build links.
+It reuses an existing notice for the same RC when retried. This notice does not
+assert that downstream builds or ATR checks passed. The RM verifies those results
+and the candidate before starting the formal vote.
+
+The workflow does not start votes, announce final releases, create final tags or
+synchronize main. These remain steps in the existing release procedure. Keep the
+candidate branch and signed artifacts until that procedure is complete.
Installing this workflow on main activates the schedule. The initiating actor and
reusable workflow's ATR OIDC identity still require a live rehearsal; local checks