ModernCIPush. Green. Merged.

Keep and fetch a check's files

How a check keeps the files it makes (rig logs, recordings, reports) with its result, red or green, and how you fetch them and the check's full log.

A check's log tells you what it printed. When a check also writes files, such as a test rig's logs, a recording or a report, declare them under outputs: and ModernCI keeps them with the check's result. It keeps them whether the check comes out red or green, so a red carries its evidence.

1. Declare the files

In the branch file, list the paths (files or directories, relative to the repo root) under the check's outputs::

yaml
checks:
  conformance:
    run: cargo xtask conformance record --all
    outputs: [target/conformance-record]

After the check runs, ModernCI packs those paths into one .tgz and stores it with the result, content-addressed.

  • A path the check didn't make is listed as missing. It isn't an error.
  • The pack can be at most 256 MiB. A check whose outputs are over that is red, and its log says so.
  • The check must run on a backend that keeps its work directory between scripts (EC2 and the local backend do). Placement picks one for you, and the wait says so when none is available.
  • Only a green check's outputs are laid into a check that needs: it. A red's outputs are kept for you to read.
  • A red is posted first, and its files are kept after it. If they can't be kept, it is still the same red, and its log ends with modernci: outputs not kept: and the reason.

2. Fetch them

artifact returns the files of the latest run of a check for a branch or change, from its check result or from a measure, whichever is newer:

modernci call artifact --repo owner/name --change 1047 --check conformance --raw > conformance.tgz
tar -xzf conformance.tgz
  • Use --from <branch> instead of --change.
  • --head <sha> (a prefix) picks the run of that commit.
  • Without --raw, the answer is JSON: the paths, the sha256 and size, and the bytes in base64, one page at a time (next is the offset of the next page). Agents use this through MCP.
  • Over HTTP, GET /api/artifact?repo=…&from=…&check=…&raw=true with your tenant's token returns the .tgz.

If nothing was kept, artifact tells you why. Most often the check declares no outputs:, or it ran before the declaration was added.

3. Run one check and fetch its files now

You don't have to wait for a branch to move. measure runs one named check at a branch's head, on the same compute, without booking a result, and keeps its outputs too:

modernci call measure --repo owner/name --from dev --check conformance
modernci call measure --repo owner/name --from dev --check conformance   # again: the result
modernci call artifact --repo owner/name --from dev --check conformance --raw > conformance.tgz

4. Read a check's full log

log returns a check's log for a change or branch: its tail by default, all of it with --full:

modernci call log --repo owner/name --change 1047 --check verify-done --full
  • A measure of the check is served when it's newer than the check result.
  • To read a measurement by name, use --from measure:<branch>:<check>, for example --from measure:dev:verify-done.
  • failed_detail gives each failing row's own lines from the whole log.

A check that didn't run (state: not_run, for example because a check it needs: was red) has no log. Measure it on its own to read one.