Skip to content

Commit cd108b3

Browse files
authored
Extend the Pull Request API (#195)
* - Extend PullRequest to read and create pull request review comments (regular comments as well as comments to specific commits / line numbers) - Add support for fetching requested reviewers (users and teams) for a Pull Request - Fix lint warnings * Team.swift was missing in the xcodeproj
1 parent 5721c0b commit cd108b3

9 files changed

+770
-86
lines changed

OctoKit.xcodeproj/project.pbxproj

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,10 @@
255255
E7EE59DA1BE10DA60012E3D2 /* StarsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7EE59D91BE10DA60012E3D2 /* StarsTests.swift */; };
256256
E7EE59DC1BE119110012E3D2 /* Follow.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7EE59DB1BE119110012E3D2 /* Follow.swift */; };
257257
E7EE59DE1BE11C2A0012E3D2 /* FollowTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E7EE59DD1BE11C2A0012E3D2 /* FollowTests.swift */; };
258+
F330CBC72D0305CC001D2BA9 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = F330CBC62D0305CC001D2BA9 /* Team.swift */; };
259+
F330CBC82D0305CC001D2BA9 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = F330CBC62D0305CC001D2BA9 /* Team.swift */; };
260+
F330CBC92D0305CC001D2BA9 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = F330CBC62D0305CC001D2BA9 /* Team.swift */; };
261+
F330CBCA2D0305CC001D2BA9 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = F330CBC62D0305CC001D2BA9 /* Team.swift */; };
258262
F8711EA21BFCAE9F005DDACA /* Time.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8711EA11BFCAE9F005DDACA /* Time.swift */; };
259263
/* End PBXBuildFile section */
260264

@@ -370,6 +374,7 @@
370374
E7EE59D91BE10DA60012E3D2 /* StarsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StarsTests.swift; sourceTree = "<group>"; };
371375
E7EE59DB1BE119110012E3D2 /* Follow.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Follow.swift; sourceTree = "<group>"; };
372376
E7EE59DD1BE11C2A0012E3D2 /* FollowTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FollowTests.swift; sourceTree = "<group>"; };
377+
F330CBC62D0305CC001D2BA9 /* Team.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Team.swift; sourceTree = "<group>"; };
373378
F8711EA11BFCAE9F005DDACA /* Time.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Time.swift; sourceTree = "<group>"; };
374379
/* End PBXFileReference section */
375380

