📑 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 ReferencesTesting & CI/CD — MVP Action Plan
The "start here" companion to the full standard: a minimal, phased plan (inventory → pilot → rollout → level up) that protects every project with just three things — P0 tests, CI on every PR, and branch protection.
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.
| Phase | Time | Outcome |
|---|---|---|
| Phase 0 · Inventory | Half a day | A 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 · Pilot | 1–2 days | ONE project fully protected: P0 tests + CI on PR + branch protection |
| Phase 2 · Rollout | ~1 week | Every remaining project gets the same 3 steps, one per day |
| Phase 3 · Level Up | Ongoing | P0/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.
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.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.
| Project | Stack | Tests today? | CI today? | Risk (money / users / data) | Activity | Score (risk × activity) |
|---|---|---|---|---|---|---|
| Example: fund-price API | Node + TS | None | None | High — feeds money decisions | High — weekly deploys | 9/9 → pilot |
| Example: marketing site | React + Vite | Smoke script | None | Low | Low | 3/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:
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.
- 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
- 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 item | Why it matters | Where it lives in the standard |
|---|---|---|
| P0 / P1 / P2 test priorities | Turns "5–10 tests" into a repeatable rule for every new feature | Standard §6 |
| Quality gates | Blocking vs non-blocking gates at each pipeline stage | Standard §9 |
| Environment strategy | Dev → staging → prod with config/secrets rules | Standard §11 |
| Security (T3) | SAST + dependency scanning in CI | Standard §4 |
| Test data management | Seed scripts and isolation — kills flaky pipelines | Standard §12 |
| Coverage + reporting | Trends you can act on, not quotas to fight | Standard §18 |
| Central templates | One CI template repo for 10+ projects | Standard §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 move | Why now | Effort |
|---|---|---|---|
| 1 | Coverage threshold as a blocking gate | Tests without an enforced floor let coverage silently slide — the standard's gate table sets the rule: ≥ 80% on changed code, PR/merge | Half a day |
| 2 | Branch protection + merge checks (verify, 5 min) | The last MVP check: protected branch, "pipelines must succeed", ≥ 1 MR approval | 5 minutes |
| 3 | Secret detection + license scanning | One job each from the same Secure templates you already run — closes the two cheapest security gaps left | 1–2 hours |
| 4 | Integration tests, then a few P0 journeys | Your pyramid is unit-only today; add Testcontainers-based integration, then 3–5 P0 journeys (login, checkout, core API) | 2–3 days |
| 5 | Review Apps (preview per MR) | A live environment on every merge request — changes how reviewers actually review | Half a day |
| 6 | SBOM / attestation | Your dependency scan already produces the data — export it as a published artifact | A 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:
test:
stage: test
script:
- npm test -- --coverage
coverage: '/All files[^|]*\|[^|]*\s+([\d.]+)%/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: coverage/cobertura-coverage.xml
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 move | Why now | Effort |
|---|---|---|---|
| 1 | Post-deploy smoke verification | Every 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 failure | 1 day |
| 2 | Flaky-test hygiene | A flaky gate gets bypassed, and a bypassed gate is worse than none (Standard §9) — track flaky suites with owners + remediation dates, quarantine or fix | Ongoing |
| 3 | Diff coverage | Total-coverage floors get gamed: 80% overall can hide 0% on new code — enforce the threshold on changed lines only | Half a day |
| 4 | DORA feedback loop | All gates green is not proof it works — track deployment frequency, lead time, change failure rate, MTTR; review quarterly, then fix the worst number | Ongoing |
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.
| Stack | Test runner (default) | API / E2E tool | CI command |
|---|---|---|---|
| React / Vue SPA | Vitest or Jest + Testing Library | Playwright (a few smoke journeys) | npm ci && npm test && npm run build |
| NestJS / Express (Node) | Jest or Vitest + Supertest | Playwright or Apifox for API flows | npm ci && npm test && npm run build |
| Bun + TypeScript | bun test | — | bun install && bun test |
| Spring Boot (Java) | JUnit 5 + MockMvc | Testcontainers / REST Assured | ./mvnw verify |
| Python (FastAPI / Django / Flask) | pytest + httpx | pytest + Playwright | pip install -e .[dev] && pytest |
| .NET | xUnit + WebApplicationFactory | Playwright | dotnet test |
| Flutter | flutter_test | integration_test | flutter test |
| iOS (Swift) | XCTest | XCUITest | xcodebuild 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.
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
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:
| Check | How to verify | Done? |
|---|---|---|
| ① P0 tests exist & pass | npm test (or equivalent) green in a clean checkout | ⬜ |
| ② CI runs on every PR | Lint + typecheck + tests + build reported on the PR | ⬜ |
| ③ Red cannot merge | Branch protection: PR required, CI check required, direct push blocked | ⬜ |
2-week calendar template — fill in project names from your inventory score:
| Day | What | Project |
|---|---|---|
| Day 1 | Phase 0 — inventory table + scores | All |
| Day 2–3 | Phase 1 — P0 tests, CI, branch protection | Pilot: ____ |
| Day 4 | Phase 2 — same 3 steps | ____ |
| Day 5 | Phase 2 — same 3 steps | ____ |
| Day 6 | Phase 2 — same 3 steps | ____ |
| Day 7–8 | Phase 2 — same 3 steps + weekend buffer | ____ |
| Day 9–10 | Phase 2 — finish remaining projects | ____ |
| Day 11 | Re-run the protected checklist on every project | All |
| Day 12–14 | Phase 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
- 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
- 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
-
1Software Testing & CI/CD Standard — Deep StudyThe full reference this plan is the companion to: categories T1–T6, levels & pyramid, P0/P1/P2, quality gates, pipeline design, environments, governance.
-
2Testing & CI/CD Pipeline Architecture (diagram)Visual reference of the end-state pipeline this MVP grows into: 11 stages, 4 quality gates, PR / staging / production contexts.
-
3Martin Fowler — The Practical Test PyramidWhy the pyramid shape (many unit tests, few E2E) is the right default and what each level is for.
-
4Martin Fowler — Continuous IntegrationThe original case for integrating and verifying every change — the backbone of Check 2.
-
5GitHub Actions DocumentationOfficial docs for the GitHub Actions snippet in section 9 (workflows, status checks, branch protection).
-
6GitLab CI/CD DocumentationOfficial docs for the GitLab snippet in section 9 (pipelines, rules, protected branches).
-
7Google Testing Blog — Just Say No to More End-to-End TestsThe argument for keeping E2E minimal — why it's Phase 3, not part of the MVP.
-
8OWASP Top TenThe security risk catalog behind T3 — the starting point for the security level-up item.