Skip to content

Commit dd55e8a

Browse files
authored
Merge pull request #753 from jglick/createCheckRun
GHRepository.createCheckRun
2 parents 8d47c72 + 3ab9381 commit dd55e8a

File tree

29 files changed

+1889
-4
lines changed

29 files changed

+1889
-4
lines changed

pom.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,10 @@
281281
<plugin>
282282
<artifactId>maven-surefire-plugin</artifactId>
283283
<version>2.22.2</version>
284+
<configuration>
285+
<!-- SUREFIRE-1226 workaround -->
286+
<trimStackTrace>false</trimStackTrace>
287+
</configuration>
284288
</plugin>
285289
<plugin>
286290
<groupId>org.codehaus.mojo</groupId>

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,24 +51,33 @@ GHPullRequest[] wrap() {
5151
}
5252

5353
/**
54-
* Gets status of the check run. It can be one of "queue", "in_progress", or "completed"
54+
* Gets status of the check run.
5555
*
5656
* @return Status of the check run
57+
* @see Status
5758
*/
5859
public String getStatus() {
5960
return status;
6061
}
6162

63+
public static enum Status {
64+
QUEUED, IN_PROGRESS, COMPLETED
65+
}
66+
6267
/**
63-
* Gets conclusion of a completed check run. It can be one of "success", "failure", "neutral", "cancelled",
64-
* "time_out", or "action_required".
68+
* Gets conclusion of a completed check run.
6569
*
6670
* @return Status of the check run
71+
* @see Conclusion
6772
*/
6873
public String getConclusion() {
6974
return conclusion;
7075
}
7176

