Git & PR Workflow Standard¶
v1.0 — 2026-06-06
Branching — environment-branch model¶
Three long-lived branches mapped to environments; there is no main:
feature/* ──squash PR──▶ development ──merge PR──▶ staging ──merge PR──▶ production
(default) (pre-prod) (live)
developmentis the default branch. All work happens in short-lived branches (target < 3 days) cut from it:feature/<ticket>-short-desc,fix/<ticket>-short-desc,chore/....- Feature/fix PRs target
developmentand are squash merged (keeps it linear). - Promotion is by PR:
development→staging→production. Promotion PRs use a plain merge — never squash: squashing a promotion rewrites the commits and makes the three branches permanently diverge, producing phantom conflicts on every later promotion. - Hotfixes: branch from
production(hotfix/<ticket>-short-desc), PR intoproduction, then back-merge intostaginganddevelopmentimmediately so the fix can't be lost by the next promotion. - Deployment triggers: merge to
stagingauto-deploys to the staging environment; merge toproductiondeploys only after environment approval in the pipeline (see CI/CD standard). - Release tagging: every merge to
productionis tagged with a semver release version (e.g.v1.7.0) — tags are the rollback and traceability anchor. Derive the version bump from Conventional Commits since the last tag (feat:→ minor,fix:→ patch,!/BREAKING CHANGE→ major).
Feature flags (item 4, accepted 2026-06-06)¶
- Unfinished or risky features ship behind a flag so they can ride a promotion to staging/production safely; release (flag on) is decoupled from deploy (merge) — this is the sanctioned mitigation for half-done work in promotions (see ADR-001).
- Every flag gets a named owner and a removal date at creation; a flag past its removal date is tech debt and gets flagged in review.
- Keep it light: .NET uses built-in
Microsoft.FeatureManagement(config / Azure App Configuration); frontends use a plain config check. No third-party flag platform at current scale. - Flags are for release control, not permanent configuration — long-lived behavioral switches belong in real configuration with an ADR.
Commits¶
Conventional Commits v1.0.0: feat:, fix:, refactor:, chore:, docs:, test:; breaking changes via ! or BREAKING CHANGE: footer. Reference the work item (AB#1234) in the body.
Pull requests¶
- Small and focused — one logical change. > ~400 changed lines: consider splitting.
- Description states what and why; use the PR template.
- Author runs build + tests + formatter locally before opening.
Azure DevOps branch policies (all three protected branches, every active repo)¶
development:
- Minimum 2 reviewers for shared libraries (ExpertGroup core), 1–2 elsewhere; prohibit most recent pusher from approving own changes.
- Reset votes on new pushes; comment resolution required; work-item linking required.
- Build validation: PR pipeline (build + tests + format check) must pass.
staging and production:
- Accept PRs only from the upstream branch (promotion) or
hotfix/*— never directly from feature branches. - 1 reviewer (content was already reviewed entering
development); build validation; deployment gated by environment approvals/checks in the pipeline rather than extra PR reviewers. - Direct pushes blocked on all three branches.
Review checklist (reviewer responsibilities)¶
Correctness and tests; security (input validation, authz checks, no secrets); standards conformance (build enforces style — review focuses on design); migrations reviewed as SQL; no N+1 in resolvers.
AI-assisted code (added from expert review, item 7 — Fowler): code generated with Claude or any AI assistant is reviewed exactly like human-written code — the PR author owns and must understand every line; unreviewed AI output ("vibe code") never reaches a production repo. AI assistance is encouraged; unaccountable code is not.
Sources: Trunk-based development · Conventional Commits · Branch policies