ADR-014: Mono-Repo Children Get a Plain CHANGELOG.md, Not a Suffixed One¶
| Field | Value |
|---|---|
| Date | 2026-07-28 |
| Status | Accepted |
| Deciders | Holger Zahnleiter |
| Supersedes | ADR-012 (changelog naming/path bullet only) |
| Superseded by | — |
Context and Problem Statement¶
ADR-012 gave each mono-repo child a changelog named CHANGELOG-<artifact.name>.md, explicitly
mirroring the convention already used in the separate, non-mono-repo build-images repo. In
build-images, every artifact's changelog sits together at repo root with no subdirectories —
there the suffix is load-bearing, since a plain CHANGELOG.md would collide across artifacts.
A mono-repo child here is different: each artifact already gets its own subdirectory (ADR-011),
generated exactly as repo init would generate it standalone. Inside that subdirectory, the
artifact-name suffix adds nothing — it can never collide with anything, since no other artifact's
files live there. Carrying the suffix forward turned what was a disambiguation mechanism in
build-images into pure noise here.
While reviewing this, a second, latent defect surfaced: GitLab parent-child pipelines share a
single git checkout — $CI_PROJECT_DIR is the mono-repo root for every child pipeline job, never
the artifact's own subdirectory (see ADR-012's "Working-directory scoping" bullet, which already
established the fix pattern for every other job). The changelog job's git cliff -o, git add,
commit, and artifacts: paths: never received that same treatment — they wrote a bare filename
directly at the mono-repo root. Combined with the scaffold-time file living inside the artifact's
subdirectory, a release tag would have produced two diverging files: the stale one from initial
scaffolding, and a second one the CI job actually maintains from then on, at the repo root. This
was never observed in practice because no mono-repo child in this generator's demo instance has
yet cut a release tag.
Decision Drivers¶
- A mono-repo child's own subdirectory already disambiguates its files from every sibling artifact's files — a filename suffix duplicates that disambiguation for no benefit.
- Consistency with ADR-011's core principle: a mono-repo child should look exactly like a standalone repo would, from inside its own subdirectory.
- Each artifact's own
mkdocs.ymllives inside that same subdirectory (no root-levelmkdocs.ymlexists); a changelog placed anywhere else could not be rendered by that artifact's own docs build without an awkward relative reference reaching outside its own directory tree. - Fixing the filename without also fixing the CI job's output path would trade one bug for another (a same-named file both inside the subdirectory and, after the first release, also at the mono-repo root) — the two fixes belong together.
Considered Options¶
- Keep
CHANGELOG-<artifact.name>.md, but move it (and the CI job's output) to the mono-repo root, so every artifact's changelog is visible together at first checkout. - Switch to a plain
CHANGELOG.mdinside each artifact's own subdirectory, and add the same working-directory-scoping thechangelogjob was missing.
Decision Outcome¶
Chosen option: 2. MonoRepoChangelogFileName now always resolves to "CHANGELOG.md". The
changelog CI job gains the same {{if .IsMonoRepoChild}}{{.TechnicalArtifactName}}/{{end}}
prefix already used by every other job in the same file (make -C, test_reports/, build/,
Kaniko's --context/--dockerfile), applied everywhere the job reads, writes, stages, commits,
or publishes the changelog.
Option 1 (root-level, suffixed) was considered and rejected: it would put every artifact's
changelog in one shared root drawer, working against ADR-011's "looks like a standalone repo"
principle, would not be visible to any single artifact's own mkdocs build without external
relative paths, and does not scale cleanly as the number of mono-repo artifacts grows — a
curated root-level index/dashboard is the better answer to "see everything at a glance," without
relocating the file each artifact actually owns.
Positive Consequences¶
- A mono-repo child's
CHANGELOG.mdis indistinguishable in name and location from what a standalone repo of the same kind would have — no special-casing for a human or tool looking inside that one subdirectory. - The latent root-collision bug in the
changelogCI job is fixed as part of the same change, before it could ever manifest against a real release tag. - Each artifact's own
mkdocsbuild can render its own changelog without reaching outside its subdirectory.
Negative Consequences / Risks¶
- Nothing at the mono-repo root lists every artifact's changelog at a glance; a future root-level index/dashboard would need to be built separately if that becomes a real need.
- Every already-scaffolded mono-repo child (e.g. this generator's own demo instance) needs its
existing
CHANGELOG-<artifact>.mdrenamed by hand —repo updatedoes not regenerateCHANGELOG.md(registered non-regenerable), so this is a one-time manualgit mvper artifact, not something futurerepo updateruns will silently fix retroactively for already-generated projects.
Pros and Cons of the Options¶
Option 1 — Root-level, suffixed (rejected)¶
- Pro: Every changelog visible in one
lsat repo root. - Con: Contradicts ADR-011's "looks like a standalone repo" principle for the one file that would now live outside the artifact's own directory.
- Con: Not renderable by an artifact's own per-directory
mkdocsbuild without reaching outside its own tree. - Con: Root directory accumulates one changelog per artifact indefinitely as the mono-repo grows.
Option 2 — Plain, per-subdirectory (chosen)¶
- Pro: Matches standalone-repo output exactly; matches per-artifact
mkdocsdocs builds; scales flatly regardless of mono-repo size. - Con: No single-glance root-level overview (addressable separately, if ever needed, via a root index rather than by relocating the file).
Links¶
- ADR-011 — mono-repo child generated exactly as
repo initwould generate it standalone. - ADR-012 — CI composition across mono-repo artifacts; its "Changelog namespace" bullet is superseded by this ADR, everything else in it remains in force.
internal/templating/model/presentation_model.go—monoRepoChangelogFileName.