Entscheidung
ADR 0005: Trunk-based development and automated releases
Diese Seite gibt es nur auf Englisch.
Auf dieser Seite
- Status: Accepted
- Date: 2026-11-07
Context#
The maintainer's other projects use two long-lived branches: work lands on stage, and stage is
promoted to main for releases. This project is open source and expects external contributors:
- Forks and pull requests target the default branch. A second integration branch is one more thing for contributors to get wrong.
- release-please works from a single release branch and derives versions and the changelog from Conventional Commits.
- npm trusted publishing (OIDC, no long-lived
NPM_TOKEN) and the MCP Registry publisher are tied to a specific workflow on a specific branch.
Decision#
- One long-lived branch,
main. All PRs target it. A ruleset requires a PR and passing checks, allows squash merges only, keeps history linear, forbids force pushes and protects tags. - PR titles are Conventional Commits, checked in CI. With squash merges the PR title becomes the
commit message on
main. - release-please keeps a release PR open with the next version and changelog. Merging it tags
the release and triggers publishing:
- npm with provenance through trusted publishing (the very first version is published by hand, then the trusted publisher is configured);
- the MCP Registry entry through
mcp-publisherwith GitHub OIDC; - the
.mcpbbundle as a release asset; - the multi-arch GHCR image with a build-provenance attestation and an SBOM.
- 0.x releases from the first milestone on, so people can try the server early; 1.0.0 at launch.
Consequences#
- Good: contributors only need to know "branch off
main, open a PR". - Good: every merge to
mainis releasable; versions and changelog are automatic. - Good: no publish secrets in the repository; releases carry provenance.
- Bad: no staging branch where changes collect before a release. The release PR is the batching
point, and the CI gate (lint, types, tests with coverage, package smoke on three OSes) has to be
strong enough to keep
mainreleasable. - Bad: it differs from the maintainer's other repositories.
Alternatives considered#
stage→mainpromotion. Rejected for this repository: it confuses fork-based contributors and fights release-please's single-branch model.- GitFlow. Rejected: too much process for one package.
- changesets or semantic-release. Rejected: changesets needs a file per PR from contributors; semantic-release publishes on every merge without a reviewable release PR.
- Manual tags and
NPM_TOKEN. Rejected: error-prone, and a long-lived publish token is a supply-chain risk.