246 }
247
248 private Optional<String> getReviewersList(List<Review> reviews) {
249 var reviewers = reviews.stream()
250 .filter(review -> review.verdict() == Review.Verdict.APPROVED)
251 .map(review -> {
252 var entry = " * " + formatReviewer(review.reviewer());
253 if (!review.hash().equals(pr.headHash())) {
254 entry += " **Note!** Review applies to " + review.hash();
255 }
256 return entry;
257 })
258 .collect(Collectors.joining("\n"));
259 if (reviewers.length() > 0) {
260 return Optional.of(reviewers);
261 } else {
262 return Optional.empty();
263 }
264 }
265
266 private String getStatusMessage(List<Review> reviews, PullRequestCheckIssueVisitor visitor) {
267 var progressBody = new StringBuilder();
268 progressBody.append("## Progress\n");
269 progressBody.append(getChecksList(visitor));
270
271 var issue = Issue.fromString(pr.title());
272 if (issueProject != null && issue.isPresent()) {
273 progressBody.append("\n\n## Issue\n");
274 var iss = issueProject.issue(issue.get().id());
275 if (iss.isPresent()) {
276 progressBody.append("[");
277 progressBody.append(iss.get().id());
278 progressBody.append("](");
279 progressBody.append(iss.get().webUrl());
280 progressBody.append("): ");
281 progressBody.append(iss.get().title());
282 progressBody.append("\n");
283 } else {
284 progressBody.append("⚠️ Failed to retrieve information on issue `");
285 progressBody.append(issue.get().id());
286 progressBody.append("`.\n");
287 }
288 }
289
290 getReviewersList(reviews).ifPresent(reviewers -> {
291 progressBody.append("\n\n## Approvers\n");
292 progressBody.append(reviewers);
293 });
294
295 return progressBody.toString();
296 }
297
298 private String updateStatusMessage(String message) {
299 var description = pr.body();
300 var markerIndex = description.lastIndexOf(progressMarker);
301
302 if (markerIndex >= 0 && description.substring(markerIndex).equals(message)) {
303 log.info("Progress already up to date");
304 return description;
305 }
306 var newBody = (markerIndex < 0 ?
460 pr.createCheck(checkBuilder.build());
461 var localHash = prInstance.commit(censusInstance.namespace(), censusDomain, null);
462
463 // Try to rebase
464 boolean rebasePossible = true;
465 var ignored = new PrintWriter(new StringWriter());
466 var rebasedHash = prInstance.rebase(localHash, ignored);
467 if (rebasedHash.isEmpty()) {
468 rebasePossible = false;
469 } else {
470 localHash = rebasedHash.get();
471 }
472
473 // Determine current status
474 var visitor = prInstance.executeChecks(localHash, censusInstance);
475 var additionalErrors = botSpecificChecks();
476 updateCheckBuilder(checkBuilder, visitor, additionalErrors);
477 updateReadyForReview(visitor, additionalErrors);
478
479 // Calculate and update the status message if needed
480 var statusMessage = getStatusMessage(activeReviews, visitor);
481 var updatedBody = updateStatusMessage(statusMessage);
482
483 // Post / update approval messages (only needed if the review itself can't contain a body)
484 if (!pr.repository().forge().supportsReviewBody()) {
485 updateReviewedMessages(comments, allReviews);
486 }
487
488 var commit = prInstance.localRepo().lookup(localHash).orElseThrow();
489 var commitMessage = String.join("\n", commit.message());
490 var readyForIntegration = visitor.getMessages().isEmpty() && additionalErrors.isEmpty();
491 updateMergeReadyComment(readyForIntegration, commitMessage, comments, activeReviews, rebasePossible);
492 if (readyForIntegration) {
493 newLabels.add("ready");
494 } else {
495 newLabels.remove("ready");
496 }
497 if (!rebasePossible) {
498 newLabels.add("outdated");
499 } else {
500 newLabels.remove("outdated");
|
246 }
247
248 private Optional<String> getReviewersList(List<Review> reviews) {
249 var reviewers = reviews.stream()
250 .filter(review -> review.verdict() == Review.Verdict.APPROVED)
251 .map(review -> {
252 var entry = " * " + formatReviewer(review.reviewer());
253 if (!review.hash().equals(pr.headHash())) {
254 entry += " **Note!** Review applies to " + review.hash();
255 }
256 return entry;
257 })
258 .collect(Collectors.joining("\n"));
259 if (reviewers.length() > 0) {
260 return Optional.of(reviewers);
261 } else {
262 return Optional.empty();
263 }
264 }
265
266 private String getStatusMessage(List<Comment> comments, List<Review> reviews, PullRequestCheckIssueVisitor visitor) {
267 var progressBody = new StringBuilder();
268 progressBody.append("## Progress\n");
269 progressBody.append(getChecksList(visitor));
270
271 var issue = Issue.fromString(pr.title());
272 if (issueProject != null && issue.isPresent()) {
273 var allIssues = new ArrayList<Issue>();
274 allIssues.add(issue.get());
275 allIssues.addAll(SolvesTracker.currentSolved(pr.repository().forge().currentUser(), comments));
276 progressBody.append("\n\n## Issue");
277 if (allIssues.size() > 1) {
278 progressBody.append("s");
279 }
280 progressBody.append("\n");
281 for (var currentIssue : allIssues) {
282 var iss = issueProject.issue(currentIssue.id());
283 if (iss.isPresent()) {
284 progressBody.append("[");
285 progressBody.append(iss.get().id());
286 progressBody.append("](");
287 progressBody.append(iss.get().webUrl());
288 progressBody.append("): ");
289 progressBody.append(iss.get().title());
290 progressBody.append("\n");
291 } else {
292 progressBody.append("⚠️ Failed to retrieve information on issue `");
293 progressBody.append(currentIssue.id());
294 progressBody.append("`.\n");
295 }
296 }
297 }
298
299 getReviewersList(reviews).ifPresent(reviewers -> {
300 progressBody.append("\n\n## Approvers\n");
301 progressBody.append(reviewers);
302 });
303
304 return progressBody.toString();
305 }
306
307 private String updateStatusMessage(String message) {
308 var description = pr.body();
309 var markerIndex = description.lastIndexOf(progressMarker);
310
311 if (markerIndex >= 0 && description.substring(markerIndex).equals(message)) {
312 log.info("Progress already up to date");
313 return description;
314 }
315 var newBody = (markerIndex < 0 ?
469 pr.createCheck(checkBuilder.build());
470 var localHash = prInstance.commit(censusInstance.namespace(), censusDomain, null);
471
472 // Try to rebase
473 boolean rebasePossible = true;
474 var ignored = new PrintWriter(new StringWriter());
475 var rebasedHash = prInstance.rebase(localHash, ignored);
476 if (rebasedHash.isEmpty()) {
477 rebasePossible = false;
478 } else {
479 localHash = rebasedHash.get();
480 }
481
482 // Determine current status
483 var visitor = prInstance.executeChecks(localHash, censusInstance);
484 var additionalErrors = botSpecificChecks();
485 updateCheckBuilder(checkBuilder, visitor, additionalErrors);
486 updateReadyForReview(visitor, additionalErrors);
487
488 // Calculate and update the status message if needed
489 var statusMessage = getStatusMessage(comments, activeReviews, visitor);
490 var updatedBody = updateStatusMessage(statusMessage);
491
492 // Post / update approval messages (only needed if the review itself can't contain a body)
493 if (!pr.repository().forge().supportsReviewBody()) {
494 updateReviewedMessages(comments, allReviews);
495 }
496
497 var commit = prInstance.localRepo().lookup(localHash).orElseThrow();
498 var commitMessage = String.join("\n", commit.message());
499 var readyForIntegration = visitor.getMessages().isEmpty() && additionalErrors.isEmpty();
500 updateMergeReadyComment(readyForIntegration, commitMessage, comments, activeReviews, rebasePossible);
501 if (readyForIntegration) {
502 newLabels.add("ready");
503 } else {
504 newLabels.remove("ready");
505 }
506 if (!rebasePossible) {
507 newLabels.add("outdated");
508 } else {
509 newLabels.remove("outdated");
|