Release Process
This page documents the release process for trueppm-suite. Releases are created by running scripts/release.sh on main, which bumps all version manifests, rotates the changelog, commits, and creates an annotated git tag. Pushing the tag triggers the CI publish jobs.
Prerequisites
Section titled “Prerequisites”Before cutting any release:
- All MRs for the milestone are merged. Check with
glab issue list --milestone <version>. mainpipeline is green. Releases are cut from a clean, passingmain.- Changelog fragments are present. Every user-visible change should have a fragment in
changelog.d/. Runbash scripts/assemble-changelog.sh --dry-runto preview the assembled changelog. - Smoke test passes.
This boots the dev stack, seeds the demo project, and curls every shipped endpoint. Fix any failures before proceeding.
Terminal window make release-smoke
Version scheme
Section titled “Version scheme”TruePPM follows semantic versioning. The script manages both stable and pre-release series:
| Command | Example | Result |
|---|---|---|
./scripts/release.sh patch | 0.1.0 → 0.1.1 | Bugfix release |
./scripts/release.sh minor | 0.1.0 → 0.2.0 | New features, backwards-compatible |
./scripts/release.sh major | 0.1.0 → 1.0.0 | Breaking changes |
./scripts/release.sh minor alpha | 0.1.0 → 0.2.0-alpha.1 | Start alpha series |
./scripts/release.sh alpha | 0.2.0-alpha.1 → 0.2.0-alpha.2 | Next alpha |
./scripts/release.sh beta | 0.2.0-alpha.2 → 0.2.0-beta.1 | Promote to beta |
./scripts/release.sh rc | 0.2.0-beta.1 → 0.2.0-rc.1 | Promote to RC |
./scripts/release.sh release | 0.2.0-rc.1 → 0.2.0 | Finalize pre-release |
./scripts/release.sh 1.2.3 | explicit | Pin to specific version |
Pre-release CHANGELOG behaviour: Alpha/beta/RC bumps do NOT rotate the [Unreleased] section — notes accumulate until the final stable release.
Step-by-step: stable release
Section titled “Step-by-step: stable release”# 1. Ensure you're on a clean, up-to-date maingit checkout main && git pull origin maingit status # must be clean
# 2. Verify the milestone is completeglab issue list --milestone 0.2 # should return 0 open issues
# 3. Run the smoke testmake release-smoke
# 4. Cut the release./scripts/release.sh minor # e.g. 0.1.0 → 0.2.0
# 5. Review the generated commit and taggit log --oneline -3git show v0.2.0 --stat
# 6. Push — this triggers the CI publish jobsgit push origin main v0.2.0The git push origin main v0.2.0 command triggers three CI publish jobs:
api:publish— pushesghcr.io/trueppm/api:0.2.0,0.2, andlatestweb:publish— pushesghcr.io/trueppm/web:0.2.0,0.2, andlatesthelm:publish— packages and pushes the Helm chart tooci://ghcr.io/trueppm/charts
Additionally, if you push a scheduler-v* tag, scheduler:publish publishes trueppm-scheduler to PyPI. Scheduler releases are versioned independently (see below).
Scheduler releases
Section titled “Scheduler releases”The scheduler package (packages/scheduler) is versioned independently from the rest of the platform. Its tag format is scheduler-v* (e.g. scheduler-v0.2.0), not v*.
# Bump the scheduler version and push its tag./scripts/release.sh minor # bumps all manifests including schedulergit push origin main scheduler-v0.2.0The scheduler:publish CI job fires on scheduler-v* tags and publishes to PyPI.
Enterprise release
Section titled “Enterprise release”After pushing the OSS tag, run the enterprise release script in trueppm-enterprise:
cd ../trueppm-enterprise./scripts/release.sh --oss-tag v0.2.0The enterprise script pins TRUEPPM_OSS_TAG to the OSS release and bumps the enterprise version independently.
Hotfix procedure
Section titled “Hotfix procedure”For a critical fix on an already-released version:
# Branch from the release taggit checkout -b fix/critical-bug v0.1.0
# Apply the fix, commit, open an MR back to main# After the MR merges to main, cherry-pick or re-cut as a patch release:git checkout main && git pull origin main./scripts/release.sh patch # 0.1.0 → 0.1.1git push origin main v0.1.1What the script modifies
Section titled “What the script modifies”| File | Change |
|---|---|
packages/scheduler/pyproject.toml | version = "x.y.z" |
packages/api/pyproject.toml | version = "x.y.z" |
packages/web/package.json | "version": "x.y.z" |
CHANGELOG.md | [Unreleased] → [x.y.z] - YYYY-MM-DD (stable only) |
The Helm chart version in packages/helm/Chart.yaml is kept in sync manually — bump version and appVersion to match before running release.sh.
Troubleshooting
Section titled “Troubleshooting”“Tag vX.Y.Z already exists” — the tag was already pushed. Check if the CI jobs ran correctly; if the images are already published, no action is needed.
“Working tree is not clean” — stash or commit pending changes before running the script.
“[Unreleased] section is empty” — add changelog fragments to changelog.d/ and run bash scripts/assemble-changelog.sh to populate [Unreleased] before releasing.
CI publish job fails — verify GHCR_TOKEN and GHCR_USER are set in GitLab CI/CD variables (Settings → CI/CD → Variables) and that the PAT has write:packages scope.