Branching Strategy β
Two long-lived branches: DEV (integration β DEV CF) and main (release β PROD). Feature work merges to DEV; a consolidated release PR promotes DEV to main only when we're ready to transport to PROD. main carries the full branch protection required by the SAP Open Source repo linter (#1634, rule rl-branch_protection).
Why this exists. After go-live (PROD 2026-08-09)
mainneeded protection to satisfyrl-branch_protection, and we wanted a staging boundary so DEV CF deploys don't require touching the PROD-facing branch. This model gives both: a fast, lightly-gated integration branch and a protected release branch.
TL;DR β
DEV | main | |
|---|---|---|
| Represents | DEV CF | PROD |
| GitHub default branch | no | yes (so protecting it satisfies #1634) |
| Feature PRs target it | yes | no |
| Protection | force-push + deletion blocked | full #1634 set (see below) |
| Deploy | deploy.yml / npm run deploy --env dev | --env prod |
feature/* ββPR (squash)βββΆ DEV ββdeployβββΆ DEV CF
β
βββrelease PR (merge commit)βββΆ main ββdeployβββΆ PROD
hotfix/* ββPR (admin-bypass)βββΆ main ββdeployβββΆ PROD ββback-mergeβββΆ DEVThe three flows β
Feature β
- Branch from
DEV:git fetch origin && git switch -c feat/<topic> origin/DEV. - Open a PR targeting
DEV(change the base β the repo default ismain). - Cheap CI runs automatically:
unit-tests(in-memory SQLite) plus the path-filtered guards (cds-build-staging-check,srv-qa-cp-list-check,schema-drift-check, β¦). These are advisory onDEVβ nothing is a required status check there. - Squash-merge into
DEV. The branch auto-deletes on merge. - Deploy
DEVto DEV CF when you want (npm run deploy -- --env dev).
Release (DEV β main) β
- Open a consolidated release PR
DEV β mainwhen a batch is ready for PROD. - Use a merge commit (not squash). This keeps
DEVan ancestor ofmainso the two never permanently diverge β a squash here would makeDEVshow as "unmerged" forever and the next release PR would replay the whole diff. mainprotection requires 1 approval + conversation resolution. Solo maintainers merge via admin bypass (see below).- Deploy
mainto PROD (npm run deploy -- --env prod) β follow the Deploy Checklist.
Hotfix (urgent PROD fix) β
- Branch from
main:git switch -c hotfix/<topic> origin/main. - PR targeting
main, admin-bypass the approval, deploy PROD. - Back-merge
main β DEVimmediately soDEVpicks up the fix and doesn't regress it at the next release:bashBack-merge is only needed after a hotfix β a normal release PR already leavesgit fetch origin git switch -c sync/main-to-dev origin/DEV git merge origin/main # resolve, then PR sync/main-to-dev β DEVDEVan ancestor ofmain.
main protection (classic branch protection) β
Configured to satisfy every control rl-branch_protection mandates on the default branch:
| Control | Setting |
|---|---|
| Require a pull request before merging | β |
| Required approvals | 1 |
| Dismiss stale approvals on new commits | β |
| Require review of the most recent push | β |
| Require conversation resolution | β |
| Block force-pushes | β |
| Restrict deletions | β |
| Required status checks | none (approval-only) |
| Enforce for administrators | off β admins bypass |
Admin bypass. enforce_admins is off so a solo maintainer can merge their own release/hotfix PRs. The approval control is still configured (which is what the linter checks), just bypassable by repository admins. If the linter is ever tightened to also require enforce-for-admins, the only compliant options are a real second reviewer (designated reviewer via CODEOWNERS, or a bot approver).
Inspect or re-apply:
gh api repos/sap-tutorials/tutorials-ims/branches/main/protectionDEV protection β
Force-pushes and deletions blocked; no PR/approval requirement so integration stays fast.
CI wiring β
unit-tests,secret-scan,no-committed-secrets-checkrun onpull_request(any base) and on push tomainandDEV.- Heavy suites (
smoke,e2e,load-test) run post-deploy or on a schedule β never on PRs, soDEVPRs stay fast. docs-deploypublishes this docs site on push tomainonly. A doc change merged toDEVtherefore goes live only after the next release PR reachesmain.
Repo hygiene β
delete_branch_on_merge is on β merged PR branches auto-delete, preventing the stale-branch buildup we cleaned up when adopting this model. Keep long-lived branches to DEV and main only.