Skip to content

Commit d586a93

Browse files
committed
Merge pull request jenkinsci#272 from jenkinsci/master
Merge jenkinsci into janinko
2 parents f64f385 + 17dca15 commit d586a93

37 files changed

+948
-244
lines changed

README.md

+7
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,13 @@ If you want to manually build the job, in the job setting check ``This build is
8686

8787
### Updates
8888

89+
#### -> 1.21
90+
* Move all commenting logic out into extensions.
91+
92+
#### -> 1.20.1
93+
* Null Pointer fix for trigger.
94+
* Added clarity to error message when access is forbidden.
95+
8996
#### -> 1.20
9097
* PullRequestMerger now notifies the taskListener of failures.
9198
* AutoCloseFailedPullRequest has been extracted from the published URL check.

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
<artifactId>ghprb</artifactId>
1212
<name>GitHub Pull Request Builder</name>
13-
<version>1.21-SNAPSHOT</version>
13+
<version>1.22-SNAPSHOT</version>
1414
<packaging>hpi</packaging>
1515

1616
<url>https://wiki.jenkins-ci.org/display/JENKINS/GitHub+pull+request+builder+plugin</url>

src/main/java/org/jenkinsci/plugins/ghprb/Ghprb.java

+103
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,19 @@
55
import hudson.Util;
66
import hudson.model.AbstractBuild;
77
import hudson.model.AbstractProject;
8+
import hudson.model.Result;
9+
import hudson.model.Saveable;
10+
import hudson.util.DescribableList;
811
import hudson.util.LogTaskListener;
912

13+
import org.apache.commons.collections.Predicate;
14+
import org.apache.commons.collections.PredicateUtils;
15+
import org.apache.commons.collections.functors.InstanceofPredicate;
16+
import org.jenkinsci.plugins.ghprb.extensions.GhprbExtension;
17+
import org.jenkinsci.plugins.ghprb.extensions.GhprbExtensionDescriptor;
18+
import org.jenkinsci.plugins.ghprb.extensions.GhprbGlobalExtension;
19+
import org.jenkinsci.plugins.ghprb.extensions.GhprbProjectExtension;
20+
import org.kohsuke.github.GHCommitState;
1021
import org.kohsuke.github.GHUser;
1122

