CI/CD Automation Tutorial 0/46 lessons ~6 min read Lesson 8

    Git Workflows for CI

    Git workflows for CI define which git events start pipelines, how long branches live, and whether production deploys from tags, merge commits, or trunk HEAD.

    Course progress0%
    Focus
    20 guided sections
    Practice signal
    Examples included
    Career prep
    Interview Q&A included

    Introduction

    Git workflows for CI define which git events start pipelines, how long branches live, and whether production deploys from tags, merge commits, or trunk HEAD. Staff engineers map Git Flow, GitHub Flow, trunk-based development, merge queues, and branch protection to explicit CI triggers — not "run CI on push" without naming the branch class.

    The story

    A 120-engineer fintech team ran Git Flow with develop and release/* branches but only wired CI to main. Hotfixes on release/4.2 merged without tests; a payment regression reached prod because the release branch had no required checks. The fix was not "more Jenkins" — it was a trigger matrix: PR → full CI, merge to protected branches → artifact + staging, tag v* → prod promotion.

    Understanding the topic

    Every workflow model implies a CI trigger contract. The contract answers: which refs fire which jobs, whether fork PRs get secrets, and how release trains map to tags.

    • Git Flow: long-lived develop + release/* + hotfix/*. CI triggers: PR to develop (integration), PR to release/* (RC gate), tag on main after hotfix merge (prod).
    • GitHub Flow: short-lived feature branches off main. CI triggers: pull_request (full verify), push to main (build artifact + deploy staging), optional workflow_dispatch for prod.
    • Trunk-Based Development (TBD): everyone commits to trunk (or ≤1-day branches). CI triggers: every push to main (fast feedback), feature flags hide incomplete work; release tags cut from green trunk SHAs.
    • Merge Queues: when branch protection requires up-to-date branches, the queue merges serially into a temporary integration branch and runs CI before landing on main — trigger is queue entry, not raw push.
    • Branch Protection: rules enforce required status checks, reviews, signed commits — CI must expose check names that match protection rules exactly.

    Internal architecture

    Workflow → CI trigger mapping — how each model connects git events to pipeline stages:

    text
    Git Flow
    feature/* --PR--> develop --> CI: unit + lint
    release/* --PR--> main --> CI: full + staging deploy
    hotfix/* --PR--> main+develop --> CI: smoke + security scan
    tag v* on main --> CD: prod promote
    GitHub Flow
    feature/* --PR--> main --> CI: full matrix
    merge main --> CI: build + push image + staging
    workflow_dispatch --> CD: prod (approval gate)
    Trunk-Based
    push main (small commits) --> CI: fast (<10 min) + deploy trunk
    tag v* (release train) --> CD: prod from same artifact digest
    Merge Queue
    PR labeled "merge queue" --> CI on merge_group ref
    green + merged --> push main triggers deploy pipeline
    Branch Protection
    required checks: ci/build, ci/test, ci/scan
    merge blocked until all green on latest merge-base

    Visual explanation

    Two diagrams show where Git Workflows for CI lives in the delivery path and how teams implement it in production.

    Git Workflows for CI — system view
    Git event
    PR · push · tag
    Branch rules
    Protection · queue
    CI pipeline
    Build · test · scan
    Artifact gate
    Immutable output
    Where this topic sits in the delivery path.
    Git Workflows for CI — execution flow
    Feature branch
    Short-lived
    Required checks
    All green
    Merge to trunk
    Queue optional
    Deploy trigger
    Tag or main push
    Follow this loop when designing or reviewing pipelines.

    Step-by-step explanation

    1. Inventory current branches: list long-lived refs (develop, main, release/*) and average branch age from git log.
    2. Draft a trigger matrix spreadsheet: rows = branch patterns, columns = CI jobs (lint, unit, integration, scan, deploy).
    3. Configure GitHub branch protection on main with required check names matching workflow job outputs exactly.
    4. Add on: pull_request and on: push: branches: [main] (or merge queue merge_group) to workflow YAML.
    5. Validate: open a PR, confirm checks appear; merge, confirm artifact job runs; tag, confirm prod workflow receives digest — not a rebuild.

    Production implementation

    GitHub Actions trigger matrix for GitHub Flow + merge queue + branch protection:

    • Use merge_group event when GitHub merge queue is enabled — without it, queued merges skip CI.
    • Name jobs consistently; branch protection references job names or check runs, not workflow file names.
    • For Git Flow release branches, duplicate workflow with on: pull_request: branches: ['release/**'] and stricter integration tests.
    yaml
    # .github/workflows/ci.yml
    name: CI
    on:
    pull_request:
    branches: [main]
    push:
    branches: [main]
    merge_group:
    branches: [main]
    concurrency:
    group: ci-${{ github.ref }}
    cancel-in-progress: true
    jobs:
    build-test:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - uses: actions/setup-node@v4
    with: { node-version: 20, cache: npm }
    - run: npm ci && npm test
    - run: npm run build
    security-scan:
    needs: build-test
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - run: npm audit --audit-level=high
    # Branch protection: require "build-test" and "security-scan"

    Execution workflow

    1Map git workflow to CI triggers
    1 / 5

    Document branch taxonomy

    List every long-lived and ephemeral branch pattern and its owner team.

    Include hotfix, release, env branches, and bot branches (renovate/dependabot).

    Real-world use

    Google's internal monorepo uses trunk-based development with TAP (Test Automation Platform) on every changelist. GitHub documented merge queues after customers hit "green PR + broken main" from merge skew. GitLab Flow adds environment branches (staging, production) — CI triggers differ per environment branch push.

    Enterprise use cases

    Shopify-scale teams often run trunk-based with merge queues and 200+ required checks split by path filters. Git Flow persists in regulated release-train orgs (quarterly SOX releases) where release/* branches get RC CI distinct from feature PR CI.

    • Merge queue + TBD: Meta-style stacked diffs land via queue; CI runs on synthetic merge commit before trunk moves.
    • Git Flow + compliance: release branch PR requires QA sign-off check + SBOM upload before tag triggers prod.
    • GitHub Flow + SaaS: every merge to main deploys staging; prod is manual environment approval on same artifact digest.

    Production case study

    A B2B payments company (80 engineers) migrated from Git Flow to GitHub Flow + merge queue over one quarter. Release cadence went from bi-weekly trains to daily trunk deploys with feature flags.

    • Before: CI only on develop; main merges were untested manual cherry-picks.
    • Trigger redesign: PR → full CI; merge queue → integration; push main → artifact + staging; tag → prod.
    • Branch protection: 2 reviews, 4 required checks, signed commits, no direct push.
    • Outcome: change failure rate 22% → 6%; median PR wait dropped 4h → 45m after queue tuning.

    Trade-offs

    • Git Flow: clear release isolation; cost is branch proliferation and complex CI trigger sprawl.
    • GitHub Flow: simple mental model; requires discipline on short branches and feature flags for incomplete work.
    • Trunk-based: fastest integration feedback; demands excellent CI speed, flags, and merge queue at scale.
    • Merge queues: eliminate skew merges; add latency (serial merges) and require CI budget for synthetic integration runs.

    Security implications

    Workflow choice directly affects supply-chain exposure — fork PR workflows must not leak secrets, and protected branches must block force-push bypass.

    • pull_request_target on fork PRs runs with base repo secrets — use only with strict path filters and approval gates.
    • Branch protection "Include administrators" prevents emergency bypass of CI on main.
    • Signed commits + required reviews pair with CI: a green build on unsigned commit should still fail policy.
    • Tag protection rules prevent arbitrary v* tags from triggering prod without release-manager role.

    Scalability analysis

    At hundreds of PRs/day, trigger design determines CI cost and developer wait time.

    • Merge queues serialize merges — size queue depth vs CI capacity; stale queue entries waste runner minutes.
    • Git Flow release branches multiply long-lived refs — each needs CI budget or drifts untested.
    • Path filters on pull_request reduce noise but require CODEOWNERS alignment for bypass risk.
    • Concurrency groups (cancel-in-progress) save minutes on feature branches but can hide flaky race tests.

    Staff engineer insights

    • Draw the trigger matrix before writing YAML — teams that start with tools end up with dead checks on unused branches.
    • Merge queue is not optional above ~30 concurrent PRs on one trunk if you require branches up to date.
    • Git Flow can coexist with trunk for platform vs product repos — don't force one religion org-wide.
    • Required check names must match what developers see in PR UI; rename a job and you silently disable protection.

    Best practices

    • One trigger matrix doc in the repo README or ADR — updated when workflows change.
    • Prefer pull_request over push on feature branches to avoid duplicate runs on every commit push.
    • Use merge queue when requiring "branch up to date" on high-velocity trunk.
    • Tag prod releases from CI-built artifacts; never rebuild on tag event.

    Common mistakes

    • Enabling merge queue without merge_group workflow trigger — merges land untested.
    • Required check names referencing old job IDs after workflow refactor — protection becomes theater.
    • Running full deploy pipeline on every PR push — burns budget and teaches ignore-red-build culture.

    Advanced interview questions

    Interview Prep

    Practice concise answers, then expand each card for the explanation.

    5 questions
    1AdvancedQuestionHow would you map Git Flow branches to CI triggers for a SOX-regulated quarterly release?+

    Answer

    Feature PRs to develop run tier-1/2 CI. Release branch PRs to main run full integration, SBOM, and staging deploy. Hotfix PRs run expedited CI with security scan. Prod only from signed tag on main built from merge commit SHA — artifact digest promoted, not rebuilt.

    Follow-up

    How do you prevent develop from drifting untested against main?
    2AdvancedQuestionWhen does a merge queue replace 'require branches up to date'?+

    Answer

    When concurrent PRs cause green-isolated PRs to break main after merge (merge skew). Queue creates temporary merge commit, runs CI, then lands. Replace manual rebase churn — not needed at low PR volume.

    Follow-up

    What happens to CI cost?
    3AdvancedQuestionDesign CI triggers for trunk-based development with feature flags.+

    Answer

    Every push to main runs fast CI (<10 min) and auto-deploys to staging. Incomplete features behind flags; flag service validates before prod. Release tags cut from green main SHAs; prod promotes artifact by digest.

    Follow-up

    How do you handle partial features in shared codebase?
    4AdvancedQuestionA fork PR needs CI but must not access prod secrets — what's your workflow design?+

    Answer

    Use pull_request (not pull_request_target) for untrusted forks — no secrets. Optional workflow_run or maintainer /ok-to-test label triggers privileged re-run on internal branch. Path filters limit changed files.

    Follow-up

    When is pull_request_target ever acceptable?
    5AdvancedQuestionBranch protection shows green but prod broke — what failed?+

    Answer

    Likely check ran on stale SHA, optional checks used instead of required, admin bypass, or deploy pipeline triggered separately without same gates. Audit merge commit vs last green check SHA; verify required checks list matches job names.

    Follow-up

    How do you prove compliance to auditors?

    Hands-on exercise

    Build a trigger matrix for a repo using GitHub Flow + merge queue. Implement workflows and branch protection in a test repo.

    • Deliberately fail a check — confirm merge blocked.
    • Enable merge queue — confirm merge_group workflow runs.
    • Document trigger matrix in TRIGGER_MATRIX.md.
    bash
    # Create test repo and protection (gh CLI)
    gh repo create cicd-trigger-lab --public --clone
    cd cicd-trigger-lab
    # Add ci.yml (from productionImplementation), then:
    gh api repos/{owner}/cicd-trigger-lab/branches/main/protection \
    -f required_status_checks[strict]=true \
    -f required_status_checks[checks][]=context=build-test \
    -f required_pull_request_reviews[required_approving_review_count]=1
    # Open PR, verify checks, enable merge queue in repo settings, merge

    Summary

    You can map Git Flow, GitHub Flow, trunk-based development, merge queues, and branch protection to concrete CI triggers — PR tiers, merge integration, trunk deploy, and tag promotion. Design the matrix before YAML; audit check names against protection rules.

    Ready to mark this lesson complete?Track your journey across the entire course.