Package publishing (a2c-core, a2c-cli, a2c-tui)
Three lockstep Python distributions are built and published from this repository
(ai-workflows/a2c-workflow).
| PyPI distribution | Import package | Console script |
|---|---|---|
a2c-core | a2c_core | — |
a2c-cli | a2c_cli | a2c |
a2c-tui | a2c_tui | a2c-tui |
All three share one product version (a2c_core.__version__, root VERSION, git tag vX.Y.Z).
Release runbook: release-pipeline.md
Normative policy: ADR-0010 (specializes ADR-0009)
Package layout
- Build: PEP 517
setuptoolsviapackages/*/pyproject.toml - Source: shared
src/a2c_core/,src/a2c_cli/,src/a2c_tui/ - Version:
src/a2c_core/__init__.py(__version__) — synced byscripts/bump_release.py - Dependencies:
a2c-clianda2c-tuipina2c-core==X.Y.Zin theirpyproject.toml
Local development install
pip install -e "./packages/a2c-core" -e "./packages/a2c-cli" -e "./packages/a2c-tui" -e ".[dev]"
Or run ./scripts/setup-dev.sh (Windows: .\scripts\setup-dev.ps1).
Local build and smoke
python scripts/build_packages.py
python -m twine check dist/*
python scripts/smoke_install_packages.py --dist dist --expected-version 0.1.1 --venv .smoke-venv
a2c validate --help
Artifacts: six files in dist/ (wheel + sdist for each distribution).
CI pipeline (GitLab)
| Stage | Job | When |
|---|---|---|
| lint | pre-commit, workflow-docs:contract | feature branch / develop / release/* / MR |
| test | test:pytest | feature branch / develop / release/* / MR |
| build | build:package | Development CI (build only; no registry publish) |
| build | build:a2c-cli-binary | Development CI (linux x64 artifact: dist/binary/a2c) |
| build | build:a2c-cli-binary-linux-arm64 | Development CI (linux arm64 artifact: dist/binary/a2c) |
| build | build:a2c-tui-binary | Development CI (linux x64 artifact: dist/binary/a2c-tui) |
| build | build:a2c-tui-binary-linux-arm64 | Development CI (linux arm64 artifact: dist/binary/a2c-tui) |
| build | package:build | tags v*.*.* (final X.Y.Z artifacts) |
| release | release:verify | tags |
| release | package:smoke | tags (local wheel smoke at X.Y.Z) |
| publish | publish:gitlab | tags (automatic, X.Y.Z) |
| publish | publish:testpypi | tags (automatic; queries TestPyPI, publishes unused X.Y.ZrcU) |
| publish | package:smoke-testpypi | tags (smoke X.Y.ZrcU from TestPyPI) |
| publish | publish:pypi | tags (automatic after TestPyPI smoke; uploads X.Y.Z) |
| publish | package:smoke-pypi | tags (smoke X.Y.Z from PyPI) |
Development CI never publishes to TestPyPI or PyPI.
Automated tag publishing flow (ADR-0010)
package:buildbuilds final-release wheels atX.Y.Z.publish:testpypiqueries TestPyPI, selects the first unusedX.Y.ZrcU(starting atrc1), rebuilds wheels at that version, and uploads.package:smoke-testpypiinstalls the publishedX.Y.ZrcUfrom TestPyPI.publish:pypiassertsX.Y.Zis absent on PyPI, then uploads thepackage:buildartifacts.package:smoke-pypiinstallsX.Y.Zfrom PyPI.
A tagged commit is released only after publish:pypi and package:smoke-pypi both succeed.
Scripts:
scripts/registry_publish.py— registry queries and version guardsscripts/build_packages.py --publish-version— temporary rc builds for TestPyPI
GitLab PyPI registry
https://gitlab.com/api/v4/projects/<PROJECT_ID>/packages/pypi
| Variable | Purpose |
|---|---|
CI_JOB_TOKEN | Built-in; upload to GitLab package registry |
TestPyPI
| Variable | Purpose |
|---|---|
TWINE_PASSWORD_TESTPYPI | TestPyPI API token (masked, protected) |
PyPI (production)
| Variable | Purpose |
|---|---|
TWINE_PASSWORD_PYPI | PyPI API token (masked, protected) |
Register three projects on PyPI / TestPyPI: a2c-core, a2c-cli, a2c-tui.
Release flow (summary)
- Curate
CHANGELOG.md[Unreleased]during development. - Create
release/X.Y.Zfrommasterand runpython scripts/bump_release.py. - Green Development CI on
release/X.Y.Z. - Push tag
vX.Y.Z— Release CI runs the automated publish chain above. - Fast-forward
masteronly after Release CI isreleased(PyPI smoke green).
Details: release-pipeline.md.