1223
import java.util.*;
@@ -178,5 +189,97 @@ public static String replaceMacros(AbstractBuild<?, ?> build, String inputString
178189
return returnString;
179190

180191
}
192+
193+
public static GHCommitState getState(AbstractBuild<?, ?> build) {
194+
195+
GHCommitState state;
196+
if (build.getResult() == Result.SUCCESS) {
197+
state = GHCommitState.SUCCESS;
198+
} else if (build.getResult() == Result.UNSTABLE) {
199+
state = GhprbTrigger.getDscp().getUnstableAs();
200+
} else {
201+
state = GHCommitState.FAILURE;
202+
}
203+
return state;
204+
}
205+
206+
public static Set<String> createSet(String list) {
207+
String listString = list == null ? "" : list;
208+
List<String> listList = Arrays.asList(listString.split("\\s+"));
209+
Set<String> listSet = new HashSet<String>(listList);
210+
listSet.remove("");
211+
return listSet;
212+
}
213+
214+
public static GhprbTrigger extractTrigger(AbstractBuild<?, ?> build) {
215+
return extractTrigger(build.getProject());
216+
}
217+
218+
public static GhprbTrigger extractTrigger(AbstractProject<?, ?> p) {
219+
GhprbTrigger trigger = p.getTrigger(GhprbTrigger.class);
220+
if (trigger == null || (!(trigger instanceof GhprbTrigger))) {
221+
return null;
222+
}
223+
return trigger;
224+
}
225+
226+
private static List<Predicate> createPredicate(Class<?> ...types) {
227+
List<Predicate> predicates = new ArrayList<Predicate>(types.length);
228+
for (Class<?> type : types) {
229+
predicates.add(InstanceofPredicate.getInstance(type));
230+
}
231+
return predicates;
232+
}
233+
234+
public static void filterList(DescribableList<GhprbExtension, GhprbExtensionDescriptor> descriptors, Predicate predicate) {
235+
for (GhprbExtension descriptor : descriptors) {
236+
if (!predicate.evaluate(descriptor)) {
237+
descriptors.remove(descriptor);
238+
}
239+
}
240+
}
241+
242+
private static DescribableList<GhprbExtension, GhprbExtensionDescriptor> copyExtensions(DescribableList<GhprbExtension, GhprbExtensionDescriptor> ...extensionsList){
243+
DescribableList<GhprbExtension, GhprbExtensionDescriptor> copiedList = new DescribableList<GhprbExtension, GhprbExtensionDescriptor>(Saveable.NOOP);
244+
for (DescribableList<GhprbExtension, GhprbExtensionDescriptor> extensions: extensionsList) {
245+
copiedList.addAll(extensions);
246+
}
247+
return copiedList;
248+
}
249+
250+
@SuppressWarnings("unchecked")
251+
public static DescribableList<GhprbExtension, GhprbExtensionDescriptor> getJobExtensions(GhprbTrigger trigger, Class<?> ...types) {
252+
253+
// First get all global extensions
254+
DescribableList<GhprbExtension, GhprbExtensionDescriptor> copied = copyExtensions(trigger.getDescriptor().getExtensions());
255+
256+
// Remove extensions that are specified by job
257+
filterList(copied, PredicateUtils.notPredicate(InstanceofPredicate.getInstance(GhprbProjectExtension.class)));
258+
259+
// Then get the rest of the extensions from the job
260+
copied = copyExtensions(copied, trigger.getExtensions());
261+
262+
// Filter extensions by desired interface
263+
filterList(copied, PredicateUtils.anyPredicate(createPredicate(types)));
264+
return copied;
265+
}
266+
267+
public static DescribableList<GhprbExtension, GhprbExtensionDescriptor> matchesAll(DescribableList<GhprbExtension, GhprbExtensionDescriptor> extensions, Class<?> ...types) {
268+
Predicate predicate = PredicateUtils.allPredicate(createPredicate(types));
269+
DescribableList<GhprbExtension, GhprbExtensionDescriptor> copyExtensions = new DescribableList<GhprbExtension, GhprbExtensionDescriptor>(Saveable.NOOP);
270+
271+
copyExtensions.addAll(extensions);
272+
filterList(copyExtensions, predicate);
273+
return copyExtensions;
274+
}
275+
276+
public static DescribableList<GhprbExtension, GhprbExtensionDescriptor> matchesSome(DescribableList<GhprbExtension, GhprbExtensionDescriptor> extensions, Class<?> ...types) {
277+
Predicate predicate = PredicateUtils.anyPredicate(createPredicate(types));
278+
DescribableList<GhprbExtension, GhprbExtensionDescriptor> copyExtensions = new DescribableList<GhprbExtension, GhprbExtensionDescriptor>(Saveable.NOOP);
279+
280+
copyExtensions.addAll(extensions);
281+
filterList(copyExtensions, predicate);
282+
return copyExtensions;
283+
}
181284

182285
}

src/main/java/org/jenkinsci/plugins/ghprb/GhprbBuildListener.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,6 @@ public void onCompleted(AbstractBuild<?, ?> build, TaskListener listener) {
2929
}
3030

3131
private static Optional<GhprbTrigger> findTrigger(AbstractBuild<?, ?> build) {
32-
return Optional.fromNullable(GhprbTrigger.extractTrigger(build.getProject()));
32+
return Optional.fromNullable(Ghprb.extractTrigger(build));
3333
}
3434
}

src/main/java/org/jenkinsci/plugins/ghprb/GhprbBuilds.java

+9-98
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,19 @@
22

