Уведомление о возникновении конфликта

This commit is contained in:
Struchkov Mark 2024-09-04 00:09:26 +03:00
parent 07b5687cf2
commit 625c59f163
No known key found for this signature in database
GPG Key ID: A3F0AC3F0FA52F3C
3 changed files with 137 additions and 50 deletions

View File

@ -2,6 +2,7 @@ package dev.struchkov.bot.gitlab.context.domain.notify.group.mr;
import dev.struchkov.bot.gitlab.context.domain.notify.GroupNotify; import dev.struchkov.bot.gitlab.context.domain.notify.GroupNotify;
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames; import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
import lombok.Builder;
import lombok.Getter; import lombok.Getter;
import static dev.struchkov.bot.gitlab.context.domain.notify.group.mr.ConflictMrGroupNotifyFields.CLASS_NAME; import static dev.struchkov.bot.gitlab.context.domain.notify.group.mr.ConflictMrGroupNotifyFields.CLASS_NAME;
@ -19,6 +20,7 @@ public class ConflictMrGroupNotify implements GroupNotify {
protected final String milestone; protected final String milestone;
protected final String authorTelegramUsername; protected final String authorTelegramUsername;
@Builder
public ConflictMrGroupNotify(String sourceBranch, String projectName, String title, String url, String milestone, String authorTelegramUsername) { public ConflictMrGroupNotify(String sourceBranch, String projectName, String title, String url, String milestone, String authorTelegramUsername) {
this.sourceBranch = sourceBranch; this.sourceBranch = sourceBranch;
this.projectName = projectName; this.projectName = projectName;

View File

@ -11,6 +11,7 @@ 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.entity.Project;
import dev.struchkov.bot.gitlab.context.domain.event.NewMergeRequestEvent; 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.event.UpdateMergeRequestEvent;
import dev.struchkov.bot.gitlab.context.domain.notify.group.mr.ConflictMrGroupNotify;
import dev.struchkov.bot.gitlab.context.domain.notify.group.mr.NewMergeRequestGroupNotify; import dev.struchkov.bot.gitlab.context.domain.notify.group.mr.NewMergeRequestGroupNotify;
import dev.struchkov.bot.gitlab.context.domain.notify.group.mr.NoReviewerGroupNotify; import dev.struchkov.bot.gitlab.context.domain.notify.group.mr.NoReviewerGroupNotify;
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ApprovalChangedMrPersonalNotify; import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ApprovalChangedMrPersonalNotify;
@ -58,7 +59,7 @@ public class MergeRequestHandler {
final boolean userReviewer = mergeRequest.isUserReviewer(); final boolean userReviewer = mergeRequest.isUserReviewer();
final boolean userAssignee = mergeRequest.isUserAssignee(); final boolean userAssignee = mergeRequest.isUserAssignee();
if (mergeRequest.isConflict()) { if (mergeRequest.isConflict()) {
sendGroupNotifyAboutConflict(mergeRequest, projectName);
} else { } else {
if (mergeRequest.isNotification()) { if (mergeRequest.isNotification()) {
if (userReviewer || userAssignee) { if (userReviewer || userAssignee) {
@ -68,42 +69,10 @@ public class MergeRequestHandler {
} }
if (checkNotEmpty(mergeRequest.getReviewers())) { if (checkNotEmpty(mergeRequest.getReviewers())) {
final Map<Long, String> reviewerTelegramUsernames = personService.getTelegramUsernamesByPersonIds(mergeRequest.getReviewers().stream().map(Person::getId).collect(Collectors.toSet())); sendGroupNotifyForReviewers(mergeRequest, projectName);
if (!reviewerTelegramUsernames.isEmpty()) {
notifyService.send(
NewMergeRequestGroupNotify.builder()
.mrId(mergeRequest.getId())
.title(mergeRequest.getTitle())
.url(mergeRequest.getWebUrl())
.author(mergeRequest.getAuthor().getName())
.reviewerTelegramUsernames(reviewerTelegramUsernames)
.milestone(mergeRequest.getMilestone())
.projectName(projectName)
.targetBranch(mergeRequest.getTargetBranch())
.sourceBranch(mergeRequest.getSourceBranch())
.description(mergeRequest.getDescription())
.build()
);
}
} else { } else {
final Optional<String> optAuthorUserName = personService.getTelegramUsernamesByPersonIds(mergeRequest.getAuthor().getId()); sendGroupNotifyAboutNoReviewers(mergeRequest, projectName);
if (optAuthorUserName.isPresent()) {
final String authorUsername = optAuthorUserName.get();
notifyService.send(
NoReviewerGroupNotify.builder()
.ownerTelegramUsername(authorUsername)
.title(mergeRequest.getTitle())
.url(mergeRequest.getWebUrl())
.milestone(mergeRequest.getMilestone())
.projectName(projectName)
.targetBranch(mergeRequest.getTargetBranch())
.sourceBranch(mergeRequest.getSourceBranch())
.build()
);
}
} }
} }
} }
@ -115,34 +84,98 @@ public class MergeRequestHandler {
final ReviewerChanged reviewerChanged = event.getReviewerChanged(); final ReviewerChanged reviewerChanged = event.getReviewerChanged();
final Optional<ApprovalChanged> optApprovalChanged = event.getOptApprovalChanged(); final Optional<ApprovalChanged> optApprovalChanged = event.getOptApprovalChanged();
final boolean isChangedMr = !oldMergeRequest.getUpdatedDate().equals(newMergeRequest.getUpdatedDate()) || oldMergeRequest.isConflict() != newMergeRequest.isConflict(); final boolean resolveConflict = oldMergeRequest.isConflict() && !newMergeRequest.isConflict();
final boolean newConflict = !oldMergeRequest.isConflict() && newMergeRequest.isConflict();
final boolean isChangedMr = !oldMergeRequest.getUpdatedDate().equals(newMergeRequest.getUpdatedDate());
final Project project = projectService.getByIdOrThrow(newMergeRequest.getProjectId());
if (oldMergeRequest.isNotification()) { if (oldMergeRequest.isNotification()) {
final Project project = projectService.getByIdOrThrow(newMergeRequest.getProjectId()); if (newConflict) {
personalNotifyAboutNewConflict(oldMergeRequest, newMergeRequest, project);
if (isChangedMr) { }
notifyAboutStatus(oldMergeRequest, newMergeRequest, project); if (resolveConflict) {
notifyAboutNewConflict(oldMergeRequest, newMergeRequest, project); personalNotifyAboutResolveConflict(oldMergeRequest, newMergeRequest, project);
notifyAboutResolveConflict(oldMergeRequest, newMergeRequest, project); }
notifyAboutUpdate(oldMergeRequest, newMergeRequest, project); if (isChangedMr) {
personalNotifyAboutStatus(oldMergeRequest, newMergeRequest, project);
personalNotifyAboutUpdate(oldMergeRequest, newMergeRequest, project);
} }
if (reviewerChanged.isChanged()) { if (reviewerChanged.isChanged()) {
notifyReviewer(reviewerChanged, newMergeRequest, project); notifyReviewer(reviewerChanged, newMergeRequest, project);
} }
if (assigneeChanged.isChanged()) { if (assigneeChanged.isChanged()) {
notifyAssignee(assigneeChanged, oldMergeRequest, newMergeRequest, project); notifyAssignee(assigneeChanged, oldMergeRequest, newMergeRequest, project);
} }
if (optApprovalChanged.isPresent()) { if (optApprovalChanged.isPresent()) {
final ApprovalChanged approvalChanged = optApprovalChanged.get(); final ApprovalChanged approvalChanged = optApprovalChanged.get();
notifyApproval(newMergeRequest, project, approvalChanged); notifyApproval(newMergeRequest, project, approvalChanged);
} }
} }
//групповые уведомления
if (newConflict) {
sendGroupNotifyAboutConflict(newMergeRequest, project.getName());
}
} }
private void sendGroupNotifyAboutConflict(MergeRequest mergeRequest, String projectName) {
final Optional<String> optAuthorUserName = personService.getTelegramUsernamesByPersonIds(mergeRequest.getAuthor().getId());
if (optAuthorUserName.isPresent()) {
final String authorUserName = optAuthorUserName.get();
notifyService.send(
ConflictMrGroupNotify.builder()
.projectName(projectName)
.url(mergeRequest.getWebUrl())
.title(mergeRequest.getTitle())
.milestone(mergeRequest.getMilestone())
.sourceBranch(mergeRequest.getSourceBranch())
.authorTelegramUsername(authorUserName)
.build()
);
}
}
private void sendGroupNotifyAboutNoReviewers(MergeRequest mergeRequest, String projectName) {
final Optional<String> optAuthorUserName = personService.getTelegramUsernamesByPersonIds(mergeRequest.getAuthor().getId());
if (optAuthorUserName.isPresent()) {
final String authorUsername = optAuthorUserName.get();
notifyService.send(
NoReviewerGroupNotify.builder()
.ownerTelegramUsername(authorUsername)
.title(mergeRequest.getTitle())
.url(mergeRequest.getWebUrl())
.milestone(mergeRequest.getMilestone())
.projectName(projectName)
.targetBranch(mergeRequest.getTargetBranch())
.sourceBranch(mergeRequest.getSourceBranch())
.build()
);
}
}
private void sendGroupNotifyForReviewers(MergeRequest mergeRequest, String projectName) {
final Map<Long, String> reviewerTelegramUsernames = personService.getTelegramUsernamesByPersonIds(mergeRequest.getReviewers().stream().map(Person::getId).collect(Collectors.toSet()));
if (!reviewerTelegramUsernames.isEmpty()) {
notifyService.send(
NewMergeRequestGroupNotify.builder()
.mrId(mergeRequest.getId())
.title(mergeRequest.getTitle())
.url(mergeRequest.getWebUrl())
.author(mergeRequest.getAuthor().getName())
.reviewerTelegramUsernames(reviewerTelegramUsernames)
.milestone(mergeRequest.getMilestone())
.projectName(projectName)
.targetBranch(mergeRequest.getTargetBranch())
.sourceBranch(mergeRequest.getSourceBranch())
.description(mergeRequest.getDescription())
.build()
);
}
}
private void notifyApproval(MergeRequest mergeRequest, Project project, ApprovalChanged approvalChanged) { private void notifyApproval(MergeRequest mergeRequest, Project project, ApprovalChanged approvalChanged) {
final Set<Person> newApproval = approvalChanged.getNewApproval().stream() final Set<Person> newApproval = approvalChanged.getNewApproval().stream()
.filter(approval -> !personInformation.getId().equals(approval.getId())) .filter(approval -> !personInformation.getId().equals(approval.getId()))
@ -212,7 +245,7 @@ public class MergeRequestHandler {
notifyService.send(builder.build()); notifyService.send(builder.build());
} }
private void notifyAboutUpdate(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) { private void personalNotifyAboutUpdate(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
final Long botUserGitlabId = personInformation.getId(); final Long botUserGitlabId = personInformation.getId();
if ( if (
!botUserGitlabId.equals(mergeRequest.getAuthor().getId()) // Автор MR не пользователь приложения !botUserGitlabId.equals(mergeRequest.getAuthor().getId()) // Автор MR не пользователь приложения
@ -262,7 +295,7 @@ public class MergeRequestHandler {
} }
} }
protected void notifyAboutNewConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) { protected void personalNotifyAboutNewConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
final Long gitlabUserId = personInformation.getId(); final Long gitlabUserId = personInformation.getId();
if ( if (
!oldMergeRequest.isConflict() // У старого MR не было конфликта !oldMergeRequest.isConflict() // У старого MR не было конфликта
@ -282,7 +315,7 @@ public class MergeRequestHandler {
} }
} }
private void notifyAboutResolveConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) { private void personalNotifyAboutResolveConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
final Long gitlabUserId = personInformation.getId(); final Long gitlabUserId = personInformation.getId();
if (oldMergeRequest.isConflict() && !mergeRequest.isConflict()) { if (oldMergeRequest.isConflict() && !mergeRequest.isConflict()) {
// проверяем даты коммитов, так как при пуше в target ветку MR у которого есть конфликт, конфликт на время пропадает. Судя по всему GitLab после пуша заново проверяет вероятность конфликта. Чаще всего конфликт никуда не девается. // проверяем даты коммитов, так как при пуше в target ветку MR у которого есть конфликт, конфликт на время пропадает. Судя по всему GitLab после пуша заново проверяет вероятность конфликта. Чаще всего конфликт никуда не девается.
@ -305,7 +338,7 @@ public class MergeRequestHandler {
} }
} }
protected void notifyAboutStatus(MergeRequest oldMergeRequest, MergeRequest newMergeRequest, Project project) { protected void personalNotifyAboutStatus(MergeRequest oldMergeRequest, MergeRequest newMergeRequest, Project project) {
final MergeRequestState oldStatus = oldMergeRequest.getState(); final MergeRequestState oldStatus = oldMergeRequest.getState();
final MergeRequestState newStatus = newMergeRequest.getState(); final MergeRequestState newStatus = newMergeRequest.getState();
final Long gitlabUserId = personInformation.getId(); final Long gitlabUserId = personInformation.getId();

View File

@ -0,0 +1,52 @@
package dev.struchkov.bot.gitlab.telegram.service.notify.group;
import dev.struchkov.bot.gitlab.context.domain.notify.group.mr.ConflictMrGroupNotify;
import dev.struchkov.bot.gitlab.context.utils.Icons;
import dev.struchkov.bot.gitlab.telegram.service.notify.NotifyBoxAnswerGenerator;
import dev.struchkov.godfather.simple.domain.BoxAnswer;
import org.springframework.stereotype.Component;
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.UrlButton.urlButton;
import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@Component
public class ConflictMrGroupNotifyGenerator implements NotifyBoxAnswerGenerator<ConflictMrGroupNotify> {
@Override
public BoxAnswer generate(ConflictMrGroupNotify notify) {
final StringBuilder builder = new StringBuilder(Icons.DANGEROUS).append(notify.getAuthorTelegramUsername()).append("*, there is a conflict in your merge request!*")
.append(Icons.HR)
.append(escapeMarkdown(notify.getTitle()))
.append(Icons.HR)
.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(Icons.TREE).append(": ").append(escapeMarkdown(notify.getSourceBranch()));
final String notifyMessage = builder.toString();
return BoxAnswer.builder()
.message(notifyMessage)
.keyBoard(inlineKeyBoard(
keyBoardLine(
urlButton(Icons.LINK, notify.getUrl())
)
))
.payload(ENABLE_MARKDOWN)
.build();
}
@Override
public String getNotifyType() {
return ConflictMrGroupNotify.TYPE;
}
}