From 564b6681dffd561facc63be256e88514f52c9e1b Mon Sep 17 00:00:00 2001 From: Nicholas Blair Date: Fri, 29 May 2015 13:53:07 -0500 Subject: Parameterize comment phrase to trigger a build Defaults to prior "test this please", can be overridden in the job configuration. --- .../BitbucketBuildTrigger.java | 104 ++++++++++++++------- .../BitbucketRepository.java | 89 +++++++++--------- 2 files changed, 115 insertions(+), 78 deletions(-) (limited to 'src') 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> { + /** + * 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> { 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> { public String getBranchesFilter() { return branchesFilter; } - + public boolean getBranchesFilterBySCMIncludes() { return branchesFilterBySCMIncludes; } @@ -136,7 +168,13 @@ public class BitbucketBuildTrigger extends Trigger> { } 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 void init(T httpFactory) { this.init(null, httpFactory); } - + public void init(ApiClient client) { this.init(client, null); } - + public 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 getAvailableBuildTagsFromTTPComment(String buildTags) { logger.log(Level.INFO, "Parse {0}", new Object[]{ buildTags }); - List availableBuildTags = new LinkedList(); + List availableBuildTags = new LinkedList(); 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 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 filterPullRequestComments(List comments) { logger.info("Filter PullRequest Comments."); Collections.sort(comments); - Collections.reverse(comments); - List filteredComments = new LinkedList(); + Collections.reverse(comments); + List filteredComments = new LinkedList(); 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 sources = new LinkedList(); 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); } -- cgit v1.2.3