aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java
diff options
context:
space:
mode:
authorMaxim Epishchev <epishev@garant.ru>2016-01-26 19:06:59 +0300
committerMaxim Epishchev <epishev@garant.ru>2016-01-26 19:06:59 +0300
commit96ab7a75f14d9990f3c8f1255f9790c496a64473 (patch)
tree439700ff0d73f9040723e7a5db43eb533c1237cd /src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java
parent91a85604177f7df2eb204c9e82564142dbe328f8 (diff)
downloadbbprb-96ab7a75f14d9990f3c8f1255f9790c496a64473.tar.gz
Bugfixes issue for continuously rebuilding PR
If available TTP (aka "test this please") comment Jenkins PR builder continuously rebuilding PR. Now Jenkins post specific build comment. If you want to rebuild already rebuilded PR, post new TTP comment.
Diffstat (limited to 'src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java')
-rw-r--r--src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java127
1 files changed, 100 insertions, 27 deletions
diff --git a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java
index c71cc99..6736ee9 100644
--- a/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java
+++ b/src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java
@@ -9,11 +9,15 @@ import java.util.logging.Logger;
import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.ApiClient;
import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.BuildState;
import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.bitbucket.Pullrequest;
+import java.util.LinkedList;
import java.util.logging.Level;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import jenkins.model.Jenkins;
import jenkins.scm.api.SCMSource;
+import jenkins.scm.api.SCMSourceOwner;
+import jenkins.scm.api.SCMSourceOwners;
+import org.apache.commons.lang.StringUtils;
/**
* Created by nishio
@@ -22,7 +26,9 @@ 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_MARKER_COUNTER_RX = "\\[(\\d+)]\\";
+ 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?(.*)\\]";
private String projectPath;
private BitbucketPullRequestsBuilder builder;
@@ -35,15 +41,19 @@ public class BitbucketRepository {
}
public void init() {
- trigger = this.builder.getTrigger();
- client = new ApiClient(
+ this.init(null);
+ }
+
+ public void init(ApiClient client) {
+ this.trigger = this.builder.getTrigger();
+ this.client = (client == null) ? new ApiClient(
trigger.getUsername(),
trigger.getPassword(),
trigger.getRepositoryOwner(),
trigger.getRepositoryName(),
trigger.getCiKey(),
trigger.getCiName()
- );
+ ) : client;
}
public Collection<Pullrequest> getTargetPullRequests() {
@@ -102,10 +112,68 @@ public class BitbucketRepository {
public void postPullRequestApproval(String pullRequestId) {
this.client.postPullRequestApproval(pullRequestId);
}
-
- private Integer extractRebuildTimesFromComment(String content) {
- Matcher matcher = Pattern.compile(BUILD_REQUEST_MARKER_COUNTER_RX).matcher(content);
- return matcher.groupCount() >= 1 ? Integer.parseInt(matcher.group(1)) : 0;
+
+ 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]```";
+
+ private List<String> getAvailableBuildTagsFromTTPComment(String buildTags) {
+ logger.log(Level.INFO, "Parse {0}", new Object[]{ buildTags });
+ 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()) {
+ logger.log(Level.INFO, "Content {0} g[1]:{1} mykey:{2}", new Object[] { content, tagsMatcher.group(1).trim(), this.getMyBuildTag(buildKey) });
+ return this.getAvailableBuildTagsFromTTPComment(tagsMatcher.group(1).trim()).contains(this.getMyBuildTag(buildKey));
+ }
+ else return false;
+ }
+
+ 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));
+ 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 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());
+ }
+
+ 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>();
+ 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 (isTTP || isTTPBuild) filteredComments.add(comment);
+ if (isTTP) break;
+ }
+ return filteredComments;
}
private boolean isBuildTarget(Pullrequest pullRequest) {
@@ -121,41 +189,40 @@ public class BitbucketRepository {
String repositoryName = destination.getRepository().getRepositoryName();
Pullrequest.Repository sourceRepository = source.getRepository();
+ String buildKeyPart = this.builder.getProjectId();
- boolean commitAlreadyBeenProcessed = this.client.hasBuildStatus(
- sourceRepository.getOwnerName(), sourceRepository.getRepositoryName(), sourceCommit, this.builder.getProjectId()
+ 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",
- new Object[]{ sourceCommit, this.builder.getProjectId() }
+ new Object[]{ sourceCommit, buildKeyPart }
);
- String id = pullRequest.getId();
+ final String id = pullRequest.getId();
List<Pullrequest.Comment> comments = client.getPullRequestComments(owner, repositoryName, id);
boolean rebuildCommentAvailable = false;
if (comments != null) {
- Collections.sort(comments);
- Collections.reverse(comments);
- for (Pullrequest.Comment comment : comments) {
+ Collection<Pullrequest.Comment> filteredComments = this.filterPullRequestComments(comments);
+ for (Pullrequest.Comment comment : filteredComments) {
String content = comment.getContent();
- if (content == null || content.isEmpty()) {
- continue;
- }
-
- if (content.contains(BUILD_REQUEST_MARKER.toLowerCase())) {
+ if (this.isTTPComment(content)) {
rebuildCommentAvailable = true;
logger.log(Level.INFO,
"Rebuild comment available for commit {0} and comment #{1}",
new Object[]{ sourceCommit, comment.getId() }
- );
- this.client.deleteComment(id, Integer.toString(comment.getId()));
- }
+ );
+ }
+ rebuildCommentAvailable &= this.processTTPCommentBuildTags(content, buildKeyPart);
+ if (!rebuildCommentAvailable) break;
}
- }
+ }
+ if (rebuildCommentAvailable) this.postBuildTagInTTPComment(id, "TTP build flag", buildKeyPart);
- logger.log(Level.INFO, "Build target? {0}", rebuildCommentAvailable || !commitAlreadyBeenProcessed);
- return rebuildCommentAvailable || !commitAlreadyBeenProcessed;
+ final boolean canBuildTarget = rebuildCommentAvailable || !commitAlreadyBeenProcessed;
+ logger.log(Level.INFO, "Build target? {0} [rebuild:{1} processed:{2}]", new Object[]{ canBuildTarget, rebuildCommentAvailable, commitAlreadyBeenProcessed});
+ return canBuildTarget;
}
return false;
@@ -188,9 +255,15 @@ public class BitbucketRepository {
pullRequest.getDestination().getCommit().getHash()
);
+ //@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() ?
BitbucketBuildFilter.InstanceByString(this.trigger.getBranchesFilter()) :
- BitbucketBuildFilter.InstanceBySCM(Jenkins.getInstance().getExtensionList(SCMSource.class), this.trigger.getBranchesFilter());
+ BitbucketBuildFilter.InstanceBySCM(sources, this.trigger.getBranchesFilter());
return filter.approved(cause);
}