Compare commits
No commits in common. "develop" and "docs-deploy" have entirely different histories.
develop
...
docs-deplo
212
.drone.yml
212
.drone.yml
@ -1,206 +1,40 @@
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: develop build
|
||||
|
||||
image_pull_secrets:
|
||||
- DOCKER_AUTH
|
||||
name: deploy-develop-docs-site
|
||||
|
||||
trigger:
|
||||
branch:
|
||||
- develop
|
||||
|
||||
services:
|
||||
- name: docker
|
||||
# https://hub.docker.com/r/library/docker
|
||||
image: hub.docker.struchkov.dev/docker:27.1.2-dind-alpine3.20
|
||||
privileged: true
|
||||
volumes:
|
||||
- name: dockersock
|
||||
path: /var/run
|
||||
|
||||
volumes:
|
||||
- name: m2
|
||||
host:
|
||||
path: /drone/volume/m2
|
||||
- name: dockersock
|
||||
temp: {}
|
||||
- docs-deploy
|
||||
|
||||
steps:
|
||||
- name: create jar
|
||||
# https://hub.docker.com/_/maven
|
||||
image: hub.docker.struchkov.dev/maven:3.9-eclipse-temurin-22-alpine
|
||||
volumes:
|
||||
- name: m2
|
||||
path: /root/.m2/repository
|
||||
commands:
|
||||
- mvn -U clean package
|
||||
|
||||
- name: docker publish develop
|
||||
image: docker.struchkov.dev/docker-buildx:latest
|
||||
- name: build site
|
||||
image: git.struchkov.dev/upagge/mkdocs-material-insiders:latest
|
||||
environment:
|
||||
DOCKER_REGISTRY_TOKEN:
|
||||
from_secret: DOCKER_REGISTRY_TOKEN
|
||||
DOCKER_REGISTRY_USER:
|
||||
from_secret: DOCKER_REGISTRY_USER
|
||||
volumes:
|
||||
- name: dockersock
|
||||
path: /var/run
|
||||
SSH_DEPLOY_KEY:
|
||||
from_secret: SSH_DEPLOY_KEY
|
||||
SSH_DEPLOY_HOST:
|
||||
from_secret: SSH_DEPLOY_HOST
|
||||
SSH_DEPLOY_PORT:
|
||||
from_secret: SSH_DEPLOY_PORT
|
||||
SSH_DEPLOY_PATH:
|
||||
from_secret: SSH_DEPLOY_PATH
|
||||
SSH_DEPLOY_USER:
|
||||
from_secret: SSH_DEPLOY_USER
|
||||
commands:
|
||||
- echo "$DOCKER_REGISTRY_TOKEN" | docker login docker.struchkov.dev --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.struchkov.dev/gitlab-notify:develop" .
|
||||
|
||||
---
|
||||
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: release build
|
||||
- eval $(ssh-agent -s)
|
||||
- mkdir -p ~/.ssh
|
||||
- echo "$SSH_DEPLOY_KEY" >> ~/.ssh/id_rsa
|
||||
- chmod 700 ~/.ssh
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- ssh-keyscan -p $SSH_DEPLOY_PORT $SSH_DEPLOY_HOST >> ~/.ssh/known_hosts
|
||||
- chmod 644 ~/.ssh/known_hosts
|
||||
- scp -r -P $SSH_DEPLOY_PORT ./gitlab-notification $SSH_DEPLOY_USER@$SSH_DEPLOY_HOST:$SSH_DEPLOY_PATH
|
||||
|
||||
image_pull_secrets:
|
||||
- DOCKER_AUTH
|
||||
|
||||
trigger:
|
||||
ref:
|
||||
- refs/tags/v.*.*.*
|
||||
|
||||
services:
|
||||
- name: docker
|
||||
# https://hub.docker.com/r/library/docker
|
||||
image: hub.docker.struchkov.dev/docker:27.1.2-dind-alpine3.20
|
||||
privileged: true
|
||||
volumes:
|
||||
- name: dockersock
|
||||
path: /var/run
|
||||
|
||||
volumes:
|
||||
- name: m2
|
||||
host:
|
||||
path: /drone/volume/m2
|
||||
- name: dockersock
|
||||
temp: {}
|
||||
|
||||
steps:
|
||||
- name: create jar
|
||||
image: hub.docker.struchkov.dev/maven:3.9-eclipse-temurin-22-alpine
|
||||
volumes:
|
||||
- name: m2
|
||||
path: /root/.m2/repository
|
||||
commands:
|
||||
- mvn -U clean package
|
||||
|
||||
- name: docker publish release
|
||||
image: docker.struchkov.dev/docker-buildx:latest
|
||||
volumes:
|
||||
- name: dockersock
|
||||
path: /var/run
|
||||
environment:
|
||||
DOCKER_REGISTRY_TOKEN:
|
||||
from_secret: DOCKER_REGISTRY_TOKEN
|
||||
DOCKER_REGISTRY_USER:
|
||||
from_secret: DOCKER_REGISTRY_USER
|
||||
commands:
|
||||
- echo "$DOCKER_REGISTRY_TOKEN" | docker login docker.struchkov.dev --username $DOCKER_REGISTRY_USER --password-stdin
|
||||
- docker buildx create --use
|
||||
- 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
|
||||
#
|
||||
#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: b0704e1ed6c75469f2197afa7de1fb6f4a96765bb00f766be8a3da6fc4a87267
|
||||
hmac: e69cfd9c4c2c1a5c23907bc68bbe1cb2663194be5dd054492977f02f58e612d6
|
||||
|
||||
...
|
||||
|
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -1 +0,0 @@
|
||||
*.mp4 filter=lfs diff=lfs merge=lfs -text
|
1
.github/FUNDING.yml
vendored
1
.github/FUNDING.yml
vendored
@ -1 +0,0 @@
|
||||
custom: ["https://docs.struchkov.dev/gitlab-notification/ru/latest/support-development/"]
|
110
.gitignore
vendored
110
.gitignore
vendored
@ -1,38 +1,78 @@
|
||||
HELP.md
|
||||
*.class
|
||||
*.log
|
||||
*.ctxt
|
||||
.mtj.tmp/
|
||||
*.jar
|
||||
*.war
|
||||
*.nar
|
||||
*.ear
|
||||
*.zip
|
||||
*.tar.gz
|
||||
*.rar
|
||||
hs_err_pid*
|
||||
replay_pid*
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**
|
||||
!**/src/test/**
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
pom.xml.tag
|
||||
pom.xml.releaseBackup
|
||||
pom.xml.versionsBackup
|
||||
pom.xml.next
|
||||
release.properties
|
||||
dependency-reduced-pom.xml
|
||||
buildNumber.properties
|
||||
.mvn/timing.properties
|
||||
.mvn/wrapper/maven-wrapper.jar
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
.classpath
|
||||
.idea/
|
||||
cmake-build-*/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
/.mvn/wrapper/
|
||||
/mvnw
|
||||
/mvnw.cmd
|
||||
/documentation/site/
|
||||
/documentation/.cache/
|
||||
/documentation/ru/site/
|
||||
/documentation/ru/.cache/
|
||||
out/
|
||||
.idea_modules/
|
||||
atlassian-ide-plugin.xml
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
*~
|
||||
.fuse_hidden*
|
||||
.directory
|
||||
.Trash-*
|
||||
.nfs*
|
||||
.gradle
|
||||
**/build/
|
||||
!src/**/build/
|
||||
gradle-app.setting
|
||||
!gradle-wrapper.jar
|
||||
!gradle-wrapper.properties
|
||||
.gradletasknamecache
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
*.stackdump
|
||||
[Dd]esktop.ini
|
||||
$RECYCLE.BIN/
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
*.lnk
|
||||
.DS_Store
|
||||
.AppleDouble
|
||||
.LSOverride
|
||||
Icon
|
||||
._*
|
||||
.DocumentRevisions-V100
|
||||
.fseventsd
|
||||
.Spotlight-V100
|
||||
.TemporaryItems
|
||||
.Trashes
|
||||
.VolumeIcon.icns
|
||||
.com.apple.timemachine.donotpresent
|
||||
.AppleDB
|
||||
.AppleDesktop
|
||||
Network Trash Folder
|
||||
Temporary Items
|
||||
.apdisk
|
||||
/documentation/
|
||||
|
33
Dockerfile
33
Dockerfile
@ -1,33 +0,0 @@
|
||||
FROM eclipse-temurin:17 AS app-build
|
||||
ENV RELEASE=17
|
||||
|
||||
WORKDIR /opt/build
|
||||
COPY ./gitlab-app/target/gitlab-notification.jar ./application.jar
|
||||
|
||||
RUN java -Djarmode=layertools -jar application.jar extract
|
||||
RUN $JAVA_HOME/bin/jlink \
|
||||
--add-modules `jdeps --ignore-missing-deps -q -recursive --multi-release ${RELEASE} --print-module-deps -cp 'dependencies/BOOT-INF/lib/*' application.jar`,jdk.crypto.cryptoki \
|
||||
--strip-java-debug-attributes \
|
||||
--no-man-pages \
|
||||
--no-header-files \
|
||||
--compress=2 \
|
||||
--output jdk
|
||||
|
||||
FROM debian:buster-slim
|
||||
|
||||
ARG BUILD_PATH=/opt/build
|
||||
ENV JAVA_HOME=/opt/jdk
|
||||
ENV PATH "${JAVA_HOME}/bin:${PATH}"
|
||||
|
||||
RUN apt update && groupadd --gid 1000 spring-app \
|
||||
&& useradd --uid 1000 --gid spring-app --shell /bin/bash --create-home spring-app
|
||||
|
||||
USER spring-app:spring-app
|
||||
WORKDIR /opt/workspace
|
||||
|
||||
COPY --from=app-build $BUILD_PATH/jdk $JAVA_HOME
|
||||
COPY --from=app-build $BUILD_PATH/spring-boot-loader/ ./
|
||||
COPY --from=app-build $BUILD_PATH/dependencies/ ./
|
||||
COPY --from=app-build $BUILD_PATH/application/ ./
|
||||
|
||||
ENTRYPOINT ["java", "-Dfile.encoding=UTF8", "-Dconsole.encoding=UTF8", "org.springframework.boot.loader.JarLauncher"]
|
@ -1,34 +0,0 @@
|
||||
FROM eclipse-temurin:17 AS app-build
|
||||
ENV RELEASE=17
|
||||
|
||||
WORKDIR /opt/build
|
||||
COPY ./gitlab-app/target/gitlab-notification.jar ./application.jar
|
||||
|
||||
RUN java -Djarmode=layertools -jar application.jar extract
|
||||
RUN $JAVA_HOME/bin/jlink \
|
||||
--add-modules `jdeps --ignore-missing-deps -q -recursive --multi-release ${RELEASE} --print-module-deps -cp 'dependencies/BOOT-INF/lib/*':'snapshot-dependencies/BOOT-INF/lib/*' application.jar`,jdk.crypto.cryptoki \
|
||||
--strip-java-debug-attributes \
|
||||
--no-man-pages \
|
||||
--no-header-files \
|
||||
--compress=2 \
|
||||
--output jdk
|
||||
|
||||
FROM debian:buster-slim
|
||||
|
||||
ARG BUILD_PATH=/opt/build
|
||||
ENV JAVA_HOME=/opt/jdk
|
||||
ENV PATH "${JAVA_HOME}/bin:${PATH}"
|
||||
|
||||
RUN apt update && groupadd --gid 1000 spring-app \
|
||||
&& useradd --uid 1000 --gid spring-app --shell /bin/bash --create-home spring-app
|
||||
|
||||
USER spring-app:spring-app
|
||||
WORKDIR /opt/workspace
|
||||
|
||||
COPY --from=app-build $BUILD_PATH/jdk $JAVA_HOME
|
||||
COPY --from=app-build $BUILD_PATH/spring-boot-loader/ ./
|
||||
COPY --from=app-build $BUILD_PATH/dependencies/ ./
|
||||
COPY --from=app-build $BUILD_PATH/snapshot-dependencies/ ./
|
||||
COPY --from=app-build $BUILD_PATH/application/ ./
|
||||
|
||||
ENTRYPOINT ["java", "-Dfile.encoding=UTF8", "-Dconsole.encoding=UTF8", "org.springframework.boot.loader.JarLauncher"]
|
201
LICENSE
201
LICENSE
@ -1,201 +0,0 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright 2020 uPagge
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
23
README.md
23
README.md
@ -1,23 +0,0 @@
|
||||
# Уведомления GitLab в Telegram
|
||||
|
||||
> Документация по проекту, с описанием возможностей: https://docs.struchkov.dev/gitlab-notification
|
||||
>
|
||||
> Канал в Telegram, в который публикуется информация о разработке: https://t.me/gitlab_notification
|
||||
|
||||
Запустите своего личного GitLab бота и получайте персональные уведомления из GitLab прямо на свой аккаунт в Telegram! Это не облачное решение, бот запускается на вашей машине или вашем сервере.
|
||||
|
||||
Вы больше никогда не пропустите важное уведомление. Будь то новый запрос на слияние или возникновение конфликта. Больше не нужно заходить в GitLab, чтобы проверить статус сборки - с нашим приложением вы сможете оставаться в курсе дел, где бы вы ни находились.
|
||||
|
||||
Бота легко настроить и использовать, а быстрые действия призваны оптимизировать ваш рабочий процесс. Не ждите больше - запустите своего персонального Telegram бота, и получайте персональные уведомления о событиях в GitLab.
|
||||
|
||||
## Основные возможности
|
||||
|
||||
1. Уведомление о новых Merge Request.
|
||||
2. Уведомление о возникновении конфликта в MergeRequest.
|
||||
3. Уведомление о результате сборки.
|
||||
4. Уведомление в тредах.
|
||||
5. И многое, многое другое
|
||||
|
||||
## Как запустить?
|
||||
|
||||
Я серьезно, все подробно описано в [соответствующем разделе документации.](https://docs.struchkov.dev/gitlab-notification/ru/latest/getting-started/configuration/)
|
@ -1,44 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>dev.struchkov.bot.gitlab</groupId>
|
||||
<artifactId>gitlab-bot</artifactId>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>bot-context</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>dev.struchkov.haiti.utils</groupId>
|
||||
<artifactId>haiti-utils-field-constants</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.struchkov.haiti</groupId>
|
||||
<artifactId>haiti-utils</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.struchkov.haiti.filter</groupId>
|
||||
<artifactId>haiti-filter-criteria</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>jakarta.persistence</groupId>
|
||||
<artifactId>jakarta.persistence-api</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -1,19 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class Answer {
|
||||
|
||||
private final String authorName;
|
||||
private final String message;
|
||||
|
||||
public static Answer of(@NonNull String name, @NonNull String message) {
|
||||
return new Answer(name, message);
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain;
|
||||
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class ExistContainer<Entity, Key> {
|
||||
|
||||
protected final List<Entity> container;
|
||||
protected final boolean allFound;
|
||||
protected final Set<Key> idNoFound;
|
||||
|
||||
protected ExistContainer(List<Entity> container, boolean allFound, Set<Key> idNoFound) {
|
||||
this.container = container;
|
||||
this.allFound = allFound;
|
||||
this.idNoFound = idNoFound;
|
||||
}
|
||||
|
||||
public static <T, K> ExistContainer<T, K> allFind(@NonNull List<T> container) {
|
||||
return new ExistContainer<>(container, true, Collections.emptySet());
|
||||
}
|
||||
|
||||
public static <T, K> ExistContainer<T, K> notAllFind(@NonNull List<T> container, @NonNull Set<K> idNoFound) {
|
||||
return new ExistContainer<>(container, false, idNoFound);
|
||||
}
|
||||
|
||||
public List<Entity> getContainer() {
|
||||
return container;
|
||||
}
|
||||
|
||||
public boolean isAllFound() {
|
||||
return allFound;
|
||||
}
|
||||
|
||||
public Set<Key> getIdNoFound() {
|
||||
return idNoFound;
|
||||
}
|
||||
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public class IdAndStatusPr {
|
||||
|
||||
private Long id;
|
||||
private Long twoId;
|
||||
private Long projectId;
|
||||
private MergeRequestState status;
|
||||
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author upagge 14.01.2021
|
||||
*/
|
||||
public enum MergeRequestState {
|
||||
|
||||
OPENED, CLOSED, LOCKED, MERGED
|
||||
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public class MessageSend {
|
||||
|
||||
@EqualsAndHashCode.Include
|
||||
private Long id;
|
||||
private Long telegramId;
|
||||
private String message;
|
||||
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author upagge 15.01.2021
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class PersonInformation {
|
||||
|
||||
private String username;
|
||||
private String name;
|
||||
private Long id;
|
||||
private String telegramId;
|
||||
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
/**
|
||||
* @author upagge 17.01.2021
|
||||
*/
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum PipelineStatus {
|
||||
|
||||
CREATED("\uD83C\uDD95"),
|
||||
WAITING_FOR_RESOURCE("\uD83D\uDCA2"),
|
||||
PREPARING("♿️"),
|
||||
PENDING("⚠️"),
|
||||
RUNNING("\uD83D\uDD04"),
|
||||
SUCCESS("✅"),
|
||||
FAILED("❌"),
|
||||
CANCELED("\uD83D\uDEAB"),
|
||||
SKIPPED("\uD83D\uDD18"),
|
||||
MANUAL("\uD83D\uDD79"),
|
||||
SCHEDULED("\uD83D\uDD52"),
|
||||
NEW("\uD83C\uDD95");
|
||||
|
||||
private final String icon;
|
||||
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
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,47 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.changed;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum AssigneeChanged {
|
||||
|
||||
BECOME(true),
|
||||
DELETED(true),
|
||||
NOT_AFFECT_USER(true),
|
||||
NOT_CHANGED(false);
|
||||
|
||||
private final boolean changed;
|
||||
|
||||
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 (oldAssignee.isPresent() && newAssignee.isEmpty() && gitlabUserId.equals(oldAssignee.get().getId())) {
|
||||
return AssigneeChanged.DELETED;
|
||||
}
|
||||
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.get().getId())) {
|
||||
return AssigneeChanged.BECOME;
|
||||
}
|
||||
return AssigneeChanged.NOT_AFFECT_USER;
|
||||
}
|
||||
return AssigneeChanged.NOT_CHANGED;
|
||||
}
|
||||
|
||||
public boolean getNewStatus(boolean oldStatus) {
|
||||
return switch (this) {
|
||||
case BECOME -> true;
|
||||
case DELETED -> false;
|
||||
case NOT_CHANGED, NOT_AFFECT_USER -> oldStatus;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.changed;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum ReviewerChanged {
|
||||
|
||||
BECOME(true),
|
||||
DELETED(true),
|
||||
NOT_AFFECT_USER(true),
|
||||
NOT_CHANGED(false);
|
||||
|
||||
private final boolean changed;
|
||||
|
||||
public static ReviewerChanged valueOf(Long gitlabUserId, List<Person> oldReviewers, List<Person> newReviewers) {
|
||||
final Map<Long, Person> oldMap = oldReviewers.stream().collect(Collectors.toMap(Person::getId, p -> p));
|
||||
final Map<Long, Person> newMap = newReviewers.stream().collect(Collectors.toMap(Person::getId, p -> p));
|
||||
|
||||
if (!oldMap.keySet().equals(newMap.keySet())) {
|
||||
if (oldMap.containsKey(gitlabUserId) && !newMap.containsKey(gitlabUserId)) {
|
||||
return ReviewerChanged.DELETED;
|
||||
}
|
||||
if (!oldMap.containsKey(gitlabUserId) && newMap.containsKey(gitlabUserId)) {
|
||||
return ReviewerChanged.BECOME;
|
||||
}
|
||||
return ReviewerChanged.NOT_AFFECT_USER;
|
||||
}
|
||||
return ReviewerChanged.NOT_CHANGED;
|
||||
}
|
||||
|
||||
public boolean getNewStatus(boolean oldStatus) {
|
||||
return switch (this) {
|
||||
case BECOME -> true;
|
||||
case DELETED -> false;
|
||||
case NOT_AFFECT_USER, NOT_CHANGED -> oldStatus;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.entity;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Основные настройки приложения.
|
||||
*
|
||||
* @author upagge 16.01.2021
|
||||
*/
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@Table(name = "app_setting")
|
||||
public class AppSetting {
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "service_key")
|
||||
private UUID serviceKey = UUID.randomUUID();
|
||||
|
||||
@Column(name = "first_start")
|
||||
private boolean firstStart;
|
||||
|
||||
@Column(name = "enable_notify")
|
||||
private boolean enableNotify;
|
||||
|
||||
@Column(name = "project_owner_scan")
|
||||
private boolean projectOwnerScan;
|
||||
|
||||
@Column(name = "project_private_scan")
|
||||
private boolean projectPrivateScan;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "discussion_notify_level")
|
||||
private DiscussionLevel discussionNotifyLevel;
|
||||
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.entity;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||
|
||||
/**
|
||||
* @author upagge 11.02.2021
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@NoArgsConstructor
|
||||
@Builder(toBuilder = true)
|
||||
@Table(name = "discussion")
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public class Discussion {
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private String id;
|
||||
|
||||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
|
||||
@JoinColumn(name = "responsible_id")
|
||||
private Person responsible;
|
||||
|
||||
@Column(name = "resolved")
|
||||
private Boolean resolved;
|
||||
|
||||
@Column(name = "notification")
|
||||
private boolean notification;
|
||||
|
||||
@ManyToOne(optional = false, cascade = CascadeType.REMOVE)
|
||||
@JoinTable(
|
||||
name = "discussion_merge_request",
|
||||
joinColumns = @JoinColumn(name = "discussion_id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "merge_request_id")
|
||||
)
|
||||
private MergeRequestForDiscussion mergeRequest;
|
||||
|
||||
@OneToMany(
|
||||
mappedBy = "discussion",
|
||||
fetch = FetchType.EAGER,
|
||||
cascade = {
|
||||
CascadeType.PERSIST,
|
||||
CascadeType.MERGE,
|
||||
CascadeType.REFRESH
|
||||
}
|
||||
)
|
||||
private List<Note> notes;
|
||||
|
||||
public void setNotes(List<Note> notes) {
|
||||
notes.forEach(note -> note.setDiscussion(this));
|
||||
this.notes = notes;
|
||||
}
|
||||
|
||||
public int getNoteSize() {
|
||||
if (checkNotEmpty(notes)) {
|
||||
return notes.size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
public Optional<Note> getNoteByNumber(int number) {
|
||||
if (checkNotEmpty(notes) && number < notes.size()) {
|
||||
return Optional.of(notes.get(number));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Note getFirstNote() {
|
||||
return this.notes.get(0);
|
||||
}
|
||||
|
||||
public Optional<Note> getLastNote() {
|
||||
if (this.notes.size() > 1) {
|
||||
return Optional.ofNullable(this.notes.get(this.notes.size() - 1));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<Note> getPrevLastNote() {
|
||||
final int size = notes.size();
|
||||
if (size > 2) {
|
||||
return Optional.of(notes.get(size - 2));
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
public Optional<Note> getLastNoteByUserId(Long personId) {
|
||||
for (int i = notes.size() - 1; i >= 0; i--) {
|
||||
final Note note = notes.get(i);
|
||||
if (note.getAuthor().getId().equals(personId)) {
|
||||
return Optional.of(note);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
}
|
@ -1,143 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.entity;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import dev.struchkov.haiti.utils.fieldconstants.domain.Mode;
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.CollectionTable;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.ElementCollection;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.FetchType;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.JoinTable;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.OneToMany;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Сущность ПуллРеквест.
|
||||
*
|
||||
* @author upagge [31.01.2020]
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@ToString(onlyExplicitlyIncluded = true)
|
||||
@NoArgsConstructor
|
||||
@Builder(toBuilder = true)
|
||||
@Table(name = "merge_request")
|
||||
@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE})
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class MergeRequest {
|
||||
|
||||
@Id
|
||||
@ToString.Include
|
||||
@Column(name = "id")
|
||||
@EqualsAndHashCode.Include
|
||||
private Long id;
|
||||
|
||||
@Column(name = "two_id")
|
||||
private Long twoId;
|
||||
|
||||
@Column(name = "project_id")
|
||||
private Long projectId;
|
||||
|
||||
@ToString.Include
|
||||
@Column(name = "title")
|
||||
private String title;
|
||||
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
|
||||
@Column(name = "milestone")
|
||||
private String milestone;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "state")
|
||||
private MergeRequestState state;
|
||||
|
||||
@Column(name = "created_date")
|
||||
private LocalDateTime createdDate;
|
||||
|
||||
@Column(name = "updated_date")
|
||||
private LocalDateTime updatedDate;
|
||||
|
||||
@Column(name = "web_url")
|
||||
private String webUrl;
|
||||
|
||||
@Column(name = "conflict")
|
||||
private boolean conflict;
|
||||
|
||||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
@JoinColumn(name = "author_id")
|
||||
private Person author;
|
||||
|
||||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
@JoinColumn(name = "assignee_id")
|
||||
private Person assignee;
|
||||
|
||||
@OneToMany(
|
||||
fetch = FetchType.LAZY,
|
||||
cascade = {CascadeType.PERSIST, CascadeType.MERGE}
|
||||
)
|
||||
@JoinTable(
|
||||
name = "merge_request_reviewer",
|
||||
joinColumns = @JoinColumn(name = "merge_request_id", referencedColumnName = "id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "person_id", referencedColumnName = "id")
|
||||
)
|
||||
private List<Person> reviewers = new ArrayList<>();
|
||||
|
||||
@Column(name = "target_branch")
|
||||
private String targetBranch;
|
||||
|
||||
@Column(name = "source_branch")
|
||||
private String sourceBranch;
|
||||
|
||||
@Column(name = "notification")
|
||||
private boolean notification;
|
||||
|
||||
@Column(name = "is_assignee")
|
||||
private boolean userAssignee;
|
||||
|
||||
@Column(name = "is_reviewer")
|
||||
private boolean userReviewer;
|
||||
|
||||
@OneToMany(
|
||||
fetch = FetchType.LAZY,
|
||||
cascade = {CascadeType.PERSIST, CascadeType.MERGE}
|
||||
)
|
||||
@JoinTable(
|
||||
name = "merge_request_approvals",
|
||||
joinColumns = @JoinColumn(name = "merge_request_id", referencedColumnName = "id"),
|
||||
inverseJoinColumns = @JoinColumn(name = "person_id", referencedColumnName = "id")
|
||||
)
|
||||
private List<Person> approvals = new ArrayList<>();
|
||||
|
||||
@ElementCollection
|
||||
@CollectionTable(name = "merge_request_label", joinColumns = @JoinColumn(name = "merge_request_id"))
|
||||
@Column(name = "label")
|
||||
private Set<String> labels = new HashSet<>();
|
||||
|
||||
@Column(name = "date_last_commit")
|
||||
private LocalDateTime dateLastCommit;
|
||||
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.entity;
|
||||
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author upagge 12.09.2020
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "merge_request")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public class MergeRequestForDiscussion {
|
||||
|
||||
/**
|
||||
* Идентификатор
|
||||
*/
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@EqualsAndHashCode.Include
|
||||
private Long id;
|
||||
|
||||
@Column(name = "two_id")
|
||||
private Long twoId;
|
||||
|
||||
@Column(name = "project_id")
|
||||
private Long projectId;
|
||||
|
||||
@Column(name = "title")
|
||||
private String title;
|
||||
|
||||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
|
||||
@JoinColumn(name = "author_id")
|
||||
private Person author;
|
||||
|
||||
@Column(name = "web_url")
|
||||
private String webUrl;
|
||||
|
||||
@Column(name = "notification")
|
||||
private boolean notification;
|
||||
|
||||
}
|
@ -1,72 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.entity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static jakarta.persistence.CascadeType.MERGE;
|
||||
import static jakarta.persistence.CascadeType.PERSIST;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "note")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public class Note {
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@EqualsAndHashCode.Include
|
||||
private Long id;
|
||||
|
||||
@Column(name = "type")
|
||||
private String type;
|
||||
|
||||
@Column(name = "body")
|
||||
private String body;
|
||||
|
||||
@Column(name = "created_date")
|
||||
private LocalDateTime created;
|
||||
|
||||
@Column(name = "updated_date")
|
||||
private LocalDateTime updated;
|
||||
|
||||
@ManyToOne(cascade = {PERSIST, MERGE})
|
||||
@JoinColumn(name = "author_id")
|
||||
private Person author;
|
||||
|
||||
@Column(name = "noteable_id")
|
||||
private Long noteableId;
|
||||
|
||||
@Column(name = "noteable_type")
|
||||
private String noteableType;
|
||||
|
||||
@Column(name = "noteable_iid")
|
||||
private Long noteableIid;
|
||||
|
||||
@Column(name = "web_url")
|
||||
private String webUrl;
|
||||
|
||||
@Column(name = "resolvable")
|
||||
private boolean resolvable;
|
||||
|
||||
@Column(name = "resolved")
|
||||
private Boolean resolved;
|
||||
|
||||
@ManyToOne(cascade = {PERSIST, MERGE})
|
||||
@JoinColumn(name = "resolved_id")
|
||||
private Person resolvedBy;
|
||||
|
||||
@ManyToOne(optional = false)
|
||||
@JoinColumn(name = "discussion_id")
|
||||
private Discussion discussion;
|
||||
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.entity;
|
||||
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import dev.struchkov.haiti.utils.fieldconstants.domain.Mode;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
/**
|
||||
* @author upagge 14.01.2021
|
||||
*/
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@Table(name = "person")
|
||||
@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE})
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public class Person {
|
||||
|
||||
@Id
|
||||
@EqualsAndHashCode.Include
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "username")
|
||||
private String userName;
|
||||
|
||||
@Column(name = "web_url")
|
||||
private String webUrl;
|
||||
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.entity;
|
||||
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import dev.struchkov.haiti.utils.fieldconstants.domain.Mode;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.ToString;
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@ToString
|
||||
@Table(name = "person_telegram")
|
||||
@FieldNames(mode = {Mode.TABLE, Mode.SIMPLE})
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public class PersonTelegram {
|
||||
|
||||
@Id
|
||||
@EqualsAndHashCode.Include
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "telegram_username")
|
||||
private String telegramUserName;
|
||||
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.entity;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import jakarta.persistence.CascadeType;
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.EnumType;
|
||||
import jakarta.persistence.Enumerated;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.JoinColumn;
|
||||
import jakarta.persistence.ManyToOne;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author upagge 17.01.2021
|
||||
*/
|
||||
|
||||
@Entity
|
||||
@Getter
|
||||
@Setter
|
||||
@FieldNames
|
||||
@NoArgsConstructor
|
||||
@Table(name = "pipeline")
|
||||
@Builder(toBuilder = true)
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class Pipeline {
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
@EqualsAndHashCode.Include
|
||||
private Long id;
|
||||
|
||||
@Column(name = "created_date")
|
||||
private LocalDateTime created;
|
||||
|
||||
@Column(name = "updated_date")
|
||||
private LocalDateTime updated;
|
||||
|
||||
@Enumerated(EnumType.STRING)
|
||||
@Column(name = "status")
|
||||
private PipelineStatus status;
|
||||
|
||||
@Column(name = "ref")
|
||||
private String ref;
|
||||
|
||||
@Column(name = "web_url")
|
||||
private String webUrl;
|
||||
|
||||
@Column(name = "project_id")
|
||||
private Long projectId;
|
||||
|
||||
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
|
||||
@JoinColumn(name = "person_id")
|
||||
private Person person;
|
||||
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.entity;
|
||||
|
||||
import jakarta.persistence.Column;
|
||||
import jakarta.persistence.Entity;
|
||||
import jakarta.persistence.Id;
|
||||
import jakarta.persistence.Table;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* @author upagge 14.01.2021
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Entity
|
||||
@Table(name = "project")
|
||||
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||
public class Project {
|
||||
|
||||
@Id
|
||||
@Column(name = "id")
|
||||
private Long id;
|
||||
|
||||
@Column(name = "name")
|
||||
private String name;
|
||||
|
||||
@Column(name = "description")
|
||||
private String description;
|
||||
|
||||
@Column(name = "created_date")
|
||||
private LocalDateTime createdDate;
|
||||
|
||||
@Column(name = "creator_id")
|
||||
private Long creatorId;
|
||||
|
||||
@Column(name = "web_url")
|
||||
private String webUrl;
|
||||
|
||||
@Column(name = "ssh_url_to_repo")
|
||||
private String sshUrlToRepo;
|
||||
|
||||
@Column(name = "http_url_to_repo")
|
||||
private String httpUrlToRepo;
|
||||
|
||||
@Column(name = "notification")
|
||||
private boolean notification;
|
||||
|
||||
@Column(name = "processing")
|
||||
private boolean processing;
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor(staticName = "newDiscussion")
|
||||
public class NewDiscussionEvent {
|
||||
|
||||
private Discussion discussion;
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor(staticName = "newMergeRequest")
|
||||
public class NewMergeRequestEvent {
|
||||
|
||||
private MergeRequest mergeRequest;
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor(staticName = "newPipeline")
|
||||
public class NewPipelineEvent {
|
||||
|
||||
private Pipeline pipeline;
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor(staticName = "newProject")
|
||||
public class NewProjectEvent {
|
||||
|
||||
private Project project;
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor(staticName = "updateDiscussion")
|
||||
public class UpdateDiscussionEvent {
|
||||
|
||||
private Discussion oldDiscussion;
|
||||
private Discussion newDiscussion;
|
||||
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
||||
|
||||
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;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor(staticName = "updateMergeRequest")
|
||||
public class UpdateMergeRequestEvent {
|
||||
|
||||
private MergeRequest oldMergeRequest;
|
||||
private MergeRequest newMergeRequest;
|
||||
|
||||
private AssigneeChanged assigneeChanged;
|
||||
private ReviewerChanged reviewerChanged;
|
||||
private Optional<ApprovalChanged> optApprovalChanged;
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.event;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor(staticName = "updatePipeline")
|
||||
public class UpdatePipelineEvent {
|
||||
|
||||
private Pipeline oldPipeline;
|
||||
private Pipeline newPipeline;
|
||||
|
||||
}
|
@ -1,23 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.filter;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class MergeRequestFilter {
|
||||
|
||||
private Long assignee;
|
||||
private Set<MergeRequestState> states;
|
||||
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.filter;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* Объект фильтра для {@link Pipeline}.
|
||||
*
|
||||
* @author upagge 08.02.2021
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class PipelineFilter {
|
||||
|
||||
private LocalDateTime lessThanCreatedDate;
|
||||
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify;
|
||||
|
||||
public interface GroupNotify extends Notify {
|
||||
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify;
|
||||
|
||||
public interface Notify {
|
||||
|
||||
String getType();
|
||||
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify;
|
||||
|
||||
public interface PersonalNotify extends Notify{
|
||||
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.comment;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@FieldNames
|
||||
public final class NewCommentPersonalNotify implements PersonalNotify {
|
||||
|
||||
public static final String TYPE = "NewCommentNotify";
|
||||
|
||||
private final String threadId;
|
||||
private final String mergeRequestName;
|
||||
private final String url;
|
||||
private final String discussionMessage;
|
||||
private final String discussionAuthor;
|
||||
private final String previousMessage;
|
||||
private final String previousAuthor;
|
||||
private final String authorName;
|
||||
private final String message;
|
||||
private final int numberNotes;
|
||||
|
||||
@Builder
|
||||
public NewCommentPersonalNotify(
|
||||
String threadId,
|
||||
String mergeRequestName,
|
||||
String url,
|
||||
String discussionMessage,
|
||||
String discussionAuthor,
|
||||
String previousMessage,
|
||||
String previousAuthor,
|
||||
String authorName,
|
||||
String message,
|
||||
int numberNotes
|
||||
) {
|
||||
this.threadId = threadId;
|
||||
this.mergeRequestName = mergeRequestName;
|
||||
this.url = url;
|
||||
this.discussionMessage = discussionMessage;
|
||||
this.discussionAuthor = discussionAuthor;
|
||||
this.previousMessage = previousMessage;
|
||||
this.previousAuthor = previousAuthor;
|
||||
this.authorName = authorName;
|
||||
this.message = message;
|
||||
this.numberNotes = numberNotes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -1,38 +0,0 @@
|
||||
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;
|
||||
|
||||
@Getter
|
||||
@FieldNames
|
||||
public class ConflictMrGroupNotify implements GroupNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
protected final String sourceBranch;
|
||||
protected final String projectName;
|
||||
protected final String title;
|
||||
protected final String url;
|
||||
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;
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
this.milestone = milestone;
|
||||
this.authorTelegramUsername = authorTelegramUsername;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.group.mr;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.GroupNotify;
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.notify.group.mr.NewMergeRequestGroupPersonalNotifyFields.CLASS_NAME;
|
||||
|
||||
@Getter
|
||||
@FieldNames
|
||||
public class NewMergeRequestGroupNotify implements GroupNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
protected final Long mrId;
|
||||
protected final String projectName;
|
||||
protected final String title;
|
||||
protected final String url;
|
||||
protected final String milestone;
|
||||
protected final String description;
|
||||
protected final String author;
|
||||
protected final String targetBranch;
|
||||
protected final String sourceBranch;
|
||||
protected final Map<Long, String> reviewerTelegramUsernames;
|
||||
protected final Person assignee;
|
||||
|
||||
@Builder
|
||||
public NewMergeRequestGroupNotify(Long mrId, String projectName, String title, String url, String milestone, String description, String author, String targetBranch, String sourceBranch, Map<Long, String> reviewerTelegramUsernames, Person assignee) {
|
||||
this.mrId = mrId;
|
||||
this.projectName = projectName;
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
this.milestone = milestone;
|
||||
this.description = description;
|
||||
this.author = author;
|
||||
this.targetBranch = targetBranch;
|
||||
this.sourceBranch = sourceBranch;
|
||||
this.reviewerTelegramUsernames = reviewerTelegramUsernames;
|
||||
this.assignee = assignee;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.group.mr;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.GroupNotify;
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@FieldNames
|
||||
public class NoReviewerGroupNotify implements GroupNotify {
|
||||
|
||||
public static final String TYPE = "NoReviewersGroupNotify";
|
||||
|
||||
protected final String projectName;
|
||||
protected final String title;
|
||||
protected final String url;
|
||||
protected final String milestone;
|
||||
protected final String targetBranch;
|
||||
protected final String sourceBranch;
|
||||
protected final Person assignee;
|
||||
protected final String ownerTelegramUsername;
|
||||
|
||||
@Builder
|
||||
public NoReviewerGroupNotify(String projectName, String title, String url, String milestone, String targetBranch, String sourceBranch, Person assignee, String ownerTelegramUsername) {
|
||||
this.projectName = projectName;
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
this.milestone = milestone;
|
||||
this.targetBranch = targetBranch;
|
||||
this.sourceBranch = sourceBranch;
|
||||
this.assignee = assignee;
|
||||
this.ownerTelegramUsername = ownerTelegramUsername;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.group.pipeline;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||
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.pipeline.PipelineGroupNotifyFields.CLASS_NAME;
|
||||
|
||||
@Getter
|
||||
@FieldNames
|
||||
public class PipelineGroupNotify implements GroupNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
private final String projectName;
|
||||
private final String refName;
|
||||
private final PipelineStatus oldStatus;
|
||||
private final PipelineStatus newStatus;
|
||||
private final String webUrl;
|
||||
private final String ownerTelegramUsername;
|
||||
|
||||
@Builder
|
||||
public PipelineGroupNotify(String projectName, String refName, PipelineStatus oldStatus, PipelineStatus newStatus, String webUrl, String ownerTelegramUsername) {
|
||||
this.projectName = projectName;
|
||||
this.refName = refName;
|
||||
this.oldStatus = oldStatus;
|
||||
this.newStatus = newStatus;
|
||||
this.webUrl = webUrl;
|
||||
this.ownerTelegramUsername = ownerTelegramUsername;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.level;
|
||||
|
||||
public enum DiscussionLevel {
|
||||
|
||||
WITHOUT_NOTIFY, NOTIFY_WITHOUT_CONTEXT, NOTIFY_WITH_CONTEXT
|
||||
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
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.ApprovalChangedMrPersonalNotifyFields.CLASS_NAME;
|
||||
|
||||
|
||||
@Getter
|
||||
@FieldNames
|
||||
public class ApprovalChangedMrPersonalNotify extends MrPersonalNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
private final Set<Person> newApproval;
|
||||
private final Set<Person> dontApproval;
|
||||
|
||||
@Builder
|
||||
public ApprovalChangedMrPersonalNotify(
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.mergerequest;
|
||||
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ConflictMrPersonalNotifyFields.CLASS_NAME;
|
||||
|
||||
@Getter
|
||||
@FieldNames
|
||||
public class ConflictMrPersonalNotify extends MrPersonalNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
private final String sourceBranch;
|
||||
|
||||
@Builder
|
||||
private ConflictMrPersonalNotify(
|
||||
Long mrId,
|
||||
String name,
|
||||
String url,
|
||||
String projectKey,
|
||||
String sourceBranch,
|
||||
String milestone
|
||||
) {
|
||||
super(mrId, projectKey, name, url, milestone);
|
||||
this.sourceBranch = sourceBranch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.mergerequest;
|
||||
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ConflictResolveMrPersonalNotifyFields.CLASS_NAME;
|
||||
|
||||
@Getter
|
||||
@FieldNames
|
||||
public class ConflictResolveMrPersonalNotify extends MrPersonalNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
private final String sourceBranch;
|
||||
|
||||
@Builder
|
||||
private ConflictResolveMrPersonalNotify(
|
||||
Long mrId,
|
||||
String name,
|
||||
String url,
|
||||
String projectKey,
|
||||
String sourceBranch,
|
||||
String milestone
|
||||
) {
|
||||
super(mrId, projectKey, name, url, milestone);
|
||||
this.sourceBranch = sourceBranch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.mergerequest;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public abstract class MrPersonalNotify implements PersonalNotify {
|
||||
|
||||
protected final Long mrId;
|
||||
protected final String projectName;
|
||||
protected final String title;
|
||||
protected final String url;
|
||||
protected final String milestone;
|
||||
|
||||
protected MrPersonalNotify(
|
||||
Long mrId,
|
||||
String projectName,
|
||||
String title,
|
||||
String url,
|
||||
String milestone
|
||||
) {
|
||||
this.mrId = mrId;
|
||||
this.projectName = projectName;
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
this.milestone = milestone;
|
||||
}
|
||||
|
||||
}
|
@ -1,61 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.mergerequest;
|
||||
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Singular;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.NewMrForAssigneeFields.CLASS_NAME;
|
||||
|
||||
@Getter
|
||||
@FieldNames
|
||||
public class NewMrForAssignee extends NewMrPersonalNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
private final List<String> reviewers;
|
||||
private final String oldAssigneeName;
|
||||
private final String newAssigneeName;
|
||||
|
||||
@Builder
|
||||
private NewMrForAssignee(
|
||||
Long mrId,
|
||||
String title,
|
||||
String url,
|
||||
String description,
|
||||
String author,
|
||||
String projectName,
|
||||
String targetBranch,
|
||||
String sourceBranch,
|
||||
Set<String> labels,
|
||||
@Singular List<String> reviewers,
|
||||
String oldAssigneeName,
|
||||
String newAssigneeName,
|
||||
String milestone
|
||||
) {
|
||||
super(
|
||||
mrId,
|
||||
title,
|
||||
url,
|
||||
description,
|
||||
author,
|
||||
projectName,
|
||||
targetBranch,
|
||||
sourceBranch,
|
||||
labels,
|
||||
milestone
|
||||
);
|
||||
this.reviewers = reviewers;
|
||||
this.oldAssigneeName = oldAssigneeName;
|
||||
this.newAssigneeName = newAssigneeName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.mergerequest;
|
||||
|
||||
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.NewMrForReviewFields.CLASS_NAME;
|
||||
|
||||
@Getter
|
||||
@FieldNames
|
||||
public class NewMrForReview extends NewMrPersonalNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
private final String assignee;
|
||||
|
||||
@Builder
|
||||
private NewMrForReview(
|
||||
Long mrId,
|
||||
String title,
|
||||
String url,
|
||||
String description,
|
||||
String author,
|
||||
String projectName,
|
||||
String targetBranch,
|
||||
String sourceBranch,
|
||||
Set<String> labels,
|
||||
String assignee,
|
||||
String milestone
|
||||
) {
|
||||
super(
|
||||
mrId,
|
||||
title,
|
||||
url,
|
||||
description,
|
||||
author,
|
||||
projectName,
|
||||
targetBranch,
|
||||
sourceBranch,
|
||||
labels,
|
||||
milestone
|
||||
);
|
||||
this.assignee = assignee;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.mergerequest;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
@Getter
|
||||
public abstract class NewMrPersonalNotify extends MrPersonalNotify {
|
||||
|
||||
protected final String description;
|
||||
protected final String author;
|
||||
protected final String targetBranch;
|
||||
protected final String sourceBranch;
|
||||
protected final Set<String> labels;
|
||||
|
||||
protected NewMrPersonalNotify(
|
||||
Long mrId,
|
||||
String title,
|
||||
String url,
|
||||
String description,
|
||||
String author,
|
||||
String projectName,
|
||||
String targetBranch,
|
||||
String sourceBranch,
|
||||
Set<String> labels,
|
||||
String milestone
|
||||
) {
|
||||
super(mrId, projectName, title, url, milestone);
|
||||
this.description = description;
|
||||
this.author = author;
|
||||
this.targetBranch = targetBranch;
|
||||
this.sourceBranch = sourceBranch;
|
||||
this.labels = labels;
|
||||
}
|
||||
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.mergerequest;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.StatusMrPersonalNotifyFields.CLASS_NAME;
|
||||
|
||||
@Getter
|
||||
@FieldNames
|
||||
public class StatusMrPersonalNotify extends MrPersonalNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
private final MergeRequestState oldStatus;
|
||||
private final MergeRequestState newStatus;
|
||||
|
||||
@Builder
|
||||
private StatusMrPersonalNotify(
|
||||
Long mrId,
|
||||
String name,
|
||||
String url,
|
||||
String projectName,
|
||||
MergeRequestState oldStatus,
|
||||
MergeRequestState newStatus,
|
||||
String milestone
|
||||
) {
|
||||
super(mrId, projectName, name, url, milestone);
|
||||
this.oldStatus = oldStatus;
|
||||
this.newStatus = newStatus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.mergerequest;
|
||||
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.UpdateMrPersonalNotifyFields.CLASS_NAME;
|
||||
|
||||
@Getter
|
||||
@FieldNames
|
||||
public class UpdateMrPersonalNotify extends MrPersonalNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
private final String author;
|
||||
private final Long allTasks;
|
||||
private final Long allResolvedTasks;
|
||||
private final Long personTasks;
|
||||
private final Long personResolvedTasks;
|
||||
private final String comment;
|
||||
|
||||
@Builder
|
||||
private UpdateMrPersonalNotify(
|
||||
Long mrId,
|
||||
String name,
|
||||
String url,
|
||||
String author,
|
||||
String projectName,
|
||||
Long allTasks,
|
||||
Long allResolvedTasks,
|
||||
Long personTasks,
|
||||
Long personResolvedTasks,
|
||||
String comment,
|
||||
String milestone
|
||||
) {
|
||||
super(mrId, projectName, name, url, milestone);
|
||||
this.author = author;
|
||||
this.allTasks = allTasks;
|
||||
this.allResolvedTasks = allResolvedTasks;
|
||||
this.personTasks = personTasks;
|
||||
this.personResolvedTasks = personResolvedTasks;
|
||||
this.comment = comment;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -1,47 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.pipeline;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.notify.pipeline.PipelinePersonalNotifyFields.CLASS_NAME;
|
||||
|
||||
/**
|
||||
* @author upagge 17.01.2021
|
||||
*/
|
||||
//TODO [16.12.2022|uPagge]: Нужно реализовать заполнение projectName
|
||||
@Getter
|
||||
@FieldNames
|
||||
public final class PipelinePersonalNotify implements PersonalNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
private final String projectName;
|
||||
private final String refName;
|
||||
private final PipelineStatus oldStatus;
|
||||
private final PipelineStatus newStatus;
|
||||
private final String webUrl;
|
||||
|
||||
@Builder
|
||||
public PipelinePersonalNotify(
|
||||
String projectName,
|
||||
String refName,
|
||||
PipelineStatus oldStatus,
|
||||
PipelineStatus newStatus,
|
||||
String webUrl
|
||||
) {
|
||||
this.projectName = projectName;
|
||||
this.refName = refName;
|
||||
this.oldStatus = oldStatus;
|
||||
this.newStatus = newStatus;
|
||||
this.webUrl = webUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.project;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.notify.project.NewProjectPersonalNotifyFields.CLASS_NAME;
|
||||
|
||||
/**
|
||||
* @author upagge 15.01.2021
|
||||
*/
|
||||
@Getter
|
||||
@FieldNames
|
||||
public final class NewProjectPersonalNotify implements PersonalNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
private final Long projectId;
|
||||
private final String projectName;
|
||||
private final String projectUrl;
|
||||
private final String projectDescription;
|
||||
private final String authorName;
|
||||
private final String sshUrlToRepo;
|
||||
private final String httpUrlToRepo;
|
||||
|
||||
@Builder
|
||||
public NewProjectPersonalNotify(
|
||||
Long projectId,
|
||||
String projectName,
|
||||
String projectUrl,
|
||||
String projectDescription,
|
||||
String authorName,
|
||||
String sshUrlToRepo,
|
||||
String httpUrlToRepo
|
||||
) {
|
||||
this.projectId = projectId;
|
||||
this.projectName = projectName;
|
||||
this.projectUrl = projectUrl;
|
||||
this.projectDescription = projectDescription;
|
||||
this.authorName = authorName;
|
||||
this.sshUrlToRepo = sshUrlToRepo;
|
||||
this.httpUrlToRepo = httpUrlToRepo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.task;
|
||||
|
||||
import dev.struchkov.haiti.utils.container.Pair;
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
import lombok.Singular;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.notify.task.DiscussionNewPersonalNotifyFields.CLASS_NAME;
|
||||
|
||||
/**
|
||||
* @author upagge 10.09.2020
|
||||
*/
|
||||
@Getter
|
||||
@FieldNames
|
||||
public class DiscussionNewPersonalNotify extends ThreadPersonalNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
private final String threadId;
|
||||
private final List<Pair<String, String>> notes;
|
||||
|
||||
@Builder
|
||||
public DiscussionNewPersonalNotify(
|
||||
String threadId,
|
||||
String mergeRequestName,
|
||||
String authorName,
|
||||
String url,
|
||||
String discussionMessage,
|
||||
@Singular List<Pair<String, String>> notes
|
||||
) {
|
||||
super(mergeRequestName, authorName, url, discussionMessage);
|
||||
this.threadId = threadId;
|
||||
this.notes = notes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.task;
|
||||
|
||||
import dev.struchkov.haiti.utils.fieldconstants.annotation.FieldNames;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.notify.task.ThreadClosePersonalNotifyFields.CLASS_NAME;
|
||||
|
||||
/**
|
||||
* @author upagge 10.09.2020
|
||||
*/
|
||||
@Getter
|
||||
@FieldNames
|
||||
public class ThreadClosePersonalNotify extends ThreadPersonalNotify {
|
||||
|
||||
public static final String TYPE = CLASS_NAME;
|
||||
|
||||
private final Long personTasks;
|
||||
private final Long personResolvedTasks;
|
||||
private final String authorLastNote;
|
||||
private final String messageLastNote;
|
||||
|
||||
@Builder
|
||||
protected ThreadClosePersonalNotify(
|
||||
String mergeRequestName,
|
||||
String authorName,
|
||||
String url,
|
||||
String messageTask,
|
||||
Long personTasks,
|
||||
Long personResolvedTasks,
|
||||
String authorLastNote,
|
||||
String messageLastNote
|
||||
) {
|
||||
super(mergeRequestName, authorName, url, messageTask);
|
||||
this.personTasks = personTasks;
|
||||
this.personResolvedTasks = personResolvedTasks;
|
||||
this.authorLastNote = authorLastNote;
|
||||
this.messageLastNote = messageLastNote;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
}
|
@ -1,26 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.domain.notify.task;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public abstract class ThreadPersonalNotify implements PersonalNotify {
|
||||
|
||||
protected final String mergeRequestName;
|
||||
protected final String authorName;
|
||||
protected final String url;
|
||||
protected final String messageTask;
|
||||
|
||||
protected ThreadPersonalNotify(
|
||||
String mergeRequestName,
|
||||
String authorName,
|
||||
String url,
|
||||
String messageTask
|
||||
) {
|
||||
this.mergeRequestName = mergeRequestName;
|
||||
this.authorName = authorName;
|
||||
this.url = url;
|
||||
this.messageTask = messageTask;
|
||||
}
|
||||
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.prop;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* Основные настройки приложения.
|
||||
*
|
||||
* @author upagge 11.10.2020
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
public class AppProperty {
|
||||
|
||||
private String version;
|
||||
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.prop;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class GroupNotifyProperty {
|
||||
|
||||
private Optional<String> chatId;
|
||||
private Optional<Integer> threadId;
|
||||
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.prop;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
/**
|
||||
* @author upagge 15.01.2021
|
||||
*/
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class PersonProperty {
|
||||
|
||||
private String telegramId;
|
||||
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.repository;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.AppSetting;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author upagge 16.01.2021
|
||||
*/
|
||||
public interface AppSettingRepository {
|
||||
|
||||
AppSetting save(AppSetting appSetting);
|
||||
|
||||
Optional<AppSetting> findById(Long key);
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.repository;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author upagge 11.02.2021
|
||||
*/
|
||||
public interface DiscussionRepository {
|
||||
|
||||
/**
|
||||
* Вернуть все дискусии для MR
|
||||
*/
|
||||
List<Discussion> findAllByMergeRequestId(Long mergeRequestId);
|
||||
|
||||
Discussion save(Discussion discussion);
|
||||
|
||||
Optional<Discussion> findById(String discussionId);
|
||||
|
||||
List<Discussion> findAll();
|
||||
|
||||
List<Discussion> findAllById(Set<String> discussionIds);
|
||||
|
||||
Set<String> findAllIds();
|
||||
|
||||
void deleteById(String id);
|
||||
|
||||
void cleanOld();
|
||||
|
||||
void notification(boolean enable, String discussionId);
|
||||
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.repository;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.IdAndStatusPr;
|
||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequestForDiscussion;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
public interface MergeRequestRepository {
|
||||
|
||||
Set<IdAndStatusPr> findAllIdByStateIn(@NonNull Set<MergeRequestState> states);
|
||||
|
||||
MergeRequest save(MergeRequest mergeRequest);
|
||||
|
||||
Optional<MergeRequest> findById(Long mergeRequestId);
|
||||
|
||||
List<MergeRequestForDiscussion> findAllForDiscussion();
|
||||
|
||||
List<MergeRequest> findAllById(Set<Long> mergeRequestIds);
|
||||
|
||||
List<MergeRequest> findAllByReviewerId(Long personId);
|
||||
|
||||
void deleteByStates(Set<MergeRequestState> states);
|
||||
|
||||
Set<Long> findAllIds();
|
||||
|
||||
void notification(boolean enable, Long mrId);
|
||||
|
||||
void notificationByProjectId(boolean enable, Set<Long> projectIds);
|
||||
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.repository;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author upagge 08.09.2020
|
||||
*/
|
||||
public interface NoteRepository {
|
||||
|
||||
List<Note> findAllByResponsibleIdAndResolved(Long userId, boolean resolved);
|
||||
|
||||
Page<Note> findAllByResolved(boolean resolved, Pageable pagination);
|
||||
|
||||
Optional<Note> findById(Long noteId);
|
||||
}
|
@ -1,25 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.repository;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.PersonTelegram;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author upagge 15.01.2021
|
||||
*/
|
||||
public interface PersonRepository {
|
||||
|
||||
Person save(Person person);
|
||||
|
||||
Optional<Person> findById(Long personId);
|
||||
|
||||
List<Person> findAllById(Set<Long> personIds);
|
||||
|
||||
Optional<PersonTelegram> findTelegramInfoById(Long personId);
|
||||
|
||||
List<PersonTelegram> findAllTelegramInfoByIds(Set<Long> personIds);
|
||||
|
||||
}
|
@ -1,28 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.repository;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author upagge 17.01.2021
|
||||
*/
|
||||
public interface PipelineRepository {
|
||||
|
||||
Pipeline save(Pipeline pipeline);
|
||||
|
||||
Optional<Pipeline> findById(Long pipelineId);
|
||||
|
||||
List<Pipeline> findAllByStatuses(Set<PipelineStatus> statuses);
|
||||
|
||||
List<Pipeline> findAllById(Set<Long> pipelineIds);
|
||||
|
||||
void deleteByCreatedBefore(LocalDateTime date);
|
||||
|
||||
Set<Long> findAllIds();
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.repository;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author upagge 14.01.2021
|
||||
*/
|
||||
public interface ProjectRepository {
|
||||
|
||||
Project save(Project project);
|
||||
|
||||
Optional<Project> findById(Long projectId);
|
||||
|
||||
List<Project> findAllById(Set<Long> projectIds);
|
||||
|
||||
boolean existById(Long projectId);
|
||||
|
||||
Page<Project> findAllById(Pageable pagination);
|
||||
|
||||
Set<Long> findAllIdByProcessingEnable();
|
||||
|
||||
Optional<String> findProjectNameById(Long projectId);
|
||||
|
||||
Set<Long> findAllIds();
|
||||
|
||||
void notification(boolean enable, Set<Long> projectIds);
|
||||
|
||||
void processing(boolean enable, Set<Long> projectIds);
|
||||
|
||||
}
|
@ -1,46 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.service;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Сервис отвечает за пользовательские настройки приложения.
|
||||
*
|
||||
* @author upagge 16.01.2021
|
||||
*/
|
||||
public interface AppSettingService {
|
||||
|
||||
/**
|
||||
* Метод позволяет проверить запускается ли приложение впервые.
|
||||
*
|
||||
* @return true - если это первый запуск
|
||||
*/
|
||||
boolean isFirstStart();
|
||||
|
||||
/**
|
||||
* Метод отмечает, что приложение было запущено.
|
||||
*
|
||||
* @see AppSettingService#isFirstStart()
|
||||
*/
|
||||
void disableFirstStart();
|
||||
|
||||
boolean isEnableAllNotify();
|
||||
|
||||
void turnOnAllNotify();
|
||||
|
||||
void privateProjectScan(boolean enable);
|
||||
|
||||
void ownerProjectScan(boolean enable);
|
||||
|
||||
boolean isOwnerProjectScan();
|
||||
|
||||
boolean isPrivateProjectScan();
|
||||
|
||||
DiscussionLevel getLevelDiscussionNotify();
|
||||
|
||||
void setDiscussionLevel(DiscussionLevel level);
|
||||
|
||||
UUID getServiceKey();
|
||||
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.service;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author upagge 11.02.2021
|
||||
*/
|
||||
public interface DiscussionService {
|
||||
|
||||
Discussion create(@NonNull Discussion discussion);
|
||||
|
||||
Discussion update(@NonNull Discussion discussion);
|
||||
|
||||
List<Discussion> updateAll(@NonNull List<Discussion> discussions);
|
||||
|
||||
/**
|
||||
* Метод отправляющий коментарий в дискуссию.
|
||||
*
|
||||
* @param discussionId Идентификатор дискуссии
|
||||
* @param text Текст комментария
|
||||
*/
|
||||
void answer(@NonNull String discussionId, @NonNull String text);
|
||||
|
||||
/**
|
||||
* Получить все дискусси для MR.
|
||||
*/
|
||||
List<Discussion> getAllByMergeRequestId(@NonNull Long mergeRequestId);
|
||||
|
||||
ExistContainer<Discussion, String> existsById(@NonNull Set<String> discussionIds);
|
||||
|
||||
List<Discussion> createAll(@NonNull List<Discussion> newDiscussions);
|
||||
|
||||
List<Discussion> getAll();
|
||||
|
||||
Set<String> getAllIds();
|
||||
|
||||
void deleteById(@NonNull String discussionId);
|
||||
|
||||
void cleanOld();
|
||||
|
||||
void notification(boolean enable, String discussionId);
|
||||
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.service;
|
||||
|
||||
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.entity.MergeRequest;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequestForDiscussion;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public interface MergeRequestsService {
|
||||
|
||||
MergeRequest create(@NonNull MergeRequest mergeRequest);
|
||||
|
||||
MergeRequest update(@NonNull MergeRequest mergeRequest);
|
||||
|
||||
List<MergeRequest> updateAll(@NonNull List<MergeRequest> mergeRequests);
|
||||
|
||||
/**
|
||||
* Получить все идентификаторы вместе со статусами.
|
||||
*
|
||||
* @param statuses Статусы ПРов
|
||||
* @return Объект, содержащий идентификатор и статус ПР
|
||||
*/
|
||||
Set<IdAndStatusPr> getAllId(Set<MergeRequestState> statuses);
|
||||
|
||||
List<MergeRequestForDiscussion> getAllForDiscussion();
|
||||
|
||||
ExistContainer<MergeRequest, Long> existsById(@NonNull Set<Long> mergeRequestIds);
|
||||
|
||||
List<MergeRequest> createAll(List<MergeRequest> newMergeRequests);
|
||||
|
||||
List<MergeRequest> getAllByReviewerId(@NonNull Long personId);
|
||||
|
||||
void cleanOld();
|
||||
|
||||
Set<Long> getAllIds();
|
||||
|
||||
void notification(boolean enable, @NonNull Long mrId);
|
||||
|
||||
void notificationByProjectId(boolean enable, @NonNull Set<Long> projectIds);
|
||||
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.service;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.GroupNotify;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
||||
import lombok.NonNull;
|
||||
|
||||
public interface MessageSendService {
|
||||
|
||||
void send(@NonNull PersonalNotify notify);
|
||||
|
||||
void send(@NonNull GroupNotify notify);
|
||||
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.service;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
||||
import lombok.NonNull;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface NoteService {
|
||||
|
||||
List<Note> getAllPersonTask(@NonNull Long userId, boolean resolved);
|
||||
|
||||
//TODO [28.01.2022]: Решить нужно ли оставлять
|
||||
Page<Note> getAllByResolved(boolean resolved, @NonNull Pageable pagination);
|
||||
|
||||
Note getByIdOrThrow(@NonNull Long noteId);
|
||||
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.service;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.GroupNotify;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.PersonalNotify;
|
||||
|
||||
/**
|
||||
* Сервис по работе с изменениями в битбакете.
|
||||
*
|
||||
* @author upagge
|
||||
* @see PersonalNotify
|
||||
*/
|
||||
public interface NotifyService {
|
||||
|
||||
<T extends PersonalNotify> void send(T notify);
|
||||
|
||||
<T extends GroupNotify> void send(T notify);
|
||||
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.service;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author upagge 15.01.2021
|
||||
*/
|
||||
public interface PersonService {
|
||||
|
||||
Person create(@NonNull Person person);
|
||||
|
||||
Person getByIdOrThrown(@NonNull Long personId);
|
||||
|
||||
ExistContainer<Person, Long> existsById(Set<Long> personIds);
|
||||
|
||||
List<Person> createAll(List<Person> newPersons);
|
||||
|
||||
Optional<String> getTelegramUsernamesByPersonIds(Long personId);
|
||||
|
||||
Map<Long, String> getTelegramUsernamesByPersonIds(Set<Long> personIds);
|
||||
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.service;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Сервис для работы с пайплайнами
|
||||
*
|
||||
* @author upagge 17.01.2021
|
||||
*/
|
||||
public interface PipelineService {
|
||||
|
||||
Pipeline create(@NonNull Pipeline pipeline);
|
||||
|
||||
List<Pipeline> createAll(@NonNull List<Pipeline> newPipelines);
|
||||
|
||||
Pipeline update(@NonNull Pipeline pipeline);
|
||||
|
||||
List<Pipeline> updateAll(@NonNull List<Pipeline> pipelines);
|
||||
|
||||
List<Pipeline> getAllByStatuses(@NonNull Set<PipelineStatus> statuses);
|
||||
|
||||
ExistContainer<Pipeline, Long> existsById(@NonNull Set<Long> pipelineIds);
|
||||
|
||||
void cleanOld();
|
||||
|
||||
Set<Long> getAllIds();
|
||||
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.service;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||
import lombok.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author upagge 14.01.2021
|
||||
*/
|
||||
public interface ProjectService {
|
||||
|
||||
Project create(@NonNull Project project, boolean sendNotify);
|
||||
|
||||
Project update(@NonNull Project project);
|
||||
|
||||
Project getByIdOrThrow(@NonNull Long projectId);
|
||||
|
||||
List<Project> createAll(List<Project> newProjects);
|
||||
|
||||
boolean existsById(Long projectId);
|
||||
|
||||
ExistContainer<Project, Long> existsById(Set<Long> projectIds);
|
||||
|
||||
Set<Long> getAllIdByProcessingEnable();
|
||||
|
||||
Optional<String> getProjectNameById(Long projectId);
|
||||
|
||||
Set<Long> getAllIds();
|
||||
|
||||
void notification(boolean enable, Set<Long> projectIds);
|
||||
|
||||
void processing(boolean enable, Set<Long> projectIds);
|
||||
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.context.utils;
|
||||
|
||||
import static dev.struchkov.haiti.utils.Exceptions.utilityClass;
|
||||
import static dev.struchkov.haiti.utils.Strings.escapeMarkdown;
|
||||
|
||||
public class Icons {
|
||||
|
||||
public static final String HR = "\n-- -- -- -- --\n";
|
||||
|
||||
public static final String FUN = "\uD83C\uDF89";
|
||||
public static final String VIEW = "\uD83D\uDC40";
|
||||
public static final String TREE = "\uD83C\uDF33";
|
||||
public static final String AUTHOR = "\uD83D\uDC68\u200D\uD83D\uDCBB️";
|
||||
public static final String UPDATE = "\uD83D\uDD04";
|
||||
public static final String COMMENT = "\uD83D\uDCAC";
|
||||
public static final String THREAD = "\uD83E\uDDF5";
|
||||
public static final String ARROW = " ➜ ";
|
||||
public static final String DANGEROUS = "⚠️";
|
||||
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";
|
||||
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 = "✅";
|
||||
public static final String NO = "❌";
|
||||
public static final String NOTIFY = "\uD83D\uDD14";
|
||||
public static final String GOOD = "\uD83D\uDC4D";
|
||||
|
||||
private Icons() {
|
||||
utilityClass();
|
||||
}
|
||||
|
||||
public static String link(String title, String url) {
|
||||
return "[" + escapeMarkdown(title) + "](" + url + ")";
|
||||
}
|
||||
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>dev.struchkov.bot.gitlab</groupId>
|
||||
<artifactId>gitlab-bot</artifactId>
|
||||
<version>2.0.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>bot-core</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>dev.struchkov.haiti.filter</groupId>
|
||||
<artifactId>haiti-filter-criteria</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.struchkov.bot.gitlab</groupId>
|
||||
<artifactId>bot-context</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.postgresql</groupId>
|
||||
<artifactId>postgresql</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>dev.struchkov.sdk.gitlab</groupId>
|
||||
<artifactId>gitlab-sdk-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.core</groupId>
|
||||
<artifactId>jackson-databind</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.hibernate.validator</groupId>
|
||||
<artifactId>hibernate-validator</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>javax.el</groupId>
|
||||
<artifactId>javax.el-api</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.glassfish</groupId>
|
||||
<artifactId>jakarta.el</artifactId>
|
||||
<version>4.0.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -1,31 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.convert;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||
import dev.struchkov.sdk.gitlab.schema.note.DiscussionJson;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author upagge 11.02.2021
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DiscussionJsonConverter implements Converter<DiscussionJson, Discussion> {
|
||||
|
||||
private final NoteJsonConvert noteJsonConvert;
|
||||
|
||||
@Override
|
||||
public Discussion convert(DiscussionJson source) {
|
||||
final Discussion discussion = new Discussion();
|
||||
discussion.setId(source.getId());
|
||||
discussion.setNotes(
|
||||
source.getNotes().stream()
|
||||
.filter(noteJson -> !noteJson.isSystem())
|
||||
.map(noteJsonConvert::convert)
|
||||
.toList()
|
||||
);
|
||||
return discussion;
|
||||
}
|
||||
|
||||
}
|
@ -1,87 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.convert;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.sdk.gitlab.schema.common.PersonJson;
|
||||
import dev.struchkov.sdk.gitlab.schema.mergerequest.MergeRequestJson;
|
||||
import dev.struchkov.sdk.gitlab.schema.mergerequest.MergeRequestStateJson;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author upagge 15.01.2021
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class MergeRequestJsonConverter implements Converter<MergeRequestJson, MergeRequest> {
|
||||
|
||||
private final PersonJsonConverter convertPerson;
|
||||
|
||||
@Override
|
||||
public MergeRequest convert(MergeRequestJson source) {
|
||||
final MergeRequest mergeRequest = new MergeRequest();
|
||||
mergeRequest.setConflict(source.isConflicts());
|
||||
mergeRequest.setTitle(source.getTitle());
|
||||
mergeRequest.setCreatedDate(source.getCreatedDate());
|
||||
mergeRequest.setDescription(source.getDescription());
|
||||
mergeRequest.setId(source.getId());
|
||||
mergeRequest.setTwoId(source.getTwoId());
|
||||
mergeRequest.setUpdatedDate(source.getUpdatedDate());
|
||||
mergeRequest.setState(convertState(source.getState()));
|
||||
mergeRequest.setProjectId(source.getProjectId());
|
||||
mergeRequest.setWebUrl(source.getWebUrl());
|
||||
|
||||
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()));
|
||||
}
|
||||
|
||||
mergeRequest.setAuthor(convertPerson.convert(source.getAuthor()));
|
||||
mergeRequest.setSourceBranch(source.getSourceBranch());
|
||||
mergeRequest.setTargetBranch(source.getTargetBranch());
|
||||
return mergeRequest;
|
||||
}
|
||||
|
||||
private void convertReviewers(MergeRequest mergeRequest, List<PersonJson> jsonReviewers) {
|
||||
if (checkNotEmpty(jsonReviewers)) {
|
||||
final List<Person> reviewers = jsonReviewers.stream()
|
||||
.map(convertPerson::convert)
|
||||
.toList();
|
||||
mergeRequest.setReviewers(reviewers);
|
||||
}
|
||||
}
|
||||
|
||||
private static void convertLabels(MergeRequest mergeRequest, Set<String> source) {
|
||||
if (checkNotEmpty(source)) {
|
||||
final Set<String> labels = source.stream()
|
||||
.map(label -> label.replace("-", "_"))
|
||||
.collect(Collectors.toSet());
|
||||
mergeRequest.setLabels(labels);
|
||||
}
|
||||
}
|
||||
|
||||
private MergeRequestState convertState(MergeRequestStateJson state) {
|
||||
return switch (state) {
|
||||
case CLOSED -> MergeRequestState.CLOSED;
|
||||
case LOCKED -> MergeRequestState.LOCKED;
|
||||
case MERGED -> MergeRequestState.MERGED;
|
||||
case OPENED -> MergeRequestState.OPENED;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.convert;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
||||
import dev.struchkov.sdk.gitlab.schema.note.NoteJson;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author upagge 12.09.2020
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class NoteJsonConvert implements Converter<NoteJson, Note> {
|
||||
|
||||
private final PersonJsonConverter personConverter;
|
||||
|
||||
@Override
|
||||
public Note convert(NoteJson source) {
|
||||
final Note note = new Note();
|
||||
note.setAuthor(personConverter.convert(source.getAuthor()));
|
||||
note.setId(source.getId());
|
||||
note.setBody(source.getBody());
|
||||
note.setType(source.getType());
|
||||
note.setNoteableType(source.getNoteableType());
|
||||
note.setCreated(source.getCreated());
|
||||
note.setUpdated(source.getUpdated());
|
||||
note.setNoteableId(source.getNoteableId());
|
||||
note.setNoteableIid(source.getNoteableIid());
|
||||
note.setResolved(source.getResolved());
|
||||
note.setResolvable(source.isResolvable());
|
||||
if (source.getResolvedBy() != null) {
|
||||
note.setResolvedBy(personConverter.convert(source.getResolvedBy()));
|
||||
}
|
||||
return note;
|
||||
}
|
||||
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.convert;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.sdk.gitlab.schema.common.PersonJson;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author upagge 15.01.2021
|
||||
*/
|
||||
@Component
|
||||
public class PersonJsonConverter implements Converter<PersonJson, Person> {
|
||||
|
||||
@Override
|
||||
public Person convert(PersonJson source) {
|
||||
final Person person = new Person();
|
||||
person.setId(source.getId());
|
||||
person.setName(source.getName());
|
||||
person.setUserName(source.getUsername());
|
||||
person.setWebUrl(source.getWebUrl());
|
||||
return person;
|
||||
}
|
||||
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.convert;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
||||
import dev.struchkov.sdk.gitlab.schema.pipeline.PipelineJson;
|
||||
import dev.struchkov.sdk.gitlab.schema.pipeline.PipelineStatusJson;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.CANCELED;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.CREATED;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.FAILED;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.MANUAL;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.PENDING;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.PREPARING;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.RUNNING;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.SCHEDULED;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.SKIPPED;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.SUCCESS;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.WAITING_FOR_RESOURCE;
|
||||
|
||||
/**
|
||||
* @author upagge 17.01.2021
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class PipelineJsonConverter implements Converter<PipelineJson, Pipeline> {
|
||||
|
||||
private final PersonJsonConverter convertPerson;
|
||||
|
||||
@Override
|
||||
public Pipeline convert(PipelineJson source) {
|
||||
final Pipeline pipeline = new Pipeline();
|
||||
pipeline.setId(source.getId());
|
||||
pipeline.setCreated(source.getCreated());
|
||||
pipeline.setUpdated(source.getUpdated());
|
||||
pipeline.setRef(source.getRef());
|
||||
pipeline.setWebUrl(source.getWebUrl());
|
||||
pipeline.setStatus(convertStatus(source.getStatus()));
|
||||
pipeline.setPerson(convertPerson.convert(source.getUser()));
|
||||
|
||||
pipeline.setProjectId(source.getProjectId());
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
private PipelineStatus convertStatus(PipelineStatusJson status) {
|
||||
return switch (status) {
|
||||
case SKIPPED -> SKIPPED;
|
||||
case CANCELED -> CANCELED;
|
||||
case SUCCESS -> SUCCESS;
|
||||
case MANUAL -> MANUAL;
|
||||
case CREATED -> CREATED;
|
||||
case PENDING -> PENDING;
|
||||
case RUNNING -> RUNNING;
|
||||
case PREPARING -> PREPARING;
|
||||
case SCHEDULED -> SCHEDULED;
|
||||
case WAITING_FOR_RESOURCE -> WAITING_FOR_RESOURCE;
|
||||
default -> FAILED;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.convert;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||
import dev.struchkov.sdk.gitlab.schema.repository.ProjectJson;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author upagge 14.01.2021
|
||||
*/
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ProjectJsonConverter implements Converter<ProjectJson, Project> {
|
||||
|
||||
@Override
|
||||
public Project convert(ProjectJson source) {
|
||||
final Project project = new Project();
|
||||
project.setId(source.getId());
|
||||
project.setCreatedDate(source.getCreatedDate());
|
||||
project.setCreatorId(source.getCreatorId());
|
||||
project.setDescription(source.getDescription());
|
||||
project.setName(source.getName());
|
||||
project.setWebUrl(source.getWebUrl());
|
||||
project.setHttpUrlToRepo(source.getHttpUrlToRepo());
|
||||
project.setSshUrlToRepo(source.getSshUrlToRepo());
|
||||
return project;
|
||||
}
|
||||
|
||||
}
|
@ -1,265 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.handler;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequestForDiscussion;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
||||
import dev.struchkov.bot.gitlab.context.domain.event.NewDiscussionEvent;
|
||||
import dev.struchkov.bot.gitlab.context.domain.event.UpdateDiscussionEvent;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.comment.NewCommentPersonalNotify;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.task.DiscussionNewPersonalNotify;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.task.ThreadClosePersonalNotify;
|
||||
import dev.struchkov.bot.gitlab.context.service.AppSettingService;
|
||||
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
||||
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
||||
import dev.struchkov.haiti.utils.container.Pair;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel.NOTIFY_WITH_CONTEXT;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel.WITHOUT_NOTIFY;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNull;
|
||||
import static java.lang.Boolean.FALSE;
|
||||
import static java.lang.Boolean.TRUE;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DiscussionHandler {
|
||||
|
||||
protected static final Pattern PATTERN = Pattern.compile("@[\\w]+");
|
||||
|
||||
private final PersonInformation personInformation;
|
||||
private final AppSettingService settingService;
|
||||
private final DiscussionService discussionService;
|
||||
|
||||
private final NotifyService notifyService;
|
||||
|
||||
@EventListener
|
||||
public void newDiscussionEvent(NewDiscussionEvent event) {
|
||||
final Discussion discussion = event.getDiscussion();
|
||||
final List<Note> notes = discussion.getNotes();
|
||||
|
||||
if (isNeedNotifyNewNote(discussion)) {
|
||||
notifyNewThread(discussion);
|
||||
} else {
|
||||
notes.forEach(note -> notifyAboutPersonalAnswer(discussion, note));
|
||||
}
|
||||
}
|
||||
|
||||
@EventListener
|
||||
public void updateDiscussionHandle(UpdateDiscussionEvent event) {
|
||||
final Discussion oldDiscussion = event.getOldDiscussion();
|
||||
final Discussion newDiscussion = event.getNewDiscussion();
|
||||
|
||||
if (oldDiscussion.isNotification()) {
|
||||
final Map<Long, Note> oldNoteMap = oldDiscussion
|
||||
.getNotes().stream()
|
||||
.collect(Collectors.toMap(Note::getId, n -> n));
|
||||
|
||||
// Пользователь участвовал в обсуждении
|
||||
final boolean userParticipatedInDiscussion = oldDiscussion.getNotes().stream()
|
||||
.anyMatch(note -> personInformation.getId().equals(note.getAuthor().getId()));
|
||||
|
||||
final Note threadFirstNote = newDiscussion.getFirstNote();
|
||||
if (TRUE.equals(newDiscussion.getResolved())) {
|
||||
notifyAboutCloseThread(threadFirstNote, oldNoteMap.get(threadFirstNote.getId()), newDiscussion.getLastNote());
|
||||
}
|
||||
|
||||
for (Note newNote : newDiscussion.getNotes()) {
|
||||
final Long newNoteId = newNote.getId();
|
||||
if (!oldNoteMap.containsKey(newNoteId)) {
|
||||
if (userParticipatedInDiscussion) {
|
||||
notifyAboutNewAnswer(newDiscussion, newNote);
|
||||
} else {
|
||||
notifyAboutPersonalAnswer(newDiscussion, newNote);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Уведомляет пользователя, если появился новый комментарий</p>
|
||||
*/
|
||||
private void notifyNewThread(Discussion discussion) {
|
||||
final DiscussionLevel discussionLevel = settingService.getLevelDiscussionNotify();
|
||||
if (!WITHOUT_NOTIFY.equals(discussionLevel)) {
|
||||
final Note firstNote = discussion.getFirstNote();
|
||||
|
||||
final MergeRequestForDiscussion mergeRequest = discussion.getMergeRequest();
|
||||
final DiscussionNewPersonalNotify.DiscussionNewPersonalNotifyBuilder messageBuilder = DiscussionNewPersonalNotify.builder()
|
||||
.url(firstNote.getWebUrl())
|
||||
.threadId(discussion.getId())
|
||||
.mergeRequestName(mergeRequest.getTitle())
|
||||
.authorName(firstNote.getAuthor().getName());
|
||||
|
||||
if (NOTIFY_WITH_CONTEXT.equals(discussionLevel)) {
|
||||
final List<Note> notes = discussion.getNotes();
|
||||
|
||||
messageBuilder
|
||||
.discussionMessage(firstNote.getBody());
|
||||
|
||||
if (notes.size() > 1) {
|
||||
for (int i = 1; i < notes.size(); i++) {
|
||||
final Note note = notes.get(i);
|
||||
messageBuilder.note(
|
||||
new Pair<>(note.getAuthor().getName(), note.getBody())
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
notifyService.send(messageBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNeedNotifyNewNote(Discussion discussion) {
|
||||
final Note firstNote = discussion.getFirstNote();
|
||||
final Long gitlabUserId = personInformation.getId();
|
||||
return firstNote.isResolvable() // Тип комментария требует решения (Задачи)
|
||||
&& gitlabUserId.equals(discussion.getResponsible().getId()) // Ответственный за дискуссию пользователь
|
||||
&& !gitlabUserId.equals(firstNote.getAuthor().getId()) // Создатель комментария не пользователь системы
|
||||
&& FALSE.equals(firstNote.getResolved()); // Комментарий не отмечен как решенный
|
||||
}
|
||||
|
||||
/**
|
||||
* Уведомляет пользователя, если его никнейм упоминается в комментарии.
|
||||
*/
|
||||
private void notifyAboutPersonalAnswer(Discussion discussion, Note note) {
|
||||
final DiscussionLevel discussionLevel = settingService.getLevelDiscussionNotify();
|
||||
if (!WITHOUT_NOTIFY.equals(discussionLevel)) {
|
||||
final Matcher matcher = PATTERN.matcher(note.getBody());
|
||||
final Set<String> recipientsLogins = new HashSet<>();
|
||||
|
||||
while (matcher.find()) {
|
||||
final String login = matcher.group(0).replace("@", "");
|
||||
recipientsLogins.add(login);
|
||||
}
|
||||
|
||||
if (recipientsLogins.contains(personInformation.getUsername())) {
|
||||
final NewCommentPersonalNotify.NewCommentPersonalNotifyBuilder notifyBuilder = NewCommentPersonalNotify.builder()
|
||||
.threadId(discussion.getId())
|
||||
.mergeRequestName(discussion.getMergeRequest().getTitle())
|
||||
.url(note.getWebUrl());
|
||||
|
||||
if (NOTIFY_WITH_CONTEXT.equals(discussionLevel)) {
|
||||
final Optional<Note> prevLastNote = discussion.getPrevLastNote();
|
||||
final Note firstNote = discussion.getFirstNote();
|
||||
|
||||
if (!firstNote.equals(note)) {
|
||||
notifyBuilder.message(note.getBody())
|
||||
.authorName(note.getAuthor().getName());
|
||||
}
|
||||
if (prevLastNote.isPresent()) {
|
||||
final Note prevNote = prevLastNote.get();
|
||||
notifyBuilder.previousMessage(prevNote.getBody());
|
||||
notifyBuilder.previousAuthor(prevNote.getAuthor().getName());
|
||||
}
|
||||
|
||||
notifyBuilder
|
||||
.discussionMessage(firstNote.getBody())
|
||||
.discussionAuthor(firstNote.getAuthor().getName());
|
||||
}
|
||||
|
||||
notifyService.send(notifyBuilder.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyAboutNewAnswer(Discussion discussion, Note note) {
|
||||
final DiscussionLevel discussionLevel = settingService.getLevelDiscussionNotify();
|
||||
|
||||
if (!WITHOUT_NOTIFY.equals(discussionLevel)
|
||||
&& !personInformation.getId().equals(note.getAuthor().getId())) {
|
||||
final Note firstNote = discussion.getFirstNote();
|
||||
|
||||
final NewCommentPersonalNotify.NewCommentPersonalNotifyBuilder notifyBuilder = NewCommentPersonalNotify.builder()
|
||||
.threadId(discussion.getId())
|
||||
.url(note.getWebUrl())
|
||||
.mergeRequestName(discussion.getMergeRequest().getTitle());
|
||||
|
||||
if (NOTIFY_WITH_CONTEXT.equals(discussionLevel)) {
|
||||
final Optional<Note> prevLastNote = discussion.getPrevLastNote();
|
||||
|
||||
if (prevLastNote.isPresent()) {
|
||||
final Note prevNote = prevLastNote.get();
|
||||
notifyBuilder.previousMessage(prevNote.getBody());
|
||||
notifyBuilder.previousAuthor(prevNote.getAuthor().getName());
|
||||
}
|
||||
|
||||
notifyBuilder
|
||||
.discussionMessage(firstNote.getBody())
|
||||
.discussionAuthor(firstNote.getAuthor().getName())
|
||||
.message(note.getBody())
|
||||
.authorName(note.getAuthor().getName());
|
||||
}
|
||||
|
||||
notifyService.send(notifyBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyAboutCloseThread(Note newNote, Note oldNote, Optional<Note> lastNote) {
|
||||
final DiscussionLevel level = settingService.getLevelDiscussionNotify();
|
||||
if (!WITHOUT_NOTIFY.equals(level)) {
|
||||
|
||||
if (isResolved(newNote, oldNote)) {
|
||||
final MergeRequestForDiscussion mergeRequest = oldNote.getDiscussion().getMergeRequest();
|
||||
|
||||
final List<Discussion> discussions = discussionService.getAllByMergeRequestId(mergeRequest.getId())
|
||||
.stream()
|
||||
.filter(discussion -> Objects.nonNull(discussion.getResponsible()))
|
||||
.toList();
|
||||
final long allYouTasks = discussions.stream()
|
||||
.filter(discussion -> personInformation.getId().equals(discussion.getFirstNote().getAuthor().getId()))
|
||||
.count();
|
||||
final long resolvedYouTask = discussions.stream()
|
||||
.filter(discussion -> personInformation.getId().equals(discussion.getFirstNote().getAuthor().getId()) && discussion.getResolved())
|
||||
.count();
|
||||
|
||||
final ThreadClosePersonalNotify.ThreadClosePersonalNotifyBuilder notifyBuilder = ThreadClosePersonalNotify.builder()
|
||||
.mergeRequestName(mergeRequest.getTitle())
|
||||
.url(oldNote.getWebUrl())
|
||||
.personTasks(allYouTasks)
|
||||
.personResolvedTasks(resolvedYouTask);
|
||||
|
||||
if (NOTIFY_WITH_CONTEXT.equals(level)) {
|
||||
notifyBuilder
|
||||
.authorName(oldNote.getAuthor().getName())
|
||||
.messageTask(oldNote.getBody());
|
||||
|
||||
|
||||
lastNote.ifPresent(
|
||||
note -> {
|
||||
notifyBuilder.authorLastNote(note.getAuthor().getName());
|
||||
notifyBuilder.messageLastNote(note.getBody());
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
notifyService.send(notifyBuilder.build());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isResolved(Note note, Note oldNote) {
|
||||
return checkNull(oldNote.getResolvedBy()) // В старом комментарии не было отметки о решении
|
||||
&& checkNotNull(note.getResolvedBy()) // А в новом есть отметка
|
||||
&& personInformation.getId().equals(oldNote.getAuthor().getId()) // и решающий не является пользователем бота
|
||||
&& !note.getResolvedBy().getId().equals(oldNote.getAuthor().getId()); // и решающий не является автором треда
|
||||
}
|
||||
|
||||
}
|
@ -1,388 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.handler;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
||||
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.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;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ConflictMrPersonalNotify;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.ConflictResolveMrPersonalNotify;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.NewMrForAssignee;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.NewMrForReview;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.StatusMrPersonalNotify;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.mergerequest.UpdateMrPersonalNotify;
|
||||
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
||||
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
||||
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
||||
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class MergeRequestHandler {
|
||||
|
||||
private final NotifyService notifyService;
|
||||
|
||||
private final PersonService personService;
|
||||
private final PersonInformation personInformation;
|
||||
private final ProjectService projectService;
|
||||
private final DiscussionService discussionService;
|
||||
|
||||
@EventListener
|
||||
public void newMrHandle(NewMergeRequestEvent event) {
|
||||
final MergeRequest mergeRequest = event.getMergeRequest();
|
||||
final String projectName = projectService.getByIdOrThrow(mergeRequest.getProjectId()).getName();
|
||||
|
||||
final boolean userReviewer = mergeRequest.isUserReviewer();
|
||||
final boolean userAssignee = mergeRequest.isUserAssignee();
|
||||
if (mergeRequest.isConflict()) {
|
||||
sendGroupNotifyAboutConflict(mergeRequest, projectName);
|
||||
} else {
|
||||
if (mergeRequest.isNotification()) {
|
||||
if (userReviewer || userAssignee) {
|
||||
if (userReviewer) sendNotifyNewMrReview(mergeRequest, projectName);
|
||||
if (userAssignee) sendNotifyNewAssignee(mergeRequest, projectName, null);
|
||||
}
|
||||
}
|
||||
|
||||
sendGroupNotifyForReviewers(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());
|
||||
}
|
||||
if (reviewerChanged.isChanged()) {
|
||||
sendGroupNotifyForReviewers(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) {
|
||||
if (checkNotEmpty(mergeRequest.getReviewers())) {
|
||||
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()
|
||||
);
|
||||
}
|
||||
} else {
|
||||
sendGroupNotifyAboutNoReviewers(mergeRequest, projectName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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(
|
||||
ApprovalChangedMrPersonalNotify.builder()
|
||||
.mrId(mergeRequest.getId())
|
||||
.milestone(mergeRequest.getMilestone())
|
||||
.projectName(project.getName())
|
||||
.title(mergeRequest.getTitle())
|
||||
.url(mergeRequest.getWebUrl())
|
||||
.newApproval(newApproval)
|
||||
.dontApproval(dontApproval)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void sendNotifyNewMrReview(MergeRequest mergeRequest, String projectName) {
|
||||
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 void sendNotifyNewAssignee(MergeRequest mergeRequest, String projectName, String oldAssigneeName) {
|
||||
final NewMrForAssignee.NewMrForAssigneeBuilder builder = NewMrForAssignee.builder()
|
||||
.mrId(mergeRequest.getId())
|
||||
.projectName(projectName)
|
||||
.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);
|
||||
|
||||
getAssignee(mergeRequest)
|
||||
.map(Person::getName)
|
||||
.ifPresent(builder::newAssigneeName);
|
||||
}
|
||||
|
||||
notifyService.send(builder.build());
|
||||
}
|
||||
|
||||
private void personalNotifyAboutUpdate(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
||||
final Long botUserGitlabId = personInformation.getId();
|
||||
if (
|
||||
!botUserGitlabId.equals(mergeRequest.getAuthor().getId()) // Автор MR не пользователь приложения
|
||||
&& !Objects.equals(oldMergeRequest.getDateLastCommit(), mergeRequest.getDateLastCommit())
|
||||
&& !mergeRequest.isConflict() // MR не находится в состоянии конфликта
|
||||
&& !botUserGitlabId.equals(oldMergeRequest.getAuthor().getId()) // и MR создан НЕ пользователем бота
|
||||
) {
|
||||
long allTask = 0;
|
||||
long resolvedTask = 0;
|
||||
long allYouTasks = 0;
|
||||
long resolvedYouTask = 0;
|
||||
|
||||
final List<Discussion> discussions = discussionService.getAllByMergeRequestId(oldMergeRequest.getId());
|
||||
for (Discussion discussion : discussions) {
|
||||
if (checkNotNull(discussion.getResponsible())) {
|
||||
final boolean isBotUserAuthorDiscussion = botUserGitlabId.equals(discussion.getFirstNote().getAuthor().getId());
|
||||
allTask += 1;
|
||||
if (isBotUserAuthorDiscussion) {
|
||||
allYouTasks += 1;
|
||||
}
|
||||
if (TRUE.equals(discussion.getResolved())) {
|
||||
resolvedTask += 1;
|
||||
if (isBotUserAuthorDiscussion) {
|
||||
resolvedYouTask += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final UpdateMrPersonalNotify.UpdateMrPersonalNotifyBuilder notifyBuilder = UpdateMrPersonalNotify.builder()
|
||||
.mrId(oldMergeRequest.getId())
|
||||
.author(oldMergeRequest.getAuthor().getName())
|
||||
.name(oldMergeRequest.getTitle())
|
||||
.projectName(project.getName())
|
||||
.url(oldMergeRequest.getWebUrl())
|
||||
.allTasks(allTask)
|
||||
.milestone(mergeRequest.getMilestone())
|
||||
.allResolvedTasks(resolvedTask)
|
||||
.personTasks(allYouTasks)
|
||||
.personResolvedTasks(resolvedYouTask);
|
||||
|
||||
if (oldMergeRequest.isConflict() && !mergeRequest.isConflict()) {
|
||||
notifyBuilder.comment("The conflict has been resolved");
|
||||
}
|
||||
|
||||
notifyService.send(notifyBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
protected void personalNotifyAboutNewConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
||||
final Long gitlabUserId = personInformation.getId();
|
||||
if (
|
||||
!oldMergeRequest.isConflict() // У старого MR не было конфликта
|
||||
&& mergeRequest.isConflict() // А у нового есть
|
||||
&& gitlabUserId.equals(oldMergeRequest.getAuthor().getId()) // и MR создан пользователем бота
|
||||
) {
|
||||
notifyService.send(
|
||||
ConflictMrPersonalNotify.builder()
|
||||
.mrId(oldMergeRequest.getId())
|
||||
.sourceBranch(oldMergeRequest.getSourceBranch())
|
||||
.name(mergeRequest.getTitle())
|
||||
.url(mergeRequest.getWebUrl())
|
||||
.projectKey(project.getName())
|
||||
.milestone(mergeRequest.getMilestone())
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private void personalNotifyAboutResolveConflict(MergeRequest oldMergeRequest, MergeRequest mergeRequest, Project project) {
|
||||
final Long gitlabUserId = personInformation.getId();
|
||||
if (oldMergeRequest.isConflict() && !mergeRequest.isConflict()) {
|
||||
// проверяем даты коммитов, так как при пуше в target ветку MR у которого есть конфликт, конфликт на время пропадает. Судя по всему GitLab после пуша заново проверяет вероятность конфликта. Чаще всего конфликт никуда не девается.
|
||||
if (Objects.equals(oldMergeRequest.getDateLastCommit(), mergeRequest.getDateLastCommit())) {
|
||||
mergeRequest.setConflict(true);
|
||||
} else {
|
||||
if (gitlabUserId.equals(oldMergeRequest.getAuthor().getId())) {
|
||||
notifyService.send(
|
||||
ConflictResolveMrPersonalNotify.builder()
|
||||
.mrId(oldMergeRequest.getId())
|
||||
.sourceBranch(oldMergeRequest.getSourceBranch())
|
||||
.name(mergeRequest.getTitle())
|
||||
.url(mergeRequest.getWebUrl())
|
||||
.projectKey(project.getName())
|
||||
.milestone(mergeRequest.getMilestone())
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void personalNotifyAboutStatus(MergeRequest oldMergeRequest, MergeRequest newMergeRequest, Project project) {
|
||||
final MergeRequestState oldStatus = oldMergeRequest.getState();
|
||||
final MergeRequestState newStatus = newMergeRequest.getState();
|
||||
final Long gitlabUserId = personInformation.getId();
|
||||
if (
|
||||
!oldStatus.equals(newStatus) // статус изменился
|
||||
&& gitlabUserId.equals(oldMergeRequest.getAuthor().getId()) // создатель MR является пользователем бота
|
||||
) {
|
||||
notifyService.send(
|
||||
StatusMrPersonalNotify.builder()
|
||||
.mrId(oldMergeRequest.getId())
|
||||
.name(newMergeRequest.getTitle())
|
||||
.url(oldMergeRequest.getWebUrl())
|
||||
.projectName(project.getName())
|
||||
.newStatus(newStatus)
|
||||
.oldStatus(oldStatus)
|
||||
.milestone(newMergeRequest.getMilestone())
|
||||
.build()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<Person> getAssignee(MergeRequest mergeRequest) {
|
||||
return Optional.ofNullable(mergeRequest.getAssignee());
|
||||
}
|
||||
|
||||
//TODO [05.12.2022|uPagge]: Добавить уведомление, если происходит удаление
|
||||
|
||||
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)
|
||||
);
|
||||
}
|
||||
}
|
||||
//TODO [05.12.2022|uPagge]: Добавить уведомление, если происходит удаление ревьювера
|
||||
|
||||
private void notifyReviewer(ReviewerChanged reviewerChanged, MergeRequest mergeRequest, Project project) {
|
||||
switch (reviewerChanged) {
|
||||
case BECOME -> sendNotifyNewMrReview(mergeRequest, project.getName());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,138 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.handler;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.PersonInformation;
|
||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
||||
import dev.struchkov.bot.gitlab.context.domain.event.NewPipelineEvent;
|
||||
import dev.struchkov.bot.gitlab.context.domain.event.UpdatePipelineEvent;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.group.pipeline.PipelineGroupNotify;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.pipeline.PipelinePersonalNotify;
|
||||
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
||||
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
||||
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
||||
import dev.struchkov.haiti.utils.Strings;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.CANCELED;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.FAILED;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.SKIPPED;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.SUCCESS;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class PipelineHandler {
|
||||
|
||||
// Статусы пайплайнов, о которых нужно уведомить
|
||||
private static final Set<PipelineStatus> notificationStatus = Set.of(FAILED, SUCCESS, CANCELED, SKIPPED);
|
||||
|
||||
private final PersonService personService;
|
||||
private final PersonInformation personInformation;
|
||||
private final NotifyService notifyService;
|
||||
private final ProjectService projectService;
|
||||
|
||||
@EventListener
|
||||
public void newPipelineHandle(NewPipelineEvent event) {
|
||||
final Pipeline pipeline = event.getPipeline();
|
||||
|
||||
final Optional<String> optProjectName = projectService.getProjectNameById(pipeline.getProjectId())
|
||||
.map(Strings::escapeMarkdown);
|
||||
|
||||
if (isNeedPersonalNotifyPipeline(pipeline)) {
|
||||
final PipelinePersonalNotify.PipelinePersonalNotifyBuilder builder = PipelinePersonalNotify.builder()
|
||||
.newStatus(pipeline.getStatus())
|
||||
.refName(pipeline.getRef())
|
||||
.webUrl(pipeline.getWebUrl())
|
||||
.oldStatus(PipelineStatus.NEW);
|
||||
|
||||
optProjectName.ifPresent(builder::projectName);
|
||||
|
||||
notifyService.send(builder.build());
|
||||
}
|
||||
|
||||
if (isNeedPersonalGroupPipeline(pipeline)) {
|
||||
final Optional<String> optTelegramUsername = personService.getTelegramUsernamesByPersonIds(pipeline.getPerson().getId());
|
||||
if (optTelegramUsername.isPresent()) {
|
||||
final String telegramUsername = optTelegramUsername.get();
|
||||
|
||||
final PipelineGroupNotify.PipelineGroupNotifyBuilder builder = PipelineGroupNotify.builder()
|
||||
.newStatus(pipeline.getStatus())
|
||||
.refName(pipeline.getRef())
|
||||
.webUrl(pipeline.getWebUrl())
|
||||
.oldStatus(PipelineStatus.NEW)
|
||||
.ownerTelegramUsername(telegramUsername);
|
||||
|
||||
optProjectName.ifPresent(builder::projectName);
|
||||
|
||||
notifyService.send(builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EventListener
|
||||
public void updatePipelineHandle(UpdatePipelineEvent event) {
|
||||
final Pipeline oldPipeline = event.getOldPipeline();
|
||||
final Pipeline newPipeline = event.getNewPipeline();
|
||||
if (!Objects.equals(oldPipeline.getUpdated(), newPipeline.getUpdated())) {
|
||||
final Optional<String> optProjectName = projectService.getProjectNameById(newPipeline.getProjectId())
|
||||
.map(Strings::escapeMarkdown);
|
||||
|
||||
if (isNeedPersonalNotifyPipeline(newPipeline)) {
|
||||
final PipelinePersonalNotify.PipelinePersonalNotifyBuilder builder = PipelinePersonalNotify.builder()
|
||||
.newStatus(newPipeline.getStatus())
|
||||
.refName(newPipeline.getRef())
|
||||
.webUrl(newPipeline.getWebUrl())
|
||||
.oldStatus(oldPipeline.getStatus());
|
||||
|
||||
optProjectName.ifPresent(builder::projectName);
|
||||
|
||||
notifyService.send(builder.build());
|
||||
}
|
||||
|
||||
if (isNeedPersonalGroupPipeline(newPipeline)) {
|
||||
final Optional<String> optTelegramUsername = personService.getTelegramUsernamesByPersonIds(newPipeline.getPerson().getId());
|
||||
if (optTelegramUsername.isEmpty()) {
|
||||
final String telegramUsername = optTelegramUsername.get();
|
||||
|
||||
final PipelineGroupNotify.PipelineGroupNotifyBuilder builder = PipelineGroupNotify.builder()
|
||||
.newStatus(newPipeline.getStatus())
|
||||
.refName(newPipeline.getRef())
|
||||
.webUrl(newPipeline.getWebUrl())
|
||||
.oldStatus(oldPipeline.getStatus())
|
||||
.ownerTelegramUsername(telegramUsername);
|
||||
|
||||
optProjectName.ifPresent(builder::projectName);
|
||||
|
||||
notifyService.send(builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNeedPersonalNotifyPipeline(@NonNull Pipeline pipeline) {
|
||||
final Person personPipelineCreator = pipeline.getPerson();
|
||||
return notificationStatus.contains(pipeline.getStatus()) // Пайплайн имеет статус необходимый для уведомления
|
||||
&& checkNotNull(personPipelineCreator) // Создатель пайплайна не null
|
||||
&& personInformation.getId().equals(personPipelineCreator.getId()) // Пользователь приложения является инициатором пайплайна
|
||||
&& LocalDateTime.now().minusDays(1).isBefore(pipeline.getCreated()); // Пайплан был создан не более 24 часов назад
|
||||
}
|
||||
|
||||
private boolean isNeedPersonalGroupPipeline(@NonNull Pipeline pipeline) {
|
||||
final Person personPipelineCreator = pipeline.getPerson();
|
||||
return notificationStatus.contains(pipeline.getStatus()) // Пайплайн имеет статус необходимый для уведомления
|
||||
&& checkNotNull(personPipelineCreator) // Создатель пайплайна не null
|
||||
&& LocalDateTime.now().minusDays(1).isBefore(pipeline.getCreated()); // Пайплан был создан не более 24 часов назад
|
||||
}
|
||||
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.handler;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||
import dev.struchkov.bot.gitlab.context.domain.event.NewProjectEvent;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.project.NewProjectPersonalNotify;
|
||||
import dev.struchkov.bot.gitlab.context.service.NotifyService;
|
||||
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class ProjectHandler {
|
||||
|
||||
private final NotifyService notifyService;
|
||||
private final PersonService personService;
|
||||
|
||||
@EventListener
|
||||
public void handleNewProjectEvent(NewProjectEvent event) {
|
||||
final Project newProject = event.getProject();
|
||||
final String authorName = personService.getByIdOrThrown(newProject.getCreatorId()).getName();
|
||||
notifyService.send(
|
||||
NewProjectPersonalNotify.builder()
|
||||
.projectId(newProject.getId())
|
||||
.projectDescription(newProject.getDescription())
|
||||
.projectName(newProject.getName())
|
||||
.projectUrl(newProject.getWebUrl())
|
||||
.sshUrlToRepo(newProject.getSshUrlToRepo())
|
||||
.httpUrlToRepo(newProject.getHttpUrlToRepo())
|
||||
.authorName(authorName)
|
||||
.build()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
@ -1,185 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.parser;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequestForDiscussion;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
||||
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
||||
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
|
||||
import dev.struchkov.sdk.gitlab.domain.GitlabUrl;
|
||||
import dev.struchkov.sdk.gitlab.schema.note.DiscussionJson;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static dev.struchkov.haiti.utils.Checker.checkFalse;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||
|
||||
/**
|
||||
* Парсер обсуждений.
|
||||
*
|
||||
* @author upagge 11.02.2021
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DiscussionParser {
|
||||
|
||||
public static final int PAGE_COUNT = 100;
|
||||
|
||||
//TODO [23.08.2024|uPagge]: Убрать
|
||||
private final GitlabUrl gitlabUrl;
|
||||
private final GitlabSdkManager gitlabSdkManager;
|
||||
|
||||
private final DiscussionService discussionService;
|
||||
|
||||
private final MergeRequestsService mergeRequestsService;
|
||||
private final ConversionService conversionService;
|
||||
|
||||
|
||||
/**
|
||||
* Поиск новых обсуждений
|
||||
*/
|
||||
public void scanNewDiscussion() {
|
||||
log.debug("Старт обработки новых дискуссий");
|
||||
final List<MergeRequestForDiscussion> mergeRequests = mergeRequestsService.getAllForDiscussion();
|
||||
|
||||
mergeRequests.forEach(this::processingNewDiscussion);
|
||||
|
||||
log.debug("Конец обработки новых дискуссий");
|
||||
}
|
||||
|
||||
private void processingNewDiscussion(MergeRequestForDiscussion mergeRequest) {
|
||||
int page = 1;
|
||||
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, PAGE_COUNT));
|
||||
}
|
||||
createNewDiscussion(discussionJson, mergeRequest);
|
||||
}
|
||||
}
|
||||
|
||||
private void createNewDiscussion(List<DiscussionJson> discussionJson, MergeRequestForDiscussion mergeRequest) {
|
||||
final Set<String> discussionIds = discussionJson.stream()
|
||||
.map(DiscussionJson::getId)
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
|
||||
final ExistContainer<Discussion, String> existContainer = discussionService.existsById(discussionIds);
|
||||
final Set<String> notFoundIds = existContainer.getIdNoFound();
|
||||
if (checkFalse(existContainer.isAllFound())) {
|
||||
final List<Discussion> newDiscussions = discussionJson.stream()
|
||||
.filter(json -> notFoundIds.contains(json.getId()))
|
||||
.map(json -> {
|
||||
final Discussion discussion = conversionService.convert(json, Discussion.class);
|
||||
discussion.setMergeRequest(mergeRequest);
|
||||
discussion.setResponsible(mergeRequest.getAuthor());
|
||||
discussion.getNotes().forEach(createNoteLink(mergeRequest));
|
||||
return discussion;
|
||||
})
|
||||
// Фильтрация специально стоит после map(). Таким образом отбрасываются системные уведомления
|
||||
.filter(discussion -> checkNotEmpty(discussion.getNotes()))
|
||||
.toList();
|
||||
|
||||
if (checkNotEmpty(newDiscussions)) {
|
||||
personMapping(newDiscussions);
|
||||
discussionService.createAll(newDiscussions);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void personMapping(List<Discussion> newDiscussions) {
|
||||
final Stream<Person> firstStream = Stream.concat(
|
||||
newDiscussions.stream()
|
||||
.flatMap(discussion -> discussion.getNotes().stream())
|
||||
.map(Note::getResolvedBy)
|
||||
.filter(Objects::nonNull),
|
||||
newDiscussions.stream()
|
||||
.flatMap(discussion -> discussion.getNotes().stream())
|
||||
.map(Note::getAuthor)
|
||||
.filter(Objects::nonNull)
|
||||
);
|
||||
|
||||
final Map<Long, Person> personMap = Stream.concat(
|
||||
firstStream,
|
||||
newDiscussions.stream()
|
||||
.map(Discussion::getResponsible)
|
||||
.filter(Objects::nonNull)
|
||||
).distinct()
|
||||
.collect(Collectors.toMap(Person::getId, p -> p));
|
||||
|
||||
for (Discussion newDiscussion : newDiscussions) {
|
||||
final Person responsible = newDiscussion.getResponsible();
|
||||
if (checkNotNull(responsible)) {
|
||||
newDiscussion.setResponsible(personMap.get(responsible.getId()));
|
||||
}
|
||||
|
||||
for (Note note : newDiscussion.getNotes()) {
|
||||
note.setAuthor(personMap.get(note.getAuthor().getId()));
|
||||
|
||||
final Person resolvedBy = note.getResolvedBy();
|
||||
if (checkNotNull(resolvedBy)) {
|
||||
note.setResolvedBy(personMap.get(resolvedBy.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Сканирование старых обсуждений на предмет новых комментарие
|
||||
*/
|
||||
public void scanOldDiscussions() {
|
||||
log.debug("Старт обработки старых дискуссий");
|
||||
final List<Discussion> discussions = discussionService.getAll();
|
||||
|
||||
final List<Discussion> newDiscussions = new ArrayList<>();
|
||||
for (Discussion discussion : discussions) {
|
||||
final MergeRequestForDiscussion mergeRequest = discussion.getMergeRequest();
|
||||
if (checkNotNull(mergeRequest)) {
|
||||
gitlabSdkManager.getDiscussionById(mergeRequest.getProjectId(), mergeRequest.getTwoId(), discussion.getId())
|
||||
.map(json -> {
|
||||
final Discussion newDiscussion = conversionService.convert(json, Discussion.class);
|
||||
newDiscussion.getNotes().forEach(createNoteLink(mergeRequest));
|
||||
return newDiscussion;
|
||||
}).ifPresent(newDiscussions::add);
|
||||
} else {
|
||||
discussionService.deleteById(discussion.getId());
|
||||
}
|
||||
}
|
||||
|
||||
if (checkNotEmpty(newDiscussions)) {
|
||||
personMapping(newDiscussions);
|
||||
discussionService.updateAll(newDiscussions);
|
||||
}
|
||||
|
||||
log.debug("Конец обработки старых дискуссий");
|
||||
}
|
||||
|
||||
private Consumer<Note> createNoteLink(MergeRequestForDiscussion mergeRequest) {
|
||||
return note -> {
|
||||
final String url = MessageFormat.format(
|
||||
gitlabUrl.getNote(),
|
||||
mergeRequest.getWebUrl(),
|
||||
note.getId()
|
||||
);
|
||||
note.setWebUrl(url);
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -1,154 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.parser;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||
import dev.struchkov.bot.gitlab.context.domain.MergeRequestState;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequest;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
||||
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
||||
import dev.struchkov.haiti.utils.container.Pair;
|
||||
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
|
||||
import dev.struchkov.sdk.gitlab.schema.approval.ApprovalJson;
|
||||
import dev.struchkov.sdk.gitlab.schema.mergerequest.MergeRequestJson;
|
||||
import dev.struchkov.sdk.gitlab.schema.repository.CommitJson;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class MergeRequestParser {
|
||||
|
||||
private static final Set<MergeRequestState> OLD_STATUSES = Set.of(
|
||||
MergeRequestState.MERGED, MergeRequestState.OPENED, MergeRequestState.CLOSED
|
||||
);
|
||||
|
||||
private final GitlabSdkManager gitlabSdkManager;
|
||||
|
||||
private final MergeRequestsService mergeRequestsService;
|
||||
private final ProjectService projectService;
|
||||
private final ConversionService conversionService;
|
||||
|
||||
public void parsingOldMergeRequest() {
|
||||
log.debug("Старт обработки старых MR");
|
||||
final Set<Pair<Long, Long>> existIds = mergeRequestsService.getAllId(OLD_STATUSES).stream()
|
||||
.map(idAndStatusPr -> new Pair<>(idAndStatusPr.getProjectId(), idAndStatusPr.getTwoId()))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
final List<MergeRequest> newMergeRequests = gitlabSdkManager.getAllMergeRequestById(existIds).stream()
|
||||
.map(mergeRequestJson -> {
|
||||
final MergeRequest newMergeRequest = conversionService.convert(mergeRequestJson, MergeRequest.class);
|
||||
parsingCommits(newMergeRequest);
|
||||
parsingApprovals(newMergeRequest);
|
||||
return newMergeRequest;
|
||||
})
|
||||
.collect(toList());
|
||||
|
||||
if (checkNotEmpty(newMergeRequests)) {
|
||||
personMapping(newMergeRequests);
|
||||
mergeRequestsService.updateAll(newMergeRequests);
|
||||
}
|
||||
log.debug("Конец обработки старых MR");
|
||||
}
|
||||
|
||||
public void parsingNewMergeRequest() {
|
||||
log.debug("Старт обработки новых MR");
|
||||
final Set<Long> projectIds = projectService.getAllIdByProcessingEnable();
|
||||
|
||||
final List<MergeRequestJson> mergeRequestJsons = gitlabSdkManager.getAllMergeRequestByProjectIds(projectIds);
|
||||
|
||||
if (checkNotEmpty(mergeRequestJsons)) {
|
||||
final Set<Long> jsonIds = mergeRequestJsons.stream()
|
||||
.map(MergeRequestJson::getId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
final ExistContainer<MergeRequest, Long> existContainer = mergeRequestsService.existsById(jsonIds);
|
||||
log.trace("Из {} полученных MR не найдены в хранилище {}", jsonIds.size(), existContainer.getIdNoFound().size());
|
||||
if (!existContainer.isAllFound()) {
|
||||
final List<MergeRequest> newMergeRequests = mergeRequestJsons.stream()
|
||||
.filter(json -> existContainer.getIdNoFound().contains(json.getId()))
|
||||
.map(json -> {
|
||||
final MergeRequest mergeRequest = conversionService.convert(json, MergeRequest.class);
|
||||
parsingCommits(mergeRequest);
|
||||
parsingApprovals(mergeRequest);
|
||||
return mergeRequest;
|
||||
})
|
||||
.toList();
|
||||
|
||||
personMapping(newMergeRequests);
|
||||
|
||||
log.trace("Пачка новых MR обработана и отправлена на сохранение. Количество: {} шт.", newMergeRequests.size());
|
||||
mergeRequestsService.createAll(newMergeRequests);
|
||||
}
|
||||
}
|
||||
|
||||
log.debug("Конец обработки новых MR");
|
||||
}
|
||||
|
||||
|
||||
private static void personMapping(List<MergeRequest> newMergeRequests) {
|
||||
final Map<Long, Person> personMap = Stream.concat(
|
||||
newMergeRequests.stream()
|
||||
.flatMap(mergeRequest -> Stream.of(mergeRequest.getAssignee(), mergeRequest.getAuthor())),
|
||||
newMergeRequests.stream()
|
||||
.flatMap(mergeRequest -> Stream.concat(mergeRequest.getReviewers().stream(), mergeRequest.getApprovals().stream()))
|
||||
).distinct()
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(Person::getId, p -> p));
|
||||
|
||||
for (MergeRequest newMergeRequest : newMergeRequests) {
|
||||
newMergeRequest.setAuthor(personMap.get(newMergeRequest.getAuthor().getId()));
|
||||
|
||||
final Person assignee = newMergeRequest.getAssignee();
|
||||
if (checkNotNull(assignee)) {
|
||||
newMergeRequest.setAssignee(personMap.get(assignee.getId()));
|
||||
}
|
||||
|
||||
newMergeRequest.setReviewers(
|
||||
newMergeRequest.getReviewers().stream()
|
||||
.map(reviewer -> personMap.get(reviewer.getId()))
|
||||
.collect(toList())
|
||||
);
|
||||
|
||||
newMergeRequest.setApprovals(
|
||||
newMergeRequest.getApprovals().stream()
|
||||
.map(approval -> personMap.get(approval.getId()))
|
||||
.collect(toList())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO [19.01.2024|uPagge]: Переделать в многопоточный режим
|
||||
private void parsingCommits(MergeRequest mergeRequest) {
|
||||
final List<CommitJson> commitJson = gitlabSdkManager.getAllCommitByProjectId(mergeRequest.getProjectId(), mergeRequest.getTwoId());
|
||||
if (checkNotEmpty(commitJson)) {
|
||||
mergeRequest.setDateLastCommit(commitJson.get(0).getCreatedDate());
|
||||
}
|
||||
}
|
||||
|
||||
//TODO [19.01.2024|uPagge]: Переделать в многопоточный режим
|
||||
private void parsingApprovals(MergeRequest mergeRequest) {
|
||||
final List<Person> personApprovals = gitlabSdkManager.getAllApprovalForMergeRequest(mergeRequest.getProjectId(), mergeRequest.getTwoId()).stream()
|
||||
.map(ApprovalJson::getUser)
|
||||
.map(personJson -> conversionService.convert(personJson, Person.class))
|
||||
.collect(toList());
|
||||
|
||||
if (checkNotEmpty(personApprovals)) {
|
||||
mergeRequest.setApprovals(personApprovals);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.parser;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||
import dev.struchkov.bot.gitlab.context.domain.PipelineStatus;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Pipeline;
|
||||
import dev.struchkov.bot.gitlab.context.service.PipelineService;
|
||||
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
||||
import dev.struchkov.haiti.utils.container.Pair;
|
||||
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
|
||||
import dev.struchkov.sdk.gitlab.schema.pipeline.PipelineShortJson;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.CREATED;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.MANUAL;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.PENDING;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.PREPARING;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.RUNNING;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.PipelineStatus.WAITING_FOR_RESOURCE;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkFalse;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
/**
|
||||
* Парсер пайплайнов.
|
||||
*
|
||||
* @author upagge 17.01.2021
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class PipelineParser {
|
||||
|
||||
private static final Set<PipelineStatus> oldSOLD_STATUSES = Set.of(
|
||||
CREATED, WAITING_FOR_RESOURCE, PREPARING, PENDING, RUNNING, MANUAL
|
||||
);
|
||||
|
||||
private final GitlabSdkManager gitlabSdkManager;
|
||||
|
||||
private final PipelineService pipelineService;
|
||||
private final ProjectService projectService;
|
||||
private final ConversionService conversionService;
|
||||
|
||||
private LocalDateTime lastUpdate = LocalDateTime.now();
|
||||
|
||||
public void scanNewPipeline() {
|
||||
log.debug("Старт обработки новых пайплайнов");
|
||||
final Set<Long> projectIds = projectService.getAllIdByProcessingEnable();
|
||||
|
||||
final Map<Long, Long> pipelineProjectMap = getPipelineShortJsons(projectIds).stream()
|
||||
.collect(toMap(PipelineShortJson::getId, PipelineShortJson::getProjectId));
|
||||
|
||||
if (checkNotEmpty(pipelineProjectMap)) {
|
||||
final ExistContainer<Pipeline, Long> existContainer = pipelineService.existsById(pipelineProjectMap.keySet());
|
||||
|
||||
if (checkFalse(existContainer.isAllFound())) {
|
||||
final Set<Pair<Long, Long>> idsNotFound = existContainer.getIdNoFound().stream()
|
||||
.map(pipelineId -> new Pair<>(pipelineProjectMap.get(pipelineId), pipelineId))
|
||||
.collect(toSet());
|
||||
|
||||
final List<Pipeline> newPipelines = gitlabSdkManager.getAllPipelineForProject(idsNotFound).stream()
|
||||
.map(json -> conversionService.convert(json, Pipeline.class))
|
||||
.collect(Collectors.toList());
|
||||
;
|
||||
|
||||
if (checkNotEmpty(newPipelines)) {
|
||||
pipelineService.createAll(newPipelines);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
log.debug("Конец обработки новых пайплайнов");
|
||||
}
|
||||
|
||||
private List<PipelineShortJson> getPipelineShortJsons(Set<Long> projectIds) {
|
||||
final LocalDateTime newLastUpdate = LocalDateTime.now();
|
||||
final List<PipelineShortJson> pipelineJsons = gitlabSdkManager.getAllPipeline(projectIds, lastUpdate.minusHours(12L));
|
||||
lastUpdate = newLastUpdate;
|
||||
return pipelineJsons;
|
||||
}
|
||||
|
||||
public void scanOldPipeline() {
|
||||
log.debug("Старт обработки старых пайплайнов");
|
||||
final List<Pipeline> pipelines = pipelineService.getAllByStatuses(oldSOLD_STATUSES);
|
||||
|
||||
final List<Pipeline> newPipelines = gitlabSdkManager.getAllPipelineForProject(
|
||||
pipelines.stream()
|
||||
.map(pipeline -> new Pair<>(pipeline.getProjectId(), pipeline.getId()))
|
||||
.collect(toSet())
|
||||
).stream()
|
||||
.map(json -> conversionService.convert(json, Pipeline.class))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
if (checkNotEmpty(newPipelines)) {
|
||||
pipelineService.updateAll(newPipelines);
|
||||
}
|
||||
|
||||
log.debug("Конец обработки старых пайплайнов");
|
||||
}
|
||||
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.parser;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Project;
|
||||
import dev.struchkov.bot.gitlab.context.service.PersonService;
|
||||
import dev.struchkov.bot.gitlab.context.service.ProjectService;
|
||||
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
|
||||
import dev.struchkov.sdk.gitlab.domain.GitlabProjectParam;
|
||||
import dev.struchkov.sdk.gitlab.schema.repository.ProjectJson;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dev.struchkov.haiti.context.exception.ConvertException.convertException;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||
|
||||
/**
|
||||
* Парсер проектов.
|
||||
*
|
||||
* @author upagge 14.01.2021
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ProjectParser {
|
||||
|
||||
private final GitlabSdkManager gitlabSdkManager;
|
||||
private final ConversionService conversionService;
|
||||
|
||||
private final ProjectService projectService;
|
||||
private final PersonService personService;
|
||||
|
||||
|
||||
public void parseAllProjectOwner() {
|
||||
log.debug("Старт обработки всех проектов, где пользователь владелец");
|
||||
parseProjects(GitlabProjectParam.OWNER);
|
||||
log.debug("Конец обработки всех проектов, где пользователь владелец");
|
||||
}
|
||||
|
||||
public void parseAllPrivateProject() {
|
||||
log.debug("Старт обработки приватных проектов");
|
||||
parseProjects(GitlabProjectParam.PRIVATE);
|
||||
log.debug("Конец обработки приватных проектов");
|
||||
}
|
||||
|
||||
private void parseProjects(GitlabProjectParam param) {
|
||||
int page = 1;
|
||||
List<ProjectJson> projectJsons = gitlabSdkManager.getAllProject(page, param);
|
||||
|
||||
while (checkNotEmpty(projectJsons)) {
|
||||
|
||||
final Set<Long> projectIds = projectJsons.stream()
|
||||
.map(ProjectJson::getId)
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
|
||||
createNewPersons(projectJsons);
|
||||
|
||||
final ExistContainer<Project, Long> existContainer = projectService.existsById(projectIds);
|
||||
final List<Project> newProjects = projectJsons.stream()
|
||||
.filter(json -> existContainer.getIdNoFound().contains(json.getId()))
|
||||
.map(json -> conversionService.convert(json, Project.class))
|
||||
.toList();
|
||||
|
||||
if (checkNotEmpty(newProjects)) {
|
||||
projectService.createAll(newProjects);
|
||||
}
|
||||
|
||||
projectJsons = gitlabSdkManager.getAllProject(++page, param);
|
||||
}
|
||||
}
|
||||
|
||||
public Project parseByUrl(String projectUrl) {
|
||||
final ProjectJson projectJson = gitlabSdkManager.getProjectByUrl(projectUrl)
|
||||
.orElseThrow(convertException("Error adding a repository"));
|
||||
if (!projectService.existsById(projectJson.getId())) {
|
||||
createNewPersons(List.of(projectJson));
|
||||
final Project newProject = conversionService.convert(projectJson, Project.class);
|
||||
return projectService.create(newProject, false);
|
||||
} else {
|
||||
return projectService.getByIdOrThrow(projectJson.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private void createNewPersons(List<ProjectJson> projectJsons) {
|
||||
final Set<Long> personCreatorId = projectJsons.stream()
|
||||
.map(ProjectJson::getCreatorId)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
final ExistContainer<Person, Long> existContainer = personService.existsById(personCreatorId);
|
||||
|
||||
if (!existContainer.isAllFound()) {
|
||||
final Collection<Long> notFoundId = existContainer.getIdNoFound();
|
||||
|
||||
final List<Person> newPersons = notFoundId.stream()
|
||||
.map(
|
||||
userId -> gitlabSdkManager.getPersonById(userId)
|
||||
.map(json -> conversionService.convert(json, Person.class))
|
||||
.orElseThrow(convertException("Ошибка преобразования нового пользователя"))
|
||||
).toList();
|
||||
|
||||
personService.createAll(newPersons);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.service;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.AppSetting;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel;
|
||||
import dev.struchkov.bot.gitlab.context.repository.AppSettingRepository;
|
||||
import dev.struchkov.bot.gitlab.context.service.AppSettingService;
|
||||
import dev.struchkov.haiti.context.exception.NotFoundException;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
||||
|
||||
/**
|
||||
* Сервис отвечает за пользовательские настройки приложения.
|
||||
*
|
||||
* @author upagge 16.01.2021
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class AppSettingServiceImpl implements AppSettingService {
|
||||
|
||||
private static final Long KEY = 1L;
|
||||
public static final Supplier<NotFoundException> NOT_FOUND_SETTINGS = notFoundException("Ошибка, невозможно найти настройки приложения, проверьте базу данных.");
|
||||
private final AppSettingRepository appSettingRepository;
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public boolean isFirstStart() {
|
||||
return getAppSetting().isFirstStart();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void disableFirstStart() {
|
||||
final AppSetting appSetting = getAppSetting();
|
||||
appSetting.setFirstStart(false);
|
||||
log.info("Первичная настройка закончена");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public boolean isEnableAllNotify() {
|
||||
return getAppSetting().isEnableNotify();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void turnOnAllNotify() {
|
||||
final AppSetting appSetting = getAppSetting();
|
||||
appSetting.setEnableNotify(true);
|
||||
log.info("Получение всех уведомлений активировано");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void privateProjectScan(boolean enable) {
|
||||
final AppSetting appSetting = getAppSetting();
|
||||
appSetting.setProjectPrivateScan(enable);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void ownerProjectScan(boolean enable) {
|
||||
final AppSetting appSetting = getAppSetting();
|
||||
appSetting.setProjectOwnerScan(enable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isOwnerProjectScan() {
|
||||
return getAppSetting().isProjectOwnerScan();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPrivateProjectScan() {
|
||||
return getAppSetting().isProjectPrivateScan();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiscussionLevel getLevelDiscussionNotify() {
|
||||
return getAppSetting().getDiscussionNotifyLevel();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void setDiscussionLevel(DiscussionLevel level) {
|
||||
final AppSetting appSetting = getAppSetting();
|
||||
appSetting.setDiscussionNotifyLevel(level);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public UUID getServiceKey() {
|
||||
final AppSetting appSetting = getAppSetting();
|
||||
if (appSetting.getServiceKey() == null) {
|
||||
appSetting.setServiceKey(UUID.randomUUID());
|
||||
}
|
||||
return appSetting.getServiceKey();
|
||||
}
|
||||
|
||||
private AppSetting getAppSetting() {
|
||||
return appSettingRepository.findById(KEY)
|
||||
.orElseThrow(NOT_FOUND_SETTINGS);
|
||||
}
|
||||
|
||||
}
|
@ -1,174 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.service;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.ExistContainer;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Discussion;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.MergeRequestForDiscussion;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Person;
|
||||
import dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel;
|
||||
import dev.struchkov.bot.gitlab.context.repository.DiscussionRepository;
|
||||
import dev.struchkov.bot.gitlab.context.service.AppSettingService;
|
||||
import dev.struchkov.bot.gitlab.context.service.DiscussionService;
|
||||
import dev.struchkov.sdk.gitlab.core.GitlabSdkManager;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.event.NewDiscussionEvent.newDiscussion;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.event.UpdateDiscussionEvent.updateDiscussion;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.notify.level.DiscussionLevel.WITHOUT_NOTIFY;
|
||||
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotNull;
|
||||
|
||||
/**
|
||||
* Сервис для работы с дискуссиями.
|
||||
*
|
||||
* @author upagge 11.02.2021
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class DiscussionServiceImpl implements DiscussionService {
|
||||
|
||||
private final DiscussionRepository repository;
|
||||
|
||||
private final AppSettingService settingService;
|
||||
private final GitlabSdkManager gitlabSdkManager;
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Discussion create(@NonNull Discussion discussion) {
|
||||
|
||||
final DiscussionLevel levelDiscussionNotify = settingService.getLevelDiscussionNotify();
|
||||
if (!WITHOUT_NOTIFY.equals(levelDiscussionNotify)) {
|
||||
discussion.setNotification(true);
|
||||
|
||||
eventPublisher.publishEvent(newDiscussion(discussion));
|
||||
} else {
|
||||
discussion.setNotification(false);
|
||||
}
|
||||
|
||||
final boolean resolved = discussion.getNotes().stream()
|
||||
.allMatch(note -> note.isResolvable() && note.getResolved());
|
||||
|
||||
discussion.setResolved(resolved);
|
||||
|
||||
return repository.save(discussion);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public Discussion update(@NonNull Discussion discussion) {
|
||||
final Discussion oldDiscussion = repository.findById(discussion.getId())
|
||||
.orElseThrow(notFoundException("Дискуссия не найдена"));
|
||||
|
||||
discussion.setResponsible(oldDiscussion.getResponsible());
|
||||
discussion.setMergeRequest(oldDiscussion.getMergeRequest());
|
||||
discussion.setNotification(oldDiscussion.isNotification());
|
||||
|
||||
final Person responsiblePerson = discussion.getResponsible();
|
||||
if (checkNotNull(responsiblePerson)) {
|
||||
for (Note note : discussion.getNotes()) {
|
||||
if (responsiblePerson.getId().equals(note.getAuthor().getId())) {
|
||||
note.setAuthor(responsiblePerson);
|
||||
}
|
||||
final Person resolvedBy = note.getResolvedBy();
|
||||
if (checkNotNull(resolvedBy)) {
|
||||
if (responsiblePerson.getId().equals(resolvedBy.getId())) {
|
||||
note.setResolvedBy(responsiblePerson);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final boolean resolved = discussion.getNotes().stream()
|
||||
.allMatch(note -> note.isResolvable() && note.getResolved());
|
||||
discussion.setResolved(resolved);
|
||||
|
||||
eventPublisher.publishEvent(updateDiscussion(oldDiscussion, discussion));
|
||||
|
||||
return repository.save(discussion);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Discussion> updateAll(@NonNull List<Discussion> discussions) {
|
||||
return discussions.stream()
|
||||
.map(this::update)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void answer(@NonNull String discussionId, @NonNull String text) {
|
||||
final Discussion discussion = repository.findById(discussionId)
|
||||
.orElseThrow(notFoundException("Дисскусия {0} не найдена", discussionId));
|
||||
final MergeRequestForDiscussion mergeRequest = discussion.getMergeRequest();
|
||||
final Long projectId = mergeRequest.getProjectId();
|
||||
|
||||
gitlabSdkManager.sendMessageToDiscussion(projectId, mergeRequest.getTwoId(), discussionId, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Discussion> getAllByMergeRequestId(@NonNull Long mergeRequestId) {
|
||||
return repository.findAllByMergeRequestId(mergeRequestId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExistContainer<Discussion, String> existsById(@NonNull Set<String> discussionIds) {
|
||||
final List<Discussion> existsEntity = repository.findAllById(discussionIds);
|
||||
final Set<String> existsIds = existsEntity.stream().map(Discussion::getId).collect(Collectors.toSet());
|
||||
if (existsIds.containsAll(discussionIds)) {
|
||||
return ExistContainer.allFind(existsEntity);
|
||||
} else {
|
||||
final Set<String> noExistsId = discussionIds.stream()
|
||||
.filter(id -> !existsIds.contains(id))
|
||||
.collect(Collectors.toSet());
|
||||
return ExistContainer.notAllFind(existsEntity, noExistsId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Discussion> createAll(@NonNull List<Discussion> newDiscussions) {
|
||||
return newDiscussions.stream()
|
||||
.map(this::create)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Discussion> getAll() {
|
||||
return repository.findAll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAllIds() {
|
||||
return repository.findAllIds();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void deleteById(@NonNull String discussionId) {
|
||||
repository.deleteById(discussionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void cleanOld() {
|
||||
log.debug("Старт очистки старых дискуссий");
|
||||
repository.cleanOld();
|
||||
log.debug("Конец очистки старых дискуссий");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void notification(boolean enable, String discussionId) {
|
||||
repository.notification(enable, discussionId);
|
||||
}
|
||||
|
||||
}
|
@ -1,199 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.service;
|
||||
|
||||
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.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;
|
||||
import dev.struchkov.bot.gitlab.context.repository.MergeRequestRepository;
|
||||
import dev.struchkov.bot.gitlab.context.service.MergeRequestsService;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dev.struchkov.bot.gitlab.context.domain.MergeRequestState.CLOSED;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.MergeRequestState.MERGED;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.event.NewMergeRequestEvent.newMergeRequest;
|
||||
import static dev.struchkov.bot.gitlab.context.domain.event.UpdateMergeRequestEvent.updateMergeRequest;
|
||||
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
||||
import static dev.struchkov.haiti.utils.Checker.checkNotEmpty;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class MergeRequestsServiceImpl implements MergeRequestsService {
|
||||
|
||||
public static final Set<MergeRequestState> DELETE_STATES = Set.of(MERGED, CLOSED);
|
||||
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
|
||||
private final MergeRequestRepository repository;
|
||||
|
||||
private final PersonInformation personInformation;
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public MergeRequest create(@NonNull MergeRequest mergeRequest) {
|
||||
final boolean botUserReviewer = isBotUserReviewer(mergeRequest);
|
||||
final boolean botUserAssignee = isBotUserAssigneeAndNotAuthor(mergeRequest);
|
||||
final boolean botUserAuthor = personInformation.getId().equals(mergeRequest.getAuthor().getId());
|
||||
|
||||
mergeRequest.setNotification(botUserReviewer || botUserAssignee || botUserAuthor);
|
||||
mergeRequest.setUserAssignee(botUserAssignee);
|
||||
mergeRequest.setUserReviewer(botUserReviewer);
|
||||
|
||||
final MergeRequest savedMergeRequest = repository.save(mergeRequest);
|
||||
|
||||
eventPublisher.publishEvent(newMergeRequest(savedMergeRequest));
|
||||
|
||||
return savedMergeRequest;
|
||||
}
|
||||
|
||||
private boolean isBotUserAssigneeAndNotAuthor(MergeRequest mergeRequest) {
|
||||
final Long gitlabUserId = personInformation.getId();
|
||||
final Optional<Person> optAssignee = getAssignee(mergeRequest);
|
||||
final Person author = mergeRequest.getAuthor();
|
||||
|
||||
if (optAssignee.isPresent()) {
|
||||
final Person assignee = optAssignee.get();
|
||||
if (gitlabUserId.equals(assignee.getId()) && !isAuthorSameAssignee(author, assignee)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Создатель MR является ответственным за этот MR
|
||||
*
|
||||
* @return true, если автор и ответственный один и тот же человек.
|
||||
*/
|
||||
private boolean isAuthorSameAssignee(Person author, Person assignee) {
|
||||
return author.getId().equals(assignee.getId());
|
||||
}
|
||||
|
||||
private boolean isBotUserReviewer(MergeRequest savedMergeRequest) {
|
||||
final List<Person> reviewers = savedMergeRequest.getReviewers();
|
||||
final Long botUserGitlabId = personInformation.getId();
|
||||
|
||||
if (checkNotEmpty(reviewers)) {
|
||||
for (Person reviewer : reviewers) {
|
||||
if (botUserGitlabId.equals(reviewer.getId())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public MergeRequest update(@NonNull MergeRequest mergeRequest) {
|
||||
final MergeRequest oldMergeRequest = repository.findById(mergeRequest.getId())
|
||||
.orElseThrow(notFoundException("MergeRequest не найден"));
|
||||
|
||||
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(oldMergeRequest, mergeRequest, assigneeChanged, reviewerChanged, optApprovalChanged)
|
||||
);
|
||||
|
||||
return repository.save(mergeRequest);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public List<MergeRequest> updateAll(@NonNull List<MergeRequest> mergeRequests) {
|
||||
return mergeRequests.stream()
|
||||
.map(this::update)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<IdAndStatusPr> getAllId(Set<MergeRequestState> statuses) {
|
||||
return repository.findAllIdByStateIn(statuses);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MergeRequestForDiscussion> getAllForDiscussion() {
|
||||
return repository.findAllForDiscussion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExistContainer<MergeRequest, Long> existsById(@NonNull Set<Long> mergeRequestIds) {
|
||||
final List<MergeRequest> existsEntity = repository.findAllById(mergeRequestIds);
|
||||
final Set<Long> existsIds = existsEntity.stream().map(MergeRequest::getId).collect(Collectors.toSet());
|
||||
if (existsIds.containsAll(mergeRequestIds)) {
|
||||
return ExistContainer.allFind(existsEntity);
|
||||
} else {
|
||||
final Set<Long> noExistsId = mergeRequestIds.stream()
|
||||
.filter(id -> !existsIds.contains(id))
|
||||
.collect(Collectors.toSet());
|
||||
return ExistContainer.notAllFind(existsEntity, noExistsId);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MergeRequest> createAll(List<MergeRequest> newMergeRequests) {
|
||||
return newMergeRequests.stream()
|
||||
.map(this::create)
|
||||
.toList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MergeRequest> getAllByReviewerId(@NonNull Long personId) {
|
||||
return repository.findAllByReviewerId(personId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanOld() {
|
||||
log.debug("Старт очистки старых MR");
|
||||
repository.deleteByStates(DELETE_STATES);
|
||||
log.debug("Конец очистки старых MR");
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Set<Long> getAllIds() {
|
||||
return repository.findAllIds();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void notification(boolean enable, @NonNull Long mrId) {
|
||||
repository.notification(enable, mrId);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
public void notificationByProjectId(boolean enable, @NonNull Set<Long> projectIds) {
|
||||
repository.notificationByProjectId(enable, projectIds);
|
||||
}
|
||||
|
||||
private Optional<Person> getAssignee(MergeRequest mergeRequest) {
|
||||
return Optional.ofNullable(mergeRequest.getAssignee());
|
||||
}
|
||||
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package dev.struchkov.bot.gitlab.core.service;
|
||||
|
||||
import dev.struchkov.bot.gitlab.context.domain.entity.Note;
|
||||
import dev.struchkov.bot.gitlab.context.repository.NoteRepository;
|
||||
import dev.struchkov.bot.gitlab.context.service.NoteService;
|
||||
import lombok.NonNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class NoteServiceImpl implements NoteService {
|
||||
|
||||
private final NoteRepository noteRepository;
|
||||
|
||||
@Override
|
||||
public Page<Note> getAllByResolved(boolean resolved, @NonNull Pageable pagination) {
|
||||
return noteRepository.findAllByResolved(resolved, pagination);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Note getByIdOrThrow(@NonNull Long noteId) {
|
||||
return noteRepository.findById(noteId)
|
||||
.orElseThrow(notFoundException("Note не найдено"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Note> getAllPersonTask(@NonNull Long userId, boolean resolved) {
|
||||
return noteRepository.findAllByResponsibleIdAndResolved(userId, resolved);
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user