@@ -94,6 +94,9 @@ public Collection<StashPullRequestResponseValue> getTargetPullRequests() {
94
94
List <StashPullRequestResponseValue > targetPullRequests =
95
95
new ArrayList <StashPullRequestResponseValue >();
96
96
97
+ // Fetch "OPEN" pull requests from the server. Failure to get the list will
98
+ // prevent builds from being scheduled. However, the call will be retried
99
+ // during the next cycle, as determined by the cron settings.
97
100
List <StashPullRequestResponseValue > pullRequests ;
98
101
try {
99
102
pullRequests = client .getPullRequests ();
@@ -110,7 +113,15 @@ public Collection<StashPullRequestResponseValue> getTargetPullRequests() {
110
113
return targetPullRequests ;
111
114
}
112
115
113
- public String postBuildStartCommentTo (StashPullRequestResponseValue pullRequest ) {
116
+ /**
117
+ * Post "BuildStarted" comment to Bitbucket Server
118
+ *
119
+ * @param pullRequest pull request
120
+ * @return comment ID
121
+ * @throws StashApiException if posting the comment fails
122
+ */
123
+ public String postBuildStartCommentTo (StashPullRequestResponseValue pullRequest )
124
+ throws StashApiException {
114
125
String sourceCommit = pullRequest .getFromRef ().getLatestCommit ();
115
126
String destinationCommit = pullRequest .getToRef ().getLatestCommit ();
116
127
String comment =
@@ -269,6 +280,9 @@ public void addFutureBuildTasks(Collection<StashPullRequestResponseValue> pullRe
269
280
for (StashPullRequestResponseValue pullRequest : pullRequests ) {
270
281
Map <String , String > additionalParameters ;
271
282
283
+ // Get parameter values for the build from the pull request comments.
284
+ // Failure to do so causes the build to be skipped, as we would not run
285
+ // the build with incorrect parameters.
272
286
try {
273
287
additionalParameters = getAdditionalParameters (pullRequest );
274
288
} catch (StashApiException e ) {
@@ -281,6 +295,8 @@ public void addFutureBuildTasks(Collection<StashPullRequestResponseValue> pullRe
281
295
continue ;
282
296
}
283
297
298
+ // Delete comments about previous build results, if that option is
299
+ // enabled. Run the build even if those comments cannot be deleted.
284
300
if (trigger .getDeletePreviousBuildFinishComments ()) {
285
301
try {
286
302
deletePreviousBuildFinishedComments (pullRequest );
@@ -294,7 +310,25 @@ public void addFutureBuildTasks(Collection<StashPullRequestResponseValue> pullRe
294
310
}
295
311
}
296
312
297
- String commentId = postBuildStartCommentTo (pullRequest );
313
+ // Post a comment indicating the build start. Strictly speaking, we are
314
+ // just adding the build to the queue, it will start after the quiet time
315
+ // expires and there are executors available. Failure to post the comment
316
+ // prevents the build for safety reasons. If the plugin cannot post this
317
+ // comment, chances are it won't be able to post the build results, which
318
+ // would trigger the build again and again, wasting Jenkins resources.
319
+ String commentId ;
320
+ try {
321
+ commentId = postBuildStartCommentTo (pullRequest );
322
+ } catch (StashApiException e ) {
323
+ logger .log (
324
+ Level .INFO ,
325
+ format (
326
+ "%s: cannot post Build Start comment for pull request %s, not building" ,
327
+ job .getName (), pullRequest .getId ()),
328
+ e );
329
+ continue ;
330
+ }
331
+
298
332
StashCause cause =
299
333
new StashCause (
300
334
trigger .getStashHost (),
@@ -315,7 +349,15 @@ public void addFutureBuildTasks(Collection<StashPullRequestResponseValue> pullRe
315
349
}
316
350
}
317
351
318
- public void deletePullRequestComment (String pullRequestId , String commentId ) {
352
+ /**
353
+ * Deletes pull request comment from Bitbucket Server
354
+ *
355
+ * @param pullRequestId pull request ID
356
+ * @param commentId comment to be deleted
357
+ * @throws StashApiException if deleting the comment fails
358
+ */
359
+ public void deletePullRequestComment (String pullRequestId , String commentId )
360
+ throws StashApiException {
319
361
this .client .deletePullRequestComment (pullRequestId , commentId );
320
362
}
321
363
@@ -359,14 +401,41 @@ public void postFinishedComment(
359
401
360
402
comment = comment .concat (additionalComment );
361
403
362
- this .client .postPullRequestComment (pullRequestId , comment );
404
+ // Post the "Build Finished" comment. Failure to post it can lead to
405
+ // scheduling another build for the pull request unnecessarily.
406
+ try {
407
+ this .client .postPullRequestComment (pullRequestId , comment );
408
+ } catch (StashApiException e ) {
409
+ logger .log (
410
+ Level .WARNING ,
411
+ format (
412
+ "%s: cannot post Build Finished comment for pull request %s" ,
413
+ job .getDisplayName (), pullRequestId ),
414
+ e );
415
+ }
363
416
}
364
417
365
- public boolean mergePullRequest (String pullRequestId , String version ) {
418
+ /**
419
+ * Instructs Bitbucket Server to merge pull request
420
+ *
421
+ * @param pullRequestId pull request ID
422
+ * @param version pull request version
423
+ * @return true if the merge succeeds, false if the server reports an error
424
+ * @throws StashApiException if cannot communicate to the server
425
+ */
426
+ public boolean mergePullRequest (String pullRequestId , String version ) throws StashApiException {
366
427
return this .client .mergePullRequest (pullRequestId , version );
367
428
}
368
429
369
- private boolean isPullRequestMergeable (StashPullRequestResponseValue pullRequest ) {
430
+ /**
431
+ * Inquiries Bitbucket Server whether the pull request can be merged
432
+ *
433
+ * @param pullRequest pull request
434
+ * @return true if the merge is allowed, false otherwise
435
+ * @throws StashApiException if cannot communicate to the server
436
+ */
437
+ private boolean isPullRequestMergeable (StashPullRequestResponseValue pullRequest )
438
+ throws StashApiException {
370
439
if (trigger .getCheckMergeable ()
371
440
|| trigger .getCheckNotConflicted ()
372
441
|| trigger .getCheckProbeMergeStatus ()) {
@@ -454,8 +523,21 @@ private boolean isBuildTarget(StashPullRequestResponseValue pullRequest) {
454
523
return false ;
455
524
}
456
525
457
- if (!isPullRequestMergeable (pullRequest )) {
458
- logger .info ("Skipping PR: " + pullRequest .getId () + " as cannot be merged" );
526
+ // Check whether the pull request can be merged and whether it's in the
527
+ // "conflicted" state. If that information cannot be retrieved, don't build
528
+ // the pull request in this cycle.
529
+ try {
530
+ if (!isPullRequestMergeable (pullRequest )) {
531
+ logger .info ("Skipping PR: " + pullRequest .getId () + " as cannot be merged" );
532
+ return false ;
533
+ }
534
+ } catch (StashApiException e ) {
535
+ logger .log (
536
+ Level .INFO ,
537
+ format (
538
+ "%s: cannot determine if pull request %s can be merged, skipping" ,
539
+ job .getDisplayName (), pullRequest .getId ()),
540
+ e );
459
541
return false ;
460
542
}
461
543
@@ -473,6 +555,10 @@ private boolean isBuildTarget(StashPullRequestResponseValue pullRequest) {
473
555
String destinationCommit = destination .getLatestCommit ();
474
556
475
557
String id = pullRequest .getId ();
558
+
559
+ // Fetch all comments for the pull request. If it fails, don't build the
560
+ // pull request in this cycle, as it cannot be determined if it should be
561
+ // built without checking the comments.
476
562
List <StashPullRequestComment > comments ;
477
563
try {
478
564
comments = client .getPullRequestComments (owner , repositoryName , id );
0 commit comments