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 { |
| 10 | 10 | let ref: String |
| 11 | 11 | let createdAt: Date |
| 12 | 12 | 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? |
| 13 | 16 | |
| 14 | 17 | enum CodingKeys: String, CodingKey { |
| 15 | | case number, job, status, sha, ref |
| 18 | case number, job, status, sha, ref, subject |
| 16 | 19 | case createdAt = "created_at" |
| 17 | 20 | case finishedAt = "finished_at" |
| 18 | 21 | } |
| 19 | 22 | |
| 20 | 23 | var id: Int64 { number } |
| 21 | 24 | 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 | } |
| 22 | 31 | } |
| 23 | 32 | |
| 24 | 33 | /// `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 { |
| 74 | 74 | Image(systemName: build.statusIcon) |
| 75 | 75 | .foregroundStyle(build.statusColor) |
| 76 | 76 | VStack(alignment: .leading, spacing: 2) { |
| 77 | | Text("#\(build.number) \(build.job)") |
| 77 | Text(build.title) |
| 78 | 78 | .font(.gbSans(.subheadline).weight(.medium)) |
| 79 | .lineLimit(2) |
| 79 | 80 | HStack(spacing: 6) { |
| 81 | Text(build.job) |
| 80 | 82 | Text(build.ref) |
| 81 | 83 | Text(build.shortSHA) |
| 82 | 84 | .font(.gbMono(.caption)) |
gitbayTests/BuildListPagingTests.swift
added
+48
| @@ -0,0 +1,48 @@ |
| 1 | import Foundation |
| 2 | import Testing |
| 3 | @testable import gitbay |
| 4 | |
| 5 | private 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 | |
| 15 | private 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 | |
| 24 | struct 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 | } |