Documentation
¶
Overview ¶
Package webhook is the GitHub leg of CI results in Redis (nova-tools #3597): the check_run and workflow_run deliveries the signed receiver (`nova-post hook`, deprecated/internal/post/hook, #2657) appends to ev:github become ci:<repo>:<sha>:gh, and every reader of a GitHub check state reads that hash. Nothing here, and nothing that reads the hash, calls the check-runs or workflow-runs REST endpoints or asks GitHub to rerun anything: a rerun is our own CI's `ci request --again`, a bench-side run recorded in Redis.
One writer: the consumer group ci-github on ev:github, through the nova_sprint function ns_ci_github (internal/nsprint/fn/lua/ci_github.lua), which writes the field, refolds the summary word and XACKs the entry in one atomic call, so the ack never runs ahead of the write. Entries of any other kind are acked as no-ops in the same pipeline. The group is fleet-wide (one per stream, not per sprint): a sha's result is the same whichever sprint reads it, so several consumers share the group and never write twice.
Index ¶
Constants ¶
const ( SourceRunner = "runner" SourceHook = "hook" SourceNone = "none" )
SourceRunner, SourceHook and SourceNone are Source's three answers.
const ( Green = "green" Red = "red" Pending = "pending" )
Words on the hash, the same three our own CI uses.
const DefaultMinIdle = 30 * time.Second
DefaultMinIdle is how long an entry another consumer read stays pending before this one reclaims it.
const Function = "ns_ci_github"
Function is the nova_sprint function that writes one entry and acks it.
const Group = "ci-github"
Group is the consumer group on ev:github that writes the GitHub leg.
const Sender = "runner"
Sender is the ev:github sender of a row the runner appended.
const Suffix = "gh"
Suffix is the record suffix of the GitHub leg: ci:<repo>:<sha>:gh.
Variables ¶
This section is empty.
Functions ¶
func ShortRepo ¶
ShortRepo is the repository name without its owner: ev:github carries owner/name, our own CI keys by name (ci:nova-tools:<sha>).
Types ¶
type Consumer ¶
type Consumer struct {
Client *redis.Client
Name string // the consumer name (the seat)
Count int64 // entries per read; 0 means 100
Block time.Duration // the first new-entry read's block; 0 means 1 s, negative never blocks
// MinIdle is how long another consumer's pending entry waits before this
// one reclaims it; 0 means DefaultMinIdle.
MinIdle time.Duration
// Now stamps the PR record writes; nil is time.Now.
Now func() time.Time
}
Consumer is one member of the ci-github group.
type Counts ¶
type Counts struct {
Applied, Kept, Skipped, Reclaimed int
Records, Failed int
LastFail string // the last failed entry: its id and why
}
Counts is one pass: entries written (APPLIED), older than what the hash holds (KEPT), not a CI result (SKIPPED), and taken over from an idle consumer (RECLAIMED, also counted in the other three). Records is the pull_request entries whose claim moved or created the PR record (land.RecordPRHead); Failed the entries left pending because that write failed.
type Receipt ¶
type Receipt struct {
Repo string // owner/name
SHA string // the head the run tested: the PR head, the group head or the pushed commit
RunID string // decimal
Event string // pull_request, merge_group, push or workflow_dispatch
HeadBranch string // github.head_ref (a ref prefix is stripped)
BaseBranch string // github.base_ref
PR string // the pull request number, "" when the event names none
Workflow string // github.workflow
Conclusion string // job.status of ci-ok: success, failure or cancelled
At string // RFC3339; "" means Now()
Jobs []Job
// Now is the clock an empty At is stamped from; nil means time.Now.
Now func() time.Time
}
Receipt is one run's result as the runner reports it.
type Record ¶
type Record struct {
Found bool
Word string // gh: green, red or pending
Fail string // gh_fail: the first red run as kind:name
At string // gh_at
PR string
EvID string // ev_id: the ev:github entry last applied
// Source is who stamped the record: SourceRunner from the ci-ok job's own
// receipt (runner.go); "" when only the consumer wrote it. Source() folds
// it with EvID into runner, hook or none.
Source string
Runs []Run // in field order (kind, then name)
}
Record is ci:<repo>:<sha>:gh as a reader sees it.
type Written ¶
type Written struct {
Key string // ci:<repo>:<sha>:gh
EntryID string // the ev:github row
Word string // gh after the write
Fail string // gh_fail after the write
Runs int // fields written: the workflow and its jobs
Applied int // of them, how many the function applied (the rest were older than the hash held)
// PR is the claim on the PR record (Key "" when the run is not a
// pull_request run or was cancelled); Folded the PR numbers whose record
// took the word at this head.
PR land.PRHeadResult
Folded []string
}
Written is the receipt as it landed.
func Write ¶
Write lands one receipt: the ev:github row, then in one pipeline the function call per run and the source stamp; then, unless the run was cancelled, the PR record's claim (a pull_request run) and the fold of a final word onto the records at the sha. It needs the nova_sprint function library on the store and a seat with XADD on ev:github, FCALL and HSET on ci:*, HMGET, HSET, SADD, SREM and SMEMBERS on pr:*, and HMGET on task:* (the card the head branch names, read when the record is new or names no task: land.RecordPRHead). It writes no key outside ev:github, ci:* and pr:*, and reads none outside those and task:*.