77+
public static enum Conclusion {
78+
SUCCESS, FAILURE, NEUTRAL, CANCELLED, TIMED_OUT, ACTION_REQUIRED
79+
}
80+
7281
/**
7382
* Gets the custom name of this check run.
7483
*
@@ -243,4 +252,8 @@ public URL getAnnotationsUrl() {
243252
}
244253
}
245254

255+
public static enum AnnotationLevel {
256+
NOTICE, WARNING, FAILURE
257+
}
258+
246259
}
Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright 2020 CloudBees, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
25+
package org.kohsuke.github;
26+
27+
import com.fasterxml.jackson.annotation.JsonInclude;
28+
import edu.umd.cs.findbugs.annotations.CheckForNull;
29+
import edu.umd.cs.findbugs.annotations.NonNull;
30+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
31+
32+
import java.io.IOException;
33+
import java.util.Collections;
34+
import java.util.Date;
35+
import java.util.LinkedList;
36+
import java.util.List;
37+
import java.util.Locale;
38+
39+
/**
40+
* Drafts a check run.
41+
*
42+
* @see GHCheckRun
43+
* @see GHRepository#createCheckRun
44+
* @see <a href="https://developer.github.com/v3/checks/runs/#create-a-check-run">documentation</a>
45+
*/
46+
@SuppressFBWarnings(value = "URF_UNREAD_FIELD", justification = "Jackson serializes these even without a getter")
47+
@Preview
48+
@Deprecated
49+
public final class GHCheckRunBuilder {
50+
51+
private final GHRepository repo;
52+
private final Requester requester;
53+
private Output output;
54+
private List<Action> actions;
55+
56+
GHCheckRunBuilder(GHRepository repo, String name, String headSHA) {
57+
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"));
64+
}
65+
66+
public @NonNull GHCheckRunBuilder withDetailsURL(@CheckForNull String detailsURL) {
67+
requester.with("details_url", detailsURL);
68+
return this;
69+
}
70+
71+
public @NonNull GHCheckRunBuilder withExternalID(@CheckForNull String externalID) {
72+
requester.with("external_id", externalID);
73+
return this;
74+
}
75+
76+
public @NonNull GHCheckRunBuilder withStatus(@CheckForNull GHCheckRun.Status status) {
77+
if (status != null) {
78+
// Do *not* use the overload taking Enum, as that s/_/-/g which would be wrong here.
79+
requester.with("status", status.toString().toLowerCase(Locale.ROOT));
80+
}
81+
return this;
82+
}
83+
84+
public @NonNull GHCheckRunBuilder withConclusion(@CheckForNull GHCheckRun.Conclusion conclusion) {
85+
if (conclusion != null) {
86+
requester.with("conclusion", conclusion.toString().toLowerCase(Locale.ROOT));
87+
}
88+
return this;
89+
}
90+
91+
public @NonNull GHCheckRunBuilder withStartedAt(@CheckForNull Date startedAt) {
92+
if (startedAt != null) {
93+
requester.with("started_at", GitHubClient.printDate(startedAt));
94+
}
95+
return this;
96+
}
97+
98+
public @NonNull GHCheckRunBuilder withCompletedAt(@CheckForNull Date completedAt) {
99+
if (completedAt != null) {
100+
requester.with("completed_at", GitHubClient.printDate(completedAt));
101+
}
102+
return this;
103+
}
104+
105+
public @NonNull GHCheckRunBuilder add(@NonNull Output output) {
106+
if (this.output != null) {
107+
throw new IllegalStateException("cannot add Output twice");
108+
}
109+
this.output = output;
110+
return this;
111+
}
112+
113+
public @NonNull GHCheckRunBuilder add(@NonNull Action action) {
114+
if (actions == null) {
115+
actions = new LinkedList<>();
116+
}
117+
actions.add(action);
118+
return this;
119+
}
120+
121+
private static final int MAX_ANNOTATIONS = 50;
122+
/**
123+
* Actually creates the check run. (If more than fifty annotations were requested, this is done in batches.)
124+
*
125+
* @return the resulting run
126+
* @throws IOException
127+
* for the usual reasons
128+
*/
129+
public @NonNull GHCheckRun create() throws IOException {
130+
List<Annotation> extraAnnotations;
131+
if (output != null && output.annotations != null && output.annotations.size() > MAX_ANNOTATIONS) {
132+
extraAnnotations = output.annotations.subList(MAX_ANNOTATIONS, output.annotations.size());
133+
output.annotations = output.annotations.subList(0, MAX_ANNOTATIONS);
134+
} else {
135+
extraAnnotations = Collections.emptyList();
136+
}
137+
GHCheckRun run = requester.with("output", output).with("actions", actions).fetch(GHCheckRun.class).wrap(repo);
138+
while (!extraAnnotations.isEmpty()) {
139+
Output output2 = new Output(output.title, output.summary);
140+
int i = Math.min(extraAnnotations.size(), MAX_ANNOTATIONS);
141+
output2.annotations = extraAnnotations.subList(0, i);
142+
extraAnnotations = extraAnnotations.subList(i, extraAnnotations.size());
143+
run = repo.root.createRequest()
144+
.withPreview(Previews.ANTIOPE)
145+
.method("PATCH")
146+
.with("output", output2)
147+
.withUrlPath(repo.getApiTailUrl("check-runs/" + run.id))
148+
.fetch(GHCheckRun.class)
149+
.wrap(repo);
150+
}
151+
return run;
152+
}
153+
154+
/**
155+
* @see <a href="https://developer.github.com/v3/checks/runs/#output-object">documentation</a>
156+
*/
157+
@JsonInclude(JsonInclude.Include.NON_NULL)
158+
public static final class Output {
159+
160+
private final String title;
161+
private final String summary;
162+
private String text;
163+
private List<Annotation> annotations;
164+
private List<Image> images;
165+
166+
public Output(@NonNull String title, @NonNull String summary) {
167+
this.title = title;
168+
this.summary = summary;
169+
}
170+
171+
public @NonNull Output withText(@CheckForNull String text) {
172+
this.text = text;
173+
return this;
174+
}
175+
176+
public @NonNull Output add(@NonNull Annotation annotation) {
177+
if (annotations == null) {
178+
annotations = new LinkedList<>();
179+
}
180+
annotations.add(annotation);
181+
return this;
182+
}
183+
184+
public @NonNull Output add(@NonNull Image image) {
185+
if (images == null) {
186+
images = new LinkedList<>();
187+
}
188+
images.add(image);
189+
return this;
190+
}
191+
192+
}
193+
194+
/**
195+
* @see <a href="https://developer.github.com/v3/checks/runs/#annotations-object">documentation</a>
196+
*/
197+
@JsonInclude(JsonInclude.Include.NON_NULL)
198+
public static final class Annotation {
199+
200+
private final String path;
201+
private final int start_line;
202+
private final int end_line;
203+
private final String annotation_level;
204+
private final String message;
205+
private Integer start_column;
206+
private Integer end_column;
207+
private String title;
208+
private String raw_details;
209+
210+
public Annotation(@NonNull String path,
211+
int line,
212+
@NonNull GHCheckRun.AnnotationLevel annotationLevel,
213+
@NonNull String message) {
214+
this(path, line, line, annotationLevel, message);
215+
}
216+
217+
public Annotation(@NonNull String path,
218+
int startLine,
219+
int endLine,
220+
@NonNull GHCheckRun.AnnotationLevel annotationLevel,
221+
@NonNull String message) {
222+
this.path = path;
223+
start_line = startLine;
224+
end_line = endLine;
225+
annotation_level = annotationLevel.toString().toLowerCase(Locale.ROOT);
226+
this.message = message;
227+
}
228+
229+
public @NonNull Annotation withStartColumn(@CheckForNull Integer startColumn) {
230+
start_column = startColumn;
231+
return this;
232+
}
233+
234+
public @NonNull Annotation withEndColumn(@CheckForNull Integer endColumn) {
235+
end_column = endColumn;
236+
return this;
237+
}
238+
239+
public @NonNull Annotation withTitle(@CheckForNull String title) {
240+
this.title = title;
241+
return this;
242+
}
243+
244+
public @NonNull Annotation withRawDetails(@CheckForNull String rawDetails) {
245+
raw_details = rawDetails;
246+
return this;
247+
}
248+
249+
}
250+
251+
/**
252+
* @see <a href="https://developer.github.com/v3/checks/runs/#images-object">documentation</a>
253+
*/
254+
@JsonInclude(JsonInclude.Include.NON_NULL)
255+
public static final class Image {
256+
257+
private final String alt;
258+
private final String image_url;
259+
private String caption;
260+
261+
public Image(@NonNull String alt, @NonNull String imageURL) {
262+
this.alt = alt;
263+
image_url = imageURL;
264+
}
265+
266+
public @NonNull Image withCaption(@CheckForNull String caption) {
267+
this.caption = caption;
268+
return this;
269+
}
270+
271+
}
272+
273+
/**
274+
* @see <a href="https://developer.github.com/v3/checks/runs/#actions-object">documentation</a>
275+
*/
276+
@JsonInclude(JsonInclude.Include.NON_NULL)
277+
public static final class Action {
278+
279+
private final String label;
280+
private final String description;
281+
private final String identifier;
282+
283+
public Action(@NonNull String label, @NonNull String description, @NonNull String identifier) {
284+
this.label = label;
285+
this.description = description;
286+
this.identifier = identifier;
287+
}
288+
289+
}
290+
291+
}

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1849,6 +1849,21 @@ public GHCommitStatus createCommitStatus(String sha1, GHCommitState state, Strin
18491849
return createCommitStatus(sha1, state, targetUrl, description, null);
18501850
}
18511851

1852+
/**
1853+
* Creates a check run for a commit.
1854+
*
1855+
* @param name
1856+
* an identifier for the run
1857+
* @param headSHA
1858+
* the commit hash
1859+
* @return a builder which you should customize, then call {@link GHCheckRunBuilder#create}
1860+
*/
1861+
@Preview
1862+
@Deprecated
1863+
public @NonNull GHCheckRunBuilder createCheckRun(@NonNull String name, @NonNull String headSHA) {
1864+
return new GHCheckRunBuilder(this, name, headSHA);
1865+
}
1866+
18521867
/**
18531868
* Lists repository events.
18541869
*

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ protected void requireProxy(String reason) {
134134

135135
protected void verifyAuthenticated(GitHub instance) {
136136
assertThat(
137-
"GitHub connection believes it is anonymous. Make sure you set GITHUB_OAUTH or both GITHUB_USER and GITHUB_PASSWORD environment variables",
137+
"GitHub connection believes it is anonymous. Make sure you set GITHUB_OAUTH or both GITHUB_LOGIN and GITHUB_PASSWORD environment variables",
138138
instance.isAnonymous(),
139139
Matchers.is(false));
140140
}

0 commit comments

Comments
 (0)