OpenClaw Release Maintainer
Use this skill for release and publish-time workflow. Keep ordinary development changes and GHSA-specific advisory work outside this skill.
Respect release guardrails
- Do not change version numbers without explicit operator approval.
- Ask permission before any npm publish or release step.
- This skill should be sufficient to drive the normal release flow end-to-end.
- Use the private maintainer release docs for credentials, recovery steps, and mac signing/notary specifics, and use
docs/reference/RELEASING.mdfor public policy. - Core
openclawpublish is manualworkflow_dispatch; creating or pushing a tag does not publish by itself.
Keep release channel naming aligned
stable: tagged releases only, published to npmlatestand then mirrored onto npmbetaunlessbetaalready points at a newer prereleasebeta: prerelease tags likevYYYY.M.D-beta.N, with npm dist-tagbeta- Prefer
-beta.N; do not mint new-1or-2beta suffixes dev: moving head onmain- When using a beta Git tag, publish npm with the matching beta version suffix so the plain version is not consumed or blocked
Handle versions and release files consistently
- Version locations include:
package.jsonapps/android/app/build.gradle.ktsapps/ios/Sources/Info.plistapps/ios/Tests/Info.plistapps/macos/Sources/OpenClaw/Resources/Info.plistdocs/install/updating.md- Peekaboo Xcode project and plist version fields
- Before creating a release tag, make every version location above match the version encoded by that tag.
- For fallback correction tags like
vYYYY.M.D-N, the repo version locations still stay atYYYY.M.D. - “Bump version everywhere” means all version locations above except
appcast.xml. - Release signing and notary credentials live outside the repo in the private maintainer docs.
- Every OpenClaw release ships the npm package and macOS app together.
- The production Sparkle feed lives at
https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml, and the canonical published file isappcast.xmlonmainin theopenclawrepo. - That shared production Sparkle feed is stable-only. Beta mac releases may
upload assets to the GitHub prerelease, but they must not replace the shared
appcast.xmlunless a separate beta feed exists. - For fallback correction tags like
vYYYY.M.D-N, the repo version still stays atYYYY.M.D, but the mac release must use a strictly higher numericAPP_BUILD/ Sparkle build than the original release so existing installs see it as newer.
Build changelog-backed release notes
- Changelog entries should be user-facing, not internal release-process notes.
- When cutting a mac release with a beta GitHub prerelease:
- tag
vYYYY.M.D-beta.Nfrom the release commit - create a prerelease titled
openclaw YYYY.M.D-beta.N - use release notes from the matching
CHANGELOG.mdversion section - attach at least the zip and dSYM zip, plus dmg if available
- tag
- Keep the top version entries in
CHANGELOG.mdsorted by impact:### Changesfirst### Fixesdeduped with user-facing fixes first
Run publish-time validation
Before tagging or publishing, run:
node --import tsx scripts/release-check.ts
pnpm release:check
pnpm test:install:smoke
For a non-root smoke path:
OPENCLAW_INSTALL_SMOKE_SKIP_NONROOT=1 pnpm test:install:smoke
After npm publish, run:
node --import tsx scripts/openclaw-npm-postpublish-verify.ts <published-version>
- This verifies the published registry install path in a fresh temp prefix.
- For stable correction releases like
YYYY.M.D-N, it also verifies the upgrade path fromYYYY.M.DtoYYYY.M.D-Nso a correction publish cannot silently leave existing global installs on the old base stable payload.
Check all relevant release builds
- Always validate the OpenClaw npm release path before creating the tag.
- Default release checks:
pnpm checkpnpm buildnode --import tsx scripts/release-check.tspnpm release:checkOPENCLAW_INSTALL_SMOKE_SKIP_NONROOT=1 pnpm test:install:smoke
- Check all release-related build surfaces touched by the release, not only the npm package.
- Include mac release readiness in preflight by running the public validation
workflow in
openclaw/openclawand the real mac preflight inopenclaw/releases-privatefor every release. - Treat the
appcast.xmlupdate onmainas part of mac release readiness, not an optional follow-up. - The workflows remain tag-based. The agent is responsible for making sure preflight runs complete successfully before any publish run starts.
- Any fix after preflight means a new commit. Delete and recreate the tag and matching GitHub release from the fixed commit, then rerun preflight from scratch before publishing.
- For stable mac releases, generate the signed
appcast.xmlbefore uploading public release assets so the updater feed cannot lag the published binaries. - Serialize stable appcast-producing runs across tags so two releases do not
generate replacement
appcast.xmlfiles from the same stale seed. - For stable releases, confirm the latest beta already passed the broader release workflows before cutting stable.
- If any required build, packaging step, or release workflow is red, do not say the release is ready.
Use the right auth flow
- OpenClaw publish uses GitHub trusted publishing.
- The publish run must be started manually with
workflow_dispatch. - The npm workflow and the private mac publish workflow accept
preflight_only=trueto run validation/build/package steps without uploading public release assets. - The private mac workflow also accepts
smoke_test_only=truefor branch-safe workflow smoke tests that use ad-hoc signing, skip notarization, skip shared appcast generation, and do not prove release readiness. preflight_only=trueon the npm workflow is also the right way to validate an existing tag after publish; it should keep running the build checks even when the npm version is already published.- Validation-only runs may be dispatched from a branch when you are testing a workflow change before merge.
.github/workflows/macos-release.ymlinopenclaw/openclawis now a public validation-only handoff. It validates the tag/release state and points operators to the private repo; it does not build or publish macOS artifacts.- Real mac preflight and real mac publish both use
openclaw/releases-private/.github/workflows/openclaw-macos-publish.yml. - The private mac workflow runs on GitHub's xlarge macOS runner and uses a SwiftPM cache because the Swift build/test/package path is CPU-heavy.
- Private mac preflight uploads notarized build artifacts as workflow artifacts instead of uploading public GitHub release assets.
- Private smoke-test runs upload ad-hoc, non-notarized build artifacts as
workflow artifacts and intentionally skip stable
appcast.xmlgeneration. - npm preflight, public mac validation, and private mac preflight must all pass before any real publish run starts.
- Real publish runs must be dispatched from
main; branch-dispatched publish attempts should fail before the protected environment is reached. - The release workflows stay tag-based; rely on the documented release sequence rather than workflow-level SHA pinning.
- The
npm-releaseenvironment must be approved by@openclaw/openclaw-release-managersbefore publish continues. - Mac publish uses
openclaw/releases-private/.github/workflows/openclaw-macos-publish.ymlfor build, signing, notarization, packaged mac artifact generation, and stable-feedappcast.xmlartifact generation. - Real private mac publish uploads the packaged
.zip,.dmg, and.dSYM.zipassets to the existing GitHub release inopenclaw/openclawautomatically whenOPENCLAW_PUBLIC_REPO_RELEASE_TOKENis present in the private repomac-releaseenvironment. - For stable releases, the agent must also download the signed
macos-appcast-<tag>artifact from the successful private mac workflow and then updateappcast.xmlonmain. - For beta mac releases, do not update the shared production
appcast.xmlunless a separate beta Sparkle feed exists. - The private repo targets a dedicated
mac-releaseenvironment. If the GitHub plan does not yet support required reviewers there, do not assume the environment alone is the approval boundary; rely on private repo access and CODEOWNERS until those settings can be enabled. - Do not use
NPM_TOKENor the plugin OTP flow for OpenClaw releases. @openclaw/*plugin publishes use a separate maintainer-only flow.- Only publish plugins that already exist on npm; bundled disk-tree-only plugins stay unpublished.
Fallback local mac publish
- Keep the original local macOS publish workflow available as a fallback in case CI/CD mac publishing is unavailable or broken.
- Preserve the existing maintainer workflow Peter uses: run it on a real Mac with local signing, notary, and Sparkle credentials already configured.
- Follow the private maintainer macOS runbook for the local steps:
scripts/package-mac-dist.shto build, sign, notarize, and package the app; manual GitHub release asset upload; thenscripts/make_appcast.shplus theappcast.xmlcommit tomain. scripts/package-mac-dist.shnow fails closed for release builds if the bundled app comes out with a debug bundle id, an empty Sparkle feed URL, or aCFBundleVersionbelow the canonical Sparkle build floor for that short version. For correction tags, set a higher explicitAPP_BUILD.scripts/make_appcast.shfirst usesgenerate_appcastfromPATH, then falls back to the SwiftPM Sparkle tool output underapps/macos/.build.- For stable tags, the local fallback may update the shared production
appcast.xml. - For beta tags, the local fallback still publishes the mac assets but must not
update the shared production
appcast.xmlunless a separate beta feed exists. - Treat the local workflow as fallback only. Prefer the CI/CD publish workflow when it is working.
- After any stable mac publish, verify all of the following before you call the
release finished:
- the GitHub release has
.zip,.dmg, and.dSYM.zipassets appcast.xmlonmainpoints at the new stable zip- the packaged app reports the expected short version and a numeric
CFBundleVersionat or above the canonical Sparkle build floor
- the GitHub release has
Run the release sequence
- Confirm the operator explicitly wants to cut a release.
- Choose the exact target version and git tag.
- Make every repo version location match that tag before creating it.
- Update
CHANGELOG.mdand assemble the matching GitHub release notes. - Run the full preflight for all relevant release builds, including mac readiness.
- Confirm the target npm version is not already published.
- Create and push the git tag.
- Create or refresh the matching GitHub release.
- Start
.github/workflows/openclaw-npm-release.ymlwithpreflight_only=trueand wait for it to pass. - Start
.github/workflows/macos-release.ymlinopenclaw/openclawand wait for the public validation-only run to pass. - Start
openclaw/releases-private/.github/workflows/openclaw-macos-publish.ymlwithpreflight_only=trueand wait for it to pass. - If any preflight or validation run fails, fix the issue on a new commit, delete the tag and matching GitHub release, recreate them from the fixed commit, and rerun all relevant preflights from scratch before continuing. Never reuse old preflight results after the commit changes.
- Start
.github/workflows/openclaw-npm-release.ymlwith the same tag for the real publish. - Wait for
npm-releaseapproval from@openclaw/openclaw-release-managers. - Start
openclaw/releases-private/.github/workflows/openclaw-macos-publish.ymlfor the real publish and wait for success. - Verify the successful real private mac run uploaded the
.zip,.dmg, and.dSYM.zipartifacts to the existing GitHub release inopenclaw/openclaw. - For stable releases, download
macos-appcast-<tag>from the successful private mac run, updateappcast.xmlonmain, and verify the feed. - For beta releases, publish the mac assets but expect no shared production
appcast.xmlartifact and do not update the shared production feed unless a separate beta feed exists. - After publish, verify npm and the attached release artifacts.
GHSA advisory work
- Use
openclaw-ghsa-maintainerfor GHSA advisory inspection, patch/publish flow, private-fork validation, and GHSA API-specific publish checks.