# Releasing This repo uses Changesets for version orchestration and two publish paths: the CLI (`executor` npm package plus its platform packages) and the `@executor-js/*` library packages (`core`, `sdk`, and the public plugins). ## Normal release flow 1. Add a changeset in the PR that should ship: - `bun run changeset` 2. Merge that PR to `main`. 3. `.github/workflows/release.yml` opens or updates a `Version Packages` PR. 4. Merge the `Version Packages` PR. 5. The release workflow then does two things in parallel: - Publishes every `@executor-js/*` library package whose current version is not already on npm, via `bun run release:publish:packages` (see `scripts/publish-packages.ts`). - If `apps/cli/package.json` bumped, tags the commit and dispatches `.github/workflows/publish-executor-package.yml`, which: - runs `bun run release:check` - performs a full dry-run release build before publish - publishes the CLI npm package under the correct dist-tag - creates or updates the GitHub release with build artifacts ## Beta releases Enter prerelease mode before starting a beta train: - `bun run release:beta:start` That commits `.changeset/pre.json` into the repo and causes future release PRs to produce versions like `1.5.0-beta.0`, `1.5.0-beta.1`, and so on. When the beta train is done: - `bun run release:beta:stop` Stable versions publish to npm under `latest`. Beta versions publish to npm under `beta`. ## Local dry run To build the full CLI release payload without publishing to npm or GitHub: - `bun run release:publish:dry-run` That produces: - platform archives in `apps/cli/dist` - the packed wrapper tarball in `apps/cli/dist/release` To pack the `@executor-js/*` library packages without publishing: - `bun run release:publish:packages:dry-run` ## Release notes User-facing release notes live at `apps/cli/release-notes/next.md` — one rolling file. **This is the single source of truth users see.** Edit it whenever you ship a user-visible change. `apps/cli/src/release.ts` reads `next.md` and uses its contents as the GitHub Release body. If the file is missing or empty it falls back to `gh release create --generate-notes` (auto-generated from PR titles). There's no per-version archive in the repo — historical release bodies live on GitHub Releases (durable, indexed, linkable). When you start a new release cycle, replace the existing `next.md` content with your new entries; the previous cycle's content is already preserved on the matching `vX.Y.Z` release page. ### Authoring rules Use this section structure (mirrors what's already in `next.md`): ```markdown ## Highlights ### bullets of concrete user value ## Fixes ## Breaking changes ### before / after code blocks for migrations ``` Lead with **user-visible stories**, not commit subjects. Group related commits into one story. Keep bullets single-line so diffs and dedupe tooling stay simple. ### Attribution For external contributors, end the bullet with `Thanks @` and the PR ref: ```markdown - OAuth2 client-credentials flow end-to-end. Thanks @octocat (#456) ``` Don't `Thanks` maintainers, bots, or the repo owner. The lint script (`bun run lint:release-notes`) rejects `Thanks @claude`, `Thanks @rhyssullivan`, `Thanks @github-actions`, etc. — the full list is in `scripts/check-release-notes.ts`. Run it before pushing release notes. ### When you ship a change If your PR adds a `.changeset/*.md` for the `executor` package, also edit `apps/cli/release-notes/next.md`. The changeset describes the version bump; the release-notes file describes the user impact. They're different audiences and shouldn't be conflated. The `.changeset/*.md` body is fine as a one-liner pointing at the release-notes section it expands. ## Notes - Changesets owns the published CLI version via `apps/cli/package.json`. - Only `apps/cli/package.json` should change during release versioning; the rest of the workspace is not version-synced for release PRs. - Changesets changelog file generation is disabled (`changelog: false` in `.changeset/config.json`), but per-package `CHANGELOG.md` stubs are still committed. The `changesets/action@v1` GitHub Action (the wrapper around the CLI used in `release.yml`) reads each bumped package's `CHANGELOG.md` to build the Version Packages PR description and crashes with `ENOENT` if any are missing. The stubs satisfy that read; the changesets CLI alone doesn't need them. - The publish workflow supports either npm trusted publishing or an `NPM_TOKEN` secret. - Re-running the publish workflow for the same tag is safe for packages that are already on npm; existing versions are skipped.