33
import hudson.model.AbstractBuild;
44
import hudson.model.Cause;
5-
import hudson.model.Result;
65
import hudson.model.TaskListener;
76
import hudson.model.queue.QueueTaskFuture;
87
import hudson.plugins.git.util.BuildData;
98

10-
import org.apache.commons.io.FileUtils;
11-
12-
import org.jenkinsci.plugins.ghprb.manager.GhprbBuildManager;
13-
import org.jenkinsci.plugins.ghprb.manager.configuration.JobConfiguration;
14-
import org.jenkinsci.plugins.ghprb.manager.factory.GhprbBuildManagerFactoryUtil;
15-
9+
import org.jenkinsci.plugins.ghprb.extensions.GhprbCommentAppender;
10+
import org.jenkinsci.plugins.ghprb.extensions.GhprbExtension;
1611
import org.kohsuke.github.GHCommitState;
1712
import org.kohsuke.github.GHIssueState;
1813
import org.kohsuke.github.GHPullRequest;
1914
import org.kohsuke.github.GHUser;
2015

21-
import java.io.File;
2216
import java.io.IOException;
2317
import java.io.PrintStream;
24-
import java.util.List;
2518
import java.util.logging.Level;
2619
import java.util.logging.Logger;
2720

@@ -123,20 +116,10 @@ public void onCompleted(AbstractBuild<?, ?> build, TaskListener listener) {
123116
}
124117

125118
GHCommitState state;
126-
if (build.getResult() == Result.SUCCESS) {
127-
state = GHCommitState.SUCCESS;
128-
} else if (build.getResult() == Result.UNSTABLE) {
129-
state = GHCommitState.valueOf(GhprbTrigger.getDscp().getUnstableAs());
130-
} else {
131-
state = GHCommitState.FAILURE;
132-
}
119+
state = Ghprb.getState(build);
133120
repo.createCommitStatus(build, state, "Build finished.", c.getPullID(), trigger.getCommitStatusContext(), listener.getLogger());
134121

