-
Notifications
You must be signed in to change notification settings - Fork 606
/
GhprbBuilds.java
190 lines (163 loc) · 7.29 KB
/
GhprbBuilds.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
package org.jenkinsci.plugins.ghprb;
import hudson.model.AbstractBuild;
import hudson.model.TaskListener;
import hudson.model.queue.QueueTaskFuture;
import hudson.plugins.git.util.BuildData;
import org.jenkinsci.plugins.ghprb.extensions.GhprbCommentAppender;
import org.jenkinsci.plugins.ghprb.extensions.GhprbCommitStatus;
import org.jenkinsci.plugins.ghprb.extensions.GhprbCommitStatusException;
import org.jenkinsci.plugins.ghprb.extensions.GhprbExtension;
import org.kohsuke.github.GHCommitState;
import org.kohsuke.github.GHIssueState;
import org.kohsuke.github.GHPullRequest;
import org.kohsuke.github.GHUser;
import java.io.IOException;
import java.io.PrintStream;
import java.util.concurrent.ConcurrentMap;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author janinko
*/
public class GhprbBuilds {
private static final Logger logger = Logger.getLogger(GhprbBuilds.class.getName());
private final GhprbTrigger trigger;
private final GhprbRepository repo;
public GhprbBuilds(GhprbTrigger trigger, GhprbRepository repo) {
this.trigger = trigger;
this.repo = repo;
}
public void build(GhprbPullRequest pr, GHUser triggerSender, String commentBody) {
GhprbCause cause = new GhprbCause(pr.getHead(), pr.getId(), pr.isMergeable(), pr.getTarget(), pr.getSource(), pr.getAuthorEmail(), pr.getTitle(), pr.getUrl(), triggerSender, commentBody,
pr.getCommitAuthor());
for (GhprbExtension ext : Ghprb.getJobExtensions(trigger, GhprbCommitStatus.class)) {
if (ext instanceof GhprbCommitStatus) {
try {
((GhprbCommitStatus) ext).onBuildTriggered(trigger, pr, repo.getGitHubRepo());
} catch (GhprbCommitStatusException e) {
repo.commentOnFailure(null, null, e);
}
}
}
QueueTaskFuture<?> build = trigger.startJob(cause, repo);
if (build == null) {
logger.log(Level.SEVERE, "Job did not start");
}
}
public void onStarted(AbstractBuild<?, ?> build, TaskListener listener) {
PrintStream logger = listener.getLogger();
GhprbCause c = Ghprb.getCause(build);
if (c == null) {
return;
}
GhprbTrigger trigger = Ghprb.extractTrigger(build);
ConcurrentMap<Integer, GhprbPullRequest> pulls = trigger.getDescriptor().getPullRequests(build.getProject().getFullName());
GHPullRequest pr = pulls.get(c.getPullID()).getPullRequest();
try {
int counter = 0;
// If the PR is being resolved by GitHub then getMergeable will return null
Boolean isMergeable = pr.getMergeable();
Boolean isMerged = pr.isMerged();
// Not sure if isMerged can return null, but adding if just in case
if (isMerged == null) {
isMerged = false;
}
while (isMergeable == null && !isMerged && counter++ < 60) {
Thread.sleep(1000);
isMergeable = pr.getMergeable();
isMerged = pr.isMerged();
if (isMerged == null) {
isMerged = false;
}
}
if (isMerged) {
logger.println("PR has already been merged, builds using the merged sha1 will fail!!!");
} else if (isMergeable == null) {
logger.println("PR merge status couldn't be retrieved, maybe GitHub hasn't settled yet");
} else if (isMergeable != c.isMerged()) {
logger.println("!!! PR mergeability status has changed !!! ");
if (isMergeable) {
logger.println("PR now has NO merge conflicts");
} else if (!isMergeable) {
logger.println("PR now has merge conflicts!");
}
}
} catch (Exception e) {
logger.print("Unable to query GitHub for status of PullRequest");
e.printStackTrace(logger);
}
for (GhprbExtension ext : Ghprb.getJobExtensions(trigger, GhprbCommitStatus.class)) {
if (ext instanceof GhprbCommitStatus) {
try {
((GhprbCommitStatus) ext).onBuildStart(build, listener, repo.getGitHubRepo());
} catch (GhprbCommitStatusException e) {
repo.commentOnFailure(build, listener, e);
}
}
}
try {
build.setDescription("<a title=\"" + c.getTitle() + "\" href=\"" + c.getUrl() + "\">PR #" + c.getPullID() + "</a>: " + c.getAbbreviatedTitle());
} catch (IOException ex) {
logger.println("Can't update build description");
ex.printStackTrace(logger);
}
}
public void onCompleted(AbstractBuild<?, ?> build, TaskListener listener) {
GhprbCause c = Ghprb.getCause(build);
if (c == null) {
return;
}
// remove the BuildData action that we may have added earlier to avoid
// having two of them, and because the one we added isn't correct
// @see GhprbTrigger
BuildData fakeOne = null;
for (BuildData data : build.getActions(BuildData.class)) {
if (data.getLastBuiltRevision() != null && !data.getLastBuiltRevision().getSha1String().equals(c.getCommit())) {
fakeOne = data;
break;
}
}
if (fakeOne != null) {
build.getActions().remove(fakeOne);
}
for (GhprbExtension ext : Ghprb.getJobExtensions(trigger, GhprbCommitStatus.class)) {
if (ext instanceof GhprbCommitStatus) {
try {
((GhprbCommitStatus) ext).onBuildComplete(build, listener, repo.getGitHubRepo());
} catch (GhprbCommitStatusException e) {
repo.commentOnFailure(build, listener, e);
}
}
}
GHCommitState state;
state = Ghprb.getState(build);
commentOnBuildResult(build, listener, state, c);
// close failed pull request automatically
if (state == GHCommitState.FAILURE && trigger.isAutoCloseFailedPullRequests()) {
closeFailedRequest(listener, c);
}
}
private void closeFailedRequest(TaskListener listener, GhprbCause c) {
try {
GHPullRequest pr = repo.getPullRequest(c.getPullID());
if (pr.getState().equals(GHIssueState.OPEN)) {
repo.closePullRequest(c.getPullID());
}
} catch (IOException ex) {
listener.getLogger().println("Can't close pull request");
ex.printStackTrace(listener.getLogger());
}
}
private void commentOnBuildResult(AbstractBuild<?, ?> build, TaskListener listener, GHCommitState state, GhprbCause c) {
StringBuilder msg = new StringBuilder();
for (GhprbExtension ext : Ghprb.getJobExtensions(trigger, GhprbCommentAppender.class)) {
if (ext instanceof GhprbCommentAppender) {
msg.append(((GhprbCommentAppender) ext).postBuildComment(build, listener));
}
}
if (msg.length() > 0) {
listener.getLogger().println(msg);
repo.addComment(c.getPullID(), msg.toString(), build, listener);
}
}
}