Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

vole
Clone

Read only, no credentials:

https://rodent.software/git/vole.git

Write over SSH with a registered key:

git clone ssh://git@0.0.0.0:2222/vole.git

A free and open-source forge that lives in your Git repo.

Phase 4 slice 3: checks on the gate, and statuses on the page

35eaeccffdab9d07e13fb7b346060e535697fee7 · Keenan Nemetz · 17d ago · parent b44cbfaf

Phase 4 slice 3: checks on the gate, and statuses on the page

A protected branch now requires both an approved change request and passing checks
for the commit being landed. Approvals say a person read the change; checks say it
works. Neither substitutes for the other.

The gate asks about the *approved head*, not about the merge commit somebody may be
pushing: CI ran on the head, and a merge commit is a new object nobody built. That
also keeps the gate consistent with what approvals already name.

Details that decide whether this is usable:

- A repository with no workflows is unaffected — nothing to run means nothing to
  wait for — so existing repositories do not start failing pushes.
- A job with no run is refused with an explanation that names the branch filter,
  because `on: push: branches: [main]` never produces a result for a feature
  branch. That is the one configuration that can deadlock a merge, and the error
  says so instead of leaving somebody guessing.
- Failed, cancelled, still-running and missing are four different messages; a
  reviewer should be able to tell which.
- `vole acl checks <repo> on|off` turns it off, default on.

Statuses are readable: the repository page lists recent runs (job, commit, status,
attempts, age) and a change request shows its head's job statuses next to the
approvals, so the reviewer sees the same facts the gate uses.

Tests cover the three interesting shapes: approved + green lands; approved + red is
refused naming the failed job; approved + no run at all is refused with the
branch-filter hint.

Verified on a live instance: pushing a workflow queues and runs it, the repository
page shows `build · .vole/workflows/ci.yaml · success`, and the change request shows
`wilbur · current` alongside `build · success`.

Phase 4 is now complete except signed run records, which are Phase 7's.

internal/web/requests.go +22−1

@@ -93,6 +93,26 @@ func (w *Web) RequestView(rw http.ResponseWriter, r *http.Request) {
93 93 Current: a.Head == req.Head && a.Base == req.Base,
94 94 })
95 95 }
96 // CI state for the commit under review: the same question the gate asks.
97 type checkRow struct {
98 Workflow, Job, Status string
99 Exit int
100 }
101 var checks []checkRow
102 if w.Runs != nil && req.Head != "" {
103 if res, err := w.Runs.ForSHA(m.Name, req.Head); err == nil {
104 for _, run := range res {
105 checks = append(checks, checkRow{run.Workflow, run.Job, run.Status, run.ExitCode})
106 }
107 sort.Slice(checks, func(i, j int) bool {
108 if checks[i].Workflow != checks[j].Workflow {
109 return checks[i].Workflow < checks[j].Workflow
110 }
111 return checks[i].Job < checks[j].Job
112 })
113 }
114 }
115
96 116 // The diff is computed from git on every view: it is cheap for one branch and
97 117 // always matches what the approver is being asked to approve.
98 118 var changed []string
@@ -112,8 +132,9 @@ func (w *Web) RequestView(rw http.ResponseWriter, r *http.Request) {
112 132 Request *requests.Request
113 133 Description template.HTML
114 134 Approvals []requestApproval
135 Checks []checkRow
115 136 Changed []string
116 137 AlreadyMerged bool
117 138 }{Page: w.base(m.Name + " · " + req.Title), Name: m.Name, Request: req,
118 Description: w.renderMarkdown(m.Name, req.Description), Approvals: approvals, Changed: changed, AlreadyMerged: alreadyMerged}, 0)
139 Description: w.renderMarkdown(m.Name, req.Description), Approvals: approvals, Checks: checks, Changed: changed, AlreadyMerged: alreadyMerged}, 0)
119 140 }