Commit bb4c0aeb12
bb4c0aeb12da38e850e1c92c1df63169a9f56a5a
parent: ec5fe62412
Verified · cmc
cmc <hello@cleberg.net> · 2026-09-28 08:06 UTC
wiki: failed step, build log --step and --tail
Closes #266
Layout: unified · split
.gitbay/wiki/Architecture/07-CI-and-Supply-Chain.org
+2 −1
| @@ -39,7 +39,8 @@ commit instead of failing silently. |
| 39 | 39 | (=cmd/gitbay-runner/isolate.go=). |
| 40 | 40 | 4. *Log.* =runner log <id>= streams stdin into the build row; the server |
| 41 | 41 | ends the stream if the build is cancelled (=build.go=). |
| 42 | | 5. *Result.* =runner done <id> success|failure= sets the status, |
| 42 | 5. *Result.* =runner done <id> success|failure [--step <n>] [--reason |
| 43 | <text>]= records where a failed build stopped, sets the status, |
| 43 | 44 | records an event and mails the repository's watchers a log tail on |
| 44 | 45 | failure (=build.go=). |
| 45 | 46 | 6. *Reap.* The scheduler fails a running build whose log stream closed |
.gitbay/wiki/CI.org
+11
| @@ -64,6 +64,17 @@ seconds: a follower who loses it is told the repository is not found. |
| 64 | 64 | A restart ends every open follow with a message saying so, rather |
| 65 | 65 | than holding the drain; follow again once the daemon is back. |
| 66 | 66 | |
| 67 | A failed build names the step it stopped at: the log's last line reads |
| 68 | =step 3/3 failed: exit 1=, and =build show= prints =failed step= (=3/3 |
| 69 | go test ./... (exit 1)=) and =duration=. =build log <owner/name> <n> |
| 70 | --step failed= prints only that step's output, =--step 2= another one |
| 71 | (=0= is the clone before the first step), and =--tail 40= the last forty |
| 72 | lines of whichever was chosen; neither combines with =--follow=. The |
| 73 | build page folds the finished log into one section per step, opens the |
| 74 | failed one and links to it from the top as "Jump to failure". Builds |
| 75 | from before this reported no step; their last section is taken as the |
| 76 | failed one. |
| 77 | |
| 67 | 78 | * What a build can reach |
| 68 | 79 | |
| 69 | 80 | Builds have outbound internet access, trusted and untrusted alike. On |
.gitbay/wiki/Parity.org
+3
| @@ -217,6 +217,9 @@ rather than the one the web page shows. |
| 217 | 217 | | build show (one build) | yes | yes | yes | |
| 218 | 218 | | build log | yes | yes | yes | |
| 219 | 219 | | build log follow (until it ends) | yes | yes | no | |
| 220 | | build failed step, duration | yes | yes | no | |
| 221 | | build log one step | yes | yes | no | |
| 222 | | build log tail | yes | no | no | |
| 220 | 223 | | build jobs | yes | yes | yes | |
| 221 | 224 | | build trigger | yes | yes | yes | |
| 222 | 225 | | build cancel | yes | yes | yes | |
.gitbay/wiki/Users.org
+3 −1
| @@ -558,7 +558,9 @@ require-contexts= names statuses the gate waits for until they report, |
| 558 | 558 | and turns the gate on. =build list= takes =--ref=, |
| 559 | 559 | =--status= and =--job= to narrow the listing, combinable; the builds |
| 560 | 560 | tab reads the same flags from its =?ref=, =?status= and =?job= query |
| 561 | | parameters and groups the result into one row per commit. Steps run |
| 561 | parameters and groups the result into one row per commit. =build show= |
| 562 | names a failed build's step and how long it ran, and =build log= takes |
| 563 | =--step <n>|failed= and =--tail <lines>=. Steps run |
| 562 | 564 | with =sh -c= on the instance's runner, stopping at the first failure; |
| 563 | 565 | a broken config surfaces as a failed =ci/config= status. Environment: |
| 564 | 566 | =GITBAY_REPO=, |
e2e/ci_test.go
+10
| @@ -147,6 +147,16 @@ func TestCI(t *testing.T) { |
| 147 | 147 | if !strings.Contains(out, "step 1/1 failed: exit 1") { |
| 148 | 148 | t.Fatalf("broken log:\n%s", out) |
| 149 | 149 | } |
| 150 | out, _, _ = inst.ssh(t, aliceKey, "", "build", "show", "alice/app", brokenN) |
| 151 | if !strings.Contains(out, "1/1 false (exit 1)") { |
| 152 | t.Fatalf("build show does not name the failed step:\n%s", out) |
| 153 | } |
| 154 | if out, _, _ = inst.ssh(t, aliceKey, "", "build", "log", "alice/app", brokenN, "--step", "failed"); strings.Contains(out, "git clone") || !strings.Contains(out, "exit 1") { |
| 155 | t.Fatalf("build log --step failed:\n%s", out) |
| 156 | } |
| 157 | if _, body := inst.get(t, "/alice/app/builds/"+brokenN); !strings.Contains(body, `id="failed" open`) { |
| 158 | t.Fatalf("build page does not open the failed step:\n%s", body) |
| 159 | } |
| 150 | 160 | // Statuses resolved, with target URLs pointing at the build pages. |
| 151 | 161 | out, _, _ = inst.ssh(t, aliceKey, "", "status", "list", "alice/app", sha, "--json") |
| 152 | 162 | if !strings.Contains(out, `"ci/ok","state":"success"`) && !strings.Contains(out, `"state":"success"`) { |