11.16 — CI: the pipeline, decoded
8.2 introduced CI as “a robot teammate that re-runs your suite on every change.” You’ve traced its fingerprints ever since — exit codes, lockfiles, secrets, the fresh-box philosophy. Today you read the robot’s actual instruction sheet — the workflow file 11.2 scaffolded — line by line, and wire the suite in as a gatekeeper on every change. This is what “deploying” a test suite means.
# .github/workflows/playwright.yml
name: Playwright Tests
on:
push: { branches: [main] }
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test
env:
BASE_URL: ${{ secrets.STAGING_URL }}
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-report/The method is the one you’ve used twice: 8.6 decoded package.json, 11.3 decoded the config — this is the third and final detective file: .github/workflows/playwright.yml, created back in 11.2 when you answered “true” to the GitHub Actions question. Every line, no mystery.
The deeper story, with the real names for things — this part is what turns “I saw it” into “I can explain it.”
The pieces compose exactly as you’d guess: shards (11.15) become a matrix of jobs (strategy: matrix: shard: [1, 2, 3, 4]), each running --shard=${{ matrix.shard }}, with a final job merging reports. Nightly full-matrix runs (11.12’s budget) use an on: schedule: cron trigger. The YAML grows; the concepts don’t.
GitHub Actions is one CI among peers — GitLab CI, Jenkins, CircleCI — all the same anatomy: triggers, a fresh runner, ordered steps, secrets, artifacts, an exit-code verdict. Read one fluently (you now do) and the others are dialects, like 9.2’s shells.
The CI=true convention completes here: Actions sets it automatically, which is what flips every process.env.CI ? … : … you decoded in 11.3 — retries on, workers pinned, forbidOnly armed, webServer never reused. One ambient variable, and the whole config shifts into robot mode.
Job note: being the person who can READ the pipeline is quietly powerful. When “CI is broken” panics a standup, the one who opens the YAML, finds the failing step, and says “npm ci failed — lockfile drift, not a test problem” in ninety seconds is the one who gets handed the release keys. That person is now you.
⌨️ run the pipeline
Model the robot: steps run in order, a failure stops everything after it (2.7’s break, career edition), and the pipeline’s color comes from 9.2’s number. Run a healthy day and a broken one.
requirements:
- Write
runPipeline(steps)for an array of{ name, ok }steps: walk them in order — print✓ nameand continue while they pass; on the first failure print✗ nameand STOP (break — nothing after a failed step runs). - After the loop, print the verdict:
pipeline: green (exit 0)if everything passed,pipeline: red (exit 1)otherwise. - Run a healthy day (checkout, setup node, npm ci, playwright test — all ok), then a broken one where
npm cifails (a lockfile mismatch, say) — and notice the suite never even ran.
when you press RUN, the console must show exactly:
✏️ Quick check 1
Why npm ci instead of npm install on the CI box? (what does ci guarantee)
✏️ Quick check 2
Why does the artifact-upload step say if: always()?
✏️ Quick check 3
What single value turns the pull request’s check red or green?
🗣️ Now teach it back
Read the whole pipeline aloud for a friend: triggers, the fresh box (and what it retroactively justifies), each step in order, how secrets reach the config, why if: always() matters, and what the verdict + published report make the suite BE.
Write it as if your friend is sitting next to you. Saved to your journal — future-you will use these notes to teach others.