Skip to content

ci(mutation): wire Stryker mutation testing into nightly CI#106

Merged
PAMulligan merged 1 commit into
mainfrom
80-wire-mutation-testing-into-ci
Jun 20, 2026
Merged

ci(mutation): wire Stryker mutation testing into nightly CI#106
PAMulligan merged 1 commit into
mainfrom
80-wire-mutation-testing-into-ci

Conversation

@PAMulligan

Copy link
Copy Markdown
Collaborator

Summary

@stryker-mutator/* was in devDependencies but no workflow ran Stryker — mutation score was referenced (Phase 8) but never measured. This wires it up end-to-end (#80).

What was actually wrong

The existing root stryker.config.json is a template for generated apps (targets a root src/ that doesn't exist here) and uses a filename Stryker doesn't auto-discover (stryker.conf.*). So the framework never mutation-tested its own code. This PR adds a working setup for packages/pipeline (the substantial TS library with 133 fast unit tests).

Changes

  • stryker.conf.json (repo root) — mutation-tests packages/pipeline/src. The interesting bit: it runs from packages/pipeline so the pnpm-linked node_modules resolve inside Stryker's sandbox (a monorepo gotcha), and declares plugins explicitly so the vitest runner + typescript checker load regardless of cwd. Excludes barrels, CLIs, entry points, and *.d.ts.
  • packages/pipeline/vitest.stryker.config.ts — excludes the end-to-end test, which reads a repo-root fixture outside the sandbox and would fail Stryker's initial test run. Unit tests provide the mutant-killing signal.
  • .github/workflows/mutation.yml — runs Stryker nightly (cron) and on demand (workflow_dispatch, with an optional --mutate scope), never on PRs. Informational/non-blocking: posts the mutation score to the run summary and uploads the HTML report as an artifact.
  • README — a "Mutation testing (Stryker)" section: how to run locally and the opt-in threshold.

Acceptance criteria

  • stryker.conf.json at the repo root with sensible defaults
  • CI workflow .github/workflows/mutation.yml (nightly + on-demand, off the PR path)
  • Mutation score threshold in pipeline.config.json, opt-in — qualityGate.mutationScore = { enabled: false, threshold: 80, blocking: false } (already present; now documented as opt-in in the README, the actionable part of the AC)
  • README updated with how to run locally

Verified locally

Stryker runs cleanly against packages/pipeline — initial test run passes, mutants instrument, the sandbox runs unit tests and kills mutants, and a complete run produces a mutation score + JSON/HTML reports (confirmed on a scoped subset; a full run is nightly-CI-scale, hence the schedule). prettier --check ., check-doc-counts, and valid-JSON checks pass; generated .stryker-tmp/ and reports/mutation/ are gitignored.

Refs #80

Stryker deps were declared but no workflow ran them. Add a working root config,
a nightly/on-demand workflow, and docs (#80).

- stryker.conf.json: mutation-tests packages/pipeline (TS); runs from the package
  so pnpm-linked node_modules resolve in the sandbox; vitest runner + typescript
  checker; excludes barrels/CLIs/entry points
- vitest.stryker.config.ts: excludes the e2e test (reads a repo-root fixture
  outside the sandbox) from mutation runs
- .github/workflows/mutation.yml: nightly + workflow_dispatch (never on PRs);
  posts the score to the run summary, uploads the HTML report
- README: how to run locally + the opt-in threshold (qualityGate.mutationScore
  in pipeline.config.json, enabled:false, threshold 80)
- Verified locally: a complete scoped run finishes and produces a mutation score

Refs #80

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@PAMulligan PAMulligan linked an issue Jun 20, 2026 that may be closed by this pull request
4 tasks
@PAMulligan PAMulligan self-assigned this Jun 20, 2026
@PAMulligan PAMulligan added the enhancement New feature or request label Jun 20, 2026
@PAMulligan PAMulligan moved this from Todo to Done in PMDS Open Source Roadmap Jun 20, 2026
@PAMulligan PAMulligan added this to the v2.0.0 milestone Jun 20, 2026
@PAMulligan PAMulligan merged commit a44e449 into main Jun 20, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

Development

Successfully merging this pull request may close these issues.

Wire mutation testing into CI

1 participant