How to cut a new Containarium (OSS) release: which files change, how the release pipeline is triggered, and how to confirm it actually shipped.
This covers the containarium repo only. containarium-cloud is a
separate, closed-source repo with its own (stricter) release gate — not
covered here.
Containarium follows Semantic Versioning —
vMAJOR.MINOR.PATCH, e.g. v0.48.2. Tags are the source of truth for
what a released binary reports as its version; see How release builds
get their version below for why
that matters.
CHANGELOG.md— move the## [Unreleased]section's contents (or add new entries) under a new## [X.Y.Z] - YYYY-MM-DDheading, above the previous release. Keep an empty## [Unreleased]heading at the top for the next round of changes. Follow Keep a Changelog categories (Added,Fixed,Changed, etc.).pkg/version/version.go— bump theVersionconstant to match the tag (novprefix, e.g."0.48.2").
That's it — two files, one commit, conventionally messaged
chore(release): cut vX.Y.Z — <one-line summary> (see recent history on
main for the pattern). PR it, get CI green, merge like any other
change.
Not required: web-ui/package.json's version field is versioned
independently of the daemon and does not need to track the release tag.
pkg/version/version.go's Version constant is only the fallback
used by a plain go build / make build. A real release build
overrides it via ldflags:
make build-release VERSION="${GITHUB_REF_NAME#v}"
.github/workflows/release.yml triggers on any pushed tag matching
v* and runs exactly this. There is currently no CI gate that checks
pkg/version/version.go matches the tag — a forgotten bump won't fail
the release build, it just means anyone building from source with plain
go build between releases sees a stale fallback version. Bump it
anyway; it's the only thing a non-release build has to go on.
- Confirm everything you want in the release is merged to
main. - Branch off
main, make the two file changes above, commit, PR, merge (see Files to change). - Tag the merged commit on
mainand push the tag:git checkout main && git pull git tag v0.48.2 git push origin v0.48.2 - This triggers
release.yml, which runsmake build-release(10 artifacts: the CLI for linux/darwin-amd64/darwin-arm64/windows, the MCP server and agent-box binaries for linux/darwin-amd64/darwin-arm64, plus a generatedSHA256SUMS.txt) and publishes them as a GitHub Release attached to the tag. - Verify the release actually built and published — don't treat a
pushed tag as done. Check the Release page has all expected
artifacts and
SHA256SUMS.txt, and thatcontainarium versionon a freshly downloaded binary reports the new tag.
Both caught after a tag was pushed, because nothing exercised the real release build at PR time:
- v0.47.0: the release build's Windows CLI binary
(
GOOS=windows go build ./cmd/containarium/) broke because a new file undercmd/transitively imported the Linux-only eBPF loader (internal/netbpf) without a//go:build !windowsguard. Regular PR CI never cross-compiled for Windows, so this was invisible until the release build itself failed. - v0.48.0:
make build-release's fullnext build(with real TypeScript type-checking) failed on two genuine web-ui compile errors. Neither was caught at PR time — no CI job ran a full production web-ui build;next devand lint both stayed green. No artifacts were ever published from the v0.48.0 tag — it's a dead tag, superseded by v0.48.1.
Both classes of gap are now covered by PR-time CI (see the "Windows
build guard" and "Web UI build guard" steps in
.github/workflows/proxyproto-e2e.yml) — but treat that as defense in
depth, not a reason to skip verifying a specific release's artifacts
before pointing anything at it.
Cutting a release and deploying it to a specific host are two different actions — don't conflate them. Once a tag's artifacts are verified published:
scripts/deploy-binary.shis the operator-side tool for rolling a release binary onto a primary + sentinel pair. See its own--helpand the script's inline comments for current flags and known gotchas (host daemon service unit naming has drifted between hosts before; verify the live unit before scripting a restart).- Never scp an ad hoc binary built from an untagged commit onto a host that serves real traffic. If a fix needs to reach production, cut a release for it first — that's the whole point of this document.