Run a project’s tests¶
Goal: run a tree’s own test suite on a runner. Same pipeline as a build, no artifact, an honest verdict.
Basic usage¶
$ saggar submit ./my-project --test
$ saggar submit ./my-project --test-cmd "make check"
$ saggar submit ./my-project --test --arch arm64 --env trixie
--test runs the tree’s own test suite instead of building: same
pipeline, same target overrides (--arch, --env), same live
logs, same failure metadata. The suite’s exit code is the verdict.
--test-cmd overrides detection with an explicit command (API:
"test_cmd", which implies "mode": "test").
What gets autodetected¶
Per build system: cargo test, go test ./..., ctest and
meson test (after the build those runners need), a make -n
probe for a check or test target, npm run test / pnpm
/ bun when the manifest declares the script, deno task test,
mix test (with a test/ directory), pytest through the
project’s tool, swift test (with a Tests/ directory), gradle
and maven (with a real suite), and the rake convention through
bundler.
Honesty rules¶
A tree with no detectable suite fails the job, never a green no-op, naming what was probed; the answer is an explicit
--test-cmd.Green means success with nothing collected: a test job produces no artifact and is never registry material.
Red is a
realfailure in thetestphase. Infra noise still retries silently; a red test never does.
Structured results¶
When the suite’s runner writes report files, saggar parses them and serves what failed; no log scraping:
$ curl -H "X-Auth-Token: $SAGGAR_TOKEN" \
https://saggar.dev/api/v1/jobs/j-…/results
The results field on the job object carries per-file suite/case
counts and the failing case names with their failure messages. Each
build system declares where its own runner drops reports: surefire XML
for maven, the Test task’s XML for gradle, nextest’s conventional
target/nextest/*/junit.xml for cargo (plain cargo test writes
no report; the project’s nextest profile opts in), and meson’s
testlog.json.
Results are collected green or red (a failing suite’s report is the most valuable one), but they are a bonus layer: a malformed report is skipped with one log line, absence is normal, and the verdict stays the exit code.
Tests on every push¶
By default a watch builds the tree and also runs its tests: a triggered push produces the formats×arches group plus a test member sharing the group id. See Set up CI: watched repos, webhooks, statuses. A watch pinned to a formats list cannot also be tests-only; the group composition is how both coexist.