diff options
13 files changed, 255 insertions, 71 deletions
@@ -1,5 +1,5 @@ Bitbucket Pull Request Builder Plugin -================================ +===================================== This Jenkins plugin builds pull requests from Bitbucket.org and will report the test results. @@ -7,25 +7,23 @@ This Jenkins plugin builds pull requests from Bitbucket.org and will report the Prerequisites -================================ +------------- - Jenkins 1.509.4 or higher. - https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin Creating a Job -================================= +------------- - Create a new job -- Select Git SCM -- Add Repository URL as bellow - - git@bitbucket.org:${repositoryOwner}/${repositoryName}.git -- In Branch Specifier, type as bellow - - */${sourceBranch} +- Select and configure Git SCM + - Add Repository URL, `git@bitbucket.org:${repositoryOwner}/${repositoryName}.git` + - In Branch Specifier, type `*/${sourceBranch}` - Under Build Triggers, check Bitbucket Pull Request Builder - In Cron, enter crontab for this job. - - ex: * * * * * -- In Bitbucket BasicAuth Username, write your bitbucket username like jenkins@densan-labs.net + - e.g. `* * * * *` will check for new pull requests every minute +- In Bitbucket BasicAuth Username, write your bitbucket username, like `jenkins@densan-labs.net` - In Bitbucket BasicAuth Password, write your password - In CI Identifier, enter an unique identifier among your Jenkins jobs related to the repo - In CI Name, enter a human readable name for your Jenkins server @@ -33,30 +31,46 @@ Creating a Job - Write RepositoryName - Save to preserve your changes + Merge the Pull Request's Source Branch into the Target Branch Before Building -============================================================================== -You may want Jenkins to attempt to merge your PR before doing the build -- this way it will find conflicts for you automatically. +----------------------------------------------------------------------------- + +You may want Jenkins to attempt to merge your PR before building. +This may help expose inconsistencies between the source branch and target branch. +Note that if the merge cannot be completed, the build will fail immediately. + - Follow the steps above in "Creating a Job" - In the "Source Code Management" > "Git" > "Additional Behaviors" section, click "Add" > "Merge Before Building" -- In "Name of Repository" put "origin" (or, if not using default name, use your remote repository's name. Note: unlike in the main part of the Git Repository config, you cannot leave this item blank for "default".) +- In "Name of Repository" put "origin" (or, if not using default name, use your remote repository's name. Note: unlike in the main part of the Git Repository config, you cannot leave this item blank for "default"). - In "Branch to merge to" put "${targetBranch}" - Note that as long as you don't push these changes to your remote repository, the merge only happens in your local repository. - If you are merging into your target branch, you might want Jenkins to do a new build of the Pull Request when the target branch changes. - There is a checkbox that says, "Rebuild if destination branch changes?" which enables this check. -Rerun test builds -==================== +Rerun a Build +------------- + +If you want to rerun a pull request build, write a comment on your pull request reading “test this please”. -If you want to rerun pull request test, write “test this please” comment to your pull request. +Environment Variables Provided +------------------------------ +- `sourceBranch` +- `targetBranch` +- `repositoryOwner` +- `repositoryName` +- `pullRequestId` +- `destinationRepositoryOwner` +- `destinationRepositoryName` +- `pullRequestTitle` +- `pullRequestAuthor` Contributing to Bitbucket Pull Request Builder Plugin -================================================ +----------------------------------------------------- - Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet. @@ -70,13 +84,13 @@ Contributing to Bitbucket Pull Request Builder Plugin Copyright -============================= +--------- Copyright © 2014 S.nishio. License -============================= +------- - BSD License - See COPYING file @@ -8,7 +8,7 @@ <artifactId>bitbucket-pullrequest-builder</artifactId> <name>Bitbucket Pullrequest Builder Plugin</name> - <version>1.4.17-SNAPSHOT</version> + <version>1.4.20-SNAPSHOT</version> <description>This Jenkins plugin builds pull requests from Bitbucket.org and will report the test results.</description> <packaging>hpi</packaging> <url>https://wiki.jenkins-ci.org/display/JENKINS/Bitbucket+pullrequest+builder+plugin</url> diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketAdditionalParameterEnvironmentContributor.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketAdditionalParameterEnvironmentContributor.java new file mode 100644 index 0000000..c531ca1 --- /dev/null +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketAdditionalParameterEnvironmentContributor.java @@ -0,0 +1,40 @@ +package bitbucketpullrequestbuilder.bitbucketpullrequestbuilder; + +import hudson.EnvVars; +import hudson.Extension; +import hudson.model.*; + +import java.io.IOException; + +@Extension +public class BitbucketAdditionalParameterEnvironmentContributor extends EnvironmentContributor { + @Override + public void buildEnvironmentFor(Run run, EnvVars envVars, TaskListener taskListener) + throws IOException, InterruptedException { + + BitbucketCause cause = (BitbucketCause) run.getCause(BitbucketCause.class); + if (cause == null) { + return; + } + + putEnvVar(envVars, "sourceBranch", cause.getSourceBranch()); + putEnvVar(envVars, "targetBranch", cause.getTargetBranch()); + putEnvVar(envVars, "repositoryOwner", cause.getRepositoryOwner()); + putEnvVar(envVars, "repositoryName", cause.getRepositoryName()); + putEnvVar(envVars, "pullRequestId", cause.getPullRequestId()); + putEnvVar(envVars, "destinationRepositoryOwner", cause.getDestinationRepositoryOwner()); + putEnvVar(envVars, "destinationRepositoryName", cause.getDestinationRepositoryName()); + putEnvVar(envVars, "pullRequestTitle", cause.getPullRequestTitle()); + putEnvVar(envVars, "pullRequestAuthor", cause.getPullRequestAuthor()); + + } + + private static void putEnvVar(EnvVars envs, String name, String value) { + envs.put(name, getString(value, "")); + } + + private static String getString(String actual, String d) { + return actual == null ? d : actual; + } + +} diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildFilter.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildFilter.java index c251930..d4173a2 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildFilter.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildFilter.java @@ -1,5 +1,6 @@ package bitbucketpullrequestbuilder.bitbucketpullrequestbuilder; +import hudson.model.Action; import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.ArrayList; @@ -29,6 +30,7 @@ abstract class Filter { public static final String SRC_RX = "s:(" + RX_FILTER_FLAG_SINGLE + ")?"; public static final String DST_RX = "d:(" + RX_FILTER_FLAG_SINGLE + ")?"; + public static final String AUTHOR_RX = "a:(" + RX_FILTER_FLAG_SINGLE + ")?"; public static final String BRANCH_FILTER_RX_PART = "([^\\s$]*)"; abstract public boolean apply(String filter, BitbucketCause cause); @@ -36,6 +38,20 @@ abstract class Filter { static final Pattern RX_SRC_DST_PARTS = Pattern.compile("(s:)|(d:)"); public static boolean HasSourceOrDestPartsPredicate(String filter) { return RX_SRC_DST_PARTS.matcher(filter).find(); } + + static final Pattern RX_AUTHOR_PARTS = Pattern.compile("(a:)"); + public static boolean HasAuthorPartsPredicate(String filter) { return RX_AUTHOR_PARTS.matcher(filter).find(); } + + protected boolean applyByRx(Pattern rx, Filter usedFilter, String filter, BitbucketCause cause) { + Matcher srcMatch = rx.matcher(filter); + boolean apply = false; + while (srcMatch.find()) { + String computedFilter = ((srcMatch.group(1) == null ? "" : srcMatch.group(1)) + srcMatch.group(2)).trim(); + logger.log(Level.INFO, "Apply computed filter: {0}", computedFilter); + apply = apply || (computedFilter.isEmpty() ? true : usedFilter.apply(computedFilter, cause)); + } + return apply; + } } class EmptyFilter extends Filter { @@ -84,17 +100,6 @@ class SourceDestFlag extends Filter { static final Pattern SRC_MATCHER_RX = Pattern.compile(SRC_RX + BRANCH_FILTER_RX_PART, Pattern.CASE_INSENSITIVE | Pattern.CANON_EQ); static final Pattern DST_MATCHER_RX = Pattern.compile(DST_RX + BRANCH_FILTER_RX_PART, Pattern.CASE_INSENSITIVE | Pattern.CANON_EQ); - boolean applyByRx(Pattern rx, Filter usedFilter, String filter, BitbucketCause cause) { - Matcher srcMatch = rx.matcher(filter); - boolean apply = rx.matcher(filter).matches(); - while (srcMatch.find()) { - String computedFilter = ((srcMatch.group(1) == null ? "" : srcMatch.group(1)) + srcMatch.group(2)).trim(); - logger.log(Level.INFO, "Apply computed filter: {0}", computedFilter); - apply = apply || (computedFilter.isEmpty() ? true : usedFilter.apply(computedFilter, cause)); - } - return apply; - } - @Override public boolean apply(String filter, BitbucketCause cause) { return this.applyByRx(SRC_MATCHER_RX, new OnlySourceFlag(), filter, cause) && @@ -106,6 +111,54 @@ class SourceDestFlag extends Filter { } } +class AuthorFlag extends Filter { + static final Pattern AUTHOR_MATCHER_RX = Pattern.compile(AUTHOR_RX + BRANCH_FILTER_RX_PART, Pattern.CASE_INSENSITIVE | Pattern.CANON_EQ); + + class AuthorFlagImpl extends Filter { + @Override + public boolean apply(String filter, BitbucketCause cause) { + String selectedRx = filter.startsWith(RX_FILTER_FLAG_SINGLE) ? filter.substring(RX_FILTER_FLAG_SINGLE.length()) : Pattern.quote(filter); + logger.log(Level.INFO, "AuthorFlagImpl using filter: {0}", selectedRx); + Matcher matcher = Pattern.compile(selectedRx, Pattern.CASE_INSENSITIVE).matcher(cause.getPullRequestAuthor()); + return filter.startsWith(RX_FILTER_FLAG_SINGLE) ? matcher.find() : matcher.matches(); + } + @Override + public boolean check(String filter) { return false; } + } + + @Override + public boolean apply(String filter, BitbucketCause cause) { + return this.applyByRx(AUTHOR_MATCHER_RX, new AuthorFlagImpl(), filter, cause); + } + @Override + public boolean check(String filter) { + return HasAuthorPartsPredicate(filter); + } +} + +class CombinedFlags extends Filter { + private final Filter[] _filters; + public CombinedFlags(Filter[] filters) { + _filters = filters; + } + + @Override + public boolean apply(String filter, BitbucketCause cause) { + boolean applied = true; + for(Filter f: _filters) + if (f.check(filter)) + applied = applied && f.apply(filter, cause); + return applied; + } + @Override + public boolean check(String filter) { + for(Filter f: _filters) + if (f.check(filter)) + return true; + return false; + } +} + /** * Created by maxvodo */ @@ -118,10 +171,15 @@ public class BitbucketBuildFilter { static { ArrayList<Filter> filters = new ArrayList<Filter>(); - filters.add(new AnyFlag()); + + filters.add(new AnyFlag()); + filters.add(new CombinedFlags(new Filter[] { + new SourceDestFlag(), + new AuthorFlag() + })); filters.add(new OnlyDestFlag()); - filters.add(new SourceDestFlag()); - filters.add(new EmptyFilter()); + filters.add(new EmptyFilter()); + AvailableFilters = filters; } diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java index 2375ec7..aedfb91 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java @@ -164,14 +164,6 @@ public class BitbucketBuildTrigger extends Trigger<AbstractProject<?, ?>> { public QueueTaskFuture<?> startJob(BitbucketCause cause) { Map<String, ParameterValue> values = this.getDefaultParameters(); - values.put("sourceBranch", new StringParameterValue("sourceBranch", cause.getSourceBranch())); - values.put("targetBranch", new StringParameterValue("targetBranch", cause.getTargetBranch())); - values.put("repositoryOwner", new StringParameterValue("repositoryOwner", cause.getRepositoryOwner())); - values.put("repositoryName", new StringParameterValue("repositoryName", cause.getRepositoryName())); - values.put("pullRequestId", new StringParameterValue("pullRequestId", cause.getPullRequestId())); - values.put("destinationRepositoryOwner", new StringParameterValue("destinationRepositoryOwner", cause.getDestinationRepositoryOwner())); - values.put("destinationRepositoryName", new StringParameterValue("destinationRepositoryName", cause.getDestinationRepositoryName())); - values.put("pullRequestTitle", new StringParameterValue("pullRequestTitle", cause.getPullRequestTitle())); return this.job.scheduleBuild2(0, cause, new ParametersAction(new ArrayList(values.values())), new RevisionParameterAction(cause.getSourceCommitHash())); } diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuilds.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuilds.java index 3e8e84b..ea8e892 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuilds.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuilds.java @@ -5,6 +5,7 @@ import hudson.model.AbstractBuild; import hudson.model.Cause; import hudson.model.Result; import jenkins.model.Jenkins; +import jenkins.model.JenkinsLocationConfiguration; import java.io.IOException; import java.util.logging.Level; @@ -49,7 +50,8 @@ public class BitbucketBuilds { return; } Result result = build.getResult(); - String rootUrl = Jenkins.getInstance().getRootUrl(); + JenkinsLocationConfiguration globalConfig = new JenkinsLocationConfiguration(); + String rootUrl = globalConfig.getUrl(); String buildUrl = ""; if (rootUrl == null) { logger.warning("PLEASE SET JENKINS ROOT URL IN GLOBAL CONFIGURATION FOR BUILD STATE REPORTING"); diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketCause.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketCause.java index e233371..3cb107b 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketCause.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketCause.java @@ -16,6 +16,7 @@ public class BitbucketCause extends Cause { private final String pullRequestTitle; private final String sourceCommitHash; private final String destinationCommitHash; + private final String pullRequestAuthor; public static final String BITBUCKET_URL = "https://bitbucket.org/"; public BitbucketCause(String sourceBranch, @@ -27,7 +28,8 @@ public class BitbucketCause extends Cause { String destinationRepositoryName, String pullRequestTitle, String sourceCommitHash, - String destinationCommitHash) { + String destinationCommitHash, + String pullRequestAuthor) { this.sourceBranch = sourceBranch; this.targetBranch = targetBranch; this.repositoryOwner = repositoryOwner; @@ -38,6 +40,7 @@ public class BitbucketCause extends Cause { this.pullRequestTitle = pullRequestTitle; this.sourceCommitHash = sourceCommitHash; this.destinationCommitHash = destinationCommitHash; + this.pullRequestAuthor = pullRequestAuthor; } public String getSourceBranch() { @@ -83,4 +86,8 @@ public class BitbucketCause extends Cause { description += "\">#" + this.getPullRequestId() + " " + this.getPullRequestTitle() + "</a>"; return description; } + + public String getPullRequestAuthor() { + return this.pullRequestAuthor; + } } diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java index 9b92775..660ec21 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java @@ -117,7 +117,9 @@ public class BitbucketRepository { pullRequest.getDestination().getRepository().getRepositoryName(), pullRequest.getTitle(), pullRequest.getSource().getCommit().getHash(), - pullRequest.getDestination().getCommit().getHash()); + pullRequest.getDestination().getCommit().getHash(), + pullRequest.getAuthor().getCombinedUsername() + ); setBuildStatus(cause, BuildState.INPROGRESS, Jenkins.getInstance().getRootUrl()); this.builder.getTrigger().startJob(cause); } @@ -180,12 +182,6 @@ public class BitbucketRepository { logger.log(Level.INFO, "Post comment: {0} with original content {1}", new Object[]{ content, this.client.postPullRequestComment(pullRequestId, content).getId() }); } - private boolean processTTPCommentBuildTags(String content, String buildKey) { - if (!this.isTTPCommentBuildTags(content)) return true; - logger.log(Level.INFO, "Processing ttp with build comment: {0}", content); - return !this.hasMyBuildTagInTTPComment(content, buildKey); - } - private boolean isTTPComment(String content) { return content.toLowerCase().contains(BUILD_REQUEST_MARKER.toLowerCase()); } @@ -239,6 +235,7 @@ public class BitbucketRepository { boolean rebuildCommentAvailable = false; if (comments != null) { Collection<Pullrequest.Comment> filteredComments = this.filterPullRequestComments(comments); + boolean hasMyBuildTag = false; for (Pullrequest.Comment comment : filteredComments) { String content = comment.getContent(); if (this.isTTPComment(content)) { @@ -247,10 +244,11 @@ public class BitbucketRepository { "Rebuild comment available for commit {0} and comment #{1}", new Object[]{ sourceCommit, comment.getId() } ); - } - rebuildCommentAvailable &= this.processTTPCommentBuildTags(content, buildKeyPart); - if (!rebuildCommentAvailable) break; + } + if (isTTPCommentBuildTags(content)) + hasMyBuildTag |= this.hasMyBuildTagInTTPComment(content, buildKeyPart); } + rebuildCommentAvailable &= !hasMyBuildTag; } if (rebuildCommentAvailable) this.postBuildTagInTTPComment(id, "TTP build flag", buildKeyPart); @@ -286,7 +284,8 @@ public class BitbucketRepository { pullRequest.getDestination().getRepository().getRepositoryName(), pullRequest.getTitle(), pullRequest.getSource().getCommit().getHash(), - pullRequest.getDestination().getCommit().getHash() + pullRequest.getDestination().getCommit().getHash(), + pullRequest.getAuthor().getCombinedUsername() ); //@FIXME: Way to iterate over all available SCMSources diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java index 1e8bf5c..140c213 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/bitbucket/Pullrequest.java @@ -28,6 +28,7 @@ public class Pullrequest { private String updatedOn; private String mergeCommit; private String id; + private Author author; @JsonIgnoreProperties(ignoreUnknown = true) public static class Response { @@ -233,6 +234,33 @@ public class Pullrequest { this.createdOn = createdOn; } } + + @JsonIgnoreProperties(ignoreUnknown = true) + public static class Author { + private String username; + private String display_name; + public static final String COMBINED_NAME = "%s <@%s>"; + + public String getUsername() { + return username; + } + public void setUsername(String username) { + this.username = username; + } + + @JsonProperty("display_name") + public String getDisplayName() { + return display_name; + } + + @JsonProperty("display_name") + public void setDisplayName(String display_name) { + this.display_name = display_name; + } + public String getCombinedUsername() { + return String.format(COMBINED_NAME, this.getDisplayName(), this.getUsername()); + } + } //-------------------- only getters and setters follow ----------------- @@ -341,5 +369,13 @@ public class Pullrequest { public void setId(String id) { this.id = id; } + + public Author getAuthor() { + return this.author; + } + + public void setAutohor(Author author) { + this.author = author; + } } diff --git a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilter.html b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilter.html index 88af799..30e5f5e 100644 --- a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilter.html +++ b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilter.html @@ -1,12 +1,19 @@ -Filter option in custom format. Default value is empty or "any". -Available formats: -* any pull requests applied for this project: "any", "*" or empty string. -* filtered by destination branch: "my-branch" or more complex reg-ex filter "r:^master" (must be started with "r:" and case insensitive match). -* filtered by source and destination branches: "s:source-branch d:dest-branch" -* filtered by source and destination branches with regex: "s:r:^feature d:r:master$" -* filtered by many destination/source branches: "s:one s:two s:three d:master d:r:master$" -* filtered by many sources branches: "s:one s:two s:r:^three d:" -When you using format with source branch filter "s" or destination filter "d", you must cpecify great than one source and destination filter, eg "s:1 s:2 s:... d:". -Any sources and any destinations for pull request: -* filter string: "*" -* filter string: "s: d:" +<div> + Filter option in custom format. Default value is empty or <tt>any</tt>.<br/> + Available formats: + <ul> + <li>any pull requests applied for this project: <tt>any</tt>, <tt>*</tt> or empty string</li> + <li>filtered by destination branch: <tt>my-branch</tt> or more complex reg-ex filter <tt>r:^master</tt> (must be started with <tt>r:</tt> and case insensitive match).</li> + <li>filtered by source and destination branches: <tt>s:source-branch d:dest-branch</tt></li> + <li>filtered by source and destination branches with regex: <tt>s:r:^feature d:r:master$</tt></li> + <li>filtered by many destination/source branches: <tt>s:one s:two s:three d:master d:r:master$</tt></li> + <li>filtered by many sources branches: <tt>s:one s:two s:r:^three d:</tt></li> + </ul> + <p/> + When you using format with source branch filter <tt>s</tt> or destination filter <tt>d</tt>, you must specify great than one source and destination filter, eg <tt>s:1 s:2 s:... d:</tt>.<br/> + Any sources and any destinations for pull request: + <ul> + <li>filter string: <tt>*</tt></li> + <li>filter string: <tt>s: d:</tt></li> + </ul> +</div> diff --git a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilterBySCMIncludes.html b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilterBySCMIncludes.html index 3f24419..cc9d47c 100644 --- a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilterBySCMIncludes.html +++ b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-branchesFilterBySCMIncludes.html @@ -1,3 +1,7 @@ -It is sugar-option for synchronize option "BranchesFilter" to Git SCM option "Branches to build" without manual editing. -Check this option suppose than your "BranchesFilter" field has logick equal value with Git SCM "Branches to build" option (original value from "BranchesFilter" field will e ignored). -If "Branches to build" option has values "*/master */feature-master */build-with-jenkins", then "BranchesFilter" field will have value "d:master d:feature-master d:build-with-jenkins". +Uses the Git SCM option "Branches to build" option as the value for +"BranchesFilter". If the "BranchesFilter" field itself has any content, +it will be ignored. +<br> +If the "Branches to build" option has values +"*/master */feature-master */build-with-jenkins", then "BranchesFilter" +field will have value "d:master d:feature-master d:build-with-jenkins". diff --git a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-ciSkipPhrases.html b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-ciSkipPhrases.html new file mode 100644 index 0000000..f30f306 --- /dev/null +++ b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/help-ciSkipPhrases.html @@ -0,0 +1,5 @@ +A comma-separated list of strings to search the pull request title for. +<br> +e.g. If set to "trivial,[skiptest]", any PRs containing either "trivial" or +"[skiptest]" (case-insensitive) will not be built. + diff --git a/src/test/java/BitbucketBuildFilterTest.java b/src/test/java/BitbucketBuildFilterTest.java index 3b35dbc..3a94c82 100644 --- a/src/test/java/BitbucketBuildFilterTest.java +++ b/src/test/java/BitbucketBuildFilterTest.java @@ -142,6 +142,26 @@ public class BitbucketBuildFilterTest { @Test @WithoutJenkins + public void authorFilter() { + BitbucketCause cause = EasyMock.createMock(BitbucketCause.class); + EasyMock.expect(cause.getTargetBranch()).andReturn("master").anyTimes(); + EasyMock.expect(cause.getSourceBranch()).andReturn("feature-master").anyTimes(); + EasyMock.expect(cause.getPullRequestAuthor()).andReturn("test").anyTimes(); + EasyMock.replay(cause); + + for(String f : new String[] {"a:test", "a:r:^test", "d: s: a:", "a:", "a:foo a:test"}) { + BitbucketBuildFilter filter = BitbucketBuildFilter.InstanceByString(f); + assertTrue(filter.approved(cause)); + } + + for(String f : new String[] {"s:feature-master", "d:master", "s:feature-master d: a:foo", "a:bar"}) { + BitbucketBuildFilter filter = BitbucketBuildFilter.InstanceByString(f); + assertFalse(filter.approved(cause)); + } + } + + @Test + @WithoutJenkins public void emptyGitSCMFilter() { BitbucketCause cause = EasyMock.createMock(BitbucketCause.class); EasyMock.expect(cause.getTargetBranch()).andReturn("master").anyTimes(); |