Versioning¶
Scheme¶
Merovingian uses 0.MINOR.PATCH before 1.0.
PATCH is the working counter: every branch — feature, fix, packaging, or
documentation-only — increments it by one.
MINOR is a series marker, not a milestone. It rolls over when a PATCH
series has grown long enough to be unwieldy, or at a natural grouping of work.
A new series does not restart at .0; it continues from wherever the
rollover happened. Both rollovers to date worked that way — 0.9.25 → 0.10.1
and 0.10.63 → 0.11.4 — and no 0.10.0 or 0.11.0 was ever cut.
1.0.0 is the one version number that carries a meaning: it is cut when the
project reaches production, as defined by
todos/production-milestone.md.
Project phase is declared in README.md and CHANGELOG.md, never encoded in
the version number. Beta was declared at v0.10.59 — mid-series, which is
what the rules above imply. Do not read a phase transition into a MINOR
rollover, and do not hold a rollover back waiting for one.
The version is a plain string — there is no pre-release suffix, build metadata,
or epoch. All three numbers are always present (e.g. 0.11.4, never 0.11).
Bump policy¶
One bump per branch, when the branch is created. Update CHANGELOG.md
and every version location below together before the branch's first commit.
Do not increment again on intermediate commits. Before raising the PR, verify
that the version remains consistent with the base branch; if another branch
has used that version in the meantime, update all locations together to the
next available patch version. There is no separate merge-time bump.
Canonical source of truth¶
meson.build — the version: field in the project() call — is the single
authoritative version. Everything else copies from it.
Every location that must be updated¶
Update all of the following in one commit when the version changes. Missing any one of them will produce a package or binary that reports a different version than the others.
| File | What to change |
|---|---|
meson.build |
version: 'X.Y.Z' in the project() call |
src/main.cpp |
constexpr auto version = std::string_view{"X.Y.Z"}; |
src/db_migrate.cpp |
constexpr auto version = std::string_view{"X.Y.Z"}; |
packaging/freebsd/+MANIFEST |
version: "X.Y.Z" |
packaging/netbsd/Makefile |
DISTNAME= merovingian-X.Y.Z |
packaging/rpm/merovingian.spec |
Version: X.Y.Z and add a new %changelog entry at the top |
packaging/rhel/merovingian.spec |
Version: X.Y.Z and add a new %changelog entry at the top |
packaging/opensuse/merovingian.spec |
Version: X.Y.Z and add a new %changelog entry at the top |
scripts/build-deb.sh |
Comment line and VERSION="X.Y.Z" |
scripts/build-rpm.sh |
Comment line and VERSION="X.Y.Z" |
scripts/build-rhel-rpm.sh |
Comment line and VERSION="X.Y.Z" |
scripts/build-opensuse-rpm.sh |
Comment line and VERSION="X.Y.Z" |
scripts/build-freebsd-pkg.sh |
Comment line and VERSION="X.Y.Z" |
scripts/build-netbsd-pkg.sh |
Comment line and VERSION="X.Y.Z" |
scripts/build-openbsd-pkg.sh |
Comment line and VERSION="X.Y.Z" |
scripts/build-static-linux.sh |
VERSION="${MEROVINGIAN_VERSION:-X.Y.Z}" |
CHANGELOG.md |
New ## X.Y.Z section at the top |
Notes¶
- The
.debDEBIAN/controlversion is generated at build time from theVERSIONvariable inscripts/build-deb.sh— it does not need a separate edit. - The
packaging/deb/controltemplate has no version field; it is used only forDependsand other metadata, not the package version. - The RPM-family
%changelog(therpm,rhel, andopensusespecs) requires a new dated entry for every version — theVersion:field alone is not sufficient forrpmbuildto accept the spec. - Historical version strings in
CHANGELOG.mdand every spec%changelogare records, not live values; do not edit them when bumping. tests/tooling/test_packages_workflow.pyenforces that every file in the table above carries the currentmeson.buildversion. Run it (orpython build.py wsl) after a bump to catch any location that was missed.
Release process¶
- Update
mainfromorigin, then create a feature or fix branch from it. - Increment the patch version in every location above and add its changelog section.
- Make the changes and keep that version for intermediate commits.
- Before raising the PR, check version consistency and conflicts with the base branch.
- Raise a PR. CI builds the configured platform artifacts and runs the test suite; see platform-support.md for the artifact matrix.
- Merge to
main. Thepublish-latestCI job replaces the rolling GitHublatestpre-release with the new artifacts automatically. - For a tagged release, push a
vX.Y.Ztag — a separate CI workflow creates the versioned GitHub release.