feat: Migrate repo releases to manual release-please with centralized changelog
Replace the current single-line `semantic-release` flow and maintainer-local `release-docs` workflow with a repo-owned release system built around `release-please`, a single accumulating release PR, explicit component version ownership, release automation-owned metadata/count updates, and a centralized root `CHANGELOG.md`. The new model keeps release timing manual by making merge of the generated
Overview
feat: Migrate repo releases to manual release-please with centralized changelog
Overview
Replace the current single-line semantic-release flow and maintainer-local release-docs workflow with a repo-owned release system built around release-please, a single accumulating release PR, explicit component version ownership, release automation-owned metadata/count updates, and a centralized root CHANGELOG.md. The new model keeps release timing manual by making merge of the generated release PR the release action while allowing dry-run previews and automatic release PR maintenance as new merges land on main.
Problem Frame
The current repo mixes one automated root CLI release line with manual plugin release conventions and stale docs/tooling. publish.yml publishes on every push to main, .releaserc.json only understands the root package, release-docs still encodes outdated repo structure, and plugin-level version/changelog ownership is inconsistent. The result is drift across root changelog history, plugin manifests, computed counts, and contributor guidance. The origin requirements define a different target: manual release timing, one release PR for the whole repo, independent component versions, no bumps for untouched plugins, centralized changelog ownership, and CI-owned release authority. (see origin: docs/brainstorms/2026-03-17-release-automation-requirements.md)
Requirements Trace
- R1. Manual release; no publish on every merge to
main - R2. Batched releasable changes may accumulate on
main - R3. One release PR for the whole repo that auto-accumulates releasable merges
- R4. Independent version bumps for
cli,compound-engineering,coding-tutor, andmarketplace - R5. Untouched components do not bump
- R6. Root
CHANGELOG.mdremains canonical - R7. Root changelog uses top-level component-version entries
- R8. Existing changelog history is preserved
- R9.
plugins/compound-engineering/CHANGELOG.mdis no longer canonical - R10. Retire
release-docsas release authority - R11. Replace
release-docswith narrow scripts - R12. Release automation owns versions, counts, and release metadata
- R13. Support dry run with no side effects
- R14. Dry run summarizes proposed component bumps, changelog entries, and blockers
- R15. Marketplace version bumps only for marketplace-level changes
- R16. Plugin version changes do not imply marketplace version bumps
- R17. Plugin-only content changes do not force CLI version bumps
- R18. Preserve compatibility with current install behavior where the npm CLI fetches plugin content from GitHub at runtime
- R19. Release flow is triggerable through CI by maintainers or AI agents
- R20. The model must scale to additional plugins
- R21. Conventional release intent signals remain required, but component scopes in titles remain optional
- R22. Component ownership is inferred primarily from changed files, not title scopes alone
- R23. The repo enforces parseable conventional PR or merge titles without requiring component scope on every change
- R24. Manual CI release supports explicit bump overrides for exceptional cases without fake commits
- R25. Bump overrides are per-component rather than repo-wide only
- R26. Dry run shows inferred bump and applied override clearly
Scope Boundaries
- No change to how Claude Code consumes marketplace/plugin version fields
- No end-user auto-update discovery flow for non-Claude harnesses in v1
- No per-plugin canonical changelog model
- No fully automatic timed release cadence in v1
Context & Research
Relevant Code and Patterns
.github/workflows/publish.ymlcurrently runsnpx semantic-releaseon every push tomain; this is the behavior being retired..releaserc.jsonis the current single-line release configuration and only writesCHANGELOG.mdandpackage.json.package.jsonalready exposes repo-maintenance scripts and is the natural place to add release preview/validation script entrypoints.src/commands/install.tsresolves named plugin installs by cloning the GitHub repo and readingplugins/<name>at runtime; this means plugin content releases can remain independent from npm CLI releases when CLI code is unchanged..claude-plugin/marketplace.json,plugins/compound-engineering/.claude-plugin/plugin.json, andplugins/coding-tutor/.claude-plugin/plugin.jsonare the current version-bearing metadata surfaces that need explicit ownership..claude/commands/release-docs.mdis stale and mixes docs generation, metadata synchronization, validation, and release guidance; it should be replaced rather than modernized in place.- Existing planning docs in
docs/plans/use one file per plan, frontmatter withorigin, and dependency-ordered implementation units with explicit file paths; this plan follows that pattern.
Institutional Learnings
docs/solutions/plugin-versioning-requirements.mdalready encodes an important constraint: version bumps and changelog entries should be release-owned, not added in routine feature PRs. The migration should preserve that principle while moving the authority into CI.
External References
release-pleaserelease PR model supports maintaining a standing release PR that updates as more work lands on the default branch.release-pleasemanifest mode supports multi-component repos and per-component extra file updates, which is a strong fit for plugin manifests and marketplace metadata.- GitHub Actions
workflow_dispatchprovides a stable manual trigger surface for dry-run preview workflows.
Key Technical Decisions
- Use
release-pleasefor version planning and release PR lifecycle: The repo needs one accumulating release PR with multiple independently versioned components; that is closer torelease-please's native model than tosemantic-release. - Keep one centralized root changelog: The root
CHANGELOG.mdremains the canonical changelog. Release automation must render component-labeled entries into that one file rather than splitting canonical history across plugin-local changelog files. - Use top-level component-version entries in the root changelog: Each released component version gets its own top-level entry in
CHANGELOG.md, including the component name, version, and release date in the heading. This keeps one centralized file while preserving readable independent version history. - Treat component versioning and changelog rendering as related but separate concerns:
release-pleasecan own component version bumps and release PR state, but root changelog formatting may require repo-specific rendering logic to preserve a single readable canonical file. - Use explicit release scripts for repo-specific logic: Count computation, metadata sync, dry-run summaries, and root changelog shaping should live in versioned scripts rather than hidden maintainer-local command prompts.
- Preserve current plugin delivery assumptions: Plugin content updates do not force CLI version bumps unless the converter/installer behavior in
src/changes. - Marketplace is catalog-scoped: Marketplace version bumps depend on marketplace file changes such as plugin additions/removals or marketplace metadata edits, not routine plugin release version updates.
- Use conventional type as release intent, not mandatory component scope:
feat,fix, and explicit breaking-change markers remain important release signals, but component scope in PR or merge titles is optional and should not be required for common compound-engineering work. - File ownership is authoritative for component selection: Optional title scope can help notes and validation, but changed-file ownership rules should decide which components bump.
- Support manual bump overrides as an explicit escape hatch: Inferred bumping remains the default, but the CI-driven release flow should allow per-component
patch/minor/majoroverrides for exceptional cases without requiring synthetic commits onmain. - Deprecate, do not rely on, legacy changelog/docs surfaces:
plugins/compound-engineering/CHANGELOG.mdandrelease-docsshould stop being live authorities; they should be removed, frozen, or reduced to pointer guidance only after the new flow is in place.
Root Changelog Format
The root CHANGELOG.md should remain the only canonical changelog and should use component-version entries rather than repo-wide release-event entries.
Format Rules
- Each released component gets its own top-level entry.
- Entry headings include the component name, version, and release date.
- Entries are ordered newest-first in the single root file.
- When multiple components release from the same merged release PR, they appear as adjacent entries with the same date.
- Each entry contains only changes relevant to that component.
- The file keeps a short header note explaining that it is the canonical changelog for the repo and that versions are component-scoped.
- Historical root changelog entries remain in place; the migration adds a note and changes formatting only for new entries after cutover.
Recommended Heading Shape
## compound-engineering v2.43.0 - 2026-04-10
### Features
- ...
### Fixes
- ...
Additional examples:
## coding-tutor v1.2.2 - 2026-04-18
### Fixes
- ...
## marketplace v1.3.0 - 2026-04-18
### Changed
- Added `new-plugin` to the marketplace catalog.
## cli v2.43.1 - 2026-04-21
### Fixes
- Correct OpenClaw install path handling.
Migration Rules
- Preserve all existing root changelog history as published.
- Add a short migration note near the top stating that, starting with the cutover release, entries are recorded per component version in the root file.
- Do not attempt to rewrite or normalize all older entries into the new structure.
plugins/compound-engineering/CHANGELOG.mdshould no longer receive new canonical entries after cutover.
Component Release Rules
The release system should use explicit file-to-component ownership rules so unchanged components do not bump accidentally.
Component Definitions
cli: The npm-distributed@every-env/compound-pluginpackage and its release-owned root metadata.compound-engineering: The plugin rooted atplugins/compound-engineering/.coding-tutor: The plugin rooted atplugins/coding-tutor/.marketplace: Marketplace-level metadata rooted at.claude-plugin/and any future repo-owned marketplace-only surfaces.
File-to-Component Mapping
cli
Changes that should trigger a cli release:
src/**package.jsonbun.lock- CLI-only tests or fixtures that validate root CLI behavior:
tests/cli.test.ts- other top-level tests whose subject is the CLI itself
- Release-owned root files only when they reflect a CLI release rather than another component:
- root
CHANGELOG.mdentry generation for theclicomponent
- root
Changes that should not trigger cli by themselves:
- Plugin content changes under
plugins/** - Marketplace metadata changes under
.claude-plugin/** - Docs or brainstorm/plan documents unless the repo explicitly decides docs-only changes are releasable for the CLI
compound-engineering
Changes that should trigger a compound-engineering release:
plugins/compound-engineering/**- Tests or fixtures whose primary purpose is validating compound-engineering content or conversion results derived from that plugin
- Release-owned metadata updates for the compound-engineering plugin:
plugins/compound-engineering/.claude-plugin/plugin.json
- Root
CHANGELOG.mdentry generation for thecompound-engineeringcomponent
Changes that should not trigger compound-engineering by themselves:
plugins/coding-tutor/**- Root CLI implementation changes in
src/** - Marketplace-only metadata changes
coding-tutor
Changes that should trigger a coding-tutor release:
plugins/coding-tutor/**- Tests or fixtures whose primary purpose is validating coding-tutor content or conversion results derived from that plugin
- Release-owned metadata updates for the coding-tutor plugin:
plugins/coding-tutor/.claude-plugin/plugin.json
- Root
CHANGELOG.mdentry generation for thecoding-tutorcomponent
Changes that should not trigger coding-tutor by themselves:
plugins/compound-engineering/**- Root CLI implementation changes in
src/** - Marketplace-only metadata changes
marketplace
Changes that should trigger a marketplace release:
.claude-plugin/marketplace.json- Future marketplace-only docs or config files if the repo later introduces them
- Adding a new plugin directory under
plugins/when that addition is accompanied by marketplace catalog changes - Removing a plugin from the marketplace catalog
- Marketplace metadata changes such as owner info, catalog description, or catalog-level structure changes
Changes that should not trigger marketplace by themselves:
- Routine version bumps to existing plugin manifests
- Plugin-only content changes under
plugins/compound-engineering/**orplugins/coding-tutor/** - Root CLI implementation changes in
src/**
Multi-Component Rules
- A single merged PR may trigger multiple components when it changes files owned by each of those components.
- A plugin content change plus a CLI behavior change should release both the plugin and
cli. - Adding a new plugin should release at least the new plugin and
marketplace; it should releaseclionly if the CLI behavior, plugin discovery logic, or install UX also changed. - Root
CHANGELOG.mdshould not itself be used as the primary signal for component detection; it is a release output, not an input. - Release-owned metadata writes generated by the release flow should not recursively cause unrelated component bumps on subsequent runs.
Release Intent Rules
- The repo should continue to require conventional release intent markers such as
feat:,fix:, and explicit breaking change notation. - Component scopes such as
feat(coding-tutor): ...are optional and should remain optional. - When a scope is present, it should be treated as advisory metadata that can improve release note grouping or mismatch detection.
- When no scope is present, release automation should still work correctly by using changed-file ownership to determine affected components.
- Docs-only, planning-only, or maintenance-only titles such as
docs:orchore:should remain parseable even when they do not imply a releasable component bump.
Manual Override Rules
- Automatic bump inference remains the default for all components.
- The manual CI workflow should support override values of at least
patch,minor, a