gitbay/Builds/BuildListViewModel.swift
51 lines · 1474 bytes
1import Foundation
2import Observation
3
4/// `build list <repo>`.
5@Observable
6@MainActor
7final class BuildListViewModel {
8
9 private(set) var state: LoadState<[Build]> = .loading
10 private(set) var actionError: String?
11 private(set) var working = false
12
13 private let client: GitbayClient
14 let repoPath: String
15
16 init(client: GitbayClient, repoPath: String) {
17 self.client = client
18 self.repoPath = repoPath
19 }
20
21 func load() async {
22 do {
23 let builds = try await client.readList(["build", "list", repoPath], of: Build.self)
24 state = builds.isEmpty
25 ? .empty("No builds. Builds run when a push touches a repo with a .gitbay/ job file.")
26 : .loaded(builds.sorted { $0.number > $1.number })
27 } catch {
28 state = .from(error)
29 }
30 }
31
32 /// The most recent job name, to prefill the trigger sheet.
33 var latestJob: String? {
34 state.value?.first?.job
35 }
36
37 /// `build trigger <owner/name> <job>` — queue a job now.
38 func trigger(job: String) async {
39 working = true
40 actionError = nil
41 defer { working = false }
42 do {
43 try await client.run(["build", "trigger", repoPath, job])
44 await load()
45 } catch let error as GitbayError {
46 actionError = error.userFacingMessage
47 } catch {
48 actionError = GitbayError.transport(error).userFacingMessage
49 }
50 }
51}