135-
136-
String publishedURL = GhprbTrigger.getDscp().getPublishedURL();
137-
if (publishedURL != null && !publishedURL.isEmpty()) {
138-
buildResultMessage(build, listener, state, c);
139-
}
122+
buildResultMessage(build, listener, state, c);
140123
// close failed pull request automatically
141124
if (state == GHCommitState.FAILURE && trigger.isAutoCloseFailedPullRequests()) {
142125
closeFailedRequest(listener, c);
@@ -158,89 +141,17 @@ private void closeFailedRequest(TaskListener listener, GhprbCause c) {
158141

159142
private void buildResultMessage(AbstractBuild<?, ?> build, TaskListener listener, GHCommitState state, GhprbCause c) {
160143
StringBuilder msg = new StringBuilder();
161-
String commentFilePath = trigger.getCommentFilePath();
162-
163-
if (commentFilePath != null && !commentFilePath.isEmpty()) {
164-
try {
165-
String scriptFilePathResolved = Ghprb.replaceMacros(build, commentFilePath);
166-
167-
String content = FileUtils.readFileToString(new File(scriptFilePathResolved));
168-
msg.append("Build comment file: \n--------------\n");
169-
msg.append(content);
170-
msg.append("\n--------------\n");
171-
} catch (IOException e) {
172-
msg.append("\n!!! Couldn't read commit file !!!\n");
173-
listener.getLogger().println("Couldn't read comment file");
174-
e.printStackTrace(listener.getLogger());
175-
}
176-
}
177-
178-
msg.append("\nRefer to this link for build results (access rights to CI server needed): \n");
179-
msg.append(generateCustomizedMessage(build));
180-
181-
int numLines = GhprbTrigger.getDscp().getlogExcerptLines();
182-
if (state != GHCommitState.SUCCESS && numLines > 0) {
183-
// on failure, append an excerpt of the build log
184-
try {
185-
// wrap log in "code" markdown
186-
msg.append("\n\n**Build Log**\n*last ").append(numLines).append(" lines*\n");
187-
msg.append("\n ```\n");
188-
List<String> log = build.getLog(numLines);
189-
for (String line : log) {
190-
msg.append(line).append('\n');
191-
}
192-
msg.append("```\n");
193-
} catch (IOException ex) {
194-
listener.getLogger().println("Can't add log excerpt to commit comments");
195-
ex.printStackTrace(listener.getLogger());
196-
}
197-
}
198-
199-
String buildMessage = null;
200-
if (state == GHCommitState.SUCCESS) {
201-
if (trigger.getMsgSuccess() != null && !trigger.getMsgSuccess().isEmpty()) {
202-
buildMessage = trigger.getMsgSuccess();
203-
} else if (GhprbTrigger.getDscp().getMsgSuccess(build) != null
204-
&& !GhprbTrigger.getDscp().getMsgSuccess(build).isEmpty()) {
205-
buildMessage = GhprbTrigger.getDscp().getMsgSuccess(build);
206-
}
207-
} else if (state == GHCommitState.FAILURE) {
208-
if (trigger.getMsgFailure() != null && !trigger.getMsgFailure().isEmpty()) {
209-
buildMessage = trigger.getMsgFailure();
210-
} else if (GhprbTrigger.getDscp().getMsgFailure(build) != null
211-
&& !GhprbTrigger.getDscp().getMsgFailure(build).isEmpty()) {
212-
buildMessage = GhprbTrigger.getDscp().getMsgFailure(build);
144+
145+
for (GhprbExtension ext : Ghprb.getJobExtensions(trigger, GhprbCommentAppender.class)){
146+
if (ext instanceof GhprbCommentAppender) {
147+
msg.append(((GhprbCommentAppender) ext).postBuildComment(build, listener));
213148
}
214149
}
215-
// Only Append the build's custom message if it has been set.
216-
if (buildMessage != null && !buildMessage.isEmpty()) {
217-
// When the msg is not empty, append a newline first, to seperate it from the rest of the String
218-
if (!"".equals(msg.toString())) {
219-
msg.append("\n");
220-
}
221-
msg.append(buildMessage);
222-
}
223-
150+
224151
if (msg.length() > 0) {
225152
listener.getLogger().println(msg);
226153
repo.addComment(c.getPullID(), msg.toString(), build, listener);
227154
}
228155
}
229156

230-
private String generateCustomizedMessage(AbstractBuild<?, ?> build) {
231-
JobConfiguration jobConfiguration = JobConfiguration.builder()
232-
.printStackTrace(trigger.isDisplayBuildErrorsOnDownstreamBuilds()).build();
233-
234-
GhprbBuildManager buildManager = GhprbBuildManagerFactoryUtil.getBuildManager(build, jobConfiguration);
235-
236-
StringBuilder sb = new StringBuilder();
237-
238-
sb.append(buildManager.calculateBuildUrl());
239-
240-
if (build.getResult() != Result.SUCCESS) {
241-
sb.append(buildManager.getTestResults());
242-
}
243-
244-
return sb.toString();
245-
}
246157
}

src/main/java/org/jenkinsci/plugins/ghprb/GhprbGitHub.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@ private void connect() throws IOException {
2323
String serverAPIUrl = GhprbTrigger.getDscp().getServerAPIUrl();
2424
if (accessToken != null && !accessToken.isEmpty()) {
2525
try {
26-
gh = new GitHubBuilder().withEndpoint(serverAPIUrl)
27-
.withOAuthToken(accessToken).withConnector(new HttpConnectorWithJenkinsProxy()).build();
26+
gh = new GitHubBuilder()
27+
.withEndpoint(serverAPIUrl)
28+
.withOAuthToken(accessToken)
29+
.withConnector(new HttpConnectorWithJenkinsProxy())
30+
.build();
2831
} catch (IOException e) {
2932
logger.log(Level.SEVERE, "Can''t connect to {0} using oauth", serverAPIUrl);
3033
throw e;

src/main/java/org/jenkinsci/plugins/ghprb/GhprbPullRequestMerge.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, final Build
8686
return true;
8787
}
8888

89-
trigger = GhprbTrigger.extractTrigger(project);
89+
trigger = Ghprb.extractTrigger(project);
9090
if (trigger == null)
9191
return false;
9292

src/main/java/org/jenkinsci/plugins/ghprb/GhprbRepository.java

+20-14
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import hudson.model.TaskListener;
77
import jenkins.model.Jenkins;
88

9+
import org.jenkinsci.plugins.ghprb.extensions.GhprbCommentAppender;
10+
import org.jenkinsci.plugins.ghprb.extensions.GhprbExtension;
11+
import org.jenkinsci.plugins.ghprb.extensions.comments.GhprbBuildStatus;
912
import org.kohsuke.github.*;
1013
import org.kohsuke.github.GHEventPayload.IssueComment;
1114
import org.kohsuke.github.GHEventPayload.PullRequest;
@@ -76,7 +79,7 @@ public void check() {
7679
if (!initGhRepository()) {
7780
return;
7881
}
79-
82+
8083
if (helper.isProjectDisabled()) {
8184
logger.log(Level.FINE, "Project is disabled, not checking github state");
8285
return;
@@ -144,16 +147,12 @@ public void createCommitStatus(AbstractBuild<?, ?> build, String sha1, GHCommitS
144147
} else {
145148
ghRepository.createCommitStatus(sha1, state, url, message);
146149
}
147-
} catch (FileNotFoundException ex) {
148-
newMessage = "FileNotFoundException means that the credentials Jenkins is using is probably wrong. Or that something is really wrong with github.";
149-
if (stream != null) {
150-
stream.println(newMessage);
151-
ex.printStackTrace(stream);
150+
} catch (IOException ex) {
151+
if (ex instanceof FileNotFoundException) {
152+
newMessage = "FileNotFoundException means that the credentials Jenkins is using is probably wrong. Or the user account does not have write access to the repo.";
152153
} else {
153-
logger.log(Level.INFO, newMessage, ex);
154+
newMessage = "Could not update commit status of the Pull Request on GitHub.";
154155
}
155-
} catch (IOException ex) {
156-
newMessage = "Could not update commit status of the Pull Request on GitHub.";
157156
if (stream != null) {
158157
stream.println(newMessage);
159158
ex.printStackTrace(stream);
@@ -162,14 +161,21 @@ public void createCommitStatus(AbstractBuild<?, ?> build, String sha1, GHCommitS
162161
}
163162
if (GhprbTrigger.getDscp().getUseComments()) {
164163

165-
if (state == GHCommitState.SUCCESS) {
166-
message = message + " " + GhprbTrigger.getDscp().getMsgSuccess(build);
167-
} else if (state == GHCommitState.FAILURE) {
168-
message = message + " " + GhprbTrigger.getDscp().getMsgFailure(build);
164+
StringBuilder msg = new StringBuilder(message);
165+
166+
if (build != null) {
167+
msg.append("\n");
168+
GhprbTrigger trigger = Ghprb.extractTrigger(build);
169+
for (GhprbExtension ext : Ghprb.matchesAll(trigger.getExtensions(), GhprbBuildStatus.class)) {
170+
if (ext instanceof GhprbCommentAppender) {
171+
msg.append(((GhprbCommentAppender) ext).postBuildComment(build, null));
172+
}
173+
}
169174
}
175+
170176
if (GhprbTrigger.getDscp().getUseDetailedComments() || (state == GHCommitState.SUCCESS || state == GHCommitState.FAILURE)) {
171177
logger.log(Level.INFO, "Trying to send comment.", ex);
172-
addComment(id, message);
178+
addComment(id, msg.toString());
173179
}
174180
} else {
175181
logger.log(Level.SEVERE, "Could not update commit status of the Pull Request on GitHub.");

0 commit comments

Comments
 (0)