Skip to content

Commit 44120e8

Browse files
authored
Support branch plugin (#36)
* Support branch only builds with Github Branch Source Plugin
1 parent 314f228 commit 44120e8

10 files changed

Lines changed: 294 additions & 103 deletions

File tree

pom.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
23
<modelVersion>4.0.0</modelVersion>
34
<parent>
45
<groupId>org.jenkins-ci.plugins</groupId>

src/main/java/com/github/terma/jenkins/githubprcoveragestatus/CompareCoverageAction.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,17 @@
3737
import java.io.IOException;
3838
import java.io.PrintStream;
3939
import java.io.PrintWriter;
40+
import java.util.Map;
4041

4142
@SuppressWarnings({"unused", "WeakerAccess"})
4243
public class CompareCoverageAction extends Recorder implements SimpleBuildStep {
4344

44-
private static final String BUILD_LOG_PREFIX = "[GitHub PR Status] ";
45+
public static final String BUILD_LOG_PREFIX = "[GitHub PR Status] ";
4546

4647
private static final long serialVersionUID = 1L;
4748
private String sonarLogin;
4849
private String sonarPassword;
50+
private Map<String, String> scmVars;
4951

5052
@DataBoundConstructor
5153
public CompareCoverageAction() {
@@ -61,6 +63,16 @@ public void setSonarPassword(String sonarPassword) {
6163
this.sonarPassword = sonarPassword;
6264
}
6365

66+
// TODO why is this needed for no public field ‘scmVars’ (or getter method) found in class ....
67+
public Map<String, String> getScmVars() {
68+
return scmVars;
69+
}
70+
71+
@DataBoundSetter
72+
public void setScmVars(Map<String, String> scmVars) {
73+
this.scmVars = scmVars;
74+
}
75+
6476
// todo show message that addition comment in progress as it could take a while
6577
@SuppressWarnings("NullableProblems")
6678
@Override
@@ -76,8 +88,8 @@ public void perform(
7688

7789
buildLog.println(BUILD_LOG_PREFIX + "start");
7890

79-
final String gitUrl = Utils.getGitUrl(build, listener);
80-
final int prId = Utils.gitPrId(build, listener);
91+
final int prId = PrIdAndUrlUtils.getPrId(scmVars, build, listener);
92+
final String gitUrl = PrIdAndUrlUtils.getGitUrl(scmVars, build, listener);
8193

8294
buildLog.println(BUILD_LOG_PREFIX + "getting master coverage...");
8395
MasterCoverageRepository masterCoverageRepository = ServiceRegistry.getMasterCoverageRepository(buildLog, sonarLogin, sonarPassword);

src/main/java/com/github/terma/jenkins/githubprcoveragestatus/GitHubPullRequestRepository.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
*/
1818
package com.github.terma.jenkins.githubprcoveragestatus;
1919

20+
import org.kohsuke.github.GHIssueState;
21+
import org.kohsuke.github.GHPullRequest;
2022
import org.kohsuke.github.GHRepository;
2123
import org.kohsuke.github.GitHub;
2224

@@ -25,6 +27,16 @@
2527

2628
public class GitHubPullRequestRepository implements PullRequestRepository {
2729

30+
@Override
31+
public GHPullRequest getPullRequestFor(String gitHubUrl, String branch, String sha) throws IOException {
32+
for (GHPullRequest pr : getGitHubRepository(gitHubUrl).getPullRequests(GHIssueState.OPEN)) {
33+
if (pr.getHead().getRef().equals(branch) && pr.getHead().getSha().equals(sha)) {
34+
return pr;
35+
}
36+
}
37+
throw new IOException(String.format("No PR found for %s %s @ %s", gitHubUrl, branch, sha));
38+
}
39+
2840
@Override
2941
public GHRepository getGitHubRepository(final String gitHubUrl) throws IOException {
3042
GitHub gitHub = getGitHub();

src/main/java/com/github/terma/jenkins/githubprcoveragestatus/MasterCoverageAction.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,30 +30,45 @@
3030
import hudson.tasks.Recorder;
3131
import jenkins.tasks.SimpleBuildStep;
3232
import org.kohsuke.stapler.DataBoundConstructor;
33+
import org.kohsuke.stapler.DataBoundSetter;
3334

3435
import javax.annotation.Nonnull;
3536
import java.io.IOException;
3637
import java.io.PrintStream;
38+
import java.util.Map;
3739

3840
@SuppressWarnings({"unused", "WeakerAccess"})
3941
public class MasterCoverageAction extends Recorder implements SimpleBuildStep {
4042

4143
public static final String DISPLAY_NAME = "Record Master Coverage";
4244
private static final long serialVersionUID = 1L;
4345

46+
47+
private Map<String, String> scmVars;
48+
4449
@DataBoundConstructor
4550
public MasterCoverageAction() {
4651

4752
}
4853

54+
// TODO why is this needed for no public field ‘scmVars’ (or getter method) found in class ....
55+
public Map<String, String> getScmVars() {
56+
return scmVars;
57+
}
58+
59+
@DataBoundSetter
60+
public void setScmVars(Map<String, String> scmVars) {
61+
this.scmVars = scmVars;
62+
}
63+
4964
@SuppressWarnings("NullableProblems")
5065
@Override
5166
public void perform(final Run build, final FilePath workspace, final Launcher launcher,
5267
final TaskListener listener) throws InterruptedException, IOException {
5368
if (build.getResult() != Result.SUCCESS) return;
5469

5570
final PrintStream buildLog = listener.getLogger();
56-
final String gitUrl = Utils.getGitUrl(build, listener);
71+
final String gitUrl = PrIdAndUrlUtils.getGitUrl(scmVars, build, listener);
5772

5873
final float masterCoverage = ServiceRegistry.getCoverageRepository().get(workspace);
5974
buildLog.println("Master coverage " + Percent.toWholeString(masterCoverage));
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
3+
Copyright 2015-2016 Artem Stasiuk
4+
5+
Licensed under the Apache License, Version 2.0 (the "License");
6+
you may not use this file except in compliance with the License.
7+
You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
17+
*/
18+
package com.github.terma.jenkins.githubprcoveragestatus;
19+
20+
import hudson.EnvVars;
21+
import hudson.model.Run;
22+
import hudson.model.TaskListener;
23+
import org.kohsuke.github.GHPullRequest;
24+
25+
import java.io.IOException;
26+
import java.io.PrintStream;
27+
import java.util.Map;
28+
29+
public class PrIdAndUrlUtils {
30+
31+
/**
32+
* Injected by Git plugin
33+
*/
34+
public static final String GIT_URL_PROPERTY = "GIT_URL";
35+
36+
/**
37+
* Injected by
38+
* https://wiki.jenkins-ci.org/display/JENKINS/GitHub+pull+request+builder+plugin
39+
*/
40+
public static final String GIT_PR_ID_ENV_PROPERTY = "ghprbPullId";
41+
public static final String CHANGE_ID_PROPERTY = "CHANGE_ID";
42+
public static final String CHANGE_URL_PROPERTY = "CHANGE_URL";
43+
44+
private PrIdAndUrlUtils() {
45+
throw new UnsupportedOperationException("Util class!");
46+
}
47+
48+
private static Integer getPullRequestBuilder(Run build, TaskListener listener) throws IOException, InterruptedException {
49+
final EnvVars envVars = build.getEnvironment(listener);
50+
final String gitPrId = envVars.get(GIT_PR_ID_ENV_PROPERTY);
51+
final String changeId = envVars.get(CHANGE_ID_PROPERTY);
52+
final String idString = gitPrId != null ? gitPrId : changeId;
53+
return idString != null ? Integer.parseInt(idString) : null;
54+
}
55+
56+
private static Integer getMultiBranch(Map<String, String> scmVars, TaskListener listener) throws IOException {
57+
if (scmVars == null) return null;
58+
final PrintStream buildLog = listener.getLogger();
59+
final String url = scmVars.get(GIT_URL_PROPERTY);
60+
final String branch = scmVars.get("GIT_BRANCH");
61+
final String sha = scmVars.get("GIT_COMMIT");
62+
buildLog.println(CompareCoverageAction.BUILD_LOG_PREFIX + String.format("Attempt to discover PR for %s @ %s", branch, sha));
63+
GHPullRequest gitPr = ServiceRegistry.getPullRequestRepository().getPullRequestFor(url, branch, sha);
64+
int id = gitPr.getNumber();
65+
buildLog.println(CompareCoverageAction.BUILD_LOG_PREFIX + String.format("Discovered PR %d", id));
66+
return id;
67+
}
68+
69+
public static int getPrId(
70+
final Map<String, String> scmVars, final Run build, final TaskListener listener) throws IOException, InterruptedException {
71+
Integer id = getPullRequestBuilder(build, listener);
72+
if (id == null) id = getMultiBranch(scmVars, listener);
73+
if (id == null) throw new UnsupportedOperationException(
74+
"Can't find " + GIT_PR_ID_ENV_PROPERTY + " or scmVars in build variables!");
75+
return id;
76+
}
77+
78+
public static String getGitUrl(final Map<String, String> scmVars, final Run build, final TaskListener listener) throws IOException, InterruptedException {
79+
Map<String, String> envVars = build.getEnvironment(listener);
80+
final String gitUrl = envVars.get(GIT_URL_PROPERTY);
81+
final String changeUrl = envVars.get(CHANGE_URL_PROPERTY);
82+
if (gitUrl != null) return gitUrl;
83+
else if (changeUrl != null) return changeUrl;
84+
else if (scmVars != null && scmVars.containsKey(GIT_URL_PROPERTY)) return scmVars.get(GIT_URL_PROPERTY);
85+
else throw new UnsupportedOperationException("Can't find " + GIT_URL_PROPERTY
86+
+ " or " + CHANGE_URL_PROPERTY + " in envs: " + envVars);
87+
}
88+
89+
}

src/main/java/com/github/terma/jenkins/githubprcoveragestatus/PullRequestRepository.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@
1919

2020
import java.io.IOException;
2121

22+
import org.kohsuke.github.GHPullRequest;
2223
import org.kohsuke.github.GHRepository;
2324

2425
interface PullRequestRepository {
2526

27+
GHPullRequest getPullRequestFor(String repo, String branch, String sha) throws IOException;
28+
2629
GHRepository getGitHubRepository(final String gitHubUrl) throws IOException;
2730

2831
void comment(GHRepository ghRepository, int prId, String message) throws IOException;

src/main/java/com/github/terma/jenkins/githubprcoveragestatus/Utils.java

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,61 +22,22 @@
2222
import hudson.model.TaskListener;
2323

2424
import java.io.IOException;
25-
import java.util.regex.Matcher;
26-
import java.util.regex.Pattern;
2725

2826
@SuppressWarnings("WeakerAccess")
2927
class Utils {
3028

31-
/**
32-
* Injected by Git plugin
33-
*/
34-
public static final String GIT_URL_ENV_PROPERTY = "GIT_URL";
35-
3629
public static final String BUILD_URL_ENV_PROPERTY = "BUILD_URL";
3730

38-
/**
39-
* Injected by
40-
* https://wiki.jenkins-ci.org/display/JENKINS/GitHub+pull+request+builder+plugin
41-
*/
42-
public static final String GIT_PR_ID_ENV_PROPERTY = "ghprbPullId";
43-
44-
public static final String CHANGE_ID_PROPERTY = "CHANGE_ID";
45-
public static final String CHANGE_URL_PROPERTY = "CHANGE_URL";
46-
4731
public static String getJenkinsUrlFromBuildUrl(String buildUrl) {
4832
final String keyword = "/job/";
4933
final int index = buildUrl.indexOf(keyword);
5034
if (index < 0) throw new IllegalArgumentException("Invalid build URL: " + buildUrl + "!");
5135
return buildUrl.substring(0, index);
5236
}
5337

54-
public static String getGitUrl(Run build, TaskListener listener) throws IOException, InterruptedException {
55-
final EnvVars envVars = build.getEnvironment(listener);
56-
final String gitUrl = envVars.get(GIT_URL_ENV_PROPERTY);
57-
final String changeUrl = envVars.get(CHANGE_URL_PROPERTY);
58-
if (gitUrl != null) return gitUrl;
59-
else if (changeUrl != null) return changeUrl;
60-
else throw new UnsupportedOperationException("Can't find " + GIT_URL_ENV_PROPERTY
61-
+ " or " + CHANGE_URL_PROPERTY + " in envs: " + envVars);
62-
}
63-
6438
public static String getBuildUrl(Run build, TaskListener listener) throws IOException, InterruptedException {
6539
final EnvVars envVars = build.getEnvironment(listener);
6640
return envVars.get(BUILD_URL_ENV_PROPERTY);
6741
}
6842

69-
public static int gitPrId(Run build, TaskListener listener) throws IOException, InterruptedException {
70-
final EnvVars envVars = build.getEnvironment(listener);
71-
final String gitPrId = envVars.get(GIT_PR_ID_ENV_PROPERTY);
72-
final String changeId = envVars.get(CHANGE_ID_PROPERTY);
73-
final String prIdString = gitPrId != null ? gitPrId : changeId;
74-
if (prIdString == null) {
75-
throw new UnsupportedOperationException("Can't find " + GIT_PR_ID_ENV_PROPERTY
76-
+ " or " + CHANGE_ID_PROPERTY + " in envs: " + envVars);
77-
} else {
78-
return Integer.parseInt(prIdString);
79-
}
80-
}
81-
8243
}

src/test/java/com/github/terma/jenkins/githubprcoveragestatus/CompareCoverageActionTest.java

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
import org.junit.Test;
2828

2929
import java.io.IOException;
30-
import java.io.PrintStream;
3130
import java.io.PrintWriter;
3231

3332
import static org.mockito.Mockito.*;
@@ -55,7 +54,7 @@ public void initMocks() throws IOException {
5554
ServiceRegistry.setSettingsRepository(settingsRepository);
5655
ServiceRegistry.setPullRequestRepository(pullRequestRepository);
5756
when(pullRequestRepository.getGitHubRepository(GIT_URL)).thenReturn(ghRepository);
58-
when(envVars.get(Utils.GIT_URL_ENV_PROPERTY)).thenReturn(GIT_URL);
57+
when(envVars.get(PrIdAndUrlUtils.GIT_URL_PROPERTY)).thenReturn(GIT_URL);
5958
when(listener.getLogger()).thenReturn(System.out);
6059
}
6160

@@ -68,7 +67,7 @@ public void skipStepIfResultOfBuildIsNotSuccess() throws IOException, Interrupte
6867
public void postCoverageStatusToPullRequestAsComment() throws IOException, InterruptedException {
6968
when(build.getResult()).thenReturn(Result.SUCCESS);
7069
when(build.getEnvironment(any(TaskListener.class))).thenReturn(envVars);
71-
when(envVars.get(Utils.GIT_PR_ID_ENV_PROPERTY)).thenReturn("12");
70+
when(envVars.get(PrIdAndUrlUtils.GIT_PR_ID_ENV_PROPERTY)).thenReturn("12");
7271
when(envVars.get(Utils.BUILD_URL_ENV_PROPERTY)).thenReturn("aaa/job/a");
7372

7473
new CompareCoverageAction().perform(build, null, null, listener);
@@ -80,7 +79,7 @@ public void postCoverageStatusToPullRequestAsComment() throws IOException, Inter
8079
public void keepBuildGreenAndLogErrorIfExceptionDuringGitHubAccess() throws IOException, InterruptedException {
8180
when(build.getResult()).thenReturn(Result.SUCCESS);
8281
when(build.getEnvironment(any(TaskListener.class))).thenReturn(envVars);
83-
when(envVars.get(Utils.GIT_PR_ID_ENV_PROPERTY)).thenReturn("12");
82+
when(envVars.get(PrIdAndUrlUtils.GIT_PR_ID_ENV_PROPERTY)).thenReturn("12");
8483
when(envVars.get(Utils.BUILD_URL_ENV_PROPERTY)).thenReturn("aaa/job/a");
8584
when(listener.error(anyString())).thenReturn(printWriter);
8685

@@ -89,15 +88,15 @@ public void keepBuildGreenAndLogErrorIfExceptionDuringGitHubAccess() throws IOEx
8988
new CompareCoverageAction().perform(build, null, null, listener);
9089

9190
verify(listener).error("Couldn't add comment to pull request #12!");
92-
verify(printWriter, atLeastOnce()).println(anyObject());
91+
verify(printWriter, atLeastOnce()).println(any(Throwable.class));
9392
}
9493

9594
@Test
9695
public void postCoverageStatusToPullRequestAsCommentWithShieldIoIfPrivateJenkinsPublicGitHubTurnOn()
9796
throws IOException, InterruptedException {
9897
when(build.getResult()).thenReturn(Result.SUCCESS);
9998
when(build.getEnvironment(any(TaskListener.class))).thenReturn(envVars);
100-
when(envVars.get(Utils.GIT_PR_ID_ENV_PROPERTY)).thenReturn("12");
99+
when(envVars.get(PrIdAndUrlUtils.GIT_PR_ID_ENV_PROPERTY)).thenReturn("12");
101100
when(envVars.get(Utils.BUILD_URL_ENV_PROPERTY)).thenReturn("aaa/job/a");
102101

103102
when(settingsRepository.isPrivateJenkinsPublicGitHub()).thenReturn(true);
@@ -111,7 +110,7 @@ public void postCoverageStatusToPullRequestAsCommentWithShieldIoIfPrivateJenkins
111110
public void postCoverageStatusToPullRequestAsCommentWithCustomJenkinsUrlIfConfigured() throws IOException, InterruptedException {
112111
when(build.getResult()).thenReturn(Result.SUCCESS);
113112
when(build.getEnvironment(any(TaskListener.class))).thenReturn(envVars);
114-
when(envVars.get(Utils.GIT_PR_ID_ENV_PROPERTY)).thenReturn("12");
113+
when(envVars.get(PrIdAndUrlUtils.GIT_PR_ID_ENV_PROPERTY)).thenReturn("12");
115114
when(envVars.get(Utils.BUILD_URL_ENV_PROPERTY)).thenReturn("aaa/job/a");
116115

117116
when(settingsRepository.getJenkinsUrl()).thenReturn("customJ");

0 commit comments

Comments
 (0)