Skip to content

ADR-0007: Release-branch promotion model (Option A)

Status: Accepted Date: 2026-08-13 Deciders: Platform engineering (Epic F) Impacted Repos: reservation-api-server, admin-web-app, venuplus-app, customer-web-app, Amplify frontends, related AWS CDK pipelines

Context

Application repos historically treated main as both integration and production. That forced either auto-deploy on every merge or ad-hoc Slack coordination. Epic F approved Option A: keep a fast develop integration channel, cut explicit release/x.y.z for PROD, and treat main as the shipped audit tip (plus tags), not the first PROD cut.

Existing CI still encodes the old model:

  • main-merge-guard allows only develop → main
  • pipeline-branch-map-guard asserts prod: 'main' as if PROD ships from main first

Those guards must match Option A or they block the approved path.

Decision

Adopt the following branch roles and promotion path for application repos (not bz-platform-context, which remains main-only docs):

Branch Role
feature/TASK-* (also fix/ chore/ docs/ hotfix/) Task-linked work
develop Integration / default PR target
release/x.y.z Release candidate; only allowed PROD deploy ref
main Record of what shipped; receives release/* after PROD validation
vX.Y.Z tag (+ GitHub Release) Immutable ship marker on the main SHA
feature/TASK-* ──PR──► develop ──cut──► release/x.y.z
                              │
                     manual PROD deploy (confirm_prod)
                              │
                              ▼
                     validate ──PR──► main ──tag──► vX.Y.Z

Deploy rules

  1. No silent auto-deploy from git push alone (Epic F.1 target: disable CodePipeline triggerOnPush; start from Actions).
  2. DEV: manual workflow_dispatch from feature/TASK-* or develop. Shared DEV overwrite requires explicit confirm.
  3. PROD: manual workflow_dispatch only from release/x.y.z, with confirm_prod=deploy. Never from feature/*.
  4. CDK branchMap: dev → develop. Prod source at deploy time is GITHUB_BRANCH=release/x.y.z. branchMap.prod may keep 'main' only as a rebuild/audit-tip fallback — not as the primary ship path.
  5. Hotfix: hotfix/TASK-* from main → patch release/x.y.z → PROD → main → back-merge develop.

Merge-guard policy

PRs into main MUST have head matching ^release/[0-9]+\.[0-9]+\.[0-9]+. Block feature/*, develop, and other heads.

Consequences

Positive

  • PROD always ties to an explicit semver release cut.
  • main stays a clean shipped history for audit and tags.
  • develop can move fast without implying production.

Negative / Trade-offs

  • Extra step (release cut + post-prod PR) vs merge-to-main ship.
  • Temporary dual mental model until F.1–F.5 automation lands.

Risks / Mitigations

  • Risk: Someone deploys main thinking it is PROD-first. Mitigation: ADR + main-merge-guard + deploy workflow ref checks (F.4).
  • Risk: Hotfix lost on develop. Mitigation: checklist requires back-merge.

Alternatives Considered

  • Option B — ship from main: rejected; conflates audit tip with first PROD cut and regenerates the old auto-deploy pressure.
  • Option C — long-lived staging: rejected for current team size; release/x.y.z cuts are enough.

Implementation Notes

Artifact Change
This ADR Canonical decision
App main-merge-guard.yml Allow only release/* → main
pipeline-branch-map-guard.yml + CDK comments Document Option A / ADR-0007; keep dev→develop
docs/git/* Already describe Option A; link this ADR
docs/PROD-RUNBOOK.md Operator checklist
docs/SDLC-RUNBOOK.md Align phases with develop / release

Automation: F.5 tag+Release workflow shipped (.github/workflows/release-tag-on-main-reusable.yml). Remaining Epic F children: F.1–F.4.

References