Skip to main content

ADR-0004: Standardized CI bump and release flow for A2C projects

  • Status: Superseded
  • Date: 2026-06-12
  • Deciders: Michel Gillet
  • Superseded by: ADR-0009

Context

A2C-governed software repositories already require:

In practice, releases across projects have been inconsistent:

  • some bump versions manually in scattered files
  • some create tags by hand without verifying version sources
  • changelog updates can lag behind merged work
  • CI may run tests but not participate in a shared release discipline

CI systems (for example GitLab CI) can run quality gates, verify tagged releases, and drive optional artifact publication. A2C needs a predictable, repeatable bump-and-release pattern that works across docs-only workflow repos, Python packages, and similar A2C-governed software — with minimal manual steps and no ad-hoc UI-only releases.

Reference implementations exist in a2c-workflow (docs-only, VERSION + release:verify) and superbuild-workflow (Python package, tag pipeline with build/publish). This ADR standardizes the shared semantics those examples encode.

Decision

All A2C-governed software repositories must adopt the standard CI-driven bump and release flow defined here.

Versioning and release markers

  • Released versions follow Semantic Versioning (MAJOR.MINOR.PATCH).
  • Git annotated tags named vX.Y.Z are the canonical release markers.
  • Each tag must correspond to exactly one released semver and one finalized changelog section ## [X.Y.Z] - YYYY-MM-DD.

Changelog responsibility

PhaseWho updates CHANGELOG.mdHow
DevelopmentHumans and AICurate bullets under ## [Unreleased] as release-relevant work lands
ReleaseRelease scriptMove [Unreleased] into the version heading; reset [Unreleased] placeholders

CI does not invent changelog bullets from commit history. CI may verify that a release is internally consistent (version file, tag name, changelog section).

The check-changelog hook (ADR-0003) enforces staging discipline during development; the release script finalizes structure at bump time.

Bump type (major / minor / patch)

A2C uses a human-confirmed, script-assisted model:

  1. scripts/bump_release.py inspects conventional commit subjects since the latest v*.*.* tag and suggests patch, minor, or major.
  2. The maintainer confirms interactively or overrides with --bump patch|minor|major (or --version X.Y.Z when needed).
  3. CI does not auto-bump versions on merge.

Rationale: A2C prioritizes curated changelog intent and explicit maintainer judgment over fully autonomous semver from commit metadata alone.

Standard release sequence

On develop, after a green branch pipeline:

  1. Curate CHANGELOG.md [Unreleased] for the intended release.
  2. Run python scripts/bump_release.py (optionally --dry-run first).
  3. Push develop, then fast-forward master from develop.
  4. Create and push annotated tag vX.Y.Z from master (locally via script --tag, or git tag -a + git push origin vX.Y.Z).

Branch pipelines must run tests and quality checks before maintainers cut a release. Tag pipelines must include a release:verify (or equivalent) job that fails when the tag and on-disk version source disagree.

Required CI shape

Project .gitlab-ci.yml (or equivalent CI) must include:

Stage / jobRequiredPurpose
lint / test on develop, master, MRsYesGate work before release
release:verify (or named equivalent) on tags v*.*.*YesTag ↔ version source consistency
build / publish jobs on tagsPer project typeWheels, containers, registry uploads, etc.

Projects must use script-driven bump and verify steps — not manual GitLab UI version fields or ad-hoc tag creation without the standard scripts.

Version source of truth

Each project documents one primary version source read by verify_release_version.py:

Project typeTypical source
Docs / workflow reporoot VERSION file
Python package__version__ in the installable package
Other stacksProject ADR or docs/release-pipeline.md names the file

bump_release.py and verify_release_version.py may be copied from a2c-workflow or superbuild-workflow and adapted for the project's version path and GitLab project slug.

Reference implementation

Consuming projects should start from:

Optional artifact publication (PyPI, GitLab registry, containers) is project-specific but must not bypass the shared bump → tag → verify sequence.

Rationale

  • Consistency — every A2C project shares the same release semantics and script names
  • Traceability — each vX.Y.Z tag has a changelog section and a green pre-release CI history
  • Reliability — scripted bumps reduce manual version/file drift
  • Compatibility — integrates with Keep a Changelog, SemVer, and check-changelog without requiring semantic-release-style automation

Consequences

Positive

  • New projects bootstrap a working release flow instead of inventing one
  • AI agents have an explicit pattern for CI and release scripts
  • Reference repos (a2c-workflow, superbuild-workflow) dogfood the same contract

Negative

  • Existing projects need migration: scripts, CI jobs, tag protection, and maintainer habit changes
  • Additional CI configuration and protected-tag setup
  • Coupling between CI, CHANGELOG.md, and the chosen version source path

Migration

Existing A2C-governed projects should:

  1. Add scripts/bump_release.py and scripts/verify_release_version.py (adapted from reference repos)
  2. Add release:verify (or equivalent) to tag pipelines
  3. Document project-specific publish jobs in docs/release-pipeline.md
  4. Align tag naming and changelog finalization with this ADR

Projects on non-GitLab CI or exotic release models need a project-specific ADR documenting deviations.

Relationship to other ADRs

ADRRelationship
ADR-0002Builds on — defines changelog format and semver; this ADR operationalizes release mechanics
ADR-0003Complementscheck-changelog enforces [Unreleased] discipline before the release script finalizes

References