Split the OpenCode reliability bullet into four per-PR entries, shorten the Windows and provider-models bullets, and drop low-signal qualifiers. Add a "Changelog conciseness" section to the release playbook so the next agent knows bullets must be scannable in one glance.
12 KiB
Release
All workspaces share one version and release together.
Two paths
There are two supported ways to ship from main:
- Direct stable release: you are ready to ship the current
maincommit to everyone immediately. - Release candidate flow: you want public test builds first, but you are not ready for the website, npm, or production mobile release flows to move yet.
Standard release (patch)
Before running any stable patch release command:
- Make sure the intended release commit is already committed to
mainand the working tree is clean. - Make sure local
npm run typecheckpasses on that commit. - Do not use
npm run release:patchas a substitute for checking whether the current commit is actually ready.
npm run release:patch
This bumps the version across all workspaces, runs checks, publishes to npm, and pushes the branch + tag (triggering desktop, APK, and EAS mobile workflows).
If asked to "release paseo" without specifying major/minor, treat it as a patch release.
Use the direct stable path when the current main changes are ready to become the public release immediately.
Manual step-by-step
npm run typecheck # Verify the exact commit you intend to release
npm run release:check # Typecheck, build, dry-run pack
npm run version:all:patch # Bump version, create commit + tag
npm run release:publish # Publish to npm
npm run release:push # Push HEAD + tag (triggers CI workflows)
Release candidate flow
npm run release:rc:patch # Bump to X.Y.Z-rc.1, push commit + tag
# ... test desktop and APK prerelease assets from GitHub Releases ...
npm run release:rc:next # Optional: cut X.Y.Z-rc.2, rc.3, ...
npm run release:promote # Promote X.Y.Z-rc.N to stable X.Y.Z
- RC tags are published GitHub prereleases like
v0.1.41-rc.1 - RCs publish desktop assets and APKs for testing, but they do not publish npm packages and do not trigger the production web/mobile release flows
release:promotecreates a fresh stable tag likev0.1.41; the final release never reuses the RC tag- Desktop assets now come from the Electron package at
packages/desktop - Do NOT create a changelog entry for RCs. The changelog remains stable-only. RC release notes are generated automatically so the website stays pinned to the latest published stable release.
Use the RC path when you need to:
- test a build manually in a Linux or Windows VM
- send a build to a user who is hitting a specific problem
- iterate on
rc.1,rc.2,rc.3, and so on before deciding to ship broadly
Website behavior
- The website download page points to GitHub's latest published stable release.
- Published RC prereleases are public on GitHub Releases, but they do not become the website download target.
- The website only moves when you publish the final stable release tag like
v0.1.41.
Fixing a failed release build
NEVER bump the version to fix a build problem. New versions are reserved for meaningful product changes (features, fixes, improvements). Build/CI failures are fixed on the current version.
Do not rely on workflow_dispatch for tagged code fixes. The workflow_dispatch trigger runs the workflow file from the default branch but checks out the code at the tag ref (ref: ${{ inputs.tag }}). That means fixes committed to main won't change the tagged source tree being built. workflow_dispatch only helps when the fix lives in the workflow file itself.
To retry a failed workflow, always push a retry tag on the commit you want to build. Reusing the same tag name is expected: move it with git tag -f ... and push it with --force so the workflow rebuilds the commit you actually want.
Prefer a tag push over workflow_dispatch whenever you are rebuilding release code or release assets.
The retry tag patterns below still work and remain the supported way to rebuild specific release targets:
# Desktop (all platforms)
git tag -f desktop-v0.1.28 HEAD && git push origin desktop-v0.1.28 --force
# Desktop (single platform)
git tag -f desktop-macos-v0.1.28 HEAD && git push origin desktop-macos-v0.1.28 --force
git tag -f desktop-linux-v0.1.28 HEAD && git push origin desktop-linux-v0.1.28 --force
git tag -f desktop-windows-v0.1.28 HEAD && git push origin desktop-windows-v0.1.28 --force
# Android APK
git tag -f android-v0.1.28 HEAD && git push origin android-v0.1.28 --force
# RC
git tag -f v0.1.29-rc.2 HEAD && git push origin v0.1.29-rc.2 --force
This ensures the checkout ref matches the actual code on main with the fix included.
vX.Y.ZorvX.Y.Z-rc.Nrebuilds the full tagged releasedesktop-vX.Y.Zrebuilds desktop for all desktop platforms onlydesktop-macos-vX.Y.Z,desktop-linux-vX.Y.Z, anddesktop-windows-vX.Y.Zrebuild only that desktop platformandroid-vX.Y.Zrebuilds the Android APK release only
Notes
version:all:*bumps root + syncs workspace versions and@getpaseo/*dependency versionsrelease:preparerefreshes workspacenode_moduleslinks to prevent stale typesnpm run dev:desktopandnpm run build:desktoptarget the Electron desktop package inpackages/desktop- If
release:publishpartially fails, re-run it — npm skips already-published versions - The website uses GitHub's latest published release API for download links, so published RC prereleases do not replace the stable download target.
Changelog format
Stable release notes depend on the changelog heading format. The heading must be strictly followed:
## X.Y.Z - YYYY-MM-DD
No prefix (v), no extra text. The parser matches the first ## X.Y.Z line to extract the version. A malformed heading will break download links on the homepage.
Changelog policy
CHANGELOG.mdis for final stable releases only.- Do not add or edit changelog entries while iterating on RCs.
- Write the proper changelog entry when you are cutting the final stable release that comes after the RC cycle.
- Between stable releases, keep changelog work out of the repo until the final release is ready.
Changelog ownership
- Only Claude should write changelog entries.
- If you are Codex and a stable release needs a changelog entry, launch a Claude agent with Paseo to draft it, then review and commit the result.
Changelog voice
The changelog is shown on the Paseo homepage. Write it for end users, not developers.
- Frame everything from the user's perspective. Describe what changed in the app, not what changed in the code. Users care that "workspaces load instantly" — not that a component no longer remounts.
- Never mention component names, internal modules, or implementation details. No
WorkingIndicator, noaccumulatedUsage, noreconcileAndEmitWorkspaceUpdates. - Collapse internal iterations. If a feature was added and then fixed within the same release, just list the feature as working. Users never saw the broken version.
- Only list changes relative to the previous stable release. The diff is
v(previous)..HEAD. If something was introduced and fixed between those two tags, it never shipped — don't mention the fix. - Cut low-signal entries. "Toolbar buttons have consistent sizing" is too granular. Combine small polish items or drop them.
Changelog conciseness
Every bullet must be scannable at a glance. The changelog is not release documentation — it's a list.
- One line per bullet. If a bullet wraps to three lines in a narrow column, it's too long.
- Split bullets that pack multiple distinct changes. If a bullet uses "and", "plus", a comma list, or an em-dash to chain several independent improvements, break them into separate bullets — even when they share a theme or author. One bullet = one user-facing change.
- Trim qualifying clauses. Drop "with a hint shown when…", "matching the CLI's behaviour", "across common install shapes". If the detail doesn't change whether a user cares, cut it.
- Lead with the outcome. "Windows: agents launch reliably from npm
.cmdshims…" is better than "Windows: agents launch reliably across common install shapes. Claude, Codex, and OpenCode now start correctly…". - Attribution follows the split. When you split a dense bullet, move each PR/author to the bullet it belongs to. Never duplicate the same PR across multiple bullets.
Changelog attribution
Every changelog bullet must credit contributors and link to the PR(s) that delivered the change. This is not one-PR-per-line — a single bullet describes a user-facing change and may reference multiple PRs.
Format: append ([#123](https://github.com/getpaseo/paseo/pull/123) by [@user](https://github.com/user)) at the end of each bullet. For changes spanning multiple PRs or contributors:
- Voice mode now works on tablets with proper microphone permissions. ([#210](https://github.com/getpaseo/paseo/pull/210), [#215](https://github.com/getpaseo/paseo/pull/215) by [@alice](https://github.com/alice), [@bob](https://github.com/bob))
Rules:
- Always link the PR number as
[#N](https://github.com/getpaseo/paseo/pull/N). - Always link the contributor's GitHub profile as
[@user](https://github.com/user). - One bullet = one user-facing change, regardless of how many PRs went into it. Group related PRs on the same bullet.
- De-duplicate contributors. If the same person authored multiple PRs in one bullet, list them once.
- Only credit external contributors. Skip attribution for @boudra. The changelog credits community contributions — core team work is the default.
- Use
git logto find PR numbers and authors. PR numbers are typically in the commit message as(#N). Usegh pr view N --json authorif the commit doesn't include the GitHub username.
Changelog ordering
Entries within each section (Added, Improved, Fixed) are ordered by user impact:
- User-facing features and changes first — things users will notice, want to try, or that change their workflow.
- Quality-of-life improvements — polish, performance, smoother interactions.
- Internal/infra changes last — only include if they have a tangible user benefit (e.g. "faster startup" is user-facing even if the fix was internal).
Pre-release sanity check
Before cutting any release (RC or stable), run a Codex review of the diff as a last line of defence against shipping bugs.
Load the paseo skill and launch a Codex 5.4 agent with a prompt like:
Review the diff between the latest release tag and HEAD. Focus on:
- Breaking changes — especially in the WebSocket protocol, agent lifecycle, and any server↔client contract.
- Backward compatibility — the important direction is old app clients talking to newly updated daemons. Users update desktop and daemon first, then keep running the old app for a while. Flag anything that breaks old clients against new daemons or requires both sides to update in lockstep.
- Regressions — anything that looks like it could break existing functionality.
Diff:
git diff <latest-release-tag>..HEAD
The agent's job is a deep sanity check, not a full code review. If it flags anything, investigate before proceeding.
Changelog scope
The changelog always covers stable-to-HEAD:
- RC release: the diff and release notes cover
latest stable tag → HEAD. RC release notes are auto-generated and not added toCHANGELOG.md. - Stable release: the diff and changelog entry cover
latest stable tag → HEAD. Any intermediate RCs are skipped — the changelog captures the full delta from the previous stable release, not just what changed since the last RC.
In other words, RCs are checkpoints along the way; the changelog only records the final jump from one stable version to the next.
Completion checklist
- Run the pre-release sanity check (see above) and address any findings
- Ensure the intended release commit is already committed and the git worktree is clean before running any
release:*patch/promote command - Ensure local
npm run typecheckpasses on that exact commit before running anyrelease:*patch/promote command - Update
CHANGELOG.mdwith user-facing release notes (features, fixes — not refactors) - Verify the changelog heading follows strict
## X.Y.Z - YYYY-MM-DDformat npm run release:patchornpm run release:promotecompletes successfully- GitHub
Desktop Releaseworkflow for thev*tag is green - GitHub
Android APK Releaseworkflow for the same tag is green - EAS
release-mobile.ymlworkflow for the same tag is green