Skip to content

Commit 8de2f25

Browse files
authored
github: use Github token, when provided (#654)
1 parent 34caac0 commit 8de2f25

File tree

6 files changed

+37
-14
lines changed

6 files changed

+37
-14
lines changed

src/main/java/me/itzg/helpers/github/DownloadLatestAssetCommand.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import picocli.CommandLine.Command;
1414
import picocli.CommandLine.Option;
1515
import picocli.CommandLine.Parameters;
16+
import picocli.CommandLine.ParentCommand;
1617

1718
@Command(name = "download-latest-asset",
1819
description = "From the latest release, downloads the first matching asset, and outputs the downloaded filename"
@@ -29,8 +30,8 @@ public class DownloadLatestAssetCommand implements Callable<Integer> {
2930
@Option(names = "--output-directory", defaultValue = ".")
3031
Path outputDirectory;
3132

32-
@Option(names = "--api-base-url", defaultValue = GithubClient.DEFAULT_API_BASE_URL)
33-
String apiBaseUrl;
33+
@ParentCommand
34+
GithubCommands parent;
3435

3536
@Parameters(arity = "1", paramLabel = "org/repo")
3637
public void setOrgRepo(String input) {
@@ -50,7 +51,7 @@ public Integer call() throws Exception {
5051

5152
try (SharedFetch sharedFetch = Fetch.sharedFetch("github download-latest-asset", sharedFetchArgs.options())) {
5253

53-
final GithubClient client = new GithubClient(sharedFetch, apiBaseUrl);
54+
final GithubClient client = new GithubClient(sharedFetch, parent.getApiBaseUrl(), parent.getToken());
5455
final Path result = client.downloadLatestAsset(organization, repo, namePattern, outputDirectory)
5556
.block();
5657

src/main/java/me/itzg/helpers/github/GithubClient.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,17 +28,20 @@ public class GithubClient {
2828

2929
private final SharedFetch sharedFetch;
3030
private final UriBuilder uriBuilder;
31+
private final String token;
3132

32-
public GithubClient(SharedFetch sharedFetch, String apiBaseUrl) {
33+
public GithubClient(SharedFetch sharedFetch, String apiBaseUrl, @Nullable String token) {
3334
this.sharedFetch = sharedFetch;
3435
this.uriBuilder = UriBuilder.withBaseUrl(apiBaseUrl);
36+
this.token = token;
3537
}
3638

3739
public Mono<Path> downloadLatestAsset(String org, String repo, @Nullable Pattern namePattern, Path outputDirectory) {
3840
return sharedFetch.fetch(
3941
uriBuilder.resolve("/repos/{org}/{repo}/releases/latest", org, repo)
4042
)
4143
.acceptContentTypes(Collections.singletonList("application/vnd.github+json"))
44+
.withAuthorization("Bearer", token)
4245
.toObject(Release.class)
4346
.assemble()
4447
.onErrorResume(throwable -> {
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,22 @@
11
package me.itzg.helpers.github;
22

3+
import lombok.Getter;
34
import picocli.CommandLine.Command;
5+
import picocli.CommandLine.Option;
46

57
@Command(name = "github",
68
subcommands = {
79
DownloadLatestAssetCommand.class
810
}
911
)
12+
@Getter
1013
public class GithubCommands {
1114

15+
@Option(names = "--api-base-url", defaultValue = GithubClient.DEFAULT_API_BASE_URL)
16+
String apiBaseUrl;
17+
18+
@Option(names = "--token", defaultValue = "${env:GH_TOKEN}",
19+
description = "An access token for GitHub to elevate rate limit vs anonymous access"
20+
)
21+
String token;
1222
}

src/main/java/me/itzg/helpers/http/FetchBuilderBase.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import me.itzg.helpers.errors.GenericException;
3030
import me.itzg.helpers.http.SharedFetch.Options;
3131
import me.itzg.helpers.json.ObjectMappers;
32+
import org.apache.commons.lang3.StringUtils;
3233
import org.slf4j.Logger;
3334
import reactor.core.publisher.Mono;
3435
import reactor.netty.ByteBufMono;
@@ -172,6 +173,15 @@ public SELF header(String name, String value) {
172173
return self();
173174
}
174175

176+
public SELF withAuthorization(String authorizationType, String credentials) {
177+
if (StringUtils.isNotBlank(authorizationType) && StringUtils.isNotBlank(credentials)) {
178+
return header(AUTHORIZATION.toString(), authorizationType + " " + credentials);
179+
}
180+
else {
181+
return self();
182+
}
183+
}
184+
175185
/**
176186
* Helps with fluent sub-type builder pattern
177187
*/

src/main/java/me/itzg/helpers/http/SharedFetch.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,12 +118,6 @@ public FetchBuilderBase<?> fetch(URI uri) {
118118
return new FetchBuilderBase<>(uri, this);
119119
}
120120

121-
@SuppressWarnings("unused")
122-
public SharedFetch addHeader(String name, String value) {
123-
headers.put(name, value);
124-
return this;
125-
}
126-
127121
@Override
128122
public void close() {
129123
}

src/test/java/me/itzg/helpers/github/DownloadLatestAssetCommandTest.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ class DownloadLatestAssetCommandTest {
3131
.configureStaticDsl(true)
3232
.build();
3333

34+
private final RandomStringUtils randomStringUtils = RandomStringUtils.insecure();
35+
3436
@Test
3537
void usingNamePattern(@TempDir Path tempDir, WireMockRuntimeInfo wmInfo) {
36-
final String filename = RandomStringUtils.randomAlphabetic(10) + ".jar";
37-
final String fileContent = RandomStringUtils.randomAlphabetic(20);
38+
final String filename = randomStringUtils.nextAlphabetic(10) + ".jar";
39+
final String fileContent = randomStringUtils.nextAlphabetic(20);
3840

3941
stubFor(get("/repos/org/repo/releases/latest")
4042
.willReturn(ok()
@@ -58,9 +60,10 @@ void usingNamePattern(@TempDir Path tempDir, WireMockRuntimeInfo wmInfo) {
5860
)
5961
);
6062

61-
final int exitCode = new CommandLine(new DownloadLatestAssetCommand())
63+
final int exitCode = new CommandLine(new GithubCommands())
6264
.execute(
6365
"--api-base-url", wmInfo.getHttpBaseUrl(),
66+
"download-latest-asset",
6467
"--name-pattern", "app-.+?(?<!-sources)\\.jar",
6568
"--output-directory", tempDir.toString(),
6669
"org/repo"
@@ -94,6 +97,7 @@ void rateLimitExceeded(@TempDir Path tempDir, WireMockRuntimeInfo wmInfo) {
9497
final Instant expectedDelayUntil = Instant.now()
9598
.plusSeconds(1);
9699

100+
//noinspection UastIncorrectHttpHeaderInspection custom declared by Github
97101
stubFor(get(anyUrl())
98102
.willReturn(forbidden()
99103
.withHeader("x-ratelimit-reset", String.valueOf(expectedDelayUntil.getEpochSecond()))
@@ -102,10 +106,11 @@ void rateLimitExceeded(@TempDir Path tempDir, WireMockRuntimeInfo wmInfo) {
102106

103107
final LatchingExecutionExceptionHandler executionExceptionHandler = new LatchingExecutionExceptionHandler();
104108

105-
final int exitCode = new CommandLine(new DownloadLatestAssetCommand())
109+
final int exitCode = new CommandLine(new GithubCommands())
106110
.setExecutionExceptionHandler(executionExceptionHandler)
107111
.execute(
108112
"--api-base-url", wmInfo.getHttpBaseUrl(),
113+
"download-latest-asset",
109114
"--output-directory", tempDir.toString(),
110115
"org/repo"
111116
);

0 commit comments

Comments
 (0)