Skip to content

Maintenance releases¤

Trestle supports releasing security and bug fixes for older major versions through maintenance branches. This allows patching e.g. v3.x while active development continues on v4.x.

Overview¤

  • Maintenance branches are named v<major> (e.g., v3, v4)
  • Patch-safe commit types are allowed (fix:, perf:, chore:, ci:, docs:, build:, refactor:, style:, test:, revert:) — feat: and breaking changes (!) are blocked by CI
  • Releases are automated via the same semantic-release pipeline as main
  • Documentation is automatically updated when a maintenance release is tagged

Developer workflow for security fixes¤

  1. Branch from the maintenance branch, not from develop:
git checkout v3
git pull origin v3
git checkout -b fix/cve-2026-xxxx
  1. Make the fix and commit using conventional commits:
git commit --signoff -m "fix: address CVE-2026-XXXX in authentication module"
  1. Open a PR targeting the maintenance branch (e.g., v3, not develop)

  2. CI runs automatically:

  3. Full test suite via python-test.yml

  4. PR title validation -- feat: titles are rejected on maintenance branches
  5. Standard code quality checks

  6. After merge (squash merge required), the deploy pipeline:

  7. Validates the branch name and version consistency

  8. Runs semantic-release to bump the patch version (e.g., 3.12.0 -> 3.12.1)
  9. Publishes to PyPI, signs with sigstore, creates a GitHub Release
  10. Updates versioned documentation

Security fix propagation¤

When a security fix is applied to a maintenance branch, it must also be applied to all other affected release trains:

  1. After merging the fix to the maintenance branch, cherry-pick to develop:
git checkout develop
git pull origin develop
git checkout -b fix/cve-2026-xxxx-develop
git cherry-pick <commit-sha-from-maintenance-branch>
  1. Open a PR targeting develop with the cherry-picked fix

  2. Track progress in the original security issue with a cross-train checklist:

- [x] v3 (v3.12.1)
- [ ] v4 (pending PR #NNN)
  1. A security fix is not considered complete until all affected trains are patched

Creating a new maintenance branch¤

When a new major version is released (e.g., v5.0.0), create a maintenance branch for the previous major version:

  1. Create the branch from main at the last release tag before the breaking change:
git checkout v4.x.y  # last v4 tag
git checkout -b v4
git push origin v4
  1. The CI pipeline automatically supports the new branch -- the v[0-9]* glob patterns in workflow triggers match any v<number> branch without code changes.

  2. Configure branch protection (see GitHub actions setup):

  3. Require pull requests with at least one CODEOWNER review

  4. Require status checks to pass
  5. Require squash merges only
  6. Restrict push access to maintainers
  7. Disallow force pushes and deletions

  8. Add the new branch to the release environment — each maintenance branch must be explicitly allowed for deployments. Follow the step-by-step instructions in GitHub actions setup → Adding a branch to the release environment.

  9. Consider enabling Dependabot for security updates on the new maintenance branch

CI/CD behavior on maintenance branches¤

Pipeline Behavior
python-test.yml Runs on PRs targeting maintenance branches (same as develop)
python-push.yml Triggers on push to maintenance branches; validates branch name, build command, version consistency, and commit types before running semantic-release
conventional-pr.yml Validates PR titles; blocks feat: commits on maintenance branches
docs-update.yml Automatically triggered by version tags (e.g., v3.12.1)
merge-main-to-develop Does not run -- maintenance releases are isolated

Restrictions on maintenance branches¤

  • No feature releases: feat: commits are blocked at the PR level and verified server-side before release. Minor version bumps cannot happen on maintenance branches.
  • No direct pushes: Branch protection requires all changes go through reviewed PRs.
  • Version consistency: The major version in trestle/__init__.py must match the branch name (e.g., branch v3 must have version 3.x.x).
  • Build command integrity: The build_command in pyproject.toml is validated against an allowlist before each release.