detached cab7cdc

ci_workflow.go RawHistoryFolder

1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package kvstore
4
5import (
6	"context"
7	"errors"
8	"fmt"
9	"sort"
10	"strings"
11	"time"
12
13	kv "bnema.dev/ermite-kv"
14	"google.golang.org/protobuf/proto"
15	"google.golang.org/protobuf/types/known/timestamppb"
16
17	storagepb "bnema.dev/ermite/gen/ermite/storage"
18	"bnema.dev/ermite/internal/domain"
19	"bnema.dev/ermite/internal/ports"
20)
21
22// The workflows a repository disabled (`ermite workflow disable`):
23//
24//	ciwfoff/<repo>/<workflow path>      CIWorkflowDisabled
25//
26// <workflow path> is ".github/workflows/<file>", whether or not the file exists.
27// Written under the guard of the repository key, deleted with the repository
28// (ciKeys).
29const workflowOffPrefix = "ciwfoff/"
30
31var _ ports.CIWorkflowStore = (*CI)(nil)
32
33func workflowOffKey(repo domain.RepoName, path string) []byte {
34	return []byte(workflowOffPrefix + repo.String() + "/" + path)
35}
36
37func workflowOffPrefixOf(repo domain.RepoName) string { return workflowOffPrefix + repo.String() + "/" }
38
39// DisableWorkflow records the path as disabled. One already disabled keeps its
40// date. A repository that does not exist is domain.ErrNotFound.
41func (c *CI) DisableWorkflow(ctx context.Context, repo domain.RepoName, path string, at time.Time) error {
42	val, err := proto.Marshal(&storagepb.CIWorkflowDisabled{DisabledAt: timestamppb.New(at)})
43	if err != nil {
44		return fmt.Errorf("encode disabled workflow: %w", err)
45	}
46	key := workflowOffKey(repo, path)
47	for range updateAttemptsTip {
48		if _, ok := c.db.Get(ctx, key); ok {
49			if _, ok := c.db.Get(ctx, repoKey(repo)); !ok {
50				return domain.ErrNotFound
51			}
52			return nil
53		}
54		var b kv.Batch
55		if err := c.guardRepo(ctx, &b, repo); err != nil {
56			return err
57		}
58		b.RequireAbsent(key)
59		b.Put(key, val)
60		_, err := c.db.Apply(ctx, &b)
61		if errors.Is(err, kv.ErrConflict) {
62			continue
63		}
64		if err != nil {
65			return fmt.Errorf("store disabled workflow: %w", err)
66		}
67		return nil
68	}
69	return fmt.Errorf("store disabled workflow: %w", domain.ErrConflict)
70}
71
72// EnableWorkflow removes the record of the path.
73func (c *CI) EnableWorkflow(ctx context.Context, repo domain.RepoName, path string) error {
74	var b kv.Batch
75	b.Delete(workflowOffKey(repo, path))
76	if _, err := c.db.Apply(ctx, &b); err != nil {
77		return fmt.Errorf("delete disabled workflow: %w", err)
78	}
79	return nil
80}
81
82// DisabledWorkflows returns the disabled paths of the repository, sorted.
83func (c *CI) DisabledWorkflows(ctx context.Context, repo domain.RepoName) ([]string, error) {
84	prefix := workflowOffPrefixOf(repo)
85	var out []string
86	for k := range c.db.Snapshot(ctx).Prefix(ctx, []byte(prefix)) {
87		out = append(out, strings.TrimPrefix(string(k), prefix))
88	}
89	sort.Strings(out)
90	return out, nil
91}

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