Release Process¶
This document describes how gepa-adk releases are created and published to PyPI.
Overview¶
Releases are fully automated via release-please and GitHub Actions:
- Conventional commits on
mainare tracked automatically - release-please opens/updates a version-bump PR with changelog
- Merging the PR creates a
v*tag - publish.yml triggers on the tag: build → verify → attest → publish to PyPI → deploy docs
No manual version bumps, tags, or GitHub Releases are needed.
How Releases Work¶
Step 1: Merge conventional commits to main¶
Use conventional commit prefixes:
| Prefix | Bump | Example |
|---|---|---|
feat: | minor | feat(engine): add mutation rationale capture |
fix: | patch | fix(scorer): handle empty output |
feat!: or BREAKING CHANGE: | major | feat!: remove evolve_sync |
docs: | none | Shown in "Documentation" section of changelog |
chore:, test:, ci: | none | Hidden from changelog |
Step 2: release-please creates a PR¶
After each push to main, the release-please.yml workflow:
- Analyzes new commits since the last release
- Opens (or updates) a PR titled
chore(main): release X.Y.Z - Generates a changelog from conventional commits
- Bumps
pyproject.tomlversion via theextra-filesconfig - An
update-lockfilejob updatesuv.lockon the PR branch
Step 3: Merge the release PR¶
When the release PR is merged:
- release-please creates a
vX.Y.Ztag (usingRELEASE_PLEASE_TOKENPAT) - The tag triggers
publish.yml
Step 4: Automatic publishing¶
The publish.yml workflow:
- Builds wheel and sdist with
uv build - Verifies tag version matches
pyproject.toml - Smoke tests wheel contents (size limit, no test files)
- Installs and verifies the wheel in a clean venv
- Publishes to PyPI via OIDC trusted publishing (no API tokens)
- Generates attestations for package provenance
- Deploys documentation to GitHub Pages
Configuration Files¶
| File | Purpose |
|---|---|
release-please-config.json | Release type, changelog sections, extra-files |
.release-please-manifest.json | Current version manifest (see file for current value) |
.github/workflows/release-please.yml | PR creation + lockfile update |
.github/workflows/publish.yml | Build, verify, publish, docs deploy |
Prerelease Versions¶
Prerelease versions (e.g., 2.0.0a1, 2.0.0rc1) are not currently automated via release-please. If needed, use the manual process below.
Emergency Manual Release¶
If release-please is broken or you need an out-of-band release:
# 1. Bump version in pyproject.toml
uv version 2.0.1
# 2. Commit and merge to main
git add pyproject.toml
git commit -m "chore: bump version to 2.0.1"
# (merge via PR)
# 3. Create and push tag
git checkout main && git pull
git tag v2.0.1
git push origin v2.0.1
The v* tag triggers publish.yml regardless of how it was created.
Troubleshooting¶
Release PR not appearing¶
- Check that commits use conventional prefixes (
feat:,fix:) - Verify
RELEASE_PLEASE_TOKENsecret is set (PAT withreposcope) - Check the release-please workflow run in Actions for errors
Tag not triggering publish¶
- Tags created by
GITHUB_TOKENdo NOT trigger other workflows - The
RELEASE_PLEASE_TOKENPAT is required for cross-workflow triggering - Verify the tag matches the
v*pattern
"Version mismatch" error in publish¶
The tag version must match pyproject.toml. release-please handles this automatically; manual tags require a matching version bump first.
"OIDC token request failed"¶
Ensure Trusted Publishing is configured at pypi.org/manage/account/publishing:
- Workflow:
.github/workflows/publish.yml - Repository:
Alberto-Codes/gepa-adk - Environment:
pypi
"Package already exists"¶
PyPI does not allow overwriting published versions. Bump the version and release again.
Version Numbering¶
Follows Semantic Versioning:
- MAJOR (2.0.0): Incompatible API changes
- MINOR (2.1.0): New features, backwards-compatible
- PATCH (2.0.1): Bug fixes, backwards-compatible