первая вресия смарт уведомлений
This commit is contained in:
parent
e1c9436a14
commit
0d5fc08c1f
@ -11,5 +11,6 @@
|
||||
<include file="liquibase/v.2.0.0/2020-10-02-add-column-status-teamcity.xml"/>
|
||||
<include file="liquibase/v.2.0.0/2020-10-07-add-colum-reviewer-date.xml"/>
|
||||
<include file="liquibase/v.2.0.0/2020-10-11-teamcity-refactoring.xml"/>
|
||||
<include file="liquibase/v.2.0.0/2020-10-11-new-colum-reviewer.xml"/>
|
||||
|
||||
</databaseChangeLog>
|
@ -0,0 +1,12 @@
|
||||
<databaseChangeLog
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
|
||||
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">
|
||||
|
||||
<changeSet id="2020-10-11-add-column-reviewer" author="upagge">
|
||||
<addColumn tableName="reviewer">
|
||||
<column name="date_smart_notify" type="datetime"/>
|
||||
</addColumn>
|
||||
</changeSet>
|
||||
|
||||
</databaseChangeLog>
|
@ -56,6 +56,9 @@ public class Reviewer {
|
||||
@Column(name = "date_change")
|
||||
private LocalDateTime dateChange;
|
||||
|
||||
@Column(name = "date_smart_notify")
|
||||
private LocalDateTime dateSmartNotify;
|
||||
|
||||
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH, optional = false)
|
||||
@JoinColumn(name = "pull_request_id")
|
||||
private PullRequest pullRequest;
|
||||
|
@ -0,0 +1,32 @@
|
||||
package org.sadtech.bot.vcs.core.domain.notify.pullrequest;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import org.sadtech.bot.vcs.core.utils.Smile;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* // TODO: 11.10.2020 Добавить описание.
|
||||
*
|
||||
* @author upagge 11.10.2020
|
||||
*/
|
||||
@Getter
|
||||
public class ForgottenSmartPrNotify extends PrNotify {
|
||||
|
||||
@Builder
|
||||
protected ForgottenSmartPrNotify(Set<String> recipients, String title, String url) {
|
||||
super(recipients, title, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateMessage() {
|
||||
return MessageFormat.format(
|
||||
"{0} *Напоминание о просмотре PullRequest*" +
|
||||
"{3}[{1}]({2})",
|
||||
Smile.SMART, title, url, Smile.HR
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
package org.sadtech.bot.vcs.core.domain.notify.pullrequest;
|
||||
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import org.sadtech.bot.vcs.core.domain.entity.Reviewer;
|
||||
import org.sadtech.bot.vcs.core.utils.Smile;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* // TODO: 11.10.2020 Добавить описание.
|
||||
*
|
||||
* @author upagge 11.10.2020
|
||||
*/
|
||||
@Getter
|
||||
public class SmartPrNotify extends PrNotify {
|
||||
|
||||
private final Reviewer reviewerTriggered;
|
||||
|
||||
@Builder
|
||||
protected SmartPrNotify(Set<String> recipients, String title, String url, Reviewer reviewerTriggered) {
|
||||
super(recipients, title, url);
|
||||
this.reviewerTriggered = reviewerTriggered;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String generateMessage() {
|
||||
return MessageFormat.format(
|
||||
"{0} *Напоминание о просмотре PullRequest*\n" +
|
||||
"{3}[{1}]({2})" +
|
||||
"{3}" +
|
||||
"{4} изменил свое решение на {5}\n\n",
|
||||
Smile.SMART, title, url, Smile.HR, reviewerTriggered.getPersonLogin(), reviewerTriggered.getStatus().getValue()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -26,7 +26,7 @@ public class UpdatePrNotify extends PrNotify {
|
||||
@Override
|
||||
public String generateMessage() {
|
||||
return MessageFormat.format(
|
||||
"{0} *Обновление Pull Request*\n" +
|
||||
"{0} *Обновление PullRequest*\n" +
|
||||
"[{1}]({2})" +
|
||||
"{3}" +
|
||||
"{4}: {5}\n\n",
|
||||
|
@ -18,8 +18,10 @@ import org.sadtech.bot.vcs.core.domain.entity.PullRequest_;
|
||||
import org.sadtech.bot.vcs.core.domain.entity.Reviewer;
|
||||
import org.sadtech.bot.vcs.core.domain.filter.PullRequestFilter;
|
||||
import org.sadtech.bot.vcs.core.domain.notify.pullrequest.ConflictPrNotify;
|
||||
import org.sadtech.bot.vcs.core.domain.notify.pullrequest.ForgottenSmartPrNotify;
|
||||
import org.sadtech.bot.vcs.core.domain.notify.pullrequest.NewPrNotify;
|
||||
import org.sadtech.bot.vcs.core.domain.notify.pullrequest.ReviewersPrNotify;
|
||||
import org.sadtech.bot.vcs.core.domain.notify.pullrequest.SmartPrNotify;
|
||||
import org.sadtech.bot.vcs.core.domain.notify.pullrequest.StatusPrNotify;
|
||||
import org.sadtech.bot.vcs.core.domain.notify.pullrequest.UpdatePrNotify;
|
||||
import org.sadtech.bot.vcs.core.domain.util.ReviewerChange;
|
||||
@ -93,30 +95,58 @@ public class PullRequestsServiceImpl extends AbstractSimpleManagerService<PullRe
|
||||
public PullRequest update(@NonNull PullRequest pullRequest) {
|
||||
final PullRequest oldPullRequest = findAndFillId(pullRequest);
|
||||
|
||||
oldPullRequest.setBitbucketVersion(pullRequest.getBitbucketVersion());
|
||||
forgottenNotification(oldPullRequest);
|
||||
|
||||
oldPullRequest.setTitle(pullRequest.getTitle());
|
||||
oldPullRequest.setDescription(pullRequest.getDescription());
|
||||
updateReviewers(oldPullRequest, pullRequest);
|
||||
oldPullRequest.setUpdateDate(pullRequest.getUpdateDate());
|
||||
updateBitbucketVersion(oldPullRequest, pullRequest);
|
||||
updateStatus(oldPullRequest, pullRequest);
|
||||
updateConflict(oldPullRequest, pullRequest);
|
||||
|
||||
final PullRequest newPullRequest = pullRequestsRepository.save(oldPullRequest);
|
||||
if (!pullRequest.getBitbucketVersion().equals(newPullRequest.getBitbucketVersion())) {
|
||||
return pullRequestsRepository.save(oldPullRequest);
|
||||
}
|
||||
|
||||
private void forgottenNotification(PullRequest pullRequest) {
|
||||
if (LocalDateTime.now().isAfter(pullRequest.getUpdateDate().plusHours(2L))) {
|
||||
final Set<String> smartReviewers = pullRequest.getReviewers().stream()
|
||||
.filter(
|
||||
reviewer -> ReviewerStatus.NEEDS_WORK.equals(reviewer.getStatus())
|
||||
&& LocalDateTime.now().isAfter(reviewer.getDateChange().plusHours(2L))
|
||||
&& reviewer.getDateSmartNotify() == null
|
||||
)
|
||||
.peek(reviewer -> reviewer.setDateSmartNotify(LocalDateTime.now()))
|
||||
.map(Reviewer::getPersonLogin)
|
||||
.collect(Collectors.toSet());
|
||||
if (!smartReviewers.isEmpty()) {
|
||||
notifyService.send(
|
||||
ForgottenSmartPrNotify.builder()
|
||||
.recipients(smartReviewers)
|
||||
.title(pullRequest.getTitle())
|
||||
.url(pullRequest.getUrl())
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateBitbucketVersion(PullRequest oldPullRequest, PullRequest pullRequest) {
|
||||
if (!oldPullRequest.getBitbucketVersion().equals(pullRequest.getBitbucketVersion())) {
|
||||
oldPullRequest.setBitbucketVersion(pullRequest.getBitbucketVersion());
|
||||
notifyService.send(
|
||||
UpdatePrNotify.builder()
|
||||
.author(oldPullRequest.getAuthorLogin())
|
||||
.name(newPullRequest.getTitle())
|
||||
.name(pullRequest.getTitle())
|
||||
.recipients(
|
||||
newPullRequest.getReviewers().stream()
|
||||
pullRequest.getReviewers().stream()
|
||||
.map(Reviewer::getPersonLogin)
|
||||
.collect(Collectors.toSet())
|
||||
)
|
||||
.url(newPullRequest.getUrl())
|
||||
.url(oldPullRequest.getUrl())
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
return newPullRequest;
|
||||
}
|
||||
|
||||
private void updateConflict(PullRequest oldPullRequest, PullRequest pullRequest) {
|
||||
@ -180,10 +210,12 @@ public class PullRequestsServiceImpl extends AbstractSimpleManagerService<PullRe
|
||||
reviewerChanges.add(ReviewerChange.ofOld(oldReviewer.getPersonLogin(), oldStatus, newStatus));
|
||||
oldReviewer.setStatus(newStatus);
|
||||
oldReviewer.setDateChange(LocalDateTime.now());
|
||||
smartNotifyAfterReviewerDecision(newReviewer, oldPullRequest);
|
||||
}
|
||||
} else {
|
||||
reviewerChanges.add(ReviewerChange.ofNew(newReviewer.getPersonLogin(), newReviewer.getStatus()));
|
||||
newReviewer.setPullRequest(oldPullRequest);
|
||||
newReviewer.setDateChange(LocalDateTime.now());
|
||||
oldPullRequest.getReviewers().add(newReviewer);
|
||||
}
|
||||
}
|
||||
@ -209,6 +241,36 @@ public class PullRequestsServiceImpl extends AbstractSimpleManagerService<PullRe
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Умное уведомление ревьюверов, после того, как кто-то изменил свое решение.
|
||||
*/
|
||||
private void smartNotifyAfterReviewerDecision(Reviewer newReviewer, PullRequest oldPullRequest) {
|
||||
final ReviewerStatus newStatus = newReviewer.getStatus();
|
||||
if (!ReviewerStatus.NEEDS_WORK.equals(newStatus) && enoughTimHasPassedSinceUpdatePr(oldPullRequest.getUpdateDate())) {
|
||||
final List<Reviewer> smartReviewers = oldPullRequest.getReviewers().stream()
|
||||
.filter(reviewer -> LocalDateTime.now().isAfter(reviewer.getDateChange().plusHours(2L)))
|
||||
.collect(Collectors.toList());
|
||||
if (!smartReviewers.isEmpty()) {
|
||||
notifyService.send(
|
||||
SmartPrNotify.builder()
|
||||
.reviewerTriggered(newReviewer)
|
||||
.title(oldPullRequest.getTitle())
|
||||
.url(oldPullRequest.getUrl())
|
||||
.recipients(
|
||||
smartReviewers.stream()
|
||||
.map(Reviewer::getPersonLogin)
|
||||
.collect(Collectors.toSet())
|
||||
)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean enoughTimHasPassedSinceUpdatePr(LocalDateTime updateDate) {
|
||||
return LocalDateTime.now().isAfter(updateDate.plusHours(4L));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<PullRequest> getAllByReviewerAndStatuses(String login, ReviewerStatus reviewerStatus, Set<PullRequestStatus> statuses) {
|
||||
|
@ -38,7 +38,8 @@ public enum Smile {
|
||||
HR("\n -- -- -- -- --\n"),
|
||||
FAILURE("❌"),
|
||||
SUCCESS("✅"),
|
||||
BUILD("♻️");
|
||||
BUILD("♻️"),
|
||||
SMART("\uD83E\uDDE0");
|
||||
|
||||
@Getter
|
||||
private final String value;
|
||||
|
Loading…
Reference in New Issue
Block a user