Skip to content

feat(cli): add --max-failures to test and trigger [RED-1227] [ship] - #1561

Merged
sorccu merged 3 commits into
mainfrom
simo/red-1227-max-failures
Oct 23, 2026
Merged

sorccu merged 3 commits into
mainfrom
simo/red-1227-max-failures

Conversation

@sorccu

@sorccu sorccu commented Oct 23, 2026 •

Copy link
Copy Markdown
Member

Linear: RED-1227

Summary

checkly test and checkly trigger get --max-failures=<n>, and the Checkly config gets cli.maxFailures, where the flag wins. Once n checks have failed, the CLI stops waiting for the rest. It writes its reports, asks Checkly to cancel the test session, and exits 1. In CI, a broken change then fails early instead of after the whole suite.

  • What counts: only a check's final outcome: a failed result, a run error, or a result timeout. Retried attempts don't count, so a check that passes on retry never stops the run. Degraded and cancelled results don't count either.
  • When the n-th failure is the last check: the run finishes normally, with no stop message and no cancel.
  • Exclusions: the flag can't be combined with --detach, which never waits for results. On checkly test it also can't be combined with --update-snapshots, because checks the run stopped waiting for would keep their old snapshots. A configured limit is ignored in those cases, with a notice for --update-snapshots.
  • Server-side cancel is best-effort: the backend only cancels running Playwright and agentic results today, so other checks may still run to completion in Checkly. Tracked in RED-1236.
  • checkly pw-test is unchanged: Playwright's own --max-failures already covers fail-fast inside a suite.

Review guide (one commit per step)

  1. Runner: AbstractCheckRunner counts final failures. The stop is decided synchronously in the CHECK_FINISHED listener, which every terminal path emits right after the outcome event. Once the run has stopped, no later or in-flight result is reported, including a final result that was still fetching its logs.
  2. Reporters: checks without a result become NOT_FINISHED in every summary, and the ci header says the run stopped. The json and github reporters used to throw on a check without a result; they now emit a "Not finished" row. JSON output gains a "result": "Not finished" value and a top-level stoppedEarly: { reason: 'maxFailures', maxFailures } field, present only when the run stopped early.
  3. Commands: flag and config resolution (prepareMaxFailures), reporter wiring, and an awaited best-effort cancel through the new cancelTestSessionBestEffort, which the Ctrl+C handler now reuses too. Config codegen keeps maxFailures when it regenerates the config.

Testing

  • Unit tests: runner cases (limit, retries, degraded, cancelled, timeouts and errors, last check, in-flight and queued results after the stop, limits of 0 or less), reporter output, flag validation, trigger wiring, and the cancel helper.
  • E2E: a fixture with an immediately failing browser check and a browser check that passes after 90s. With --max-failures=1, the run must exit 1 well before 90s, and the JSON report must show stoppedEarly and a "Not finished" row.

Docs: checkly/docs#590 (merge after this PR is released).

🤖 Generated with Claude Code

sorccu and others added 3 commits October 23, 2026 21:42
…[RED-1227]

AbstractCheckRunner takes an optional maxFailures limit. Once that many
checks have a failed final outcome (failed result, run error or timeout;
retried attempts, degraded and cancelled results do not count) while
other checks are still unfinished, the run stops right away: later
results are dropped, timeouts are cleared, and MAX_FAILURES_REACHED is
emitted before RUN_FINISHED. When the failure that reaches the limit is
the last check, the run finishes normally.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reporters get onMaxFailuresReached. Checks without a result are then
shown as "not finished" in the list, dot and ci summaries, which also
say the run stopped after reaching the max failures limit. The json and
github reports no longer assume every check has a result: they emit a
"Not finished" row, and the json report adds a top-level stoppedEarly
field when the run stopped early.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`checkly test` and `checkly trigger` take --max-failures=<n>, and the
Checkly config takes cli.maxFailures (the flag wins). Once n checks have
failed, the CLI stops waiting for the rest, writes its reports, asks
Checkly to cancel the test session and exits with an error. Checks that
pass after a retry do not count.

The limit cannot be combined with --detach, which never waits for
results, or with --update-snapshots on `checkly test`, where checks the
run stopped waiting for would keep their old snapshots. A configured
limit is ignored in those cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sorccu sorccu changed the title feat(cli): add --max-failures to test and trigger [RED-1227] feat(cli): add --max-failures to test and trigger [RED-1227] [ship] Oct 23, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Auto-approved: ship/show PR from a same-repo branch.

@sorccu
sorccu merged commit 25ab41e into main Oct 23, 2026
17 checks passed
@sorccu
sorccu deleted the simo/red-1227-max-failures branch October 23, 2026 12:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant