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

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.haiti.utils.fieldconstants.annotation.FieldNames;
import lombok.Builder;
import lombok.Getter;
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 authorTelegramUsername;
@Builder
public ConflictMrGroupNotify(String sourceBranch, String projectName, String title, String url, String milestone, String authorTelegramUsername) {
this.sourceBranch = sourceBranch;
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.event.NewMergeRequestEvent;
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.NoReviewerGroupNotify;
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ApprovalChangedMrPersonalNotify;
@ -58,7 +59,7 @@ public class MergeRequestHandler {
final boolean userReviewer = mergeRequest.isUserReviewer();
final boolean userAssignee = mergeRequest.isUserAssignee();
if (mergeRequest.isConflict()) {
sendGroupNotifyAboutConflict(mergeRequest, projectName);
} else {
if (mergeRequest.isNotification()) {
if (userReviewer || userAssignee) {
@ -68,24 +69,75 @@ public class MergeRequestHandler {
}
if (checkNotEmpty(mergeRequest.getReviewers())) {
final Map<Long, String> reviewerTelegramUsernames = personService.getTelegramUsernamesByPersonIds(mergeRequest.getReviewers().stream().map(Person::getId).collect(Collectors.toSet()));
if (!reviewerTelegramUsernames.isEmpty()) {
sendGroupNotifyForReviewers(mergeRequest, projectName);
} else {
sendGroupNotifyAboutNoReviewers(mergeRequest, projectName);
}
}
}
@EventListener
public void updateMrHandle(UpdateMergeRequestEvent event) {
final MergeRequest oldMergeRequest = event.getOldMergeRequest();
final MergeRequest newMergeRequest = event.getNewMergeRequest();
final AssigneeChanged assigneeChanged = event.getAssigneeChanged();
final ReviewerChanged reviewerChanged = event.getReviewerChanged();
final Optional<ApprovalChanged> optApprovalChanged = event.getOptApprovalChanged();
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 (newConflict) {
personalNotifyAboutNewConflict(oldMergeRequest, newMergeRequest, project);
}
if (resolveConflict) {
personalNotifyAboutResolveConflict(oldMergeRequest, newMergeRequest, project);
}
if (isChangedMr) {
personalNotifyAboutStatus(oldMergeRequest, newMergeRequest, project);
personalNotifyAboutUpdate(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);
}
}
//групповые уведомления
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(
NewMergeRequestGroupNotify.builder()
.mrId(mergeRequest.getId())
.title(mergeRequest.getTitle())
.url(mergeRequest.getWebUrl())
.author(mergeRequest.getAuthor().getName())
.reviewerTelegramUsernames(reviewerTelegramUsernames)
.milestone(mergeRequest.getMilestone())
ConflictMrGroupNotify.builder()
.projectName(projectName)
.targetBranch(mergeRequest.getTargetBranch())
.url(mergeRequest.getWebUrl())
.title(mergeRequest.getTitle())
.milestone(mergeRequest.getMilestone())
.sourceBranch(mergeRequest.getSourceBranch())
.description(mergeRequest.getDescription())
.authorTelegramUsername(authorUserName)
.build()
);
}
} else {
}
private void sendGroupNotifyAboutNoReviewers(MergeRequest mergeRequest, String projectName) {
final Optional<String> optAuthorUserName = personService.getTelegramUsernamesByPersonIds(mergeRequest.getAuthor().getId());
if (optAuthorUserName.isPresent()) {
final String authorUsername = optAuthorUserName.get();
@ -103,45 +155,26 @@ public class MergeRequestHandler {
}
}
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()
);
}
}
@EventListener
public void updateMrHandle(UpdateMergeRequestEvent event) {
final MergeRequest oldMergeRequest = event.getOldMergeRequest();
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();
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 (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()
@ -212,7 +245,7 @@ public class MergeRequestHandler {
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();
if (
!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();
if (
!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();
if (oldMergeRequest.isConflict() && !mergeRequest.isConflict()) {
// проверяем даты коммитов, так как при пуше в 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 newStatus = newMergeRequest.getState();
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;
}
}