Skip to content
This repository was archived by the owner on Oct 29, 2024. It is now read-only.

Commit 93043b1

Browse files
balihbkageiit
authored andcommitted
Jenkins pipeline support for notifier (#185)
1 parent 99a4231 commit 93043b1

12 files changed

+102
-52
lines changed

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ target/
66
.gradle
77
local.properties
88
**build
9+
/bin/

Diff for: build.gradle

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ dependencies {
4747
jenkinsPlugins 'org.jenkins-ci.plugins:credentials:1.22@jar'
4848

4949
optionalJenkinsPlugins 'org.jenkins-ci.plugins:junit:1.6@jar'
50-
optionalJenkinsPlugins 'org.jenkins-ci.plugins:cobertura:1.9.6@jar'
50+
optionalJenkinsPlugins 'org.jenkins-ci.plugins:cobertura:1.11@jar'
5151

5252
testCompile 'junit:junit:4.12'
5353
testCompile 'org.apache.httpcomponents:httpclient:4.3:tests'

Diff for: docs/advanced.md

+15
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,18 @@ avoid confusion. Please note that builds on the same diff triggered by the same
8080

8181
Also note that if you pass additional arguments to your harbormaster request they may need to be included in the `ABORT_ON_REVISION_ID` field as well. A good example is when you use the same CI job to build multiple targets on a single diff. So for example, if the jenkins request params have
8282
`TARGET=some_target`, then to ensure other targets are not cancelled for the same diff, you may want to set `ABORT_ON_REVISION_ID=some_target_${buildable.revision}`.
83+
84+
Pipeline
85+
--------
86+
87+
Typically the Phabricator Notifier is used as a reporting step in a Jenkins Pipeline. The test result collector step must be run before the Notifier.
88+
89+
```groovy
90+
stage ('report') {
91+
//...
92+
// junit()
93+
step([$class: 'PhabricatorNotifier', commentOnSuccess: true, commentWithConsoleLinkOnFailure: true])
94+
//...
95+
}
96+
97+
```

Diff for: src/main/java/com/uber/jenkins/phabricator/BuildResultProcessor.java

+9-5
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
import com.uber.jenkins.phabricator.utils.CommonUtils;
3838
import com.uber.jenkins.phabricator.utils.Logger;
3939
import hudson.FilePath;
40-
import hudson.model.AbstractBuild;
4140
import hudson.model.Result;
41+
import hudson.model.Run;
4242
import net.sf.json.JSONException;
4343
import net.sf.json.JSONObject;
4444

@@ -59,15 +59,15 @@ public class BuildResultProcessor {
5959
private final String buildUrl;
6060
private final boolean runHarbormaster;
6161
private final FilePath workspace;
62-
private final AbstractBuild build;
62+
private final Run<?, ?> build;
6363
private String commentAction;
6464
private final CommentBuilder commenter;
6565
private UnitResults unitResults;
6666
private Map<String, String> harbormasterCoverage;
6767
private LintResults lintResults;
6868

6969
public BuildResultProcessor(
70-
Logger logger, AbstractBuild build, Differential diff, DifferentialClient diffClient,
70+
Logger logger, Run<?, ?> build, FilePath workspace, Differential diff, DifferentialClient diffClient,
7171
String phid, CodeCoverageMetrics coverageResult, String buildUrl, boolean preserveFormatting,
7272
CoverageCheckSettings coverageCheckSettings) {
7373
this.logger = logger;
@@ -76,7 +76,7 @@ public BuildResultProcessor(
7676
this.phid = phid;
7777
this.buildUrl = buildUrl;
7878
this.build = build;
79-
this.workspace = build.getWorkspace();
79+
this.workspace = workspace;
8080

8181
this.commentAction = "none";
8282
this.commenter = new CommentBuilder(logger, build.getResult(), coverageResult, buildUrl, preserveFormatting,
@@ -85,7 +85,11 @@ public BuildResultProcessor(
8585
}
8686

8787
public Result getBuildResult() {
88-
return this.build.getResult();
88+
if (this.build.getResult() == null) {
89+
return Result.SUCCESS;
90+
} else {
91+
return this.build.getResult();
92+
}
8993
}
9094

9195
/**

Diff for: src/main/java/com/uber/jenkins/phabricator/PhabricatorNotifier.java

+33-18
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,22 @@
3535
import com.uber.jenkins.phabricator.unit.UnitTestProvider;
3636
import com.uber.jenkins.phabricator.utils.CommonUtils;
3737
import com.uber.jenkins.phabricator.utils.Logger;
38+
39+
import hudson.AbortException;
3840
import hudson.EnvVars;
41+
import hudson.FilePath;
3942
import hudson.Launcher;
40-
import hudson.model.AbstractBuild;
41-
import hudson.model.BuildListener;
4243
import hudson.model.Job;
4344
import hudson.model.Result;
45+
import hudson.model.Run;
46+
import hudson.model.TaskListener;
4447
import hudson.tasks.BuildStepMonitor;
4548
import hudson.tasks.Notifier;
4649
import jenkins.model.CauseOfInterruption;
4750
import jenkins.model.InterruptedBuildAction;
4851
import jenkins.model.Jenkins;
52+
import jenkins.tasks.SimpleBuildStep;
53+
4954
import org.apache.commons.io.FilenameUtils;
5055
import org.kohsuke.stapler.DataBoundConstructor;
5156

@@ -55,7 +60,7 @@
5560
import java.util.List;
5661
import java.util.Set;
5762

58-
public class PhabricatorNotifier extends Notifier {
63+
public class PhabricatorNotifier extends Notifier implements SimpleBuildStep {
5964
public static final String COBERTURA_CLASS_NAME = "com.uber.jenkins.phabricator.coverage.CoberturaCoverageProvider";
6065

6166
private static final String JUNIT_PLUGIN_NAME = "junit";
@@ -105,8 +110,8 @@ public BuildStepMonitor getRequiredMonitorService() {
105110
}
106111

107112
@Override
108-
public final boolean perform(final AbstractBuild<?, ?> build, final Launcher launcher,
109-
final BuildListener listener) throws InterruptedException, IOException {
113+
public final void perform(final Run<?, ?> build, FilePath workspace, final Launcher launcher,
114+
final TaskListener listener) throws InterruptedException, IOException {
110115
EnvVars environment = build.getEnvironment(listener);
111116
Logger logger = new Logger(listener.getLogger());
112117

@@ -128,7 +133,7 @@ public final boolean perform(final AbstractBuild<?, ?> build, final Launcher lau
128133
if (cause instanceof PhabricatorCauseOfInterruption) {
129134
logger.warn(ABORT_TAG, "Skipping notification step since this build was interrupted"
130135
+ " by a newer build with the same differential revision");
131-
return true;
136+
return;
132137
}
133138
}
134139
}
@@ -144,7 +149,7 @@ public final boolean perform(final AbstractBuild<?, ?> build, final Launcher lau
144149
build.addAction(PhabricatorPostbuildAction.createShortText(branch, null));
145150
}
146151

147-
coverageProvider = getCoverageProvider(build, listener, Collections.<String>emptySet());
152+
coverageProvider = getCoverageProvider(build, workspace, listener, Collections.<String>emptySet());
148153
CodeCoverageMetrics coverageResult = null;
149154
if (coverageProvider != null) {
150155
coverageResult = coverageProvider.getMetrics();
@@ -160,7 +165,7 @@ public final boolean perform(final AbstractBuild<?, ?> build, final Launcher lau
160165

161166
// Ignore the result.
162167
nonDifferentialBuildTask.run();
163-
return true;
168+
return;
164169
}
165170

166171
ConduitAPIClient conduitClient;
@@ -169,7 +174,7 @@ public final boolean perform(final AbstractBuild<?, ?> build, final Launcher lau
169174
} catch (ConduitAPIException e) {
170175
e.printStackTrace(logger.getStream());
171176
logger.warn(CONDUIT_TAG, e.getMessage());
172-
return false;
177+
throw new AbortException();
173178
}
174179

175180
final String buildUrl = environment.get("BUILD_URL");
@@ -183,7 +188,11 @@ public final boolean perform(final AbstractBuild<?, ?> build, final Launcher lau
183188
build.getResult(),
184189
buildUrl
185190
).run();
186-
return result == Task.Result.SUCCESS;
191+
if (result == Task.Result.SUCCESS) {
192+
return;
193+
} else {
194+
throw new AbortException();
195+
}
187196
}
188197

189198
DifferentialClient diffClient = new DifferentialClient(diffID, conduitClient);
@@ -194,7 +203,7 @@ public final boolean perform(final AbstractBuild<?, ?> build, final Launcher lau
194203
e.printStackTrace(logger.getStream());
195204
logger.warn(CONDUIT_TAG, "Unable to fetch differential from Conduit API");
196205
logger.warn(CONDUIT_TAG, e.getMessage());
197-
return true;
206+
return;
198207
}
199208

200209
if (needsDecoration) {
@@ -206,7 +215,7 @@ public final boolean perform(final AbstractBuild<?, ?> build, final Launcher lau
206215
includeFileNames.add(FilenameUtils.getName(file));
207216
}
208217

209-
coverageProvider = getCoverageProvider(build, listener, includeFileNames);
218+
coverageProvider = getCoverageProvider(build, workspace, listener, includeFileNames);
210219
CodeCoverageMetrics coverageResult = null;
211220
if (coverageProvider != null) {
212221
coverageResult = coverageProvider.getMetrics();
@@ -215,6 +224,7 @@ public final boolean perform(final AbstractBuild<?, ?> build, final Launcher lau
215224
BuildResultProcessor resultProcessor = new BuildResultProcessor(
216225
logger,
217226
build,
227+
workspace,
218228
diff,
219229
diffClient,
220230
environment.get(PhabricatorPlugin.PHID_FIELD),
@@ -247,14 +257,12 @@ public final boolean perform(final AbstractBuild<?, ?> build, final Launcher lau
247257

248258
// Fail the build if we can't report to Harbormaster
249259
if (!resultProcessor.processHarbormaster()) {
250-
return false;
260+
throw new AbortException();
251261
}
252262

253263
resultProcessor.processRemoteComment(commentFile, commentSize);
254264

255265
resultProcessor.sendComment(commentWithConsoleLinkOnFailure);
256-
257-
return true;
258266
}
259267

260268
protected UberallsClient getUberallsClient(Logger logger, String gitUrl, String branch) {
@@ -291,9 +299,15 @@ private ConduitAPIClient getConduitClient(Job owner) throws ConduitAPIException
291299
* @param listener The build listener
292300
* @return The current cobertura coverage, if any
293301
*/
294-
private CoverageProvider getCoverageProvider(AbstractBuild build, BuildListener listener,
302+
private CoverageProvider getCoverageProvider(Run<?, ?> build, FilePath workspace, TaskListener listener,
295303
Set<String> includeFileNames) {
296-
if (!build.getResult().isBetterOrEqualTo(Result.UNSTABLE)) {
304+
Result buildResult = null;
305+
if (build.getResult() == null) {
306+
buildResult = Result.SUCCESS;
307+
} else {
308+
buildResult = build.getResult();
309+
}
310+
if (!buildResult.isBetterOrEqualTo(Result.UNSTABLE)) {
297311
return null;
298312
}
299313

@@ -311,6 +325,7 @@ private CoverageProvider getCoverageProvider(AbstractBuild build, BuildListener
311325
}
312326

313327
coverage.setBuild(build);
328+
coverage.setWorkspace(workspace);
314329
coverage.setIncludeFileNames(includeFileNames);
315330
coverage.setCoverageReportPattern(coverageReportPattern);
316331
if (coverage.hasCoverage()) {
@@ -321,7 +336,7 @@ private CoverageProvider getCoverageProvider(AbstractBuild build, BuildListener
321336
}
322337
}
323338

324-
private UnitTestProvider getUnitProvider(AbstractBuild build, BuildListener listener) {
339+
private UnitTestProvider getUnitProvider(Run<?, ?> build, TaskListener listener) {
325340
Logger logger = new Logger(listener.getLogger());
326341

327342
InstanceProvider<UnitTestProvider> provider = new InstanceProvider<UnitTestProvider>(

Diff for: src/main/java/com/uber/jenkins/phabricator/conduit/Differential.java

+2-6
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,14 @@
2323
import com.uber.jenkins.phabricator.PhabricatorPostbuildAction;
2424
import com.uber.jenkins.phabricator.PhabricatorPostbuildSummaryAction;
2525

26-
import hudson.EnvVars;
27-
import hudson.model.AbstractBuild;
28-
26+
import hudson.model.Run;
2927
import net.sf.json.JSONArray;
3028
import net.sf.json.JSONNull;
3129
import net.sf.json.JSONObject;
3230

3331
import java.net.MalformedURLException;
3432
import java.net.URL;
35-
import java.util.ArrayList;
3633
import java.util.HashSet;
37-
import java.util.List;
3834
import java.util.Set;
3935

4036
public class Differential {
@@ -78,7 +74,7 @@ public String getPhabricatorLink(String phabricatorURL) {
7874
}
7975
}
8076

81-
public void decorate(AbstractBuild build, String phabricatorURL) {
77+
public void decorate(Run<?, ?> build, String phabricatorURL) {
8278
// Add a badge next to the build
8379
build.addAction(PhabricatorPostbuildAction.createShortText(
8480
getRevisionID(true),

Diff for: src/main/java/com/uber/jenkins/phabricator/coverage/CoberturaCoverageProvider.java

+8-9
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
import hudson.FilePath;
4040
import hudson.model.AbstractBuild;
41+
import hudson.model.Run;
4142
import hudson.plugins.cobertura.Ratio;
4243
import hudson.plugins.cobertura.targets.CoverageMetric;
4344
import hudson.plugins.cobertura.targets.CoverageResult;
@@ -96,7 +97,8 @@ Map<String, List<Integer>> parseReports(CoberturaXMLParser parser, File[] report
9697
}
9798

9899
private void computeCoverage() {
99-
AbstractBuild build = getBuild();
100+
Run<?, ?> build = getBuild();
101+
FilePath workspace = getWorkspace();
100102
if (build == null) {
101103
mHasComputedCoverage = true;
102104
return;
@@ -114,7 +116,7 @@ private void computeCoverage() {
114116
}
115117

116118
// Fallback to scanning for the reports
117-
copyCoverageToJenkinsMaster(build);
119+
copyCoverageToJenkinsMaster(build, workspace);
118120
File[] reports = getCoberturaReports(build);
119121
CoverageResult result = null;
120122
if (reports != null) {
@@ -142,17 +144,14 @@ private void computeCoverage() {
142144
}
143145

144146
private void computeLineCoverage() {
145-
FilePath workspace = getBuild().getWorkspace();
147+
FilePath workspace = getWorkspace();
146148
File[] reports = getCoberturaReports(getBuild());
147149
CoberturaXMLParser parser = new CoberturaXMLParser(workspace, getIncludeFileNames());
148150
mLineCoverage = parseReports(parser, reports);
149151
}
150152

151-
private void copyCoverageToJenkinsMaster(AbstractBuild build) {
152-
final FilePath[] moduleRoots = build.getModuleRoots();
153-
final boolean multipleModuleRoots =
154-
moduleRoots != null && moduleRoots.length > 1;
155-
final FilePath moduleRoot = multipleModuleRoots ? build.getWorkspace() : build.getModuleRoot();
153+
private void copyCoverageToJenkinsMaster(Run<?, ?> build, FilePath workspace) {
154+
final FilePath moduleRoot = workspace;
156155
final File buildCoberturaDir = build.getRootDir();
157156
FilePath buildTarget = new FilePath(buildCoberturaDir);
158157

@@ -225,7 +224,7 @@ private static float getCoveragePercentage(CoverageResult result, CoverageMetric
225224
return ratio.getPercentageFloat();
226225
}
227226

228-
private File[] getCoberturaReports(AbstractBuild build) {
227+
private File[] getCoberturaReports(Run<?, ?> build) {
229228
return build.getRootDir().listFiles(CoberturaPublisher.COBERTURA_FILENAME_FILTER);
230229
}
231230
}

Diff for: src/main/java/com/uber/jenkins/phabricator/coverage/CoverageProvider.java

+14-4
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,16 @@
2020

2121
package com.uber.jenkins.phabricator.coverage;
2222

23-
import hudson.model.AbstractBuild;
23+
import hudson.FilePath;
24+
import hudson.model.Run;
2425

2526
import java.util.List;
2627
import java.util.Map;
2728
import java.util.Set;
2829

2930
public abstract class CoverageProvider {
30-
private AbstractBuild<?, ?> build;
31+
private Run<?, ?> build;
32+
private FilePath workspace;
3133
private Set<String> includeFileNames;
3234
private String coverageReportPattern;
3335

@@ -47,14 +49,22 @@ protected Set<String> getIncludeFileNames() {
4749
* Set the owning build for this provider
4850
* @param build The build that is associated with the current run
4951
*/
50-
public void setBuild(AbstractBuild<?, ?> build) {
52+
public void setBuild(Run<?, ?> build) {
5153
this.build = build;
5254
}
5355

54-
protected AbstractBuild getBuild() {
56+
protected Run<?, ?> getBuild() {
5557
return build;
5658
}
5759

60+
public void setWorkspace(FilePath workspace) {
61+
this.workspace = workspace;
62+
}
63+
64+
protected FilePath getWorkspace() {
65+
return workspace;
66+
}
67+
5868
/**
5969
* Set the coverage report pattern to scan for
6070
* @param coverageReportPattern The coverage report pattern to scan for

0 commit comments

Comments
 (0)