Status: Accepted Date: 2026-07-18 Authors: Development Team Supersedes: ADR-0006 (Versioning and Release Strategy) Superseded by: N/A
Context and Problem Statement#
ADR-0006 (2026-01-10) selected Changesets as the monorepo's versioning and
release mechanism. Its implementation plan was never executed: no
.changeset/config.json was ever created, no changeset files were ever
authored, and no CI workflow invokes the changesets CLI. Meanwhile the release
pipeline that actually shipped — .github/workflows/release.yml — was built on
nx release: pnpm nx release version <v> --git-commit --git-tag followed
by pnpm nx release publish --tag latest, driven by the release block in
nx.json (conventional commits, per-project changelogs, GitHub release
creation).
The 2026-07-16 monorepo architecture audit (finding C-8) flagged the
resulting ambiguity: two release mechanisms coexisted in package.json (the
dead changeset/version-packages/release scripts plus the @changesets/cli
devDependency) with no explicit decision on which owns releases.
Decision#
nx release owns versioning, changelogs, and publishing. The changesets
scripts and the @changesets/cli devDependency are removed. ADR-0006 is
superseded: its analysis remains a valid record, but its chosen option was never
implemented and the de facto standard is the one wired into CI.
Rationale:
- Reality wins.
release.ymlhas only ever released vianx release; changesets never progressed past a devDependency. Re-platforming the working pipeline onto the unimplemented choice would be churn without benefit. - Conventional commits are already enforced (commitlint with the
registry-generated scope enum), so
nx release's commit-parsing changelog input is trustworthy here — the "explicit intent" advantage ADR-0006 credited to changesets is substantially covered by the commit convention. - One less toolchain. Nx already orchestrates build/test/lint; keeping version/publish in the same tool removes a second config surface.
Release scope#
nx.json release.projects is ["libs/*", "apps/*"]. Because slash-containing
globs match project roots, this deliberately reaches only the single-level
packages (libs/contracts, libs/proto, libs/openapi, …) — the public
interface surface — and none of the ~3,300 nested internal workspace packages.
Widening this scope is a deliberate per-package publishing decision, not a
config cleanup (audit C-8): adding a nested glob would put every internal
package into the publish set.
Consequences#
package.jsonno longer carrieschangeset,version-packages, orreleasescripts;@changesets/cliis removed from devDependencies.- Releases are dispatched via
release.yml(workflow_dispatch) which computes the version and runsnx release version/publish. - Any future desire for changeset-style explicit intent files should be re-proposed as a new ADR rather than resurrecting the dormant tooling.