Skip to content

CI

Nostr CI results are published as events, like everything else. Two things matter: finding the workflow, and reading the result correctly.

Where workflows live

.ngit/act/workflows/

Not .github/workflows/. A repository can have both, and the presence of one says nothing about the other. To read the workflow as it existed at a given commit:

bash
git show <COMMIT>:.ngit/act/workflows/<WORKFLOW>.yaml

Check that its triggers actually cover the event you care about, and that its steps run the checks you think they do.

Checking a commit

bash
ngit ci status <COMMIT-ISH>
ngit ci status <COMMIT-ISH> --offline    # cache only, after the first query

The target can be a commit-ish, a PR (#<prefix>, an nevent, or a full event ID), or nothing at all — in which case it means HEAD. Query the commit that introduced the change, not just the tip.

A PR reports only the runs for its latest revision; results from earlier revisions are never presented as current.

status: ok does not mean CI passed

The top-level status field reports whether the query succeeded. Whether the build passed is ci.conclusion.

A green status: "ok" next to a failing ci.conclusion is a perfectly normal response, and reading the wrong one is the most common way to mistake a broken commit for a working one.

What the fields mean:

FieldMeaning
statusDid the query command succeed
ci.statePending, running, or concluded
ci.conclusionSuccess, failure, cancelled, or other outcome
ci.runs[].jobsWhich job passed or failed
ci.runs[].workflowWhich workflow produced the run
ci.runs[].integrityWhether the commit is present locally and the workflow hash matches
coverageHow completely the result covers the commit

Partial coverage is not evidence of success.

Gating on a result

To make the command exit non-zero unless CI is green and meets a trust floor:

bash
ngit ci status <COMMIT-ISH> --require-ci-trust maintainer-directed

Two floors are available:

LevelMeaning
maintainer-directedThe result traces back to a maintainer's instruction
operationally-associatedA weaker association with the repository's operators

The gate passes only if the result is a success and its weakest run meets the floor.

The same gate works on a merge, which is where it matters most:

bash
ngit merge <ID> --require-ci-trust maintainer-directed

Without it, a failing, unfinished, untrusted or entirely absent CI result will not block the merge. A successful push does not enforce CI by itself.

Asking a coordinator to run CI

CI runs are performed by a coordinator you ask. A request is standing: it covers runs the coordinator starts after it, never earlier ones, and stays in force until you stop it.

bash
ngit ci request <COORDINATOR>     # npub or hex
ngit ci stop <COORDINATOR>

Requests are signed for one repository perspective — your own announcement if you've published one, otherwise the selected maintainer's. A coordinator's default policy accepts only a confirmed maintainer of that perspective, so ngit warns (but doesn't refuse) if you aren't one; an operator may have allowed your key explicitly.

To run a single workflow once, without a standing request:

bash
ngit ci trigger <COORDINATOR> --workflow .ngit/act/workflows/test.yaml
ngit ci trigger <COORDINATOR> <COMMIT-ISH> --workflow .ngit/act/workflows/test.yaml

The workflow is identified by the SHA-256 of the blob at the resolved commit — not your working tree, whose line endings and clean/smudge filters may hash differently from what the coordinator sees.

When no run appears

Report it as "no matching CI event found" rather than as a pass. Then check, in order:

  1. Did the workflow exist at that commit?
  2. Did its trigger match the event?
  3. Did the query refresh the repository relays — or was it --offline against a cold cache?

Only after all three should you conclude that CI genuinely did not run.

Next

Contribute with ngit: nostr://danconwaydev.com/relay.ngit.dev/ngit