Skip to content

Commit 208904b

Browse files
authored
Merge pull request #980 from mrginglymus/check-patcher
Add ability to update a check run
2 parents a433bcd + 77baafa commit 208904b

File tree

78 files changed

+3080
-1185
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+3080
-1185
lines changed

src/main/java/org/kohsuke/github/GHCheckRun.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.kohsuke.github;
22

33
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import edu.umd.cs.findbugs.annotations.NonNull;
45
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
56

67
import java.io.IOException;
@@ -292,4 +293,15 @@ public static enum AnnotationLevel {
292293
NOTICE, WARNING, FAILURE
293294
}
294295

296+
/**
297+
* Updates this check run.
298+
*
299+
* @return a builder which you should customize, then call {@link GHCheckRunBuilder#create}
300+
*/
301+
@Preview
302+
@Deprecated
303+
public @NonNull GHCheckRunBuilder update() {
304+
return new GHCheckRunBuilder(owner, getId());
305+
}
306+
295307
}

src/main/java/org/kohsuke/github/GHCheckRunBuilder.java

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,30 +37,45 @@
3737
import java.util.Locale;
3838

3939
/**
40-
* Drafts a check run.
40+
* Drafts or updates a check run.
4141
*
4242
* @see GHCheckRun
4343
* @see GHRepository#createCheckRun
4444
* @see <a href="https://developer.github.com/v3/checks/runs/#create-a-check-run">documentation</a>
45+
* @see GHCheckRun#update()
46+
* @see <a href="https://developer.github.com/v3/checks/runs/#update-a-check-run">documentation</a>
4547
*/
4648
@SuppressFBWarnings(value = "URF_UNREAD_FIELD", justification = "Jackson serializes these even without a getter")
4749
@Preview
4850
@Deprecated
4951
public final class GHCheckRunBuilder {
5052

51-
private final GHRepository repo;
52-
private final Requester requester;
53+
protected final GHRepository repo;
54+
protected final Requester requester;
5355
private Output output;
5456
private List<Action> actions;
5557

56-
GHCheckRunBuilder(GHRepository repo, String name, String headSHA) {
58+
private GHCheckRunBuilder(GHRepository repo, Requester requester) {
5759
this.repo = repo;
58-
requester = repo.root.createRequest()
59-
.withPreview(Previews.ANTIOPE)
60-
.method("POST")
61-
.with("name", name)
62-
.with("head_sha", headSHA)
63-
.withUrlPath(repo.getApiTailUrl("check-runs"));
60+
this.requester = requester;
61+
}
62+
63+
GHCheckRunBuilder(GHRepository repo, String name, String headSHA) {
64+
this(repo,
65+
repo.root.createRequest()
66+
.withPreview(Previews.ANTIOPE)
67+
.method("POST")
68+
.with("name", name)
69+
.with("head_sha", headSHA)
70+
.withUrlPath(repo.getApiTailUrl("check-runs")));
71+
}
72+
73+
GHCheckRunBuilder(GHRepository repo, long checkId) {
74+
this(repo,
75+
repo.root.createRequest()
76+
.withPreview(Previews.ANTIOPE)
77+
.method("PATCH")
78+
.withUrlPath(repo.getApiTailUrl("check-runs/" + checkId)));
6479
}
6580

6681
public @NonNull GHCheckRunBuilder withDetailsURL(@CheckForNull String detailsURL) {

src/main/java/org/kohsuke/github/GHRepository.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1958,6 +1958,19 @@ public GHCommitStatus createCommitStatus(String sha1, GHCommitState state, Strin
19581958
return new GHCheckRunBuilder(this, name, headSHA);
19591959
}
19601960

1961+
/**
1962+
* Updates an existing check run.
1963+
*
1964+
* @param checkId
1965+
* the existing checkId
1966+
* @return a builder which you should customize, then call {@link GHCheckRunBuilder#create}
1967+
*/
1968+
@Preview
1969+
@Deprecated
1970+
public @NonNull GHCheckRunBuilder updateCheckRun(long checkId) {
1971+
return new GHCheckRunBuilder(this, checkId);
1972+
}
1973+
19611974
/**
19621975
* Lists repository events.
19631976
*
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package org.kohsuke.github;
2+
3+
import io.jsonwebtoken.Jwts;
4+
import org.apache.commons.io.IOUtils;
5+
6+
import java.io.IOException;
7+
import java.security.KeyFactory;
8+
import java.security.PrivateKey;
9+
import java.security.spec.PKCS8EncodedKeySpec;
10+
import java.time.Instant;
11+
import java.time.temporal.ChronoUnit;
12+
import java.util.Base64;
13+
import java.util.Date;
14+
15+
public class AbstractGHAppInstallationTest extends AbstractGitHubWireMockTest {
16+
17+
private static String TEST_APP_ID_1 = "82994";
18+
private static String TEST_APP_ID_2 = "83009";
19+
private static String TEST_APP_ID_3 = "89368";
20+
private static String PRIVATE_KEY_FILE_APP_1 = "/ghapi-test-app-1.private-key.pem";
21+
private static String PRIVATE_KEY_FILE_APP_2 = "/ghapi-test-app-2.private-key.pem";
22+
private static String PRIVATE_KEY_FILE_APP_3 = "/ghapi-test-app-3.private-key.pem";
23+
24+
private String createJwtToken(String keyFileResouceName, String appId) {
25+
try {
26+
String keyPEM = IOUtils.toString(this.getClass().getResource(keyFileResouceName), "US-ASCII")
27+
.replaceAll("(?m)^--.*", "") // remove comments from PEM to allow decoding
28+
.replaceAll("\\s", "");
29+
30+
PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(keyPEM));
31+
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpecPKCS8);
32+
33+
return Jwts.builder()
34+
.setIssuedAt(Date.from(Instant.now()))
35+
.setExpiration(Date.from(Instant.now().plus(5, ChronoUnit.MINUTES)))
36+
.setIssuer(appId)
37+
.signWith(privateKey)
38+
.compact();
39+
} catch (Exception e) {
40+
throw new RuntimeException("Error creating JWT token.", e);
41+
}
42+
}
43+
44+
private GHAppInstallation getAppInstallationWithToken(String jwtToken) throws IOException {
45+
GitHub gitHub = getGitHubBuilder().withJwtToken(jwtToken)
46+
.withEndpoint(mockGitHub.apiServer().baseUrl())
47+
.build();
48+
49+
GHAppInstallation appInstallation = gitHub.getApp()
50+
.listInstallations()
51+
.toList()
52+
.stream()
53+
.filter(it -> it.getAccount().login.equals("hub4j-test-org"))
54+
.findFirst()
55+
.get();
56+
57+
appInstallation
58+
.setRoot(getGitHubBuilder().withAppInstallationToken(appInstallation.createToken().create().getToken())
59+
.withEndpoint(mockGitHub.apiServer().baseUrl())
60+
.build());
61+
62+
return appInstallation;
63+
}
64+
65+
protected GHAppInstallation getAppInstallationWithTokenApp1() throws IOException {
66+
return getAppInstallationWithToken(createJwtToken(PRIVATE_KEY_FILE_APP_1, TEST_APP_ID_1));
67+
}
68+
69+
protected GHAppInstallation getAppInstallationWithTokenApp2() throws IOException {
70+
return getAppInstallationWithToken(createJwtToken(PRIVATE_KEY_FILE_APP_2, TEST_APP_ID_2));
71+
}
72+
73+
protected GHAppInstallation getAppInstallationWithTokenApp3() throws IOException {
74+
return getAppInstallationWithToken(createJwtToken(PRIVATE_KEY_FILE_APP_3, TEST_APP_ID_3));
75+
}
76+
77+
}

src/test/java/org/kohsuke/github/GHAppInstallationTest.java

Lines changed: 2 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,72 +1,11 @@
11
package org.kohsuke.github;
22

3-
import io.jsonwebtoken.Jwts;
4-
import org.apache.commons.io.IOUtils;
53
import org.junit.Test;
64

75
import java.io.IOException;
8-
import java.security.KeyFactory;
9-
import java.security.PrivateKey;
10-
import java.security.spec.PKCS8EncodedKeySpec;
11-
import java.time.Instant;
12-
import java.time.temporal.ChronoUnit;
13-
import java.util.*;
6+
import java.util.List;
147

15-
public class GHAppInstallationTest extends AbstractGitHubWireMockTest {
16-
17-
private static String TEST_APP_ID_1 = "82994";
18-
private static String TEST_APP_ID_2 = "83009";
19-
private static String PRIVATE_KEY_FILE_APP_1 = "/ghapi-test-app-1.private-key.pem";
20-
private static String PRIVATE_KEY_FILE_APP_2 = "/ghapi-test-app-2.private-key.pem";
21-
22-
private String createJwtToken(String keyFileResouceName, String appId) {
23-
try {
24-
String keyPEM = IOUtils.toString(this.getClass().getResource(keyFileResouceName), "US-ASCII")
25-
.replaceAll("(?m)^--.*", "") // remove comments from PEM to allow decoding
26-
.replaceAll("\\s", "");
27-
28-
PKCS8EncodedKeySpec keySpecPKCS8 = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(keyPEM));
29-
PrivateKey privateKey = KeyFactory.getInstance("RSA").generatePrivate(keySpecPKCS8);
30-
31-
return Jwts.builder()
32-
.setIssuedAt(Date.from(Instant.now()))
33-
.setExpiration(Date.from(Instant.now().plus(5, ChronoUnit.MINUTES)))
34-
.setIssuer(appId)
35-
.signWith(privateKey)
36-
.compact();
37-
} catch (Exception e) {
38-
throw new RuntimeException("Error creating JWT token.", e);
39-
}
40-
}
41-
42-
private GHAppInstallation getAppInstallationWithToken(String jwtToken) throws IOException {
43-
GitHub gitHub = getGitHubBuilder().withJwtToken(jwtToken)
44-
.withEndpoint(mockGitHub.apiServer().baseUrl())
45-
.build();
46-
47-
GHAppInstallation appInstallation = gitHub.getApp()
48-
.listInstallations()
49-
.toList()
50-
.stream()
51-
.filter(it -> it.getAccount().login.equals("hub4j-test-org"))
52-
.findFirst()
53-
.get();
54-
55-
appInstallation
56-
.setRoot(getGitHubBuilder().withAppInstallationToken(appInstallation.createToken().create().getToken())
57-
.withEndpoint(mockGitHub.apiServer().baseUrl())
58-
.build());
59-
60-
return appInstallation;
61-
}
62-
63-
private GHAppInstallation getAppInstallationWithTokenApp1() throws IOException {
64-
return getAppInstallationWithToken(createJwtToken(PRIVATE_KEY_FILE_APP_1, TEST_APP_ID_1));
65-
}
66-
67-
private GHAppInstallation getAppInstallationWithTokenApp2() throws IOException {
68-
return getAppInstallationWithToken(createJwtToken(PRIVATE_KEY_FILE_APP_2, TEST_APP_ID_2));
69-
}
8+
public class GHAppInstallationTest extends AbstractGHAppInstallationTest {
709

7110
@Test
7211
public void testListRepositoriesTwoRepos() throws IOException {

src/test/java/org/kohsuke/github/GHCheckRunBuilderTest.java

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,22 @@
2626

2727
import org.junit.Test;
2828

29+
import java.io.IOException;
2930
import java.util.Date;
3031

3132
import static org.hamcrest.Matchers.containsString;
3233

3334
@SuppressWarnings("deprecation") // preview
34-
public class GHCheckRunBuilderTest extends AbstractGitHubWireMockTest {
35+
public class GHCheckRunBuilderTest extends AbstractGHAppInstallationTest {
36+
37+
protected GitHub getInstallationGithub() throws IOException {
38+
return getAppInstallationWithTokenApp3().getRoot();
39+
}
3540

3641
@Test
3742
public void createCheckRun() throws Exception {
38-
GHCheckRun checkRun = gitHub.getRepository("jglick/github-api-test")
39-
.createCheckRun("foo", "4a929d464a2fae7ee899ce603250f7dab304bc4b")
43+
GHCheckRun checkRun = getInstallationGithub().getRepository("hub4j-test-org/test-checks")
44+
.createCheckRun("foo", "89a9ae301e35e667756034fdc933b1fc94f63fc1")
4045
.withStatus(GHCheckRun.Status.COMPLETED)
4146
.withConclusion(GHCheckRun.Conclusion.SUCCESS)
4247
.withDetailsURL("http://nowhere.net/stuff")
@@ -55,7 +60,7 @@ public void createCheckRun() throws Exception {
5560
.create();
5661
assertEquals("completed", checkRun.getStatus());
5762
assertEquals(1, checkRun.getOutput().getAnnotationsCount());
58-
assertEquals(546384586, checkRun.getId());
63+
assertEquals(1424883286, checkRun.getId());
5964
}
6065

6166
@Test
@@ -65,46 +70,46 @@ public void createCheckRunManyAnnotations() throws Exception {
6570
output.add(
6671
new GHCheckRunBuilder.Annotation("stuff.txt", 1, GHCheckRun.AnnotationLevel.NOTICE, "hello #" + i));
6772
}
68-
GHCheckRun checkRun = gitHub.getRepository("jglick/github-api-test")
69-
.createCheckRun("big", "4a929d464a2fae7ee899ce603250f7dab304bc4b")
73+
GHCheckRun checkRun = getInstallationGithub().getRepository("hub4j-test-org/test-checks")
74+
.createCheckRun("big", "89a9ae301e35e667756034fdc933b1fc94f63fc1")
7075
.withConclusion(GHCheckRun.Conclusion.SUCCESS)
7176
.add(output)
7277
.create();
7378
assertEquals("completed", checkRun.getStatus());
7479
assertEquals("Big Run", checkRun.getOutput().getTitle());
7580
assertEquals("Lots of stuff here »", checkRun.getOutput().getSummary());
7681
assertEquals(101, checkRun.getOutput().getAnnotationsCount());
77-
assertEquals(546384622, checkRun.getId());
82+
assertEquals(1424883599, checkRun.getId());
7883
}
7984

8085
@Test
8186
public void createCheckRunNoAnnotations() throws Exception {
82-
GHCheckRun checkRun = gitHub.getRepository("jglick/github-api-test")
83-
.createCheckRun("quick", "4a929d464a2fae7ee899ce603250f7dab304bc4b")
87+
GHCheckRun checkRun = getInstallationGithub().getRepository("hub4j-test-org/test-checks")
88+
.createCheckRun("quick", "89a9ae301e35e667756034fdc933b1fc94f63fc1")
8489
.withConclusion(GHCheckRun.Conclusion.NEUTRAL)
8590
.add(new GHCheckRunBuilder.Output("Quick note", "nothing more to see here"))
8691
.create();
8792
assertEquals("completed", checkRun.getStatus());
8893
assertEquals(0, checkRun.getOutput().getAnnotationsCount());
89-
assertEquals(546384705, checkRun.getId());
94+
assertEquals(1424883957, checkRun.getId());
9095
}
9196

9297
@Test
9398
public void createPendingCheckRun() throws Exception {
94-
GHCheckRun checkRun = gitHub.getRepository("jglick/github-api-test")
95-
.createCheckRun("outstanding", "4a929d464a2fae7ee899ce603250f7dab304bc4b")
99+
GHCheckRun checkRun = getInstallationGithub().getRepository("hub4j-test-org/test-checks")
100+
.createCheckRun("outstanding", "89a9ae301e35e667756034fdc933b1fc94f63fc1")
96101
.withStatus(GHCheckRun.Status.IN_PROGRESS)
97102
.create();
98103
assertEquals("in_progress", checkRun.getStatus());
99104
assertNull(checkRun.getConclusion());
100-
assertEquals(546469053, checkRun.getId());
105+
assertEquals(1424883451, checkRun.getId());
101106
}
102107

103108
@Test
104109
public void createCheckRunErrMissingConclusion() throws Exception {
105110
try {
106-
gitHub.getRepository("jglick/github-api-test")
107-
.createCheckRun("outstanding", "4a929d464a2fae7ee899ce603250f7dab304bc4b")
111+
getInstallationGithub().getRepository("hub4j-test-org/test-checks")
112+
.createCheckRun("outstanding", "89a9ae301e35e667756034fdc933b1fc94f63fc1")
108113
.withStatus(GHCheckRun.Status.COMPLETED)
109114
.create();
110115
fail("should have been rejected");
@@ -114,4 +119,26 @@ public void createCheckRunErrMissingConclusion() throws Exception {
114119
}
115120
}
116121

122+
@Test
123+
public void updateCheckRun() throws Exception {
124+
GHCheckRun checkRun = getInstallationGithub().getRepository("hub4j-test-org/test-checks")
125+
.createCheckRun("foo", "89a9ae301e35e667756034fdc933b1fc94f63fc1")
126+
.withStatus(GHCheckRun.Status.IN_PROGRESS)
127+
.withStartedAt(new Date(999_999_000))
128+
.add(new GHCheckRunBuilder.Output("Some Title", "what happened…")
129+
.add(new GHCheckRunBuilder.Annotation("stuff.txt",
130+
1,
131+
GHCheckRun.AnnotationLevel.NOTICE,
132+
"hello to you too").withTitle("Look here")))
133+
.create();
134+
GHCheckRun updated = checkRun.update()
135+
.withStatus(GHCheckRun.Status.COMPLETED)
136+
.withConclusion(GHCheckRun.Conclusion.SUCCESS)
137+
.withCompletedAt(new Date(999_999_999))
138+
.create();
139+
assertEquals(updated.getStartedAt(), new Date(999_999_000));
140+
assertEquals(updated.getName(), "foo");
141+
assertEquals(1, checkRun.getOutput().getAnnotationsCount());
142+
}
143+
117144
}

0 commit comments

Comments
 (0)