From 4da58e696b03273a2c48a3b8c223512bd70bbc80 Mon Sep 17 00:00:00 2001 From: Oscar Salvador Morillo Victoria Date: Thu, 3 Dec 2015 14:41:09 +0100 Subject: [PATCH] New feature: Add support for regex based filtering and more Two new features were introduced: (1) Allow branch filtering through regular expressions (2) Use branch filtering also for Merge Request events By making use of radioBlocks, the user is forced to choose between allowing all branches to trigger the job and filtering the branches by one out of two possible approaches: * filtering by name * filtering by regular expression [FIXED #97] [FIXED #142] --- .../gitlabjenkins/GitLabPushTrigger.java | 63 +++++++++++++---- .../GitLabPushTrigger/config.jelly | 67 ++++++++++++------- .../webapp/help/help-allowedBranches.html | 5 +- .../help/help-filterBranchesByRegex.html | 9 +++ .../webapp/help/help-noBranchFiltering.html | 3 + ...ractGitLabPushTriggerGitlabServerTest.java | 7 +- 6 files changed, 111 insertions(+), 43 deletions(-) create mode 100644 src/main/webapp/help/help-filterBranchesByRegex.html create mode 100644 src/main/webapp/help/help-noBranchFiltering.html diff --git a/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushTrigger.java b/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushTrigger.java index 497aad1..a4a41ec 100644 --- a/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushTrigger.java +++ b/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushTrigger.java @@ -34,6 +34,7 @@ import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Pattern; import jenkins.model.Jenkins; import jenkins.model.ParameterizedJobMixIn; @@ -53,6 +54,7 @@ import org.kohsuke.stapler.StaplerRequest; import org.springframework.util.AntPathMatcher; import com.google.common.base.Joiner; +import com.google.common.base.Objects; import com.google.common.base.Splitter; import com.google.common.collect.HashMultimap; import com.google.common.collect.Lists; @@ -83,14 +85,17 @@ public class GitLabPushTrigger extends Trigger> { private boolean addNoteOnMergeRequest = true; private boolean addCiMessage = false; private boolean addVoteOnMergeRequest = true; - private boolean allowAllBranches = false; + private final String branchFilterName; private final String includeBranchesSpec; private final String excludeBranchesSpec; + private final String targetBranchRegex; private boolean acceptMergeRequestOnSuccess = false; @DataBoundConstructor - public GitLabPushTrigger(boolean triggerOnPush, boolean triggerOnMergeRequest, String triggerOpenMergeRequestOnPush, boolean ciSkip, boolean setBuildDescription, boolean addNoteOnMergeRequest, boolean addCiMessage, boolean addVoteOnMergeRequest, boolean acceptMergeRequestOnSuccess, boolean allowAllBranches, - String includeBranchesSpec, String excludeBranchesSpec) { + public GitLabPushTrigger(boolean triggerOnPush, boolean triggerOnMergeRequest, String triggerOpenMergeRequestOnPush, + boolean ciSkip, boolean setBuildDescription, boolean addNoteOnMergeRequest, boolean addCiMessage, + boolean addVoteOnMergeRequest, boolean acceptMergeRequestOnSuccess, String branchFilterName, + String includeBranchesSpec, String excludeBranchesSpec, String targetBranchRegex) { this.triggerOnPush = triggerOnPush; this.triggerOnMergeRequest = triggerOnMergeRequest; this.triggerOpenMergeRequestOnPush = triggerOpenMergeRequestOnPush; @@ -99,9 +104,10 @@ public class GitLabPushTrigger extends Trigger> { this.addNoteOnMergeRequest = addNoteOnMergeRequest; this.addCiMessage = addCiMessage; this.addVoteOnMergeRequest = addVoteOnMergeRequest; - this.allowAllBranches = allowAllBranches; + this.branchFilterName = branchFilterName; this.includeBranchesSpec = includeBranchesSpec; this.excludeBranchesSpec = excludeBranchesSpec; + this.targetBranchRegex = targetBranchRegex; this.acceptMergeRequestOnSuccess = acceptMergeRequestOnSuccess; } @@ -133,10 +139,6 @@ public class GitLabPushTrigger extends Trigger> { return acceptMergeRequestOnSuccess; } - public boolean getAllowAllBranches() { - return allowAllBranches; - } - public boolean getAddCiMessage() { return addCiMessage; } @@ -144,7 +146,19 @@ public class GitLabPushTrigger extends Trigger> { public boolean getCiSkip() { return ciSkip; } - private boolean isBranchAllowed(final String branchName) { + + private boolean isAllowedByTargetBranchRegex(String branchName) { + final String regex = this.getTargetBranchRegex(); + + if (StringUtils.isEmpty(regex)) { + return true; + } + final Pattern pattern = Pattern.compile(regex); + return pattern.matcher(branchName).matches(); + } + + private boolean isAllowedByList(final String branchName) { + final List exclude = DescriptorImpl.splitBranchSpec(this.getExcludeBranchesSpec()); final List include = DescriptorImpl.splitBranchSpec(this.getIncludeBranchesSpec()); if (exclude.isEmpty() && include.isEmpty()) { @@ -166,6 +180,27 @@ public class GitLabPushTrigger extends Trigger> { return false; } + private boolean isBranchAllowed(final String branchName) { + + final String branchFilterName = this.getBranchFilterName(); + if (branchFilterName.isEmpty()) { + // no filter is applied, allow all branches + return true; + } + + if (Objects.equal(branchFilterName, "NameBasedFilter")) { + return this.isAllowedByList(branchName); + } + + if (Objects.equal(branchFilterName, "RegexBasedFilter")) { + return this.isAllowedByTargetBranchRegex(branchName); + } + + return false; + } + + public String getBranchFilterName() { return this.branchFilterName; } + public String getIncludeBranchesSpec() { return this.includeBranchesSpec == null ? "" : this.includeBranchesSpec; } @@ -174,6 +209,8 @@ public class GitLabPushTrigger extends Trigger> { return this.excludeBranchesSpec == null ? "" : this.excludeBranchesSpec; } + public String getTargetBranchRegex() { return this.targetBranchRegex == null ? "" : this.targetBranchRegex; } + // executes when the Trigger receives a push request public void onPost(final GitLabPushRequest req) { // TODO 1.621+ use standard method @@ -184,7 +221,8 @@ public class GitLabPushTrigger extends Trigger> { } }; - if (triggerOnPush && (allowAllBranches || this.isBranchAllowed(this.getSourceBranch(req)))) { + if (triggerOnPush && this.isBranchAllowed(this.getSourceBranch(req))) { + getDescriptor().queue.execute(new Runnable() { public void run() { @@ -311,7 +349,8 @@ public class GitLabPushTrigger extends Trigger> { // executes when the Trigger receives a merge request public void onPost(final GitLabMergeRequest req) { - if (triggerOnMergeRequest) { + if (triggerOnMergeRequest && this.isBranchAllowed(req.getObjectAttribute().getTargetBranch())) { + getDescriptor().queue.execute(new Runnable() { public void run() { LOGGER.log(Level.INFO, "{0} triggered for merge request.", job.getName()); @@ -403,7 +442,7 @@ public class GitLabPushTrigger extends Trigger> { }); - } + } } private Map getDefaultParameters() { diff --git a/src/main/resources/com/dabsquared/gitlabjenkins/GitLabPushTrigger/config.jelly b/src/main/resources/com/dabsquared/gitlabjenkins/GitLabPushTrigger/config.jelly index bc68fa6..27c8a2f 100644 --- a/src/main/resources/com/dabsquared/gitlabjenkins/GitLabPushTrigger/config.jelly +++ b/src/main/resources/com/dabsquared/gitlabjenkins/GitLabPushTrigger/config.jelly @@ -1,47 +1,62 @@ - + - + - + - + - + - + - + - - + + - - + + - - - - - + + - - - - - - - - - -
+ + + + + + + + + + + + + + + + + + +
+
diff --git a/src/main/webapp/help/help-allowedBranches.html b/src/main/webapp/help/help-allowedBranches.html index d858277..2f0d469 100644 --- a/src/main/webapp/help/help-allowedBranches.html +++ b/src/main/webapp/help/help-allowedBranches.html @@ -1,3 +1,4 @@ -
- Comma-separated list of source branches allowed to trigger a build from a Push event. +

Comma-separated list of source branches allowed to trigger a build from a Push event or a Merge Request event. + If both fields are left empty, all branches are allowed to trigger this job. + For Merge Request events only the target branch name is filtered out by the include and exclude lists.

\ No newline at end of file diff --git a/src/main/webapp/help/help-filterBranchesByRegex.html b/src/main/webapp/help/help-filterBranchesByRegex.html new file mode 100644 index 0000000..99587c3 --- /dev/null +++ b/src/main/webapp/help/help-filterBranchesByRegex.html @@ -0,0 +1,9 @@ +
+
+

The target branch regex allows to limit the execution of this job to certain branches. Any branch matching the specified pattern triggers the + job. No filtering is performed if the field is left empty.

+

Examples:

+
# Allow execution for debug and release branches: (.*debug.*|.*release.*) 
+
# Ignore any branch with `Release` or `release` as subword: ^(?:(?![R|r]elease).)*$ 
+
+
\ No newline at end of file diff --git a/src/main/webapp/help/help-noBranchFiltering.html b/src/main/webapp/help/help-noBranchFiltering.html new file mode 100644 index 0000000..87202e7 --- /dev/null +++ b/src/main/webapp/help/help-noBranchFiltering.html @@ -0,0 +1,3 @@ +
+

All branches are allowed to trigger this job.

+
\ No newline at end of file diff --git a/src/test/java/com/dabsquared/gitlabjenkins/AbstractGitLabPushTriggerGitlabServerTest.java b/src/test/java/com/dabsquared/gitlabjenkins/AbstractGitLabPushTriggerGitlabServerTest.java index c43791a..959359d 100644 --- a/src/test/java/com/dabsquared/gitlabjenkins/AbstractGitLabPushTriggerGitlabServerTest.java +++ b/src/test/java/com/dabsquared/gitlabjenkins/AbstractGitLabPushTriggerGitlabServerTest.java @@ -111,13 +111,14 @@ public abstract class AbstractGitLabPushTriggerGitlabServerTest { boolean addCiMessage = true; boolean addVoteOnMergeRequest = true; boolean acceptMergeRequestOnSuccess = false; - boolean allowAllBranches = true; + String branchFilter = null; String includeBranchesSpec = null; String excludeBranchesSpec = null; + String targetBranchRegex = null; GitLabPushTrigger gitLabPushTrigger = new GitLabPushTrigger(triggerOnPush, triggerOnMergeRequest, triggerOpenMergeRequestOnPush, ciSkip, setBuildDescription, addNoteOnMergeRequest, addCiMessage, - addVoteOnMergeRequest, acceptMergeRequestOnSuccess, allowAllBranches, includeBranchesSpec, - excludeBranchesSpec); + addVoteOnMergeRequest, acceptMergeRequestOnSuccess, branchFilter, includeBranchesSpec, + excludeBranchesSpec, targetBranchRegex); return gitLabPushTrigger; }