первая вресия смарт уведомлений
This commit is contained in:
@@ -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-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-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-teamcity-refactoring.xml"/>
|
||||||
|
<include file="liquibase/v.2.0.0/2020-10-11-new-colum-reviewer.xml"/>
|
||||||
|
|
||||||
</databaseChangeLog>
|
</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")
|
@Column(name = "date_change")
|
||||||
private LocalDateTime dateChange;
|
private LocalDateTime dateChange;
|
||||||
|
|
||||||
|
@Column(name = "date_smart_notify")
|
||||||
|
private LocalDateTime dateSmartNotify;
|
||||||
|
|
||||||
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH, optional = false)
|
@ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.REFRESH, optional = false)
|
||||||
@JoinColumn(name = "pull_request_id")
|
@JoinColumn(name = "pull_request_id")
|
||||||
private PullRequest pullRequest;
|
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
|
@Override
|
||||||
public String generateMessage() {
|
public String generateMessage() {
|
||||||
return MessageFormat.format(
|
return MessageFormat.format(
|
||||||
"{0} *Обновление Pull Request*\n" +
|
"{0} *Обновление PullRequest*\n" +
|
||||||
"[{1}]({2})" +
|
"[{1}]({2})" +
|
||||||
"{3}" +
|
"{3}" +
|
||||||
"{4}: {5}\n\n",
|
"{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.entity.Reviewer;
|
||||||
import org.sadtech.bot.vcs.core.domain.filter.PullRequestFilter;
|
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.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.NewPrNotify;
|
||||||
import org.sadtech.bot.vcs.core.domain.notify.pullrequest.ReviewersPrNotify;
|
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.StatusPrNotify;
|
||||||
import org.sadtech.bot.vcs.core.domain.notify.pullrequest.UpdatePrNotify;
|
import org.sadtech.bot.vcs.core.domain.notify.pullrequest.UpdatePrNotify;
|
||||||
import org.sadtech.bot.vcs.core.domain.util.ReviewerChange;
|
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) {
|
public PullRequest update(@NonNull PullRequest pullRequest) {
|
||||||
final PullRequest oldPullRequest = findAndFillId(pullRequest);
|
final PullRequest oldPullRequest = findAndFillId(pullRequest);
|
||||||
|
|
||||||
oldPullRequest.setBitbucketVersion(pullRequest.getBitbucketVersion());
|
forgottenNotification(oldPullRequest);
|
||||||
|
|
||||||
oldPullRequest.setTitle(pullRequest.getTitle());
|
oldPullRequest.setTitle(pullRequest.getTitle());
|
||||||
oldPullRequest.setDescription(pullRequest.getDescription());
|
oldPullRequest.setDescription(pullRequest.getDescription());
|
||||||
updateReviewers(oldPullRequest, pullRequest);
|
updateReviewers(oldPullRequest, pullRequest);
|
||||||
|
oldPullRequest.setUpdateDate(pullRequest.getUpdateDate());
|
||||||
|
updateBitbucketVersion(oldPullRequest, pullRequest);
|
||||||
updateStatus(oldPullRequest, pullRequest);
|
updateStatus(oldPullRequest, pullRequest);
|
||||||
updateConflict(oldPullRequest, pullRequest);
|
updateConflict(oldPullRequest, pullRequest);
|
||||||
|
|
||||||
final PullRequest newPullRequest = pullRequestsRepository.save(oldPullRequest);
|
return pullRequestsRepository.save(oldPullRequest);
|
||||||
if (!pullRequest.getBitbucketVersion().equals(newPullRequest.getBitbucketVersion())) {
|
}
|
||||||
|
|
||||||
|
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(
|
notifyService.send(
|
||||||
UpdatePrNotify.builder()
|
UpdatePrNotify.builder()
|
||||||
.author(oldPullRequest.getAuthorLogin())
|
.author(oldPullRequest.getAuthorLogin())
|
||||||
.name(newPullRequest.getTitle())
|
.name(pullRequest.getTitle())
|
||||||
.recipients(
|
.recipients(
|
||||||
newPullRequest.getReviewers().stream()
|
pullRequest.getReviewers().stream()
|
||||||
.map(Reviewer::getPersonLogin)
|
.map(Reviewer::getPersonLogin)
|
||||||
.collect(Collectors.toSet())
|
.collect(Collectors.toSet())
|
||||||
)
|
)
|
||||||
.url(newPullRequest.getUrl())
|
.url(oldPullRequest.getUrl())
|
||||||
.build()
|
.build()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return newPullRequest;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateConflict(PullRequest oldPullRequest, PullRequest pullRequest) {
|
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));
|
reviewerChanges.add(ReviewerChange.ofOld(oldReviewer.getPersonLogin(), oldStatus, newStatus));
|
||||||
oldReviewer.setStatus(newStatus);
|
oldReviewer.setStatus(newStatus);
|
||||||
oldReviewer.setDateChange(LocalDateTime.now());
|
oldReviewer.setDateChange(LocalDateTime.now());
|
||||||
|
smartNotifyAfterReviewerDecision(newReviewer, oldPullRequest);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reviewerChanges.add(ReviewerChange.ofNew(newReviewer.getPersonLogin(), newReviewer.getStatus()));
|
reviewerChanges.add(ReviewerChange.ofNew(newReviewer.getPersonLogin(), newReviewer.getStatus()));
|
||||||
newReviewer.setPullRequest(oldPullRequest);
|
newReviewer.setPullRequest(oldPullRequest);
|
||||||
|
newReviewer.setDateChange(LocalDateTime.now());
|
||||||
oldPullRequest.getReviewers().add(newReviewer);
|
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
|
@NonNull
|
||||||
@Override
|
@Override
|
||||||
public List<PullRequest> getAllByReviewerAndStatuses(String login, ReviewerStatus reviewerStatus, Set<PullRequestStatus> statuses) {
|
public List<PullRequest> getAllByReviewerAndStatuses(String login, ReviewerStatus reviewerStatus, Set<PullRequestStatus> statuses) {
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ public enum Smile {
|
|||||||
HR("\n -- -- -- -- --\n"),
|
HR("\n -- -- -- -- --\n"),
|
||||||
FAILURE("❌"),
|
FAILURE("❌"),
|
||||||
SUCCESS("✅"),
|
SUCCESS("✅"),
|
||||||
BUILD("♻️");
|
BUILD("♻️"),
|
||||||
|
SMART("\uD83E\uDDE0");
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final String value;
|
private final String value;
|
||||||
|
|||||||
Reference in New Issue
Block a user