This is an automated email from the ASF dual-hosted git repository.
PsiACE pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git
The following commit(s) were added to refs/heads/main by this push:
new 979eb69fb docs: update OpenDAL release skill (#7655)
979eb69fb is described below
commit 979eb69fb8cc7d8f3126181f26401ca5f7b08282
Author: Xuanwo <[email protected]>
AuthorDate: Mon Jun 1 17:22:24 2026 +0800
docs: update OpenDAL release skill (#7655)
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