New failure
Nothing in the history explains it.
What to do: assume your change caused it and reproduce it locally.
A test just failed on your pull request. notmyfault remembers how every test behaves on your main branch, and tells you which failures are new, which tests are known to be flaky and which were broken before you touched anything.
Add it to your workflow See a real pull request
A free GitHub Action. MIT licensed, nothing to host.
3 tests failed, 1 looks related to this change
Quarantine: 1 failure not tolerated, so this check fails.
Each failed test is checked against its recent runs on main, retries within the run and re-runs of the same commit. The first rule that matches decides, and the comment says why in one sentence.
Nothing in the history explains it.
What to do: assume your change caused it and reproduce it locally.
It failed once or twice on main, between two successful runs. Flaky, or a breakage fixed right after: too early to tell.
What to do: read the message. If it looks unrelated, re-run the job. A pass on the same commit proves it flaky.
The latest runs on main failed too, so the problem predates your pull request.
What to do: nothing in your pull request. Update your branch once main is fixed.
Known flaky when a retry or a re-run proved it, probably flaky when it keeps failing in isolation.
What to do: re-run if it blocks you, then fix the test, or let quarantine mode tolerate it.
And when a test failing on main passes in your pull request, the comment says so, even if nothing else failed.
After every run on your default branch, notmyfault records the outcome of each test on a notmyfault-history branch of your repository. A single commit, rewritten each time, so it never grows.
When a test fails on a pull request, notmyfault looks at its last 50 runs on main, at retries within the run and at re-runs of the same commit.
One comment per pull request, updated on every push. The job summary also ranks your least reliable tests.
Your tests need to write JUnit XML, and almost every runner can: Vitest, Jest, pytest, Go, Maven, Gradle, cargo-nextest, Playwright, PHPUnit, RSpec, .NET.
if: ${{ !cancelled() }} runs notmyfault when the tests fail, which is exactly when you need it.on:
push:
branches: [main]
pull_request:
permissions:
contents: write # store the history
pull-requests: write # comment on pull requests
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- run: npm ci
- run: npm test # writes JUnit XML to reports/
- uses: tashikomaaa/notmyfault@v1
if: ${{ !cancelled() }}
with:
junit: reports/**/*.xml
In quarantine mode, notmyfault decides whether the check fails. Known flaky tests stop blocking, failures that look real still do, and when in doubt, it blocks.
- run: npm test
continue-on-error: true
- uses: tashikomaaa/notmyfault@v1
with:
junit: reports/**/*.xml
mode: quarantine
The demo repository is a small shop with a flaky payment test and a search test broken on main. Each of its open pull requests gets a different comment.
#1 Support fixed-amount discount codes
A new failure caused by the change, next to a test already failing on main and a known flaky test. Quarantine blocks the merge.
#2 Charge the reduced VAT rate on coffee beans, again
A suspect failure: the test failed once on main, when the same change landed and was reverted.
#3 Explain how to run the tests
Two failures, neither of them related to a README change. Quarantine lets the check pass.
#4 Find products regardless of accents again
A fix for the test broken on main, which the comment lists as fixed. The flaky test failed, passed on a re-run, and the comment turned green.
notmyfault runs inside your workflow and keeps everything in your repository.
checkout › applies percentage discount codesNew failure. Passed the last 20 runs onmain.search › finds products regardless of accentsAlready failing onmain. Failed the last 8 runs there.payments › confirms card payments with the sandbox bankKnown flaky. Passed when the same commit was re-run.