Build iOS App / Build .ipa and publish source (push) Successful in 21s
Commits tab was empty: Gitea PR commits have no 'id' field (only sha), but
PRCommit.id was a non-optional let decoded from 'id', so decoding [PRCommit]
always threw and the tab silently showed nothing. Make PRCommit.id a computed
sha-based identity so the array decodes and renders.
CI: add a Logs button per job that fetches the job's raw log text
(/actions/jobs/{id}/logs) into a viewable, shareable screen. Bump to 1.7.
67 lines
2.0 KiB
Swift
67 lines
2.0 KiB
Swift
import SwiftUI
|
|
|
|
/// Displays a Gitea Actions job's raw log text, with a share button.
|
|
struct JobLogsView: View {
|
|
let repo: Repository
|
|
let runID: Int64
|
|
let jobID: Int64
|
|
let jobName: String
|
|
|
|
@State private var text = ""
|
|
@State private var isLoading = true
|
|
@State private var errorMessage: String?
|
|
@State private var showShare = false
|
|
|
|
var body: some View {
|
|
Group {
|
|
if isLoading {
|
|
ProgressView("Loading logs…")
|
|
} else if let errorMessage {
|
|
ContentUnavailableView(
|
|
"Couldn't load logs",
|
|
systemImage: "doc.text",
|
|
description: Text(errorMessage))
|
|
} else {
|
|
ScrollView {
|
|
Text(text)
|
|
.font(.caption.monospaced())
|
|
.frame(maxWidth: .infinity, alignment: .leading)
|
|
.textSelection(.enabled)
|
|
.padding()
|
|
}
|
|
}
|
|
}
|
|
.navigationTitle(jobName)
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
.toolbar {
|
|
ToolbarItem(placement: .primaryAction) {
|
|
Button {
|
|
showShare = true
|
|
} label: {
|
|
Image(systemName: "square.and.arrow.up")
|
|
}
|
|
.disabled(text.isEmpty)
|
|
}
|
|
}
|
|
.sheet(isPresented: $showShare) {
|
|
ShareSheet(text: text)
|
|
}
|
|
.task { await load() }
|
|
}
|
|
|
|
private func load() async {
|
|
isLoading = true
|
|
errorMessage = nil
|
|
defer { isLoading = false }
|
|
guard let client = SettingsStore.shared.client() else {
|
|
errorMessage = "Not configured."
|
|
return
|
|
}
|
|
do {
|
|
text = try await client.jobLogs(owner: repo.owner.login, repo: repo.name, jobID: jobID)
|
|
} catch {
|
|
errorMessage = error.localizedDescription
|
|
}
|
|
}
|
|
}
|