Skip to main content

ADR 0064: Automate Draft Release Proposals Without Releasing

Status: Accepted

Date: 2026-08-01

Context

ADR 0063 gave new STAGE commits machine-readable change types but deferred release automation until its authority and update boundaries were explicit.

STAGE releases synchronize a plugin package version, website package metadata, method-version references when applicable, compatibility guidance, a changelog, and a required evidence-bearing release record. An automated version guess cannot decide whether those materials are complete, whether a change alters the method version, or whether the plugin is ready to refresh and publish.

Release Please can separately prepare a release pull request and create a tag or GitHub Release. The first operation reduces recurring version and changelog work. The second is a release action and must remain human-owned.

Decision

Run a pinned Release Please v5 workflow only after STAGE quality gate succeeds for main, with manual dispatch available for recovery. Configure it to open or update a draft release pull request and explicitly skip GitHub release and tag creation.

For a quality-triggered run, the workflow also confirms that the successfully verified revision still heads main. If main has advanced, that run does not prepare a proposal; the quality run for the newer revision becomes the next opportunity. Manual dispatch always operates on the current main.

The automated proposal may update only:

  • .release-please-manifest.json;
  • root package.json and package-lock.json release mirrors;
  • plugin/.codex-plugin/plugin.json, which remains the plugin package version;
  • website/package.json; and
  • CHANGELOG.md from accepted Conventional Commits.

The root package version and Release Please manifest are automation mirrors, not independent release identities. Repository tests keep them synchronized with the plugin and website versions.

Every generated proposal starts as a draft. Before marking it ready, a human must:

  • reconcile the existing Unreleased changelog material with the proposed version section;
  • refresh website/package-lock.json from the proposed website version;
  • decide whether SPEC.md method major/minor changes;
  • update all current-version, compatibility, adoption, and evaluation references;
  • add docs/releases/<version>.md with evidence and limitations;
  • run the full release gate and direct package validators; and
  • approve the version and complete diff.

Merging the completed proposal does not create a tag, GitHub Release, plugin publication, public source publication, or package refresh. The maintainer creates the annotated tag and any GitHub Release explicitly after inspecting the merged revision, then performs the existing plugin refresh and fresh-task verification.

The workflow uses only repository-content and pull-request write permissions and skips labels to avoid issue permission. It prefers an optional scoped STAGE_RELEASE_PLEASE_TOKEN; without that secret it falls back to GITHUB_TOKEN. GitHub does not start new workflows for pull requests created with GITHUB_TOKEN, so the first human completion commit must establish the PR quality run before merge.

For pre-1.0 releases, breaking changes propose a minor rather than major bump. The proposal remains editable and rejectable; commit syntax never grants release approval.

Consequences

  • Conventional Commit metadata now has a bounded automated consumer.
  • Repeated version and changelog preparation becomes reviewable draft work without automating publication.
  • Release proposals deliberately begin incomplete and fail closed on the existing version, release-record, and documentation contracts until a human completes them.
  • The default Actions token keeps credential scope narrow but does not trigger the initial pull-request checks. A future scoped token or GitHub App may remove that limitation without widening release authority.
  • Existing pre-adoption Unreleased material remains human-curated; automation begins at the Conventional Commit adoption boundary.