Skip to content

Commit

Permalink
Add support for pull requests (#3)
Browse files Browse the repository at this point in the history
  • Loading branch information
madsodgaard committed Apr 1, 2024
1 parent 38ae3d2 commit 36621cf
Showing 1 changed file with 100 additions and 15 deletions.
115 changes: 100 additions & 15 deletions Sources/xcc.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import SwiftTUI
@Option var product: String?
@Option var workflow: String?
@Option var reference: String?
@Option var pullRequestID: Int?

mutating func run() async throws {
Termios.enterRawMode()
Expand All @@ -32,6 +33,10 @@ import SwiftTUI
guard let privateKeyID else { throw ValidationError("Missing Private Key ID. Create an API key with the \"Developer\" role at https://appstoreconnect.apple.com/access/api") }
guard var privateKey else { throw ValidationError("Missing Private Key. Create an API key with the \"Developer\" role at https://appstoreconnect.apple.com/access/api") }

guard reference == nil || pullRequestID == nil else {
throw Error.multipleSourceTypes
}

privateKey = privateKey.replacingOccurrences(of: "\n", with: "")
if privateKey.hasPrefix("-----BEGIN PRIVATE KEY-----") {
privateKey.removeFirst("-----BEGIN PRIVATE KEY-----".count)
Expand Down Expand Up @@ -93,24 +98,59 @@ import SwiftTUI
throw Error.couldNotFindWorkflow(availableWorkflows: workflows)
}

let selectedSourceType = if reference != nil {
SourceType.reference
} else if pullRequestID != nil {
SourceType.pullRequest
} else {
CommandLine.chooseFromList(SourceType.allCases, prompt: "Select a source type:")
}

ActivityIndicator.start()

let repository = try await provider.request(
APIEndpoint.v1.ciWorkflows.id(selectedWorkflow.id).repository.get()
).data

let gitReferences = try await provider.requestAll(
APIEndpoint.v1.scmRepositories.id(repository.id).gitReferences.get()
).flatMap(\.data)
ActivityIndicator.stop()
var selectedGitReference: ScmGitReference? = nil
var selectedPullRequest: ScmPullRequest? = nil

let selectedGitReference = if let reference {
gitReferences.first(where: { $0.attributes?.name == reference })
} else {
CommandLine.chooseFromList(gitReferences, prompt: "Select a reference:")
}
guard let selectedGitReference else {
throw Error.couldNotFindReference(availableReferences: gitReferences)
switch selectedSourceType {
case .pullRequest:
let pullRequests = try await provider.requestAll(
APIEndpoint.v1.scmRepositories.id(repository.id).pullRequests.get()
).flatMap(\.data)

ActivityIndicator.stop()

selectedPullRequest = if let pullRequestID {
pullRequests.first(where: { $0.attributes?.number == pullRequestID })
} else {
CommandLine.chooseFromList(pullRequests, prompt: "Select a pull request:")
}

if selectedPullRequest == nil, pullRequestID != nil {
throw Error.couldNotFindPullRequest(availablePullRequests: pullRequests)
}

case .reference:
let gitReferences = try await provider.requestAll(
APIEndpoint.v1.scmRepositories.id(repository.id).gitReferences.get()
).flatMap(\.data)

ActivityIndicator.stop()

selectedGitReference = if let reference {
gitReferences.first(where: { $0.attributes?.name == reference })
} else {
CommandLine.chooseFromList(gitReferences, prompt: "Select a reference:")
}

guard let selectedGitReference else {
throw Error.couldNotFindReference(availableReferences: gitReferences)
}
}


ActivityIndicator.start()
_ = try? await provider.request(APIEndpoint.v1.ciBuildRuns.post(.init(
Expand All @@ -121,10 +161,18 @@ import SwiftTUI
type: .ciWorkflows,
id: selectedWorkflow.id
)),
sourceBranchOrTag: .init(data: .init(
type: .scmGitReferences,
id: selectedGitReference.id
))
sourceBranchOrTag: selectedGitReference.map {
.init(data: .init(
type: .scmGitReferences,
id: $0.id
))
},
pullRequest: selectedPullRequest.map {
.init(data: .init(
type: .scmPullRequests,
id: $0.id
))
}
)
)
))).data
Expand All @@ -141,6 +189,8 @@ extension xcc {
case couldNotFindProduct(availableProducts: [CiProduct])
case couldNotFindWorkflow(availableWorkflows: [CiWorkflow])
case couldNotFindReference(availableReferences: [ScmGitReference])
case couldNotFindPullRequest(availablePullRequests: [ScmPullRequest])
case multipleSourceTypes

// MARK: Internal

Expand All @@ -160,6 +210,14 @@ extension xcc {
Could not find reference with specified name. Available references:
\(references.compactMap(\.attributes?.name).map { "- \($0)" }.joined(separator: "\n"))
"""

case let .couldNotFindPullRequest(pullRequests): """
Could not find pull request with number. Available references:
\(pullRequests.compactMap(\.attributes?.number).map { "- \($0)" }.joined(separator: "\n"))
"""

case .multipleSourceTypes:
"Please only supply one source argument, either `reference` or `pullRequestID`"
}
}
}
Expand Down Expand Up @@ -198,6 +256,19 @@ extension ScmGitReference: CustomStringConvertible {
}
}

// MARK: - ScmPullRequest + CustomStringConvertible

extension ScmPullRequest: CustomStringConvertible {
public var description: String {
guard let number = attributes?.number, let title = attributes?.title else {
return "Unknown"
}

return "#\(number): \(title)"
}
}


extension APIProvider {
func requestAll<T: Decodable>(_ endpoint: Request<T>) async throws -> [T] {
var results: [T] = []
Expand All @@ -207,3 +278,17 @@ extension APIProvider {
return results
}
}

enum SourceType: CustomStringConvertible, CaseIterable {
case reference
case pullRequest

var description: String {
switch self {
case .reference:
"Git Reference (branch/tag)"
case .pullRequest:
"Pull Request"
}
}
}

0 comments on commit 36621cf

Please sign in to comment.