2025-12-09 17:51:05 +00:00
---
2026-02-09 14:20:56 -08:00
title: "Release Checklist"
2025-12-19 18:02:30 +01:00
summary: "Step-by-step release checklist for npm + macOS app"
2025-12-09 17:51:05 +00:00
read_when:
- Cutting a new npm release
2025-12-19 18:02:30 +01:00
- Cutting a new macOS app release
2025-12-09 17:51:05 +00:00
- Verifying metadata before publishing
---
2025-12-19 18:02:30 +01:00
# Release Checklist (npm + macOS)
2025-11-25 11:59:15 +01:00
Use `pnpm` (Node 22+) from the repo root. Keep the working tree clean before tagging/publishing.
2026-01-17 12:47:54 +00:00
## Operator trigger
2026-01-31 21:13:13 +09:00
2026-01-17 12:47:54 +00:00
When the operator says “release”, immediately do this preflight (no extra questions unless blocked):
2026-01-31 21:13:13 +09:00
2026-01-17 12:47:54 +00:00
- Read this doc and `docs/platforms/mac/release.md` .
2026-01-23 08:25:20 +00:00
- Load env from `~/.profile` and confirm `SPARKLE_PRIVATE_KEY_FILE` + App Store Connect vars are set (SPARKLE_PRIVATE_KEY_FILE should live in `~/.profile` ).
2026-01-17 12:47:54 +00:00
- Use Sparkle keys from `~/Library/CloudStorage/Dropbox/Backup/Sparkle` if needed.
2026-01-31 21:13:13 +09:00
1. **Version & metadata **
2026-01-29 16:48:13 +00:00
- [ ] Bump `package.json` version (e.g., `2026.1.29` ).
2026-01-16 02:58:08 +00:00
- [ ] Run `pnpm plugins:sync` to align extension package versions + changelogs.
2026-01-30 03:15:10 +01:00
- [ ] Update CLI/version strings: [`src/cli/program.ts` ](https://github.com/openclaw/openclaw/blob/main/src/cli/program.ts ) and the Baileys user agent in [`src/provider-web.ts` ](https://github.com/openclaw/openclaw/blob/main/src/provider-web.ts ).
- [ ] Confirm package metadata (name, description, repository, keywords, license) and `bin` map points to [`openclaw.mjs` ](https://github.com/openclaw/openclaw/blob/main/openclaw.mjs ) for `openclaw` .
2025-11-25 11:59:15 +01:00
- [ ] If dependencies changed, run `pnpm install` so `pnpm-lock.yaml` is current.
2026-02-06 10:00:08 -05:00
2. **Build & artifacts **
2026-01-31 21:13:13 +09:00
2026-01-30 03:15:10 +01:00
- [ ] If A2UI inputs changed, run `pnpm canvas:a2ui:bundle` and commit any updated [`src/canvas-host/a2ui/a2ui.bundle.js` ](https://github.com/openclaw/openclaw/blob/main/src/canvas-host/a2ui/a2ui.bundle.js ).
2025-11-25 11:59:15 +01:00
- [ ] `pnpm run build` (regenerates `dist/` ).
2026-01-21 08:10:44 +00:00
- [ ] Verify npm package `files` includes all required `dist/*` folders (notably `dist/node-host/**` and `dist/acp/**` for headless node + ACP CLI).
2026-01-17 12:34:37 +00:00
- [ ] Confirm `dist/build-info.json` exists and includes the expected `commit` hash (CLI banner uses this for npm installs).
2025-11-25 11:59:15 +01:00
- [ ] Optional: `npm pack --pack-destination /tmp` after the build; inspect the tarball contents and keep it handy for the GitHub release (do **not ** commit it).
2026-02-06 10:00:08 -05:00
3. **Changelog & docs **
2026-01-31 21:13:13 +09:00
2025-11-25 11:59:15 +01:00
- [ ] Update `CHANGELOG.md` with user-facing highlights (create the file if missing); keep entries strictly descending by version.
- [ ] Ensure README examples/flags match current CLI behavior (notably new commands or options).
2026-02-06 10:00:08 -05:00
4. **Validation **
2026-01-31 21:13:13 +09:00
2026-02-02 11:14:27 +09:00
- [ ] `pnpm build`
- [ ] `pnpm check`
2025-11-25 11:59:15 +01:00
- [ ] `pnpm test` (or `pnpm test:coverage` if you need coverage output)
2025-12-27 19:35:39 +01:00
- [ ] `pnpm release:check` (verifies npm pack contents)
2026-01-30 03:15:10 +01:00
- [ ] `OPENCLAW_INSTALL_SMOKE_SKIP_NONROOT=1 pnpm test:install:smoke` (Docker install smoke test, fast path; required before release)
- If the immediate previous npm release is known broken, set `OPENCLAW_INSTALL_SMOKE_PREVIOUS=<last-good-version>` or `OPENCLAW_INSTALL_SMOKE_SKIP_PREVIOUS=1` for the preinstall step.
2026-01-23 09:18:09 +00:00
- [ ] (Optional) Full installer smoke (adds non-root + CLI coverage): `pnpm test:install:smoke`
2026-01-31 13:57:35 +01:00
- [ ] (Optional) Installer E2E (Docker, runs `curl -fsSL https://openclaw.ai/install.sh | bash` , onboards, then runs real tool calls):
2026-01-11 10:20:50 +00:00
- `pnpm test:install:e2e:openai` (requires `OPENAI_API_KEY` )
- `pnpm test:install:e2e:anthropic` (requires `ANTHROPIC_API_KEY` )
- `pnpm test:install:e2e` (requires both keys; runs both providers)
2025-12-09 17:51:05 +00:00
- [ ] (Optional) Spot-check the web gateway if your changes affect send/receive paths.
2025-11-25 11:59:15 +01:00
2026-02-06 10:00:08 -05:00
5. **macOS app (Sparkle) **
2026-01-31 21:13:13 +09:00
2025-12-19 18:02:30 +01:00
- [ ] Build + sign the macOS app, then zip it for distribution.
2026-01-30 03:15:10 +01:00
- [ ] Generate the Sparkle appcast (HTML notes via [`scripts/make_appcast.sh` ](https://github.com/openclaw/openclaw/blob/main/scripts/make_appcast.sh )) and update `appcast.xml` .
2025-12-19 18:02:30 +01:00
- [ ] Keep the app zip (and optional dSYM zip) ready to attach to the GitHub release.
2026-01-10 14:51:21 -06:00
- [ ] Follow [macOS release ](/platforms/mac/release ) for the exact commands and required env vars.
2026-01-03 06:55:58 +01:00
- `APP_BUILD` must be numeric + monotonic (no `-beta` ) so Sparkle compares versions correctly.
2026-01-30 03:15:10 +01:00
- If notarizing, use the `openclaw-notary` keychain profile created from App Store Connect API env vars (see [macOS release ](/platforms/mac/release )).
2025-12-19 18:02:30 +01:00
2026-02-06 10:00:08 -05:00
6. **Publish (npm) **
2026-01-31 21:13:13 +09:00
2025-11-25 11:59:15 +01:00
- [ ] Confirm git status is clean; commit and push as needed.
- [ ] `npm login` (verify 2FA) if needed.
- [ ] `npm publish --access public` (use `--tag beta` for pre-releases).
2026-01-30 03:15:10 +01:00
- [ ] Verify the registry: `npm view openclaw version` , `npm view openclaw dist-tags` , and `npx -y openclaw@X.Y.Z --version` (or `--help` ).
2025-11-25 11:59:15 +01:00
2025-12-21 04:10:20 +01:00
### Troubleshooting (notes from 2.0.0-beta2 release)
2026-01-31 21:13:13 +09:00
2026-01-30 03:15:10 +01:00
- **npm pack/publish hangs or produces huge tarball**: the macOS app bundle in `dist/OpenClaw.app` (and release zips) get swept into the package. Fix by whitelisting publish contents via `package.json` `files` (include dist subdirs, docs, skills; exclude app bundles). Confirm with `npm pack --dry-run` that `dist/OpenClaw.app` is not listed.
2025-12-21 04:10:20 +01:00
- **npm auth web loop for dist-tags**: use legacy auth to get an OTP prompt:
2026-01-30 03:15:10 +01:00
- `NPM_CONFIG_AUTH_TYPE=legacy npm dist-tag add openclaw@X.Y.Z latest`
2025-12-21 04:10:20 +01:00
- **`npx` verification fails with `ECOMPROMISED: Lock compromised` **: retry with a fresh cache:
2026-01-30 03:15:10 +01:00
- `NPM_CONFIG_CACHE=/tmp/npm-cache-$(date +%s) npx -y openclaw@X.Y.Z --version`
2025-12-21 04:10:20 +01:00
- **Tag needs repointing after a late fix**: force-update and push the tag, then ensure the GitHub release assets still match:
- `git tag -f vX.Y.Z && git push -f origin vX.Y.Z`
2026-02-06 10:00:08 -05:00
7. **GitHub release + appcast **
2026-01-31 21:13:13 +09:00
2025-11-25 11:59:15 +01:00
- [ ] Tag and push: `git tag vX.Y.Z && git push origin vX.Y.Z` (or `git push --tags` ).
2026-01-30 03:15:10 +01:00
- [ ] Create/refresh the GitHub release for `vX.Y.Z` with **title `openclaw X.Y.Z` ** (not just the tag); body should include the **full ** changelog section for that version (Highlights + Changes + Fixes), inline (no bare links), and **must not repeat the title inside the body ** .
- [ ] Attach artifacts: `npm pack` tarball (optional), `OpenClaw-X.Y.Z.zip` , and `OpenClaw-X.Y.Z.dSYM.zip` (if generated).
2025-12-19 18:02:30 +01:00
- [ ] Commit the updated `appcast.xml` and push it (Sparkle feeds from main).
2026-01-30 03:15:10 +01:00
- [ ] From a clean temp directory (no `package.json` ), run `npx -y openclaw@X.Y.Z send --help` to confirm install/CLI entrypoints work.
2025-11-25 11:59:15 +01:00
- [ ] Announce/share release notes.
2026-01-24 12:51:13 +00:00
## Plugin publish scope (npm)
2026-01-30 03:15:10 +01:00
We only publish **existing npm plugins ** under the `@openclaw/*` scope. Bundled
2026-01-24 12:51:13 +00:00
plugins that are not on npm stay **disk-tree only ** (still shipped in
`extensions/**` ).
Process to derive the list:
2026-01-31 21:13:13 +09:00
1. `npm search @openclaw --json` and capture the package names.
2. Compare with `extensions/*/package.json` names.
3. Publish only the **intersection ** (already on npm).
2026-01-24 12:51:13 +00:00
Current npm plugin list (update as needed):
2026-01-31 21:13:13 +09:00
2026-01-30 03:15:10 +01:00
- @openclaw/bluebubbles
- @openclaw/diagnostics -otel
- @openclaw/discord
2026-02-03 23:24:32 -08:00
- @openclaw/feishu
2026-01-30 03:15:10 +01:00
- @openclaw/lobster
- @openclaw/matrix
- @openclaw/msteams
- @openclaw/nextcloud -talk
- @openclaw/nostr
- @openclaw/voice -call
- @openclaw/zalo
- @openclaw/zalouser
2026-01-24 12:51:13 +00:00
Release notes must also call out **new optional bundled plugins ** that are **not
on by default** (example: `tlon` ).