diff options
Diffstat (limited to 'src/main')
3 files changed, 66 insertions, 46 deletions
diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java index 846ecb5..34e12b2 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java @@ -51,6 +51,7 @@ public class BitbucketBuildTrigger extends Trigger<Job<?, ?>> { private final boolean checkDestinationCommit; private final boolean approveIfSuccess; private final boolean cancelOutdatedJobs; + private final String commentTrigger; transient private BitbucketPullRequestsBuilder bitbucketPullRequestsBuilder; @@ -73,7 +74,8 @@ public class BitbucketBuildTrigger extends Trigger<Job<?, ?>> { String ciSkipPhrases, boolean checkDestinationCommit, boolean approveIfSuccess, - boolean cancelOutdatedJobs + boolean cancelOutdatedJobs, + String commentTrigger ) throws ANTLRException { super(cron); this.projectPath = projectPath; @@ -91,6 +93,7 @@ public class BitbucketBuildTrigger extends Trigger<Job<?, ?>> { this.checkDestinationCommit = checkDestinationCommit; this.approveIfSuccess = approveIfSuccess; this.cancelOutdatedJobs = cancelOutdatedJobs; + this.commentTrigger = commentTrigger; } public String getProjectPath() { @@ -152,6 +155,12 @@ public class BitbucketBuildTrigger extends Trigger<Job<?, ?>> { public boolean getCancelOutdatedJobs() { return cancelOutdatedJobs; } + /** + * @return a phrase that when entered in a comment will trigger a new build + */ + public String getCommentTrigger() { + return commentTrigger; + } @Override public void start(Job<?, ?> project, boolean newInstance) { diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java index 660ec21..01da88e 100644 --- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java +++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java @@ -35,16 +35,19 @@ 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?(.*)\\]"; + /** + * Default value for comment trigger. + */ + public static final String DEFAULT_COMMENT_TRIGGER = "test this please"; private String projectPath; private BitbucketPullRequestsBuilder builder; private BitbucketBuildTrigger trigger; private ApiClient client; - + public BitbucketRepository(String projectPath, BitbucketPullRequestsBuilder builder) { this.projectPath = projectPath; this.builder = builder; @@ -53,26 +56,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 +85,7 @@ public class BitbucketRepository { trigger.getCiName(), httpFactory ); - + } else this.client = client; } @@ -97,7 +100,7 @@ public class BitbucketRepository { } return targetPullRequests; } - + public ApiClient getClient() { return this.client; } @@ -148,23 +151,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 +175,45 @@ 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()); + // special case: in unit tests, trigger is null and can't be mocked + String commentTrigger = DEFAULT_COMMENT_TRIGGER; + if(trigger != null && StringUtils.isNotBlank(trigger.getCommentTrigger())) { + commentTrigger = trigger.getCommentTrigger(); + } + return content.toLowerCase().contains(commentTrigger); } - + 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 +232,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 +246,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 +295,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); } diff --git a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly index 971954f..97e5d5c 100644 --- a/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly +++ b/src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly @@ -41,4 +41,7 @@ <f:entry title="Cancel outdated jobs?" field="cancelOutdatedJobs"> <f:checkbox default="false"/> </f:entry> + <f:entry title="Comment phrase to trigger build" field="commentTrigger"> + <f:textbox default="test this please"/> + </f:entry> </j:jelly> |