New failure
Nothing in the history explains it, or it failed with an error never seen on main, even if the test is known to be flaky.
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
Free, for GitHub, GitLab, Forgejo, Gitea and any CI with Node.js. 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, or it failed with an error never seen on main, even if the test is known to be flaky.
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. For a flaky test, it takes more failures in a row than bad luck explains. The comment names the commit and the pull request the failures started with.
What to do: nothing in your pull request. Tell whoever broke it, and 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. Tests that ran on main but no longer run in your pull request are listed too.
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, and an annotation next to the code of each failed test. 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.suites: one comment, and a history for each.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
The same history and the same verdicts in GitLab CI/CD, from a job of its own that reads the reports of your tests, whatever their language.
NOTMYFAULT_TOKEN lets it store the history and comment.On Forgejo and Gitea, whose workflows follow GitHub Actions, the action itself runs as it is. Jenkins, CircleCI, Buildkite and the others run the same bundle with npx notmyfault, with the report in the log and a summary file.
Set it up on GitLab · See merge requests · Forgejo and Gitea · Any CI
include:
- remote: https://raw.githubusercontent.com/tashikomaaa/notmyfault/v1/templates/notmyfault.gitlab-ci.yml
test:
script: npm test # writes JUnit XML to reports/
artifacts:
when: always
paths: [reports/]
notmyfault:
extends: .notmyfault
needs: [test]
variables:
NOTMYFAULT_JUNIT: reports/*.xml
NOTMYFAULT_KEY: test
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
Or keep your tests failing the job as usual, and have branch protection require the notmyfault check instead, which only fails on failures that look real.
Quarantine keeps them from blocking. The rest makes sure someone deals with them, from the same history.
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 GitHub workflow or GitLab pipeline, 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.