7.3 Branching & Promotion
This page defines how a change travels from a developer's branch to customers. There is one main branch; a release candidate is built from a reviewed commit and the same image digests are used for later promotion. Environments are not branches. Development is local with Docker. The current cloud path is stage; production and automatic push-to-release orchestration are not activated by this policy.
7.3.1 One Main Branch¶
Every repository has one long-lived branch, main, which is always releasable. Work happens in short-lived branches that live for days, not weeks:
- Branch names are
<type>/<short-description>, with typefeat,fix,choreordocs. - Our documented merge policy requires a branch to reach
mainonly through a pull request, with the relevant checks passed (format, lint, tests as applicable), no merge conflicts and another code owner's approval. - Jacopo and Lorenzo review and approve each other's pull requests. The author does not approve their own change under this policy.
- A ruleset on
mainenforces repository protections in every repository: changes arrive only through a pull request, review threads are resolved, the merge is a squash, andmaincannot be force-pushed or deleted. Nobody bypasses it, administrators included. CI moves to Cloud Build (decided 2026-11-04): until its checks report to GitHub, the ruleset requires none, and the author checks that CI passed before merging. - Pull requests are squash-merged; the pull request title becomes the line in the release notes.
- Work that is not ready for customers is merged behind a feature flag, so
mainstays releasable.
Why there are no stage or prod branches
With a branch per environment, the code in prod is a merge of a merge, never exactly what was tested in stage, and the branches drift apart until merging them hurts. Promoting one build keeps what was tested and what runs identical.
7.3.2 From Merge to Prod¶
| Environment | Receives | When | Who decides |
|---|---|---|---|
| Local development | Work-in-progress code and synthetic fixtures | Before proposing the change | Developer |
| Stage | A verified candidate from main |
After checks, publication, release preparation and rollout approval | A member of stage-release-admins, for the intended stage target |
| Prod, future | The tagged SHA and image digests that succeeded in stage and passed required tests | After the production checks and approval | A member of the existing release-admins group, a second person, never the author of the change |
There is no cloud development deployment to pass first. A production release never skips stage: an approval or a started rollout is insufficient; the rollout must succeed and the required tests must pass for the same candidate. The automatic production evidence check remains a prerequisite to implement before production activation.
Releases are delivered by Cloud Deploy using environment targets. Promotion reuses the same images, identified by digest; environment configuration is rendered and verified separately. Stage and future prod require approval. Access currently implements the stage approver grant on its delivery pipeline with an IAM condition for the stage target. Do not infer environment separation from group names alone; Cloud Build approval remains project-wide. A native delivery handles one Cloud Run workload per target/render; multiple components require explicitly coordinated deliveries, not an assumed atomic release. See Application Delivery.
The initial approved source-free release build is initiated explicitly from a reviewed candidate. Generalizing it does not enable deployment on every GitHub push. Infrastructure changes follow the separate Terraform workflow.
The initial stage operator CLI accepts current remote main, not any historical merged commit. Its kit, manual same-component release ordering, retry and compatible fix/revert procedure are defined in Stage Release and Recovery. A rollout retry is not a rollback; the future production recovery policy below does not certify that either recovery path has already been enabled and tested in stage.
7.3.3 When Prod Breaks¶
- First restore, then fix. Send traffic back to the previous version, as described in Service Recovery. This takes minutes and needs no new build.
- The fix is a normal pull request to
main. It may be promoted straight to stage, and it still passes stage like any other change. There are no hotfix branches. - Database migrations stay compatible with the previous release, so going back never needs a database rollback.