Skip to content

Commit 86578ea

Browse files
author
Steve Riesenberg
committed
Merge branch '5.7.x' into 5.8.x
Closes gh-12801
2 parents 383e0c2 + 5257e36 commit 86578ea

File tree

7 files changed

+270
-9
lines changed

7 files changed

+270
-9
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright 2020-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.gradle.github.user;
17+
18+
import java.io.IOException;
19+
20+
import com.google.gson.Gson;
21+
import okhttp3.Interceptor;
22+
import okhttp3.OkHttpClient;
23+
import okhttp3.Request;
24+
import okhttp3.Response;
25+
26+
/**
27+
* @author Steve Riesenberg
28+
*/
29+
public class GitHubUserApi {
30+
private String baseUrl = "https://api.github.com";
31+
32+
private final OkHttpClient httpClient;
33+
private Gson gson = new Gson();
34+
35+
public GitHubUserApi(String gitHubAccessToken) {
36+
this.httpClient = new OkHttpClient.Builder()
37+
.addInterceptor(new AuthorizationInterceptor(gitHubAccessToken))
38+
.build();
39+
}
40+
41+
public void setBaseUrl(String baseUrl) {
42+
this.baseUrl = baseUrl;
43+
}
44+
45+
/**
46+
* Retrieve a GitHub user by the personal access token.
47+
*
48+
* @return The GitHub user
49+
*/
50+
public User getUser() {
51+
String url = this.baseUrl + "/user";
52+
Request request = new Request.Builder().url(url).get().build();
53+
try (Response response = this.httpClient.newCall(request).execute()) {
54+
if (!response.isSuccessful()) {
55+
throw new RuntimeException(
56+
String.format("Unable to retrieve GitHub user." +
57+
" Please check the personal access token and try again." +
58+
" Got response %s", response));
59+
}
60+
return this.gson.fromJson(response.body().charStream(), User.class);
61+
} catch (IOException ex) {
62+
throw new RuntimeException("Unable to retrieve GitHub user.", ex);
63+
}
64+
}
65+
66+
private static class AuthorizationInterceptor implements Interceptor {
67+
private final String token;
68+
69+
public AuthorizationInterceptor(String token) {
70+
this.token = token;
71+
}
72+
73+
@Override
74+
public Response intercept(Chain chain) throws IOException {
75+
Request request = chain.request().newBuilder()
76+
.addHeader("Authorization", "Bearer " + this.token)
77+
.build();
78+
79+
return chain.proceed(request);
80+
}
81+
}
82+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.springframework.gradle.github.user;
2+
3+
/**
4+
* @author Steve Riesenberg
5+
*/
6+
public class User {
7+
private Long id;
8+
private String login;
9+
private String name;
10+
private String url;
11+
12+
public Long getId() {
13+
return this.id;
14+
}
15+
16+
public void setId(Long id) {
17+
this.id = id;
18+
}
19+
20+
public String getLogin() {
21+
return this.login;
22+
}
23+
24+
public void setLogin(String login) {
25+
this.login = login;
26+
}
27+
28+
public String getName() {
29+
return this.name;
30+
}
31+
32+
public void setName(String name) {
33+
this.name = name;
34+
}
35+
36+
public String getUrl() {
37+
return this.url;
38+
}
39+
40+
public void setUrl(String url) {
41+
this.url = url;
42+
}
43+
44+
@Override
45+
public String toString() {
46+
return "User{" +
47+
"id=" + id +
48+
", login='" + login + '\'' +
49+
", name='" + name + '\'' +
50+
", url='" + url + '\'' +
51+
'}';
52+
}
53+
}

buildSrc/src/main/java/org/springframework/gradle/sagan/SaganApi.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,14 +26,14 @@
2626
* Implements necessary calls to the Sagan API See https://spring.io/restdocs/index.html
2727
*/
2828
public class SaganApi {
29-
private String baseUrl = "https://spring.io/api";
29+
private String baseUrl = "https://api.spring.io";
3030

3131
private OkHttpClient client;
3232
private Gson gson = new Gson();
3333

34-
public SaganApi(String gitHubToken) {
34+
public SaganApi(String username, String gitHubToken) {
3535
this.client = new OkHttpClient.Builder()
36-
.addInterceptor(new BasicInterceptor("not-used", gitHubToken))
36+
.addInterceptor(new BasicInterceptor(username, gitHubToken))
3737
.build();
3838
}
3939

buildSrc/src/main/java/org/springframework/gradle/sagan/SaganCreateReleaseTask.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
import org.gradle.api.tasks.Input;
2121
import org.gradle.api.tasks.TaskAction;
2222

23+
import org.springframework.gradle.github.user.GitHubUserApi;
24+
import org.springframework.gradle.github.user.User;
25+
2326
public class SaganCreateReleaseTask extends DefaultTask {
2427

2528
@Input
@@ -35,11 +38,22 @@ public class SaganCreateReleaseTask extends DefaultTask {
3538

3639
@TaskAction
3740
public void saganCreateRelease() {
38-
SaganApi sagan = new SaganApi(this.gitHubAccessToken);
41+
GitHubUserApi github = new GitHubUserApi(this.gitHubAccessToken);
42+
User user = github.getUser();
43+
44+
// Antora reference docs URLs for snapshots do not contain -SNAPSHOT
45+
String referenceDocUrl = this.referenceDocUrl;
46+
if (this.version.endsWith("-SNAPSHOT")) {
47+
referenceDocUrl = this.referenceDocUrl
48+
.replace("{version}", this.version)
49+
.replace("-SNAPSHOT", "");
50+
}
51+
52+
SaganApi sagan = new SaganApi(user.getLogin(), this.gitHubAccessToken);
3953
Release release = new Release();
4054
release.setVersion(this.version);
4155
release.setApiDocUrl(this.apiDocUrl);
42-
release.setReferenceDocUrl(this.referenceDocUrl);
56+
release.setReferenceDocUrl(referenceDocUrl);
4357
sagan.createReleaseForProject(release, this.projectName);
4458
}
4559

buildSrc/src/main/java/org/springframework/gradle/sagan/SaganDeleteReleaseTask.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
import org.gradle.api.tasks.Input;
2121
import org.gradle.api.tasks.TaskAction;
2222

23+
import org.springframework.gradle.github.user.GitHubUserApi;
24+
import org.springframework.gradle.github.user.User;
25+
2326
public class SaganDeleteReleaseTask extends DefaultTask {
2427

2528
@Input
@@ -31,7 +34,10 @@ public class SaganDeleteReleaseTask extends DefaultTask {
3134

3235
@TaskAction
3336
public void saganCreateRelease() {
34-
SaganApi sagan = new SaganApi(this.gitHubAccessToken);
37+
GitHubUserApi github = new GitHubUserApi(this.gitHubAccessToken);
38+
User user = github.getUser();
39+
40+
SaganApi sagan = new SaganApi(user.getLogin(), this.gitHubAccessToken);
3541
sagan.deleteReleaseForProject(this.version, this.projectName);
3642
}
3743

buildSrc/src/test/java/io/spring/gradle/convention/sagan/SaganApiTests.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class SaganApiTests {
4242
public void setup() throws Exception {
4343
this.server = new MockWebServer();
4444
this.server.start();
45-
this.sagan = new SaganApi("mock-oauth-token");
45+
this.sagan = new SaganApi("user", "mock-oauth-token");
4646
this.baseUrl = this.server.url("/api").toString();
4747
this.sagan.setBaseUrl(this.baseUrl);
4848
}
@@ -63,7 +63,7 @@ public void createWhenValidThenNoException() throws Exception {
6363
RecordedRequest request = this.server.takeRequest(1, TimeUnit.SECONDS);
6464
assertThat(request.getRequestUrl().toString()).isEqualTo(this.baseUrl + "/projects/spring-security/releases");
6565
assertThat(request.getMethod()).isEqualToIgnoringCase("post");
66-
assertThat(request.getHeaders().get("Authorization")).isEqualTo("Basic bm90LXVzZWQ6bW9jay1vYXV0aC10b2tlbg==");
66+
assertThat(request.getHeaders().get("Authorization")).isEqualTo("Basic dXNlcjptb2NrLW9hdXRoLXRva2Vu");
6767
assertThat(request.getBody().readString(Charset.defaultCharset())).isEqualToIgnoringWhitespace("{\n" +
6868
" \"version\":\"5.6.0-SNAPSHOT\",\n" +
6969
" \"current\":false,\n" +
@@ -79,7 +79,7 @@ public void deleteWhenValidThenNoException() throws Exception {
7979
RecordedRequest request = this.server.takeRequest(1, TimeUnit.SECONDS);
8080
assertThat(request.getRequestUrl().toString()).isEqualTo(this.baseUrl + "/projects/spring-security/releases/5.6.0-SNAPSHOT");
8181
assertThat(request.getMethod()).isEqualToIgnoringCase("delete");
82-
assertThat(request.getHeaders().get("Authorization")).isEqualTo("Basic bm90LXVzZWQ6bW9jay1vYXV0aC10b2tlbg==");
82+
assertThat(request.getHeaders().get("Authorization")).isEqualTo("Basic dXNlcjptb2NrLW9hdXRoLXRva2Vu");
8383
assertThat(request.getBody().readString(Charset.defaultCharset())).isEmpty();
8484
}
8585
}
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Copyright 2020-2023 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package org.springframework.gradle.github.user;
17+
18+
import okhttp3.mockwebserver.MockResponse;
19+
import okhttp3.mockwebserver.MockWebServer;
20+
import org.junit.jupiter.api.AfterEach;
21+
import org.junit.jupiter.api.BeforeEach;
22+
import org.junit.jupiter.api.Test;
23+
24+
import static org.assertj.core.api.Assertions.assertThat;
25+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
26+
27+
/**
28+
* @author Steve Riesenberg
29+
*/
30+
public class GitHubUserApiTests {
31+
private GitHubUserApi gitHubUserApi;
32+
33+
private MockWebServer server;
34+
35+
private String baseUrl;
36+
37+
@BeforeEach
38+
public void setup() throws Exception {
39+
this.server = new MockWebServer();
40+
this.server.start();
41+
this.baseUrl = this.server.url("/api").toString();
42+
this.gitHubUserApi = new GitHubUserApi("mock-oauth-token");
43+
this.gitHubUserApi.setBaseUrl(this.baseUrl);
44+
}
45+
46+
@AfterEach
47+
public void cleanup() throws Exception {
48+
this.server.shutdown();
49+
}
50+
51+
@Test
52+
public void getUserWhenValidParametersThenSuccess() {
53+
// @formatter:off
54+
String responseJson = "{\n" +
55+
" \"avatar_url\": \"https://avatars.githubusercontent.com/u/583231?v=4\",\n" +
56+
" \"bio\": null,\n" +
57+
" \"blog\": \"https://github.blog\",\n" +
58+
" \"company\": \"@github\",\n" +
59+
" \"created_at\": \"2011-01-25T18:44:36Z\",\n" +
60+
" \"email\": null,\n" +
61+
" \"events_url\": \"https://api.github.com/users/octocat/events{/privacy}\",\n" +
62+
" \"followers\": 8481,\n" +
63+
" \"followers_url\": \"https://api.github.com/users/octocat/followers\",\n" +
64+
" \"following\": 9,\n" +
65+
" \"following_url\": \"https://api.github.com/users/octocat/following{/other_user}\",\n" +
66+
" \"gists_url\": \"https://api.github.com/users/octocat/gists{/gist_id}\",\n" +
67+
" \"gravatar_id\": \"\",\n" +
68+
" \"hireable\": null,\n" +
69+
" \"html_url\": \"https://github.com/octocat\",\n" +
70+
" \"id\": 583231,\n" +
71+
" \"location\": \"San Francisco\",\n" +
72+
" \"login\": \"octocat\",\n" +
73+
" \"name\": \"The Octocat\",\n" +
74+
" \"node_id\": \"MDQ6VXNlcjU4MzIzMQ==\",\n" +
75+
" \"organizations_url\": \"https://api.github.com/users/octocat/orgs\",\n" +
76+
" \"public_gists\": 8,\n" +
77+
" \"public_repos\": 8,\n" +
78+
" \"received_events_url\": \"https://api.github.com/users/octocat/received_events\",\n" +
79+
" \"repos_url\": \"https://api.github.com/users/octocat/repos\",\n" +
80+
" \"site_admin\": false,\n" +
81+
" \"starred_url\": \"https://api.github.com/users/octocat/starred{/owner}{/repo}\",\n" +
82+
" \"subscriptions_url\": \"https://api.github.com/users/octocat/subscriptions\",\n" +
83+
" \"twitter_username\": null,\n" +
84+
" \"type\": \"User\",\n" +
85+
" \"updated_at\": \"2023-02-25T12:14:58Z\",\n" +
86+
" \"url\": \"https://api.github.com/users/octocat\"\n" +
87+
"}";
88+
// @formatter:on
89+
this.server.enqueue(new MockResponse().setBody(responseJson));
90+
91+
User user = this.gitHubUserApi.getUser();
92+
assertThat(user.getId()).isEqualTo(583231);
93+
assertThat(user.getLogin()).isEqualTo("octocat");
94+
assertThat(user.getName()).isEqualTo("The Octocat");
95+
assertThat(user.getUrl()).isEqualTo("https://api.github.com/users/octocat");
96+
}
97+
98+
@Test
99+
public void getUserWhenErrorResponseThenException() {
100+
this.server.enqueue(new MockResponse().setResponseCode(400));
101+
// @formatter:off
102+
assertThatExceptionOfType(RuntimeException.class)
103+
.isThrownBy(() -> this.gitHubUserApi.getUser());
104+
// @formatter:on
105+
}
106+
}

0 commit comments

Comments
 (0)