Release pipeline
Maintainer workflow for versioning and publishing the A2C workflow product
(a2c-core, a2c-cli, a2c-tui).
Normative policy: ADR-0009 (supersedes ADR-0004). Python registry publishing: ADR-0010.
Package publishing details: package-publishing.md.
Script index: scripts/README.md. Implementation plan: plans/release-orchestration.md.
Automated release (recommended)
From a clean checkout with GITLAB_TOKEN set:
python scripts/publish_release.py --align-develop
Dry-run:
python scripts/publish_release.py --dry-run --bump patch
The orchestrator creates release/X.Y.Z, runs bump_release.py, waits for Development CI, pushes the tag, waits for Release CI (including ADR-0010 publish jobs), then ff-merges master (and develop with --align-develop).
Partial steps: --from-step, --stop-after. See python scripts/publish_release.py --help.
Branch and CI profiles (ADR-0009)
| Ref | Role | CI profile |
|---|---|---|
Feature branch or develop | Day-to-day work | Development CI |
release/X.Y.Z | Release bump and qualification | Development CI |
Tag vX.Y.Z | Canonical release marker | Release CI (build, publish, binaries) |
master | Integrated history | Master CI (light, non-gating) |
Normal development (untagged → master)
- Work on a feature branch or
develop - Wait for green Development CI
- Fast-forward merge to
master(untagged, code_clean)
Release steps (release/X.Y.Z → tag → master)
-
Land features; ff-merge code_clean commits to
master -
Create release branch from
master:git checkout master && git pull origin mastergit checkout -b release/X.Y.Z -
Run
python scripts/bump_release.pyon the release branch -
Push
release/X.Y.Z -
Wait for green Development CI on the release branch
-
Tag and push:
git push origin vX.Y.Z -
Wait for green Release CI on the tag
-
Fast-forward
masterfrom the release branch
If Release CI fails: fix on release/X.Y.Z, rerun Development CI, move tag if needed, retry.
CI on tags (Release CI)
| Job | Purpose |
|---|---|
release:verify | Tag matches VERSION and a2c_core.__version__ |
package:build | Build six final-release artifacts at X.Y.Z; twine check |
package:a2c-cli-binary | PyInstaller a2c linux x64 (permanent artifact) |
package:a2c-cli-binary-linux-arm64 | PyInstaller a2c linux arm64 |
package:a2c-tui-binary | PyInstaller a2c-tui linux x64 |
package:a2c-tui-binary-linux-arm64 | PyInstaller a2c-tui linux arm64 |
package:smoke | Install wheels from dist/ at X.Y.Z |
publish:gitlab | GitLab package registry upload (X.Y.Z) |
publish:testpypi | Query TestPyPI, publish unused X.Y.ZrcU, automatic |
package:smoke-testpypi | Install X.Y.ZrcU from TestPyPI |
publish:pypi | Assert X.Y.Z absent on PyPI, upload final release, automatic |
package:smoke-pypi | Install X.Y.Z from PyPI — released gate |
Fast-forward master only after package:smoke-pypi succeeds.
Master CI (light)
| Job | Purpose |
|---|---|
master:integration-record | Non-gating audit on master pushes |
Local dry-run
python scripts/bump_release.py --dry-run
python scripts/build_packages.py