Skip to content

chore(release): automate releases with Release Please and document released versions - #517

Merged
christso merged 9 commits into
mainfrom
chore/changelog
Sep 23, 2026
Merged

christso merged 9 commits into
mainfrom
chore/changelog

Conversation

@christso

@christso christso commented Sep 23, 2026 •

Copy link
Copy Markdown
Contributor

What

Two related changes: the changelog now covers every released version, and releases are automated end to end with Release Please.

1. CHANGELOG.md documented every stable release

The file previously had a single ## [Unreleased] section plus ## [1.0.0]. Fifty stable releases (v1.0.1 … v1.16.6) had shipped without entries. The changelog now carries one dated section per stable release, reconstructed from that release's commit window (207 commits) and checked against the tagged source.

  • Every non-release-bump commit is either documented or excluded as internal with a reason: 116 documented, 8 carried over from the maintainer's Unreleased prose, 83 excluded (tests, CI, release tooling, dependency bumps, docs-site copy, repo-internal guidance, example workspaces, net-zero revert pairs).
  • Four adversarial audits re-checked the claims against git show <tag>:src/... and produced seven corrections (v1.3.0 workspace update alias, v1.0.9 scope default, v1.0.10 output claim, v1.11.9 managed-repository environment, v1.15.0 skipped-reporting clause, and unsupported mcp auth / plugin list clauses), one removal (a v1.13.1 heading bullet that netted out in its own window), and three missing entries (Copilot and Codex global profiles, MCP --scope/--profile destinations, the engineering plugin introduction).
  • v1.4.9 has no section (no user-facing change). v1.15.0, v1.16.0 and v1.16.3 keep the maintainer's curated wording.

2. Release Please owns versions, tags, and the changelog

  • release-please-config.json + .release-please-manifest.json (at 1.16.6): node release type, vX.Y.Z tags, feat → Added, fix → Fixed, perf → Performance, every other type hidden from the changelog while still counting toward the bump. Validated against the official Release Please config schema.
  • .github/workflows/release-please.yml: on every push, Release Please maintains a release pull request that bumps package.json, the manifest, and CHANGELOG.md. Merging that pull request is the finalize step: it creates the tag and GitHub release and publishes to npm latest through the reusable Publish workflow. No manual bump, no dispatch, no next-tag step.
  • next previews: every push that has an open release pull request stamps the pending version as <pending>-next.<run>, publishes it to npm next, tags that commit v<pending>-next.<run>, and creates a GitHub prerelease. Nothing is published when main already matches the last release. latest only ever moves on a release pull request merge.
  • .github/workflows/publish.yml became a reusable publisher: it takes a release tag, validates the tag against package.json at that commit, ensures the GitHub release exists, and publishes idempotently. The manual next/finalize/stable channels are gone.
  • scripts/release.ts and its tests are deleted; conventional-commit versioning replaces manual bumping.
  • Docs: .agents/publishing.md, AGENTS.md, CONTRIBUTING.md.

No binaries are published to GitHub releases. The distributed artifact stays the npm package (currently a 1.97 MB JS bundle run by Node ≥22 or bun), matching what shipped before.

Maintainer workflow after this lands

  1. Merge conventional commits to main as usual. feat → minor, fix/perf → patch, ! or BREAKING CHANGE: → major.
  2. Review the release pull request Release Please opens (edit the changelog wording there if needed) and squash merge it. That merge is the finalize step: tag, GitHub release, npm latest. Minutes after merging a fix, if that's what you want.
  3. Recovery: dispatch Publish with the release tag.

Notes:

  • Set the repository secret RELEASE_PLEASE_TOKEN (a PAT) if CI checks should run on the release pull request; the default token cannot trigger other workflows.
  • npm trusted publishing is unchanged: the reusable publisher is still .github/workflows/publish.yml, so the existing binding still matches.
  • npm's trusted publishing covers only npm publish, so CI cannot move a dist-tag by hand. Between a release and the next preview, next therefore points at the last preview; bun scripts/tag-channel.ts next <version> covers that locally if it ever matters.
  • The two bullets that used to sit under ## [Unreleased] (plugin-update classification, update progress) will be regenerated from their commit subjects by the first Release Please release pull request; the curated wording is preserved here:
    • `plugin update` now classifies an already-current plugin as skipped instead of updated: it is not re-applied and its marketplace registry timestamp is left untouched. Client synchronization for its scope still runs.
    • Plugin and skill updates now expose truthful live progress. Direct plugin updates check each source without mutating it, report how many plugin updates were found, then name each source as it is applied. Direct skill updates check each source first, report the number of discovered skill updates, then name each skill as it is applied. **Plugins → Update all** keeps the current source on its existing spinner. Warnings and failures remain detailed; JSON and redirected direct output remain one-shot and batched.

Verification

Changelog reconstruction:

git log --format=%h --reverse origin/main -- CHANGELOG.md   # attribution per release window
git tag --contains <hash> --list 'v1.*'                     # entry → first stable release
git show v1.4.5:src/cli/commands/workspace.ts               # per-entry source checks

Every section date equals its tag date, every stable tag has exactly one section, and the 207-commit coverage list accounts for every commit in every window.

Release automation:

bun run src/cli/index.ts --help --json        # help surface unchanged
git tag -a v1.16.7-next.999 -m "..." && git push origin …   # preview tag mechanics in a scratch clone
node -e "…stamp version…" && bun run build && bun run dist/index.js --version   # → 1.16.7-next.999
actionlint .github/workflows/*.yml                          # clean (1.7.7)

A dry run of Release Please's changelog updater against the rewritten file inserts the next release directly under # Changelog, above ## [1.16.6], with no Unreleased section left behind. The Release Please config validates against its published JSON schema.

Repository checks:

bun run typecheck   # clean
bun run lint        # clean
bun test            # full suite
bun run build && bun run package:smoke   # packed artifact smoke passed
bun run schema:check                     # no drift
bun run docs:build                       # 13 pages built

Notes for reviewers

  • Historical sections keep the file's existing heading style (## [1.16.6] - 2026-09-22); Release Please writes its own heading style for new releases and does not rewrite history.
  • A pre-existing bug found while auditing (src/cli/metadata/plugin.ts advertising a removed flag) is fixed in fix(plugin): remove the unused --force flag from marketplace add #518, not here.

CHANGELOG.md stopped at 1.0.0 and carried everything since under a single
Unreleased heading, so the 50 stable releases from v1.0.1 to v1.16.6 had no
documented history.

Each stable release now has a dated section reconstructed from its own commit
window (v<previous>..v<tag>). Every non-release-bump commit in those windows is
either documented or excluded as internal with a reason: 116 documented, 8
carried over from the maintainer's Unreleased prose, 83 excluded. Entries were
checked against the tagged source, and adversarial audits corrected six claims:
the v1.3.0 alias, the v1.0.9 scope default, the v1.0.10 output claim, the
v1.11.9 managed-repository environment, the v1.15.0 skipped-reporting clause,
and the v1.16.0 migration guidance for a command that never shipped.

The Unreleased section is removed because Release Please now owns the
changelog; the next release pull request regenerates those two entries from
their commit subjects.
Standalone binaries built with `bun build --compile` report a virtual
import.meta.dir, so the src-versus-dist heuristic looked for templates outside
the executable and `workspace init` failed with "Default template not found".

Prefer the templates directory beside the entrypoint and fall back to the
source layout, which covers the published bundle, source runs, and compiled
binaries carrying embedded templates.
Releases were manual: a maintainer dispatched the Publish workflow, chose the
bump, created the next tag, and later finalized it. Release Please now computes
the version from conventional commits and keeps a release pull request that
updates package.json and CHANGELOG.md. Merging that pull request is the
finalize step: the new Release Please workflow publishes the tag to npm through
the reusable Publish workflow, builds standalone binaries for five platforms,
attaches them plus SHA256SUMS to the GitHub release, and leaves no manual
next-tag release to run.

- release-please-config.json and .release-please-manifest.json: node release
  type, vX.Y.Z tags, and changelog sections mapped to the repository's
  vocabulary (feat to Added, fix to Fixed, perf to Performance) while hidden
  types still count toward the bump.
- .github/workflows/release-please.yml: release pull requests, release
  creation, npm publishing, binary builds, and checksums, with a dispatch input
  to rebuild binaries for an existing tag.
- .github/workflows/publish.yml: reusable publisher that validates the tag
  against package.json at that commit, ensures the GitHub release exists, and
  publishes idempotently. The manual next, finalize, and stable channels are
  gone; publishing a prerelease tag still uses the npm next dist-tag.
- scripts/build-binary.ts: compiles a self-contained executable per platform
  with embedded templates and archives it with THIRD_PARTY_NOTICES.txt. The
  target list lives in the script, so the workflow matrix has one source of
  truth.
- scripts/release.ts and its tests are deleted; version computation replaces
  manual bumping.
- Docs: .agents/publishing.md, AGENTS.md, CONTRIBUTING.md, and the installation
  page describe the new flow and the standalone binaries.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Deploying allagents with  Cloudflare Pages  Cloudflare Pages

Latest commit: f001159
Status: ✅  Deploy successful!
Preview URL: https://0fe22fdf.allagents.pages.dev
Branch Preview URL: https://chore-changelog.allagents.pages.dev

View logs

The previous flow published X.Y.Z-next.N to the npm next channel from the
Publish workflow's next channel. Release Please owns stable versions now, so
the preview needs its own entry point that cannot move the stable version.

Release Next reads the pending version from the open release pull request,
increments the highest vX.Y.Z-next.N tag, writes that prerelease version into a
commit tagged on top of the release pull request content, and publishes through
the same reusable Publish workflow. The prerelease version lives in the tagged
commit rather than on main, so the release pull request stays the only version
source and Release Please keeps resolving its base release from the manifest.
`next` should mean what main has right now, not the release candidate an
operator dispatched. Replace the dispatchable preview workflow with a preview
job in the release workflow: when a push leaves an open release pull request,
it stamps the pending version as <pending>-next.<run>, builds, and publishes to
the npm next tag. `latest` stays the newest stable release and still only moves
when a release pull request is merged.

The prerelease stamp lives in the working tree only, so main keeps the version
the last release published, and the run number keeps each preview strictly
ahead of the previous one. Nothing is published when main already matches the
last release, because then there is nothing to preview.
Previews were npm-only, so a preview build had no git ref and left no entry on
the releases page. Comparable preview channels (gemini-cli nightly, qwen-code
nightly and preview, codex alpha, sure alpha) tag every preview and publish it
as a prerelease, which is what makes a preview reproducible.

The preview job now creates an annotated v<pending>-next.<run> tag at the
pushed commit and a matching GitHub prerelease. The tagged commit keeps the
last released version in package.json; the preview version exists only in the
published artifact. Release Please resolves its base release by matching the
manifest version, so prerelease tags stay invisible to it.
Releases never carried binaries: the distributed artifact is the npm package,
so attaching platform archives to GitHub releases duplicated that channel.

Drop the platform build matrix, the checksum job, the rebuild dispatch input,
and `scripts/build-binary.ts`, and revert the template-resolution change that
existed only so a compiled executable could find its embedded templates. The
CLI keeps shipping as the same npm bundle it ships today.
@christso
christso merged commit f092118 into main Sep 23, 2026
10 checks passed
@christso
christso deleted the chore/changelog branch September 23, 2026 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant