Skip to content

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)
  • development is 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 development and are squash merged (keeps it linear).
  • Promotion is by PR: developmentstagingproduction. 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 into production, then back-merge into staging and development immediately so the fix can't be lost by the next promotion.
  • Deployment triggers: merge to staging auto-deploys to the staging environment; merge to production deploys only after environment approval in the pipeline (see CI/CD standard).
  • Release tagging: every merge to production is 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