Skip to main content

Release pipeline

Maintainer workflow for publishing the eai-sup* family (eai-supcore, eai-supinit, eai-supmig) in lockstep. Mirrors the pyswig / a2c release pipeline: curated changelog, bump_release.py, tag verification, wheel smoke tests, GitLab registry, TestPyPI gate, then manual production PyPI.

See also package-publishing.md for package layout and CI variables.

Prerequisites​

  • Protected refs (Settings → Repository → Protected branches and tags):
    • Branches: master, develop
    • Tags: v* (required so masked/protected CI variables are available on tag pipelines)
  • CI variables (masked):
    • TWINE_PASSWORD_TESTPYPI — TestPyPI API token; not protected (needed on develop for manual publish:testpypi:branch)
    • TWINE_PASSWORD_PYPI — PyPI API token; protected (tag pipelines only)
  • PyPI and TestPyPI projects registered for eai-supcore, eai-supinit, eai-supmig
  • GitLab Package Registry enabled (publish:gitlab uses CI_JOB_TOKEN)

Changelog policy​

CHANGELOG.md follows Keep a Changelog.

  • Keep a single ## [Unreleased] section with ### Added / ### Changed / ### Fixed bullets as work lands on develop.
  • Use - (nothing yet) when a subsection has no entries yet.
  • Do not dump raw commit lists into the changelog; write user-facing notes.
  • At release, python scripts/bump_release.py:
    • moves [Unreleased] notes into ## [X.Y.Z] - YYYY-MM-DD
    • resets [Unreleased] with placeholder bullets
    • updates footer compare/tag links ([Unreleased]: …, [X.Y.Z]: …)
  • The bump script also syncs lockstep version across VERSION, all three __version__ attrs, packages/eai-supcore project version, and CLI eai-supcore== pins, then creates a chore(release): Bump version to X.Y.Z commit (add --tag to create the annotated tag locally).

Example unreleased section:

## [Unreleased]

### Added

- `eai-supmig doctor` reports missing Conan profiles

### Fixed

- Bootstrap skips ai-rules submodule when `tools/ai-rules/` is already a git repo

Release steps​

  1. Land features on develop; keep CHANGELOG.md [Unreleased] curated.
  2. Wait for green CI on develop.
  3. Run python scripts/bump_release.py (lockstep version sync + changelog + commit) and push develop.
  4. Wait for green CI on the bump commit on develop.
  5. Tag from develop: git tag -a vX.Y.Z -m "Release X.Y.Z" then git push origin vX.Y.Z (tag pipelines use protected v* variables).
  6. Wait for the tag pipeline to succeed through at least package:build, package:smoke, publish:gitlab, publish:testpypi, and package:smoke-testpypi. Fix on develop and re-tag only if that fails — do not update master yet.
  7. Optionally run manual publish:pypi (then package:smoke-pypi) when ready for production.
  8. Last step: FF-merge (or rebase) develop → master and push master only after the release is known good.

Optional pre-tag validation on develop: after a branch pipeline builds wheels (build:package), trigger manual publish:testpypi:branch.

Branch pipeline jobs​

JobWhenPurpose
build:packagedevelop, master, MRBuild wheel/sdist; twine check
publish:testpypi:branchmanual on develop / masterUpload to TestPyPI (allow_failure: true)

Tag pipeline jobs​

JobWhenPurpose
package:buildtagverify_release_version.py; build; twine check
package:smoketagFresh venv: install all three wheels; CLI --help
publish:gitlabtag, automaticUpload to GitLab PyPI registry
publish:testpypitag, automaticUpload to TestPyPI
package:smoke-testpypiafter TestPyPILockstep eai-supcore/init/mig==X.Y.Z from TestPyPI
publish:pypitag, manualUpload to production PyPI
package:smoke-pypiafter PyPILockstep eai-supcore/init/mig==X.Y.Z from PyPI

Local dry-run​

pip install -e packages/eai-supcore -e packages/eai-supinit -e packages/eai-supmig -e ".[dev]"
python scripts/build_packages.py
python -m twine check dist/*
python scripts/smoke_install_package.py --dist dist --expected-version 0.4.4 --venv .smoke-venv
python scripts/bump_release.py --dry-run

On Windows, use the same commands from an activated .venv.

Version source of truth​

  • VERSION (repo root) — lockstep version for all three distributions
  • Mirrored in src/eai_sup{core,init,mig}/__init__.py and CLI eai-supcore== pins
  • Git tag vX.Y.Z must match that version (scripts/verify_release_version.py)