diff options
author | Nicholas Blair <nicholas.blair@wisc.edu> | 2015-05-29 13:53:07 -0500 |
---|---|---|
committer | Nicholas Blair <nicholas.blair@gmail.com> | 2017-02-18 15:18:14 -0600 |
commit | 564b6681dffd561facc63be256e88514f52c9e1b (patch) | |
tree | f37b03564da0efc253b6fa76519a3caf61d46304 /src/main/java/bitbucketpullrequestbuilder | |
parent | 325f247ceb7b0f60df6e061343cda89758f9ef19 (diff) | |
download | bbprb-564b6681dffd561facc63be256e88514f52c9e1b.tar.gz |
Parameterize comment phrase to trigger a build
Defaults to prior "test this please", can be overridden in the job
configuration.
Diffstat (limited to 'src/main/java/bitbucketpullrequestbuilder')
2 files changed, 115 insertions, 78 deletions
diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java index aedfb91..10d6c98 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java @@ -28,6 +28,11 @@ import static com.cloudbees.plugins.credentials.CredentialsMatchers.instanceOf; * Created by nishio */ public class BitbucketBuildTrigger extends Trigger<AbstractProject<?, ?>> { + /** + * Default value for {@link #getCommentTrigger()}. + */ + public static final String DEFAULT_COMMENT_TRIGGER = "test this please"; + private static final Logger logger = Logger.getLogger(BitbucketBuildTrigger.class.getName()); private final String projectPath; private final String cron; @@ -43,44 +48,71 @@ public class BitbucketBuildTrigger extends Trigger<AbstractProject<?, ?>> { private final String ciSkipPhrases; private final boolean checkDestinationCommit; private final boolean approveIfSuccess; + private final String commentTrigger; transient private BitbucketPullRequestsBuilder bitbucketPullRequestsBuilder; @Extension - public static final BitbucketBuildTriggerDescriptor descriptor = new BitbucketBuildTriggerDescriptor(); + public static final BitbucketBuildTriggerDescriptor descriptor = new BitbucketBuildTriggerDescriptor(); + /** + * Sets {@link #getCommentTrigger()} to {@link #DEFAULT_COMMENT_TRIGGER}. + */ + @DataBoundConstructor + public BitbucketBuildTrigger( + String projectPath, + String cron, + String credentialsId, + String username, + String password, + String repositoryOwner, + String repositoryName, + String branchesFilter, + boolean branchesFilterBySCMIncludes, + String ciKey, + String ciName, + String ciSkipPhrases, + boolean checkDestinationCommit, + boolean approveIfSuccess + ) throws ANTLRException { + this(projectPath, cron, credentialsId, username, password, repositoryOwner, repositoryName, + branchesFilter, branchesFilterBySCMIncludes, ciKey, ciName, ciSkipPhrases, + checkDestinationCommit, approveIfSuccess, DEFAULT_COMMENT_TRIGGER); + } @DataBoundConstructor public BitbucketBuildTrigger( - String projectPath, - String cron, - String credentialsId, - String username, - String password, - String repositoryOwner, - String repositoryName, - String branchesFilter, - boolean branchesFilterBySCMIncludes, - String ciKey, - String ciName, - String ciSkipPhrases, - boolean checkDestinationCommit, - boolean approveIfSuccess - ) throws ANTLRException { - super(cron); - this.projectPath = projectPath; - this.cron = cron; - this.credentialsId = credentialsId; - this.username = username; - this.password = password; - this.repositoryOwner = repositoryOwner; - this.repositoryName = repositoryName; - this.branchesFilter = branchesFilter; - this.branchesFilterBySCMIncludes = branchesFilterBySCMIncludes; - this.ciKey = ciKey; - this.ciName = ciName; - this.ciSkipPhrases = ciSkipPhrases; - this.checkDestinationCommit = checkDestinationCommit; - this.approveIfSuccess = approveIfSuccess; + String projectPath, + String cron, + String credentialsId, + String username, + String password, + String repositoryOwner, + String repositoryName, + String branchesFilter, + boolean branchesFilterBySCMIncludes, + String ciKey, + String ciName, + String ciSkipPhrases, + boolean checkDestinationCommit, + boolean approveIfSuccess, + String commentTrigger + ) throws ANTLRException { + super(cron); + this.projectPath = projectPath; + this.cron = cron; + this.credentialsId = credentialsId; + this.username = username; + this.password = password; + this.repositoryOwner = repositoryOwner; + this.repositoryName = repositoryName; + this.branchesFilter = branchesFilter; + this.branchesFilterBySCMIncludes = branchesFilterBySCMIncludes; + this.ciKey = ciKey; + this.ciName = ciName; + this.ciSkipPhrases = ciSkipPhrases; + this.checkDestinationCommit = checkDestinationCommit; + this.approveIfSuccess = approveIfSuccess; + this.commentTrigger = commentTrigger; } public String getProjectPath() { @@ -114,7 +146,7 @@ public class BitbucketBuildTrigger extends Trigger<AbstractProject<?, ?>> { public String getBranchesFilter() { return branchesFilter; } - + public boolean getBranchesFilterBySCMIncludes() { return branchesFilterBySCMIncludes; } @@ -136,7 +168,13 @@ public class BitbucketBuildTrigger extends Trigger<AbstractProject<?, ?>> { } public boolean getApproveIfSuccess() { - return approveIfSuccess; + return approveIfSuccess; + } + /** + * @return a phrase that when entered in a comment will trigger a new build + */ + public String getCommentTrigger() { + return commentTrigger; } @Override diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java index 660ec21..ee11e75 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java @@ -35,7 +35,6 @@ import static com.cloudbees.plugins.credentials.CredentialsMatchers.instanceOf; public class BitbucketRepository { private static final Logger logger = Logger.getLogger(BitbucketRepository.class.getName()); private static final String BUILD_DESCRIPTION = "%s: %s into %s"; - private static final String BUILD_REQUEST_MARKER = "test this please"; private static final String BUILD_REQUEST_DONE_MARKER = "ttp build flag"; private static final String BUILD_REQUEST_MARKER_TAG_SINGLE_RX = "\\#[\\w\\-\\d]+"; private static final String BUILD_REQUEST_MARKER_TAGS_RX = "\\[bid\\:\\s?(.*)\\]"; @@ -44,7 +43,7 @@ public class BitbucketRepository { private BitbucketPullRequestsBuilder builder; private BitbucketBuildTrigger trigger; private ApiClient client; - + public BitbucketRepository(String projectPath, BitbucketPullRequestsBuilder builder) { this.projectPath = projectPath; this.builder = builder; @@ -53,26 +52,26 @@ public class BitbucketRepository { public void init() { this.init(null, null); } - + public <T extends ApiClient.HttpClientFactory> void init(T httpFactory) { this.init(null, httpFactory); } - + public void init(ApiClient client) { this.init(client, null); } - + public <T extends ApiClient.HttpClientFactory> void init(ApiClient client, T httpFactory) { this.trigger = this.builder.getTrigger(); - - if (client == null) { + + if (client == null) { String username = trigger.getUsername(); - String password = trigger.getPassword(); + String password = trigger.getPassword(); StandardUsernamePasswordCredentials credentials = getCredentials(trigger.getCredentialsId()); if (credentials != null) { username = credentials.getUsername(); password = credentials.getPassword().getPlainText(); - } + } this.client = new ApiClient( username, password, @@ -82,7 +81,7 @@ public class BitbucketRepository { trigger.getCiName(), httpFactory ); - + } else this.client = client; } @@ -97,7 +96,7 @@ public class BitbucketRepository { } return targetPullRequests; } - + public ApiClient getClient() { return this.client; } @@ -148,23 +147,23 @@ public class BitbucketRepository { public void postPullRequestApproval(String pullRequestId) { this.client.postPullRequestApproval(pullRequestId); } - + public String getMyBuildTag(String buildKey) { return "#" + this.client.buildStatusKey(buildKey); - } - + } + final static Pattern BUILD_TAGS_RX = Pattern.compile(BUILD_REQUEST_MARKER_TAGS_RX, Pattern.CASE_INSENSITIVE | Pattern.CANON_EQ); - final static Pattern SINGLE_BUILD_TAG_RX = Pattern.compile(BUILD_REQUEST_MARKER_TAG_SINGLE_RX, Pattern.CASE_INSENSITIVE | Pattern.CANON_EQ); - final static String CONTENT_PART_TEMPLATE = "```[bid: %s]```"; - + final static Pattern SINGLE_BUILD_TAG_RX = Pattern.compile(BUILD_REQUEST_MARKER_TAG_SINGLE_RX, Pattern.CASE_INSENSITIVE | Pattern.CANON_EQ); + final static String CONTENT_PART_TEMPLATE = "```[bid: %s]```"; + private List<String> getAvailableBuildTagsFromTTPComment(String buildTags) { logger.log(Level.INFO, "Parse {0}", new Object[]{ buildTags }); - List<String> availableBuildTags = new LinkedList<String>(); + List<String> availableBuildTags = new LinkedList<String>(); Matcher subBuildTagMatcher = SINGLE_BUILD_TAG_RX.matcher(buildTags); while(subBuildTagMatcher.find()) availableBuildTags.add(subBuildTagMatcher.group(0).trim()); return availableBuildTags; } - + public boolean hasMyBuildTagInTTPComment(String content, String buildKey) { Matcher tagsMatcher = BUILD_TAGS_RX.matcher(content); if (tagsMatcher.find()) { @@ -172,40 +171,40 @@ public class BitbucketRepository { return this.getAvailableBuildTagsFromTTPComment(tagsMatcher.group(1).trim()).contains(this.getMyBuildTag(buildKey)); } else return false; - } - - private void postBuildTagInTTPComment(String pullRequestId, String content, String buildKey) { + } + + private void postBuildTagInTTPComment(String pullRequestId, String content, String buildKey) { logger.log(Level.INFO, "Update build tag for {0} build key", buildKey); List<String> builds = this.getAvailableBuildTagsFromTTPComment(content); - builds.add(this.getMyBuildTag(buildKey)); + builds.add(this.getMyBuildTag(buildKey)); content += " " + String.format(CONTENT_PART_TEMPLATE, StringUtils.join(builds, " ")); logger.log(Level.INFO, "Post comment: {0} with original content {1}", new Object[]{ content, this.client.postPullRequestComment(pullRequestId, content).getId() }); } - + private boolean isTTPComment(String content) { - return content.toLowerCase().contains(BUILD_REQUEST_MARKER.toLowerCase()); + return content.toLowerCase().contains(trigger.getCommentTrigger().toLowerCase()); } - + private boolean isTTPCommentBuildTags(String content) { return content.toLowerCase().contains(BUILD_REQUEST_DONE_MARKER.toLowerCase()); } - + public List<Pullrequest.Comment> filterPullRequestComments(List<Pullrequest.Comment> comments) { logger.info("Filter PullRequest Comments."); Collections.sort(comments); - Collections.reverse(comments); - List<Pullrequest.Comment> filteredComments = new LinkedList<Pullrequest.Comment>(); + Collections.reverse(comments); + List<Pullrequest.Comment> filteredComments = new LinkedList<Pullrequest.Comment>(); for(Pullrequest.Comment comment : comments) { String content = comment.getContent(); - if (content == null || content.isEmpty()) continue; - boolean isTTP = this.isTTPComment(content); - boolean isTTPBuild = this.isTTPCommentBuildTags(content); + if (content == null || content.isEmpty()) continue; + boolean isTTP = this.isTTPComment(content); + boolean isTTPBuild = this.isTTPCommentBuildTags(content); if (isTTP || isTTPBuild) filteredComments.add(comment); if (isTTP) break; } return filteredComments; } - + private boolean isBuildTarget(Pullrequest pullRequest) { if (pullRequest.getState() != null && pullRequest.getState().equals("OPEN")) { if (isSkipBuild(pullRequest.getTitle()) || !isFilteredBuild(pullRequest)) { @@ -224,8 +223,8 @@ public class BitbucketRepository { final boolean commitAlreadyBeenProcessed = this.client.hasBuildStatus( sourceRepository.getOwnerName(), sourceRepository.getRepositoryName(), sourceCommit, buildKeyPart ); - if (commitAlreadyBeenProcessed) logger.log(Level.INFO, - "Commit {0}#{1} has already been processed", + if (commitAlreadyBeenProcessed) logger.log(Level.INFO, + "Commit {0}#{1} has already been processed", new Object[]{ sourceCommit, buildKeyPart } ); @@ -238,18 +237,18 @@ public class BitbucketRepository { boolean hasMyBuildTag = false; for (Pullrequest.Comment comment : filteredComments) { String content = comment.getContent(); - if (this.isTTPComment(content)) { + if (this.isTTPComment(content)) { rebuildCommentAvailable = true; - logger.log(Level.INFO, - "Rebuild comment available for commit {0} and comment #{1}", + logger.log(Level.INFO, + "Rebuild comment available for commit {0} and comment #{1}", new Object[]{ sourceCommit, comment.getId() } - ); + ); } if (isTTPCommentBuildTags(content)) hasMyBuildTag |= this.hasMyBuildTagInTTPComment(content, buildKeyPart); } rebuildCommentAvailable &= !hasMyBuildTag; - } + } if (rebuildCommentAvailable) this.postBuildTagInTTPComment(id, "TTP build flag", buildKeyPart); final boolean canBuildTarget = rebuildCommentAvailable || !commitAlreadyBeenProcessed; @@ -287,17 +286,17 @@ public class BitbucketRepository { pullRequest.getDestination().getCommit().getHash(), pullRequest.getAuthor().getCombinedUsername() ); - + //@FIXME: Way to iterate over all available SCMSources List<SCMSource> sources = new LinkedList<SCMSource>(); for(SCMSourceOwner owner : SCMSourceOwners.all()) for(SCMSource src : owner.getSCMSources()) - sources.add(src); - - BitbucketBuildFilter filter = !this.trigger.getBranchesFilterBySCMIncludes() ? + sources.add(src); + + BitbucketBuildFilter filter = !this.trigger.getBranchesFilterBySCMIncludes() ? BitbucketBuildFilter.InstanceByString(this.trigger.getBranchesFilter()) : BitbucketBuildFilter.InstanceBySCM(sources, this.trigger.getBranchesFilter()); - + return filter.approved(cause); } |