detached ce785bf

fix(ci): make no run and no check while no runner is registered

CI is on once a runner exists. The check is made by the worker, so a push is
never slowed down.
commit
ce785bfd247feaff84105a8cc9174e3f0be115f8
author
brice · · 2026-10-12 19:08 UTC
parent
5aba7f2
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
2 files · +23 -0
M internal/app/ci_flow_test.go +14 -0
@@ -580,3 +580,17 @@ func TestCIPushWithoutNewCommitsStillRuns(t *testing.T) {
580580 c.waitFor("the rewind runs", func() bool { return len(c.runs()) == 4 })
581581 assert.Equal(t, first, c.runs()[0].GetSha())
582582 }
583+
584+// CI is on once a runner is registered: before that a push makes no run and no
585+// check; after, it does.
586+func TestCINoRunnerNoRunsNoChecks(t *testing.T) {
587+ c := newCIHarness(t, nil)
588+ sha := c.push("main", map[string]string{".github/workflows/ci.yml": ciWorkflow}, "")
589+ time.Sleep(400 * time.Millisecond)
590+ assert.Empty(t, c.runs())
591+ assert.Empty(t, c.checks(sha))
592+
593+ c.registerRunner("alpha", "ubuntu-latest")
594+ c.push("main", map[string]string{"a.txt": "a\n"}, "")
595+ c.waitFor("a run once a runner exists", func() bool { return len(c.runs()) == 1 })
596+}
@@ -580,3 +580,17 @@ func TestCIPushWithoutNewCommitsStillRuns(t *testing.T) {
580 c.waitFor("the rewind runs", func() bool { return len(c.runs()) == 4 })580 c.waitFor("the rewind runs", func() bool { return len(c.runs()) == 4 })
581 assert.Equal(t, first, c.runs()[0].GetSha())581 assert.Equal(t, first, c.runs()[0].GetSha())
582 }582 }
583+
584+// CI is on once a runner is registered: before that a push makes no run and no
585+// check; after, it does.
586+func TestCINoRunnerNoRunsNoChecks(t *testing.T) {
587+ c := newCIHarness(t, nil)
588+ sha := c.push("main", map[string]string{".github/workflows/ci.yml": ciWorkflow}, "")
589+ time.Sleep(400 * time.Millisecond)
590+ assert.Empty(t, c.runs())
591+ assert.Empty(t, c.checks(sha))
592+
593+ c.registerRunner("alpha", "ubuntu-latest")
594+ c.push("main", map[string]string{"a.txt": "a\n"}, "")
595+ c.waitFor("a run once a runner exists", func() bool { return len(c.runs()) == 1 })
596+}
M internal/usecase/ci_trigger.go +9 -0
@@ -93,6 +93,15 @@ func (c *CI) planPush(t ciTrigger) {
9393
9494 // handlePush starts the workflows that match each ref of the push.
9595 func (c *CI) handlePush(ctx context.Context, t ciTrigger) error {
96+ // CI is on once a runner is registered (plan, "Config"): without one a push
97+ // makes no run and no check, so a forge that does not use CI shows nothing.
98+ runners, err := c.cfg.Store.ListRunners(ctx)
99+ if err != nil {
100+ return fmt.Errorf("list the runners: %w", err)
101+ }
102+ if len(runners) == 0 {
103+ return nil
104+ }
96105 tags := 0
97106 for _, u := range t.updates {
98107 if strings.HasPrefix(u.Ref, "refs/tags/") {
@@ -93,6 +93,15 @@ func (c *CI) planPush(t ciTrigger) {
93 93
94 // handlePush starts the workflows that match each ref of the push.94 // handlePush starts the workflows that match each ref of the push.
95 func (c *CI) handlePush(ctx context.Context, t ciTrigger) error {95 func (c *CI) handlePush(ctx context.Context, t ciTrigger) error {
96+ // CI is on once a runner is registered (plan, "Config"): without one a push
97+ // makes no run and no check, so a forge that does not use CI shows nothing.
98+ runners, err := c.cfg.Store.ListRunners(ctx)
99+ if err != nil {
100+ return fmt.Errorf("list the runners: %w", err)
101+ }
102+ if len(runners) == 0 {
103+ return nil
104+ }
96 tags := 0105 tags := 0
97 for _, u := range t.updates {106 for _, u := range t.updates {
98 if strings.HasPrefix(u.Ref, "refs/tags/") {107 if strings.HasPrefix(u.Ref, "refs/tags/") {

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 2

Tags 45

↑↓ moveenter openesc close