Merge branch 'develop' into approvals

# Conflicts:
#	gitlab-app/src/main/resources/liquibase/v.2.0.0/changelog.xml
This commit is contained in:
Struchkov Mark 2024-08-21 16:57:45 +03:00
commit 5c4dca0d57
No known key found for this signature in database
GPG Key ID: A3F0AC3F0FA52F3C
45 changed files with 446 additions and 338 deletions

View File

@ -3,13 +3,17 @@ kind: pipeline
type: docker
name: develop build
image_pull_secrets:
- DOCKER_AUTH
trigger:
branch:
- develop
services:
- name: docker
image: docker:20.10.22-dind-alpine3.17
# https://hub.docker.com/r/library/docker
image: hub.docker.struchkov.dev/docker:27.0.3-dind-alpine3.20
privileged: true
volumes:
- name: dockersock
@ -24,7 +28,8 @@ volumes:
steps:
- name: create jar
image: maven:3.8.6-eclipse-temurin-17
# https://hub.docker.com/_/maven
image: hub.docker.struchkov.dev/maven:3.9-eclipse-temurin-17-alpine
volumes:
- name: m2
path: /root/.m2/repository
@ -32,26 +37,15 @@ steps:
- mvn -U clean package
- name: docker publish develop
image: upagge/docker-buildx:latest
image: docker.struchkov.dev/docker-buildx:latest
environment:
STRUCHKOV_DOCKER_REGISTRY_TOKEN:
from_secret: STRUCHKOV_DOCKER_REGISTRY_TOKEN
STRUCHKOV_DOCKER_IMAGE_NAME:
from_secret: STRUCHKOV_DOCKER_IMAGE_NAME
DOCKER_REGISTRY_TOKEN:
from_secret: DOCKER_REGISTRY_TOKEN
DOCKER_IMAGE_NAME:
from_secret: DOCKER_IMAGE_NAME
DOCKER_REGISTRY_USER:
from_secret: DOCKER_REGISTRY_USER
volumes:
- name: dockersock
path: /var/run
commands:
- echo "$STRUCHKOV_DOCKER_REGISTRY_TOKEN" | docker login git.struchkov.dev --username $DOCKER_REGISTRY_USER --password-stdin
- echo "$DOCKER_REGISTRY_TOKEN" | docker login docker.io --username $DOCKER_REGISTRY_USER --password-stdin
- docker buildx create --use
- docker buildx build -f Dockerfile-develop --push --platform linux/amd64,linux/arm64/v8 -t "$DOCKER_IMAGE_NAME:develop" -t "git.struchkov.dev/$STRUCHKOV_DOCKER_IMAGE_NAME:develop" .
- docker buildx build -f Dockerfile-develop --push --platform linux/amd64,linux/arm64/v8 -t "docker.struchkov.dev/gitlab-notify:develop" .
---
@ -59,13 +53,17 @@ kind: pipeline
type: docker
name: release build
image_pull_secrets:
- DOCKER_AUTH
trigger:
ref:
- refs/tags/v.*.*.*
services:
- name: docker
image: docker:20.10.22-dind-alpine3.17
# https://hub.docker.com/r/library/docker
image: hub.docker.struchkov.dev/docker:27.0.3-dind-alpine3.20
privileged: true
volumes:
- name: dockersock
@ -88,122 +86,111 @@ steps:
- mvn -U clean package
- name: docker publish release
image: upagge/docker-buildx:latest
environment:
STRUCHKOV_DOCKER_REGISTRY_TOKEN:
from_secret: STRUCHKOV_DOCKER_REGISTRY_TOKEN
STRUCHKOV_DOCKER_IMAGE_NAME:
from_secret: STRUCHKOV_DOCKER_IMAGE_NAME
DOCKER_REGISTRY_TOKEN:
from_secret: DOCKER_REGISTRY_TOKEN
DOCKER_IMAGE_NAME:
from_secret: DOCKER_IMAGE_NAME
DOCKER_REGISTRY_USER:
from_secret: DOCKER_REGISTRY_USER
image: docker.struchkov.dev/docker-buildx:latest
volumes:
- name: dockersock
path: /var/run
commands:
- echo "$STRUCHKOV_DOCKER_REGISTRY_TOKEN" | docker login git.struchkov.dev --username $DOCKER_REGISTRY_USER --password-stdin
- echo "$DOCKER_REGISTRY_TOKEN" | docker login docker.io --username $DOCKER_REGISTRY_USER --password-stdin
- docker buildx create --use
- docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t "$DOCKER_IMAGE_NAME:latest" -t "$DOCKER_IMAGE_NAME:$DRONE_TAG" -t "git.struchkov.dev/$STRUCHKOV_DOCKER_IMAGE_NAME:latest" -t "git.struchkov.dev/$STRUCHKOV_DOCKER_IMAGE_NAME:$DRONE_TAG" .
- docker buildx build --push --platform linux/amd64,linux/arm64/v8 -t "docker.struchkov.dev/gitlab-notify:latest" -t "docker.struchkov.dev/gitlab-notify:$DRONE_TAG" .
---
kind: pipeline
type: docker
name: create-develop-docs-site
#---
#kind: pipeline
#type: docker
#name: create-develop-docs-site
#
#trigger:
# branch:
# - develop
# - docs
#
#clone:
# disable: true
#
#steps:
#
# - name: build docs
# image: git.struchkov.dev/upagge/mkdocs-material-insiders:latest
# volumes:
# - name: mkdocs_cache
# path: ${DRONE_WORKSPACE}/documentation/ru/.cache
# environment:
# GIT_SSH:
# from_secret: GIT_SSH
# GIT_SSH_COMMAND: "ssh -i ~/.ssh/id_rsa -p 222"
# commands:
# - eval $(ssh-agent -s)
# - mkdir -p ~/.ssh
# - chmod 700 ~/.ssh
# - echo "$GIT_SSH" >> ~/.ssh/id_rsa
# - chmod 600 ~/.ssh/id_rsa
# - ssh-keyscan -p 222 git.struchkov.dev >> ~/.ssh/known_hosts
# - chmod 644 ~/.ssh/known_hosts
# - git config --global user.name "${DRONE_COMMIT_AUTHOR_NAME}"
# - git config --global user.email "${DRONE_COMMIT_AUTHOR_EMAIL}"
# - git clone ssh://git@git.struchkov.dev:222/Telegram-Bots/gitlab-notification.git .
# - git checkout $DRONE_COMMIT
# - cd documentation/ru
# - mike deploy --prefix gitlab-notification/ru --branch docs-deploy --push --update-aliases develop
#
#image_pull_secrets:
# - DOCKER_AUTH
#
#volumes:
# - name: mkdocs_cache
# host:
# path: /drone/volume/mkdocs_cache/gitlab_notification/ru
#
#---
#kind: pipeline
#type: docker
#name: create-release-docs-site
#
#trigger:
# ref:
# - refs/tags/v.*.*.*
#
#clone:
# disable: true
#
#steps:
#
# - name: build docs
# image: git.struchkov.dev/upagge/mkdocs-material-insiders:latest
# volumes:
# - name: mkdocs_cache
# path: ${DRONE_WORKSPACE}/documentation/ru/.cache
# environment:
# GIT_SSH:
# from_secret: GIT_SSH
# GIT_SSH_COMMAND: "ssh -i ~/.ssh/id_rsa -p 222"
# commands:
# - eval $(ssh-agent -s)
# - mkdir -p ~/.ssh
# - chmod 700 ~/.ssh
# - echo "$GIT_SSH" >> ~/.ssh/id_rsa
# - chmod 600 ~/.ssh/id_rsa
# - ssh-keyscan -p 222 git.struchkov.dev >> ~/.ssh/known_hosts
# - chmod 644 ~/.ssh/known_hosts
# - git config --global user.name "${DRONE_COMMIT_AUTHOR_NAME}"
# - git config --global user.email "${DRONE_COMMIT_AUTHOR_EMAIL}"
# - git clone ssh://git@git.struchkov.dev:222/Telegram-Bots/gitlab-notification.git .
# - git checkout $DRONE_COMMIT
# - cd documentation/ru
# - mike deploy --prefix gitlab-notification/ru --branch docs-deploy --push --update-aliases ${DRONE_TAG}
# - mike deploy --prefix gitlab-notification/ru --branch docs-deploy --push --update-aliases latest
#
#image_pull_secrets:
# - DOCKER_AUTH
#
#volumes:
# - name: mkdocs_cache
# host:
# path: /drone/volume/mkdocs_cache/gitlab_notification\
trigger:
branch:
- develop
- docs
clone:
disable: true
steps:
- name: build docs
image: git.struchkov.dev/upagge/mkdocs-material-insiders:latest
volumes:
- name: mkdocs_cache
path: ${DRONE_WORKSPACE}/documentation/ru/.cache
environment:
GIT_SSH:
from_secret: GIT_SSH
GIT_SSH_COMMAND: "ssh -i ~/.ssh/id_rsa -p 222"
commands:
- eval $(ssh-agent -s)
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo "$GIT_SSH" >> ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- ssh-keyscan -p 222 git.struchkov.dev >> ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
- git config --global user.name "${DRONE_COMMIT_AUTHOR_NAME}"
- git config --global user.email "${DRONE_COMMIT_AUTHOR_EMAIL}"
- git clone ssh://git@git.struchkov.dev:222/Telegram-Bots/gitlab-notification.git .
- git checkout $DRONE_COMMIT
- cd documentation/ru
- mike deploy --prefix gitlab-notification/ru --branch docs-deploy --push --update-aliases develop
image_pull_secrets:
- DOCKER_AUTH
volumes:
- name: mkdocs_cache
host:
path: /drone/volume/mkdocs_cache/gitlab_notification/ru
---
kind: pipeline
type: docker
name: create-release-docs-site
trigger:
ref:
- refs/tags/v.*.*.*
clone:
disable: true
steps:
- name: build docs
image: git.struchkov.dev/upagge/mkdocs-material-insiders:latest
volumes:
- name: mkdocs_cache
path: ${DRONE_WORKSPACE}/documentation/ru/.cache
environment:
GIT_SSH:
from_secret: GIT_SSH
GIT_SSH_COMMAND: "ssh -i ~/.ssh/id_rsa -p 222"
commands:
- eval $(ssh-agent -s)
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo "$GIT_SSH" >> ~/.ssh/id_rsa
- chmod 600 ~/.ssh/id_rsa
- ssh-keyscan -p 222 git.struchkov.dev >> ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
- git config --global user.name "${DRONE_COMMIT_AUTHOR_NAME}"
- git config --global user.email "${DRONE_COMMIT_AUTHOR_EMAIL}"
- git clone ssh://git@git.struchkov.dev:222/Telegram-Bots/gitlab-notification.git .
- git checkout $DRONE_COMMIT
- cd documentation/ru
- mike deploy --prefix gitlab-notification/ru --branch docs-deploy --push --update-aliases ${DRONE_TAG}
- mike deploy --prefix gitlab-notification/ru --branch docs-deploy --push --update-aliases latest
image_pull_secrets:
- DOCKER_AUTH
volumes:
- name: mkdocs_cache
host:
path: /drone/volume/mkdocs_cache/gitlab_notification
# drone sign --save Telegram-Bots/gitlab-notification
---
kind: signature
hmac: cf1bd0800e8f6bb49dae0a6c5f607676b87d5ee713f4203f4f1ed08a17f71f68
hmac: 0f4fa66591566ee4272ac8c36e887966037a407a1441575ef26e1813205a7ae8
...

