📑 Contents Overview / TL;DR What "MVP" Means Phase 0 · Inventory Phase 1 · Pilot — 3 Steps Phase 2 · Rollout Phase 3 · Level Up Already There? Skip Ahead Per-Stack Cheat Table CI Snippets (YAML) Checklist & 2-Week Calendar One-Page Cheat Sheet References

1. Overview / TL;DR

The full standard (Software Testing & CI/CD Standard) answers "what should the end state look like?". This page answers the question you actually have first: "what do I do on Monday?" It is the MVP — the smallest amount of work that stops broken code from landing and regressions from shipping, applied one project at a time.

💡

Core idea — protect, don't perfect. The MVP is exactly 3 things per project: ① P0 tests on the core logic, ② CI that runs lint + typecheck + tests + build on every pull request, ③ branch protection so nothing merges red. Nothing else counts toward the MVP. Coverage thresholds, E2E suites, staging environments, security scanners — all of that is Phase 3.

PhaseTimeOutcome
Phase 0 · InventoryHalf a dayA one-page list of every project, its stack, and its risk × activity score — you know what you're protecting and in what order
Phase 1 · Pilot1–2 daysONE project fully protected: P0 tests + CI on PR + branch protection
Phase 2 · Rollout~1 weekEvery remaining project gets the same 3 steps, one per day
Phase 3 · Level UpOngoingP0/P1/P2 priorities, quality gates, staging, security, reporting — from the full standard

The whole plan fits in two weeks. If a project doesn't have the 3 things after Phase 2, it's not done — everything else is optional and can wait.

2. What "MVP" Means

