commit dd6d7b56fe908cd3f0347a9cdb5d74cade8a6a91 Author: Struchkov Mark Date: Fri Aug 23 23:37:58 2024 +0300 init commit diff --git a/.drone.yml b/.drone.yml new file mode 100644 index 0000000..7143cc2 --- /dev/null +++ b/.drone.yml @@ -0,0 +1,109 @@ +--- +kind: pipeline +type: docker +name: snapshot-publish + +trigger: + branch: + - develop + +volumes: + - name: m2 + host: + path: /drone/volume/m2 + +steps: + - name: publish + image: hub.docker.struchkov.dev/maven:3.9.5-eclipse-temurin-17-alpine + privileged: true + volumes: + - name: m2 + path: /root/.m2/repository + environment: + MAVEN_SETTINGS: + from_secret: MAVEN_SETTINGS + commands: + - echo "$MAVEN_SETTINGS" >> maven-settings.xml + - mvn --settings maven-settings.xml -U -P snapshot clean deploy + +image_pull_secrets: + - DOCKER_AUTH +--- +kind: pipeline +type: docker +name: release-maven-central + +trigger: + ref: + - refs/tags/v.*.*.* + +volumes: + - name: m2 + host: + path: /drone/volume/m2 + +steps: + - name: publish maven central + image: hub.docker.struchkov.dev/maven:3.9.5-eclipse-temurin-17-alpine + privileged: true + volumes: + - name: m2 + path: /root/.m2/repository + environment: + GPG_PRIVATE_KEY: + from_secret: GPG_PRIVATE_KEY + MAVEN_SETTINGS: + from_secret: MAVEN_SETTINGS + GPG_PASSPHRASE: + from_secret: GPG_PASSPHRASE + commands: + - apk add --no-cache gnupg + - echo "$GPG_PRIVATE_KEY" >> gpg.key + - echo "$MAVEN_SETTINGS" >> maven-settings.xml + - gpg --pinentry-mode loopback --passphrase $GPG_PASSPHRASE --import gpg.key + - mvn --settings maven-settings.xml -U -P ossrh,release clean deploy + +image_pull_secrets: + - DOCKER_AUTH +--- +kind: pipeline +type: docker +name: release-struchkov-nexus + +trigger: + ref: + - refs/tags/v.*.*.* + +volumes: + - name: m2 + host: + path: /drone/volume/m2 + +steps: + - name: publish struchkov nexus + image: hub.docker.struchkov.dev/maven:3.9.5-eclipse-temurin-17-alpine + privileged: true + volumes: + - name: m2 + path: /root/.m2/repository + environment: + GPG_PRIVATE_KEY: + from_secret: GPG_PRIVATE_KEY + MAVEN_SETTINGS: + from_secret: MAVEN_SETTINGS + GPG_PASSPHRASE: + from_secret: GPG_PASSPHRASE + commands: + - apk add --no-cache gnupg + - echo "$GPG_PRIVATE_KEY" >> gpg.key + - echo "$MAVEN_SETTINGS" >> maven-settings.xml + - gpg --pinentry-mode loopback --passphrase $GPG_PASSPHRASE --import gpg.key + - mvn --settings maven-settings.xml -U -P ossrh,release-struchkov-nexus clean deploy + +image_pull_secrets: + - DOCKER_AUTH +--- +kind: signature +hmac: af8e179fe00b1dfd731421af268fcd63b5aa4c78e1552f608e7613e2382bb2d5 + +... diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5ff6309 --- /dev/null +++ b/.gitignore @@ -0,0 +1,38 @@ +target/ +!.mvn/wrapper/maven-wrapper.jar +!**/src/main/**/target/ +!**/src/test/**/target/ + +### IntelliJ IDEA ### +.idea/modules.xml +.idea/jarRepositories.xml +.idea/compiler.xml +.idea/libraries/ +*.iws +*.iml +*.ipr + +### Eclipse ### +.apt_generated +.classpath +.factorypath +.project +.settings +.springBeans +.sts4-cache + +### NetBeans ### +/nbproject/private/ +/nbbuild/ +/dist/ +/nbdist/ +/.nb-gradle/ +build/ +!**/src/main/**/build/ +!**/src/test/**/build/ + +### VS Code ### +.vscode/ + +### Mac OS ### +.DS_Store \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 0000000..b554f7e --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..4cf8858 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,15 @@ + + + + + + + + + + \ No newline at end of file diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml new file mode 100644 index 0000000..2b63946 --- /dev/null +++ b/.idea/uiDesigner.xml @@ -0,0 +1,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..1bf9c5b --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1724441351469 + + + + + + \ No newline at end of file diff --git a/gitlab-core/pom.xml b/gitlab-core/pom.xml new file mode 100644 index 0000000..f88a42d --- /dev/null +++ b/gitlab-core/pom.xml @@ -0,0 +1,54 @@ + + + 4.0.0 + + dev.struchkov.sdk.gitlab + gitlab-sdk + 0.0.1-SNAPSHOT + + + gitlab-core + + + 21 + 21 + UTF-8 + + + + + dev.struchkov.sdk.gitlab + gitlab-schema + + + dev.struchkov.sdk.gitlab + gitlab-domain + + + dev.struchkov.haiti + haiti-utils + + + + org.projectlombok + lombok + + + + com.squareup.okhttp3 + okhttp + + + + + + uPagge + Struchkov Mark + mark@struchkov.dev + https://mark.struchkov.dev + + + + \ No newline at end of file diff --git a/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/GitlabSdkManager.java b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/GitlabSdkManager.java new file mode 100644 index 0000000..d820f78 --- /dev/null +++ b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/GitlabSdkManager.java @@ -0,0 +1,216 @@ +package dev.struchkov.sdk.gitlab.core; + +import dev.struchkov.haiti.utils.container.Pair; +import dev.struchkov.sdk.gitlab.core.client.HttpParse; +import dev.struchkov.sdk.gitlab.core.client.StringUtils; +import dev.struchkov.sdk.gitlab.core.forktask.GetAllMergeRequestForProjectTask; +import dev.struchkov.sdk.gitlab.core.forktask.GetPipelineShortTask; +import dev.struchkov.sdk.gitlab.core.forktask.GetPipelineTask; +import dev.struchkov.sdk.gitlab.core.forktask.GetSingleMergeRequestTask; +import dev.struchkov.sdk.gitlab.domain.GitlabProjectParam; +import dev.struchkov.sdk.gitlab.domain.GitlabProperty; +import dev.struchkov.sdk.gitlab.domain.GitlabUrl; +import dev.struchkov.sdk.gitlab.schema.approval.ApprovalContainerJson; +import dev.struchkov.sdk.gitlab.schema.approval.ApprovalJson; +import dev.struchkov.sdk.gitlab.schema.common.PersonJson; +import dev.struchkov.sdk.gitlab.schema.mergerequest.MergeRequestJson; +import dev.struchkov.sdk.gitlab.schema.note.DiscussionJson; +import dev.struchkov.sdk.gitlab.schema.pipeline.PipelineJson; +import dev.struchkov.sdk.gitlab.schema.pipeline.PipelineShortJson; +import dev.struchkov.sdk.gitlab.schema.repository.CommitJson; +import dev.struchkov.sdk.gitlab.schema.repository.ProjectJson; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import okhttp3.FormBody; +import okhttp3.Request; +import okhttp3.RequestBody; + +import java.io.IOException; +import java.text.MessageFormat; +import java.time.LocalDateTime; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.ForkJoinPool; +import java.util.concurrent.ForkJoinTask; +import java.util.stream.Collectors; + +import static dev.struchkov.haiti.context.exception.NotFoundException.notFoundException; +import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResult; +import static dev.struchkov.haiti.utils.concurrent.ForkJoinUtils.pullTaskResults; +import static dev.struchkov.sdk.gitlab.core.client.HttpParse.ACCEPT; +import static java.util.Collections.emptyList; +import static java.util.stream.Collectors.toList; + +@Slf4j +@RequiredArgsConstructor +public class GitlabSdkManager { + + private final ForkJoinPool forkJoinPool; + private final GitlabUrl gitlabUrl; + private final GitlabProperty gitlabProperty; + + public PersonJson getAuthPerson() { + return HttpParse.request(gitlabUrl.getUser()) + .header(ACCEPT) + .header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken()) + .execute(PersonJson.class) + .orElseThrow(notFoundException("Пользователь не найден")); + } + + public Optional getPersonById(Long userId) { + return HttpParse.request(gitlabUrl.getUsers() + "/" + userId) + .header(ACCEPT) + .header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken()) + .execute(PersonJson.class); + } + + public List getAllProject(int pageNumber, GitlabProjectParam... params) { + String param = Arrays.stream(params) + .map(GitlabProjectParam::getUrl) + .collect(Collectors.joining()); + final String url = MessageFormat.format(gitlabUrl.getProjects(), pageNumber); + return HttpParse.request(url + param) + .header(ACCEPT) + .header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken()) + .executeList(ProjectJson.class); + } + + public Optional getProjectByUrl(String projectUrl) { + return HttpParse.request(projectUrl) + .header(ACCEPT) + .header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken()) + .execute(ProjectJson.class); + } + + /** + * Позволяет получить MR для переданных идентификаторов проектов. + * + * @param projectIds идентификаторы проектов + * @return полученные у GitLab MergeRequests + */ + public List getAllMergeRequestByProjectIds(Set projectIds) { + final List>> tasks = projectIds.stream() + .map(projectId -> new GetAllMergeRequestForProjectTask(projectId, gitlabUrl.getOpenMergeRequests(), gitlabProperty.getAccessToken())) + .map(forkJoinPool::submit) + .collect(Collectors.toList()); + + return pullTaskResults(tasks); + } + + public List getAllCommitByProjectId(Long projectId, Long mergeRequestIdForProject) { + return HttpParse.request( + MessageFormat.format(gitlabUrl.getLastCommitOfMergeRequest(), projectId, mergeRequestIdForProject) + ) + .header(ACCEPT) + .header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken()) + .executeList(CommitJson.class); + } + + public List getAllApprovalForMergeRequest(Long projectId, Long mergeRequestIdForProject) { + return HttpParse.request( + MessageFormat.format(gitlabUrl.getMergeRequestApproval(), projectId, mergeRequestIdForProject) + ) + .header(ACCEPT) + .header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken()) + .execute(ApprovalContainerJson.class) + .map(ApprovalContainerJson::getApprovals) + .orElse(emptyList()); + } + + /** + * projectId + mrTwoId + */ + public List getAllMergeRequestById(Collection> projectIdAndMrIdForProject) { + final List>> tasks = projectIdAndMrIdForProject.stream() + .map( + pair -> new GetSingleMergeRequestTask( + gitlabUrl.getMergeRequest(), + pair.getKey(), + pair.getValue(), + gitlabProperty.getAccessToken() + ) + ).map(forkJoinPool::submit) + .collect(toList()); + + return pullTaskResult(tasks).stream() + .flatMap(Optional::stream) + .collect(toList()); + } + + public List getAllPipelineForProject(Collection> projectIdAndPipelineId) { + final List>> tasks = projectIdAndPipelineId.stream() + .map( + pair -> GetPipelineTask.builder() + .pipelineId(pair.getValue()) + .projectId(pair.getKey()) + .urlPipeline(gitlabUrl.getPipeline()) + .gitlabToken(gitlabProperty.getAccessToken()) + .build() + ) + .map(forkJoinPool::submit) + .collect(Collectors.toList()); + + return pullTaskResult(tasks).stream() + .flatMap(Optional::stream) + .collect(toList()); + } + + public List getAllPipeline(Collection projectIds, LocalDateTime updatedAfter) { + final List>> tasks = projectIds.stream() + .map(projectId -> new GetPipelineShortTask( + gitlabUrl.getPipelines(), + projectId, + updatedAfter, + gitlabProperty.getAccessToken() + )) + .map(forkJoinPool::submit) + .collect(Collectors.toList()); + + return pullTaskResults(tasks); + } + + public List getDiscussionForMergeRequest(Long projectId, Long mergeRequestIdForProject, int pageNumber) { + return HttpParse.request(MessageFormat.format(gitlabUrl.getDiscussions(), projectId, mergeRequestIdForProject, pageNumber, pageNumber)) + .header(ACCEPT) + .header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken()) + .executeList(DiscussionJson.class); + } + + public Optional getDiscussionById(Long projectId, Long mergeRequestIdForProject, String discussionId) { + return HttpParse.request(createLinkOldDiscussion(projectId, mergeRequestIdForProject, discussionId)) + .header(ACCEPT) + .header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken()) + .execute(DiscussionJson.class); + } + + private String createLinkOldDiscussion(Long projectId, Long mergeRequestIdForProject, String discussionId) { + return MessageFormat.format( + gitlabUrl.getDiscussion(), + projectId, + mergeRequestIdForProject, + discussionId + ); + } + + public void sendMessageToDiscussion(Long projectId, Long mergeRequestIdForProject, String discussionId, String message) { + final String requestUrl = MessageFormat.format(gitlabUrl.getNewNote(), projectId, mergeRequestIdForProject, discussionId, message); + + final RequestBody formBody = new FormBody.Builder().build(); + + final Request request = new Request.Builder() + .post(formBody) + .header(StringUtils.H_PRIVATE_TOKEN, gitlabProperty.getAccessToken()) + .url(requestUrl) + .build(); + try { + HttpParse.getNewClient().newCall(request).execute(); + } catch (IOException e) { + log.error(e.getMessage(), e); + } + } + + +} diff --git a/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/HttpHeader.java b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/HttpHeader.java new file mode 100644 index 0000000..e7e5dc3 --- /dev/null +++ b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/HttpHeader.java @@ -0,0 +1,33 @@ +package dev.struchkov.sdk.gitlab.core.client; + +import dev.struchkov.haiti.utils.Inspector; + +/** + * Утилитарная сущность для {@link HttpParse}. Упрощает сохранения в константы заголовков для запроса. + * + * @author upagge 23.12.2020 + */ +public class HttpHeader { + + private final String name; + private final String value; + + private HttpHeader(String name, String value) { + this.name = name; + this.value = value; + } + + public static HttpHeader of(String name, String value) { + Inspector.isNotNull(name, value); + return new HttpHeader(name, value); + } + + public String getName() { + return name; + } + + public String getValue() { + return value; + } + +} diff --git a/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/HttpParse.java b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/HttpParse.java new file mode 100644 index 0000000..c5b5dea --- /dev/null +++ b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/HttpParse.java @@ -0,0 +1,121 @@ +package dev.struchkov.sdk.gitlab.core.client; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import dev.struchkov.haiti.utils.Checker; +import dev.struchkov.haiti.utils.Inspector; +import okhttp3.HttpUrl; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.ResponseBody; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +/** + * Утилитарный класс для работы с web. + * + * @author upagge 30.09.2020 + */ +public class HttpParse { + + private static final Logger log = LoggerFactory.getLogger(HttpParse.class); + + public static final HttpHeader ACCEPT = HttpHeader.of("Accept", "text/html,application/xhtml+xml,application/json"); + + private static final ObjectMapper objectMapper; + + private final Request.Builder requestBuilder = new Request.Builder(); + private final HttpUrl.Builder httpUrlBuilder; + + static { + objectMapper = new ObjectMapper(); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + + public HttpParse(String url) { + Inspector.isNotNull(url); + httpUrlBuilder = HttpUrl.parse(url).newBuilder(); + } + + public static HttpParse request(String url) { + Inspector.isNotNull(url); + return new HttpParse(url); + } + + public HttpParse header(String name, String value) { + Inspector.isNotNull(name); + if (value != null) { + requestBuilder.header(name, value); + } + return this; + } + + public HttpParse header(HttpHeader header) { + Inspector.isNotNull(header); + requestBuilder.header(header.getName(), header.getValue()); + return this; + } + + public HttpParse getParameter(String name, String value) { + Inspector.isNotNull(name); + if (value != null) { + httpUrlBuilder.addQueryParameter(name, value); + } + return this; + } + + public Optional execute(Class classOfT) { + Inspector.isNotNull(classOfT); + final HttpUrl url = httpUrlBuilder.build(); + final Request request = requestBuilder.url(url).build(); + log.trace("Выполняется okhttp3 запрос | {}", url); + final OkHttpClient httpClient = getNewClient(); + try (final Response execute = httpClient.newCall(request).execute()) { + log.trace("Запрос выполнен | {}", url); + if (execute.isSuccessful() && Checker.checkNotNull(execute.body())) { + final String string = execute.body().string(); + return Optional.ofNullable(objectMapper.readValue(string, classOfT)); + } + } catch (IOException e) { + log.error("Ошибка выполнения okhttp3", e); + } + return Optional.empty(); + } + + //TODO [16.01.2023|uPagge]: Okhttp Client создается на каждый запрос, что не рационально по потреблению ресурсов и производительности, но позволяет обойти ограничение со стороны гитлаба, при котором один и тот же клиент отбрасывался спустя 1000 запросов. Возможно стоит заменить OkHttp на что-то другое, например, RestTemplate + public List executeList(Class classOfT) { + Inspector.isNotNull(classOfT); + final HttpUrl url = httpUrlBuilder.build(); + final Request request = requestBuilder.url(url).build(); + log.trace("Выполняется okhttp3 запрос | {}", url); + final OkHttpClient httpClient = getNewClient(); + try (Response execute = httpClient.newCall(request).execute()) { + log.trace("Запрос выполнен | {}", url); + ResponseBody body = execute.body(); + if (execute.isSuccessful() && Checker.checkNotNull(body)) { + final String stringBody = body.string(); + final List list = objectMapper.readValue(stringBody, objectMapper.getTypeFactory().constructCollectionType(List.class, classOfT)); + return (list == null || list.isEmpty()) ? Collections.emptyList() : list; + } + } catch (IOException e) { + log.error("Ошибка выполнения okhttp3", e); + } + return Collections.emptyList(); + } + + public static OkHttpClient getNewClient() { + return new OkHttpClient().newBuilder() + .connectTimeout(30, TimeUnit.SECONDS) + .readTimeout(30, TimeUnit.SECONDS) + .writeTimeout(30, TimeUnit.SECONDS) + .build(); + } + +} \ No newline at end of file diff --git a/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/HttpParseNew.java b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/HttpParseNew.java new file mode 100644 index 0000000..772b34b --- /dev/null +++ b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/HttpParseNew.java @@ -0,0 +1,100 @@ +//package dev.struchkov.bot.gitlab.core.utils; +// +//import com.fasterxml.jackson.databind.DeserializationFeature; +//import com.fasterxml.jackson.databind.ObjectMapper; +//import org.slf4j.Logger; +//import org.slf4j.LoggerFactory; +//import org.springframework.http.HttpEntity; +//import org.springframework.http.HttpHeaders; +//import org.springframework.http.HttpMethod; +//import org.springframework.http.ResponseEntity; +//import org.springframework.stereotype.Component; +//import org.springframework.web.client.RestTemplate; +//import org.springframework.web.util.UriComponentsBuilder; +// +//import java.io.IOException; +//import java.util.Collections; +//import java.util.List; +//import java.util.Optional; +// +//@Component +//public class HttpParse { +// +// private static final Logger log = LoggerFactory.getLogger(HttpParse.class); +// private static final ObjectMapper objectMapper; +// +// static { +// objectMapper = new ObjectMapper(); +// objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); +// } +// +// private final RestTemplate restTemplate; +// private final HttpHeaders headers = new HttpHeaders(); +// private UriComponentsBuilder uriBuilder; +// +// public HttpParse(RestTemplate restTemplate) { +// this.restTemplate = restTemplate; +// } +// +// public HttpParse url(String url) { +// this.uriBuilder = UriComponentsBuilder.fromHttpUrl(url); +// return this; +// } +// +// public HttpParse header(String name, String value) { +// if (name != null && value != null) { +// headers.add(name, value); +// } +// return this; +// } +// +// public HttpParse header(HttpHeader header) { +// if (header != null) { +// headers.add(header.getName(), header.getValue()); +// } +// return this; +// } +// +// public HttpParse getParameter(String name, String value) { +// if (name != null && value != null) { +// uriBuilder.queryParam(name, value); +// } +// return this; +// } +// +// public Optional execute(Class classOfT) { +// try { +// String url = uriBuilder.toUriString(); +// log.trace("Выполняется RestTemplate запрос | {}", url); +// HttpEntity entity = new HttpEntity<>(headers); +// ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class); +// log.trace("Запрос выполнен | {}", url); +// if (response.getStatusCode().is2xxSuccessful() && response.hasBody()) { +// String body = response.getBody(); +// return Optional.ofNullable(objectMapper.readValue(body, classOfT)); +// } +// } catch (IOException e) { +// log.error("Ошибка выполнения RestTemplate", e); +// } +// return Optional.empty(); +// } +// +// public List executeList(Class classOfT) { +// try { +// String url = uriBuilder.toUriString(); +// log.trace("Выполняется RestTemplate запрос | {}", url); +// HttpEntity entity = new HttpEntity<>(headers); +// ResponseEntity response = restTemplate.exchange(url, HttpMethod.GET, entity, String.class); +// log.trace("Запрос выполнен | {}", url); +// if (response.getStatusCode().is2xxSuccessful() && response.hasBody()) { +// String body = response.getBody(); +// return objectMapper.readValue(body, objectMapper.getTypeFactory().constructCollectionType(List.class, classOfT)); +// } +// } catch (IOException e) { +// log.error("Ошибка выполнения RestTemplate", e); +// } +// return Collections.emptyList(); +// } +// +//} + diff --git a/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/OkHttpUtil.java b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/OkHttpUtil.java new file mode 100644 index 0000000..f1bb0da --- /dev/null +++ b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/OkHttpUtil.java @@ -0,0 +1,60 @@ +package dev.struchkov.sdk.gitlab.core.client; + +import dev.struchkov.haiti.utils.Exceptions; +import okhttp3.OkHttpClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +public class OkHttpUtil { + + private static final Logger log = LoggerFactory.getLogger(OkHttpUtil.class); + + public OkHttpUtil() { + Exceptions.utilityClass(); + } + + public static void ignoreCertificate(OkHttpClient.Builder builder) { + log.info("Initialising httpUtil with default configuration"); + configureToIgnoreCertificate(builder); + } + + //Setting testMode configuration. If set as testMode, the connection will skip certification check + private static void configureToIgnoreCertificate(OkHttpClient.Builder builder) { + log.warn("Ignore Ssl Certificate"); + try { + + // Create a trust manager that does not validate certificate chains + final TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + @Override + public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) { + } + + @Override + public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) { + } + + @Override + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new java.security.cert.X509Certificate[]{}; + } + } + }; + + final SSLContext sslContext = SSLContext.getInstance("SSL"); + sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); + final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); + + builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]); + builder.hostnameVerifier((hostname, session) -> true); + } catch (Exception e) { + log.warn("Exception while configuring IgnoreSslCertificate" + e, e); + } + } + +} diff --git a/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/StringUtils.java b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/StringUtils.java new file mode 100644 index 0000000..872ca75 --- /dev/null +++ b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/client/StringUtils.java @@ -0,0 +1,16 @@ +package dev.struchkov.sdk.gitlab.core.client; + +import lombok.AccessLevel; +import lombok.NoArgsConstructor; + +/** + * Утилитарный класс для работы со сторками. + * + * @author upagge 29.09.2020 + */ +@NoArgsConstructor(access = AccessLevel.PRIVATE) +public class StringUtils { + + public static final String H_PRIVATE_TOKEN = "PRIVATE-TOKEN"; + +} diff --git a/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetAllDiscussionForMergeRequestTask.java b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetAllDiscussionForMergeRequestTask.java new file mode 100644 index 0000000..a8e0f3d --- /dev/null +++ b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetAllDiscussionForMergeRequestTask.java @@ -0,0 +1,49 @@ +package dev.struchkov.sdk.gitlab.core.forktask; + +import dev.struchkov.sdk.gitlab.core.client.HttpParse; +import dev.struchkov.sdk.gitlab.schema.note.DiscussionJson; +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; + +import java.text.MessageFormat; +import java.util.List; +import java.util.concurrent.RecursiveTask; + +import static dev.struchkov.haiti.utils.Checker.checkNotEmpty; +import static dev.struchkov.sdk.gitlab.core.client.HttpParse.ACCEPT; +import static dev.struchkov.sdk.gitlab.core.client.StringUtils.H_PRIVATE_TOKEN; + +@AllArgsConstructor +@RequiredArgsConstructor +public class GetAllDiscussionForMergeRequestTask extends RecursiveTask> { + + private static final int PAGE_COUNT = 100; + + private final String discussionsUrl; + private final long projectId; + private final long mergeRequestTwoId; + private final String personalGitlabToken; + private int page = 1; + + @Override + @SneakyThrows + protected List compute() { + Thread.sleep(100); + final List jsons = getDiscussionJson(); + if (checkNotEmpty(jsons) && jsons.size() == PAGE_COUNT) { + final var newTask = new GetAllDiscussionForMergeRequestTask(discussionsUrl, projectId, mergeRequestTwoId, personalGitlabToken, page + 1); + newTask.fork(); + jsons.addAll(newTask.join()); + } + return jsons; + } + + private List getDiscussionJson() { + return HttpParse.request(MessageFormat.format(discussionsUrl, projectId, mergeRequestTwoId, page, PAGE_COUNT)) + .header(ACCEPT) + .header(H_PRIVATE_TOKEN, personalGitlabToken) + .executeList(DiscussionJson.class); + } + +} diff --git a/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetAllMergeRequestForProjectTask.java b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetAllMergeRequestForProjectTask.java new file mode 100644 index 0000000..de591ef --- /dev/null +++ b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetAllMergeRequestForProjectTask.java @@ -0,0 +1,52 @@ +package dev.struchkov.sdk.gitlab.core.forktask; + +import dev.struchkov.sdk.gitlab.core.client.HttpParse; +import dev.struchkov.sdk.gitlab.core.client.StringUtils; +import dev.struchkov.sdk.gitlab.schema.mergerequest.MergeRequestJson; +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +import java.text.MessageFormat; +import java.util.List; +import java.util.concurrent.RecursiveTask; + +import static dev.struchkov.haiti.utils.Checker.checkNotEmpty; +import static dev.struchkov.sdk.gitlab.core.client.HttpParse.ACCEPT; + +@Slf4j +@AllArgsConstructor +@RequiredArgsConstructor +public class GetAllMergeRequestForProjectTask extends RecursiveTask> { + + private static final int PAGE_COUNT = 100; + + private final long projectId; + private int pageNumber = 1; + private final String urlMrOpen; + private final String gitlabToken; + + @Override + @SneakyThrows + protected List compute() { + Thread.sleep(100); + final List mergeRequestJsons = getMergeRequestJsons(); + if (checkNotEmpty(mergeRequestJsons) && mergeRequestJsons.size() == PAGE_COUNT) { + final GetAllMergeRequestForProjectTask newTask = new GetAllMergeRequestForProjectTask(projectId, pageNumber + 1, urlMrOpen, gitlabToken); + newTask.fork(); + mergeRequestJsons.addAll(newTask.join()); + } + return mergeRequestJsons; + } + + private List getMergeRequestJsons() { + final List jsons = HttpParse.request(MessageFormat.format(urlMrOpen, projectId, pageNumber, PAGE_COUNT)) + .header(StringUtils.H_PRIVATE_TOKEN, gitlabToken) + .header(ACCEPT) + .executeList(MergeRequestJson.class); + log.trace("Получено {} шт потенциально новых MR для проекта id:'{}' ", jsons.size(), projectId); + return jsons; + } + +} diff --git a/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetPipelineShortTask.java b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetPipelineShortTask.java new file mode 100644 index 0000000..8877073 --- /dev/null +++ b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetPipelineShortTask.java @@ -0,0 +1,55 @@ +package dev.struchkov.sdk.gitlab.core.forktask; + +import dev.struchkov.sdk.gitlab.core.client.HttpParse; +import dev.struchkov.sdk.gitlab.core.client.StringUtils; +import dev.struchkov.sdk.gitlab.schema.pipeline.PipelineShortJson; +import lombok.AllArgsConstructor; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +import java.text.MessageFormat; +import java.time.LocalDateTime; +import java.util.List; +import java.util.concurrent.RecursiveTask; + +import static dev.struchkov.sdk.gitlab.core.client.HttpParse.ACCEPT; + +@Slf4j +@AllArgsConstructor +@RequiredArgsConstructor +public class GetPipelineShortTask extends RecursiveTask> { + + private static final int PAGE_COUNT = 100; + + private final String urlPipelines; + private final long projectId; + private int pageNumber = 1; + private final LocalDateTime lastUpdate; + private final String gitlabToken; + + @Override + @SneakyThrows + protected List compute() { + Thread.sleep(100); + final List jsons = getPipelineJsons(); + if (jsons.size() == PAGE_COUNT) { + final GetPipelineShortTask newTask = new GetPipelineShortTask(urlPipelines, projectId, pageNumber + 1, lastUpdate, gitlabToken); + newTask.fork(); + jsons.addAll(newTask.join()); + } + jsons.forEach(pipelineJson -> pipelineJson.setProjectId(projectId)); + return jsons; + } + + private List getPipelineJsons() { + final List jsons = HttpParse.request(MessageFormat.format(urlPipelines, projectId, pageNumber, PAGE_COUNT)) + .header(ACCEPT) + .header(StringUtils.H_PRIVATE_TOKEN, gitlabToken) + .getParameter("updated_after", lastUpdate.toString()) + .executeList(PipelineShortJson.class); + log.trace("Получено {} шт потенциально новых пайплайнов для проекта id:'{}' ", jsons.size(), projectId); + return jsons; + } + +} diff --git a/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetPipelineTask.java b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetPipelineTask.java new file mode 100644 index 0000000..4f85038 --- /dev/null +++ b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetPipelineTask.java @@ -0,0 +1,45 @@ +package dev.struchkov.sdk.gitlab.core.forktask; + +import dev.struchkov.sdk.gitlab.core.client.HttpParse; +import dev.struchkov.sdk.gitlab.core.client.StringUtils; +import dev.struchkov.sdk.gitlab.schema.pipeline.PipelineJson; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.NoArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +import java.text.MessageFormat; +import java.util.Optional; +import java.util.concurrent.RecursiveTask; + +import static dev.struchkov.sdk.gitlab.core.client.HttpParse.ACCEPT; + + +@Slf4j +@Builder +@NoArgsConstructor +@AllArgsConstructor(access = AccessLevel.PRIVATE) +public class GetPipelineTask extends RecursiveTask> { + + private String urlPipeline; + private long projectId; + private long pipelineId; + private String gitlabToken; + + @Override + @SneakyThrows + protected Optional compute() { + Thread.sleep(100); + return HttpParse.request(MessageFormat.format(urlPipeline, projectId, pipelineId)) + .header(ACCEPT) + .header(StringUtils.H_PRIVATE_TOKEN, gitlabToken) + .execute(PipelineJson.class) + .map(json -> { + json.setProjectId(projectId); + return json; + }); + } + +} diff --git a/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetSingleMergeRequestTask.java b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetSingleMergeRequestTask.java new file mode 100644 index 0000000..f60583d --- /dev/null +++ b/gitlab-core/src/main/java/dev/struchkov/sdk/gitlab/core/forktask/GetSingleMergeRequestTask.java @@ -0,0 +1,36 @@ +package dev.struchkov.sdk.gitlab.core.forktask; + +import dev.struchkov.sdk.gitlab.core.client.HttpParse; +import dev.struchkov.sdk.gitlab.core.client.StringUtils; +import dev.struchkov.sdk.gitlab.schema.mergerequest.MergeRequestJson; +import lombok.RequiredArgsConstructor; +import lombok.SneakyThrows; +import lombok.extern.slf4j.Slf4j; + +import java.text.MessageFormat; +import java.util.Optional; +import java.util.concurrent.RecursiveTask; + +import static dev.struchkov.sdk.gitlab.core.client.HttpParse.ACCEPT; + +@Slf4j +@RequiredArgsConstructor +public class GetSingleMergeRequestTask extends RecursiveTask> { + + private final String urlMr; + private final long projectId; + private final long mrTwoId; + private final String gitlabToken; + + @Override + @SneakyThrows + protected Optional compute() { + Thread.sleep(100); + final String mrUrl = MessageFormat.format(urlMr, projectId, mrTwoId); + return HttpParse.request(mrUrl) + .header(ACCEPT) + .header(StringUtils.H_PRIVATE_TOKEN, gitlabToken) + .execute(MergeRequestJson.class); + } + +} diff --git a/gitlab-domain/pom.xml b/gitlab-domain/pom.xml new file mode 100644 index 0000000..5a12ca0 --- /dev/null +++ b/gitlab-domain/pom.xml @@ -0,0 +1,27 @@ + + + 4.0.0 + + dev.struchkov.sdk.gitlab + gitlab-sdk + 0.0.1-SNAPSHOT + + + gitlab-domain + + + 21 + 21 + UTF-8 + + + + + org.projectlombok + lombok + + + + \ No newline at end of file diff --git a/gitlab-domain/src/main/java/dev/struchkov/sdk/gitlab/domain/GitlabProjectParam.java b/gitlab-domain/src/main/java/dev/struchkov/sdk/gitlab/domain/GitlabProjectParam.java new file mode 100644 index 0000000..6527fbb --- /dev/null +++ b/gitlab-domain/src/main/java/dev/struchkov/sdk/gitlab/domain/GitlabProjectParam.java @@ -0,0 +1,14 @@ +package dev.struchkov.sdk.gitlab.domain; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public enum GitlabProjectParam { + + OWNER("&owned=true"), + PRIVATE("&visibility=private"); + + private final String url; +} diff --git a/gitlab-domain/src/main/java/dev/struchkov/sdk/gitlab/domain/GitlabProperty.java b/gitlab-domain/src/main/java/dev/struchkov/sdk/gitlab/domain/GitlabProperty.java new file mode 100644 index 0000000..ff4e67c --- /dev/null +++ b/gitlab-domain/src/main/java/dev/struchkov/sdk/gitlab/domain/GitlabProperty.java @@ -0,0 +1,21 @@ +package dev.struchkov.sdk.gitlab.domain; + +import lombok.Getter; +import lombok.Setter; + +/** + * Данные необходимые для взаимодействия с API GitLab. + * + * @author upagge [31.01.2020] + */ +@Getter +@Setter +public class GitlabProperty { + + private String baseUrl; + + private String accessToken; + + private String replaceUrl; + +} diff --git a/gitlab-domain/src/main/java/dev/struchkov/sdk/gitlab/domain/GitlabUrl.java b/gitlab-domain/src/main/java/dev/struchkov/sdk/gitlab/domain/GitlabUrl.java new file mode 100644 index 0000000..2e8a1e6 --- /dev/null +++ b/gitlab-domain/src/main/java/dev/struchkov/sdk/gitlab/domain/GitlabUrl.java @@ -0,0 +1,47 @@ +package dev.struchkov.sdk.gitlab.domain; + +import lombok.Getter; + +@Getter +public class GitlabUrl { + + private final String users; + private final String user; + private final String projects; + private final String openMergeRequests; + private final String closeMergeRequests; + private final String commentsOfMergeRequest; + private final String mergeRequest; + private final String mergeRequestApproval; + private final String projectAdd; + private final String note; + private final String noteOfMergeRequest; + private final String pipelines; + private final String pipeline; + private final String lastCommitOfMergeRequest; + private final String newNote; + private final String discussions; + private final String discussion; + + public GitlabUrl(GitlabProperty gitlabProperty) { + final String baseUrl = gitlabProperty.getBaseUrl(); + this.users = baseUrl + "/api/v4/users"; + this.user = baseUrl + "/api/v4/user"; + this.projects = baseUrl + "/api/v4/projects?page={0, number, integer}&per_page=100"; + this.openMergeRequests = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests?state=opened&page={1, number, integer}&per_page={2, number, integer}"; + this.closeMergeRequests = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests?state=closed&page={1, number, integer}&per_page=100"; + this.commentsOfMergeRequest = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/notes?&page={2,number,#}&per_page=100"; + this.mergeRequest = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}"; + this.mergeRequestApproval = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/approvals"; + this.projectAdd = baseUrl + "/api/v4/projects/"; + this.note = baseUrl + "{0}#note_{1,number,#}"; + this.noteOfMergeRequest = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/notes/{2,number,#}"; + this.pipelines = baseUrl + "/api/v4/projects/{0,number,#}/pipelines?&page={1,number,#}&per_page={2,number,#}"; + this.pipeline = baseUrl + "/api/v4/projects/{0,number,#}/pipelines/{1,number,#}"; + this.lastCommitOfMergeRequest = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/commits?&page=1&per_page=1"; + this.newNote = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/discussions/{2}/notes?body={3}"; + this.discussions = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/discussions?&page={2,number,#}&per_page={3,number,#}"; + this.discussion = baseUrl + "/api/v4/projects/{0,number,#}/merge_requests/{1,number,#}/discussions/{2}"; + } + +} diff --git a/gitlab-schema/pom.xml b/gitlab-schema/pom.xml new file mode 100644 index 0000000..2af8ef9 --- /dev/null +++ b/gitlab-schema/pom.xml @@ -0,0 +1,45 @@ + + + 4.0.0 + + dev.struchkov.sdk.gitlab + gitlab-sdk + 0.0.1-SNAPSHOT + + + gitlab-schema + + + 21 + 21 + UTF-8 + + + + + org.projectlombok + lombok + + + com.fasterxml.jackson.core + jackson-databind + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + + + + + + uPagge + Struchkov Mark + mark@struchkov.dev + https://mark.struchkov.dev + + + + \ No newline at end of file diff --git a/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/approval/ApprovalContainerJson.java b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/approval/ApprovalContainerJson.java new file mode 100644 index 0000000..82e120f --- /dev/null +++ b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/approval/ApprovalContainerJson.java @@ -0,0 +1,14 @@ +package dev.struchkov.sdk.gitlab.schema.approval; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.List; + +@Data +public class ApprovalContainerJson { + + @JsonProperty("approved_by") + private List approvals; + +} diff --git a/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/approval/ApprovalJson.java b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/approval/ApprovalJson.java new file mode 100644 index 0000000..381470b --- /dev/null +++ b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/approval/ApprovalJson.java @@ -0,0 +1,11 @@ +package dev.struchkov.sdk.gitlab.schema.approval; + +import dev.struchkov.sdk.gitlab.schema.common.PersonJson; +import lombok.Data; + +@Data +public class ApprovalJson { + + private PersonJson user; + +} diff --git a/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/common/MilestoneJson.java b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/common/MilestoneJson.java new file mode 100644 index 0000000..b049807 --- /dev/null +++ b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/common/MilestoneJson.java @@ -0,0 +1,9 @@ +package dev.struchkov.sdk.gitlab.schema.common; + +import lombok.Data; + +@Data +public class MilestoneJson { + private Long id; + private String title; +} diff --git a/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/common/PersonJson.java b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/common/PersonJson.java new file mode 100644 index 0000000..9d2fe27 --- /dev/null +++ b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/common/PersonJson.java @@ -0,0 +1,19 @@ +package dev.struchkov.sdk.gitlab.schema.common; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * @author upagge [31.01.2020] + */ +@Data +public class PersonJson { + + private Long id; + private String name; + private String username; + + @JsonProperty("web_url") + private String webUrl; + +} diff --git a/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/common/UserJson.java b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/common/UserJson.java new file mode 100644 index 0000000..8a1d4e1 --- /dev/null +++ b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/common/UserJson.java @@ -0,0 +1,14 @@ +package dev.struchkov.sdk.gitlab.schema.common; + +import lombok.Data; + +/** + * @author upagge [31.01.2020] + */ +@Data +public class UserJson { + + private String name; + private String displayName; + +} diff --git a/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/mergerequest/MergeRequestJson.java b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/mergerequest/MergeRequestJson.java new file mode 100644 index 0000000..a9d2ff2 --- /dev/null +++ b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/mergerequest/MergeRequestJson.java @@ -0,0 +1,63 @@ +package dev.struchkov.sdk.gitlab.schema.mergerequest; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import dev.struchkov.sdk.gitlab.schema.common.MilestoneJson; +import dev.struchkov.sdk.gitlab.schema.common.PersonJson; +import lombok.Data; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Set; + +/** + * @author upagge [30.01.2020] + */ +@Data +public class MergeRequestJson { + + private Long id; + + @JsonProperty("iid") + private Long twoId; + + @JsonProperty("project_id") + private Long projectId; + private String title; + private String description; + private MergeRequestStateJson state; + + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonProperty("created_at") + private LocalDateTime createdDate; + + @JsonProperty("updated_at") + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + private LocalDateTime updatedDate; + + private PersonJson author; + private PersonJson assignee; + + private MilestoneJson milestone; + private List reviewers; + + @JsonProperty("web_url") + private String webUrl; + + @JsonProperty("has_conflicts") + private boolean conflicts; + + @JsonProperty("target_branch") + private String targetBranch; + + @JsonProperty("source_branch") + private String sourceBranch; + + private Set labels; + +} diff --git a/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/mergerequest/MergeRequestStateJson.java b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/mergerequest/MergeRequestStateJson.java new file mode 100644 index 0000000..f1e9ba1 --- /dev/null +++ b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/mergerequest/MergeRequestStateJson.java @@ -0,0 +1,19 @@ +package dev.struchkov.sdk.gitlab.schema.mergerequest; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author upagge [01.02.2020] + */ +public enum MergeRequestStateJson { + + @JsonProperty("opened") + OPENED, + @JsonProperty("closed") + CLOSED, + @JsonProperty("locked") + LOCKED, + @JsonProperty("merged") + MERGED + +} diff --git a/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/note/DiscussionJson.java b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/note/DiscussionJson.java new file mode 100644 index 0000000..c1a7e89 --- /dev/null +++ b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/note/DiscussionJson.java @@ -0,0 +1,18 @@ +package dev.struchkov.sdk.gitlab.schema.note; + +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +/** + * @author upagge 11.02.2021 + */ +@Getter +@Setter +public class DiscussionJson { + + private String id; + private List notes; + +} diff --git a/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/note/NoteJson.java b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/note/NoteJson.java new file mode 100644 index 0000000..308d9ab --- /dev/null +++ b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/note/NoteJson.java @@ -0,0 +1,50 @@ +package dev.struchkov.sdk.gitlab.schema.note; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import dev.struchkov.sdk.gitlab.schema.common.PersonJson; +import lombok.Data; + +import java.time.LocalDateTime; + +@Data +public class NoteJson { + + private Long id; + private String type; + private String body; + + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonProperty("created_at") + private LocalDateTime created; + + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonProperty("updated_at") + private LocalDateTime updated; + + private PersonJson author; + private boolean system; + + @JsonProperty("noteable_id") + private Long noteableId; + + @JsonProperty("noteable_type") + private String noteableType; + + private boolean resolvable; + + private Boolean resolved; + + @JsonProperty("resolved_by") + private PersonJson resolvedBy; + + @JsonProperty("noteable_iid") + private Long noteableIid; + + +} diff --git a/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/pipeline/PipelineJson.java b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/pipeline/PipelineJson.java new file mode 100644 index 0000000..8cf9714 --- /dev/null +++ b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/pipeline/PipelineJson.java @@ -0,0 +1,44 @@ +package dev.struchkov.sdk.gitlab.schema.pipeline; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import dev.struchkov.sdk.gitlab.schema.common.PersonJson; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * @author upagge 17.01.2021 + */ +@Data +public class PipelineJson { + + private Long id; + + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonProperty("created_at") + private LocalDateTime created; + + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonProperty("updated_at") + private LocalDateTime updated; + + private PipelineStatusJson status; + + private String ref; + + private PersonJson user; + + @JsonProperty("web_url") + private String webUrl; + + // Поля ниже не отдаются гитлабом, а заполняются вручную + + private Long projectId; + +} diff --git a/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/pipeline/PipelineShortJson.java b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/pipeline/PipelineShortJson.java new file mode 100644 index 0000000..a4fb969 --- /dev/null +++ b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/pipeline/PipelineShortJson.java @@ -0,0 +1,41 @@ +package dev.struchkov.sdk.gitlab.schema.pipeline; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * @author upagge 17.01.2021 + */ +@Data +public class PipelineShortJson { + + private Long id; + + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonProperty("created_at") + private LocalDateTime created; + + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonProperty("updated_at") + private LocalDateTime updated; + + private PipelineStatusJson status; + + private String ref; + + @JsonProperty("web_url") + private String webUrl; + + // Поля ниже не отдаются гитлабом, а заполняются вручную + + private Long projectId; + +} diff --git a/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/pipeline/PipelineStatusJson.java b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/pipeline/PipelineStatusJson.java new file mode 100644 index 0000000..4b71810 --- /dev/null +++ b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/pipeline/PipelineStatusJson.java @@ -0,0 +1,43 @@ +package dev.struchkov.sdk.gitlab.schema.pipeline; + +import com.fasterxml.jackson.annotation.JsonProperty; + +/** + * @author upagge 17.01.2021 + */ +public enum PipelineStatusJson { + + @JsonProperty("created") + CREATED, + + @JsonProperty("waiting_for_resource") + WAITING_FOR_RESOURCE, + + @JsonProperty("preparing") + PREPARING, + + @JsonProperty("pending") + PENDING, + + @JsonProperty("running") + RUNNING, + + @JsonProperty("success") + SUCCESS, + + @JsonProperty("failed") + FAILED, + + @JsonProperty("canceled") + CANCELED, + + @JsonProperty("skipped") + SKIPPED, + + @JsonProperty("manual") + MANUAL, + + @JsonProperty("scheduled") + SCHEDULED + +} diff --git a/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/repository/CommitJson.java b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/repository/CommitJson.java new file mode 100644 index 0000000..5df34c7 --- /dev/null +++ b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/repository/CommitJson.java @@ -0,0 +1,25 @@ +package dev.struchkov.sdk.gitlab.schema.repository; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * @author upagge 19.01.2021 + */ +@Data +public class CommitJson { + + private String id; + + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonProperty("created_at") + private LocalDateTime createdDate; + +} diff --git a/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/repository/ProjectJson.java b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/repository/ProjectJson.java new file mode 100644 index 0000000..b694551 --- /dev/null +++ b/gitlab-schema/src/main/java/dev/struchkov/sdk/gitlab/schema/repository/ProjectJson.java @@ -0,0 +1,39 @@ +package dev.struchkov.sdk.gitlab.schema.repository; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import lombok.Data; + +import java.time.LocalDateTime; + +/** + * @author upagge 14.01.2021 + */ +@Data +public class ProjectJson { + + private Long id; + private String name; + private String description; + + @JsonSerialize(using = LocalDateTimeSerializer.class) + @JsonDeserialize(using = LocalDateTimeDeserializer.class) + @JsonProperty("created_at") + private LocalDateTime createdDate; + + @JsonProperty("web_url") + private String webUrl; + + @JsonProperty("ssh_url_to_repo") + private String sshUrlToRepo; + + @JsonProperty("http_url_to_repo") + private String httpUrlToRepo; + + @JsonProperty("creator_id") + private Long creatorId; + +} diff --git a/gitlab-sdk-spring-boot-starter/pom.xml b/gitlab-sdk-spring-boot-starter/pom.xml new file mode 100644 index 0000000..0c1e2b9 --- /dev/null +++ b/gitlab-sdk-spring-boot-starter/pom.xml @@ -0,0 +1,309 @@ + + + 4.0.0 + + org.springframework.boot + spring-boot-starter-parent + 3.3.3 + + + + dev.struchkov.sdk.gitlab + gitlab-sdk-spring-boot-starter + 0.0.1-SNAPSHOT + + GitLab SDK Spring Boot Starter + Spring Boot GitLab SDK для упрощения вызовов к Gitlab API. + https://git.struchkov.dev/SDK/gitlab-sdk + + + BSD 3-Clause "New" or "Revised" License + https://git.struchkov.dev/SDK/gitlab-sdk/blob/master/LICENSE + + + + + 21 + ${java.version} + ${java.version} + UTF-8 + UTF-8 + + + 1.3.1 + + 1.5.2 + + + 3.13.0 + + 1.7.0 + + 3.3.1 + + 3.8.0 + + 3.2.5 + + 3.1.1 + + + + + dev.struchkov.sdk.gitlab + gitlab-core + 0.0.1-SNAPSHOT + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot + spring-boot-autoconfigure-processor + true + + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + ${plugin.nexus.staging.ver} + true + + + org.apache.maven.plugins + maven-source-plugin + ${plugin.maven.source.ver} + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${plugin.maven.javadoc.ver} + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + ${plugin.maven.gpg.ver} + + + sign-artifacts + verify + + sign + + + + + + org.apache.maven.plugins + maven-compiler-plugin + ${plugin.maven.compiler.ver} + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-release-plugin + ${plugin.maven.release.ver} + + clean install + v.@{project.version} + true + false + true + true + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-release-plugin + + + + + + + release + + + + org.sonatype.plugins + nexus-staging-maven-plugin + + ossrh + https://s01.oss.sonatype.org/ + true + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-gpg-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + + release-struchkov-nexus + + + + org.sonatype.plugins + nexus-staging-maven-plugin + + struchkov-nexus + https://nexus.struchkov.dev/nexus/ + true + true + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-gpg-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + + snapshot + + + + org.sonatype.plugins + nexus-staging-maven-plugin + + struchkov-nexus + https://nexus.struchkov.dev/nexus/ + true + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + + + + + + struchkov-nexus-release + https://nexus.struchkov.dev/repository/maven-releases/ + + true + always + fail + + + false + + + + struchkov-nexus-snapshot + https://nexus.struchkov.dev/repository/maven-snapshots/ + + false + + + true + always + warn + + + + + + + struchkov-nexus-release + https://nexus.struchkov.dev/repository/maven-releases/ + + + struchkov-nexus-snapshot + https://nexus.struchkov.dev/repository/maven-snapshots/ + + + + + scm:git:ssh://git@git.struchkov.dev:222/SDK/gitlab-sdk.git + https://git.struchkov.dev/SDK/gitlab-sdk + scm:git:ssh://git@git.struchkov.dev:222/SDK/gitlab-sdk.git + HEAD + + + + + uPagge + Struchkov Mark + mark@struchkov.dev + https://mark.struchkov.dev + + + + \ No newline at end of file diff --git a/gitlab-sdk-spring-boot-starter/src/main/java/dev/struchkov/sdk/gitlab/spring/starter/GitlabSdkAutoconfiguration.java b/gitlab-sdk-spring-boot-starter/src/main/java/dev/struchkov/sdk/gitlab/spring/starter/GitlabSdkAutoconfiguration.java new file mode 100644 index 0000000..3beb89d --- /dev/null +++ b/gitlab-sdk-spring-boot-starter/src/main/java/dev/struchkov/sdk/gitlab/spring/starter/GitlabSdkAutoconfiguration.java @@ -0,0 +1,24 @@ +package dev.struchkov.sdk.gitlab.spring.starter; + +import dev.struchkov.sdk.gitlab.core.GitlabSdkManager; +import dev.struchkov.sdk.gitlab.domain.GitlabProperty; +import dev.struchkov.sdk.gitlab.domain.GitlabUrl; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.util.concurrent.ForkJoinPool; + +@Configuration +@AutoConfigureAfter(GitlabSdkPropertyAutoconfiguration.class) +public class GitlabSdkAutoconfiguration { + + @Bean + public GitlabSdkManager gitlabSdkManager( + ForkJoinPool forkJoinPool, GitlabUrl gitlabUrl, GitlabProperty gitlabProperty + + ) { + return new GitlabSdkManager(forkJoinPool, gitlabUrl, gitlabProperty); + } + +} diff --git a/gitlab-sdk-spring-boot-starter/src/main/java/dev/struchkov/sdk/gitlab/spring/starter/GitlabSdkPropertyAutoconfiguration.java b/gitlab-sdk-spring-boot-starter/src/main/java/dev/struchkov/sdk/gitlab/spring/starter/GitlabSdkPropertyAutoconfiguration.java new file mode 100644 index 0000000..ecc27f4 --- /dev/null +++ b/gitlab-sdk-spring-boot-starter/src/main/java/dev/struchkov/sdk/gitlab/spring/starter/GitlabSdkPropertyAutoconfiguration.java @@ -0,0 +1,27 @@ +package dev.struchkov.sdk.gitlab.spring.starter; + +import dev.struchkov.sdk.gitlab.domain.GitlabProperty; +import dev.struchkov.sdk.gitlab.domain.GitlabUrl; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class GitlabSdkPropertyAutoconfiguration { + + @Bean + @ConfigurationProperties("gitlab-sdk") + @ConditionalOnProperty(prefix = "gitlab-sdk", name = "access-token") + public GitlabProperty gitlabProperty() { + return new GitlabProperty(); + } + + @Bean + @ConditionalOnBean(GitlabProperty.class) + public GitlabUrl gitlabUrl(GitlabProperty gitlabProperty) { + return new GitlabUrl(gitlabProperty); + } + +} diff --git a/gitlab-sdk-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/gitlab-sdk-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports new file mode 100644 index 0000000..b397382 --- /dev/null +++ b/gitlab-sdk-spring-boot-starter/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports @@ -0,0 +1,2 @@ +dev.struchkov.sdk.gitlab.spring.starter.GitlabSdkPropertyAutoconfiguration +dev.struchkov.sdk.gitlab.spring.starter.GitlabSdkAutoconfiguration \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..1eaebc3 --- /dev/null +++ b/pom.xml @@ -0,0 +1,329 @@ + + + 4.0.0 + + dev.struchkov.sdk.gitlab + gitlab-sdk + 0.0.1-SNAPSHOT + pom + + gitlab-schema + gitlab-domain + gitlab-core + + + GitLab SDK + SDK для упрощения вызовов к Gitlab API. + https://git.struchkov.dev/SDK/gitlab-sdk + + + BSD 3-Clause "New" or "Revised" License + https://git.struchkov.dev/SDK/gitlab-sdk/blob/master/LICENSE + + + + + 17 + ${java.version} + ${java.version} + UTF-8 + UTF-8 + + + 3.13.0 + + 1.7.0 + + 3.3.1 + + 3.7.0 + + 3.2.4 + + 3.1.0 + + + + + + dev.struchkov.sdk.gitlab + gitlab-schema + ${project.version} + + + dev.struchkov.sdk.gitlab + gitlab-domain + ${project.version} + + + + org.projectlombok + lombok + 1.18.34 + + + + com.fasterxml.jackson.core + jackson-databind + 2.17.2 + + + + + com.fasterxml.jackson.datatype + jackson-datatype-jsr310 + 2.17.2 + + + + + com.squareup.okhttp3 + okhttp + 4.12.0 + + + + + dev.struchkov.haiti + haiti-utils + 3.0.3 + + + + + + + + + + org.sonatype.plugins + nexus-staging-maven-plugin + ${plugin.nexus.staging.ver} + true + + + org.apache.maven.plugins + maven-compiler-plugin + ${plugin.maven.compiler.ver} + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-source-plugin + ${plugin.maven.source.ver} + + + attach-sources + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + ${plugin.maven.javadoc.ver} + + + attach-javadocs + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + ${plugin.maven.gpg.ver} + + + sign-artifacts + verify + + sign + + + + + + org.apache.maven.plugins + maven-release-plugin + ${plugin.maven.release.ver} + + clean install + v.@{project.version} + true + false + true + true + + + + + + + + org.apache.maven.plugins + maven-release-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-source-plugin + + + + + + + release + + + + org.sonatype.plugins + nexus-staging-maven-plugin + + ossrh + https://s01.oss.sonatype.org/ + true + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-gpg-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + + release-struchkov-nexus + + + + org.sonatype.plugins + nexus-staging-maven-plugin + + struchkov-nexus + https://nexus.struchkov.dev/nexus/ + true + true + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-gpg-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + + snapshot + + + + org.sonatype.plugins + nexus-staging-maven-plugin + + struchkov-nexus + https://nexus.struchkov.dev/nexus/ + true + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + + + + + + struchkov-nexus-release + https://nexus.struchkov.dev/repository/maven-releases/ + + true + always + fail + + + false + + + + struchkov-nexus-snapshot + https://nexus.struchkov.dev/repository/maven-snapshots/ + + false + + + true + always + warn + + + + + + + struchkov-nexus-release + https://nexus.struchkov.dev/repository/maven-releases/ + + + struchkov-nexus-snapshot + https://nexus.struchkov.dev/repository/maven-snapshots/ + + + + + scm:git:ssh://git@git.struchkov.dev:222/SDK/gitlab-sdk.git + https://git.struchkov.dev/SDK/gitlab-sdk + scm:git:ssh://git@git.struchkov.dev:222/SDK/gitlab-sdk.git + HEAD + + + + + uPagge + Struchkov Mark + mark@struchkov.dev + https://mark.struchkov.dev + + + + \ No newline at end of file