Release Process¶
Opencomplai follows Semantic Versioning (MAJOR.MINOR.PATCH). Four Python packages ship from this repo, all published to PyPI: opencomplai-core, opencomplai-cli, opencomplai-ai, and the opencomplai meta-package (the SDK). To find the version currently released, check the version field in packages/core/pyproject.toml (the other three packages track it — see below), the PyPI badge in the repo README, or run opencomplai --version. Don't trust a version number written into this page as a fact — packages move fast enough that it would go stale.
Version policy¶
| Package | Versioning |
|---|---|
opencomplai-core | Semver; breaking model or rule API changes bump MAJOR |
opencomplai-cli | Semver; new commands or changed exit codes bump MINOR |
opencomplai-ai | Semver; follows core |
opencomplai (SDK meta-package) | Semver; follows core and cli |
| Gateway API | Path-prefix versioning (/v1/, /v2/); parallel for ≥ 90 days |
All four Python packages move together — same version number across all four pyproject.toml files in a given release. The gateway API versions independently of the Python packages.
Build and publish order¶
The four packages have a dependency chain, so they are built and published in this order (both locally and in CI):
opencomplai-core— no local dependencies.opencomplai-cli— depends onopencomplai-core.opencomplai-ai— depends onopencomplai-coreonly, independent ofcli.opencomplai(SDK meta-package) — depends on bothopencomplai-coreandopencomplai-cli, so it is always built and published last.
Checker widget build prerequisite¶
Before opencomplai-cli is built, the docs checker widget must be built:
This generates packages/cli/src/opencomplai_cli/data/checker-local.html, a git-ignored asset that packages/cli/pyproject.toml force-includes into the wheel. Skip this step and the opencomplai-cli build fails with "Forced include not found." .github/workflows/publish-pypi.yml runs this build automatically before building any of the four distributions, so a tag-push release never needs it done by hand.
Release checklist¶
- Create a release branch from
main:git checkout -b release/vX.Y.Z. - Bump
versionto the same new value in all four package manifests: packages/core/pyproject.tomlpackages/cli/pyproject.tomlpackages/ai/pyproject.tomlpackages/sdk-python/pyproject.toml- Update
CHANGELOG.md— move items fromUnreleasedto the new version heading. - Run the full test suite:
uv run pytest packages/for the four Python packages, pluscd services/gateway-api && pnpm testfor the gateway API. - Open a release PR targeting
main, get it reviewed, and merge it. - Tag the merge commit
vX.Y.Zand push the tag. - Pushing the tag triggers
.github/workflows/publish-pypi.yml— itsbuildjob first checks the tag against the four manifest versions and fails on any mismatch, builds the checker widget and all four distributions, runs the wheel smoke test and generates a CycloneDX SBOM per package (kept as a workflow-run artifact). Only then does thepublishjob upload the tested distributions to PyPI in the dependency order above via Trusted Publishing (OIDC; no stored API token) with PEP 740 attestations. Each upload usesskip-existing: true, so re-pushing a tag for a version already on PyPI is a no-op, not an error. A manualworkflow_dispatchrun is a dry run: it builds, smoke tests and produces SBOMs, and publishes nothing. - Create a GitHub Release from the tag with the CHANGELOG section as the body.
Hotfixes¶
For critical security or correctness fixes on a released version:
- Branch from the release tag:
git checkout -b hotfix/vX.Y.Z+1 vX.Y.Z. - Apply the minimal fix.
- Follow the release checklist from step 2.