@@ -436,27 +441,27 @@
436441
234F4BAA1BDDE31A00A58EF7 /* OctoKitTests */ = {
437442
isa = PBXGroup;
438443
children = (
439-
234F4BD71BDDE40400A58EF7 /* Fixtures */,
444+
234F4BAD1BDDE31A00A58EF7 /* Info.plist */,
440445
234F4BC91BDDE3F900A58EF7 /* ConfigurationTests.swift */,
441446
E7EE59DD1BE11C2A0012E3D2 /* FollowTests.swift */,
442447
515337F022529C380024544D /* GistTests.swift */,
443448
E7EDEA6B1C871D01006BAAF2 /* IssueTests.swift */,
444449
D4D28F6B2299D87300F8E92A /* LabelTests.swift */,
445450
234F4BCB1BDDE3F900A58EF7 /* OctokitSwiftTests.swift */,
446-
234F4BCC1BDDE3F900A58EF7 /* PublicKeyTests.swift */,
447-
234F4BCD1BDDE3F900A58EF7 /* RepositoryTests.swift */,
448-
E7EE59D91BE10DA60012E3D2 /* StarsTests.swift */,
449-
234F4BCE1BDDE3F900A58EF7 /* TestHelper.swift */,
450-
234F4BCF1BDDE3F900A58EF7 /* UserTests.swift */,
451451
23A0521E1CA924950068BFF7 /* OctoKitURLTestSession.swift */,
452-
234F4BAD1BDDE31A00A58EF7 /* Info.plist */,
453-
BF8C76EB002802C14A08F63E /* PullRequestTests.swift */,
454-
5090ED7523E48EE60062C763 /* ReleasesTests.swift */,
455-
9D9ADDDE23EEFD4A000AC34D /* ReviewTests.swift */,
456452
D1EAE84C25038A910023806C /* PlanTests.swift */,
457453
23EA618125EAE2FA001B0964 /* PreviewHeaderTests.swift */,
454+
234F4BCC1BDDE3F900A58EF7 /* PublicKeyTests.swift */,
455+
BF8C76EB002802C14A08F63E /* PullRequestTests.swift */,
458456
23EA618325EAE2FA001B0964 /* ReactionsTests.swift */,
457+
5090ED7523E48EE60062C763 /* ReleasesTests.swift */,
458+
234F4BCD1BDDE3F900A58EF7 /* RepositoryTests.swift */,
459+
9D9ADDDE23EEFD4A000AC34D /* ReviewTests.swift */,
460+
E7EE59D91BE10DA60012E3D2 /* StarsTests.swift */,
459461
23EA618225EAE2FA001B0964 /* StatusesTests.swift */,
462+
234F4BCE1BDDE3F900A58EF7 /* TestHelper.swift */,
463+
234F4BCF1BDDE3F900A58EF7 /* UserTests.swift */,
464+
234F4BD71BDDE40400A58EF7 /* Fixtures */,
460465
);
461466
name = OctoKitTests;
462467
path = Tests/OctoKitTests;
@@ -465,34 +470,34 @@
465470
234F4BD71BDDE40400A58EF7 /* Fixtures */ = {
466471
isa = PBXGroup;
467472
children = (
468-
721F73E829889A040064B11A /* latest_release.json */,
469-
03CCD2512453A9AA007D5CB3 /* users.json */,
473+
C1B2EE912A0C0090001CF2FA /* created_pull_request.json */,
470474
84B89D022C814DE400273C68 /* forked_repo.json */,
471475
515337F92252A0410024544D /* gist.json */,
472476
515337F522529E7B0024544D /* gists.json */,
473477
5090ED7123E483820062C763 /* issue_comment.json */,
478+
23EA619B25EAE31A001B0964 /* issue_comments.json */,
474479
DABBDE4F1C8C0C20008F57CD /* issue.json */,
475480
515337A8224FC3760024544D /* issue2.json */,
476481
E7EDEA6D1C871D0E006BAAF2 /* issues.json */,
477482
D4D28F732299DCE700F8E92A /* label.json */,
478483
D4D28F6F2299DBE600F8E92A /* labels.json */,
484+
721F73E829889A040064B11A /* latest_release.json */,
485+
23EA619D25EAE31A001B0964 /* plan.json */,
479486
5090ED7723E48FBC0062C763 /* post_release.json */,
480487
234F4BD81BDDE44600A58EF7 /* public_key.json */,
481-
234F4BD91BDDE44600A58EF7 /* repo.json */,
482-
665D5D5F24A639D70045E3B4 /* status.json */,
483-
665D5D5E24A639D70045E3B4 /* statuses.json */,
484-
234F4BDA1BDDE44600A58EF7 /* user_me.json */,
485-
234F4BDB1BDDE44600A58EF7 /* user_mietzmithut.json */,
486-
234F4BDC1BDDE44600A58EF7 /* user_repos.json */,
487-
23EA619B25EAE31A001B0964 /* issue_comments.json */,
488-
23EA619D25EAE31A001B0964 /* plan.json */,
489488
23EA61A025EAE31A001B0964 /* pull_request.json */,
490489
23EA61A125EAE31A001B0964 /* pull_requests.json */,
491-
C1B2EE912A0C0090001CF2FA /* created_pull_request.json */,
492490
23EA619C25EAE31A001B0964 /* reactions.json */,
493491
23EA619F25EAE31A001B0964 /* releases.json */,
492+
234F4BD91BDDE44600A58EF7 /* repo.json */,
494493
23EA619E25EAE31A001B0964 /* reviews.json */,
494+
665D5D5F24A639D70045E3B4 /* status.json */,
495+
665D5D5E24A639D70045E3B4 /* statuses.json */,
495496
849DF0792D029AF400A202DF /* topics.json */,
497+
234F4BDA1BDDE44600A58EF7 /* user_me.json */,
498+
234F4BDB1BDDE44600A58EF7 /* user_mietzmithut.json */,
499+
234F4BDC1BDDE44600A58EF7 /* user_repos.json */,
500+
03CCD2512453A9AA007D5CB3 /* users.json */,
496501
);
497502
name = Fixtures;
498503
sourceTree = "<group>";
@@ -501,7 +506,6 @@
501506
isa = PBXGroup;
502507
children = (
503508
239BE7CD1B8C47A100D2CE22 /* OctoKit.h */,
504-
84B89D002C814DBC00273C68 /* Organization.swift */,
505509
23B267851BDDD756003887E3 /* Configuration.swift */,
506510
515337C3225179FB0024544D /* File.swift */,
507511
E7EE59DB1BE119110012E3D2 /* Follow.swift */,
@@ -510,22 +514,24 @@
510514
DAEFC58F1C83D85100CF3785 /* Label.swift */,
511515
DAEFC5941C83EF0D00CF3785 /* Milestone.swift */,
512516
23B267861BDDD756003887E3 /* Octokit.swift */,
517+
84B89D002C814DBC00273C68 /* Organization.swift */,
518+
BF8C72B985869B84F46B4E9D /* Parameters.swift */,
519+
D1EAE8472503886C0023806C /* Plan.swift */,
520+
D1EAE8612503D33B0023806C /* PreviewHeader.swift */,
513521
23B267871BDDD756003887E3 /* PublicKey.swift */,
522+
BF8C73E0EF3CEEBDEA68DD5E /* PullRequest.swift */,
523+
D1EAE86A2503D9280023806C /* Reactions.swift */,
514524
5090ED7323E48AA80062C763 /* Releases.swift */,
515525
23B267881BDDD756003887E3 /* Repositories.swift */,
516-
23B267891BDDD756003887E3 /* User.swift */,
526+
9D9ADDE023EEFDE0000AC34D /* Review.swift */,
517527
E7EE59D71BDFEFB30012E3D2 /* Stars.swift */,
518528
665D5D5924A639960045E3B4 /* Statuses.swift */,
529+
D4D28F772299E9F200F8E92A /* String+PercentEncoding.swift */,
530+
F330CBC62D0305CC001D2BA9 /* Team.swift */,
519531
F8711EA11BFCAE9F005DDACA /* Time.swift */,
520532
237F91E31E5AEC82005FAA6B /* URL+URLParameters.swift */,
533+
23B267891BDDD756003887E3 /* User.swift */,
521534
239BE7CB1B8C47A100D2CE22 /* Supporting Files */,
522-
BF8C73E0EF3CEEBDEA68DD5E /* PullRequest.swift */,
523-
BF8C72B985869B84F46B4E9D /* Parameters.swift */,
524-
9D9ADDE023EEFDE0000AC34D /* Review.swift */,
525-
D4D28F772299E9F200F8E92A /* String+PercentEncoding.swift */,
526-
D1EAE8612503D33B0023806C /* PreviewHeader.swift */,
527-
D1EAE86A2503D9280023806C /* Reactions.swift */,
528-
D1EAE8472503886C0023806C /* Plan.swift */,
529535
);
530536
path = OctoKit;
531537
sourceTree = "<group>";
@@ -1003,6 +1009,7 @@
10031009
84B89D012C814DBC00273C68 /* Organization.swift in Sources */,
10041010
515337C4225179FB0024544D /* File.swift in Sources */,
10051011
515337C2225166600024544D /* Gist.swift in Sources */,
1012+
F330CBC92D0305CC001D2BA9 /* Team.swift in Sources */,
10061013
23B2678C1BDDD756003887E3 /* PublicKey.swift in Sources */,
10071014
23B2678E1BDDD756003887E3 /* User.swift in Sources */,
10081015
237F91E41E5AEC82005FAA6B /* URL+URLParameters.swift in Sources */,
@@ -1034,6 +1041,7 @@
10341041
84B89D0A2C81587100273C68 /* Organization.swift in Sources */,
10351042
23CAF2B71C7AB6EB005011C4 /* Time.swift in Sources */,
10361043
23CAF2B41C7AB6D4005011C4 /* Stars.swift in Sources */,
1044+
F330CBCA2D0305CC001D2BA9 /* Team.swift in Sources */,
10371045
23CAF2AB1C7AB6C9005011C4 /* PublicKey.swift in Sources */,
10381046
D1EAE86C2503D9280023806C /* Reactions.swift in Sources */,
10391047
237F91E51E5AEC87005FAA6B /* URL+URLParameters.swift in Sources */,
@@ -1091,6 +1099,7 @@
10911099
84B89D0B2C81587100273C68 /* Organization.swift in Sources */,
10921100
23CAF2B81C7AB6EB005011C4 /* Time.swift in Sources */,
10931101
23CAF2B51C7AB6D5005011C4 /* Stars.swift in Sources */,
1102+
F330CBC72D0305CC001D2BA9 /* Team.swift in Sources */,
10941103
23CAF2AC1C7AB6CA005011C4 /* PublicKey.swift in Sources */,
10951104
D1EAE86D2503D9280023806C /* Reactions.swift in Sources */,
10961105
237F91E61E5AEC88005FAA6B /* URL+URLParameters.swift in Sources */,
@@ -1148,6 +1157,7 @@
11481157
84B89D0C2C81587200273C68 /* Organization.swift in Sources */,
11491158
23CAF2B91C7AB6EC005011C4 /* Time.swift in Sources */,
11501159
23CAF2B61C7AB6D5005011C4 /* Stars.swift in Sources */,
1160+
F330CBC82D0305CC001D2BA9 /* Team.swift in Sources */,
11511161
23CAF2AD1C7AB6CA005011C4 /* PublicKey.swift in Sources */,
11521162
D1EAE86E2503D9280023806C /* Reactions.swift in Sources */,
11531163
237F91E71E5AEC89005FAA6B /* URL+URLParameters.swift in Sources */,

OctoKit/Issue.swift

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -104,21 +104,23 @@ open class Issue: Codable {
104104
}
105105
}
106106

107-
public struct Comment: Codable {
108-
public let id: Int
109-
public let url: URL
110-
public let htmlURL: URL
111-
public let body: String
112-
public let user: User
113-
public let createdAt: Date
114-
public let updatedAt: Date
115-
public let reactions: Reactions?
107+
public extension Issue {
108+
struct Comment: Codable {
109+
public let id: Int
110+
public let url: URL
111+
public let htmlURL: URL
112+
public let body: String
113+
public let user: User
114+
public let createdAt: Date
115+
public let updatedAt: Date
116+
public let reactions: Reactions?
116117

117-
enum CodingKeys: String, CodingKey {
118-
case id, url, body, user, reactions
119-
case htmlURL = "html_url"
120-
case createdAt = "created_at"
121-
case updatedAt = "updated_at"
118+
enum CodingKeys: String, CodingKey {
119+
case id, url, body, user, reactions
120+
case htmlURL = "html_url"
121+
case createdAt = "created_at"
122+
case updatedAt = "updated_at"
123+
}
122124
}
123125
}
124126

@@ -382,11 +384,11 @@ public extension Octokit {
382384
repository: String,
383385
number: Int,
384386
body: String,
385-
completion: @escaping (_ response: Result<Comment, Error>) -> Void) -> URLSessionDataTaskProtocol? {
387+
completion: @escaping (_ response: Result<Issue.Comment, Error>) -> Void) -> URLSessionDataTaskProtocol? {
386388
let router = IssueRouter.commentIssue(configuration, owner, repository, number, body)
387389
let decoder = JSONDecoder()
388390
decoder.dateDecodingStrategy = .formatted(Time.rfc3339DateFormatter)
389-
return router.post(session, decoder: decoder, expectedResultType: Comment.self) { issue, error in
391+
return router.post(session, decoder: decoder, expectedResultType: Issue.Comment.self) { issue, error in
390392
if let error = error {
391393
completion(.failure(error))
392394
} else {
@@ -406,11 +408,11 @@ public extension Octokit {
406408
/// - body: The contents of the comment.
407409
/// - completion: Callback for the comment that is created.
408410
@available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
409-
func commentIssue(owner: String, repository: String, number: Int, body: String) async throws -> Comment {
411+
func commentIssue(owner: String, repository: String, number: Int, body: String) async throws -> Issue.Comment {
410412
let router = IssueRouter.commentIssue(configuration, owner, repository, number, body)
411413
let decoder = JSONDecoder()
412414
decoder.dateDecodingStrategy = .formatted(Time.rfc3339DateFormatter)
413-
return try await router.post(session, decoder: decoder, expectedResultType: Comment.self)
415+
return try await router.post(session, decoder: decoder, expectedResultType: Issue.Comment.self)
414416
}
415417
#endif
416418

@@ -428,9 +430,9 @@ public extension Octokit {
428430
number: Int,
429431
page: String = "1",
430432
perPage: String = "100",
431-
completion: @escaping (_ response: Result<[Comment], Error>) -> Void) -> URLSessionDataTaskProtocol? {
433+
completion: @escaping (_ response: Result<[Issue.Comment], Error>) -> Void) -> URLSessionDataTaskProtocol? {
432434
let router = IssueRouter.readIssueComments(configuration, owner, repository, number, page, perPage)
433-
return router.load(session, dateDecodingStrategy: .formatted(Time.rfc3339DateFormatter), expectedResultType: [Comment].self) { comments, error in
435+
return router.load(session, dateDecodingStrategy: .formatted(Time.rfc3339DateFormatter), expectedResultType: [Issue.Comment].self) { comments, error in
434436
if let error = error {
435437
completion(.failure(error))
436438
} else {
@@ -455,9 +457,9 @@ public extension Octokit {
455457
repository: String,
456458
number: Int,
457459
page: String = "1",
458-
perPage: String = "100") async throws -> [Comment] {
460+
perPage: String = "100") async throws -> [Issue.Comment] {
459461
let router = IssueRouter.readIssueComments(configuration, owner, repository, number, page, perPage)
460-
return try await router.load(session, dateDecodingStrategy: .formatted(Time.rfc3339DateFormatter), expectedResultType: [Comment].self)
462+
return try await router.load(session, dateDecodingStrategy: .formatted(Time.rfc3339DateFormatter), expectedResultType: [Issue.Comment].self)
461463
}
462464
#endif
463465

@@ -473,11 +475,11 @@ public extension Octokit {
473475
repository: String,
474476
number: Int,
475477
body: String,
476-
completion: @escaping (_ response: Result<Comment, Error>) -> Void) -> URLSessionDataTaskProtocol? {
478+
completion: @escaping (_ response: Result<Issue.Comment, Error>) -> Void) -> URLSessionDataTaskProtocol? {
477479
let router = IssueRouter.patchIssueComment(configuration, owner, repository, number, body)
478480
let decoder = JSONDecoder()
479481
decoder.dateDecodingStrategy = .formatted(Time.rfc3339DateFormatter)
480-
return router.post(session, decoder: decoder, expectedResultType: Comment.self) { issue, error in
482+
return router.post(session, decoder: decoder, expectedResultType: Issue.Comment.self) { issue, error in
481483
if let error = error {
482484
completion(.failure(error))
483485
} else {
@@ -497,11 +499,11 @@ public extension Octokit {
497499
/// - body: The contents of the comment.
498500
/// - completion: Callback for the comment that is created.
499501
@available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *)
500-
func patchIssueComment(owner: String, repository: String, number: Int, body: String) async throws -> Comment {
502+
func patchIssueComment(owner: String, repository: String, number: Int, body: String) async throws -> Issue.Comment {
501503
let router = IssueRouter.patchIssueComment(configuration, owner, repository, number, body)
502504
let decoder = JSONDecoder()
503505
decoder.dateDecodingStrategy = .formatted(Time.rfc3339DateFormatter)
504-
return try await router.post(session, decoder: decoder, expectedResultType: Comment.self)
506+
return try await router.post(session, decoder: decoder, expectedResultType: Issue.Comment.self)
505507
}
506508
#endif
507509
}

0 commit comments

Comments
 (0)