Добавлена поддержка апрувов
This commit is contained in:
parent
214c0401ac
commit
e844942973
@ -0,0 +1,51 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.changed;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class ApprovalChanged {
|
||||
|
||||
private Set<Person> newApproval;
|
||||
private Set<Person> dontApprove;
|
||||
|
||||
public static Optional<ApprovalChanged> approvalChanged(List<Person> oldApproval, List<Person> newApproval) {
|
||||
// Если списки одинаковы, возвращаем пустой Optional
|
||||
if (Objects.equals(oldApproval, newApproval)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
// Преобразуем списки в множества для удобства вычислений
|
||||
Set<Person> oldApprovalSet = new HashSet<>(oldApproval);
|
||||
Set<Person> newApprovalSet = new HashSet<>(newApproval);
|
||||
|
||||
// Вычисляем новые одобрения: те, кто есть в новом списке, но нет в старом
|
||||
final Set<Person> newApprovalSetOnly = new HashSet<>(newApprovalSet);
|
||||
newApprovalSetOnly.removeAll(oldApprovalSet);
|
||||
|
||||
// Вычисляем тех, кто больше не одобряет: те, кто есть в старом списке, но нет в новом
|
||||
final Set<Person> dontApproveSet = new HashSet<>(oldApprovalSet);
|
||||
dontApproveSet.removeAll(newApprovalSet);
|
||||
|
||||
if (!newApprovalSetOnly.isEmpty() || !dontApproveSet.isEmpty()) {
|
||||
return Optional.of(new ApprovalChanged(newApprovalSetOnly, dontApproveSet));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain;
|
||||
package dev.struchkov.bot.gitlab.context.domain.changed;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import lombok.Getter;
|
@ -1,4 +1,4 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain;
|
||||
package dev.struchkov.bot.gitlab.context.domain.changed;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import lombok.Getter;
|
@ -1,7 +1,8 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.AssigneeChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.ReviewerChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.changed.ApprovalChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.changed.AssigneeChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.changed.ReviewerChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
@ -9,6 +10,8 @@ import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@ -21,5 +24,6 @@ public class UpdateMergeRequestEvent {
|
||||
|
||||
private AssigneeChanged assigneeChanged;
|
||||
private ReviewerChanged reviewerChanged;
|
||||
private Optional<ApprovalChanged> optApprovalChanged;
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,41 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.mergerequest;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ApprovalChangedMrNotifyFields.CLASS_NAME;
|
||||
|
||||
@Getter
|
||||
@FieldNames
|
||||
public class ApprovalChangedMrNotify extends MrNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
private final Set<Person> newApproval;
|
||||
private final Set<Person> dontApproval;
|
||||
|
||||
@Builder
|
||||
public ApprovalChangedMrNotify(
|
||||
Long mrId,
|
||||
String projectName,
|
||||
String title,
|
||||
String url,
|
||||
String milestone,
|
||||
Set<Person> newApproval,
|
||||
Set<Person> dontApproval
|
||||
) {
|
||||
super(mrId, projectName, title, url, milestone);
|
||||
this.newApproval = newApproval;
|
||||
this.dontApproval = dontApproval;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -19,6 +19,7 @@ public class Icons {
|
||||
public static final String GREEN_CIRCLE = "\uD83D\uDFE2";
|
||||
public static final String PEN = "✏️";
|
||||
public static final String ASSIGNEE = "\uD83C\uDFA9";
|
||||
public static final String APPROVAL = "\uD83D\uDC4D";
|
||||
public static final String BUILD = "⚙️";
|
||||
public static final String LINK = "\uD83D\uDD17";
|
||||
public static final String REVIEWER = "\uD83D\uDD0E";
|
||||
|
@ -1,15 +1,17 @@
|
||||
package dev.struchkov.bot.gitlab.core.handler;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.AssigneeChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
||||
import dev.struchkov.bot.gitlab.context.domain.ReviewerChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.changed.ApprovalChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.changed.AssigneeChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.changed.ReviewerChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||
import dev.struchkov.bot.gitlab.context.domain.event.NewMergeRequestEvent;
|
||||
import dev.struchkov.bot.gitlab.context.domain.event.UpdateMergeRequestEvent;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ApprovalChangedMrNotify;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ConflictMrNotify;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ConflictResolveMrNotify;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.NewMrForAssignee;
|
||||
@ -24,9 +26,11 @@ import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
|
||||
@ -62,29 +66,56 @@ public class MergeRequestHandler {
|
||||
final MergeRequest newMergeRequest = event.getNewMergeRequest();
|
||||
final AssigneeChanged assigneeChanged = event.getAssigneeChanged();
|
||||
final ReviewerChanged reviewerChanged = event.getReviewerChanged();
|
||||
final Optional<ApprovalChanged> optApprovalChanged = event.getOptApprovalChanged();
|
||||
|
||||
final boolean isChangedMr = !oldMergeRequest.getUpdatedDate().equals(newMergeRequest.getUpdatedDate()) || oldMergeRequest.isConflict() != newMergeRequest.isConflict();
|
||||
final boolean isChangedLinkedEntity = reviewerChanged.isChanged() || assigneeChanged.isChanged();
|
||||
final boolean isMilestone = !Objects.equals(oldMergeRequest.getMilestone(), newMergeRequest.getMilestone());
|
||||
|
||||
if (isChangedMr || isChangedLinkedEntity || isMilestone) {
|
||||
if (oldMergeRequest.isNotification()) {
|
||||
final Project project = projectService.getByIdOrThrow(newMergeRequest.getProjectId());
|
||||
|
||||
if (oldMergeRequest.isNotification()) {
|
||||
final Project project = projectService.getByIdOrThrow(newMergeRequest.getProjectId());
|
||||
|
||||
if (isChangedMr) {
|
||||
notifyAboutStatus(oldMergeRequest, newMergeRequest, project);
|
||||
notifyAboutNewConflict(oldMergeRequest, newMergeRequest, project);
|
||||
notifyAboutResolveConflict(oldMergeRequest, newMergeRequest, project);
|
||||
notifyAboutUpdate(oldMergeRequest, newMergeRequest, project);
|
||||
}
|
||||
|
||||
if (isChangedLinkedEntity) {
|
||||
notifyReviewer(reviewerChanged, newMergeRequest, project);
|
||||
notifyAssignee(assigneeChanged, oldMergeRequest, newMergeRequest, project);
|
||||
}
|
||||
if (isChangedMr) {
|
||||
notifyAboutStatus(oldMergeRequest, newMergeRequest, project);
|
||||
notifyAboutNewConflict(oldMergeRequest, newMergeRequest, project);
|
||||
notifyAboutResolveConflict(oldMergeRequest, newMergeRequest, project);
|
||||
notifyAboutUpdate(oldMergeRequest, newMergeRequest, project);
|
||||
}
|
||||
|
||||
if (reviewerChanged.isChanged()) {
|
||||
notifyReviewer(reviewerChanged, newMergeRequest, project);
|
||||
}
|
||||
|
||||
if (assigneeChanged.isChanged()) {
|
||||
notifyAssignee(assigneeChanged, oldMergeRequest, newMergeRequest, project);
|
||||
}
|
||||
|
||||
if (optApprovalChanged.isPresent()) {
|
||||
final ApprovalChanged approvalChanged = optApprovalChanged.get();
|
||||
notifyApproval(newMergeRequest, project, approvalChanged);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void notifyApproval(MergeRequest mergeRequest, Project project, ApprovalChanged approvalChanged) {
|
||||
final Set<Person> newApproval = approvalChanged.getNewApproval().stream()
|
||||
.filter(approval -> !personInformation.getId().equals(approval.getId()))
|
||||
.collect(Collectors.toSet());
|
||||
final Set<Person> dontApproval = approvalChanged.getDontApprove().stream()
|
||||
.filter(approval -> !personInformation.getId().equals(approval.getId()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
if (checkNotEmpty(newApproval) || checkNotEmpty(dontApproval)) {
|
||||
notifyService.send(
|
||||
ApprovalChangedMrNotify.builder()
|
||||
.mrId(mergeRequest.getId())
|
||||
.milestone(mergeRequest.getMilestone())
|
||||
.projectName(project.getName())
|
||||
.title(mergeRequest.getTitle())
|
||||
.url(mergeRequest.getWebUrl())
|
||||
.newApproval(newApproval)
|
||||
.dontApproval(dontApproval)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -257,8 +288,9 @@ public class MergeRequestHandler {
|
||||
|
||||
private void notifyAssignee(AssigneeChanged assigneeChanged, MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
||||
switch (assigneeChanged) {
|
||||
case BECOME ->
|
||||
sendNotifyNewAssignee(mergeRequest, project.getName(), getAssignee(oldMergeRequest).map(Person::getName).orElse(null));
|
||||
case BECOME -> sendNotifyNewAssignee(
|
||||
mergeRequest, project.getName(), getAssignee(oldMergeRequest).map(Person::getName).orElse(null)
|
||||
);
|
||||
}
|
||||
}
|
||||
//TODO [05.12.2022|uPagge]: Добавить уведомление, если происходит удаление ревьювера
|
||||
|
@ -65,11 +65,11 @@ public class DiscussionParser {
|
||||
|
||||
private void processingNewDiscussion(MergeRequestForDiscussion mergeRequest) {
|
||||
int page = 1;
|
||||
final List<DiscussionJson> discussionJson = gitlabSdkManager.getDiscussionForMergeRequest(mergeRequest.getProjectId(), mergeRequest.getTwoId(), page);
|
||||
final List<DiscussionJson> discussionJson = gitlabSdkManager.getDiscussionForMergeRequest(mergeRequest.getProjectId(), mergeRequest.getTwoId(), page, PAGE_COUNT);
|
||||
|
||||
if (checkNotEmpty(discussionJson)) {
|
||||
while (discussionJson.size() == PAGE_COUNT) {
|
||||
discussionJson.addAll(gitlabSdkManager.getDiscussionForMergeRequest(mergeRequest.getProjectId(), mergeRequest.getTwoId(), ++page));
|
||||
discussionJson.addAll(gitlabSdkManager.getDiscussionForMergeRequest(mergeRequest.getProjectId(), mergeRequest.getTwoId(), ++page, PAGE_COUNT));
|
||||
}
|
||||
createNewDiscussion(discussionJson, mergeRequest);
|
||||
}
|
||||
|
@ -104,7 +104,7 @@ public class MergeRequestParser {
|
||||
newMergeRequests.stream()
|
||||
.flatMap(mergeRequest -> Stream.of(mergeRequest.getAssignee(), mergeRequest.getAuthor())),
|
||||
newMergeRequests.stream()
|
||||
.flatMap(mergeRequest -> mergeRequest.getReviewers().stream())
|
||||
.flatMap(mergeRequest -> Stream.concat(mergeRequest.getReviewers().stream(), mergeRequest.getApprovals().stream()))
|
||||
).distinct()
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(Person::getId, p -> p));
|
||||
@ -122,6 +122,12 @@ public class MergeRequestParser {
|
||||
.map(reviewer -> personMap.get(reviewer.getId()))
|
||||
.collect(toList())
|
||||
);
|
||||
|
||||
newMergeRequest.setApprovals(
|
||||
newMergeRequest.getApprovals().stream()
|
||||
.map(approval -> personMap.get(approval.getId()))
|
||||
.collect(toList())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,12 @@
|
||||
package dev.struchkov.bot.gitlab.core.service;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.AssigneeChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||
import dev.struchkov.bot.gitlab.context.domain.IdAndStatusPr;
|
||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
||||
import dev.struchkov.bot.gitlab.context.domain.ReviewerChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.changed.ApprovalChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.changed.AssigneeChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.changed.ReviewerChanged;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequestForDiscussion;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
@ -104,19 +105,18 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
|
||||
final MergeRequest oldMergeRequest = repository.findById(mergeRequest.getId())
|
||||
.orElseThrow(notFoundException("MergeRequest не найден"));
|
||||
|
||||
final MergeRequest cloneOldMergeRequest = oldMergeRequest.toBuilder().build();
|
||||
|
||||
mergeRequest.setNotification(oldMergeRequest.isNotification());
|
||||
|
||||
final Long gitlabUserId = personInformation.getId();
|
||||
final AssigneeChanged assigneeChanged = AssigneeChanged.valueOf(gitlabUserId, getAssignee(oldMergeRequest), getAssignee(mergeRequest));
|
||||
final ReviewerChanged reviewerChanged = ReviewerChanged.valueOf(gitlabUserId, oldMergeRequest.getReviewers(), mergeRequest.getReviewers());
|
||||
final Optional<ApprovalChanged> optApprovalChanged = ApprovalChanged.approvalChanged(oldMergeRequest.getApprovals(), mergeRequest.getApprovals());
|
||||
|
||||
mergeRequest.setUserAssignee(assigneeChanged.getNewStatus(oldMergeRequest.isUserAssignee()));
|
||||
mergeRequest.setUserReviewer(reviewerChanged.getNewStatus(oldMergeRequest.isUserReviewer()));
|
||||
|
||||
eventPublisher.publishEvent(
|
||||
updateMergeRequest(cloneOldMergeRequest, mergeRequest, assigneeChanged, reviewerChanged)
|
||||
updateMergeRequest(oldMergeRequest, mergeRequest, assigneeChanged, reviewerChanged, optApprovalChanged)
|
||||
);
|
||||
|
||||
return repository.save(mergeRequest);
|
||||
|
@ -8,7 +8,7 @@ spring:
|
||||
change-log: classpath:liquibase/changelog.xml
|
||||
jpa:
|
||||
show-sql: false
|
||||
# open-in-view: false
|
||||
open-in-view: false
|
||||
hibernate:
|
||||
ddl-auto: none
|
||||
properties:
|
||||
|
@ -0,0 +1,83 @@
|
||||
package dev.struchkov.bot.gitlab.telegram.service.notify;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ApprovalChangedMrNotify;
|
||||
import dev.struchkov.bot.gitlab.context.utils.Icons;
|
||||
import dev.struchkov.godfather.simple.domain.BoxAnswer;
|
||||
import dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_CONFIRMATION;
|
||||
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_MR_ID;
|
||||
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_VALUE_FALSE;
|
||||
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
|
||||
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard;
|
||||
import static dev.struchkov.godfather.telegram.domain.keyboard.SimpleKeyBoardLine.keyBoardLine;
|
||||
import static dev.struchkov.godfather.telegram.domain.keyboard.button.SimpleButton.simpleButton;
|
||||
import static dev.struchkov.godfather.telegram.domain.keyboard.button.UrlButton.urlButton;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
|
||||
import static java.util.stream.Collectors.joining;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ApprovalChangedMrNotifyGenerator implements NotifyBoxAnswerGenerator<ApprovalChangedMrNotify> {
|
||||
|
||||
@Override
|
||||
public BoxAnswer generate(ApprovalChangedMrNotify notify) {
|
||||
final StringBuilder builder = new StringBuilder(Icons.APPROVAL).append(" *Approvals changed*")
|
||||
.append(Icons.HR)
|
||||
.append(escapeMarkdown(notify.getTitle()));
|
||||
|
||||
if (checkNotNull(notify.getProjectName()) || checkNotNull(notify.getMilestone())) {
|
||||
builder
|
||||
.append(Icons.HR);
|
||||
|
||||
if (checkNotNull(notify.getProjectName())) {
|
||||
builder.append(Icons.PROJECT).append(": ").append(escapeMarkdown(notify.getProjectName())).append("\n");
|
||||
}
|
||||
|
||||
if (checkNotNull(notify.getMilestone())) {
|
||||
builder.append(Icons.MILESTONE).append(": ").append(notify.getMilestone()).append("\n");
|
||||
}
|
||||
|
||||
builder
|
||||
.append("-- -- -- -- --\n");
|
||||
}
|
||||
|
||||
final Set<Person> newApprovals = notify.getNewApproval();
|
||||
if (checkNotEmpty(newApprovals)) {
|
||||
builder.append(Icons.YES).append(" : ").append(newApprovals.stream().map(Person::getName).collect(joining(", ")))
|
||||
.append("\n\n");
|
||||
}
|
||||
|
||||
final Set<Person> dontApproval = notify.getDontApproval();
|
||||
if (checkNotEmpty(dontApproval)) {
|
||||
builder.append(Icons.NO).append(" : ").append(dontApproval.stream().map(Person::getName).collect(joining(", ")));
|
||||
}
|
||||
|
||||
return BoxAnswer.builder()
|
||||
.message(builder.toString())
|
||||
.keyBoard(
|
||||
inlineKeyBoard(
|
||||
keyBoardLine(
|
||||
simpleButton(Icons.VIEW, DELETE_MESSAGE),
|
||||
urlButton(Icons.LINK, notify.getUrl()),
|
||||
simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_MR_ID + ":" + notify.getMrId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]")
|
||||
)
|
||||
)
|
||||
)
|
||||
.payload(BoxAnswerPayload.ENABLE_MARKDOWN)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNotifyType() {
|
||||
return ApprovalChangedMrNotify.TYPE;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user