diff options
Diffstat (limited to 'src/main')
10 files changed, 200 insertions, 50 deletions
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. + |