CI/CD Fundamentals · Module 05 of 12

Tests, quality gates and build matrices

Layer fast checks, tests and compatibility matrices so a pipeline reports useful evidence instead of a single opaque pass/fail result.

Learning objectives

By the end of this module, you should be able to:

  • Order fast static checks before slower tests.
  • Explain when a matrix is useful.
  • Avoid making required quality gates non-blocking.

Quality gates should answer specific risks

Syntax, lint, unit, integration and security checks catch different classes of problems. Name jobs and checks by the evidence they provide so failures are diagnosable.

Matrices test meaningful combinations

A strategy matrix can run the same job against multiple supported runtimes or operating systems. Test combinations you actually support; an oversized matrix can waste time without increasing confidence.

Required checks must really block

continue-on-error is useful for experimental diagnostics, not for a check that is supposed to protect a deployment or merge.

Worked examples

See the idea in practice.

Runtime matrix

strategy:
  matrix:
    node: [22, 24]
steps:
  - uses: actions/setup-node@v7
    with:
      node-version: ${{ matrix.node }}
  - run: npm ci
  - run: npm test
  • The same validation executes against two supported Node versions.
  • Matrix jobs can run in parallel.
Hands-on lab

Lab — Build a layered quality gate

Goal: Create syntax, unit and integration checks and stop on the first failing required gate.

STEP 1

Create application

mkdir -p ~/gnu-cicd-labs/module05 && cd ~/gnu-cicd-labs/module05
printf 'module.exports=(a,b)=>a+b;\n' > calc.js
STEP 2

Create unit gate

cat > unit.sh <<'EOF'
#!/usr/bin/env bash
set -e
[ "$(node -e "process.stdout.write(String(require('./calc')(2,3)))")" = "5" ]
EOF
chmod +x unit.sh
STEP 3

Create pipeline gate

cat > quality.sh <<'EOF'
#!/usr/bin/env bash
set -euo pipefail
node --check calc.js
./unit.sh
node -e "const f=require('./calc'); if(f(10,-3)!==7) process.exit(1)"
echo 'QUALITY PASS'
EOF
chmod +x quality.sh
STEP 4

Run gates

./quality.sh

Verify

  • Syntax and both behavior checks pass.
  • QUALITY PASS appears only after all required checks succeed.

Expected outcome

  • The pipeline has multiple explicit confidence layers.

If it fails

  • Run the failing gate directly to narrow the problem.
  • Do not hide a required failure with || true or continue-on-error.
Real-world connection

Well-layered CI reduces time-to-diagnosis because developers can see whether a change failed syntax, unit behavior, integration or another specific gate.

Avoid these traps

Common mistakes

  • Using one huge test command with no diagnostic separation.
  • Creating a matrix for versions the product does not support.
  • Marking a required quality gate continue-on-error.
Knowledge check

Can you explain it without looking back?

Open each answer only after you have tried to answer the question yourself.

1Why put fast checks early?

They fail quickly and avoid spending runner time on slower downstream work when basic validation already failed.

2What problem does a matrix solve?

It repeats a job across meaningful supported combinations such as runtime versions or operating systems.

3Should a required deployment gate use continue-on-error?

Normally no, because that would allow a failed required check to be treated as non-blocking.

My Learning

Record your progress for this module.

Progress is saved in this browser immediately. When you sign in to My Learning, it can also sync across devices.

Not started

Attempt the core lab and knowledge checks before marking the module complete.