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
 

Reply via email to