Modern DevSecOps Foundations Module 1 · The Operating Picture

Trunk-Based, For Real

Last reviewed · content updated

Intermediate

What you'll learn

~18 min
  • Run trunk-based delivery with short-lived branches and an always-releasable main
  • Configure branch policies that gate for real - and audit docs against repo reality
  • Place merge queues and stacked PRs on the maturity ladder without cargo-culting either

The debate that ended

Start with the unusual thing: this argument is over, and the losing side’s author says so. GitFlow’s creator amended his famous post years ago — use it only for explicitly versioned, multi-version software; Atlassian’s own docs file GitFlow under legacy; Microsoft’s current guidance teaches feature-branches-off-main with an always-releasable trunk; and Lesson 1.1’s research names small batches an AI-returns amplifier. The consensus:

main - protected, always releasable; the only long-lived branch
feature/* - hours-to-days lived, one change each, PR back to main
release/* - CUT AT RELEASE TIME when you need them (Release Flow):
fixes cherry-pick FROM main TO the release branch,
never developed on it
what does NOT exist: a develop branch, environment branches (dev/uat/prod),
merge trains of long-lived branches "integrating"

That release-branch variant — Release Flow — matters for this audience because it’s the trunk-based shape that fits shops with versioned or scheduled releases (and it’s what Azure DevOps’ own teams practice): trunk stays the single source of truth, releases are snapshots taken from it, and the flow of fixes is one-directional.

The case study: your wiki lies to you

Here’s a true story shape, anonymized from a real 2026 estate — and the best argument for auditing rather than believing. The estate’s documentation, in several places, prescribed GitFlow: “branch from dev, PRs target dev.” The estate’s git history told the truth: one main, ~160 merged PRs of short-lived feature/* branches, squash merges, and no dev/uat/prod branch having ever existed. The team had quietly evolved to trunk-based years earlier; the docs never caught up, and every new hire’s first day included a confusing hour of reconciling paper with reality.

The lesson is a habit, and it’s this training’s version of Zero Trust’s currency-checking: docs describe intent; the repo describes practice; audit the gap. Your artifact does both halves:

1. AUDIT: for each of our active repos, report from git history - long-lived
branches that exist (and their last merge in either direction), median
feature-branch lifetime, merge style, PRs targeting anything other than
main. Then diff that reality against what our contributing docs claim,
and list every doc sentence that no longer matches practice.
2. GATE: generate the branch-policy set for main: minimum 1 reviewer with
reset-votes-on-new-push, linked work items required, build-validation
check that plans/builds the changed components, no direct pushes, and
the policy applied via the platform's policy API so it's reviewable
config, not console clicks.

The policy half is the enforcement that makes trunk-based real rather than aspirational: a protected main whose gates run on every PR — reviewer with vote-reset (a re-push after approval re-requires eyes), work-item linkage (traceability for free), and a build check that actually exercises the change. These four are the ground-truth-verified table stakes; everything fancier builds on them.

The maturity ladder above table stakes

RUNG 1 protected main + PR + CI gate <- table stakes, this lesson
RUNG 2 policy-as-config (rulesets/policy API), <- also this lesson
org-level enforcement
RUNG 3 MERGE QUEUE - serializes merges through speculative CI so a green
PR can't land on a main that moved beneath it. Worth it above
roughly ten merges/day per repo; its failure mode is flaky tests
(Lesson 4.2's whole subject)
RUNG 4 true commit-to-trunk behind flags; stacked PRs for dependent
change series
ℹOn GitHub: where the ladder's top rungs live

The upper rungs are currently GitHub-native territory, and that asymmetry is itself worth knowing: GitHub has a built-in merge queue (Enterprise/public repos) and shipped native stacked pull requests in public preview in July 2026; branch protection is being superseded by org-level rulesets, and a separate org-wide Actions policy can require SHA-pinned actions (Lesson 3.3). Azure DevOps has no native merge queue as of August 2026 — the closest native approximation is build validation with expiration set to immediately when the target branch updates (it closes the stale-green race, not the throughput problem), and third-party tools fill the rest of the gap. If your ADO repo genuinely needs rung 3, that’s a real input to platform selection, not a footnote. Statuses here are August-2026; re-verify before relying.

One discipline for the whole ladder: resist quoting adoption statistics for any of it — no credible survey measures merge-queue or stacked-PR adoption, and numbers you’ll see floating around are vendor content. The honest claims are the mechanisms and where they pay.

KNOWLEDGE CHECK

A Meridian team lead reads the trunk-based guidance and objects: 'We ship a versioned product to a regulator quarterly. We NEED release branches — so we're keeping GitFlow.' What's the accurate response?

Key takeaway

One long-lived branch, short-lived features, squash merges, release branches cut-and-cherry-picked when versioning demands them — enforced by four table-stakes policies applied as config, with merge queues and stacked PRs as earned upper rungs rather than defaults. And audit your docs against your git history; one of them is lying, and it’s usually the docs. Next: deciding what to build before building it.

Search lessons