TL;DR:
- Work: cut
feat/,fix/,docs/,chore/,refactor/ortest/branches namedtype/AB####-short-namefromdev, and PR them intodev. Personal experiments go inusers/<alias>/<topic>.- Promote:
dev→qa/X.Y.Z→stg/X.Y.Z→release/X.Y.Z(taggedvX.Y.Z) →mainafter the store release is live and the build is GA. Merged work stacks until the release owner reviews it and promotes it intostgas one bundle; a hotfix, or a stack of one, goes alone.- Gates:
devhas no automated gate: you test before the PR and build the mergeddevafter it.qa/runs the PR validation builds.stg/,release/andmainneed one reviewer. A merge intostgproduces the tester build for the stores.- Late fixes: fix on the branch where the defect was found; whoever merged the fix merges it into every lower branch the same day, by merge, never cherry-pick.
- Always: every PR completes as a merge commit (no squash, no rebase), and branch names are lowercase.
| Step | Branch | Entry | What happens on merge |
|---|---|---|---|
| 1 | dev | PR from a work branch | Developer integration. No automated gate. |
| 2 | qa/X.Y.Z | PR dev → qa/X.Y.Z | QA test build. The PR validation builds must pass first. No store upload. |
| 3 | stg/X.Y.Z | PR qa/X.Y.Z → stg/X.Y.Z, opened and merged by the release owner after reviewing the stack | Automated tester build for the stores, one build per bundle. |
| 4 | release/X.Y.Z | Cut at the stg tip | This is what the stores review. Tagged vX.Y.Z at the go decision. |
| 5 | main | release/X.Y.Z once the store release is live and the build is GA | Production signal. After each GA, main is merged back into dev. |
stg is bundledA merge into stg/X.Y.Z produces a tester build for the stores, so merged work stacks ahead of stg until a manual review: the release owner reviews the stack, opens the promotion PR into stg and merges it, so one tester build carries many changes. Exceptions that go alone: a hotfix, or when there is nothing else to stack. Nothing promotes automatically. A promotion PR carries the whole tip of the branch it merges from; a branch cannot be promoted PR by PR without cherry-picking.
| Prefix | Use | Cut from, PR into |
|---|---|---|
feat/, fix/, docs/, chore/, refactor/, test/ | Shared work by type, named type/AB####-short-name | dev to dev. A late fix is cut from the branch where it was found. |
task/<wi-id>- | Work-item-scoped tasks | dev to dev |
users/<alias>/<topic> | Developer playground. Nobody else depends on it; anything that ships goes through a work branch. | never promoted |
imp/<topic> | Long-running topic integration that needs several PRs before dev | dev to dev, never straight to qa |
qa/X.Y.Z, stg/X.Y.Z, release/X.Y.Z | The release line for one version | The PR chain above |
archive/<name>-<date> | Tags only, for retired branches | never a working branch |
QA/x is accepted as a different folder from qa/.dev/x is rejected while dev exists, so dev and main block <name>/…, and no branch may be named qa, stg, users, imp or release.users/, not initials. No bot prefixes.imp/blazor-hybrid, DotNet10 and staging branches are retired lines: do not target them.| Branch | Required before merge | After merge |
|---|---|---|
dev | Nothing automated. Before the PR you have run the unit and architecture tests (the pre-commit hook runs them when code is staged) and built your platform. | The developer who merged builds the merged dev tip (not their own branch, because PRs that are each green can break the build together) for the platform(s) the change touches. If it is red, fix forward or revert the same working day. The last merger owns a red dev. |
qa/X.Y.Z | Blocking builds: PR Validation Android (98), iOS (99) and Docs (100). No reviewer policy: the builds are the gate. | QA testing. |
stg/X.Y.Z | PR from qa/X.Y.Z and 1 reviewer (the creator's vote counts). | Automated tester build and store upload. |
release/X.Y.Z | 1 reviewer (the creator's vote counts). | What the stores review. |
main | 1 reviewer (the creator's vote counts). A PR that touches docs/ or .githooks/ also runs PR Validation Docs (100), which must pass. | The production signal. Docs Publish deploys the docs site from main. |
Every PR into dev, qa/, stg/, release/ and main completes as a merge commit (no squash, no rebase), enforced by branch policy. A squash or rebase would give a promoted fix a different commit on each branch and the back-merge rule would stop working. A reviewer policy whose creator's vote counts is a deliberate pause, not an access control.
The docs site is published from main, so a docs fix normally reaches it with the next release. A docs-only fix that cannot wait goes in a docs/ work branch and is PR'd straight into main (merge commit). The docs PR validation (100) and one reviewer gate it. Afterwards merge main back into dev, as after a release.
qa, stg or release is fixed on a branch cut from that branch and merged by PR into that branch, so the code under test is the code fixed.release/X.Y.Z gets PRs into stg/, qa/ and dev (skip branches that already contain the commit). Each completes as a merge commit; never cherry-pick. Tag the work item BackMerge.release/X.Y.Z is not merged to main, while a back-merge PR is open. Check: git log --no-merges --oneline origin/dev..origin/release/X.Y.Z must print nothing. Promotion merge commits exist only on the higher branch, so --no-merges is required.release/X.Y.Z is merged to main, main is merged back into dev so the tag and any hotfix are reachable from dev.vX.Y.Z, goes by PR into release/X.Y.Z and then stg/ (the store build is its check), is merged to main, and is back-merged into qa and dev.release/X.Y.Z is merged into main (and main into dev), a PR into dev sets Version and ApplicationDisplayVersion in ALPAMobile/ALPAMobile.csproj to the next version. The two lines must stay aligned.qa/X.Y.Z+1 and stg/X.Y.Z+1 through the normal promotion. Those branches can exist before the bump.azdo_windows.yml and azdo_mac.yml run on every branch except dev and main: automatically on a merge into stg/* (the CI trigger), and on a manual run from any other branch, for example a topic or release branch that needs a tester build (AB#3156). A manual run from dev or main builds without uploading.vX.Y.Z (the display version, no build number) on the exact commit the stores approved.release/X.Y.Z tip, before merging into main. Not at the cut: until the go, the branch can still take late fixes.git tag -a and push, or the portal.git log v6.0.0..v6.0.1), and Sentry release finalization.A branch policy may be bypassed only for an emergency: a production-impacting defect (crash, data loss, sign-in) that must reach the stores quickly, or a gate outage where builds cannot run on the hosted agents and the delay would block a release. A deadline is not an emergency. dev has nothing to bypass: a red dev is fixed forward or reverted.
az repos pr update --bypass-policy true --bypass-policy-reason "<why>", or the portal). The reason is recorded on the PR.PolicyBypass. The same day, queue the PR validation builds (98 and 99) manually on the merged branch; they must pass.wiki/engineering/GIT-DEVOPS-CONVENTIONS.md): worktrees, PR and work-item text, branch policies and auto-complete