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/vole.git

Write over SSH with a registered key:

git clone ssh://git@rodent.software:2222/vole.git

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

refactor

c5902451905acdaa478f8476844ccd4a510d9ca9 · Keenan Nemetz · 17d ago · parent ec2aba4b

internal/hook/checks.go → server/hook/checks.go +17−16

@@ -4,10 +4,11 @@ import (
4 4 "fmt"
5 5 "strings"
6 6
7 "github.com/rodent-software/vole/internal/acl"
8 "github.com/rodent-software/vole/internal/gitx"
9 "github.com/rodent-software/vole/internal/runs"
10 "github.com/rodent-software/vole/internal/workflow"
7 "github.com/rodent-software/vole/ci"
8 "github.com/rodent-software/vole/ci/runs"
9 "github.com/rodent-software/vole/core/git"
10 "github.com/rodent-software/vole/forge/access"
11 "github.com/rodent-software/vole/internal/format"
11 12 )
12 13
13 14 // checkGaps reports which required CI jobs have not passed for a commit.
@@ -19,12 +20,12 @@ import (
19 20 // counts when the host has allowed the account that reported it: a required check is
20 21 // a claim about a commit, and without that rule any writer could satisfy it by
21 22 // running CI on their own machine and saying it passed.
22 func checkGaps(g *gitx.Repo, runsDB, repo, sha, branch string, a *acl.ACL, names func(string) string) ([]string, error) {
23 wfs, problems := workflow.At(g, sha)
23 func checkGaps(g *git.Repo, runsDB, repo, sha, branch string, a *access.ACL, names func(string) string) ([]string, error) {
24 wfs, problems := ci.At(g, sha)
24 25 if len(problems) > 0 {
25 return nil, fmt.Errorf("cannot read the workflows at %s: %s", short(sha), strings.Join(problems, "; "))
26 return nil, fmt.Errorf("cannot read the workflows at %s: %s", format.SHA(sha), strings.Join(problems, "; "))
26 27 }
27 var required []*workflow.Workflow
28 var required []*ci.Workflow
28 29 for _, wf := range wfs {
29 30 if wf.Applies(branch) {
30 31 required = append(required, wf)
@@ -56,16 +57,16 @@ func checkGaps(g *gitx.Repo, runsDB, repo, sha, branch string, a *acl.ACL, names
56 57 gaps = append(gaps, fmt.Sprintf(
57 58 "%s: job %q has no run for %s — push the branch and let CI run on it "+
58 59 "(this job filters on [%s]; a commit tested only on other branches has no result here)",
59 wf.Path, job.ID, short(sha), strings.Join(wf.Branches, " ")))
60 wf.Path, job.ID, format.SHA(sha), strings.Join(wf.Branches, " ")))
60 61 case run.Status == runs.StatusFailed:
61 62 gaps = append(gaps, fmt.Sprintf(
62 "%s: job %q failed for %s (exit %d)", wf.Path, job.ID, short(sha), run.ExitCode))
63 "%s: job %q failed for %s (exit %d)", wf.Path, job.ID, format.SHA(sha), run.ExitCode))
63 64 case run.Status == runs.StatusCanceled:
64 65 gaps = append(gaps, fmt.Sprintf(
65 "%s: job %q was canceled for %s", wf.Path, job.ID, short(sha)))
66 "%s: job %q was canceled for %s", wf.Path, job.ID, format.SHA(sha)))
66 67 case run.Status != runs.StatusSuccess:
67 68 gaps = append(gaps, fmt.Sprintf(
68 "%s: job %q is %s for %s; wait for it to finish", wf.Path, job.ID, run.Status, short(sha)))
69 "%s: job %q is %s for %s; wait for it to finish", wf.Path, job.ID, run.Status, format.SHA(sha)))
69 70 }
70 71 if run == nil || run.Status != runs.StatusSuccess {
71 72 continue
@@ -74,20 +75,20 @@ func checkGaps(g *gitx.Repo, runsDB, repo, sha, branch string, a *acl.ACL, names
74 75 // is a green light from a party with nothing at stake in this branch.
75 76 att, err := store.Attestation(run.ID)
76 77 if err != nil {
77 return nil, fmt.Errorf("cannot read who reported the run for %s: %w", short(sha), err)
78 return nil, fmt.Errorf("cannot read who reported the run for %s: %w", format.SHA(sha), err)
78 79 }
79 80 switch {
80 81 case att == nil:
81 82 gaps = append(gaps, fmt.Sprintf(
82 83 "%s: job %q passed for %s but the result is unsigned, so it cannot count as a check; "+
83 "re-run it with a current `vole runner`", wf.Path, job.ID, short(sha)))
84 "re-run it with a current `vole runner`", wf.Path, job.ID, format.SHA(sha)))
84 85 case a != nil && !a.CanReport(att.Signer):
85 86 gaps = append(gaps, fmt.Sprintf(
86 87 "%s: job %q passed for %s, but %s reported it and is not a runner for this "+
87 88 "repository (runners: %s) — so the result is recorded and does not count. "+
88 89 "An admin can allow that account with `vole acl runners %s --add %s`, "+
89 90 "or a permitted runner can run the job",
90 wf.Path, job.ID, short(sha), names(att.Signer),
91 wf.Path, job.ID, format.SHA(sha), names(att.Signer),
91 92 runnerSummary(a, names), repo, att.Signer))
92 93 }
93 94 }
@@ -97,7 +98,7 @@ func checkGaps(g *gitx.Repo, runsDB, repo, sha, branch string, a *acl.ACL, names
97 98
98 99 // runnerSummary renders the allowlist for a message. Admins are named as implicit
99 100 // because an operator reading the refusal needs to know who already counts.
100 func runnerSummary(a *acl.ACL, names func(string) string) string {
101 func runnerSummary(a *access.ACL, names func(string) string) string {
101 102 if len(a.Runners) == 0 {
102 103 return "none named, so only admins"
103 104 }