Operational guide for cutting a release of pbr-cpp-memory-pool. The policy that governs this workflow is ADR-0004, amended by ADR-0008 for the tag-push delegation; the high-level summary lives in AGENTS.md §11.
A new tag is cut whenever a milestone closes (per ADR-0004 §2) or when a hotfix lands between milestones.
| Trigger | Tag form | Initiator |
|---|---|---|
| Milestone N closes (N = 1..6) | v0.N.0 |
Agent ¹ |
| Milestone 7 closes (full release) | v1.0.0 |
Agent ¹ |
| Milestone feature-complete, under review | v0.N.0-rc.M |
Agent ¹ |
| Hotfix between milestones | v<X.Y.(Z+1)> |
Agent ¹ |
¹ The agent creates and pushes the annotated tag immediately after the corresponding release (or hotfix) PR merges to master, per ADR-0008. The maintainer still controls whether a release happens — they review and merge the release PR, and they retain the final Publish checkpoint on the draft GitHub Release that release.yml produces.
The agent-vs-human boundary mirrors the PR-merge boundary in AGENTS.md §6.1, with the tag-creation and tag-push steps delegated to the agent per ADR-0008 (the amendment of ADR-0004 §6 motivated by the v0.1.0 release). The Publish click remains a deliberate human checkpoint:
| Action | Who |
|---|---|
| Bump version constant in source | Agent |
Update CHANGELOG.md (Unreleased → version) |
Agent |
| Draft GitHub Release notes | Agent |
| Open the release PR | Maintainer |
| Merge the release PR | Maintainer |
| Create annotated git tag | Agent ¹ |
| Push the tag | Agent ¹ |
| Publish the GitHub Release | Maintainer |
| Build & attach release artifacts | CI |
¹ See ADR-0008: the agent runs git tag -a and git push origin v<X.Y.Z> immediately after the release PR merges to master. The agent never amends or deletes a published tag; the only acceptable corrective action is delete-and-repush of an unpublished tag whose release.yml run visibly failed (the escape hatch documented in ADR-0008's Decision section).
The flow below assumes Milestone 1 is closing, producing v0.1.0. Adjust the version number for other milestones.
git switch -c release/v0.1.0
Branch naming for releases: release/v<X.Y.Z>. The release/ prefix joins the existing branch-type vocabulary (feat/, fix/, docs/, …) — it carries the same one-logical-change-per-commit rule.
A single source of truth for the project version lives in src/main/cpp/it/d4np/memorypool/version.hpp (added in Milestone 1.6). It exposes:
namespace it::d4np::memorypool {
inline constexpr unsigned PBR_MEMORY_POOL_VERSION_MAJOR = 0;
inline constexpr unsigned PBR_MEMORY_POOL_VERSION_MINOR = 1;
inline constexpr unsigned PBR_MEMORY_POOL_VERSION_PATCH = 0;
inline constexpr const char* PBR_MEMORY_POOL_VERSION_STRING = "0.1.0";
} // namespace it::d4np::memorypoolCMakeLists.txt reads these constants when configuring the project (project(pbr_memory_pool VERSION ...)); never edit the version in CMake directly.
Bump the three integers and the string to the target version. Commit:
git commit -m "chore(release): bump version to 0.1.0"
CHANGELOG.md follows Keep a Changelog. Released entries are immutable, one file per release under docs/changelog/v<MAJOR>/v<X.Y.Z>.md; the root CHANGELOG.md carries only the [Unreleased] block and the Released versions index (ADR-0038). To cut a release, move — never copy-and-edit-in-place — the accumulated Unreleased entries into a new per-version file:
-
Create
docs/changelog/v<MAJOR>/v<X.Y.Z>.mdfrom the currentUnreleasedbody, with the dated heading and its own link definition:# Changelog — v0.1.0 > Immutable release entry — part of the [project changelog](../../../CHANGELOG.md). … ## [0.1.0] — YYYY-MM-DD ### Added - … [0.1.0]: https://github.com/danielPoloWork/pbr-cpp-memory-pool/releases/tag/v0.1.0
-
Reset the root
Unreleasedblock to empty (keep its intro sentence), and update the[Unreleased]:compare link tocompare/v<X.Y.Z>...HEAD. -
Add a row to the Released versions index table in
CHANGELOG.md(newest first): version link, date, one-line highlight.
The version-lockstep consistency check reads the latest version from the per-version files, so the new file must exist and match version.hpp. Commit:
git commit -m "docs(changelog): roll Unreleased into 0.1.0"
Add a docs/releases/v0.1.0.md file containing the release notes that will be posted to GitHub. The body should:
- Lead with the milestone's headline outcome (one sentence).
- Summarise the Added / Changed / Fixed lines from
CHANGELOG.mdin human-readable prose, grouped by theme rather than by category. - Link to the closing PR and to the roadmap milestone.
- Note which Spec Coverage Map rows flipped to ✅ in this release.
- Call out any known limitations or deferred work.
Commit:
git commit -m "docs(release): draft v0.1.0 release notes"
git push -u origin release/v0.1.0
PR title: chore(release): v0.1.0. PR body: the standard template (.github/PULL_REQUEST_TEMPLATE.md), with the Summary section pointing to docs/releases/v0.1.0.md and the Documentation Impact checkboxes covering CHANGELOG + release notes + version bump.
Agent stops here. The maintainer reviews the PR.
Squash-and-merge, same as any other PR. The merge commit's body becomes the durable git log entry; the user-facing release notes live in the GitHub Release created in §8.
Delegated to the agent in ADR-0008. Immediately after §6 merges, the agent runs, from a local clone synchronised with the merge commit:
git fetch origin
git checkout master
git pull --ff-only
git tag -a v0.1.0 -m "v0.1.0 — <milestone headline>"
git push origin v0.1.0
Tag messages mirror the release-notes headline. Annotated tags only — never lightweight tags (they don't carry a message). The push triggers release.yml (§8); the agent's job ends here. The maintainer reviews and Publishes the draft Release that the workflow produces.
If the agent observes a visible failure in the release.yml run before §8's Publish click — wrong commit tagged, build matrix produced corrupt artifacts, or the release-notes file is missing — it deletes the tag and repushes after the underlying problem is fixed:
git push --delete origin v0.1.0
git tag -d v0.1.0
# fix the underlying problem, then re-run the four-line sequence above.
This escape hatch is the only legitimate tag-mutation operation after §7. Once the maintainer Publishes (§8), the tag is consumer-visible and effectively immutable.
The tag push triggers the release CI workflow (added in Milestone 1.12). The workflow:
- Runs the full test matrix.
- Builds per-platform artifacts (Linux x86_64, Windows x86_64, macOS arm64) — degrades gracefully if a platform is not yet set up.
- Creates a draft GitHub Release with the body copied from
docs/releases/v0.1.0.md, attaches the source and binary artifacts plusSHA256SUMS. - Stops in Draft state.
The maintainer reviews the draft release, edits notes if needed, and clicks Publish. CI does not auto-publish — the human keeps the final say (mirrors the PR-merge boundary).
Post-1.0 governance — how to choose the SemVer level (patch / minor / major), the hotfix-by-releasability and backport rules, the security-fix path, and the deprecation policy — lives in
maintenance.md(ADR-0034). This section is the mechanical short form for the common case.
A defect found between milestone tags follows a compressed version of the above:
git switch -c fix/<short-name>frommaster.- Fix the bug; add tests.
- Add a
Fixedline toCHANGELOG.mdunderUnreleased. - Open the PR — normal flow.
- After merge, the maintainer decides whether to cut a patch tag (
v0.1.1) immediately or batch it with the next milestone tag. - If a patch tag is cut, repeat §3–§8 with the patch version.
-alpha.N, -beta.N, -rc.N follow SemVer 2.0 ordering: 1.0.0-alpha.1 < 1.0.0-beta.1 < 1.0.0-rc.1 < 1.0.0. Use them when:
- The milestone is feature-complete but undergoing soak testing →
-rc.N. - Major work is partially shippable but known-incomplete →
-alpha.N/-beta.N(rare in this project).
Pre-release tags trigger the same CI workflow as final tags, but the GitHub Release is automatically marked pre-release.
- Pushing to package registries (vcpkg, Conan) — gated behind v1.0.0 per ADR-0004 §5.
- Maintaining release branches — single-maintainer project; reconsider only if a parallel major-version line emerges.
- Auto-publishing releases without human review — explicitly rejected by ADR-0004 §6.