import Foundation /// Aggregate CI status across a PR's workflow runs. enum CIStatus: Equatable { case running case success case failure case cancelled case unknown /// Runs are ordered newest-first. Any still running → running wins. /// Otherwise: any failure → failure, else success. static func from(runs: [ActionRun]) -> CIStatus { guard !runs.isEmpty else { return .unknown } var sawSuccess = false for run in runs { let conclusion = (run.conclusion ?? "").lowercased() if run.status?.lowercased() == "running" || run.status?.lowercased() == "queued" || run.status?.lowercased() == "waiting" { return .running } switch conclusion { case "success": sawSuccess = true case "failure", "cancelled": return conclusion == "cancelled" ? .cancelled : .failure default: continue } } return sawSuccess ? .success : .unknown } } /// Aggregate review state across review submissions. enum ReviewState: Equatable { case approved case changesRequested case needsReview case unknown static func from(reviews: [PullReview]) -> ReviewState { var hasReview = false for r in reviews { switch r.state.uppercased() { case "APPROVED": return .approved case "REQUEST_CHANGES": return .changesRequested default: hasReview = true } } return hasReview ? .needsReview : .unknown } }