This is an automated email from the ASF dual-hosted git repository. Xuanwo pushed a commit to branch xuanwo/update-opendal-release-skill in repository https://gitbox.apache.org/repos/asf/opendal.git
commit b3bb833ecfdadc8355bbaa822e8b4e3291b5866b Author: Xuanwo <[email protected]> AuthorDate: Mon Jun 1 15:49:48 2026 +0800 docs: update opendal release skill --- .agents/skills/opendal-release/SKILL.md | 127 +++++++++++++++++++++++++++++--- 1 file changed, 116 insertions(+), 11 deletions(-) diff --git a/.agents/skills/opendal-release/SKILL.md b/.agents/skills/opendal-release/SKILL.md index 5204d2b7a..fa1d28d8a 100644 --- a/.agents/skills/opendal-release/SKILL.md +++ b/.agents/skills/opendal-release/SKILL.md @@ -21,6 +21,7 @@ The primary repository runbook is `website/community/release/release.md`. The sp - Do not start a public vote with broken links, open Maven staging, missing SVN artifacts, or incomplete required workflows. - Do not conflate Nexus `Close` before voting with Nexus `Release` after the vote passes. - Do not over-block on unrelated/noncritical CI if the release gate is explicitly narrowed. +- Do not put SVN, Nexus, or mail credentials in commands, files, issue text, PRs, or release notes. Read them from environment variables or an interactive prompt and avoid shell history when possible. - Commit messages and public release text must not include agent attribution. ## Version Scope Rules @@ -155,6 +156,7 @@ Rules: - Python wheel matrix can be slow. Poll job status before treating long runtime as a real failure. - The Go binding has no `release_go.yml` in this repository. Its RC gate in `apache/opendal` is `Bindings Go CI`; publishing is tag-driven and handled separately. - Dotnet/NuGet RC publish failures are nonblocking only if Dotnet is outside the agreed gate. RC tags must not publish prerelease packages to NuGet. +- If `Docs` fails, inspect the failed jobs. A docs build failure is release-relevant; a tagged website/nightlies deploy failure caused only by rsync SSH key or secret issues can be recorded as follow-up if the release manager explicitly narrows the gate. ## Go Binding Release Readiness @@ -199,6 +201,24 @@ versions such as `fs/v${go_version}`. Do not treat a green `Bindings Go CI` run as proof that the service artifacts were generated; check the separate `opendal-go-services` workflow and module versions when Go is in scope. +After the vote passes, if the Go binding RC was included in the vote, also push +the final Go binding tag at the same commit as the final top-level release tag: + +```bash +git tag -s "bindings/go/v${go_version}" "${main_sha}" -m "bindings/go/v${go_version}" +git tag -v "bindings/go/v${go_version}" +git push "${apache_remote}" "bindings/go/v${go_version}" +``` + +Then trigger or monitor `apache/opendal-go-services` `build_artifacts` and verify +both the binding module and at least one service module: + +```bash +gh workflow run build_artifacts --repo apache/opendal-go-services --ref main +GOPROXY=direct go list -m -versions github.com/apache/opendal/bindings/go +GOPROXY=direct go list -m -versions github.com/apache/opendal-go-services/fs +``` + ## Rust Release Readiness Before official release, and preferably before vote, inspect the Rust publish plan: @@ -290,7 +310,12 @@ Run this checklist immediately before creating the vote discussion: - Staged website URL is reachable: `https://opendal-v${release_version with dots replaced by hyphens}.staged.apache.org/`. - `scripts/verify.py` is reachable from the RC tag. -Do not start a vote if any checklist item fails. +Do not start a vote if any checklist item fails unless the release manager +explicitly narrows the gate or waives a non-source-package readiness issue. + +If TestPyPI publish failed only because a file already exists from the same RC +attempt, distinguish that from missing artifacts. Report the exact duplicate +filename and proceed only with an explicit release-manager waiver. ## Start Vote Discussion @@ -376,10 +401,14 @@ test -n "${apache_remote}" || { git checkout "v${release_version}" git tag -s "v${opendal_version}" -m "v${opendal_version}" +git tag -v "v${opendal_version}" git push "${apache_remote}" "v${opendal_version}" ``` -2. Move SVN artifacts from `dist/dev` to `dist/release`: +2. If Go is in scope, push the final Go binding tag and verify Go services as + described in `Go Binding Release Readiness`. + +3. Move SVN artifacts from `dist/dev` to `dist/release`: ```bash svn mv https://dist.apache.org/repos/dist/dev/opendal/${release_version} \ @@ -387,28 +416,84 @@ svn mv https://dist.apache.org/repos/dist/dev/opendal/${release_version} \ -m "Release ${opendal_version}" ``` -3. Release Maven artifacts in Nexus: +If remote `svn mv` or `svn mv --force-interactive` hangs on macOS Keychain +authentication, use a shallow working copy and commit a local move instead: + +```bash +svn checkout --depth empty https://dist.apache.org/repos/dist /tmp/opendal-dist-root-${opendal_version} +cd /tmp/opendal-dist-root-${opendal_version} +svn update --set-depth empty dev release +svn update --set-depth empty dev/opendal release/opendal +svn update "dev/opendal/${release_version}" +svn move "dev/opendal/${release_version}" "release/opendal/${opendal_version}" +svn status +svn commit -m "Release ${opendal_version}" +svn ls https://dist.apache.org/repos/dist/release/opendal/${opendal_version}/ +if svn ls https://dist.apache.org/repos/dist/dev/opendal/${release_version}/; then + echo "dev RC directory still exists" >&2 + exit 1 +fi +``` + +If the release manager provides SVN credentials, pass them through environment +variables and avoid caching or echoing them: + +```bash +svn commit -m "Release ${opendal_version}" \ + --username "$SVN_USER" --password "$SVN_PASS" \ + --non-interactive --no-auth-cache +``` + +4. Release Maven artifacts in Nexus. The UI path is acceptable: - Open https://repository.apache.org/#stagingRepositories. - Find `orgapacheopendal-${maven_artifact_number}`. - Click `Release`. -4. Verify language package repositories: - - Rust: `https://crates.io/crates/opendal` - - Python: `https://pypi.org/project/opendal/` - - Java: Maven Central or Nexus search for `opendal` - - Node.js: `https://www.npmjs.com/package/opendal` +The REST API path is also acceptable and easier to audit: + +```bash +curl -fsSL -u "$NEXUS_USER:$NEXUS_PASS" \ + "https://repository.apache.org/service/local/staging/repository/orgapacheopendal-${maven_artifact_number}" + +printf '{"data":{"stagedRepositoryIds":["orgapacheopendal-%s"],"description":"Release Apache OpenDAL %s"}}\n' \ + "$maven_artifact_number" "$opendal_version" \ + >/tmp/opendal-nexus-release.json + +curl -fsSL -u "$NEXUS_USER:$NEXUS_PASS" \ + -H 'Content-Type: application/json' \ + -X POST \ + -d @/tmp/opendal-nexus-release.json \ + https://repository.apache.org/service/local/staging/bulk/promote \ + -w '\nHTTP %{http_code}\n' +``` + +After releasing, query the same staging repository API and confirm it reports +`released` before declaring Maven complete. Then verify Maven Central propagation +for the package-specific Java version. + +5. Verify package repositories: + - Rust: crates.io for every crate in `.github/scripts/release_rust/plan.py`, not only `opendal`. + - Python: version-specific PyPI JSON or the simple index for the package-specific Python version. + - Java: Maven Central or Nexus search for the package-specific Java version. + - Node.js: npm for the package-specific Node.js version. + - Go: `GOPROXY=direct go list -m -versions` for the binding module and service modules when Go is in scope. For Rust, verify both top-level `opendal` and any split crates added or changed in the release. For bindings and integrations, verify the package-specific version from `dev/src/release/package.rs`, not `opendal_version`. -5. Create GitHub Release for `v${opendal_version}`: +Use version-specific PyPI checks. The top-level PyPI JSON endpoint can lag or +temporarily report the previous version even after the version-specific endpoint +and simple index show the new release. + +6. Create GitHub Release for `v${opendal_version}`: - Target branch is `main`. - Generate release notes. - Prepend upgrade notes only for components with breaking changes. -6. Send announcement: +7. Send announcement: - GitHub Discussions `Announcements`. - `[email protected]` from the committer email setup. - Use notable changes, not a raw breaking-change dump. + - Verify the GitHub discussion URL and mail client send result before reporting completion. ## Post Release @@ -439,6 +524,22 @@ Use the agreed gate. For 0.56.0, the blocking gate was Rust / Java / Python / No The wheel matrix can take a long time, especially macOS Intel and Windows. Poll actual job status and wait for conclusion before rerunning. +### TestPyPI reports duplicate files + +`uv publish` can fail with `400 File already exists` when an RC attempt already uploaded the same wheel to TestPyPI. Record the filename, verify whether the existing TestPyPI artifacts are usable, and get an explicit release-manager waiver before voting. Do not treat duplicate files as equivalent to a successful fresh upload. + +### PyPI top-level JSON is stale + +Do not rely only on `https://pypi.org/pypi/opendal/json` immediately after publishing. Check `https://pypi.org/pypi/opendal/${python_version}/json` and the simple index for the exact version. + +### Java CI fails on crates.io index flakiness + +Failures such as `no matching package named futures-channel found` from the crates.io sparse index are registry flakes. Rerun failed jobs before opening a code-fix PR. + +### Docs deploy fails after docs build succeeds + +If the build jobs pass but the tagged website deploy fails with SSH key or rsync errors such as `error in libcrypto` or `Permission denied (publickey)`, separate it from documentation correctness. It can be a release follow-up when the release manager explicitly agrees; otherwise fix the deploy secret and create a new RC if the agreed gate requires `Docs` success. + ### Dotnet tries to publish on RC tags RC tags should build/validate but not publish prerelease packages to NuGet. The durable fix is a prerelease guard in `.github/workflows/release_dotnet.yml`, as done in PR `#7433`. @@ -453,7 +554,11 @@ Include `core/testkit` / `opendal-testkit` when `opendal` references it through ### SVN authentication fails -Confirm whether the files are staged locally. If yes, the blocker is credentials. Do not claim upload until `svn commit` returns a revision. macOS Keychain credentials may be visible to `svn auth` but unavailable to the Codex process. +Confirm whether the files are staged locally. If yes, the blocker is credentials. Do not claim upload until `svn commit` returns a revision. macOS Keychain credentials may be visible to `svn auth` but unavailable to the Codex process. If `--force-interactive` hangs, stop retrying it and switch to a shallow working copy plus explicit credential environment variables. + +### Rust publish takes a long time + +The final Rust publish can run for a long time and still be healthy because split crates publish in plan order. Inspect `.github/scripts/release_rust/plan.py`, watch the workflow logs, and verify crates progressively instead of assuming the job is stuck. ### Maven URL returns 404
