Skip to content

Commit

Permalink
Adding ability to create new pull request. (#167)
Browse files Browse the repository at this point in the history
* Adding create pull request support

* Updates from review

* Add async version

* Adding tests

* Support older swift versions

* Formatting tweaks to satisfy linter.
  • Loading branch information
ps2 authored May 23, 2023
1 parent 0c4076a commit 61be8eb
Show file tree
Hide file tree
Showing 4 changed files with 732 additions and 3 deletions.
8 changes: 8 additions & 0 deletions OctoKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,9 @@
BF8C7BE0F4071324EBDCA204 /* PullRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8C73E0EF3CEEBDEA68DD5E /* PullRequest.swift */; };
BF8C7DEE90DD25CBCA4AEE71 /* Parameters.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8C72B985869B84F46B4E9D /* Parameters.swift */; };
BF8C7FFFDDAFA560EBEC35EE /* PullRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8C73E0EF3CEEBDEA68DD5E /* PullRequest.swift */; };
C1B2EE922A0C0090001CF2FA /* created_pull_request.json in Resources */ = {isa = PBXBuildFile; fileRef = C1B2EE912A0C0090001CF2FA /* created_pull_request.json */; };
C1B2EE932A0C0090001CF2FA /* created_pull_request.json in Resources */ = {isa = PBXBuildFile; fileRef = C1B2EE912A0C0090001CF2FA /* created_pull_request.json */; };
C1B2EE942A0C0090001CF2FA /* created_pull_request.json in Resources */ = {isa = PBXBuildFile; fileRef = C1B2EE912A0C0090001CF2FA /* created_pull_request.json */; };
D1EAE8482503886C0023806C /* Plan.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1EAE8472503886C0023806C /* Plan.swift */; };
D1EAE8492503886C0023806C /* Plan.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1EAE8472503886C0023806C /* Plan.swift */; };
D1EAE84A2503886C0023806C /* Plan.swift in Sources */ = {isa = PBXBuildFile; fileRef = D1EAE8472503886C0023806C /* Plan.swift */; };
Expand Down Expand Up @@ -335,6 +338,7 @@
BF8C72B985869B84F46B4E9D /* Parameters.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Parameters.swift; sourceTree = "<group>"; };
BF8C73E0EF3CEEBDEA68DD5E /* PullRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PullRequest.swift; sourceTree = "<group>"; };
BF8C76EB002802C14A08F63E /* PullRequestTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PullRequestTests.swift; sourceTree = "<group>"; };
C1B2EE912A0C0090001CF2FA /* created_pull_request.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; name = created_pull_request.json; path = Fixtures/created_pull_request.json; sourceTree = "<group>"; };
D1EAE8472503886C0023806C /* Plan.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Plan.swift; sourceTree = "<group>"; };
D1EAE84C25038A910023806C /* PlanTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlanTests.swift; sourceTree = "<group>"; };
D1EAE8612503D33B0023806C /* PreviewHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewHeader.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -470,6 +474,7 @@
23EA619D25EAE31A001B0964 /* plan.json */,
23EA61A025EAE31A001B0964 /* pull_request.json */,
23EA61A125EAE31A001B0964 /* pull_requests.json */,
C1B2EE912A0C0090001CF2FA /* created_pull_request.json */,
23EA619C25EAE31A001B0964 /* reactions.json */,
23EA619F25EAE31A001B0964 /* releases.json */,
23EA619E25EAE31A001B0964 /* reviews.json */,
Expand Down Expand Up @@ -831,6 +836,7 @@
E7EDEA6E1C871D0E006BAAF2 /* issues.json in Resources */,
23EA61A525EAE31A001B0964 /* reactions.json in Resources */,
5090ED7823E48FBC0062C763 /* post_release.json in Resources */,
C1B2EE922A0C0090001CF2FA /* created_pull_request.json in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -878,6 +884,7 @@
D4D28F712299DBE600F8E92A /* labels.json in Resources */,
23EA61A625EAE31A001B0964 /* reactions.json in Resources */,
E7EDEA741C871FA8006BAAF2 /* issues.json in Resources */,
C1B2EE932A0C0090001CF2FA /* created_pull_request.json in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -917,6 +924,7 @@
D4D28F722299DBE600F8E92A /* labels.json in Resources */,
23EA61A725EAE31A001B0964 /* reactions.json in Resources */,
E7EDEA751C871FA9006BAAF2 /* issues.json in Resources */,
C1B2EE942A0C0090001CF2FA /* created_pull_request.json in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
105 changes: 102 additions & 3 deletions OctoKit/PullRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,79 @@ open class PullRequest: Codable {
// MARK: Request

public extension Octokit {
/**
Create a pull request
- parameter session: RequestKitURLSession, defaults to URLSession.shared
- parameter owner: The user or organization that owns the repositories.
- parameter repo: The name of the repository.
- parameter title: The title of the new pull request.
- parameter head: The name of the branch where your changes are implemented.
- parameter headRepo: The name of the repository where the changes in the pull request were made.
- parameter base: The name of the branch you want the changes pulled into.
- parameter body: The contents of the pull request.
- parameter maintainerCanModify: Indicates whether maintainers can modify the pull request.
- parameter draft: Indicates whether the pull request is a draft.
- parameter completion: Callback for the outcome of the fetch.
*/
@discardableResult
func createPullRequest(_ session: RequestKitURLSession = URLSession.shared,
owner: String,
repo: String,
title: String,
head: String,
headRepo: String? = nil,
base: String,
body: String? = nil,
maintainerCanModify: Bool? = nil,
draft: Bool? = nil,
completion: @escaping (_ response: Result<PullRequest, Error>) -> Void) -> URLSessionDataTaskProtocol? {
let router = PullRequestRouter.createPullRequest(configuration, owner, repo, title, head, headRepo, base, body, maintainerCanModify, draft)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(Time.rfc3339DateFormatter)
return router.post(session, decoder: decoder, expectedResultType: PullRequest.self) { pullRequest, error in
if let error = error {
completion(.failure(error))
} else {
if let pullRequest = pullRequest {
completion(.success(pullRequest))
}
}
}
}

