Skip to content

Commit 30d7149

Browse files
committed
Add branch filter
1 parent 12ffa3a commit 30d7149

File tree

5 files changed

+74
-15
lines changed

5 files changed

+74
-15
lines changed

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>org.jenkins-ci.plugins</groupId>
77
<artifactId>plugin</artifactId>
8-
<version>2.11</version>
8+
<version>2.30</version>
99
</parent>
1010
<artifactId>gogs-webhook</artifactId>
1111
<version>1.0.15-SNAPSHOT</version>
@@ -16,7 +16,7 @@
1616
<java.level.test>8</java.level.test>
1717

1818
<!-- Jenkins -->
19-
<jenkins.version>2.60.3</jenkins.version>
19+
<jenkins.version>2.138.3</jenkins.version>
2020
<jenkins-test-harness.version>2.38</jenkins-test-harness.version>
2121

2222
<!-- Security -->

src/main/java/org/jenkinsci/plugins/gogs/GogsProjectProperty.java

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,17 @@ associated documentation files (the "Software"), to deal in the Software without
3636

3737
@SuppressWarnings("ALL")
3838
public class GogsProjectProperty extends JobProperty<Job<?, ?>> {
39+
private static final Logger LOGGER = Logger.getLogger(GogsWebHook.class.getName());
40+
3941
private final String gogsSecret;
4042
private final boolean gogsUsePayload;
43+
private final String gogsBranchFilter;
4144

4245
@DataBoundConstructor
43-
public GogsProjectProperty(String gogsSecret, boolean gogsUsePayload) {
46+
public GogsProjectProperty(String gogsSecret, boolean gogsUsePayload, String gogsBranchFilter) {
4447
this.gogsSecret = gogsSecret;
4548
this.gogsUsePayload = gogsUsePayload;
49+
this.gogsBranchFilter = gogsBranchFilter;
4650
}
4751

4852
public String getGogsSecret() {
@@ -53,13 +57,27 @@ public boolean getGogsUsePayload() {
5357
return this.gogsUsePayload;
5458
}
5559

56-
private static final Logger LOGGER = Logger.getLogger(GogsWebHook.class.getName());
60+
public String getGogsBranchFilter() {
61+
return gogsBranchFilter;
62+
}
63+
64+
public boolean getHasBranchFilter() {
65+
return gogsBranchFilter != null && gogsBranchFilter.length() > 0;
66+
}
67+
68+
public boolean filterBranch(String ref) {
69+
if (gogsBranchFilter != null && gogsBranchFilter.length() > 0 && !gogsBranchFilter.equals("*")) {
70+
return ref == null || ref.length() == 0 || ref.endsWith(gogsBranchFilter);
71+
}
72+
return true;
73+
}
5774

5875
@Extension
5976
public static final class DescriptorImpl extends JobPropertyDescriptor {
6077
public static final String GOGS_PROJECT_BLOCK_NAME = "gogsProject";
6178
private String gogsSecret;
6279
private boolean gogsUsePayload;
80+
private String gogsBranchFilter;
6381

6482
public String getGogsSecret() {
6583
return gogsSecret;
@@ -69,6 +87,10 @@ public boolean getGogsUsePayload() {
6987
return gogsUsePayload;
7088
}
7189

90+
public String getGogsBranchFilter() {
91+
return gogsBranchFilter;
92+
}
93+
7294
public JobProperty<?> newInstance(@Nonnull StaplerRequest req, @Nonnull JSONObject formData) {
7395
GogsProjectProperty tpp = req.bindJSON(
7496
GogsProjectProperty.class,
@@ -77,15 +99,17 @@ public JobProperty<?> newInstance(@Nonnull StaplerRequest req, @Nonnull JSONObje
7799
if (tpp != null) {
78100
LOGGER.finest(formData.toString());
79101
LOGGER.finest(tpp.gogsSecret);
102+
LOGGER.finest(tpp.gogsBranchFilter);
80103

81104
gogsSecret = tpp.gogsSecret;
105+
gogsBranchFilter = tpp.gogsBranchFilter;
82106
}
83107
return tpp;
84108
}
85109

86110
@Override
87111
public String getDisplayName() {
88-
return "Gogs Secret";
112+
return "Gogs Project Property";
89113
}
90114
}
91115
}

src/main/java/org/jenkinsci/plugins/gogs/GogsWebHook.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ private void setGogsSignature(String gogsSignature) {
102102
* @param rsp response
103103
* @throws IOException problem while parsing
104104
*/
105+
@SuppressWarnings("WeakerAccess")
105106
public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException {
106107
GogsPayloadProcessor payloadProcessor = new GogsPayloadProcessor();
107108
GogsCause gogsCause = new GogsCause();
@@ -121,7 +122,8 @@ public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException
121122
if (!body.isEmpty() && req.getRequestURI().contains("/" + URLNAME + "/")) {
122123
JSONObject jsonObject = JSONObject.fromObject(body);
123124
JSONObject commits = (JSONObject) jsonObject.getJSONArray("commits").get(0);
124-
String message = (String) commits.get("message");
125+
String ref = jsonObject.getString("ref");
126+
String message = commits.getString("message");
125127

126128
if (message.startsWith("[IGNORE]")) {
127129
// Ignore commits starting with message "[IGNORE]"
@@ -140,22 +142,23 @@ public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException
140142

141143
AtomicReference<String> jSecret = new AtomicReference<>(null);
142144
AtomicBoolean foundJob = new AtomicBoolean(false);
145+
AtomicBoolean isRefMatched = new AtomicBoolean(true);
143146
gogsCause.setGogsPayloadData(jsonObject.toString());
144147
gogsCause.setDeliveryID(getGogsDelivery());
145148
payloadProcessor.setCause(gogsCause);
146149

147-
try (ACLContext ctx = ACL.as(ACL.SYSTEM)) {
150+
try (ACLContext ignored = ACL.as(ACL.SYSTEM)) {
148151
StringJoiner stringJoiner = new StringJoiner("%2F");
149-
Pattern.compile("/").splitAsStream((String) jsonObject.get("ref")).skip(2)
150-
.forEach(stringJoiner::add);
151-
String ref = stringJoiner.toString();
152+
Pattern.compile("/").splitAsStream(jsonObject.getString("ref")).skip(2).forEach(stringJoiner::add);
153+
String ref_strj = stringJoiner.toString();
152154

153155
/* secret is stored in the properties of Job */
154-
Stream.of(jobName, jobName + "/" + ref).map(j -> GogsUtils.find(j, Job.class)).filter(Objects::nonNull).forEach(job -> {
156+
Stream.of(jobName, jobName + "/" + ref_strj).map(j -> GogsUtils.find(j, Job.class)).filter(Objects::nonNull).forEach(job -> {
155157
foundJob.set(true);
156158
final GogsProjectProperty property = (GogsProjectProperty) job.getProperty(GogsProjectProperty.class);
157159
if (property != null) { /* only if Gogs secret is defined on the job */
158160
jSecret.set(property.getGogsSecret()); /* Secret provided by Jenkins */
161+
isRefMatched.set(property.filterBranch(ref));
159162
}
160163
});
161164
}
@@ -178,6 +181,10 @@ public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException
178181
String msg = String.format("Job '%s' is not defined in Jenkins", jobName);
179182
result.setStatus(404, msg);
180183
LOGGER.warning(msg);
184+
} else if (!isRefMatched.get()) {
185+
String msg = String.format("received ref ('%s') is not matched with branch filter in job '%s'", ref, jobName);
186+
result.setStatus(200, msg);
187+
LOGGER.info(msg);
181188
} else if (isNullOrEmpty(jSecret.get()) && isNullOrEmpty(gSecret)) {
182189
/* No password is set in Jenkins and Gogs, run without secrets */
183190
result = payloadProcessor.triggerJobs(jobName);

src/main/resources/org/jenkinsci/plugins/gogs/GogsProjectProperty/config.jelly

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
<?jelly escape-by-default='true'?>
2-
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
2+
<j:jelly xmlns:j="jelly:core" xmlns:f="/lib/form">
33
<f:section title="Gogs Webhook" name="${descriptor.GOGS_PROJECT_BLOCK_NAME}">
44
<f:optionalBlock title="Use Gogs secret" inline="true" checked="${instance.gogsSecret != null}">
55
<f:entry title="${%Secret}">
6-
<f:password field="gogsSecret" />
6+
<f:password field="gogsSecret"/>
7+
</f:entry>
8+
</f:optionalBlock>
9+
<f:optionalBlock title="Branch Filter" inline="true" checked="${instance.hasBranchFilter}">
10+
<f:entry title="${%BranchFilter}">
11+
<f:textbox field="gogsBranchFilter"/>
712
</f:entry>
813
</f:optionalBlock>
914
</f:section>

src/test/java/org/jenkinsci/plugins/gogs/GogsWebHookTest.java

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@
2424
import java.io.InputStream;
2525
import java.io.PrintWriter;
2626

27-
import static org.junit.Assert.assertEquals;
28-
import static org.junit.Assert.fail;
27+
import static org.junit.Assert.*;
2928
import static org.mockito.Mockito.verify;
3029
import static org.mockito.Mockito.when;
3130

@@ -232,6 +231,30 @@ public void whenUriDoesNotContainUrlNameMustReturnError() throws Exception {
232231
log.info("Test succeeded.");
233232
}
234233

234+
@Test
235+
public void whenJobBranchNotMatchMustReturnError() throws Exception {
236+
String[][] test_vals = {
237+
{null, "master", "true"},
238+
{null, "dev", "true"},
239+
{"", "master", "true"},
240+
{"", "dev", "true"},
241+
{"*", "master", "true"},
242+
{"*", "dev", "true"},
243+
{"dev", "master", "false"},
244+
{"dev", "dev", "true"},
245+
{"master", "master", "true"},
246+
{"master", "dev", "false"},
247+
};
248+
for (String[] test_val : test_vals) {
249+
String filter = test_val[0];
250+
String ref = test_val[1];
251+
boolean ret = Boolean.parseBoolean(test_val[2]);
252+
GogsProjectProperty property = new GogsProjectProperty(null, false, filter);
253+
assertSame(String.format("branch filter check failed for [%s -> %s]", ref, filter), ret, property.filterBranch(ref));
254+
}
255+
log.info("Test succeeded.");
256+
}
257+
235258
//
236259
// Helper methods
237260
//

0 commit comments

Comments
 (0)