Branching & releases¶
How code flows from a feature branch to production, and how to ship an urgent fix.
Branching model¶
flowchart LR
feature["feature / bugfix / chore<br/>(PPL-NNNN/...)"] -->|"squash PR"| develop["develop"]
develop -->|"pnpm run cut-release -- X.Y.Z"| release["release/X.Y.Z"]
release -->|"PR to main, merge commit"| main["main"]
main -->|"automatic PR"| sync["sync/main-to-develop"]
sync -->|"merge commit"| develop
develop— the integration branch. All feature/fix/chore PRs target it and are squash-merged. This is what staging runs.release/X.Y.Z— cut fromdevelop, never frommain, so the release is grounded in the same state that was tested on staging.main— production. Onlyrelease/*andhotfix/*branches merge here, via a merge commit (not squash) so release commits propagate back.sync/main-to-develop— the automatic back-merge that keepsmainanddevelopfrom diverging. Merge it with a real merge commit.
Multi-ticket features
For a feature/epic spanning several tickets, we're trialling epic (feature)
branches: tickets merge into a long-lived epic branch that lands on
develop atomically, rather than each ticket merging to develop on its own.
Normal release¶
Releases are mechanical — run the script:
Then review the generated release/X.Y.Z → main PR, merge it with a merge commit, and
merge the resulting sync/main-to-develop PR back into develop.
Full mechanics live in the Releasing runbook
The step-by-step release runbook, the GitHub Actions Cut Release alternative, and the troubleshooting are in Releasing. This page is the why and the shape; Releasing is the exact steps.
Hotfixes¶
A production fix still gets fixed on develop first, then cherry-picked to a hotfix
branch — so the fix can never be lost on the next release.
- Author on
develop. Open a normalPPL-NNNN/...PR intodevelopand merge it. - Cherry-pick into a
hotfix/*branch offmain, and open a PR intomain.
Rules for main PRs
- The branch must be prefixed
release/orhotfix/(enforced by the release-PR guard). - It must bump both app pubspec versions
(
perci-platform-membersandperci-platform-clinicians). For a hotfix, bumping the build number is sufficient. - PRs into
developneed neither the prefix nor a version bump.
Versioning¶
Versions are semver (MAJOR.MINOR.PATCH). The version of record lives in the two app
pubspec.yaml files (perci-platform-members and perci-platform-clinicians), which the
release script writes as <version>+1; the +1 build number is intentionally stable for web
releases. See Releasing for the full detail.