Branch strategy
App repositories develop on test and release on main. They stay in step by
cherry-pick, never by merging test into main.
The rule
feature work → test → CI deploys :test → verified → cherry-pick onto main → CI deploys :prod
A merge is not a shortcut here. It is a production identity change.
Why, specifically
gstv-website/src/Firebase/FirebaseConfig.js selects its Firebase project by branch:
| Branch | Firebase project |
|---|---|
main | grey-screen-tv (production) |
test | greyscreen-test-5fb86 (test) |
public/firebase-messaging-sw.js carries the same project. Both native apps follow a
build-variant equivalent in app.config.ts.
Merging test into main would carry the test project into production and silently regress
every user's identity. This has happened before; the fix is recorded in the history, and the
branch-selection pattern is deliberately kept.
gstv-website/.env.production separately carries a live publishable Stripe key, while its
comments still mention a sandbox. The comments are stale. Inspect the key prefix; never copy the
value.
Branches by repository
| Repository | Development | Release | Notes |
|---|---|---|---|
gstv-website | test | main | Branch-selected Firebase |
greyscreen-webview | test | main | Identity comes from the native shell |
greyscreen-expo-webview | test | main | Variant-selected Firebase; store builds from android / ios |
gstv-tv | test | main | Variant-selected Firebase; EAS branches |
gstv-admin-web | test | main | Talks to the admin API only |
gstv-customer-api | test | main | Production main lags unless cherry-picked |
gstv-admin-api | test | main | Same; artwork work was cherry-picked |
gstv-vps | test | main | main has no deploy job |
gstv-multimedia | test | main | Test auto-deploys |
gstv-migration | — | master | master, not main |
vps-reverse-proxy | one branch per VPS | same | The branch is the deployment |
Several repositories carry long-lived firebase-migration branches. They are historical; do not
treat them as release branches.
The checked-out branch is not the release branch
Verification on 2026-10-22 found main checked out in only five of the app/API repositories.
Before you assume what is deployed, read the branch list, not the working tree:
git for-each-ref --format='%(refname:short) %(objectname:short)' refs/heads
git log --oneline -5 origin/main
Cherry-picking safely
- Land the change on
testand verify it there. - Note the commit hash.
- On
main, cherry-pick that hash, not the branch. - Resolve conflicts by keeping
main's branch-selected identity files. - Confirm the diff does not include
FirebaseConfig.js,firebase-messaging-sw.js,app.config.ts, or a.envfile that belongs to the other environment. - Push
main; production deploy runs behind its environment approval.
If a cherry-pick touches a queue contract, deploy the worker image first — the branch order does not change the consumer-before-producer rule.
Known divergence today
| Area | Reality |
|---|---|
| Test stack | Points at the production Firebase project. Only buckets are separate. |
| Worker images | Test :test is coherent; production's Artifact Registry tag is not built by any repo. |
gstv-db-core | Canonical and both API mirrors have diverged. Do not run sync.sh. |
| Pairing contract | Three copies, no canonical source, no syncing script that exists. |
These are not branch problems, but they are the reason a "just merge and see" instinct is expensive here.
Commit style
Conventional prefixes are used consistently in the history — feat(scope):, fix(scope):,
merge: — and the scope names the surface (billing, firebase, title, catalogue). Match
it; the history is the only changelog.
Next: Security notes.