Skip to content

CI Integration

GitHub Actions

irradiate provides a composite action for drop-in CI integration. It auto-detects GitHub Actions and emits inline ::warning annotations on survived mutants, plus a Markdown step summary.

Quick start (3 lines)

- uses: actions/checkout@v4
  with:
    fetch-depth: 0
- uses: nwyin/irradiate@v0
  with:
    diff: origin/main
    fail-under: "80"

This will:

  • Install irradiate and your project's test dependencies
  • Only test functions changed in the PR (diff: origin/main)
  • Fail the check if mutation score drops below 80%
  • Add inline annotations on survived mutants
  • Write a summary table to the step summary

Full workflow example

name: Mutation Testing

on:
  pull_request:
    branches: [main]

jobs:
  mutation-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - uses: nwyin/irradiate@v0
        id: mutants
        with:
          diff: origin/main
          fail-under: "80"
          report: json

      - name: Print score
        run: echo "Mutation score: ${{ steps.mutants.outputs.score }}% (${{ steps.mutants.outputs.killed }}/${{ steps.mutants.outputs.total }})"

Action inputs

Input Description Default
version irradiate version to install latest
paths-to-mutate Source paths (space-separated) from pyproject.toml
tests-dir Test directory from pyproject.toml
diff Git ref for incremental mode (e.g. origin/main) disabled
fail-under Minimum mutation score (0-100) no threshold
sample Random sample fraction (0.1) or count (100) all mutants
report Report format (json or html) none
report-output Report output path auto
workers Number of parallel workers CPU count
python-version Python version 3.12
extra-args Additional irradiate run arguments none

Action outputs

Output Description Example
score Mutation score percentage 85.7
killed Killed mutant count 120
survived Survived mutant count 21
total Total tested mutants 141

Caching results

Cache irradiate's content-addressable result store between runs:

      - name: Cache irradiate results
        uses: actions/cache@v4
        with:
          path: .irradiate/cache/
          key: irradiate-${{ runner.os }}-${{ hashFiles('src/**/*.py') }}
          restore-keys: irradiate-${{ runner.os }}-

Full run (scheduled)

For nightly or release-branch checks, run against all code:

      - uses: nwyin/irradiate@v0
        with:
          fail-under: "70"
          report: html

      - uses: actions/upload-artifact@v4
        with:
          name: mutation-report
          path: irradiate-report.html

Manual setup (without the action)

If you prefer not to use the composite action:

      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - run: pip install pytest irradiate

      - run: irradiate run --diff origin/main --fail-under 80 --report json

Exit codes

Code Meaning
0 Run completed, score above --fail-under (or no threshold set)
1 Score below --fail-under threshold

What to gate on

Start with --diff main --fail-under 80 on PRs. This only tests changed code and adds minimal friction. You can also run --report json without a threshold to upload as an artifact for manual review. For release branches, consider --fail-under 70 on the whole codebase. Tighten over time.

Other CI systems

irradiate is a standalone binary. Any CI that can run pip install irradiate and irradiate run works. The GitHub Actions annotations are specific to GitHub, but --report json and --fail-under work everywhere.