Skip to content

Commit 8f78b18

Browse files
authored
Implement the API endpoint to fetch specific release by tag name (nerdishbynature#141)
* add `Get a release by tag name` * add test case * rename router * format with running `SwiftFormat`
1 parent 4b2afd0 commit 8f78b18

File tree

3 files changed

+99
-2
lines changed

3 files changed

+99
-2
lines changed

OctoKit/Releases.swift

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,33 @@ public extension Octokit {
7676
}
7777
}
7878

79+
/// Fetches a published release with the specified tag.
80+
/// - Parameters:
81+
/// - session: RequestKitURLSession, defaults to URLSession.shared()
82+
/// - owner: The user or organization that owns the repositories.
83+
/// - repository: The name of the repository.
84+
/// - tag: The specified tag
85+
/// - completion: Callback for the outcome of the fetch.
86+
@discardableResult
87+
func release(_ session: RequestKitURLSession = URLSession.shared,
88+
owner: String,
89+
repository: String,
90+
tag: String,
91+
completion: @escaping (_ response: Result<Release, Error>) -> Void) -> URLSessionDataTaskProtocol?
92+
{
93+
let router = ReleaseRouter.getReleaseByTag(configuration, owner, repository, tag)
94+
return router.load(session,
95+
dateDecodingStrategy: .formatted(Time.rfc3339DateFormatter),
96+
expectedResultType: Release.self)
97+
{ release, error in
98+
if let error = error {
99+
completion(.failure(error))
100+
} else if let release = release {
101+
completion(.success(release))
102+
}
103+
}
104+
}
105+
79106
/// Creates a new release.
80107
/// - Parameters:
81108
/// - session: RequestKitURLSession, defaults to URLSession.shared()
@@ -138,20 +165,22 @@ public extension Octokit {
138165

139166
enum ReleaseRouter: JSONPostRouter {
140167
case listReleases(Configuration, String, String, Int)
168+
case getReleaseByTag(Configuration, String, String, String)
141169
case postRelease(Configuration, String, String, String, String?, String?, String?, Bool, Bool)
142170
case deleteRelease(Configuration, String, String, Int)
143171

144172
var configuration: Configuration {
145173
switch self {
146174
case let .listReleases(config, _, _, _): return config
175+
case let .getReleaseByTag(config, _, _, _): return config
147176
case let .postRelease(config, _, _, _, _, _, _, _, _): return config
148177
case let .deleteRelease(config, _, _, _): return config
149178
}
150179
}
151180

152181
var method: HTTPMethod {
153182
switch self {
154-
case .listReleases:
183+
case .listReleases, .getReleaseByTag:
155184
return .GET
156185
case .postRelease:
157186
return .POST
@@ -162,7 +191,7 @@ enum ReleaseRouter: JSONPostRouter {
162191

163192
var encoding: HTTPEncoding {
164193
switch self {
165-
case .listReleases:
194+
case .listReleases, .getReleaseByTag:
166195
return .url
167196
case .postRelease:
168197
return .json
@@ -175,6 +204,8 @@ enum ReleaseRouter: JSONPostRouter {
175204
switch self {
176205
case let .listReleases(_, _, _, perPage):
177206
return ["per_page": "\(perPage)"]
207+
case .getReleaseByTag:
208+
return [:]
178209
case let .postRelease(_, _, _, tagName, targetCommitish, name, body, prerelease, draft):
179210
var params: [String: Any] = [
180211
"tag_name": tagName,
@@ -200,6 +231,8 @@ enum ReleaseRouter: JSONPostRouter {
200231
switch self {
201232
case let .listReleases(_, owner, repo, _):
202233
return "repos/\(owner)/\(repo)/releases"
234+
case let .getReleaseByTag(_, owner, repo, tag):
235+
return "repos/\(owner)/\(repo)/releases/tags/\(tag)"
203236
case let .postRelease(_, owner, repo, _, _, _, _, _, _):
204237
return "repos/\(owner)/\(repo)/releases"
205238
case let .deleteRelease(_, owner, repo, releaseId):
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"url": "https://api.github.com/repos/octocat/Hello-World/releases/1",
3+
"html_url": "https://github.com/octocat/Hello-World/releases/v1.0.0",
4+
"assets_url": "https://api.github.com/repos/octocat/Hello-World/releases/1/assets",
5+
"upload_url": "https://uploads.github.com/repos/octocat/Hello-World/releases/1/assets{?name,label}",
6+
"tarball_url": "https://api.github.com/repos/octocat/Hello-World/tarball/v1.0.0",
7+
"zipball_url": "https://api.github.com/repos/octocat/Hello-World/zipball/v1.0.0",
8+
"id": 1,
9+
"node_id": "MDc6UmVsZWFzZTE=",
10+
"tag_name": "v1.0.0",
11+
"target_commitish": "master",
12+
"name": "v1.0.0 Release",
13+
"body": "The changelog of this release",
14+
"draft": false,
15+
"prerelease": false,
16+
"created_at": "2013-02-27T19:35:32Z",
17+
"published_at": "2013-02-27T19:35:32Z",
18+
"author": {
19+
"login": "octocat",
20+
"id": 1,
21+
"node_id": "MDQ6VXNlcjE=",
22+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
23+
"gravatar_id": "",
24+
"url": "https://api.github.com/users/octocat",
25+
"html_url": "https://github.com/octocat",
26+
"followers_url": "https://api.github.com/users/octocat/followers",
27+
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
28+
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
29+
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
30+
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
31+
"organizations_url": "https://api.github.com/users/octocat/orgs",
32+
"repos_url": "https://api.github.com/users/octocat/repos",
33+
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
34+
"received_events_url": "https://api.github.com/users/octocat/received_events",
35+
"type": "User",
36+
"site_admin": false
37+
},
38+
"assets": []
39+
}

Tests/OctoKitTests/ReleasesTests.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,29 @@ final class ReleasesTests: XCTestCase {
105105
XCTAssertNotNil(task)
106106
XCTAssertTrue(session.wasCalled)
107107
}
108+
109+
func testReleaseTagName() {
110+
let session = OctoKitURLTestSession(expectedURL: "https://api.github.com/repos/octocat/Hello-World/releases/tags/v1.0.0",
111+
expectedHTTPMethod: "GET",
112+
jsonFile: "Fixtures/release",
113+
statusCode: 201)
114+
let task = Octokit().release(session, owner: "octocat", repository: "Hello-World", tag: "v1.0.0") {
115+
switch $0 {
116+
case let .success(release):
117+
XCTAssertEqual(release.tagName, "v1.0.0")
118+
XCTAssertEqual(release.commitish, "master")
119+
XCTAssertEqual(release.name, "v1.0.0 Release")
120+
XCTAssertEqual(release.body, "The changelog of this release")
121+
XCTAssertFalse(release.prerelease)
122+
XCTAssertFalse(release.draft)
123+
XCTAssertEqual(release.tarballURL?.absoluteString, "https://api.github.com/repos/octocat/Hello-World/tarball/v1.0.0")
124+
XCTAssertEqual(release.zipballURL?.absoluteString, "https://api.github.com/repos/octocat/Hello-World/zipball/v1.0.0")
125+
XCTAssertEqual(release.publishedAt, Date(timeIntervalSince1970: 1361993732.0))
126+
case let .failure(error):
127+
XCTAssert(false, "Endpoint failed with error \(error)")
128+
}
129+
}
130+
XCTAssertNotNil(task)
131+
XCTAssertTrue(session.wasCalled)
132+
}
108133
}

0 commit comments

Comments
 (0)