#if compiler(>=5.5.2) && canImport(_Concurrency)
/**
Create a pull request
- parameter session: RequestKitURLSession, defaults to URLSession.shared
- parameter owner: The user or organization that owns the repositories.
- parameter repo: The name of the repository.
- parameter title: The title of the new pull request.
- parameter head: The name of the branch where your changes are implemented.
- parameter headRepo: The name of the repository where the changes in the pull request were made.
- parameter base: The name of the branch you want the changes pulled into.
- parameter body: The contents of the pull request.
- parameter maintainerCanModify: Indicates whether maintainers can modify the pull request.
- parameter draft: Indicates whether the pull request is a draft.
- Returns: A PullRequest
*/
@available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
func createPullRequest(_ session: RequestKitURLSession = URLSession.shared,
owner: String,
repo: String,
title: String,
head: String,
headRepo: String? = nil,
base: String,
body: String? = nil,
maintainerCanModify: Bool? = nil,
draft: Bool? = nil) async throws -> PullRequest {
let router = PullRequestRouter.createPullRequest(configuration, owner, repo, title, head, headRepo, base, body, maintainerCanModify, draft)
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(Time.rfc3339DateFormatter)
return try await router.post(session, decoder: decoder, expectedResultType: PullRequest.self)
}
#endif

/**
Get a single pull request
- parameter session: RequestKitURLSession, defaults to URLSession.shared
Expand Down Expand Up @@ -261,10 +334,13 @@ public extension Octokit {
enum PullRequestRouter: JSONPostRouter {
case readPullRequest(Configuration, String, String, String)
case readPullRequests(Configuration, String, String, String?, String?, Openness, SortType, SortDirection)
case createPullRequest(Configuration, String, String, String, String, String?, String, String?, Bool?, Bool?)
case patchPullRequest(Configuration, String, String, String, String, String, Openness, String?, Bool?)

var method: HTTPMethod {
switch self {
case .createPullRequest:
return .POST
case .readPullRequest,
.readPullRequests:
return .GET
Expand All @@ -275,7 +351,7 @@ enum PullRequestRouter: JSONPostRouter {

var encoding: HTTPEncoding {
switch self {
case .patchPullRequest:
case .patchPullRequest, .createPullRequest:
return .json
default:
return .url
Expand All @@ -287,6 +363,7 @@ enum PullRequestRouter: JSONPostRouter {
case let .readPullRequest(config, _, _, _): return config
case let .readPullRequests(config, _, _, _, _, _, _, _): return config
case let .patchPullRequest(config, _, _, _, _, _, _, _, _): return config
case let .createPullRequest(config, _, _, _, _, _, _, _, _, _): return config
}
}

Expand All @@ -311,7 +388,7 @@ enum PullRequestRouter: JSONPostRouter {

return parameters
case let .patchPullRequest(_, _, _, _, title, body, state, base, mantainerCanModify):
var parameters = [
var parameters: [String: Any] = [
"title": title,
"state": state.rawValue,
"body": body
Expand All @@ -320,7 +397,27 @@ enum PullRequestRouter: JSONPostRouter {
parameters["base"] = base
}
if let mantainerCanModify = mantainerCanModify {
parameters["maintainer_can_modify"] = (mantainerCanModify ? "true" : "false")
parameters["maintainer_can_modify"] = mantainerCanModify
}
return parameters

case let .createPullRequest(_, _, _, title, head, headRepo, base, body, mantainerCanModify, draft):
var parameters: [String: Any] = [
"title": title,
"head": head,
"base": base
]
if let headRepo = headRepo {
parameters["head_repo"] = headRepo
}
if let body = body {
parameters["body"] = body
}
if let mantainerCanModify = mantainerCanModify {
parameters["maintainer_can_modify"] = mantainerCanModify
}
if let draft = draft {
parameters["draft"] = draft
}
return parameters
}
Expand All @@ -334,6 +431,8 @@ enum PullRequestRouter: JSONPostRouter {
return "repos/\(owner)/\(repository)/pulls/\(number)"
case let .readPullRequests(_, owner, repository, _, _, _, _, _):
return "repos/\(owner)/\(repository)/pulls"
case let .createPullRequest(_, owner, repository, _, _, _, _, _, _, _):
return "repos/\(owner)/\(repository)/pulls"
}
}
}
Loading

0 comments on commit 61be8eb

Please sign in to comment.