v0.12.0 dccd128

checks.go RawHistoryFolder

1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package web
4
5import (
6	"context"
7	"errors"
8	"fmt"
9
10	"github.com/bnema/zerowrap"
11
12	"bnema.dev/ermite/internal/domain"
13	"bnema.dev/ermite/internal/ports"
14)
15
16// ChecksSummary is the combined state of the checks of a commit.
17type ChecksSummary struct {
18	Total        int
19	Kind, State  string
20	Label, Title string
21	Href         string
22}
23
24// CheckRow is a check of a commit or a merge request.
25type CheckRow struct {
26	Name, Kind, State, Href string
27	Waiting                 bool
28}
29
30// ChecksSection is the checks of the head of a merge request.
31type ChecksSection struct {
32	Rows []CheckRow
33	// Note explains the rule that applies to them.
34	Note string
35}
36
37// checksFor reads the checks of a commit as the caller of the request. A page
38// shows them when it can: a failure of the read is logged and the page goes on
39// without, since the code and the review do not depend on CI.
40func (s *Server) checksFor(ctx context.Context, repo domain.RepoName, sha string) []ports.CheckView {
41	if s.cfg.Runs == nil || sha == "" {
42		return nil
43	}
44	res, err := s.cfg.Runs.ListChecks(ctx, principal(ctx), repo, sha)
45	if err != nil {
46		if !errors.Is(err, domain.ErrNotFound) {
47			log := zerowrap.FromCtx(ctx)
48			log.Warn().Err(err).Str("repo", repo.String()).Msg("read the checks of a commit")
49		}
50		return nil
51	}
52	return res.Checks
53}
54
55// checksSummary reduces checks to the mark a list shows next to a commit.
56func checksSummary(repo domain.RepoName, sha string, checks []ports.CheckView) ChecksSummary {
57	if len(checks) == 0 {
58		return ChecksSummary{}
59	}
60	plain := make([]domain.CICheck, 0, len(checks))
61	passed := 0
62	for _, c := range checks {
63		plain = append(plain, c.CICheck)
64		if c.Status == domain.CICompleted && c.Conclusion.PassesMerge() {
65			passed++
66		}
67	}
68	sum := ChecksSummary{Total: len(checks), Href: repoHref(repo.String(), "actions"), Label: fmt.Sprintf("%d/%d", passed, len(checks))}
69	switch domain.CombineChecks(plain) {
70	case domain.CheckStateSuccess:
71		sum.Kind, sum.State = "ok", "checks passed"
72	case domain.CheckStateFailure:
73		sum.Kind, sum.State = "bad", "checks failed"
74	default:
75		sum.Kind, sum.State = "running", "checks pending"
76	}
77	sum.Title = sum.State + ": " + sum.Label
78	return sum
79}
80
81// checksSection is the checks of the rail of a merge request, with the rule of
82// the repository that applies to them.
83func checksSection(repo domain.Repo, checks []ports.CheckView) ChecksSection {
84	sec := ChecksSection{}
85	for _, c := range checks {
86		row := CheckRow{
87			Name: visibleText(c.Name), Kind: ciKind(c.Status, c.Conclusion), State: ciState(c.Status, c.Conclusion),
88			Waiting: c.WaitingForRunner,
89		}
90		if c.JobID != "" {
91			row.Href = jobHref(repo.Name.String(), c.RunID, c.JobID)
92		} else {
93			row.Href = runHref(repo.Name.String(), c.RunID)
94		}
95		sec.Rows = append(sec.Rows, row)
96	}
97	switch {
98	case len(checks) == 0:
99		sec.Note = "no check on this commit: nothing blocks the merge."
100	case repo.Settings.FailingChecksBlock:
101		sec.Note = "a failing or unfinished check blocks the merge."
102	default:
103		sec.Note = "checks do not block the merge in this repository."
104	}
105	return sec
106}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 4

Tags 45

↑↓ moveenter openesc close