Skip to content

v1.2.0

Choose a tag to compare

@xanojustin xanojustin released this 19 Aug 22:42
· 34 commits to main since this release
0399582

What's New

Honest exit codes and valid JSON from every test runner

run and run_all no longer behave differently depending on --output. Two bugs made -o json unusable in CI, and both existed in all twelve run/run_all commands across unit_test, workflow_test, tenant, and sandbox — not just the two the tickets named. (#49, #50)

  • run -o json exited 0 on a failing test. The this.exit(1) sat inside the summary-only branch, so any CI job that added -o json to get machine-readable output silently lost failure detection and the pipeline went green over red tests. (DEV-7545)
  • run_all -o json printed a bare string on an empty branch. The empty-list early return logged No workflow tests found before ever consulting --output, so JSON.parse() threw a SyntaxError. A branch with no tests is a normal state — fresh branches routinely have none. (DEV-7546)

Two further defects surfaced during the fix and are also resolved:

  • Summary mode exited 2, not 1. this.exit(1) throws an oclif ExitError that the surrounding catch swallowed and re-raised through this.error(), producing exit 2 plus a spurious Failed to run workflow test: EEXIT: 1 line. The same swallow double-wrapped genuine API error messages.
  • workflow_test run_all counted a timing-less result twice. .toFixed() ran on a timing that was typed required but can be absent, throwing after the result had already been pushed — so the inner catch pushed a second result for the same test, reporting 1 passed, 1 failed (NaNs total) and exit 1 for a suite where nothing failed.

process.exitCode replaces this.exit(1) throughout. It does not throw, so the catch cannot swallow it, it applies in both output modes, and it is the mechanism run_all already used — so run and run_all now agree by construction rather than by coincidence.

Exit-code contract (now documented in the README)

Code Meaning
0 All tests passed, or there were no tests to run
1 At least one test failed
2 The command could not run the tests at all — bad workspace, auth failure, unreadable profile, or the test-list request failed

Identical for -o json and summary, on all four surfaces.

One asymmetry is documented rather than hidden: inside run_all, a non-2xx for an individual test is recorded as a failed test (API error <status>) and contributes to exit 1, because run_all's job is to finish the batch and report a roll-up. The same 500 in run is a CLI error and exits 2. A README claiming clean 1-vs-2 separation would send CI authors to file bugs against healthy tests during an outage. Consumers needing to tell the two apart inspect results[].message.

⚠️ Behavior change

A failing run in summary mode now exits 1 instead of 2. The prior value was accidental, not designed — it was the swallowed ExitError described above. Non-zero checks (the common case) are unaffected; anything matching specifically on 2 needs updating.

Output shapes are otherwise unchanged. total_timing remains emitted by workflow_test run_all only.

Testing

test/commands/test-runner-exit-parity.test.ts adds 79 cases across all twelve commands, verified to fail against the pre-fix tree — 35 go red when src/ is reverted, so they catch the defects rather than merely describing them. Three layers: behavioral (stubbing globalThis.fetch and asserting the real process.exitCode), static flag-shape, and a source scan asserting all 18 catch blocks re-throw oclif errors and no command calls this.exit().

Published to npm as @xano/cli@1.2.0.

Full Changelog: v1.1.0...v1.2.0