aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger.java11
-rw-r--r--src/main/java/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketRepository.java98
-rw-r--r--src/main/resources/bitbucketpullrequestbuilder/bitbucketpullrequestbuilder/BitbucketBuildTrigger/config.jelly3
-rw-r--r--src/test/java/BitbucketBuildFilterTest.java6
-rw-r--r--src/test/java/BitbucketBuildRepositoryTest.java8
5 files changed, 74 insertions, 52 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>
diff --git a/src/test/java/BitbucketBuildFilterTest.java b/src/test/java/BitbucketBuildFilterTest.java
index 3a94c82..2bc03fa 100644
--- a/src/test/java/BitbucketBuildFilterTest.java
+++ b/src/test/java/BitbucketBuildFilterTest.java
@@ -1,5 +1,7 @@
+import antlr.ANTLRException;
import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketBuildFilter;
+import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketBuildTrigger;
import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketCause;
import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketPullRequestsBuilder;
import bitbucketpullrequestbuilder.bitbucketpullrequestbuilder.BitbucketRepository;
@@ -194,8 +196,8 @@ public class BitbucketBuildFilterTest {
@Test
@WithoutJenkins
- public void filterPRComments() {
- BitbucketPullRequestsBuilder builder = EasyMock.createMock(BitbucketPullRequestsBuilder.class);
+ public void filterPRComments() throws ANTLRException {
+ BitbucketPullRequestsBuilder builder = EasyMock.createMock(BitbucketPullRequestsBuilder.class);
EasyMock.expect(builder.getTrigger()).andReturn(null).anyTimes();
EasyMock.replay(builder);
diff --git a/src/test/java/BitbucketBuildRepositoryTest.java b/src/test/java/BitbucketBuildRepositoryTest.java
index 148e504..f076c4d 100644
--- a/src/test/java/BitbucketBuildRepositoryTest.java
+++ b/src/test/java/BitbucketBuildRepositoryTest.java
@@ -119,7 +119,7 @@ public class BitbucketBuildRepositoryTest {
"", "", "",
true,
true,
- false
+ false, BitbucketRepository.DEFAULT_COMMENT_TRIGGER
);
BitbucketPullRequestsBuilder builder = EasyMock.createMock(BitbucketPullRequestsBuilder.class);
@@ -150,7 +150,7 @@ public class BitbucketBuildRepositoryTest {
"", "", "",
true,
true,
- false
+ false, BitbucketRepository.DEFAULT_COMMENT_TRIGGER
);
BitbucketPullRequestsBuilder builder = EasyMock.createMock(BitbucketPullRequestsBuilder.class);
@@ -205,7 +205,7 @@ public class BitbucketBuildRepositoryTest {
"jenkins", "Jenkins", "",
true,
true,
- false
+ false, BitbucketRepository.DEFAULT_COMMENT_TRIGGER
);
BitbucketPullRequestsBuilder builder = EasyMock.createMock(BitbucketPullRequestsBuilder.class);
@@ -252,7 +252,7 @@ public class BitbucketBuildRepositoryTest {
"jenkins-too-long-ci-key", "Jenkins", "",
true,
true,
- false
+ false, BitbucketRepository.DEFAULT_COMMENT_TRIGGER
);
final MessageDigest MD5 = MessageDigest.getInstance("MD5");