Commit 8c9ab4e1a9

8c9ab4e1a98906adef1f8a0e945c3278b02aef20

parent: 045cba839a

Verified · cmc

cmc <hello@cleberg.net> · 2026-09-22 20:55 UTC

builds: lead each row with the commit subject

build list returns subject since gitbay v1.33.0 (krz/gitbay#241). The
job, ref and sha move to the meta line.

Layout: unified · split

gitbay/Builds/BuildModels.swift +10 −1
@@ -10,15 +10,24 @@ nonisolated struct Build: Decodable, Sendable, Hashable, Identifiable {
1010 let ref: String
1111 let createdAt: Date
1212 let finishedAt: Date?
13 /// The built commit's subject, which `build list` resolves since
14 /// gitbay v1.33.0. Absent when the commit is gone.
15 let subject: String?
1316
1417 enum CodingKeys: String, CodingKey {
15 case number, job, status, sha, ref
18 case number, job, status, sha, ref, subject
1619 case createdAt = "created_at"
1720 case finishedAt = "finished_at"
1821 }
1922
2023 var id: Int64 { number }
2124 var shortSHA: String { String(sha.prefix(10)) }
25 /// What a row leads with. Recognising a build by its sha meant
26 /// opening the commit or already knowing it (krz/gitbay#241).
27 var title: String {
28 if let subject, !subject.isEmpty { return "#\(number) \(subject)" }
29 return "#\(number) \(shortSHA)"
30 }
2231}
2332
2433/// `build jobs` — what a trigger can name. A repo with no CI config has
gitbay/Views/Builds/BuildListView.swift +3 −1
@@ -74,9 +74,11 @@ private struct BuildRow: View {
7474 Image(systemName: build.statusIcon)
7575 .foregroundStyle(build.statusColor)
7676 VStack(alignment: .leading, spacing: 2) {
77 Text("#\(build.number) \(build.job)")
77 Text(build.title)
7878 .font(.gbSans(.subheadline).weight(.medium))
79 .lineLimit(2)
7980 HStack(spacing: 6) {
81 Text(build.job)
8082 Text(build.ref)
8183 Text(build.shortSHA)
8284 .font(.gbMono(.caption))
gitbayTests/BuildListPagingTests.swift added +48
@@ -0,0 +1,48 @@
1import Foundation
2import Testing
3@testable import gitbay
4
5private func makeClient() throws -> (GitbayClient, StubProtocol.Box) {
6 let box = StubProtocol.box()
7 let client = GitbayClient(
8 instance: try GitbayInstance(url: "https://gitbay.org"),
9 token: "test-token",
10 session: box.session()
11 )
12 return (client, box)
13}
14
15private func buildRow(_ number: Int, subject: String? = nil) -> String {
16 let subjectField = subject.map { #","subject":"\#($0)""# } ?? ""
17 return """
18 {"number":\(number),"job":"test","status":"success",\
19 "sha":"db7503f06f11c31a41f1c8e91187e1ff8f861c7f","ref":"main",\
20 "created_at":"2026-09-22T04:40:16.000Z"\(subjectField)}
21 """
22}
23
24struct BuildSubjectTests {
25
26 private func decode(_ json: String) throws -> Build {
27 try GitbayClient.decoder().decode(Build.self, from: Data(json.utf8))
28 }
29
30 @Test func aRowLeadsWithTheCommitSubject() throws {
31 let build = try decode(buildRow(1479, subject: "CHANGELOG: v1.34.1"))
32 #expect(build.subject == "CHANGELOG: v1.34.1")
33 #expect(build.title == "#1479 CHANGELOG: v1.34.1")
34 }
35
36 /// A build whose commit is gone has no subject to report; the sha is
37 /// all there is.
38 @Test func aRowWithoutASubjectFallsBackToTheSha() throws {
39 let build = try decode(buildRow(12))
40 #expect(build.subject == nil)
41 #expect(build.title == "#12 db7503f06f")
42 }
43
44 @Test func anEmptySubjectAlsoFallsBack() throws {
45 let build = try decode(buildRow(12, subject: ""))
46 #expect(build.title == "#12 db7503f06f")
47 }
48}