The MVP is not "a little bit of testing". It is a definition of protected — three checks that take five minutes to verify on any repo. When all three pass, broken code cannot reach production unnoticed. That is the entire goal.

  • ✓
    Check 1 — Tests exist and pass locally. In a clean checkout, npm test (or the stack's equivalent) runs and passes, and it covers the core logic: auth/session, money or payments math, data persistence and migrations, external API integrations, and critical transforms.
  • ✓
    Check 2 — CI runs on every PR. Opening a pull request automatically runs lint + typecheck + tests + build (snippets in section 8), and the results are visible on the PR itself.
  • ✓
    Check 3 — Red cannot merge. Branch protection requires a pull request, requires the CI status check to pass, and blocks direct pushes to main.
  • ✅

    Protected = Check 1 yes, Check 2 yes, Check 3 no (can't merge red). Say that sentence to yourself when you're tempted to add a 4th requirement — a coverage gate, a linter rule, an E2E suite. Those improve quality; they do not belong in the MVP.

    ⚠️

    Explicitly NOT in the MVP: coverage thresholds, E2E test suites, staging environments, SAST/security scanners, test data management, reporting dashboards, k6 performance tests. Each has a home in the full standard — adding any of them early is how the MVP turns into a 3-month project that never ships.

    3. Phase 0 · Inventory (Half a Day)

    You can't prioritize what you haven't listed. Copy this table, fill it in for every project (including internal tools and scripts — they're the cheapest to protect and the first to be forgotten), and score each row. Build nothing in this phase.

    ProjectStackTests today?CI today?Risk (money / users / data)ActivityScore (risk × activity)
    Example: fund-price APINode + TSNoneNoneHigh — feeds money decisionsHigh — weekly deploys9/9 → pilot
    Example: marketing siteReact + ViteSmoke scriptNoneLowLow3/9 → last
    Your project…………………
    Your project…………………
    💡

    Ranking rule: score = risk × activity (each 1–3). Highest score goes first. Ties go to the simplest project — the fastest possible first win builds the habit and the template.

    "Risk" is about blast radius: does it move money, hold user data, or serve paying users? "Activity" is about how often code changes — a dormant repo is already protected; an active one is bleeding.

    4. Phase 1 · Pilot — The 3 Steps (1–2 Days)

    Pick the pilot from the inventory score (see the ranking rule in Phase 0). Then do exactly three things — in this order, no skipping:

  • 1
    P0 tests on the core logic. Identify the code paths where a bug hurts most: authentication/session handling, payment or money math, data persistence and migrations, external API integrations, and any critical transforms (pricing, fee, risk calculations). Write 5–10 focused tests covering those paths. Not a quota — a safety net for the parts that matter.
  • 2
    CI on every PR. Add a minimal pipeline that runs lint → typecheck → tests → build and reports status on the pull request. Ready-to-copy YAML for GitHub Actions and GitLab CI in section 8.
  • 3
    Branch protection. Protect main: pull requests required, the CI status check required, direct pushes blocked. GitHub: Settings → Branches → Add rule. GitLab: Settings → Repository → Protected branches.
  • ✅

    Pilot is done when… all three checks from section 2 are green on the pilot repo: tests pass locally, CI runs on every PR, and a red PR cannot be merged. You now have a working template — everything after this is copy-paste.

    ⚠️

    One project at a time. Wiring 5 repos in parallel is how the pilot dies on day 2. The pilot exists to produce the template; the template is what makes the rollout fast.

    5. Phase 2 · Rollout (~1 Week)

    Work through the inventory in score order, one project per day. For each project, repeat the same 3 steps, adapting only the tooling via the per-stack cheat table (section 7). The pipeline shape stays identical: lint → typecheck → tests → build on every PR.

    ✅ During rollout
    • Copy the pilot's CI file and adjust package-manager / commands only
    • Move the pilot's 5–10 P0 test cases to the new project's core paths
    • Apply the same branch protection rule
    • Mark the project protected in your inventory table
    🚫 During rollout
    • No new requirements mid-rollout — a missing check goes on the Phase 3 list, not into today
    • No tool migration mandates — if the project already has a test runner, keep it
    • No perfecting the template — ship the same skeleton, improve it after the week
    💡

    If a project has no test runner at all, pick the stack's default from the cheat table — do not spend the day evaluating frameworks. The MVP cares that tests exist and run in CI, not which framework they use.

    6. Phase 3 · Level Up (Ongoing)

    Once every project passes the 3 checks, the MVP has done its job. Everything after this point comes from the full standard — add items one at a time, each on its own, only when the previous one is actually working. Suggested order:

    Level-up itemWhy it mattersWhere it lives in the standard
    P0 / P1 / P2 test prioritiesTurns "5–10 tests" into a repeatable rule for every new featureStandard §6
    Quality gatesBlocking vs non-blocking gates at each pipeline stageStandard §9
    Environment strategyDev → staging → prod with config/secrets rulesStandard §11
    Security (T3)SAST + dependency scanning in CIStandard §4
    Test data managementSeed scripts and isolation — kills flaky pipelinesStandard §12
    Coverage + reportingTrends you can act on, not quotas to fightStandard §18
    Central templatesOne CI template repo for 10+ projectsStandard §13
    ⚠️

    The trap: skipping straight to coverage thresholds or E2E suites while the 3 checks are missing on some project. The standard is a ladder — you can climb from any rung, but you still have to stand on the one below it.

    7. Already There? Skip-Ahead Fork (GitLab)

    If your project already runs unit tests + SAST + dependency scanning in GitLab CI, you are past the MVP baseline — do not start at Phase 0. Your "three checks" are mostly in place; the next moves are about making what you already run enforce quality instead of just reporting it.

    ✅

    You are here: Phase 1 steps (b) and (c) are done. Start at step 1 below. Each step is one pipeline change with a merge-request gate — same "one change, one PR" rhythm as the MVP.

    #Next moveWhy nowEffort
    1Coverage threshold as a blocking gateTests without an enforced floor let coverage silently slide — the standard's gate table sets the rule: ≥ 80% on changed code, PR/mergeHalf a day
    2Branch protection + merge checks (verify, 5 min)The last MVP check: protected branch, "pipelines must succeed", ≥ 1 MR approval5 minutes
    3Secret detection + license scanningOne job each from the same Secure templates you already run — closes the two cheapest security gaps left1–2 hours
    4Integration tests, then a few P0 journeysYour pyramid is unit-only today; add Testcontainers-based integration, then 3–5 P0 journeys (login, checkout, core API)2–3 days
    5Review Apps (preview per MR)A live environment on every merge request — changes how reviewers actually reviewHalf a day
    6SBOM / attestationYour dependency scan already produces the data — export it as a published artifactA few hours

    Step 1 in practice — GitLab: publish a Cobertura report from the test job (this also turns on the coverage-delta widget on every MR), then add a check job that fails below your threshold:

    .gitlab-ci.yml — test job
    test:
      stage: test
      script:
        - npm test -- --coverage
      coverage: '/All files[^|]*\|[^|]*\s+([\d.]+)%/'
      artifacts:
        reports:
          coverage_report:
            coverage_format: cobertura
            path: coverage/cobertura-coverage.xml
    .gitlab-ci.yml — blocking threshold job
    coverage-check:
      stage: test
      needs: [test]
      script:
        - |
          cov=$(grep -oP 'All files[^|]*\|\s*\K[\d.]+' coverage/coverage-summary.txt)
          if (( $(echo "$cov < 80" | bc -l) )); then
            echo "Coverage ${cov}% < 80% — failing the MR"; exit 1
          fi
          echo "Coverage ${cov}% ≥ 80% — gate passed"
    ℹ️

    Out of scope here: deployment / GitOps. If deployment is already set up for the project, this fork deliberately stops at the merge gate — nothing in steps 1–6 touches delivery. The point of the fork is to make "merged" mean "protected", not to change how code ships.

    ⚠️

    Gate hygiene (Standard §9): a gate that is routinely bypassed is worse than no gate. Each threshold you add needs an owner and a removal process — when the coverage check is flaky, fix the test or remove the gate; never "just merge it". Tag your existing tests P0/P1 so the gate model knows which must be 100% green.

    Past the fork — operate the loop. If steps 1–6 are all green, you have finished the build phase of CI/CD: every "should we have this?" question is answered. The next phase is operate — verify deploys, keep the gates trustworthy, measure outcomes, and ratchet thresholds up quarterly instead of adding new ones.

    #Next moveWhy nowEffort
    1Post-deploy smoke verificationEvery gate above runs before merge; nothing verifies the deployed artifact after. Smoke the P0 journeys against the deployed URL — staging blocks the pipeline, prod alerts on failure1 day
    2Flaky-test hygieneA flaky gate gets bypassed, and a bypassed gate is worse than none (Standard §9) — track flaky suites with owners + remediation dates, quarantine or fixOngoing
    3Diff coverageTotal-coverage floors get gamed: 80% overall can hide 0% on new code — enforce the threshold on changed lines onlyHalf a day
    4DORA feedback loopAll gates green is not proof it works — track deployment frequency, lead time, change failure rate, MTTR; review quarterly, then fix the worst numberOngoing
    🔄

    Mental model: the fork made "merged" mean "protected". Operating the loop makes "deployed" mean "verified" and "green" mean "trustworthy" — the gates tell you how, DORA tells you whether. Still zero deployment/GitOps content: everything above verifies and hardens the delivery you already have.

    8. Per-Stack Cheat Table

    The MVP is technology-agnostic: same 3 checks, different tools. Use the stack's default runner — if the project already has one, keep it. This table is only for projects starting from zero.

    StackTest runner (default)API / E2E toolCI command
    React / Vue SPAVitest or Jest + Testing LibraryPlaywright (a few smoke journeys)npm ci && npm test && npm run build
    NestJS / Express (Node)Jest or Vitest + SupertestPlaywright or Apifox for API flowsnpm ci && npm test && npm run build
    Bun + TypeScriptbun test—bun install && bun test
    Spring Boot (Java)JUnit 5 + MockMvcTestcontainers / REST Assured./mvnw verify
    Python (FastAPI / Django / Flask)pytest + httpxpytest + Playwrightpip install -e .[dev] && pytest
    .NETxUnit + WebApplicationFactoryPlaywrightdotnet test
    Flutterflutter_testintegration_testflutter test
    iOS (Swift)XCTestXCUITestxcodebuild test
    Android (Kotlin)JUnit + Espresso—./gradlew test
    ℹ️

    Lint + typecheck exist per language too (ESLint / Biome, ESLint or tsc --noEmit, Checkstyle, Ruff / mypy, swiftlint…). Whatever the project already uses, wire it into the same pipeline — the stage is standard, the tool is not.

    9. CI Snippets — GitHub Actions & GitLab CI

    Minimal, copy-paste, no extras. Both run the same 4 commands on every pull request: lint → typecheck → tests → build. Adapt the commands per stack from section 8.

    GitHub Actions — .github/workflows/ci.yml
    name: CI
    on:
      pull_request:
      push:
        branches: [main]
    
    jobs:
      verify:
        runs-on: ubuntu-latest
        steps:
          - uses: actions/checkout@v4
          - uses: actions/setup-node@v4
            with:
              node-version: 20
              cache: npm
          - run: npm ci
          - run: npm run lint
          - run: npm run typecheck
          - run: npm test
          - run: npm run build
    GitLab CI — .gitlab-ci.yml
    stages: [verify, build]
    
    verify:
      stage: verify
      image: node:20
      rules:
        - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      script:
        - npm ci
        - npm run lint
        - npm run typecheck
        - npm test
    
    build:
      stage: build
      image: node:20
      rules:
        - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
      script:
        - npm ci
        - npm run build
    💡

    Run on PRs only at first. Don't add nightly runs, release pipelines, or deploy stages in the MVP — that's Phase 3. A pipeline that only verifies pull requests is the whole MVP.

    10. Protected Checklist & 2-Week Calendar

    Per-project protected checklist — tick all three, or the project is not done:

    CheckHow to verifyDone?
    ① P0 tests exist & passnpm test (or equivalent) green in a clean checkout⬜
    ② CI runs on every PRLint + typecheck + tests + build reported on the PR⬜
    ③ Red cannot mergeBranch protection: PR required, CI check required, direct push blocked⬜

    2-week calendar template — fill in project names from your inventory score:

    DayWhatProject
    Day 1Phase 0 — inventory table + scoresAll
    Day 2–3Phase 1 — P0 tests, CI, branch protectionPilot: ____
    Day 4Phase 2 — same 3 steps____
    Day 5Phase 2 — same 3 steps____
    Day 6Phase 2 — same 3 steps____
    Day 7–8Phase 2 — same 3 steps + weekend buffer____
    Day 9–10Phase 2 — finish remaining projects____
    Day 11Re-run the protected checklist on every projectAll
    Day 12–14Phase 3 — pick the first level-up item, one only____
    ✅

    End of week 2: every project protected, one level-up item started. From here the standard's maturity model takes over — each level-up is its own small project.

    11. One-Page Cheat Sheet

    ✅ The 3 steps (every project)
    • 1. P0 tests — auth, money, data, external APIs, critical transforms (5–10 tests)
    • 2. CI on PR — lint → typecheck → tests → build
    • 3. Branch protection — PR required, CI required, no direct push
    🗓 The 4 phases
    • P0 · Inventory — half a day, score = risk × activity
    • P1 · Pilot — 1–2 days, one project, produce the template
    • P2 · Rollout — ~1 week, one project per day, same skeleton
    • P3 · Level Up — ongoing, one item at a time from the standard
    ℹ️

    Decision rules: pilot = highest risk × activity (tie → simplest). Keep existing runners, never migrate tools in the MVP. New requirement mid-rollout → Phase 3 list, not today. Protected = tests pass + CI on PR + red can't merge.

    💡

    If you remember one sentence: "Protect first, perfect later — three things per project, one project at a time, everything else from the standard."

    12. References