View File

@ -1,4 +1,4 @@
FROM eclipse-temurin:17 as app-build
FROM eclipse-temurin:17 AS app-build
ENV RELEASE=17
WORKDIR /opt/build

View File

@ -1,4 +1,4 @@
FROM eclipse-temurin:17 as app-build
FROM eclipse-temurin:17 AS app-build
ENV RELEASE=17
WORKDIR /opt/build

View File

@ -4,8 +4,7 @@ import dev.struchkov.bot.gitlab.context.domain.entity.Person;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
import static dev.struchkov.haiti.utils.Checker.checkNull;
import java.util.Optional;
@Getter
@RequiredArgsConstructor
@ -18,18 +17,18 @@ public enum AssigneeChanged {
private final boolean changed;
public static AssigneeChanged valueOf(Long gitlabUserId, Person oldAssignee, Person newAssignee) {
if (checkNull(oldAssignee) && checkNotNull(newAssignee) && gitlabUserId.equals(newAssignee.getId())) {
public static AssigneeChanged valueOf(Long gitlabUserId, Optional<Person> oldAssignee, Optional<Person> newAssignee) {
if (oldAssignee.isEmpty() && newAssignee.isPresent() && gitlabUserId.equals(newAssignee.get().getId())) {
return AssigneeChanged.BECOME;
}
if (checkNotNull(oldAssignee) && checkNull(newAssignee) && gitlabUserId.equals(oldAssignee.getId())) {
if (oldAssignee.isPresent() && newAssignee.isEmpty() && gitlabUserId.equals(oldAssignee.get().getId())) {
return AssigneeChanged.DELETED;
}
if (checkNotNull(oldAssignee) && checkNotNull(newAssignee) && !oldAssignee.getId().equals(newAssignee.getId())) {
if (gitlabUserId.equals(oldAssignee.getId())) {
if (oldAssignee.isPresent() && newAssignee.isPresent() && !oldAssignee.get().getId().equals(newAssignee.get().getId())) {
if (gitlabUserId.equals(oldAssignee.get().getId())) {
return AssigneeChanged.DELETED;
}
if (gitlabUserId.equals(newAssignee.getId())) {
if (gitlabUserId.equals(newAssignee.get().getId())) {
return AssigneeChanged.BECOME;
}
return AssigneeChanged.NOT_AFFECT_USER;

View File

@ -57,6 +57,9 @@ public class MergeRequest {
@Column(name = "description")
private String description;
@Column(name = "milestone")
private String milestone;
@Enumerated(EnumType.STRING)
@Column(name = "state")
private MergeRequestState state;

View File

@ -20,9 +20,10 @@ public class ConflictMrNotify extends MrNotify {
String name,
String url,
String projectKey,
String sourceBranch
String sourceBranch,
String milestone
) {
super(mrId, projectKey, name, url);
super(mrId, projectKey, name, url, milestone);
this.sourceBranch = sourceBranch;
}

View File

@ -20,9 +20,10 @@ public class ConflictResolveMrNotify extends MrNotify {
String name,
String url,
String projectKey,
String sourceBranch
String sourceBranch,
String milestone
) {
super(mrId, projectKey, name, url);
super(mrId, projectKey, name, url, milestone);
this.sourceBranch = sourceBranch;
}

View File

@ -10,17 +10,20 @@ public abstract class MrNotify implements Notify {
protected final String projectName;
protected final String title;
protected final String url;
protected final String milestone;
protected MrNotify(
Long mrId,
String projectName,
String title,
String url
String url,
String milestone
) {
this.mrId = mrId;
this.projectName = projectName;
this.title = title;
this.url = url;
this.milestone = milestone;
}
}

View File

@ -33,7 +33,8 @@ public class NewMrForAssignee extends NewMrNotify {
Set<String> labels,
@Singular List<String> reviewers,
String oldAssigneeName,
String newAssigneeName
String newAssigneeName,
String milestone
) {
super(
mrId,
@ -44,7 +45,8 @@ public class NewMrForAssignee extends NewMrNotify {
projectName,
targetBranch,
sourceBranch,
labels
labels,
milestone
);
this.reviewers = reviewers;
this.oldAssigneeName = oldAssigneeName;

View File

@ -27,7 +27,8 @@ public class NewMrForReview extends NewMrNotify {
String targetBranch,
String sourceBranch,
Set<String> labels,
String assignee
String assignee,
String milestone
) {
super(
mrId,
@ -38,7 +39,8 @@ public class NewMrForReview extends NewMrNotify {
projectName,
targetBranch,
sourceBranch,
labels
labels,
milestone
);
this.assignee = assignee;
}

View File

@ -22,9 +22,10 @@ public abstract class NewMrNotify extends MrNotify {
String projectName,
String targetBranch,
String sourceBranch,
Set<String> labels
Set<String> labels,
String milestone
) {
super(mrId, projectName, title, url);
super(mrId, projectName, title, url, milestone);
this.description = description;
this.author = author;
this.targetBranch = targetBranch;

View File

@ -23,9 +23,10 @@ public class StatusMrNotify extends MrNotify {
String url,
String projectName,
MergeRequestState oldStatus,
MergeRequestState newStatus
MergeRequestState newStatus,
String milestone
) {
super(mrId, projectName, name, url);
super(mrId, projectName, name, url, milestone);
this.oldStatus = oldStatus;
this.newStatus = newStatus;
}

View File

@ -30,9 +30,10 @@ public class UpdateMrNotify extends MrNotify {
Long allResolvedTasks,
Long personTasks,
Long personResolvedTasks,
String comment
String comment,
String milestone
) {
super(mrId, projectName, name, url);
super(mrId, projectName, name, url, milestone);
this.author = author;
this.allTasks = allTasks;
this.allResolvedTasks = allResolvedTasks;

View File

@ -22,6 +22,7 @@ public class Icons {
public static final String BUILD = "⚙️";
public static final String LINK = "\uD83D\uDD17";
public static final String REVIEWER = "\uD83D\uDD0E";
public static final String MILESTONE = "\uD83C\uDFAF";
public static final String PROJECT = "\uD83C\uDFD7";
public static final String DISABLE_NOTIFY = "\uD83D\uDD15";
public static final String YES = "";

View File

@ -43,6 +43,10 @@ public class MergeRequestJsonConverter implements Converter<MergeRequestJson, Me
convertLabels(mergeRequest, source.getLabels());
convertReviewers(mergeRequest, source.getReviewers());
if (checkNotNull(source.getMilestone())) {
mergeRequest.setMilestone(source.getMilestone().getTitle());
}
if (checkNotNull(source.getAssignee())) {
mergeRequest.setAssignee(convertPerson.convert(source.getAssignee()));
}

View File

@ -29,6 +29,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@ -81,10 +82,11 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
private boolean isBotUserAssigneeAndNotAuthor(MergeRequest mergeRequest) {
final Long gitlabUserId = personInformation.getId();
final Person assignee = mergeRequest.getAssignee();
final Optional<Person> optAssignee = getAssignee(mergeRequest);
final Person author = mergeRequest.getAuthor();
if (checkNotNull(assignee)) {
if (optAssignee.isPresent()) {
final Person assignee = optAssignee.get();
if (gitlabUserId.equals(assignee.getId()) && !isAuthorSameAssignee(author, assignee)) {
return true;
}
@ -116,20 +118,27 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
}
private void sendNotifyNewMrReview(MergeRequest mergeRequest, String projectName) {
notifyService.send(
NewMrForReview.builder()
.mrId(mergeRequest.getId())
.projectName(projectName)
.labels(mergeRequest.getLabels())
.author(mergeRequest.getAuthor().getName())
.description(mergeRequest.getDescription())
.title(mergeRequest.getTitle())
.url(mergeRequest.getWebUrl())
.targetBranch(mergeRequest.getTargetBranch())
.sourceBranch(mergeRequest.getSourceBranch())
.assignee(mergeRequest.getAssignee().getName())
.build()
);
final NewMrForReview.NewMrForReviewBuilder builder = NewMrForReview.builder()
.mrId(mergeRequest.getId())
.projectName(projectName)
.labels(mergeRequest.getLabels())
.author(mergeRequest.getAuthor().getName())
.milestone(mergeRequest.getMilestone())
.description(mergeRequest.getDescription())
.title(mergeRequest.getTitle())
.url(mergeRequest.getWebUrl())
.targetBranch(mergeRequest.getTargetBranch())
.sourceBranch(mergeRequest.getSourceBranch());
getAssignee(mergeRequest)
.map(Person::getName)
.ifPresent(builder::assignee);
notifyService.send(builder.build());
}
private Optional<Person> getAssignee(MergeRequest mergeRequest) {
return Optional.ofNullable(mergeRequest.getAssignee());
}
private void sendNotifyNewAssignee(MergeRequest mergeRequest, String projectName, String oldAssigneeName) {
@ -139,18 +148,20 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
.labels(mergeRequest.getLabels())
.author(mergeRequest.getAuthor().getName())
.description(mergeRequest.getDescription())
.milestone(mergeRequest.getMilestone())
.title(mergeRequest.getTitle())
.url(mergeRequest.getWebUrl())
.targetBranch(mergeRequest.getTargetBranch())
.sourceBranch(mergeRequest.getSourceBranch())
.milestone(mergeRequest.getMilestone())
.reviewers(mergeRequest.getReviewers().stream().map(Person::getName).toList());
if (checkNotNull(oldAssigneeName)) {
builder.oldAssigneeName(oldAssigneeName);
if (checkNotNull(mergeRequest.getAssignee())) {
builder.newAssigneeName(mergeRequest.getAssignee().getName());
}
getAssignee(mergeRequest)
.map(Person::getName)
.ifPresent(builder::newAssigneeName);
}
notifyService.send(builder.build());
@ -165,7 +176,7 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
mergeRequest.setNotification(oldMergeRequest.isNotification());
final Long gitlabUserId = personInformation.getId();
final AssigneeChanged assigneeChanged = AssigneeChanged.valueOf(gitlabUserId, oldMergeRequest.getAssignee(), mergeRequest.getAssignee());
final AssigneeChanged assigneeChanged = AssigneeChanged.valueOf(gitlabUserId, getAssignee(oldMergeRequest), getAssignee(mergeRequest));
final ReviewerChanged reviewerChanged = ReviewerChanged.valueOf(gitlabUserId, oldMergeRequest.getReviewers(), mergeRequest.getReviewers());
mergeRequest.setUserAssignee(assigneeChanged.getNewStatus(oldMergeRequest.isUserAssignee()));
@ -173,8 +184,9 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
final boolean isChangedMr = !oldMergeRequest.getUpdatedDate().equals(mergeRequest.getUpdatedDate()) || oldMergeRequest.isConflict() != mergeRequest.isConflict();
final boolean isChangedLinkedEntity = reviewerChanged.isChanged() || assigneeChanged.isChanged();
final boolean isMilestone = !Objects.equals(oldMergeRequest.getMilestone(), mergeRequest.getMilestone());
if (isChangedMr || isChangedLinkedEntity) {
if (isChangedMr || isChangedLinkedEntity || isMilestone) {
if (oldMergeRequest.isNotification()) {
final Project project = projectService.getByIdOrThrow(mergeRequest.getProjectId());
@ -191,6 +203,7 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
notifyAssignee(assigneeChanged, oldMergeRequest, mergeRequest, project);
}
}
return repository.save(mergeRequest);
}
@ -202,7 +215,7 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
private void notifyAssignee(AssigneeChanged assigneeChanged, MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
switch (assigneeChanged) {
case BECOME ->
sendNotifyNewAssignee(mergeRequest, project.getName(), Optional.ofNullable(oldMergeRequest.getAssignee()).map(Person::getName).orElse(null));
sendNotifyNewAssignee(mergeRequest, project.getName(), getAssignee(oldMergeRequest).map(Person::getName).orElse(null));
}
}
//TODO [05.12.2022|uPagge]: Добавить уведомление, если происходит удаление ревьювера
@ -319,6 +332,7 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
.projectName(project.getName())
.url(oldMergeRequest.getWebUrl())
.allTasks(allTask)
.milestone(mergeRequest.getMilestone())
.allResolvedTasks(resolvedTask)
.personTasks(allYouTasks)
.personResolvedTasks(resolvedYouTask);
@ -345,6 +359,7 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
.name(mergeRequest.getTitle())
.url(mergeRequest.getWebUrl())
.projectKey(project.getName())
.milestone(mergeRequest.getMilestone())
.build()
);
}
@ -365,6 +380,7 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
.name(mergeRequest.getTitle())
.url(mergeRequest.getWebUrl())
.projectKey(project.getName())
.milestone(mergeRequest.getMilestone())
.build()
);
}
@ -388,6 +404,7 @@ public class MergeRequestsServiceImpl implements MergeRequestsService {
.projectName(project.getName())
.newStatus(newStatus)
.oldStatus(oldStatus)
.milestone(newMergeRequest.getMilestone())
.build()
);
}

View File

@ -101,8 +101,9 @@ public class PipelineServiceImpl implements PipelineService {
private boolean isNeedNotifyNewPipeline(@NonNull Pipeline pipeline) {
final Person personPipelineCreator = pipeline.getPerson();
return notificationStatus.contains(pipeline.getStatus()) // Пайплайн имеет статус необходимый для уведомления
&& checkNotNull(personPipelineCreator) // Создатель пайплайна не null
&& personInformation.getId().equals(personPipelineCreator.getId()); // Пользователь приложения является инициатором пайплайна
&& checkNotNull(personPipelineCreator) // Создатель пайплайна не null
&& personInformation.getId().equals(personPipelineCreator.getId()) // Пользователь приложения является инициатором пайплайна
&& LocalDateTime.now().minusDays(1).isBefore(pipeline.getCreated()); // Пайплан был создан не более 24 часов назад
}
@Override
@ -128,7 +129,7 @@ public class PipelineServiceImpl implements PipelineService {
@Override
public void cleanOld() {
log.debug("Старт очистки старых пайплайнов");
repository.deleteByCreatedBefore(LocalDateTime.now().minusDays(1L));
repository.deleteByCreatedBefore(LocalDateTime.now().minusDays(7L));
log.debug("Конец очистки старых пайплайнов");
}

View File

@ -35,6 +35,7 @@ import static dev.struchkov.haiti.utils.Checker.checkFalse;
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResult;
import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResults;
import static java.util.stream.Collectors.toMap;
/**
* Парсер пайплайнов.
@ -79,7 +80,7 @@ public class PipelineParser {
final Set<Long> projectIds = projectService.getAllIdByProcessingEnable();
final Map<Long, Long> pipelineProjectMap = getPipelineShortJsons(projectIds).stream()
.collect(Collectors.toMap(PipelineShortJson::getId, PipelineShortJson::getProjectId));
.collect(toMap(PipelineShortJson::getId, PipelineShortJson::getProjectId));
if (checkNotEmpty(pipelineProjectMap)) {
final ExistContainer<Pipeline, Long> existContainer = pipelineService.existsById(pipelineProjectMap.keySet());
@ -99,14 +100,16 @@ public class PipelineParser {
log.debug("Конец обработки новых пайплайнов");
}
private List<Pipeline> getNewPipelines(Map<Long, Long> pipelineProjectMap, Set<Long> idsNotFound) {
private List<Pipeline> getNewPipelines(Map<Long, Long> pipelineIdAndProjectId, Set<Long> idsNotFound) {
final List<ForkJoinTask<Optional<PipelineJson>>> tasks = idsNotFound.stream()
.map(pipelineId -> new GetPipelineTask(
gitlabProperty.getPipelineUrl(),
pipelineProjectMap.get(pipelineId),
pipelineId,
personProperty.getToken()
))
.map(
pipelineId -> GetPipelineTask.builder()
.pipelineId(pipelineId)
.projectId(pipelineIdAndProjectId.get(pipelineId))
.urlPipeline(gitlabProperty.getPipelineUrl())
.gitlabToken(personProperty.getToken())
.build()
)
.map(forkJoinPool::submit)
.collect(Collectors.toList());
@ -117,7 +120,7 @@ public class PipelineParser {
}
private List<PipelineShortJson> getPipelineShortJsons(Set<Long> projectIds) {
LocalDateTime newLastUpdate = LocalDateTime.now();
final LocalDateTime newLastUpdate = LocalDateTime.now();
final List<ForkJoinTask<List<PipelineShortJson>>> tasks = projectIds.stream()
.map(projectId -> new GetPipelineShortTask(
gitlabProperty.getPipelinesUrl(),
@ -141,12 +144,13 @@ public class PipelineParser {
final List<ForkJoinTask<Optional<PipelineJson>>> tasks = pipelines.stream()
.map(
pipeline -> new GetPipelineTask(
gitlabProperty.getPipelineUrl(),
pipeline.getProjectId(),
pipeline.getId(),
personProperty.getToken()
)
pipeline ->
GetPipelineTask.builder()
.projectId(pipeline.getProjectId())
.pipelineId(pipeline.getId())
.urlPipeline(gitlabProperty.getPipelineUrl())
.gitlabToken(gitlabProperty.getPipelineUrl())
.build()
)
.map(forkJoinPool::submit)
.collect(Collectors.toList());

View File

@ -3,7 +3,10 @@ package dev.struchkov.bot.gitlab.core.service.parser.forktask;
import dev.struchkov.bot.gitlab.core.utils.HttpParse;
import dev.struchkov.bot.gitlab.core.utils.StringUtils;
import dev.struchkov.bot.gitlab.sdk.domain.PipelineJson;
import lombok.RequiredArgsConstructor;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@ -15,13 +18,15 @@ import static dev.struchkov.bot.gitlab.core.utils.HttpParse.ACCEPT;
@Slf4j
@RequiredArgsConstructor
@Builder
@NoArgsConstructor
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class GetPipelineTask extends RecursiveTask<Optional<PipelineJson>> {
private final String urlPipeline;
private final long projectId;
private final long pipelineId;
private final String gitlabToken;
private String urlPipeline;
private long projectId;
private long pipelineId;
private String gitlabToken;
@Override
@SneakyThrows

View File

@ -3,6 +3,7 @@ package dev.struchkov.bot.gitlab.core.utils;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import dev.struchkov.haiti.utils.Inspector;
import jakarta.validation.constraints.NotNull;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
@ -15,6 +16,7 @@ import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
import static dev.struchkov.haiti.utils.Inspector.isNotNull;
@ -77,7 +79,7 @@ public class HttpParse {
final HttpUrl url = httpUrlBuilder.build();
final Request request = requestBuilder.url(url).build();
log.trace("Выполняется okhttp3 запрос | {}", url);
final OkHttpClient httpClient = new OkHttpClient();
final OkHttpClient httpClient = getNewClient();
try (final Response execute = httpClient.newCall(request).execute()) {
log.trace("Запрос выполнен | {}", url);
if (execute.isSuccessful() && checkNotNull(execute.body())) {
@ -96,7 +98,7 @@ public class HttpParse {
final HttpUrl url = httpUrlBuilder.build();
final Request request = requestBuilder.url(url).build();
log.trace("Выполняется okhttp3 запрос | {}", url);
final OkHttpClient httpClient = new OkHttpClient();
final OkHttpClient httpClient = getNewClient();
try (Response execute = httpClient.newCall(request).execute()) {
log.trace("Запрос выполнен | {}", url);
ResponseBody body = execute.body();
@ -111,4 +113,13 @@ public class HttpParse {
return Collections.emptyList();
}
@NotNull
private static OkHttpClient getNewClient() {
return new OkHttpClient().newBuilder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS)
.build();
}
}

View File

@ -19,7 +19,8 @@ spring:
logging:
level:
"dev.struchkov": ${LOG_LEVEL:info}
"dev.struchkov": ${LOG_LEVEL:INFO}
"dev.struchkov.bot.gitlab": ${APP_LOG_LEVEL:INFO}
telegram:
bot:
@ -39,9 +40,9 @@ gitlab-bot:
version: 1.0.0
cron:
scan:
general: "0 */1 * * * *"
new-project: "0 0 */1 * * *"
new-merge-request: "0 */15 * * * *"
general: ${CRON_GENERAL:0 */1 * * * *}
new-project: ${CRON_NEW_PROJECTS:0 0 */1 * * *}
new-merge-request: ${CRON_NEW_MR:0 */15 * * * *}
person:
telegram-id: ${TELEGRAM_PERSON_ID}
token: ${GITLAB_PERSONAL_TOKEN}

View File

@ -0,0 +1,34 @@
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.17.xsd">
<changeSet id="2024-02-06-change-varchar" author="struchkov">
<modifyDataType tableName="merge_request" columnName="title" newDataType="varchar"/>
<modifyDataType tableName="merge_request" columnName="description" newDataType="varchar"/>
<modifyDataType tableName="merge_request" columnName="state" newDataType="varchar"/>
<modifyDataType tableName="merge_request" columnName="web_url" newDataType="varchar"/>
<modifyDataType tableName="merge_request" columnName="source_branch" newDataType="varchar"/>
<modifyDataType tableName="merge_request" columnName="target_branch" newDataType="varchar"/>
<modifyDataType tableName="discussion" columnName="id" newDataType="varchar"/>
<modifyDataType tableName="discussion_merge_request" columnName="discussion_id" newDataType="varchar"/>
<modifyDataType tableName="merge_request_label" columnName="label" newDataType="varchar"/>
<modifyDataType tableName="note" columnName="type" newDataType="varchar"/>
<modifyDataType tableName="note" columnName="body" newDataType="varchar"/>
<modifyDataType tableName="note" columnName="noteable_type" newDataType="varchar"/>
<modifyDataType tableName="note" columnName="resolvable" newDataType="varchar"/>
<modifyDataType tableName="note" columnName="web_url" newDataType="varchar"/>
<modifyDataType tableName="person" columnName="username" newDataType="varchar"/>
<modifyDataType tableName="person" columnName="name" newDataType="varchar"/>
<modifyDataType tableName="person" columnName="web_url" newDataType="varchar"/>
<modifyDataType tableName="pipeline" columnName="ref" newDataType="varchar"/>
<modifyDataType tableName="pipeline" columnName="status" newDataType="varchar"/>
<modifyDataType tableName="pipeline" columnName="web_url" newDataType="varchar"/>
<modifyDataType tableName="project" columnName="name" newDataType="varchar"/>
<modifyDataType tableName="project" columnName="description" newDataType="varchar"/>
<modifyDataType tableName="project" columnName="web_url" newDataType="varchar"/>
<modifyDataType tableName="project" columnName="ssh_url_to_repo" newDataType="varchar"/>
<modifyDataType tableName="project" columnName="http_url_to_repo" newDataType="varchar"/>
</changeSet>
</databaseChangeLog>

View File

@ -0,0 +1,14 @@
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.17.xsd">
<changeSet id="2024-08-21-add-milestone" author="mstruchkov">
<addColumn tableName="merge_request">
<column name="milestone" type="varchar">
<constraints nullable="true"/>
</column>
</addColumn>
</changeSet>
</databaseChangeLog>

View File

@ -3,10 +3,12 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.17.xsd">
<changeSet id="2024-01-20-add-tab-v-2-0-0" author="uPagge">
<changeSet id="2024-02-06-add-tab-v-2-0-0" author="uPagge">
<tagDatabase tag="v.2.0.0"/>
</changeSet>
<include file="2024-02-06-change-varchar.xml" relativeToChangelogFile="true"/>
<include file="2024-08-21-add-milestone.xml" relativeToChangelogFile="true"/>
<include file="2024-01-20-create-merge-request-approvals.xml" relativeToChangelogFile="true"/>
</databaseChangeLog>

View File

@ -41,6 +41,7 @@ public class MergeRequestJson {
private PersonJson author;
private PersonJson assignee;
private MilestoneJson milestone;
private List<PersonJson> reviewers;
@JsonProperty("web_url")

View File

@ -0,0 +1,9 @@
package dev.struchkov.bot.gitlab.sdk.domain;
import lombok.Data;
@Data
public class MilestoneJson {
private Long id;
private String title;
}

View File

@ -45,7 +45,7 @@
<godfather.telegram.version>1.0.0-SNAPSHOT</godfather.telegram.version>
<!-- https://mvnrepository.com/artifact/dev.struchkov.haiti/haiti-utils -->
<haiti.utils.version>3.0.2</haiti.utils.version>
<haiti.utils.version>3.0.3</haiti.utils.version>
<haiti.utils.fields.version>1.1.1</haiti.utils.fields.version>
<haiti.filter.version>0.0.5</haiti.filter.version>
@ -53,12 +53,12 @@
<jakarta.persistance.version>3.2.0-M1</jakarta.persistance.version>
<!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
<google.guava.version>33.0.0-jre</google.guava.version>
<google.guava.version>33.3.0-jre</google.guava.version>
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-compiler-plugin -->
<plugin.maven.compiler.ver>3.12.1</plugin.maven.compiler.ver>
<plugin.maven.compiler.ver>3.13.0</plugin.maven.compiler.ver>
<!-- https://mvnrepository.com/artifact/org.apache.maven.plugins/maven-release-plugin -->
<plugin.maven.release.ver>3.0.1</plugin.maven.release.ver>
<plugin.maven.release.ver>3.1.1</plugin.maven.release.ver>
</properties>
<dependencyManagement>

View File

@ -8,6 +8,7 @@ import dev.struchkov.godfather.simple.domain.BoxAnswer;
import dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload;
import dev.struchkov.godfather.telegram.simple.context.service.TelegramSending;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.List;
@ -20,6 +21,7 @@ import java.util.stream.Collectors;
*
* @author upagge 17.09.2020
*/
@Slf4j
@Service
public class MessageSendTelegramService implements MessageSendService {
@ -45,6 +47,7 @@ public class MessageSendTelegramService implements MessageSendService {
final BoxAnswer answer = generator.generate(notify);
answer.setRecipientIfNull(personInformation.getTelegramId());
answer.addPayload(BoxAnswerPayload.DISABLE_WEB_PAGE_PREVIEW, true);
log.debug("Будет отправлено следующее уведомление: {}. Текст: {}", answer, answer.getMessage());
return answer;
})
.ifPresent(sending::send);

View File

@ -5,27 +5,21 @@ import dev.struchkov.bot.gitlab.context.utils.Icons;
import dev.struchkov.bot.gitlab.core.config.properties.AppProperty;
import dev.struchkov.bot.gitlab.core.config.properties.PersonProperty;
import dev.struchkov.godfather.simple.domain.BoxAnswer;
import dev.struchkov.godfather.simple.domain.SentBox;
import dev.struchkov.godfather.telegram.domain.ClientBotCommand;
import dev.struchkov.godfather.telegram.simple.context.service.TelegramSending;
import dev.struchkov.godfather.telegram.simple.context.service.TelegramService;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
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.button.SimpleButton.simpleButton;
import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.DISABLE_WEB_PAGE_PREVIEW;
import static dev.struchkov.haiti.utils.Checker.checkNotBlank;
import static dev.struchkov.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
/**
* @author upagge 19.01.2021
@ -35,8 +29,6 @@ import static dev.struchkov.haiti.utils.Checker.checkNotBlank;
@RequiredArgsConstructor
public class StartNotify {
private final OkHttpClient client = new OkHttpClient();
private final TelegramSending sending;
private final TelegramService telegramService;
@ -62,56 +54,10 @@ public class StartNotify {
simpleButton("Open Menu", "/start")
)
)
.payload(DISABLE_WEB_PAGE_PREVIEW, true)
.payload(ENABLE_MARKDOWN)
.payload(DISABLE_WEB_PAGE_PREVIEW)
.build();
sending.send(boxAnswer);
sendNotice();
}
registrationForStatistic();
}
/**
* Отправляет service_key для сбора анонимной статистики использования.
*/
private void registrationForStatistic() {
final UUID serviceKey = settingService.getServiceKey();
final boolean firstStart = settingService.isFirstStart();
final String requestUrl = "https://metrika.struchkov.dev/gitlab-notify/registration?key=" + serviceKey + "&initFlow=" + firstStart;
final Request request = new Request.Builder().get().url(requestUrl).build();
try {
client.newCall(request).execute();
} catch (Exception e) {
log.warn(e.getMessage());
}
}
/**
* Используется для уведомления пользователя о выходе новой версии.
*/
private void sendNotice() {
final String requestUrl = "https://metrika.struchkov.dev/gitlab-notify/start-notice";
final Request request = new Request.Builder().get().url(requestUrl).build();
try {
final Response response = client.newCall(request).execute();
if (response.code() == 200) {
final String noticeMessage = response.body().string();
if (checkNotBlank(noticeMessage)) {
final BoxAnswer notice = BoxAnswer.builder()
.message(noticeMessage)
.recipientPersonId(personProperty.getTelegramId())
.payload(DISABLE_WEB_PAGE_PREVIEW, true)
.build();
final Optional<SentBox> optSentBox = sending.send(notice);
if (optSentBox.isPresent()) {
final SentBox sentBox = optSentBox.get();
final String messageId = sentBox.getMessageId();
telegramService.pinMessage(personProperty.getTelegramId(), messageId);
}
}
}
} catch (Exception e) {
log.warn(e.getMessage());
}
}

View File

@ -9,11 +9,12 @@ import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_CONFIRMAT
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.simple.domain.BoxAnswer.boxAnswer;
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.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@Component
@ -26,20 +27,28 @@ public class ConflictPrNotifyGenerator implements NotifyBoxAnswerGenerator<Confl
.append(Icons.HR)
.append(escapeMarkdown(notify.getTitle()))
.append(Icons.HR)
.append(Icons.PROJECT).append(": ").append(escapeMarkdown(notify.getProjectName())).append("\n")
.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(
notifyMessage,
inlineKeyBoard(
return BoxAnswer.builder()
.message(notifyMessage)
.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(ENABLE_MARKDOWN)
.build();
}
@Override

View File

@ -9,11 +9,12 @@ import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_CONFIRMAT
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.simple.domain.BoxAnswer.boxAnswer;
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.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@Component
@ -26,20 +27,28 @@ public class ConflictResolvePrNotifyGenerator implements NotifyBoxAnswerGenerato
.append(Icons.HR)
.append(escapeMarkdown(notify.getTitle()))
.append(Icons.HR)
.append(Icons.PROJECT).append(": ").append(escapeMarkdown(notify.getProjectName())).append("\n")
.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(
notifyMessage,
inlineKeyBoard(
return BoxAnswer.builder()
.message(notifyMessage)
.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(ENABLE_MARKDOWN)
.build();
}
@Override

View File

@ -10,10 +10,10 @@ import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_CONFIRMAT
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_THREAD_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.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard;
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.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Checker.checkNotBlank;
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@ -51,14 +51,16 @@ public class NewCommentNotifyGenerator implements NotifyBoxAnswerGenerator<NewCo
}
final String messageNotify = builder.toString();
return boxAnswer(
messageNotify,
inlineKeyBoard(
return BoxAnswer.builder()
.message(messageNotify)
.keyBoard(inlineKeyBoard(
simpleButton(Icons.VIEW, DELETE_MESSAGE),
urlButton(Icons.LINK, notify.getUrl()),
simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_THREAD_ID + ":" + notify.getThreadId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]")
)
);
))
.payload(ENABLE_MARKDOWN)
.build();
}
@Override

View File

@ -48,6 +48,10 @@ public class NewMrForAssigneeNotifyGenerator implements NotifyBoxAnswerGenerator
.append(Icons.TREE).append(": ").append(escapeMarkdown(notify.getSourceBranch())).append(Icons.ARROW).append(escapeMarkdown(notify.getTargetBranch())).append("\n")
.append(Icons.AUTHOR).append(": ").append(notify.getAuthor()).append("\n");
if (checkNotNull(notify.getMilestone())) {
builder.append(Icons.MILESTONE).append(": ").append(notify.getMilestone()).append("\n");
}
final List<String> reviewers = notify.getReviewers();
if (checkNotEmpty(reviewers)) {
builder.append(Icons.REVIEWER).append(": ").append(String.join(", ", reviewers)).append("\n");

View File

@ -11,11 +11,11 @@ import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_CONFIRMAT
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.simple.domain.BoxAnswer.boxAnswer;
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.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@ -31,7 +31,7 @@ public class NewMrForReviewNotifyGenerator implements NotifyBoxAnswerGenerator<N
final StringBuilder builder = new StringBuilder(Icons.FUN).append(" *New merge request for review*")
.append(Icons.HR)
.append(notify.getTitle());
.append(escapeMarkdown(notify.getTitle()));
if (!labelText.isEmpty()) {
builder.append("\n\n").append(labelText);
@ -43,6 +43,10 @@ public class NewMrForReviewNotifyGenerator implements NotifyBoxAnswerGenerator<N
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(Icons.TREE).append(": ").append(escapeMarkdown(notify.getSourceBranch())).append(Icons.ARROW).append(escapeMarkdown(notify.getTargetBranch())).append("\n")
.append(Icons.AUTHOR).append(": ").append(notify.getAuthor()).append("\n");
@ -52,16 +56,18 @@ public class NewMrForReviewNotifyGenerator implements NotifyBoxAnswerGenerator<N
}
final String notifyMessage = builder.toString();
return boxAnswer(
notifyMessage,
inlineKeyBoard(
return BoxAnswer.builder()
.message(notifyMessage)
.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(ENABLE_MARKDOWN)
.build();
}
@Override

View File

@ -11,11 +11,11 @@ import org.springframework.stereotype.Component;
import java.util.Optional;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
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.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@Component
@ -46,16 +46,17 @@ public class NewProjectNotifyGenerator implements NotifyBoxAnswerGenerator<NewPr
final String notifyMessage = builder.toString();
return boxAnswer(
notifyMessage,
inlineKeyBoard(
return BoxAnswer.builder()
.message(notifyMessage)
.keyBoard(inlineKeyBoard(
keyBoardLine(urlButton(Icons.LINK, notify.getProjectUrl())),
keyBoardLine(
simpleButton(Icons.NOTIFY, "[" + Const.BUTTON_ARG_ENABLE_NOTIFY_PROJECT_ID + ":" + notify.getProjectId() + "]"),
simpleButton(Icons.DISABLE_NOTIFY, DELETE_MESSAGE)
)
)
);
))
.payload(ENABLE_MARKDOWN)
.build();
}
@Override

View File

@ -13,10 +13,10 @@ import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_CONFIRMAT
import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_DISABLE_NOTIFY_THREAD_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.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard;
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.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Checker.checkNotBlank;
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@ -49,14 +49,16 @@ public class NewThreadNotifyGenerator implements NotifyBoxAnswerGenerator<Discus
}
final String notifyMessage = builder.toString();
return boxAnswer(
notifyMessage,
inlineKeyBoard(
return BoxAnswer.builder()
.message(notifyMessage)
.keyBoard(inlineKeyBoard(
simpleButton(Icons.VIEW, DELETE_MESSAGE),
urlButton(Icons.LINK, notify.getUrl()),
simpleButton(Icons.DISABLE_NOTIFY, "[" + BUTTON_ARG_DISABLE_NOTIFY_THREAD_ID + ":" + notify.getThreadId() + ";" + BUTTON_ARG_CONFIRMATION + ":" + BUTTON_VALUE_FALSE + "]")
)
);
))
.payload(ENABLE_MARKDOWN)
.build();
}
private String convertNotes(List<Pair<String, String>> notes) {

View File

@ -11,11 +11,11 @@ import org.springframework.stereotype.Service;
import java.util.Optional;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
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.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
@Service
@RequiredArgsConstructor
@ -42,15 +42,16 @@ public class PipelineNotifyGenerator implements NotifyBoxAnswerGenerator<Pipelin
builder
.append(Icons.TREE).append(": ").append(notify.getRefName());
return boxAnswer(
builder.toString(),
inlineKeyBoard(
return BoxAnswer.builder()
.message(builder.toString())
.keyBoard(inlineKeyBoard(
keyBoardLine(
simpleButton(Icons.VIEW, DELETE_MESSAGE),
urlButton(Icons.LINK, notify.getWebUrl())
)
)
);
))
.payload(ENABLE_MARKDOWN)
.build();
}
@Override

View File

@ -6,11 +6,12 @@ import dev.struchkov.godfather.simple.domain.BoxAnswer;
import org.springframework.stereotype.Component;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
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.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@Component
@ -22,21 +23,29 @@ public class StatusMrNotifyGenerator implements NotifyBoxAnswerGenerator<StatusM
final StringBuilder builder = new StringBuilder(Icons.PEN).append(" *MergeRequest status changed*")
.append(Icons.HR)
.append(escapeMarkdown(notify.getTitle())).append("\n\n")
.append(notify.getOldStatus().name()).append(Icons.ARROW).append(notify.getNewStatus().name())
.append(notify.getOldStatus().name()).append(Icons.ARROW).append(notify.getNewStatus().name());
if (checkNotNull(notify.getMilestone())) {
builder
.append("\n").append(Icons.MILESTONE).append(": ").append(notify.getMilestone()).append("\n");
}
builder
.append(Icons.HR)
.append(Icons.PROJECT).append(": ").append(escapeMarkdown(notify.getProjectName()));
final String notifyMessage = builder.toString();
return boxAnswer(
notifyMessage,
inlineKeyBoard(
return BoxAnswer.builder()
.message(notifyMessage)
.keyBoard(inlineKeyBoard(
keyBoardLine(
simpleButton(Icons.VIEW, DELETE_MESSAGE),
urlButton(Icons.LINK, notify.getUrl())
)
)
);
))
.payload(ENABLE_MARKDOWN)
.build();
}
@Override

View File

@ -6,10 +6,10 @@ import dev.struchkov.godfather.simple.domain.BoxAnswer;
import org.springframework.stereotype.Component;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.DELETE_MESSAGE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.godfather.telegram.domain.keyboard.InlineKeyBoard.inlineKeyBoard;
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.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Checker.checkNotBlank;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@ -38,13 +38,14 @@ public class ThreadCloseNotifyGenerate implements NotifyBoxAnswerGenerator<Threa
}
final String notifyMessage = builder.toString();
return boxAnswer(
notifyMessage,
inlineKeyBoard(
return BoxAnswer.builder()
.message(notifyMessage)
.keyBoard(inlineKeyBoard(
simpleButton(Icons.VIEW, DELETE_MESSAGE),
urlButton(Icons.LINK, notify.getUrl())
)
);
))
.payload(ENABLE_MARKDOWN)
.build();
}
@Override

View File

@ -9,11 +9,11 @@ import static dev.struchkov.bot.gitlab.telegram.utils.Const.BUTTON_ARG_CONFIRMAT
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.simple.domain.BoxAnswer.boxAnswer;
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.godfather.telegram.main.context.BoxAnswerPayload.ENABLE_MARKDOWN;
import static dev.struchkov.haiti.utils.Checker.checkNotBlank;
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
@ -48,20 +48,25 @@ public class UpdateMrNotifyGenerator implements NotifyBoxAnswerGenerator<UpdateM
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(Icons.AUTHOR).append(": ").append(notify.getAuthor());
final String notifyMessage = builder.toString();
return boxAnswer(
notifyMessage,
inlineKeyBoard(
return BoxAnswer.builder()
.message(notifyMessage)
.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(ENABLE_MARKDOWN)
.build();
}
@Override

View File

@ -11,17 +11,16 @@ import dev.struchkov.godfather.simple.domain.unit.AnswerText;
import dev.struchkov.godfather.telegram.domain.attachment.LinkAttachment;
import dev.struchkov.godfather.telegram.main.core.util.Attachments;
import dev.struchkov.godfather.telegram.starter.PersonUnitConfiguration;
import dev.struchkov.haiti.utils.Checker;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.text.MessageFormat;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static dev.struchkov.bot.gitlab.telegram.utils.UnitName.ANSWER_NOTE;
import static dev.struchkov.godfather.simple.domain.BoxAnswer.boxAnswer;
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
@Component
@RequiredArgsConstructor
@ -40,11 +39,9 @@ public class AnswerNoteUnit implements PersonUnitConfiguration {
return AnswerText.<Mail>builder()
.triggerCheck(
mail -> {
final List<Mail> forwardMails = mail.getForwardMail();
if (Checker.checkNotNull(forwardMails) && forwardMails.size() == 1) {
final Mail forwardMail = forwardMails.get(0);
final boolean isLink = Attachments.findFirstLink(forwardMail.getAttachments())
.isPresent();
final Mail replay = mail.getReplayMail();
if (checkNotNull(replay)) {
final boolean isLink = Attachments.findFirstLink(replay.getAttachments()).isPresent();
if (isLink) {
final boolean isAccess = personInformation.getTelegramId().equals(mail.getFromPersonId());
final boolean firstStart = settingService.isFirstStart();
@ -56,7 +53,7 @@ public class AnswerNoteUnit implements PersonUnitConfiguration {
)
.answer(
mail -> {
final String noteUrl = Attachments.findFirstLink(mail.getForwardMail().get(0).getAttachments())
final String noteUrl = Attachments.findFirstLink(mail.getReplayMail().getAttachments())
.map(LinkAttachment::getUrl)
.orElseThrow();
final Matcher matcher = NOTE_LINK.matcher(noteUrl);

View File

@ -44,7 +44,8 @@ public class DeleteMessageUnit implements PersonUnitConfiguration {
})
.answer(mail -> {
final ButtonClickAttachment clickButton = Attachments.findFirstButtonClick(mail.getAttachments()).orElseThrow();
telegramSending.deleteMessage(mail.getFromPersonId(), clickButton.getMessage().getId());
//TODO [21.08.2024|uPagge]: fixme
telegramSending.deleteMessage(mail.getFromPersonId(), clickButton.getMessage().get().getId());
})
.build();
}

View File

@ -77,7 +77,8 @@ public class DisableNotifyMrUnit implements PersonUnitConfiguration {
if (confirmation) {
mergeRequestsService.notification(false, mrId);
scheduledExecutorService.schedule(() -> telegramSending.deleteMessage(mail.getFromPersonId(), clickButton.getMessage().getId()), 5, TimeUnit.SECONDS);
//TODO [21.08.2024|uPagge]: fixme
scheduledExecutorService.schedule(() -> telegramSending.deleteMessage(mail.getFromPersonId(), clickButton.getMessage().get().getId()), 5, TimeUnit.SECONDS);
return replaceBoxAnswer(SUCCESSFULLY_DISABLED);
} else {
return replaceBoxAnswer(

View File

@ -73,7 +73,8 @@ public class DisableNotifyThreadUnit implements PersonUnitConfiguration {
if (confirmation) {
discussionService.notification(false, discussionId);
scheduledExecutorService.schedule(() -> telegramSending.deleteMessage(mail.getFromPersonId(), clickButton.getMessage().getId()), 5, TimeUnit.SECONDS);
//TODO [21.08.2024|uPagge]: fixme
scheduledExecutorService.schedule(() -> telegramSending.deleteMessage(mail.getFromPersonId(), clickButton.getMessage().get().getId()), 5, TimeUnit.SECONDS);
return replaceBoxAnswer(SUCCESSFULLY_DISABLED);
} else {
return replaceBoxAnswer(

View File

@ -24,6 +24,7 @@ import dev.struchkov.godfather.telegram.starter.PersonUnitConfiguration;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -218,6 +219,8 @@ public class InitSettingFlow implements PersonUnitConfiguration {
final String personId = mail.getFromPersonId();
final String messageId = Attachments.findFirstButtonClick(mail.getAttachments())
.map(ButtonClickAttachment::getMessage)
//TODO [21.08.2024|uPagge]: fixme
.map(Optional::get)
.map(Mail::getId)
.orElseThrow();
sending.send(
@ -407,6 +410,8 @@ public class InitSettingFlow implements PersonUnitConfiguration {
final String personId = mail.getFromPersonId();
final String messageId = Attachments.findFirstButtonClick(mail.getAttachments())
.map(ButtonClickAttachment::getMessage)
//TODO [21.08.2024|uPagge]: fixme
.map(Optional::get)
.map(Message::getId)
.orElseThrow();
sending.send(