diff --git a/pom.xml b/pom.xml index a0580ba..1e1b4d5 100644 --- a/pom.xml +++ b/pom.xml @@ -3,14 +3,20 @@ org.jenkins-ci.plugins plugin - 2.3 + 4.15 + - 1.609.3 - 1.115 - ${jenkins.version} - false + 8 + 2.275 + 2.5 + 3.7 + 2.4.0 + 1.18.16 + 3.11 + 2.12.0 + 4.9.0 gitee @@ -27,6 +33,13 @@ + + scm:git:ssh://github.com:jenkinsci/gitee-plugin.git + scm:git:git@github.com:jenkinsci/gitee-plugin.git + https://github.com/jenkinsci/gitee-plugin + HEAD + + Yashin @@ -48,13 +61,130 @@ - - scm:git:ssh://github.com:jenkinsci/gitee-plugin.git - scm:git:git@github.com:jenkinsci/gitee-plugin.git - https://github.com/jenkinsci/gitee-plugin - HEAD - - + + + + io.jenkins.tools.bom + bom-2.263.x + 20 + import + pom + + + + + + + org.jenkins-ci.plugins + structs + + + org.jenkins-ci.plugins.workflow + workflow-job + + + org.jenkins-ci.plugins + credentials + + + org.jenkins-ci.plugins + plain-credentials + + + org.jenkins-ci + symbol-annotation + + + org.jenkins-ci.plugins + matrix-project + + + org.jenkins-ci.plugins + git + + + org.jenkins-ci.plugins + git-client + + + + org.jenkins-ci.plugins.workflow + workflow-cps + test + + + org.jenkins-ci.plugins.workflow + workflow-basic-steps + test + + + org.jenkins-ci.plugins.workflow + workflow-durable-task-step + test + + + org.jenkins-ci.plugins.workflow + workflow-aggregator + ${workflow-aggregator.version} + test + + + jackson-datatype-json-org + com.fasterxml.jackson.datatype + + + + + org.jenkins-ci.main + maven-plugin + ${jenkins-maven.version} + test + + + org.jenkins-ci.plugins + envinject + ${jenkins-envinject.version} + test + + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + + + org.apache.commons + commons-lang3 + ${commons-lang3.version} + + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + + com.squareup.okhttp3 + okhttp + ${okhttp.version} + + + org.jetbrains.kotlin + kotlin-stdlib-common + + + + + + + repo.jenkins-ci.org @@ -74,194 +204,4 @@ - - clean install - ${project.basedir}/target - ${project.build.directory}/classes - ${project.artifactId}-${project.version} - ${project.build.directory}/test-classes - ${project.basedir}/src/main/java - ${project.basedir}/src/main/scripts - ${project.basedir}/src/test/java - - - ${project.basedir}/src/main/resources - - - - - ${project.basedir}/src/test/resources - - - - - - org.codehaus.mojo - findbugs-maven-plugin - 3.0.4 - - false - - - - - - - - - - org.jenkins-ci.plugins - git - 2.4.1 - - - org.jenkins-ci.plugins - git-client - 1.19.0 - - - org.jenkins-ci.plugins.workflow - workflow-step-api - 1.15 - - - org.jenkins-ci.plugins.workflow - workflow-job - 1.15 - - - org.jenkins-ci.plugins - credentials - 2.1.0 - - - org.jenkins-ci.plugins - plain-credentials - 1.1 - true - - - org.jenkins-ci - symbol-annotation - 1.5 - - - org.eclipse.jgit - org.eclipse.jgit - 3.5.2.201411120430-r - - - org.jenkins-ci.plugins - matrix-project - 1.10 - - - org.jenkins-ci.plugins - display-url-api - 1.1.1 - - - - - - org.jboss.spec.javax.ws.rs - jboss-jaxrs-api_2.0_spec - 1.0.0.Final - - - org.jboss.resteasy - resteasy-client - 3.0.16.Final - - - com.fasterxml.jackson.jaxrs - jackson-jaxrs-json-provider - 2.9.9 - - - com.fasterxml.jackson.core - jackson-databind - 2.9.9.3 - - - org.apache.httpcomponents - httpclient - 4.3.1 - - - - - com.google.guava - guava - 18.0 - - - net.karneim - pojobuilder - 3.4.0 - provided - - - - - junit - junit - 4.12 - test - - - org.hamcrest - hamcrest-all - 1.3 - test - - - org.mockito - mockito-all - 1.9.5 - test - - - org.powermock - powermock-api-mockito - 1.6.1 - test - - - org.powermock - powermock-module-junit4 - 1.6.1 - test - - - org.mock-server - mockserver-netty - 3.10.2 - test - - - org.bouncycastle - bcmail-jdk15on - - - org.bouncycastle - bcprov-jdk15on - - - org.bouncycastle - bcpkix-jdk15on - - - javax.servlet - javax.servlet-api - - - - - org.postgresql - postgresql - 9.4.1208 - test - - diff --git a/src/main/java/com/gitee/jenkins/GiteeWebHook.java b/src/main/java/com/gitee/jenkins/GiteeWebHook.java new file mode 100644 index 0000000..a2ba3dc --- /dev/null +++ b/src/main/java/com/gitee/jenkins/GiteeWebHook.java @@ -0,0 +1,88 @@ +package com.gitee.jenkins; + +import com.gitee.jenkins.entity.WebHook; +import com.gitee.jenkins.entity.WebHookAction; +import com.gitee.jenkins.event.GiteeEventResolver; +import com.gitee.jenkins.handler.GiteeWebHookHandler; +import hudson.Extension; +import hudson.model.UnprotectedRootAction; +import hudson.security.csrf.CrumbExclusion; +import org.kohsuke.stapler.HttpResponses; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; +import org.kohsuke.stapler.interceptor.RequirePOST; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Receives gitee hook + */ +@Extension +public class GiteeWebHook implements UnprotectedRootAction { + + private static final Logger LOGGER = Logger.getLogger(GiteeWebHook.class.getName()); + + public static final String WEBHOOK_URL = "gitee-project"; + + @Override + public String getIconFileName() { + return null; + } + + @Override + public String getDisplayName() { + return null; + } + + @Override + public String getUrlName() { + return WEBHOOK_URL; + } + + /** + * Receives the webhook call + * + * @param projectName 项目名 + * @param request + * @param response + */ + @RequirePOST + public void getDynamic(String projectName, StaplerRequest request, StaplerResponse response) { + LOGGER.log(Level.INFO, "WebHook called with url: {0}", request.getRequestURIWithQueryString()); + WebHookAction webHookAction = GiteeEventResolver.resolve(projectName, request); + GiteeWebHookHandler.handler(webHookAction); + response(webHookAction.getWebHook()); + } + + public static void response(WebHook webHook) { + throw new HttpResponses.HttpResponseException() { + @Override + public void generateResponse(StaplerRequest staplerRequest, StaplerResponse staplerResponse, Object o) throws IOException, ServletException { + staplerResponse.setContentType("text/plain;charset=UTF-8"); + staplerResponse.getWriter().println(webHook.getWebHookDescription() + " has been accepted."); + } + }; + } + + @Extension + public static class GiteeWebHookCrumbExclusion extends CrumbExclusion { + + @Override + public boolean process(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { + String pathInfo = request.getPathInfo(); + if (pathInfo != null && pathInfo.startsWith("/" + WEBHOOK_URL + "/")) { + chain.doFilter(request, response); + return true; + } + return false; + } + + } + +} diff --git a/src/main/java/com/gitee/jenkins/api/GiteeApi.java b/src/main/java/com/gitee/jenkins/api/GiteeApi.java new file mode 100644 index 0000000..88101e0 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/api/GiteeApi.java @@ -0,0 +1,34 @@ +package com.gitee.jenkins.api; + +import com.gitee.jenkins.entity.User; +import com.gitee.jenkins.excetion.GiteeClientRequestException; + +public interface GiteeApi { + + /** + * 合并 PR 请求 + * + * @param owner 使用者 + * @param repo 仓库 + * @param number PR 序号 + */ + void mergerPullRequest(String owner, String repo, Integer number) throws GiteeClientRequestException; + + /** + * 创建 PR 评论 + * + * @param owner 所有者 + * @param repo 仓库 + * @param number PR 序号 + * @param body 评论内容 + */ + void submitPullRequestComments(String owner, String repo, Integer number, String body) throws GiteeClientRequestException; + + /** + * 获取当前用户(返回用户数据) + * + * @return + */ + User getUser() throws GiteeClientRequestException; + +} diff --git a/src/main/java/com/gitee/jenkins/api/client/GiteeClient.java b/src/main/java/com/gitee/jenkins/api/client/GiteeClient.java new file mode 100644 index 0000000..4e5e4fc --- /dev/null +++ b/src/main/java/com/gitee/jenkins/api/client/GiteeClient.java @@ -0,0 +1,37 @@ +package com.gitee.jenkins.api.client; + +import com.gitee.jenkins.api.GiteeApi; +import lombok.AllArgsConstructor; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +@AllArgsConstructor +@Restricted(NoExternalUse.class) +public abstract class GiteeClient implements GiteeApi { + + /** + * gitee服务器地址 + */ + String hostname; + + /** + * access token + */ + String accessToken; + + /** + * 是否忽略证书错误 + */ + boolean ignoreCertificateErrors; + + /** + * 链接超时时间 + */ + int connectionTimeout; + + /** + * 读取超时时间 + */ + int readTimeout; + +} diff --git a/src/main/java/com/gitee/jenkins/api/client/GiteeV5Client.java b/src/main/java/com/gitee/jenkins/api/client/GiteeV5Client.java new file mode 100644 index 0000000..bcdd1e4 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/api/client/GiteeV5Client.java @@ -0,0 +1,54 @@ +package com.gitee.jenkins.api.client; + +import com.gitee.jenkins.entity.User; +import com.gitee.jenkins.excetion.GiteeClientRequestException; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import java.util.HashMap; +import java.util.Map; + +@Restricted(NoExternalUse.class) +public class GiteeV5Client extends HttpGiteeClient { + + private static final String ACCESS_TOKEN_PARAM_NAME = "access_token"; + + /** + * /api/v5/repos/{owner}/{repo}/pulls/{number}/merge + */ + private static final String MERGE_PULL_REQUEST_URL = "/api/v5/repos/%s/%s/pulls/%s/merge"; + /** + * /api/v5/repos/{owner}/{repo}/pulls/{number}/comments + */ + private static final String SUBMIT_PULL_REQUEST_COMMENTS_URL = "/api/v5/repos/%s/%s/pulls/%s/comments"; + private static final String GET_USER_URL = "/api/v5/user"; + + public GiteeV5Client(String url, String accessToken, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout) { + super(url, accessToken, ignoreCertificateErrors, connectionTimeout, readTimeout); + } + + @Override + public void mergerPullRequest(String owner, String repo, Integer number) throws GiteeClientRequestException { + Map requestParamsMap = getRequestParamsMap(); + putJson(hostname + String.format(MERGE_PULL_REQUEST_URL, owner, repo, number), requestParamsMap); + } + + @Override + public void submitPullRequestComments(String owner, String repo, Integer number, String body) throws GiteeClientRequestException { + Map requestParamsMap = getRequestParamsMap(); + requestParamsMap.put("body", body); + postJson(hostname + String.format(SUBMIT_PULL_REQUEST_COMMENTS_URL, owner, repo, number), requestParamsMap); + } + + @Override + public User getUser() throws GiteeClientRequestException { + return getForEntity(hostname + GET_USER_URL, getRequestParamsMap(), User.class); + } + + private Map getRequestParamsMap() { + Map map = new HashMap<>(4); + map.put(ACCESS_TOKEN_PARAM_NAME, accessToken); + return map; + } + +} diff --git a/src/main/java/com/gitee/jenkins/api/client/HttpGiteeClient.java b/src/main/java/com/gitee/jenkins/api/client/HttpGiteeClient.java new file mode 100644 index 0000000..d7e2fd6 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/api/client/HttpGiteeClient.java @@ -0,0 +1,221 @@ +package com.gitee.jenkins.api.client; + +import com.gitee.jenkins.excetion.GiteeClientRequestException; +import com.gitee.jenkins.util.JsonUtil; +import okhttp3.*; +import okhttp3.Request.Builder; +import org.jetbrains.annotations.NotNull; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; +import java.io.IOException; +import java.security.cert.X509Certificate; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.logging.Logger; + +@Restricted(NoExternalUse.class) +public abstract class HttpGiteeClient extends GiteeClient { + + private static final Logger LOGGER = Logger.getLogger(HttpGiteeClient.class.getName()); + + public static final MediaType APPLICATION_JSON_UTF8 = MediaType.get("application/json; charset=utf-8"); + + private static final String CONNECTION_TIMEOUT_HEADER = "connection_timeout"; + private static final String READ_TIMEOUT_HEADER = "read_timeout"; + + /** + * 正常http客户端 + */ + private static final OkHttpClient SAFE_HTTP_CLIENT; + + /** + * 忽略证书安全的http客户端 + */ + private static final OkHttpClient UNSAFE_HTTP_CLIENT; + + static { + DynamicTimeoutsInterceptor dynamicTimeoutsInterceptor = new DynamicTimeoutsInterceptor(); + // 创建正常http客户端 + SAFE_HTTP_CLIENT = new OkHttpClient.Builder() + .addInterceptor(dynamicTimeoutsInterceptor) + .build(); + // 创建忽略证书安全得http客户端 + UNSAFE_HTTP_CLIENT = configureToIgnoreCertificate(new OkHttpClient.Builder()) + .addInterceptor(dynamicTimeoutsInterceptor) + .build(); + } + + protected HttpGiteeClient(String hostname, + String accessToken, + boolean ignoreCertificateErrors, + int connectionTimeout, + int readTimeout) { + super(hostname, accessToken, ignoreCertificateErrors, connectionTimeout, readTimeout); + } + + /** + * get请求,解析结果 + * + * @param url url + * @param params 参数 + * @param clazz 结果解析类型 + * @param 结果类泛型 + * @return 请求解析结果 + * @throws Exception 请求失败 + */ + T getForEntity(String url, Map params, Class clazz) throws GiteeClientRequestException { + try (Response response = reqGet(url, params)) { + return JsonUtil.string2Obj(response.body().string(), clazz); + } catch (IOException e) { + throw new GiteeClientRequestException(e); + } + } + + /** + * post json请求,不解析结果 + * + * @param url url + * @param params 参数 + * @throws Exception 请求失败 + */ + void postJson(String url, Map params) throws GiteeClientRequestException { + try (Response response = reqPostJson(url, params)) { + } + } + + /** + * put json请求,不解析结果 + * + * @param url url + * @param params 参数 + * @throws Exception 请求失败 + */ + void putJson(String url, Map params) throws GiteeClientRequestException { + try (Response response = reqPutJson(url, params)) { + } + } + + private Response reqGet(String url, Map params) throws GiteeClientRequestException { + Request request = getRequestBuilder(url, params).build(); + return getResponse(url, request); + } + + private Response reqPostJson(String url, Map params) throws GiteeClientRequestException { + Request request = getRequestBuilder(url) + .post(RequestBody.create(JsonUtil.obj2String(params), APPLICATION_JSON_UTF8)) + .build(); + return getResponse(url, request); + } + + private Response reqPutJson(String url, Map params) throws GiteeClientRequestException { + Request request = getRequestBuilder(url) + .put(RequestBody.create(JsonUtil.obj2String(params), APPLICATION_JSON_UTF8)) + .build(); + return getResponse(url, request); + } + + private Builder getRequestBuilder(String url) { + return getRequestBuilder(url, null); + } + + private Builder getRequestBuilder(String url, Map params) { + HttpUrl.Builder httpUrlBuilder = HttpUrl.parse(url).newBuilder(); + if (Objects.nonNull(params)) { + for (Map.Entry entry : params.entrySet()) { + httpUrlBuilder.addQueryParameter(entry.getKey(), entry.getValue()); + } + } + + return new Builder() + .url(httpUrlBuilder.build()) + .header(CONNECTION_TIMEOUT_HEADER, String.valueOf(connectionTimeout)) + .header(READ_TIMEOUT_HEADER, String.valueOf(readTimeout)); + } + + private Response getResponse(String url, Request request) throws GiteeClientRequestException { + try { + Response response = getHttpClient().newCall(request).execute(); + if (!response.isSuccessful()) { + throw new GiteeClientRequestException(String.format("request %s error: %s", url, response.body().string())); + } + return response; + } catch (IOException e) { + throw new GiteeClientRequestException(e); + } + } + + private OkHttpClient getHttpClient() { + return ignoreCertificateErrors ? UNSAFE_HTTP_CLIENT : SAFE_HTTP_CLIENT; + } + + /** + * 忽略https错误 + * + * @param builder + * @return + */ + private static OkHttpClient.Builder configureToIgnoreCertificate(OkHttpClient.Builder builder) { + try { + // Create a trust manager that does not validate certificate chains + final TrustManager[] trustAllCerts = new TrustManager[]{ + new X509TrustManager() { + @Override + public void checkClientTrusted(X509Certificate[] x509Certificates, String authType) { + } + + @Override + public void checkServerTrusted(X509Certificate[] x509Certificates, String authType) { + } + + @Override + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[]{}; + } + } + }; + + // Install the all-trusting trust manager + final SSLContext sslContext = SSLContext.getInstance("SSL"); + sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); + // Create an ssl socket factory with our all-trusting manager + final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); + + builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]) + .hostnameVerifier((hostname, session) -> true); + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Exception while configuring IgnoreSslCertificate" + e, e); + } + return builder; + } + + /** + * 动态配置超时时间拦截器 + */ + private static class DynamicTimeoutsInterceptor implements Interceptor { + + @NotNull + @Override + public Response intercept(@NotNull Chain chain) throws IOException { + Request request = chain.request(); + int connectionTimeout = Integer.parseInt(request.header(CONNECTION_TIMEOUT_HEADER)); + int readTimeout = Integer.parseInt(request.header(READ_TIMEOUT_HEADER)); + request = request.newBuilder() + .removeHeader(CONNECTION_TIMEOUT_HEADER) + .removeHeader(READ_TIMEOUT_HEADER) + .build(); + + return chain.withConnectTimeout(connectionTimeout, TimeUnit.SECONDS) + .withReadTimeout(readTimeout, TimeUnit.SECONDS) + .proceed(request); + } + + } + +} diff --git a/src/main/java/com/gitee/jenkins/api/client/factory/GiteeClientFactory.java b/src/main/java/com/gitee/jenkins/api/client/factory/GiteeClientFactory.java new file mode 100644 index 0000000..a430ece --- /dev/null +++ b/src/main/java/com/gitee/jenkins/api/client/factory/GiteeClientFactory.java @@ -0,0 +1,25 @@ +package com.gitee.jenkins.api.client.factory; + +import com.gitee.jenkins.api.client.GiteeClient; +import com.gitee.jenkins.enums.GiteeClientType; +import hudson.ExtensionList; +import hudson.ExtensionPoint; + +public interface GiteeClientFactory extends ExtensionPoint { + + GiteeClient getGiteeClient(String hostname, + String accessToken, + boolean ignoreCertificateErrors, + int connectionTimeout, + int readTimeout); + + GiteeClientType getGiteeClientType(); + + static GiteeClientFactory getGiteeClientFactory(GiteeClientType giteeClientType) { + return ExtensionList.lookup(GiteeClientFactory.class).stream() + .filter(giteeClientFactory -> giteeClientFactory.getGiteeClientType() == giteeClientType) + .findFirst() + .orElse(ExtensionList.lookup(GiteeClientFactory.class).get(GiteeV5ClientFactory.class)); + } + +} diff --git a/src/main/java/com/gitee/jenkins/api/client/factory/GiteeV5ClientFactory.java b/src/main/java/com/gitee/jenkins/api/client/factory/GiteeV5ClientFactory.java new file mode 100644 index 0000000..3b1ee4a --- /dev/null +++ b/src/main/java/com/gitee/jenkins/api/client/factory/GiteeV5ClientFactory.java @@ -0,0 +1,24 @@ +package com.gitee.jenkins.api.client.factory; + +import com.gitee.jenkins.api.client.GiteeClient; +import com.gitee.jenkins.api.client.GiteeV5Client; +import com.gitee.jenkins.enums.GiteeClientType; +import hudson.Extension; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +@Extension +@Restricted(NoExternalUse.class) +public class GiteeV5ClientFactory implements GiteeClientFactory { + + @Override + public GiteeClient getGiteeClient(String hostname, String accessToken, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout) { + return new GiteeV5Client(hostname, accessToken, ignoreCertificateErrors, connectionTimeout, readTimeout); + } + + @Override + public GiteeClientType getGiteeClientType() { + return GiteeClientType.V5; + } + +} diff --git a/src/main/java/com/gitee/jenkins/cause/CauseData.java b/src/main/java/com/gitee/jenkins/cause/CauseData.java deleted file mode 100644 index 7931db5..0000000 --- a/src/main/java/com/gitee/jenkins/cause/CauseData.java +++ /dev/null @@ -1,603 +0,0 @@ -package com.gitee.jenkins.cause; - -import com.gitee.jenkins.gitee.api.model.PullRequest; -import hudson.markup.EscapedMarkupFormatter; -import jenkins.model.Jenkins; -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -import java.util.*; - -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * @author Robin Müller - */ -public final class CauseData { - private final ActionType actionType; - private final Integer sourceProjectId; - private final Integer targetProjectId; - private final String branch; - private final String pathWithNamespace; - private final String sourceBranch; - private final String userName; - private final String userEmail; - private final String sourceRepoHomepage; - private final String sourceRepoName; - private final String sourceNamespace; - private final String sourceRepoUrl; - private final String sourceRepoSshUrl; - private final String sourceRepoHttpUrl; - private final String pullRequestTitle; - private final String pullRequestDescription; - private final Integer pullRequestId; - private final Integer pullRequestIid; - private final String pullRequestState; - private final String mergedByUser; - private final String pullRequestAssignee; - private final Integer pullRequestTargetProjectId; - private final String targetBranch; - private final String targetRepoName; - private final String targetNamespace; - private final String targetRepoSshUrl; - private final String targetRepoHttpUrl; - private final String triggeredByUser; - private final String before; - private final String after; - private final String lastCommit; - private final String targetProjectUrl; - private final String triggerPhrase; - private final String ref; - private final String beforeSha; - private final String isTag; - private final String sha; - private final String status; - private final String stages; - private final String createdAt; - private final String finishedAt; - private final String buildDuration; - private final String jsonBody; - private final String noteBody; - private final boolean created; - private final boolean deleted; - - @GeneratePojoBuilder(withFactoryMethod = "*") - CauseData(ActionType actionType, Integer sourceProjectId, Integer targetProjectId, String branch, String sourceBranch, String userName, - String userEmail, String sourceRepoHomepage, String sourceRepoName, String sourceNamespace, String sourceRepoUrl, - String sourceRepoSshUrl, String sourceRepoHttpUrl, String pullRequestTitle, String pullRequestDescription, Integer pullRequestId, - Integer pullRequestIid, Integer pullRequestTargetProjectId, String targetBranch, String targetRepoName, String targetNamespace, - String targetRepoSshUrl, String targetRepoHttpUrl, String triggeredByUser, String before, String after, String lastCommit, - String targetProjectUrl, String triggerPhrase, String pullRequestState, String mergedByUser, String pullRequestAssignee, - String ref, String isTag, String sha, String beforeSha, String status, String stages, String createdAt, String finishedAt, - String buildDuration, String pathWithNamespace, boolean created, boolean deleted, String jsonBody, String noteBody) { - this.actionType = checkNotNull(actionType, "actionType must not be null."); - this.sourceProjectId = checkNotNull(sourceProjectId, "sourceProjectId must not be null."); - this.targetProjectId = checkNotNull(targetProjectId, "targetProjectId must not be null."); - this.branch = checkNotNull(branch, "branch must not be null."); - this.sourceBranch = checkNotNull(sourceBranch, "sourceBranch must not be null."); - this.userName = checkNotNull(userName, "userName must not be null."); - this.userEmail = userEmail == null ? "" : userEmail; - this.sourceRepoHomepage = sourceRepoHomepage == null ? "" : sourceRepoHomepage; - this.sourceRepoName = checkNotNull(sourceRepoName, "sourceRepoName must not be null."); - this.sourceNamespace = checkNotNull(sourceNamespace, "sourceNamespace must not be null."); - this.sourceRepoUrl = sourceRepoUrl == null ? sourceRepoSshUrl : sourceRepoUrl; - this.sourceRepoSshUrl = checkNotNull(sourceRepoSshUrl, "sourceRepoSshUrl must not be null."); - this.sourceRepoHttpUrl = checkNotNull(sourceRepoHttpUrl, "sourceRepoHttpUrl must not be null."); - this.pullRequestTitle = checkNotNull(pullRequestTitle, "pullRequestTitle must not be null."); - this.pullRequestDescription = pullRequestDescription == null ? "" : pullRequestDescription; - this.pullRequestId = pullRequestId; - this.pullRequestIid = pullRequestIid; - this.pullRequestState = pullRequestState == null ? "" : pullRequestState; - this.mergedByUser = mergedByUser == null ? "" : mergedByUser; - this.pullRequestAssignee = pullRequestAssignee == null ? "" : pullRequestAssignee; - this.pullRequestTargetProjectId = pullRequestTargetProjectId; - this.targetBranch = checkNotNull(targetBranch, "targetBranch must not be null."); - this.targetRepoName = checkNotNull(targetRepoName, "targetRepoName must not be null."); - this.targetNamespace = checkNotNull(targetNamespace, "targetNamespace must not be null."); - this.targetRepoSshUrl = checkNotNull(targetRepoSshUrl, "targetRepoSshUrl must not be null."); - this.targetRepoHttpUrl = checkNotNull(targetRepoHttpUrl, "targetRepoHttpUrl must not be null."); - this.triggeredByUser = checkNotNull(triggeredByUser, "triggeredByUser must not be null."); - this.before = before == null ? "" : before; - this.after = after == null ? "" : after; -// this.lastCommit = checkNotNull(lastCommit, "lastCommit must not be null"); - // 直接checkout到分支,而非commit sha,暂时不需要确保lastCommit 非空 - this.lastCommit = lastCommit; - this.targetProjectUrl = targetProjectUrl; - this.triggerPhrase = triggerPhrase; - this.ref = ref; - this.isTag = isTag; - this.sha = sha; - this.beforeSha = beforeSha; - this.status = status; - this.stages = stages; - this.createdAt = createdAt; - this.finishedAt = finishedAt; - this.buildDuration = buildDuration; - this.pathWithNamespace = pathWithNamespace; - this.created = created; - this.deleted = deleted; - this.jsonBody = jsonBody; - this.noteBody = noteBody; - } - - public Map getBuildVariables() { - MapWrapper variables = new MapWrapper<>(new HashMap()); - variables.put("giteeBranch", branch); - variables.put("giteeSourceBranch", sourceBranch); - variables.put("giteeActionType", actionType.name()); - variables.put("giteeUserName", userName); - variables.put("giteeUserEmail", userEmail); - variables.put("giteeSourceRepoHomepage", sourceRepoHomepage); - variables.put("giteeSourceRepoName", sourceRepoName); - variables.put("giteeSourceNamespace", sourceNamespace); - variables.put("giteeSourceRepoURL", sourceRepoUrl); - variables.put("giteeSourceRepoSshUrl", sourceRepoSshUrl); - variables.put("giteeSourceRepoHttpUrl", sourceRepoHttpUrl); - variables.put("giteePullRequestTitle", pullRequestTitle); - variables.put("giteePullRequestDescription", pullRequestDescription); - variables.put("giteePullRequestId", pullRequestId == null ? "" : pullRequestId.toString()); - variables.put("giteePullRequestIid", pullRequestIid == null ? "" : pullRequestIid.toString()); - variables.put("giteePullRequestTargetProjectId", pullRequestTargetProjectId == null ? "" : pullRequestTargetProjectId.toString()); - variables.put("giteePullRequestLastCommit", lastCommit); - variables.put("giteePushCreated", created ? "true" : "false"); - variables.put("giteePushDeleted", deleted ? "true" : "false"); - variables.putIfNotNull("giteePullRequestState", pullRequestState); - variables.putIfNotNull("giteeMergedByUser", mergedByUser); - variables.putIfNotNull("giteePullRequestAssignee", pullRequestAssignee); - variables.put("giteeTargetBranch", targetBranch); - variables.put("giteeTargetRepoName", targetRepoName); - variables.put("giteeTargetNamespace", targetNamespace); - variables.put("giteeTargetRepoSshUrl", targetRepoSshUrl); - variables.put("giteeTargetRepoHttpUrl", targetRepoHttpUrl); - variables.put("giteeBefore", before); - variables.put("giteeAfter", after); - variables.put("giteeBeforeCommitSha", before); - variables.put("giteeAfterCommitSha", after); - variables.put("giteeRef", ref); - variables.put("ref", ref); - variables.put("beforeSha", beforeSha); - variables.put("isTag", isTag); - variables.put("sha", sha); - variables.put("status", status); - variables.put("stages", stages); - variables.put("createdAt", createdAt); - variables.put("finishedAt", finishedAt); - variables.put("duration", buildDuration); - variables.put("jsonBody", jsonBody); - variables.put("noteBody", noteBody); - variables.putIfNotNull("giteeTriggerPhrase", triggerPhrase); - return variables; - } - - public Integer getSourceProjectId() { - return sourceProjectId; - } - - public Integer getTargetProjectId() { - return targetProjectId; - } - - public String getBranch() { - return branch; - } - - public String getSourceBranch() { - return sourceBranch; - } - - public ActionType getActionType() { - return actionType; - } - - public String getUserName() { - return userName; - } - - public String getUserEmail() { - return userEmail; - } - - public String getSourceRepoHomepage() { - return sourceRepoHomepage; - } - - public String getSourceRepoName() { - return sourceRepoName; - } - - public String getSourceNamespace() { - return sourceNamespace; - } - - public String getSourceRepoUrl() { - return sourceRepoUrl; - } - - public String getSourceRepoSshUrl() { - return sourceRepoSshUrl; - } - - public String getSourceRepoHttpUrl() { - return sourceRepoHttpUrl; - } - - public String getPullRequestTitle() { - return pullRequestTitle; - } - - public String getPullRequestDescription() { - return pullRequestDescription; - } - - public String getPathWithNamespace() { return pathWithNamespace; } - - public Integer getPullRequestId() { - return pullRequestId; - } - - public Integer getPullRequestIid() { - return pullRequestIid; - } - - public Integer getPullRequestTargetProjectId() { - return pullRequestTargetProjectId; - } - - public String getTargetBranch() { - return targetBranch; - } - - public String getTargetRepoName() { - return targetRepoName; - } - - public String getTargetNamespace() { - return targetNamespace; - } - - public String getTargetRepoSshUrl() { - return targetRepoSshUrl; - } - - public String getTargetRepoHttpUrl() { - return targetRepoHttpUrl; - } - - public String getTriggeredByUser() { - return triggeredByUser; - } - - public String getBefore() { - return before; - } - - public String getAfter() { - return after; - } - - public String getLastCommit() { - return lastCommit; - } - - public String getTargetProjectUrl() { - return targetProjectUrl; - } - - public String getRef() { return ref; } - - public String getIsTag() { return isTag; } - - public String getSha() { return sha; } - - public String getBeforeSha() {return beforeSha; } - - public String getStatus() { return status; } - - public String getStages() { return stages; } - - public String getCreatedAt() { return createdAt; } - - public String getFinishedAt() { return finishedAt; } - - public String getBuildDuration() { return buildDuration; } - - public String getJsonBody() { return jsonBody; } - - public String getNoteBody() { return noteBody; } - - - String getShortDescription() { - return actionType.getShortDescription(this); - } - - public String getPullRequestState() { - return pullRequestState; - } - - public String getMergedByUser() { - return mergedByUser; - } - - public String getPullRequestAssignee() { - return pullRequestAssignee; - } - - - public boolean getCreated() { - return created; - } - - public boolean getDeleted() { - return deleted; - } - - public PullRequest getPullRequest() { - if (pullRequestId == null) { - return null; - } - - return new PullRequest(pullRequestId, pullRequestIid, sourceBranch, targetBranch, pullRequestTitle, - sourceProjectId, targetProjectId, pullRequestDescription, pullRequestState, pathWithNamespace); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - CauseData causeData = (CauseData) o; - return new EqualsBuilder() - .append(actionType, causeData.actionType) - .append(sourceProjectId, causeData.sourceProjectId) - .append(targetProjectId, causeData.targetProjectId) - .append(branch, causeData.branch) - .append(sourceBranch, causeData.sourceBranch) - .append(userName, causeData.userName) - .append(userEmail, causeData.userEmail) - .append(sourceRepoHomepage, causeData.sourceRepoHomepage) - .append(sourceRepoName, causeData.sourceRepoName) - .append(sourceNamespace, causeData.sourceNamespace) - .append(sourceRepoUrl, causeData.sourceRepoUrl) - .append(sourceRepoSshUrl, causeData.sourceRepoSshUrl) - .append(sourceRepoHttpUrl, causeData.sourceRepoHttpUrl) - .append(pullRequestTitle, causeData.pullRequestTitle) - .append(pullRequestDescription, causeData.pullRequestDescription) - .append(pullRequestId, causeData.pullRequestId) - .append(pullRequestIid, causeData.pullRequestIid) - .append(pullRequestState, causeData.pullRequestState) - .append(mergedByUser, causeData.mergedByUser) - .append(pullRequestAssignee, causeData.pullRequestAssignee) - .append(pullRequestTargetProjectId, causeData.pullRequestTargetProjectId) - .append(targetBranch, causeData.targetBranch) - .append(targetRepoName, causeData.targetRepoName) - .append(targetNamespace, causeData.targetNamespace) - .append(targetRepoSshUrl, causeData.targetRepoSshUrl) - .append(targetRepoHttpUrl, causeData.targetRepoHttpUrl) - .append(triggeredByUser, causeData.triggeredByUser) - .append(before, causeData.before) - .append(after, causeData.after) - .append(lastCommit, causeData.lastCommit) - .append(targetProjectUrl, causeData.targetProjectUrl) - .append(ref, causeData.getRef()) - .append(isTag, causeData.getIsTag()) - .append(sha, causeData.getSha()) - .append(beforeSha, causeData.getBeforeSha()) - .append(status, causeData.getStatus()) - .append(stages, causeData.getStages()) - .append(createdAt, causeData.getCreatedAt()) - .append(finishedAt, causeData.getFinishedAt()) - .append(buildDuration, causeData.getBuildDuration()) - .append(pathWithNamespace, causeData.getPathWithNamespace()) - .append(created, causeData.getCreated()) - .append(deleted, causeData.getDeleted()) - .append(jsonBody, causeData.getJsonBody()) - .append(noteBody, causeData.getNoteBody()) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(actionType) - .append(sourceProjectId) - .append(targetProjectId) - .append(branch) - .append(sourceBranch) - .append(userName) - .append(userEmail) - .append(sourceRepoHomepage) - .append(sourceRepoName) - .append(sourceNamespace) - .append(sourceRepoUrl) - .append(sourceRepoSshUrl) - .append(sourceRepoHttpUrl) - .append(pullRequestTitle) - .append(pullRequestDescription) - .append(pullRequestId) - .append(pullRequestIid) - .append(pullRequestState) - .append(mergedByUser) - .append(pullRequestAssignee) - .append(pullRequestTargetProjectId) - .append(targetBranch) - .append(targetRepoName) - .append(targetNamespace) - .append(targetRepoSshUrl) - .append(targetRepoHttpUrl) - .append(triggeredByUser) - .append(before) - .append(after) - .append(lastCommit) - .append(targetProjectUrl) - .append(ref) - .append(isTag) - .append(sha) - .append(beforeSha) - .append(status) - .append(stages) - .append(createdAt) - .append(finishedAt) - .append(buildDuration) - .append(pathWithNamespace) - .append(created) - .append(deleted) - .append(jsonBody) - .append(noteBody) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("actionType", actionType) - .append("sourceProjectId", sourceProjectId) - .append("targetProjectId", targetProjectId) - .append("branch", branch) - .append("sourceBranch", sourceBranch) - .append("userName", userName) - .append("userEmail", userEmail) - .append("sourceRepoHomepage", sourceRepoHomepage) - .append("sourceRepoName", sourceRepoName) - .append("sourceNamespace", sourceNamespace) - .append("sourceRepoUrl", sourceRepoUrl) - .append("sourceRepoSshUrl", sourceRepoSshUrl) - .append("sourceRepoHttpUrl", sourceRepoHttpUrl) - .append("pullRequestTitle", pullRequestTitle) - .append("pullRequestDescription", pullRequestDescription) - .append("pullRequestId", pullRequestId) - .append("pullRequestIid", pullRequestIid) - .append("pullRequestState", pullRequestState) - .append("mergedByUser", mergedByUser) - .append("pullRequestAssignee", pullRequestAssignee) - .append("pullRequestTargetProjectId", pullRequestTargetProjectId) - .append("targetBranch", targetBranch) - .append("targetRepoName", targetRepoName) - .append("targetNamespace", targetNamespace) - .append("targetRepoSshUrl", targetRepoSshUrl) - .append("targetRepoHttpUrl", targetRepoHttpUrl) - .append("triggeredByUser", triggeredByUser) - .append("before", before) - .append("after", after) - .append("lastCommit", lastCommit) - .append("targetProjectUrl", targetProjectUrl) - .append("ref", ref) - .append("isTag", isTag) - .append("sha", sha) - .append("beforeSha", beforeSha) - .append("status", status) - .append("stages", stages) - .append("createdAt", createdAt) - .append("finishedAt", finishedAt) - .append("duration", buildDuration) - .append("pathWithNamespace", pathWithNamespace) - .append("created", created) - .append("deleted", deleted) - .append("jsonBody", jsonBody) - .append("noteBody", noteBody) - .toString(); - } - - public enum ActionType { - PUSH { - @Override - String getShortDescription(CauseData data) { - return getShortDescriptionPush(data); - } - }, TAG_PUSH { - @Override - String getShortDescription(CauseData data) { - return getShortDescriptionPush(data); - } - }, MERGE { - @Override - String getShortDescription(CauseData data) { - String forkNamespace = StringUtils.equals(data.getSourceNamespace(), data.getTargetBranch()) ? "" : data.getSourceNamespace() + "/"; - if (Jenkins.getActiveInstance().getMarkupFormatter() instanceof EscapedMarkupFormatter || data.getTargetProjectUrl() == null) { - return Messages.GiteeWebHookCause_ShortDescription_PullRequestHook_plain(String.valueOf(data.getPullRequestIid()), - forkNamespace + data.getSourceBranch(), - data.getTargetBranch()); - } else { - return Messages.GiteeWebHookCause_ShortDescription_PullRequestHook_html(String.valueOf(data.getPullRequestIid()), - forkNamespace + data.getSourceBranch(), - data.getTargetBranch(), - data.getTargetProjectUrl()); - } - } - }, NOTE { - @Override - String getShortDescription(CauseData data) { - String triggeredBy = data.getTriggeredByUser(); - String forkNamespace = StringUtils.equals(data.getSourceNamespace(), data.getTargetBranch()) ? "" : data.getSourceNamespace() + "/"; - if (Jenkins.getActiveInstance().getMarkupFormatter() instanceof EscapedMarkupFormatter || data.getTargetProjectUrl() == null) { - return Messages.GiteeWebHookCause_ShortDescription_NoteHook_plain(triggeredBy, - String.valueOf(data.getPullRequestIid()), - forkNamespace + data.getSourceBranch(), - data.getTargetBranch()); - } else { - return Messages.GiteeWebHookCause_ShortDescription_NoteHook_html(triggeredBy, - String.valueOf(data.getPullRequestIid()), - forkNamespace + data.getSourceBranch(), - data.getTargetBranch(), - data.getTargetProjectUrl()); - } - } - }, COMMIT_COMMENT { - @Override - String getShortDescription(CauseData data) { - return Messages.GiteeWebHookCause_ShortDescription_Commit_comment(data.getTriggeredByUser()); - } - }, PIPELINE { - @Override - String getShortDescription(CauseData data) { - String getStatus = data.getStatus(); - if (getStatus == null) { - return Messages.GiteeWebHookCause_ShortDescription_PipelineHook_noStatus(); - } else { - return Messages.GiteeWebHookCause_ShortDescription_PipelineHook(getStatus); - } - } - }; - - private static String getShortDescriptionPush(CauseData data) { - String pushedBy = data.getTriggeredByUser(); - if (pushedBy == null) { - return Messages.GiteeWebHookCause_ShortDescription_PushHook_noUser(); - } else { - return Messages.GiteeWebHookCause_ShortDescription_PushHook(pushedBy); - } - } - - abstract String getShortDescription(CauseData data); - } - - private static class MapWrapper extends AbstractMap { - - private final Map map; - - MapWrapper(Map map) { - this.map = map; - } - - @Override - public V put(K key, V value) { - return map.put(key, value); - } - - @Override - public Set> entrySet() { - return map.entrySet(); - } - - void putIfNotNull(K key, V value) { - if (value != null) { - map.put(key, value); - } - } - } -} diff --git a/src/main/java/com/gitee/jenkins/cause/GiteeWebHookCause.java b/src/main/java/com/gitee/jenkins/cause/GiteeWebHookCause.java index 0bb8a9c..d05cc87 100644 --- a/src/main/java/com/gitee/jenkins/cause/GiteeWebHookCause.java +++ b/src/main/java/com/gitee/jenkins/cause/GiteeWebHookCause.java @@ -1,23 +1,20 @@ package com.gitee.jenkins.cause; +import com.google.common.base.Preconditions; import hudson.triggers.SCMTrigger; +import lombok.EqualsAndHashCode; -import static com.google.common.base.Preconditions.checkNotNull; - -/** - * @author Robin Müller - * @author Yashin - */ +@EqualsAndHashCode public class GiteeWebHookCause extends SCMTrigger.SCMTriggerCause { - private final CauseData data; + private final GiteeWebHookCauseData data; - public GiteeWebHookCause(CauseData data) { + public GiteeWebHookCause(GiteeWebHookCauseData giteeWebHookCauseData) { super(""); - this.data = checkNotNull(data, "data must not be null"); + this.data = Preconditions.checkNotNull(giteeWebHookCauseData, "data must not be null"); } - public CauseData getData() { + public GiteeWebHookCauseData getData() { return data; } @@ -25,4 +22,5 @@ public class GiteeWebHookCause extends SCMTrigger.SCMTriggerCause { public String getShortDescription() { return data.getShortDescription(); } + } diff --git a/src/main/java/com/gitee/jenkins/cause/GiteeWebHookCauseData.java b/src/main/java/com/gitee/jenkins/cause/GiteeWebHookCauseData.java new file mode 100644 index 0000000..c197a7e --- /dev/null +++ b/src/main/java/com/gitee/jenkins/cause/GiteeWebHookCauseData.java @@ -0,0 +1,210 @@ +package com.gitee.jenkins.cause; + +import com.gitee.jenkins.enums.WebHookType; +import com.google.common.base.Preconditions; +import lombok.Builder; +import lombok.Data; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +@Data +public class GiteeWebHookCauseData { + + private WebHookType webHookType; + + private String userName; + + private String userEmail; + + private Integer sourceProjectId; + + private Integer targetProjectId; + + private String pathWithNamespace; + + private String branch; + + private String sourceBranch; + + private String sourceRepoHomepage; + + private String sourceRepoName; + + private String sourceNamespace; + + private String sourceRepoUrl; + + private String sourceRepoSshUrl; + + private String sourceRepoHttpUrl; + + private String targetBranch; + + private String targetRepoName; + + private String targetNamespace; + + private String targetProjectUrl; + + private String targetRepoSshUrl; + + private String targetRepoHttpUrl; + + private String pullRequestTitle; + + private String pullRequestDescription; + + private Integer pullRequestId; + + private Integer pullRequestIid; + + private String pullRequestState; + + private String mergedByUser; + + private String pullRequestAssignee; + + private Integer pullRequestTargetProjectId; + + private String before; + + private String after; + + private String lastCommit; + + private final String ref; + + private final String beforeSha; + + private final String sha; + + private final String isTag; + + private boolean created; + + private boolean deleted; + + private String status; + + private String stages; + + private String createdAt; + + private String finishedAt; + + private String buildDuration; + + private String jsonBody; + + private String noteBody; + + private String triggerPhrase; + + private String triggeredByUser; + + @Builder + private GiteeWebHookCauseData(WebHookType webHookType, String userName, String userEmail, Integer sourceProjectId, Integer targetProjectId, String pathWithNamespace, String branch, String sourceBranch, String sourceRepoHomepage, String sourceRepoName, String sourceNamespace, String sourceRepoUrl, String sourceRepoSshUrl, String sourceRepoHttpUrl, String targetBranch, String targetRepoName, String targetNamespace, String targetProjectUrl, String targetRepoSshUrl, String targetRepoHttpUrl, String pullRequestTitle, String pullRequestDescription, Integer pullRequestId, Integer pullRequestIid, String pullRequestState, String mergedByUser, String pullRequestAssignee, Integer pullRequestTargetProjectId, String before, String after, String lastCommit, String ref, String beforeSha, String sha, String isTag, boolean created, boolean deleted, String status, String stages, String createdAt, String finishedAt, String buildDuration, String jsonBody, String noteBody, String triggerPhrase, String triggeredByUser) { + this.webHookType = Preconditions.checkNotNull(webHookType, "actionType must not be null."); + this.userName = Preconditions.checkNotNull(userName, "userName must not be null."); + this.userEmail = Optional.ofNullable(userEmail).orElse(""); + this.sourceProjectId = Preconditions.checkNotNull(sourceProjectId, "sourceProjectId must not be null."); + this.targetProjectId = Preconditions.checkNotNull(targetProjectId, "targetProjectId must not be null."); + this.pathWithNamespace = pathWithNamespace; + this.branch = Preconditions.checkNotNull(branch, "branch must not be null."); + this.sourceBranch = Preconditions.checkNotNull(sourceBranch, "sourceBranch must not be null."); + this.sourceRepoHomepage = Optional.ofNullable(sourceRepoHomepage).orElse(""); + this.sourceRepoName = Preconditions.checkNotNull(sourceRepoName, "sourceRepoName must not be null."); + this.sourceNamespace = Preconditions.checkNotNull(sourceNamespace, "sourceNamespace must not be null."); + this.sourceRepoUrl = Optional.ofNullable(sourceRepoUrl).orElse(sourceRepoSshUrl); + this.sourceRepoSshUrl = Preconditions.checkNotNull(sourceRepoSshUrl, "sourceRepoSshUrl must not be null."); + this.sourceRepoHttpUrl = Preconditions.checkNotNull(sourceRepoHttpUrl, "sourceRepoHttpUrl must not be null."); + this.targetBranch = Preconditions.checkNotNull(targetBranch, "targetBranch must not be null."); + this.targetRepoName = Preconditions.checkNotNull(targetRepoName, "targetRepoName must not be null."); + this.targetNamespace = Preconditions.checkNotNull(targetNamespace, "targetNamespace must not be null."); + this.targetProjectUrl = targetProjectUrl; + this.targetRepoSshUrl = Preconditions.checkNotNull(targetRepoSshUrl, "targetRepoSshUrl must not be null."); + this.targetRepoHttpUrl = Preconditions.checkNotNull(targetRepoHttpUrl, "targetRepoHttpUrl must not be null."); + this.pullRequestTitle = Preconditions.checkNotNull(pullRequestTitle, "pullRequestTitle must not be null."); + this.pullRequestDescription = Optional.ofNullable(pullRequestDescription).orElse(""); + this.pullRequestId = pullRequestId; + this.pullRequestIid = pullRequestIid; + this.pullRequestState = Optional.ofNullable(pullRequestState).orElse(""); + this.mergedByUser = Optional.ofNullable(mergedByUser).orElse(""); + this.pullRequestAssignee = Optional.ofNullable(pullRequestAssignee).orElse(""); + this.pullRequestTargetProjectId = pullRequestTargetProjectId; + this.before = Optional.ofNullable(before).orElse(""); + this.after = Optional.ofNullable(after).orElse(""); + this.lastCommit = lastCommit; + this.ref = ref; + this.beforeSha = beforeSha; + this.sha = sha; + this.isTag = isTag; + this.created = created; + this.deleted = deleted; + this.status = status; + this.stages = stages; + this.createdAt = createdAt; + this.finishedAt = finishedAt; + this.buildDuration = buildDuration; + this.jsonBody = jsonBody; + this.noteBody = noteBody; + this.triggerPhrase = triggerPhrase; + this.triggeredByUser = Preconditions.checkNotNull(triggeredByUser, "triggeredByUser must not be null."); + } + + public Map getBuildEnvironmentVariables() { + Map map = new HashMap<>(64); + map.put("giteeActionType", webHookType.name()); + map.put("giteeUserName", userName); + map.put("giteeUserEmail", userEmail); + map.put("giteeBranch", branch); + map.put("giteeSourceBranch", sourceBranch); + map.put("giteeSourceRepoHomepage", sourceRepoHomepage); + map.put("giteeSourceRepoName", sourceRepoName); + map.put("giteeSourceNamespace", sourceNamespace); + map.put("giteeSourceRepoURL", sourceRepoUrl); + map.put("giteeSourceRepoSshUrl", sourceRepoSshUrl); + map.put("giteeSourceRepoHttpUrl", sourceRepoHttpUrl); + map.put("giteeTargetBranch", targetBranch); + map.put("giteeTargetRepoName", targetRepoName); + map.put("giteeTargetNamespace", targetNamespace); + map.put("giteeTargetRepoSshUrl", targetRepoSshUrl); + map.put("giteeTargetRepoHttpUrl", targetRepoHttpUrl); + map.put("giteePullRequestTitle", pullRequestTitle); + map.put("giteePullRequestDescription", pullRequestDescription); + map.put("giteePullRequestId", Optional.ofNullable(pullRequestId).map(String::valueOf).orElse("")); + map.put("giteePullRequestIid", Optional.ofNullable(pullRequestIid).map(String::valueOf).orElse("")); + map.put("giteePullRequestTargetProjectId", Optional.ofNullable(pullRequestTargetProjectId).map(String::valueOf).orElse("")); + map.compute("giteePullRequestState", (k, v) -> pullRequestState); + map.compute("giteeMergedByUser", (k, v) -> mergedByUser); + map.compute("giteePullRequestAssignee", (k, v) -> pullRequestAssignee); + map.put("giteeBefore", before); + map.put("giteeAfter", after); + map.put("giteeBeforeCommitSha", before); + map.put("giteeAfterCommitSha", after); + map.put("giteePullRequestLastCommit", lastCommit); + map.put("giteeRef", ref); + map.put("ref", ref); + map.put("beforeSha", beforeSha); + map.put("sha", sha); + map.put("isTag", isTag); + map.put("giteePushCreated", String.valueOf(created)); + map.put("giteePushDeleted", String.valueOf(deleted)); + map.put("status", status); + map.put("stages", stages); + map.put("createdAt", createdAt); + map.put("finishedAt", finishedAt); + map.put("duration", buildDuration); + map.put("jsonBody", jsonBody); + map.put("noteBody", noteBody); + map.compute("giteeTriggerPhrase", (k, v) -> triggerPhrase); + return map; + } + + public String getShortDescription() { + return webHookType.getShortDescription(this); + } + +} diff --git a/src/main/java/com/gitee/jenkins/config/ApiTokenConfig.java b/src/main/java/com/gitee/jenkins/config/ApiTokenConfig.java new file mode 100644 index 0000000..62a58f4 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/config/ApiTokenConfig.java @@ -0,0 +1,15 @@ +package com.gitee.jenkins.config; + +import com.cloudbees.plugins.credentials.common.StandardCredentials; +import hudson.util.Secret; + +public interface ApiTokenConfig extends StandardCredentials { + + /** + * 获取 Api Token + * + * @return Api Token + */ + Secret getApiToken(); + +} diff --git a/src/main/java/com/gitee/jenkins/config/GiteeApiTokenConfig.java b/src/main/java/com/gitee/jenkins/config/GiteeApiTokenConfig.java new file mode 100644 index 0000000..4007127 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/config/GiteeApiTokenConfig.java @@ -0,0 +1,55 @@ +package com.gitee.jenkins.config; + +import com.cloudbees.plugins.credentials.CredentialsNameProvider; +import com.cloudbees.plugins.credentials.CredentialsScope; +import com.cloudbees.plugins.credentials.NameWith; +import com.cloudbees.plugins.credentials.impl.BaseStandardCredentials; +import hudson.Extension; +import hudson.Util; +import hudson.util.Secret; +import org.kohsuke.stapler.DataBoundConstructor; + +import java.util.Optional; + +@NameWith(GiteeApiTokenConfig.NameProvider.class) +public final class GiteeApiTokenConfig extends BaseStandardCredentials implements ApiTokenConfig { + + /** + * gitee api token + */ + private Secret apiToken; + + /** + * 获取 gitee api token + * + * @return apiToken + */ + @Override + public Secret getApiToken() { + return apiToken; + } + + @DataBoundConstructor + public GiteeApiTokenConfig(CredentialsScope scope, String id, String description, Secret apiToken) { + super(scope, id, description); + this.apiToken = apiToken; + } + + protected static class NameProvider extends CredentialsNameProvider { + @Override + public String getName(ApiTokenConfig c) { + String description = Util.fixEmptyAndTrim(c.getDescription()); + return Messages.GiteeApiToken_name() + + Optional.ofNullable(description).map(s -> String.join("(", description, ")")).orElse(""); + } + } + + @Extension + public static class DescriptorImpl extends BaseStandardCredentialsDescriptor { + @Override + public String getDisplayName() { + return Messages.GiteeApiToken_name(); + } + } + +} diff --git a/src/main/java/com/gitee/jenkins/config/GiteeConnectionConfig.java b/src/main/java/com/gitee/jenkins/config/GiteeConnectionConfig.java new file mode 100644 index 0000000..572cb36 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/config/GiteeConnectionConfig.java @@ -0,0 +1,281 @@ +package com.gitee.jenkins.config; + +import com.cloudbees.plugins.credentials.*; +import com.cloudbees.plugins.credentials.common.StandardCredentials; +import com.cloudbees.plugins.credentials.common.StandardListBoxModel; +import com.cloudbees.plugins.credentials.domains.Domain; +import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; +import com.gitee.jenkins.api.client.GiteeClient; +import com.gitee.jenkins.api.client.factory.GiteeClientFactory; +import com.gitee.jenkins.enums.GiteeClientType; +import com.gitee.jenkins.excetion.GiteeClientRequestException; +import hudson.Extension; +import hudson.init.InitMilestone; +import hudson.init.Initializer; +import hudson.model.AbstractDescribableImpl; +import hudson.model.Descriptor; +import hudson.model.Item; +import hudson.security.ACL; +import hudson.util.FormValidation; +import hudson.util.ListBoxModel; +import hudson.util.Secret; +import jenkins.model.Jenkins; +import lombok.Getter; +import lombok.Setter; +import org.apache.commons.lang3.StringUtils; +import org.jenkinsci.plugins.plaincredentials.StringCredentials; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.QueryParameter; + +import java.io.IOException; +import java.util.*; + +/** + * Gitee链接配置 + */ +@Getter +@Setter +public class GiteeConnectionConfig extends AbstractDescribableImpl { + + private static final GiteeClientType GITEE_CLIENT_TYPE = GiteeClientType.V5; + + /** + * 链接名 + */ + private String name; + + /** + * Gitee域名URL + */ + private String url; + + /** + * 证书令牌id + */ + private String apiTokenId; + + /** + * 证书令牌 + * + * @deprecated 已废弃设置,现在不直接配置 apiToken,而是配置链接 + */ + @Deprecated + private transient String apiToken; + + /** + * 忽略 SSL 证书错误 + */ + private final boolean ignoreCertificateErrors; + + /** + * 建立链接超时时间 单位:秒 + */ + private Integer connectionTimeout; + + /** + * 读取超时时间 单位:秒 + */ + private Integer readTimeout; + + private transient GiteeClientFactory giteeClientFactory; + + private transient GiteeClient giteeClient; + + @DataBoundConstructor + public GiteeConnectionConfig(String name, String url, String apiTokenId, boolean ignoreCertificateErrors, Integer connectionTimeout, Integer readTimeout) { + this.name = name; + this.url = url; + this.apiTokenId = apiTokenId; + this.ignoreCertificateErrors = ignoreCertificateErrors; + this.connectionTimeout = connectionTimeout; + this.readTimeout = readTimeout; + this.giteeClientFactory = GiteeClientFactory.getGiteeClientFactory(GITEE_CLIENT_TYPE); + } + + @Restricted(NoExternalUse.class) + public GiteeConnectionConfig(String url, String apiTokenId, boolean ignoreCertificateErrors) { + this("", url, apiTokenId, ignoreCertificateErrors, 0, 0); + } + + public GiteeClient getGiteeClient() { + if (giteeClient == null) { + giteeClient = giteeClientFactory.getGiteeClient(url, getApiToken(apiTokenId), ignoreCertificateErrors, connectionTimeout, readTimeout); + } + return giteeClient; + } + + @Restricted(NoExternalUse.class) + private String getApiToken(String apiTokenId) { + Jenkins.get().checkPermission(Jenkins.ADMINISTER); + + StandardCredentials credentials = CredentialsMatchers.firstOrNull( + CredentialsProvider.lookupCredentials(StandardCredentials.class, (Item) null, ACL.SYSTEM, Collections.emptyList()), + CredentialsMatchers.withId(apiTokenId) + ); + + if (credentials != null) { + if (credentials instanceof GiteeApiTokenConfig) { + return ((GiteeApiTokenConfig) credentials).getApiToken().getPlainText(); + } + if (credentials instanceof StringCredentials) { + return ((StringCredentials) credentials).getSecret().getPlainText(); + } + } + + throw new IllegalStateException("No credentials found for credentialsId: " + apiTokenId); + } + + protected GiteeConnectionConfig readResolve() { + if (connectionTimeout == null || readTimeout == null) { + return new GiteeConnectionConfig(name, url, apiTokenId, ignoreCertificateErrors, 10, 10); + } + giteeClientFactory = GiteeClientFactory.getGiteeClientFactory(GITEE_CLIENT_TYPE); + return this; + } + + /** + * 兼容直接输入token的场景 + */ + @Initializer(after = InitMilestone.PLUGINS_STARTED) + public static void compatibleProcessing() throws IOException { + GiteeGlobalConfig giteeGlobalConfig = (GiteeGlobalConfig) Jenkins.get().getDescriptor(GiteeGlobalConfig.class); + if (giteeGlobalConfig == null) { + return; + } + for (GiteeConnectionConfig giteeConnectionConfig : giteeGlobalConfig.getGiteeConnectionConfigs()) { + if (Objects.isNull(giteeConnectionConfig.apiTokenId) && Objects.nonNull(giteeConnectionConfig.apiToken)) { + for (CredentialsStore credentialsStore : CredentialsProvider.lookupStores(Jenkins.get())) { + if (credentialsStore instanceof SystemCredentialsProvider.StoreImpl) { + List domains = credentialsStore.getDomains(); + giteeConnectionConfig.apiTokenId = UUID.randomUUID().toString(); + credentialsStore.addCredentials( + domains.get(0), + new GiteeApiTokenConfig(CredentialsScope.SYSTEM, giteeConnectionConfig.apiTokenId, "Gitee API Token", Secret.fromString(giteeConnectionConfig.apiToken)) + ); + } + } + } + } + giteeGlobalConfig.save(); + } + + @Extension + public static class DescriptorImpl extends Descriptor { + /** + * 测试链接 + * + * @param url + * @param apiTokenId + * @param ignoreCertificateErrors + * @return + */ + public FormValidation doTestConnection(@QueryParameter String url, + @QueryParameter String apiTokenId, + @QueryParameter boolean ignoreCertificateErrors) { + Jenkins.get().checkPermission(Jenkins.ADMINISTER); + + try { + new GiteeConnectionConfig(url, apiTokenId, ignoreCertificateErrors) + .getGiteeClient() + .getUser(); + return FormValidation.ok(Messages.connection_success()); + } catch (GiteeClientRequestException e) { + return FormValidation.error(Messages.connection_error(e.getMessage())); + } + + } + + /** + * 名称校验 + * + * @param value + * @return + */ + public FormValidation doCheckName(@QueryParameter String id, @QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error(Messages.name_required()); + } + boolean nameExist = Optional.ofNullable((GiteeGlobalConfig) Jenkins.get().getDescriptor(GiteeGlobalConfig.class)) + .map(giteeGlobalConfig -> giteeGlobalConfig.containsGiteeConnectionName(id, value)) + .orElse(false); + if (nameExist) { + return FormValidation.error(Messages.name_exists(value)); + } + return FormValidation.ok(); + } + + /** + * url校验 + * + * @param value + * @return + */ + public FormValidation doCheckUrl(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error(Messages.url_required()); + } + return FormValidation.ok(); + } + + /** + * api token id校验 + * + * @param value + * @return + */ + public FormValidation doCheckApiTokenId(@QueryParameter String value) { + if (StringUtils.isBlank(value)) { + return FormValidation.error(Messages.apiToken_required()); + } + return FormValidation.ok(); + } + + /** + * 链接超时时间校验 + * + * @param value + * @return + */ + public FormValidation doCheckConnectionTimeout(@QueryParameter Integer value) { + if (Objects.isNull(value)) { + return FormValidation.error(Messages.connectionTimeout_required()); + } + return FormValidation.ok(); + } + + /** + * 读取超时时间校验 + * + * @param value + * @return + */ + public FormValidation doCheckReadTimeout(@QueryParameter Integer value) { + if (value == null) { + return FormValidation.error(Messages.readTimeout_required()); + } + return FormValidation.ok(); + } + + public ListBoxModel doFillApiTokenIdItems(@QueryParameter String url, @QueryParameter String apiTokenId) { + if (Jenkins.get().hasPermission(Item.CONFIGURE)) { + new StandardListBoxModel() + .includeEmptyValue() + .includeCurrentValue(apiTokenId); + return new StandardListBoxModel() + .includeEmptyValue() + .includeMatchingAs( + ACL.SYSTEM, + Jenkins.get(), + StandardCredentials.class, + URIRequirementBuilder.fromUri(url).build(), + new GiteeCredentialMatcher() + ).includeCurrentValue(apiTokenId); + } + return new StandardListBoxModel(); + } + + } + +} diff --git a/src/main/java/com/gitee/jenkins/config/GiteeCredentialMatcher.java b/src/main/java/com/gitee/jenkins/config/GiteeCredentialMatcher.java new file mode 100644 index 0000000..1c549b5 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/config/GiteeCredentialMatcher.java @@ -0,0 +1,18 @@ +package com.gitee.jenkins.config; + +import com.cloudbees.plugins.credentials.Credentials; +import com.cloudbees.plugins.credentials.CredentialsMatcher; +import org.jenkinsci.plugins.plaincredentials.StringCredentials; + +public class GiteeCredentialMatcher implements CredentialsMatcher { + + @Override + public boolean matches(Credentials credentials) { + try { + return credentials instanceof GiteeApiTokenConfig || credentials instanceof StringCredentials; + } catch (Exception e) { + return false; + } + } + +} diff --git a/src/main/java/com/gitee/jenkins/config/GiteeGlobalConfig.java b/src/main/java/com/gitee/jenkins/config/GiteeGlobalConfig.java new file mode 100644 index 0000000..0d75ca2 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/config/GiteeGlobalConfig.java @@ -0,0 +1,91 @@ +package com.gitee.jenkins.config; + +import com.gitee.jenkins.api.client.GiteeClient; +import hudson.Extension; +import hudson.init.InitMilestone; +import hudson.init.Initializer; +import jenkins.model.GlobalConfiguration; +import jenkins.model.Jenkins; +import lombok.Getter; +import lombok.Setter; +import net.sf.json.JSONObject; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; +import org.kohsuke.stapler.StaplerRequest; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.function.Function; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +/** + * Gitee全局配置 + */ +@Getter +@Setter +@Extension +public class GiteeGlobalConfig extends GlobalConfiguration { + + private static final Logger LOGGER = Logger.getLogger(GiteeGlobalConfig.class.getName()); + + private List giteeConnectionConfigs; + private transient Map giteeConnectionConfigMap; + + @DataBoundConstructor + public GiteeGlobalConfig() { + giteeConnectionConfigs = new ArrayList<>(); + // 加载持久化配置 + load(); + refreshGiteeConnectionConfigMap(); + } + + @Override + public boolean configure(StaplerRequest req, JSONObject json) throws FormException { + giteeConnectionConfigs = req.bindJSONToList(GiteeConnectionConfig.class, json.get("connections")); + refreshGiteeConnectionConfigMap(); + save(); + return super.configure(req, json); + } + + /** + * 重建Gitee链接配置映射 + */ + private void refreshGiteeConnectionConfigMap() { + giteeConnectionConfigMap = giteeConnectionConfigs.stream().collect(Collectors.toMap(GiteeConnectionConfig::getName, Function.identity())); + } + + @DataBoundSetter + public void setGiteeConnectionConfigs(List giteeConnectionConfigs) { + this.giteeConnectionConfigs = giteeConnectionConfigs; + refreshGiteeConnectionConfigMap(); + save(); + } + + public GiteeClient getGiteeClient(String giteeConnectionName) { + return Optional.ofNullable(giteeConnectionConfigMap.get(giteeConnectionName)) + .map(GiteeConnectionConfig::getGiteeClient) + .orElse(null); + } + + public boolean containsGiteeConnectionName(String id, String giteeConnectionName) { + return Optional.ofNullable(giteeConnectionConfigMap) + .map(map -> map.get(giteeConnectionName)) + .map(giteeConnectionConfig -> !giteeConnectionConfig.toString().equals(id)) + .orElse(false); + } + + /** + * 提供一个空输入 + */ + @Initializer(after = InitMilestone.SYSTEM_CONFIG_ADAPTED) + public static void init() { + GiteeGlobalConfig giteeGlobalConfig = (GiteeGlobalConfig) Jenkins.get().getDescriptor(GiteeGlobalConfig.class); + if (giteeGlobalConfig != null && giteeGlobalConfig.getGiteeConnectionConfigs().isEmpty()) { + giteeGlobalConfig.getGiteeConnectionConfigs().add(new GiteeConnectionConfig("", null, false)); + } + } + +} diff --git a/src/main/java/com/gitee/jenkins/config/GiteeItemConfig.java b/src/main/java/com/gitee/jenkins/config/GiteeItemConfig.java new file mode 100644 index 0000000..b3c88c6 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/config/GiteeItemConfig.java @@ -0,0 +1,78 @@ +package com.gitee.jenkins.config; + +import com.gitee.jenkins.api.client.GiteeClient; +import hudson.Extension; +import hudson.model.Job; +import hudson.model.JobProperty; +import hudson.model.JobPropertyDescriptor; +import hudson.util.ListBoxModel; +import jenkins.model.Jenkins; +import lombok.Getter; +import net.sf.json.JSONObject; +import org.apache.commons.lang3.StringUtils; +import org.jenkinsci.Symbol; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.StaplerRequest; + +import java.util.Optional; + +/** + * 单个Item内Gitee配置 + */ +@Getter +public class GiteeItemConfig extends JobProperty> { + + private String giteeConnectionName; + + @DataBoundConstructor + public GiteeItemConfig(String giteeConnectionName) { + this.giteeConnectionName = giteeConnectionName; + } + + public static GiteeClient getGiteeClient(Job job) { + return Optional.ofNullable(job.getProperty(GiteeItemConfig.class)) + .map(GiteeItemConfig::getGiteeClient) + .orElse(null); + } + + public GiteeClient getGiteeClient() { + if (StringUtils.isNotBlank(giteeConnectionName)) { + GiteeGlobalConfig giteeGlobalConfig = (GiteeGlobalConfig) Jenkins.get().getDescriptor(GiteeGlobalConfig.class); + return giteeGlobalConfig == null ? null : giteeGlobalConfig.getGiteeClient(giteeConnectionName); + } + return null; + } + + @Extension + @Symbol("giteeConnectionName") + public static class DescriptorImpl extends JobPropertyDescriptor { + + @Override + public String getDisplayName() { + return "Gitee connection"; + } + + @Override + public boolean isApplicable(Class jobType) { + return true; + } + + @Override + public JobProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException { + return req.bindJSON(GiteeItemConfig.class, formData); + } + + public ListBoxModel doFillGiteeConnectionNameItems() { + ListBoxModel listBoxModel = new ListBoxModel(); + GiteeGlobalConfig giteeGlobalConfig = (GiteeGlobalConfig) Jenkins.get().getDescriptor(GiteeGlobalConfig.class); + if (giteeGlobalConfig != null) { + for (GiteeConnectionConfig giteeConnectionConfig : giteeGlobalConfig.getGiteeConnectionConfigs()) { + listBoxModel.add(giteeConnectionConfig.getName(), giteeConnectionConfig.getName()); + } + } + return listBoxModel; + } + + } + +} diff --git a/src/main/java/com/gitee/jenkins/connection/GiteeApiToken.java b/src/main/java/com/gitee/jenkins/connection/GiteeApiToken.java deleted file mode 100644 index 28cfec4..0000000 --- a/src/main/java/com/gitee/jenkins/connection/GiteeApiToken.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gitee.jenkins.connection; - -import com.cloudbees.plugins.credentials.CredentialsNameProvider; -import com.cloudbees.plugins.credentials.NameWith; -import com.cloudbees.plugins.credentials.common.StandardCredentials; -import hudson.Util; -import hudson.util.Secret; - -/** - * @author Robin Müller - */ -@NameWith(GiteeApiToken.NameProvider.class) -public interface GiteeApiToken extends StandardCredentials { - - Secret getApiToken(); - - class NameProvider extends CredentialsNameProvider { - @Override - public String getName(GiteeApiToken c) { - String description = Util.fixEmptyAndTrim(c.getDescription()); - return Messages.GiteeApiToken_name() + (description != null ? " (" + description + ")" : ""); - } - } -} diff --git a/src/main/java/com/gitee/jenkins/connection/GiteeApiTokenImpl.java b/src/main/java/com/gitee/jenkins/connection/GiteeApiTokenImpl.java deleted file mode 100644 index 99f7a9a..0000000 --- a/src/main/java/com/gitee/jenkins/connection/GiteeApiTokenImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.gitee.jenkins.connection; - -import com.cloudbees.plugins.credentials.CredentialsScope; -import com.cloudbees.plugins.credentials.impl.BaseStandardCredentials; -import hudson.Extension; -import hudson.util.Secret; -import org.kohsuke.stapler.DataBoundConstructor; - -/** - * @author Robin Müller - */ -public final class GiteeApiTokenImpl extends BaseStandardCredentials implements GiteeApiToken { - - private Secret apiToken; - - @DataBoundConstructor - public GiteeApiTokenImpl(CredentialsScope scope, String id, String description, Secret apiToken) { - super(scope, id, description); - this.apiToken = apiToken; - } - - @Override - public Secret getApiToken() { - return apiToken; - } - - @Extension - public static class DescriptorImpl extends BaseStandardCredentialsDescriptor { - @Override - public String getDisplayName() { - return Messages.GiteeApiToken_name(); - } - } -} diff --git a/src/main/java/com/gitee/jenkins/connection/GiteeConnection.java b/src/main/java/com/gitee/jenkins/connection/GiteeConnection.java deleted file mode 100644 index 32390c3..0000000 --- a/src/main/java/com/gitee/jenkins/connection/GiteeConnection.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.gitee.jenkins.connection; - - -import com.cloudbees.plugins.credentials.CredentialsMatchers; -import com.cloudbees.plugins.credentials.CredentialsProvider; -import com.cloudbees.plugins.credentials.CredentialsScope; -import com.cloudbees.plugins.credentials.CredentialsStore; -import com.cloudbees.plugins.credentials.SystemCredentialsProvider; -import com.cloudbees.plugins.credentials.common.StandardCredentials; -import com.cloudbees.plugins.credentials.domains.Domain; -import com.cloudbees.plugins.credentials.domains.DomainRequirement; -import com.gitee.jenkins.gitee.api.GiteeClient; -import com.gitee.jenkins.gitee.api.GiteeClientBuilder; -import com.gitee.jenkins.gitee.api.impl.GiteeV5ClientBuilder; -import hudson.init.InitMilestone; -import hudson.init.Initializer; -import hudson.model.Item; -import hudson.security.ACL; -import hudson.util.Secret; -import jenkins.model.Jenkins; -import org.jenkinsci.plugins.plaincredentials.StringCredentials; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; -import org.kohsuke.stapler.DataBoundConstructor; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; - -import static com.cloudbees.plugins.credentials.CredentialsProvider.lookupCredentials; -import static com.gitee.jenkins.gitee.api.GiteeClientBuilder.getGiteeClientBuilderById; - - -/** - * @author Robin Müller - */ -public class GiteeConnection { - private final String name; - private final String url; - private transient String apiToken; - // TODO make final when migration code gets removed - private String apiTokenId; - private GiteeClientBuilder clientBuilder; - private final boolean ignoreCertificateErrors; - private final Integer connectionTimeout; - private final Integer readTimeout; - private transient GiteeClient apiCache; - - public GiteeConnection(String name, String url, String apiTokenId, boolean ignoreCertificateErrors, Integer connectionTimeout, Integer readTimeout) { - this( - name, - url, - apiTokenId, - new GiteeV5ClientBuilder(), - ignoreCertificateErrors, - connectionTimeout, - readTimeout - ); - } - - @DataBoundConstructor - public GiteeConnection(String name, String url, String apiTokenId, String clientBuilderId, boolean ignoreCertificateErrors, Integer connectionTimeout, Integer readTimeout) { - this( - name, - url, - apiTokenId, - getGiteeClientBuilderById(clientBuilderId), - ignoreCertificateErrors, - connectionTimeout, - readTimeout - ); - } - - @Restricted(NoExternalUse.class) - public GiteeConnection(String name, String url, String apiTokenId, GiteeClientBuilder clientBuilder, boolean ignoreCertificateErrors, Integer connectionTimeout, Integer readTimeout) { - this.name = name; - this.url = url; - this.apiTokenId = apiTokenId; - this.clientBuilder = clientBuilder; - this.ignoreCertificateErrors = ignoreCertificateErrors; - this.connectionTimeout = connectionTimeout; - this.readTimeout = readTimeout; - } - - public String getName() { - return name; - } - - public String getUrl() { - return url; - } - - public String getApiTokenId() { - return apiTokenId; - } - - public String getClientBuilderId() { - return clientBuilder.id(); - } - - public boolean isIgnoreCertificateErrors() { - return ignoreCertificateErrors; - } - - public int getConnectionTimeout() { - return connectionTimeout; - } - - public int getReadTimeout() { - return readTimeout; - } - - public GiteeClient getClient() { - if (apiCache == null) { - apiCache = clientBuilder.buildClient(url, getApiToken(apiTokenId), ignoreCertificateErrors, connectionTimeout, readTimeout); - } - - return apiCache; - } - - private String getApiToken(String apiTokenId) { - StandardCredentials credentials = CredentialsMatchers.firstOrNull( - lookupCredentials(StandardCredentials.class, (Item) null, ACL.SYSTEM, new ArrayList()), - CredentialsMatchers.withId(apiTokenId)); - if (credentials != null) { - if (credentials instanceof GiteeApiToken) { - return ((GiteeApiToken) credentials).getApiToken().getPlainText(); - } - if (credentials instanceof StringCredentials) { - return ((StringCredentials) credentials).getSecret().getPlainText(); - } - } - throw new IllegalStateException("No credentials found for credentialsId: " + apiTokenId); - } - - - protected GiteeConnection readResolve() { - if (connectionTimeout == null || readTimeout == null) { - return new GiteeConnection(name, url, apiTokenId, new GiteeV5ClientBuilder(), ignoreCertificateErrors, 10, 10); - } - if (clientBuilder == null) { - return new GiteeConnection(name, url, apiTokenId, new GiteeV5ClientBuilder(), ignoreCertificateErrors, connectionTimeout, readTimeout); - } - - return this; - } - - @Initializer(after = InitMilestone.PLUGINS_STARTED) - public static void migrate() throws IOException { - GiteeConnectionConfig descriptor = (GiteeConnectionConfig) Jenkins.getInstance().getDescriptor(GiteeConnectionConfig.class); - for (GiteeConnection connection : descriptor.getConnections()) { - if (connection.apiTokenId == null && connection.apiToken != null) { - for (CredentialsStore credentialsStore : CredentialsProvider.lookupStores(Jenkins.getInstance())) { - if (credentialsStore instanceof SystemCredentialsProvider.StoreImpl) { - List domains = credentialsStore.getDomains(); - connection.apiTokenId = UUID.randomUUID().toString(); - credentialsStore.addCredentials(domains.get(0), - new GiteeApiTokenImpl(CredentialsScope.SYSTEM, connection.apiTokenId, "Gitee API Token", Secret.fromString(connection.apiToken))); - } - } - } - } - descriptor.save(); - } -} diff --git a/src/main/java/com/gitee/jenkins/connection/GiteeConnectionConfig.java b/src/main/java/com/gitee/jenkins/connection/GiteeConnectionConfig.java deleted file mode 100644 index b5df991..0000000 --- a/src/main/java/com/gitee/jenkins/connection/GiteeConnectionConfig.java +++ /dev/null @@ -1,210 +0,0 @@ -package com.gitee.jenkins.connection; - - -import com.cloudbees.plugins.credentials.Credentials; -import com.cloudbees.plugins.credentials.CredentialsMatcher; -import com.cloudbees.plugins.credentials.common.AbstractIdCredentialsListBoxModel; -import com.cloudbees.plugins.credentials.common.StandardCredentials; -import com.cloudbees.plugins.credentials.common.StandardListBoxModel; -import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder; -import com.gitee.jenkins.gitee.api.GiteeClient; -import com.gitee.jenkins.gitee.api.GiteeClientBuilder; -import edu.umd.cs.findbugs.annotations.NonNull; -import hudson.Extension; -import hudson.model.Item; -import hudson.security.ACL; -import hudson.util.FormValidation; -import hudson.util.ListBoxModel; -import jenkins.model.GlobalConfiguration; -import jenkins.model.Jenkins; -import net.sf.json.JSONObject; -import org.eclipse.jgit.util.StringUtils; -import org.jenkinsci.plugins.plaincredentials.StringCredentials; -import org.kohsuke.stapler.QueryParameter; -import org.kohsuke.stapler.StaplerRequest; - -import javax.ws.rs.ProcessingException; -import javax.ws.rs.WebApplicationException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static com.gitee.jenkins.gitee.api.GiteeClientBuilder.getAllGiteeClientBuilders; - - -/** - * @author Robin Müller - */ -@Extension -public class GiteeConnectionConfig extends GlobalConfiguration { - - private Boolean useAuthenticatedEndpoint = true; - private List connections = new ArrayList<>(); - private transient Map connectionMap = new HashMap<>(); - - public GiteeConnectionConfig() { - load(); - refreshConnectionMap(); - } - - @Override - public boolean configure(StaplerRequest req, JSONObject json) throws FormException { - connections = req.bindJSONToList(GiteeConnection.class, json.get("connections")); -// useAuthenticatedEndpoint = json.getBoolean("useAuthenticatedEndpoint"); - refreshConnectionMap(); - save(); - return super.configure(req, json); - } - - public boolean isUseAuthenticatedEndpoint() { - return useAuthenticatedEndpoint; - } - - void setUseAuthenticatedEndpoint(boolean useAuthenticatedEndpoint) { - this.useAuthenticatedEndpoint = useAuthenticatedEndpoint; - } - - public List getConnections() { - return connections; - } - - public void addConnection(GiteeConnection connection) { - connections.add(connection); - connectionMap.put(connection.getName(), connection); - } - - public void setConnections(List newConnections) { - connections = new ArrayList<>(); - connectionMap = new HashMap<>(); - for (GiteeConnection connection: newConnections){ - addConnection(connection); - } - } - - public GiteeClient getClient(String connectionName) { - if (!connectionMap.containsKey(connectionName)) { - return null; - } - return connectionMap.get(connectionName).getClient(); - } - - public FormValidation doCheckName(@QueryParameter String id, @QueryParameter String value) { - if (StringUtils.isEmptyOrNull(value)) { - return FormValidation.error(Messages.name_required()); - } else if (connectionMap.containsKey(value) && !connectionMap.get(value).toString().equals(id)) { - return FormValidation.error(Messages.name_exists(value)); - } else { - return FormValidation.ok(); - } - } - - public FormValidation doCheckUrl(@QueryParameter String value) { - if (StringUtils.isEmptyOrNull(value)) { - return FormValidation.error(Messages.url_required()); - } else { - return FormValidation.ok(); - } - } - - public FormValidation doCheckApiTokenId(@QueryParameter String value) { - if (StringUtils.isEmptyOrNull(value)) { - return FormValidation.error(Messages.apiToken_required()); - } else { - return FormValidation.ok(); - } - } - - public FormValidation doCheckConnectionTimeout(@QueryParameter Integer value) { - if (value == null) { - return FormValidation.error(Messages.connectionTimeout_required()); - } else { - return FormValidation.ok(); - } - } - - public FormValidation doCheckReadTimeout(@QueryParameter Integer value) { - if (value == null) { - return FormValidation.error(Messages.readTimeout_required()); - } else { - return FormValidation.ok(); - } - } - - public FormValidation doTestConnection(@QueryParameter String url, - @QueryParameter String apiTokenId, - @QueryParameter String clientBuilderId, - @QueryParameter boolean ignoreCertificateErrors, - @QueryParameter int connectionTimeout, - @QueryParameter int readTimeout) { - try { - if (clientBuilderId == null) { - clientBuilderId = "v5"; - } - - new GiteeConnection("", url, apiTokenId, clientBuilderId, ignoreCertificateErrors, connectionTimeout, readTimeout).getClient().getCurrentUser(); - return FormValidation.ok(Messages.connection_success()); - } catch (WebApplicationException e) { - return FormValidation.error(Messages.connection_error(e.getMessage())); - } catch (ProcessingException e) { - return FormValidation.error(Messages.connection_error(e.getCause().getMessage())); - } - } - - public ListBoxModel doFillApiTokenIdItems(@QueryParameter String name, @QueryParameter String url) { - if (Jenkins.getInstance().hasPermission(Item.CONFIGURE)) { - AbstractIdCredentialsListBoxModel options = new StandardListBoxModel() - .includeEmptyValue() - .includeMatchingAs(ACL.SYSTEM, - Jenkins.getActiveInstance(), - StandardCredentials.class, - URIRequirementBuilder.fromUri(url).build(), - new GiteeCredentialMatcher()); - if (name != null && connectionMap.containsKey(name)) { - String apiTokenId = connectionMap.get(name).getApiTokenId(); - options.includeCurrentValue(apiTokenId); - for (ListBoxModel.Option option : options) { - if (option.value.equals(apiTokenId)) { - option.selected = true; - } - } - } - return options; - } - return new StandardListBoxModel(); - } - - public ListBoxModel doFillClientBuilderIdItems() { - ListBoxModel model = new ListBoxModel(); - for (GiteeClientBuilder builder : getAllGiteeClientBuilders()) { - model.add(builder.id()); - } - - return model; - } - - private void refreshConnectionMap() { - connectionMap.clear(); - for (GiteeConnection connection : connections) { - connectionMap.put(connection.getName(), connection); - } - } - - private static class GiteeCredentialMatcher implements CredentialsMatcher { - @Override - public boolean matches(@NonNull Credentials credentials) { - try { - return credentials instanceof GiteeApiToken || credentials instanceof StringCredentials; - } catch (Throwable e) { - return false; - } - } - } - //For backwards compatibility. ReadResolve is called on startup - protected GiteeConnectionConfig readResolve() { - if (useAuthenticatedEndpoint == null) { - setUseAuthenticatedEndpoint(false); - } - return this; - } -} diff --git a/src/main/java/com/gitee/jenkins/connection/GiteeConnectionProperty.java b/src/main/java/com/gitee/jenkins/connection/GiteeConnectionProperty.java deleted file mode 100644 index ce985b2..0000000 --- a/src/main/java/com/gitee/jenkins/connection/GiteeConnectionProperty.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.gitee.jenkins.connection; - - -import com.gitee.jenkins.gitee.api.GiteeClient; -import hudson.Extension; -import hudson.model.Job; -import hudson.model.JobProperty; -import hudson.model.JobPropertyDescriptor; -import hudson.model.Run; -import hudson.util.ListBoxModel; -import jenkins.model.Jenkins; -import net.sf.json.JSONObject; -import org.apache.commons.lang.StringUtils; -import org.jenkinsci.Symbol; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.StaplerRequest; - -/** - * @author Robin Müller - */ -public class GiteeConnectionProperty extends JobProperty> { - - private String giteeConnection; - - @DataBoundConstructor - public GiteeConnectionProperty(String giteeConnection) { - this.giteeConnection = giteeConnection; - } - - public String getGiteeConnection() { - return giteeConnection; - } - - public GiteeClient getClient() { - if (StringUtils.isNotEmpty(giteeConnection)) { - GiteeConnectionConfig connectionConfig = (GiteeConnectionConfig) Jenkins.getInstance().getDescriptor(GiteeConnectionConfig.class); - return connectionConfig != null ? connectionConfig.getClient(giteeConnection) : null; - } - return null; - } - - public static GiteeClient getClient(Run build) { - final GiteeConnectionProperty connectionProperty = build.getParent().getProperty(GiteeConnectionProperty.class); - if (connectionProperty != null) { - return connectionProperty.getClient(); - } - return null; - } - - public static GiteeClient getClient(Job job) { - final GiteeConnectionProperty connectionProperty = job.getProperty(GiteeConnectionProperty.class); - if (connectionProperty != null) { - return connectionProperty.getClient(); - } - return null; - } - - - @Extension - @Symbol("giteeConnection") - public static class DescriptorImpl extends JobPropertyDescriptor { - - @Override - public String getDisplayName() { - return "Gitee connection"; - } - - @Override - public boolean isApplicable(Class jobType) { - return true; - } - - @Override - public JobProperty newInstance(StaplerRequest req, JSONObject formData) throws FormException { - return req.bindJSON(GiteeConnectionProperty.class, formData); - } - - public ListBoxModel doFillGiteeConnectionItems() { - ListBoxModel options = new ListBoxModel(); - GiteeConnectionConfig descriptor = (GiteeConnectionConfig) Jenkins.getInstance().getDescriptor(GiteeConnectionConfig.class); - for (GiteeConnection connection : descriptor.getConnections()) { - options.add(connection.getName(), connection.getName()); - } - return options; - } - } -} diff --git a/src/main/java/com/gitee/jenkins/entity/Branch.java b/src/main/java/com/gitee/jenkins/entity/Branch.java new file mode 100644 index 0000000..d7b3e63 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/Branch.java @@ -0,0 +1,33 @@ +package com.gitee.jenkins.entity; + +import lombok.Data; + +@Data +public class Branch { + + /** + * 标签 + */ + private String label; + + /** + * 分支名称 + */ + private String ref; + + /** + * sha + */ + private String sha; + + /** + * 用户 + */ + private User user; + + /** + * 仓库 + */ + private Repository repo; + +} diff --git a/src/main/java/com/gitee/jenkins/entity/Commit.java b/src/main/java/com/gitee/jenkins/entity/Commit.java new file mode 100644 index 0000000..1d1822e --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/Commit.java @@ -0,0 +1,35 @@ +package com.gitee.jenkins.entity; + +import lombok.Data; + +import java.util.Date; +import java.util.List; + +@Data +public class Commit { + + private String id; + + private String treeId; + + private List parentIds; + + private String message; + + private Date timestamp; + + private String url; + + private User author; + + private User committer; + + private Boolean distinct; + + private List added; + + private List removed; + + private List modified; + +} diff --git a/src/main/java/com/gitee/jenkins/entity/CommitComment.java b/src/main/java/com/gitee/jenkins/entity/CommitComment.java new file mode 100644 index 0000000..ea6fe8f --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/CommitComment.java @@ -0,0 +1,12 @@ +package com.gitee.jenkins.entity; + +import lombok.Data; + +@Data +public class CommitComment extends PullRequestComment { + + private String position; + + private String commitId; + +} diff --git a/src/main/java/com/gitee/jenkins/entity/CommitCommentWebHook.java b/src/main/java/com/gitee/jenkins/entity/CommitCommentWebHook.java new file mode 100644 index 0000000..755dfa2 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/CommitCommentWebHook.java @@ -0,0 +1,45 @@ +package com.gitee.jenkins.entity; + +import com.gitee.jenkins.enums.PullRequestCommentAction; +import com.gitee.jenkins.enums.WebHookType; +import lombok.Data; + +@Data +public class CommitCommentWebHook extends WebHook { + + private PullRequestCommentAction action; + + private CommitComment comment; + + private User author; + + private String url; + + private String note; + + private String noteableType; + + private Integer noteableId; + + private String title; + + private String perIid; + + private String shortCommitId; + + @Override + public WebHookType getWebHookType() { + return WebHookType.COMMIT_COMMENT; + } + + @Override + public String getWebHookDescription() { + return super.getHookName() + " commit sha = " + comment.getCommitId(); + } + + @Override + public String getTargetBranch() { + return ""; + } + +} diff --git a/src/main/java/com/gitee/jenkins/entity/Enterprise.java b/src/main/java/com/gitee/jenkins/entity/Enterprise.java new file mode 100644 index 0000000..0eafc4f --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/Enterprise.java @@ -0,0 +1,12 @@ +package com.gitee.jenkins.entity; + +import lombok.Data; + +@Data +public class Enterprise { + + private String name; + + private String url; + +} diff --git a/src/main/java/com/gitee/jenkins/entity/PullRequest.java b/src/main/java/com/gitee/jenkins/entity/PullRequest.java new file mode 100644 index 0000000..4bf49d2 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/PullRequest.java @@ -0,0 +1,160 @@ +package com.gitee.jenkins.entity; + +import com.gitee.jenkins.enums.PullRequestState; +import lombok.Data; + +import java.util.Date; +import java.util.List; + +@Data +public class PullRequest { + + /** + * PR id + */ + private Integer id; + + /** + * PR 序号 + */ + private Integer number; + + private PullRequestState state; + + private String htmlUrl; + + private String diffUrl; + + private String patchUrl; + + /** + * PR 标题 + */ + private String title; + + /** + * PR 内容 + */ + private String body; + + /** + * PR 标签 + */ + private List labels; + + private List languages; + + /** + * 创建时间 + */ + private Date createdAt; + + /** + * 修改时间 + */ + private Date updatedAt; + + /** + * 关闭时间 + */ + private Date closedAt; + + /** + * 合并时间 + */ + private Date mergedAt; + + /** + * 合并sha + */ + private String mergeCommitSha; + + /** + * mergeReferenceName + */ + private String mergeReferenceName; + + private User assignee; + + private List assignees; + + private User tester; + + private List testers; + + /** + * 是否需要测试 + */ + private Boolean needTest; + + /** + * 是否想要审核 + */ + private Boolean needReview; + + /** + * 里程碑 + */ + private String milestone; + + /** + * 是否合并 + */ + private Boolean merged; + + /** + * 是否可以合并 + */ + private Boolean mergeable; + + /** + * 合并状态 + */ + private String mergeStatus; + + /** + * 评论数 + */ + private Integer comments; + + /** + * 提交数 + */ + private Integer commits; + + /** + * 增加文件数量 + */ + private Integer additions; + + /** + * 删除文件数量 + */ + private Integer deletions; + + /** + * 修改文件数 + */ + private Integer changedFiles; + + /** + * 创建人 + */ + private User user; + + /** + * 修改人 + */ + private User updatedBy; + + /** + * 目标分支 + */ + private Branch head; + + /** + * 源分支 + */ + private Branch base; + +} diff --git a/src/main/java/com/gitee/jenkins/entity/PullRequestComment.java b/src/main/java/com/gitee/jenkins/entity/PullRequestComment.java new file mode 100644 index 0000000..4427f79 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/PullRequestComment.java @@ -0,0 +1,22 @@ +package com.gitee.jenkins.entity; + +import lombok.Data; + +import java.util.Date; + +@Data +public class PullRequestComment { + + private Integer id; + + private String body; + + private User user; + + private Date createdAt; + + private Date updatedAt; + + private String htmlUrl; + +} diff --git a/src/main/java/com/gitee/jenkins/entity/PullRequestCommentWebHook.java b/src/main/java/com/gitee/jenkins/entity/PullRequestCommentWebHook.java new file mode 100644 index 0000000..a11a52e --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/PullRequestCommentWebHook.java @@ -0,0 +1,52 @@ +package com.gitee.jenkins.entity; + +import com.gitee.jenkins.enums.PullRequestCommentAction; +import com.gitee.jenkins.enums.WebHookType; +import lombok.Data; + +import java.util.Optional; + +@Data +public class PullRequestCommentWebHook extends WebHook { + + private PullRequestCommentAction action; + + private PullRequestComment comment; + + private User author; + + private String url; + + private String note; + + private String noteableType; + + private Integer noteableId; + + private String title; + + private String perIid; + + private String shortCommitId; + + private PullRequest pullRequest; + + @Override + public WebHookType getWebHookType() { + return WebHookType.PULL_REQUEST_COMMENT; + } + + @Override + public String getWebHookDescription() { + return super.getHookName() + " iid = " + pullRequest.getNumber() + " merge commit sha = " + pullRequest.getMergeCommitSha(); + } + + @Override + public String getTargetBranch() { + return Optional.ofNullable(pullRequest) + .map(PullRequest::getBase) + .map(Branch::getRef) + .orElse(""); + } + +} diff --git a/src/main/java/com/gitee/jenkins/entity/PullRequestWebHook.java b/src/main/java/com/gitee/jenkins/entity/PullRequestWebHook.java new file mode 100644 index 0000000..cf48a45 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/PullRequestWebHook.java @@ -0,0 +1,71 @@ +package com.gitee.jenkins.entity; + +import com.gitee.jenkins.enums.PullRequestAction; +import com.gitee.jenkins.enums.PullRequestActionDesc; +import com.gitee.jenkins.enums.PullRequestState; +import com.gitee.jenkins.enums.WebHookType; +import lombok.Data; + +import java.util.List; +import java.util.Optional; + +@Data +public class PullRequestWebHook extends WebHook { + + private PullRequestAction action; + + private PullRequestActionDesc actionDesc; + + private PullRequest pullRequest; + + private Integer number; + + private Integer iid; + + private String title; + + private String body; + + private List languages; + + private PullRequestState state; + + private String mergeStatus; + + private String mergeCommitSha; + + private String url; + + private String sourceBranch; + + private TargetRepository sourceRepo; + + private String targetBranch; + + private TargetRepository targetRepo; + + private User author; + + private User updatedBy; + + private User targetUser; + + @Override + public WebHookType getWebHookType() { + return WebHookType.PULL_REQUEST; + } + + @Override + public String getWebHookDescription() { + return super.getHookName() + " iid = " + pullRequest.getNumber() + " merge commit sha = " + pullRequest.getMergeCommitSha(); + } + + @Override + public String getTargetBranch() { + return Optional.ofNullable(pullRequest) + .map(PullRequest::getBase) + .map(Branch::getRef) + .orElse(""); + } + +} diff --git a/src/main/java/com/gitee/jenkins/entity/PushWebHook.java b/src/main/java/com/gitee/jenkins/entity/PushWebHook.java new file mode 100644 index 0000000..6f7e2d5 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/PushWebHook.java @@ -0,0 +1,58 @@ +package com.gitee.jenkins.entity; + +import com.gitee.jenkins.enums.WebHookType; +import lombok.Data; + +import java.util.List; +import java.util.Optional; + +@Data +public class PushWebHook extends WebHook { + + private String ref; + + private String before; + + private String after; + + private Integer totalCommitsCount; + + private Boolean commitsMoreThanTen; + + private Boolean created; + + private Boolean deleted; + + private String compare; + + private List commits; + + private Commit headCommit; + + private Integer userId; + + private String userName; + + private User user; + + private User pusher; + + + @Override + public WebHookType getWebHookType() { + return WebHookType.PUSH; + } + + @Override + public String getWebHookDescription() { + return super.getHookName() + " ref = " + ref + " commit sha = " + after; + } + + @Override + public String getTargetBranch() { + return Optional.ofNullable(ref) + .map(s -> s.replaceFirst("^refs/heads/", "")) + .orElse(""); + } + +} diff --git a/src/main/java/com/gitee/jenkins/entity/Repository.java b/src/main/java/com/gitee/jenkins/entity/Repository.java new file mode 100644 index 0000000..b66b5a8 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/Repository.java @@ -0,0 +1,95 @@ +package com.gitee.jenkins.entity; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +import java.util.Date; + +@Data +public class Repository { + + /** + * 仓库 id + */ + private Integer id; + + /** + * 仓库名称 + */ + private String name; + + private String path; + + /** + * 仓库全名 + */ + private String fullName; + + /** + * 仓库所有人 + */ + private User owner; + + /** + * 是否私有 + */ + @JsonProperty("private") + private Boolean priv; + + private String htmlUrl; + + private String url; + + private String description; + + private Boolean fork; + + private Date createdAt; + + private Date updatedAt; + + private Date pushedAt; + + private String gitUrl; + + private String sshUrl; + + private String cloneUrl; + + private String svnUrl; + + private String gitHttpUrl; + + private String gitSshUrl; + + private String gitSvnUrl; + + private String homepage; + + private Integer stargazersCount; + + private Integer watchersCount; + + private Integer forksCount; + + private String language; + + private Boolean hasIssues; + + private Boolean hasWiki; + + private Boolean hasPages; + + private String license; + + private Integer openIssuesCount; + + private String defaultBranch; + + private String namespace; + + private String nameWithNamespace; + + private String pathWithNamespace; + +} diff --git a/src/main/java/com/gitee/jenkins/entity/TargetRepository.java b/src/main/java/com/gitee/jenkins/entity/TargetRepository.java new file mode 100644 index 0000000..806f660 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/TargetRepository.java @@ -0,0 +1,12 @@ +package com.gitee.jenkins.entity; + +import lombok.Data; + +@Data +public class TargetRepository { + + private Repository project; + + private Repository repository; + +} diff --git a/src/main/java/com/gitee/jenkins/entity/User.java b/src/main/java/com/gitee/jenkins/entity/User.java new file mode 100644 index 0000000..301256e --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/User.java @@ -0,0 +1,96 @@ +package com.gitee.jenkins.entity; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class User { + + /** + * 用户id + */ + private Integer id; + + private String login; + + /** + * 用户名 + */ + private String name; + + private String username; + + private String userName; + + /** + * 头像url + */ + private String avatarUrl; + + /** + * 主页url + */ + private String url; + + private String htmlUrl; + + private String followersUrl; + + private String followingUrl; + + private String gistsUrl; + + private String starredUrl; + + private String subscriptionsUrl; + + private String organizationsUrl; + + private String reposUrl; + + private String eventsUrl; + + private String receivedEventsUrl; + + private String type; + + private String blog; + + private String weibo; + + private String bio; + + private Integer publicRepos; + + private Integer publicGists; + + private Integer followers; + + private Integer following; + + private Integer stared; + + private Integer watched; + + private Date createdAt; + + private Date updatedAt; + + /** + * 邮箱 + */ + private String email; + + /** + * 是否为网站管理员 + */ + private Boolean siteAdmin; + +} diff --git a/src/main/java/com/gitee/jenkins/entity/WebHook.java b/src/main/java/com/gitee/jenkins/entity/WebHook.java new file mode 100644 index 0000000..19cf71e --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/WebHook.java @@ -0,0 +1,54 @@ +package com.gitee.jenkins.entity; + +import com.gitee.jenkins.enums.WebHookType; +import lombok.Data; + +import java.util.Date; + +@Data +public abstract class WebHook { + + private Repository project; + + private Repository repository; + + private User sender; + + private Enterprise enterprise; + + private String hookName; + + private String hookId; + + private String hookUrl; + + private String password; + + private Date timestamp; + + private String sign; + + private String jsonBody; + + /** + * WebHook 类型 + * + * @return + */ + public abstract WebHookType getWebHookType(); + + /** + * WebHook 说明 + * + * @return + */ + public abstract String getWebHookDescription(); + + /** + * 获取构建目标分支 + * + * @return + */ + public abstract String getTargetBranch(); + +} diff --git a/src/main/java/com/gitee/jenkins/entity/WebHookAction.java b/src/main/java/com/gitee/jenkins/entity/WebHookAction.java new file mode 100644 index 0000000..fa490ce --- /dev/null +++ b/src/main/java/com/gitee/jenkins/entity/WebHookAction.java @@ -0,0 +1,17 @@ +package com.gitee.jenkins.entity; + +import hudson.model.Job; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class WebHookAction { + + private Job job; + + private WebHook webHook; + + private String secretToken; + +} diff --git a/src/main/java/com/gitee/jenkins/enums/BranchNameFilterType.java b/src/main/java/com/gitee/jenkins/enums/BranchNameFilterType.java new file mode 100644 index 0000000..39d8c0d --- /dev/null +++ b/src/main/java/com/gitee/jenkins/enums/BranchNameFilterType.java @@ -0,0 +1,21 @@ +package com.gitee.jenkins.enums; + +/** + * 分支名称过滤器类型 + */ +public enum BranchNameFilterType { + + /** + * 允许所有分支触发构建 + */ + ALL, + /** + * 通过分支名过滤 + */ + NAME_FILTER, + /** + * 通过正则表达式过滤 + */ + REGEX_FILTER + +} diff --git a/src/main/java/com/gitee/jenkins/enums/BuildInstructionFilterType.java b/src/main/java/com/gitee/jenkins/enums/BuildInstructionFilterType.java new file mode 100644 index 0000000..40a532c --- /dev/null +++ b/src/main/java/com/gitee/jenkins/enums/BuildInstructionFilterType.java @@ -0,0 +1,28 @@ +package com.gitee.jenkins.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +/** + * 构建指令过滤器类型 + */ +@Getter +@AllArgsConstructor +public enum BuildInstructionFilterType { + + /** + * 无过滤 + */ + NONE(""), + /** + * 包含 [ci-skip] 时跳过构建 + */ + CI_SKIP("[ci-skip]"), + /** + * 包含 [ci-build] 时触发构建 + */ + CI_BUILD("[ci-build]"); + + private String body; + +} diff --git a/src/main/java/com/gitee/jenkins/enums/GiteeClientType.java b/src/main/java/com/gitee/jenkins/enums/GiteeClientType.java new file mode 100644 index 0000000..124222b --- /dev/null +++ b/src/main/java/com/gitee/jenkins/enums/GiteeClientType.java @@ -0,0 +1,10 @@ +package com.gitee.jenkins.enums; + +/** + * Gitee 客户端类型 + */ +public enum GiteeClientType { + + V5 + +} diff --git a/src/main/java/com/gitee/jenkins/enums/PullRequestAction.java b/src/main/java/com/gitee/jenkins/enums/PullRequestAction.java new file mode 100644 index 0000000..154c482 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/enums/PullRequestAction.java @@ -0,0 +1,76 @@ +package com.gitee.jenkins.enums; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.gitee.jenkins.trigger.GiteeTrigger; + +/** + * PR 操作枚举 + */ +public enum PullRequestAction { + + /** + * 新建 + */ + OPEN("open"), + /** + * 修改 + */ + UPDATE("update"), + /** + * 测试通过 + */ + TESTED("tested"), + /** + * 审核通过 + */ + APPROVED("approved"), + /** + * 合并 + */ + MERGE("merge"), + /** + * 关闭 + */ + CLOSE("close"); + + private final String value; + + PullRequestAction(String value) { + this.value = value; + } + + @JsonCreator + public static PullRequestAction parseJson(String str) { + for (PullRequestAction pullRequestAction : values()) { + if (pullRequestAction.value.equals(str)) { + return pullRequestAction; + } + } + return null; + } + + /** + * 是否允许该操作触发构建 + * + * @param giteeTrigger Gitee 触发器 + * @param pullRequestAction 操作 + * @return 是否允许触发构建 + */ + public static boolean allowAction(GiteeTrigger giteeTrigger, PullRequestAction pullRequestAction, PullRequestActionDesc pullRequestActionDesc) { + if (pullRequestAction == UPDATE) { + if (giteeTrigger.getTriggerOnUpdatePullRequest() == PullRequestUpdateType.SOURCE_BRANCH_UPDATED) { + return pullRequestActionDesc == PullRequestActionDesc.SOURCE_BRANCH_CHANGED; + } else if (giteeTrigger.getTriggerOnUpdatePullRequest() == PullRequestUpdateType.TARGET_BRANCH_UPDATED) { + return pullRequestActionDesc == PullRequestActionDesc.TARGET_BRANCH_CHANGED; + } else { + return giteeTrigger.getTriggerOnUpdatePullRequest() == PullRequestUpdateType.BOTH_SOURCE_AND_TARGET_BRANCH_UPDATED; + } + } + return (pullRequestAction == OPEN && giteeTrigger.isTriggerOnOpenPullRequest()) + || (pullRequestAction == TESTED && giteeTrigger.isTriggerOnTestedPullRequest()) + || (pullRequestAction == APPROVED && giteeTrigger.isTriggerOnTestedPullRequest()) + || (pullRequestAction == MERGE && giteeTrigger.isTriggerOnTestedPullRequest()) + || (pullRequestAction == CLOSE && giteeTrigger.isTriggerOnTestedPullRequest()); + } + +} diff --git a/src/main/java/com/gitee/jenkins/enums/PullRequestActionDesc.java b/src/main/java/com/gitee/jenkins/enums/PullRequestActionDesc.java new file mode 100644 index 0000000..14442e5 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/enums/PullRequestActionDesc.java @@ -0,0 +1,29 @@ +package com.gitee.jenkins.enums; + +import com.fasterxml.jackson.annotation.JsonCreator; + +/** + * PR 修改操作 + */ +public enum PullRequestActionDesc { + + TARGET_BRANCH_CHANGED("target_branch_changed"), + SOURCE_BRANCH_CHANGED("source_branch_changed"); + + private String value; + + PullRequestActionDesc(String value) { + this.value = value; + } + + @JsonCreator + public static PullRequestActionDesc parseJson(String str) { + for (PullRequestActionDesc pullRequestActionDesc : values()) { + if (pullRequestActionDesc.value.equals(str)) { + return pullRequestActionDesc; + } + } + return null; + } + +} diff --git a/src/main/java/com/gitee/jenkins/enums/PullRequestCommentAction.java b/src/main/java/com/gitee/jenkins/enums/PullRequestCommentAction.java new file mode 100644 index 0000000..c18a981 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/enums/PullRequestCommentAction.java @@ -0,0 +1,30 @@ +package com.gitee.jenkins.enums; + +import com.fasterxml.jackson.annotation.JsonCreator; + +/** + * PR 评论操作类型 + */ +public enum PullRequestCommentAction { + + COMMENT("comment"), + EDITED("edited"), + DELETED("deleted"); + + private String value; + + PullRequestCommentAction(String value) { + this.value = value; + } + + @JsonCreator + public static PullRequestCommentAction parseJson(String str) { + for (PullRequestCommentAction pullRequestCommentAction : values()) { + if (pullRequestCommentAction.value.equals(str)) { + return pullRequestCommentAction; + } + } + return null; + } + +} diff --git a/src/main/java/com/gitee/jenkins/enums/PullRequestState.java b/src/main/java/com/gitee/jenkins/enums/PullRequestState.java new file mode 100644 index 0000000..7bd6787 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/enums/PullRequestState.java @@ -0,0 +1,71 @@ +package com.gitee.jenkins.enums; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.gitee.jenkins.trigger.GiteeTrigger; +import lombok.Getter; + +/** + * PR 状态枚举 + */ +@Getter +public enum PullRequestState { + + /** + * open + */ + OPEN("open"), + /** + * opened + */ + OPENED("opened"), + /** + * reopened + */ + REOPENED("reopened"), + /** + * updated + */ + UPDATED("updated"), + /** + * merged + */ + MERGED("merged"), + /** + * closed + */ + CLOSED("closed"); + + private String value; + + PullRequestState(String value) { + this.value = value; + } + + @JsonCreator + public static PullRequestState parseJson(String str) { + for (PullRequestState pullRequestState : values()) { + if (pullRequestState.value.equals(str)) { + return pullRequestState; + } + } + return null; + } + /** + * 是否允许该状态触发构建 + * + * @param giteeTrigger Gitee 触发器 + * @param pullRequestState PR 状态 + * @return 是否允许该状态触发构建 + */ + public static boolean allowState(GiteeTrigger giteeTrigger, PullRequestState pullRequestState) { + if (pullRequestState == OPEN || pullRequestState == OPENED || pullRequestState == REOPENED || pullRequestState == UPDATED) { + return giteeTrigger.isTriggerOnOpenPullRequest() + || giteeTrigger.getTriggerOnUpdatePullRequest() != PullRequestUpdateType.NONE + || giteeTrigger.isTriggerOnTestedPullRequest() + || giteeTrigger.isTriggerOnApprovedPullRequest(); + } + return (pullRequestState == MERGED && giteeTrigger.isTriggerOnAcceptedPullRequest()) + || (pullRequestState == CLOSED && giteeTrigger.isTriggerOnClosedPullRequest()); + } + +} diff --git a/src/main/java/com/gitee/jenkins/enums/PullRequestUpdateType.java b/src/main/java/com/gitee/jenkins/enums/PullRequestUpdateType.java new file mode 100644 index 0000000..92bc9e0 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/enums/PullRequestUpdateType.java @@ -0,0 +1,25 @@ +package com.gitee.jenkins.enums; + +/** + * 触发器 PR 修改操作类型 + */ +public enum PullRequestUpdateType { + + /** + * 无 + */ + NONE, + /** + * 原分支修改 + */ + SOURCE_BRANCH_UPDATED, + /** + * 目标分支修改 + */ + TARGET_BRANCH_UPDATED, + /** + * 原分支和目标分支修改 + */ + BOTH_SOURCE_AND_TARGET_BRANCH_UPDATED; + +} diff --git a/src/main/java/com/gitee/jenkins/enums/WebHookEvent.java b/src/main/java/com/gitee/jenkins/enums/WebHookEvent.java new file mode 100644 index 0000000..1e1d9ae --- /dev/null +++ b/src/main/java/com/gitee/jenkins/enums/WebHookEvent.java @@ -0,0 +1,37 @@ +package com.gitee.jenkins.enums; + +/** + * WebHook event + */ +public enum WebHookEvent { + + /** + * 代码推送 + */ + PUSH("Push Hook"), + TAG_PUSH("Tag Push Hook"), + /** + * PR + */ + PULL_REQUEST("Merge Request Hook"), + /** + * 评论 + */ + NOTE("Note Hook"); + + private String value; + + WebHookEvent(String value) { + this.value = value; + } + + public static WebHookEvent getWebHookEvent(String event) { + for (WebHookEvent webHookEvent : values()) { + if (webHookEvent.value.equals(event)) { + return webHookEvent; + } + } + return null; + } + +} diff --git a/src/main/java/com/gitee/jenkins/enums/WebHookType.java b/src/main/java/com/gitee/jenkins/enums/WebHookType.java new file mode 100644 index 0000000..eae2d69 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/enums/WebHookType.java @@ -0,0 +1,94 @@ +package com.gitee.jenkins.enums; + +import com.gitee.jenkins.cause.GiteeWebHookCauseData; +import hudson.markup.EscapedMarkupFormatter; +import jenkins.model.Jenkins; +import org.apache.commons.lang3.StringUtils; + +/** + * WebHook 类型 + */ +public enum WebHookType { + + /** + * 代码推送 + */ + PUSH { + @Override + public String getShortDescription(GiteeWebHookCauseData data) { + String triggeredByUser = data.getTriggeredByUser(); + if (triggeredByUser == null) { + return Messages.GiteeWebHookCause_ShortDescription_PushHook_noUser(); + } else { + return Messages.GiteeWebHookCause_ShortDescription_PushHook(triggeredByUser); + } + } + }, + /** + * PR + */ + PULL_REQUEST { + @Override + public String getShortDescription(GiteeWebHookCauseData data) { + String forkNamespace = StringUtils.equals(data.getSourceNamespace(), data.getTargetBranch()) ? "" : data.getSourceNamespace() + "/"; + if (Jenkins.get().getMarkupFormatter() instanceof EscapedMarkupFormatter || data.getTargetProjectUrl() == null) { + return Messages.GiteeWebHookCause_ShortDescription_PullRequestHook_plain( + String.valueOf(data.getPullRequestIid()), + forkNamespace + data.getSourceBranch(), + data.getTargetBranch() + ); + } else { + return Messages.GiteeWebHookCause_ShortDescription_PullRequestHook_html( + String.valueOf(data.getPullRequestIid()), + forkNamespace + data.getSourceBranch(), + data.getTargetBranch(), + data.getTargetProjectUrl() + ); + } + } + }, + /** + * PR 评论 + */ + PULL_REQUEST_COMMENT { + @Override + public String getShortDescription(GiteeWebHookCauseData data) { + String triggeredByUser = data.getTriggeredByUser(); + String forkNamespace = StringUtils.equals(data.getSourceNamespace(), data.getTargetBranch()) ? "" : data.getSourceNamespace() + "/"; + if (Jenkins.get().getMarkupFormatter() instanceof EscapedMarkupFormatter || data.getTargetProjectUrl() == null) { + return Messages.GiteeWebHookCause_ShortDescription_NoteHook_plain( + triggeredByUser, + String.valueOf(data.getPullRequestIid()), + forkNamespace + data.getSourceBranch(), + data.getTargetBranch() + ); + } else { + return Messages.GiteeWebHookCause_ShortDescription_NoteHook_html( + triggeredByUser, + String.valueOf(data.getPullRequestIid()), + forkNamespace + data.getSourceBranch(), + data.getTargetBranch(), + data.getTargetProjectUrl() + ); + } + } + }, + /** + * commit 评论 + */ + COMMIT_COMMENT { + @Override + public String getShortDescription(GiteeWebHookCauseData data) { + return Messages.GiteeWebHookCause_ShortDescription_Commit_comment(data.getTriggeredByUser()); + } + }; + + /** + * 构建说明 + * + * @param data + * @return + */ + public abstract String getShortDescription(GiteeWebHookCauseData data); + +} diff --git a/src/main/java/com/gitee/jenkins/environment/GiteeEnvironmentContributor.java b/src/main/java/com/gitee/jenkins/environment/GiteeEnvironmentContributor.java index f6312b2..b7c2198 100644 --- a/src/main/java/com/gitee/jenkins/environment/GiteeEnvironmentContributor.java +++ b/src/main/java/com/gitee/jenkins/environment/GiteeEnvironmentContributor.java @@ -3,33 +3,32 @@ package com.gitee.jenkins.environment; import com.gitee.jenkins.cause.GiteeWebHookCause; import hudson.EnvVars; import hudson.Extension; -import hudson.matrix.MatrixRun; import hudson.matrix.MatrixBuild; +import hudson.matrix.MatrixRun; import hudson.model.EnvironmentContributor; import hudson.model.Run; import hudson.model.TaskListener; +import org.jetbrains.annotations.NotNull; -import javax.annotation.Nonnull; import java.io.IOException; -/** - * @author Robin Müller - */ @Extension public class GiteeEnvironmentContributor extends EnvironmentContributor { + @Override - public void buildEnvironmentFor(@Nonnull Run r, @Nonnull EnvVars envs, @Nonnull TaskListener listener) throws IOException, InterruptedException { + public void buildEnvironmentFor(@NotNull Run r, @NotNull EnvVars envs, @NotNull TaskListener listener) throws IOException, InterruptedException { GiteeWebHookCause cause = null; if (r instanceof MatrixRun) { - MatrixBuild parent = ((MatrixRun)r).getParentBuild(); + MatrixBuild parent = ((MatrixRun) r).getParentBuild(); if (parent != null) { - cause = (GiteeWebHookCause) parent.getCause(GiteeWebHookCause.class); + cause = parent.getCause(GiteeWebHookCause.class); } } else { cause = (GiteeWebHookCause) r.getCause(GiteeWebHookCause.class); } if (cause != null) { - envs.overrideAll(cause.getData().getBuildVariables()); + envs.overrideAll(cause.getData().getBuildEnvironmentVariables()); } } + } diff --git a/src/main/java/com/gitee/jenkins/event/GiteeEventResolver.java b/src/main/java/com/gitee/jenkins/event/GiteeEventResolver.java new file mode 100644 index 0000000..c4957f6 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/event/GiteeEventResolver.java @@ -0,0 +1,128 @@ +package com.gitee.jenkins.event; + +import com.gitee.jenkins.entity.WebHook; +import com.gitee.jenkins.entity.WebHookAction; +import com.gitee.jenkins.enums.WebHookEvent; +import hudson.ExtensionList; +import hudson.ExtensionPoint; +import hudson.model.Item; +import hudson.model.Job; +import hudson.security.ACL; +import hudson.security.ACLContext; +import hudson.util.HttpResponses; +import jenkins.model.Jenkins; +import org.apache.commons.io.IOUtils; +import org.kohsuke.stapler.StaplerRequest; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Map; +import java.util.function.Function; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +public abstract class GiteeEventResolver implements ExtensionPoint { + + private static final Logger LOGGER = Logger.getLogger(GiteeEventResolver.class.getName()); + + private static final Map GITEE_EVENT_RESOLVER_MAP; + + static { + GITEE_EVENT_RESOLVER_MAP = ExtensionList.lookup(GiteeEventResolver.class).stream() + .collect(Collectors.toMap(GiteeEventResolver::resolveEvent, Function.identity())); + } + + public static WebHookAction resolve(String projectName, StaplerRequest request) { + WebHookEvent webHookEvent = resolveEvent(request); + return GITEE_EVENT_RESOLVER_MAP.get(webHookEvent) + .process(projectName, request); + } + + /** + * 解析请求 + * + * @param projectName + * @param request + * @return + */ + private WebHookAction process(String projectName, StaplerRequest request) { + String requestBody = resolveRequestBody(request); + WebHook webHook = resolveWebHook(requestBody); + webHook.setJsonBody(requestBody); + String secretToken = request.getHeader("X-Gitee-Token"); + + try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)) { + Job job = resolveProject(projectName); + + return WebHookAction.builder() + .job(job) + .webHook(webHook) + .secretToken(secretToken) + .build(); + } + } + + /** + * 解析请求事件 + * + * @param request + * @return + */ + private static WebHookEvent resolveEvent(StaplerRequest request) { + WebHookEvent webHookEvent = WebHookEvent.getWebHookEvent(request.getHeader("X-Gitee-Event")); + if (webHookEvent != null) { + return webHookEvent; + } + LOGGER.log(Level.INFO, "Missing X-Gitee-Event header"); + throw HttpResponses.errorWithoutStack(HttpServletResponse.SC_BAD_REQUEST, "Unsupported event"); + } + + /** + * 解析请求体 + * + * @param request + * @return + */ + private static String resolveRequestBody(StaplerRequest request) { + try { + Charset charset = request.getCharacterEncoding() == null ? StandardCharsets.UTF_8 : Charset.forName(request.getCharacterEncoding()); + return IOUtils.toString(request.getInputStream(), charset); + } catch (IOException e) { + LOGGER.log(Level.INFO, "Failed to read request body"); + throw HttpResponses.errorWithoutStack(HttpServletResponse.SC_BAD_REQUEST, "Failed to read request body"); + } + } + + /** + * 获取项目 + * + * @param projectName + * @return + */ + private static Job resolveProject(String projectName) { + Item item = Jenkins.get().getItemByFullName(projectName); + if (item instanceof Job) { + return (Job) item; + } + LOGGER.log(Level.INFO, "No project found: {0}", projectName); + throw HttpResponses.errorWithoutStack(HttpServletResponse.SC_BAD_REQUEST, "No project found"); + } + + /** + * 获取 Handler 处理 WebHook 类型 + * + * @return + */ + protected abstract WebHookEvent resolveEvent(); + + /** + * 获取 WebHook + * + * @return + */ + protected abstract WebHook resolveWebHook(String requestBody); + +} diff --git a/src/main/java/com/gitee/jenkins/event/NoteEventResolver.java b/src/main/java/com/gitee/jenkins/event/NoteEventResolver.java new file mode 100644 index 0000000..1df6e57 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/event/NoteEventResolver.java @@ -0,0 +1,30 @@ +package com.gitee.jenkins.event; + +import com.gitee.jenkins.entity.CommitCommentWebHook; +import com.gitee.jenkins.entity.PullRequestCommentWebHook; +import com.gitee.jenkins.entity.WebHook; +import com.gitee.jenkins.enums.WebHookEvent; +import com.gitee.jenkins.util.JsonUtil; +import hudson.Extension; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +@Extension +@Restricted(NoExternalUse.class) +public class NoteEventResolver extends GiteeEventResolver { + + @Override + protected WebHookEvent resolveEvent() { + return WebHookEvent.NOTE; + } + + @Override + protected WebHook resolveWebHook(String requestBody) { + if (JsonUtil.has(requestBody, "pull_request")) { + return JsonUtil.string2Obj(requestBody, PullRequestCommentWebHook.class); + } else { + return JsonUtil.string2Obj(requestBody, CommitCommentWebHook.class); + } + } + +} diff --git a/src/main/java/com/gitee/jenkins/event/PullRequestEventResolver.java b/src/main/java/com/gitee/jenkins/event/PullRequestEventResolver.java new file mode 100644 index 0000000..3859d1e --- /dev/null +++ b/src/main/java/com/gitee/jenkins/event/PullRequestEventResolver.java @@ -0,0 +1,25 @@ +package com.gitee.jenkins.event; + +import com.gitee.jenkins.entity.PullRequestWebHook; +import com.gitee.jenkins.entity.WebHook; +import com.gitee.jenkins.enums.WebHookEvent; +import com.gitee.jenkins.util.JsonUtil; +import hudson.Extension; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +@Extension +@Restricted(NoExternalUse.class) +public class PullRequestEventResolver extends GiteeEventResolver { + + @Override + protected WebHookEvent resolveEvent() { + return WebHookEvent.PULL_REQUEST; + } + + @Override + protected WebHook resolveWebHook(String requestBody) { + return JsonUtil.string2Obj(requestBody, PullRequestWebHook.class); + } + +} diff --git a/src/main/java/com/gitee/jenkins/event/PushEventResolver.java b/src/main/java/com/gitee/jenkins/event/PushEventResolver.java new file mode 100644 index 0000000..d3d488a --- /dev/null +++ b/src/main/java/com/gitee/jenkins/event/PushEventResolver.java @@ -0,0 +1,25 @@ +package com.gitee.jenkins.event; + +import com.gitee.jenkins.entity.PushWebHook; +import com.gitee.jenkins.entity.WebHook; +import com.gitee.jenkins.enums.WebHookEvent; +import com.gitee.jenkins.util.JsonUtil; +import hudson.Extension; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +@Extension +@Restricted(NoExternalUse.class) +public class PushEventResolver extends GiteeEventResolver { + + @Override + protected WebHookEvent resolveEvent() { + return WebHookEvent.PUSH; + } + + @Override + protected WebHook resolveWebHook(String requestBody) { + return JsonUtil.string2Obj(requestBody, PushWebHook.class); + } + +} diff --git a/src/main/java/com/gitee/jenkins/event/TagPushEventResolver.java b/src/main/java/com/gitee/jenkins/event/TagPushEventResolver.java new file mode 100644 index 0000000..34477b1 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/event/TagPushEventResolver.java @@ -0,0 +1,17 @@ +package com.gitee.jenkins.event; + +import com.gitee.jenkins.enums.WebHookEvent; +import hudson.Extension; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +@Extension +@Restricted(NoExternalUse.class) +public class TagPushEventResolver extends PushEventResolver { + + @Override + protected WebHookEvent resolveEvent() { + return WebHookEvent.TAG_PUSH; + } + +} diff --git a/src/main/java/com/gitee/jenkins/excetion/GiteeClientRequestException.java b/src/main/java/com/gitee/jenkins/excetion/GiteeClientRequestException.java new file mode 100644 index 0000000..cb8b937 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/excetion/GiteeClientRequestException.java @@ -0,0 +1,13 @@ +package com.gitee.jenkins.excetion; + +public class GiteeClientRequestException extends Exception { + + public GiteeClientRequestException(String message) { + super(message); + } + + public GiteeClientRequestException(Throwable cause) { + super(cause); + } + +} diff --git a/src/main/java/com/gitee/jenkins/excetion/NoRevisionToBuildException.java b/src/main/java/com/gitee/jenkins/excetion/NoRevisionToBuildException.java new file mode 100644 index 0000000..8c8b90b --- /dev/null +++ b/src/main/java/com/gitee/jenkins/excetion/NoRevisionToBuildException.java @@ -0,0 +1,4 @@ +package com.gitee.jenkins.excetion; + +public class NoRevisionToBuildException extends Exception { +} diff --git a/src/main/java/com/gitee/jenkins/filter/AlreadyBuildCommitFilter.java b/src/main/java/com/gitee/jenkins/filter/AlreadyBuildCommitFilter.java new file mode 100644 index 0000000..2310e0f --- /dev/null +++ b/src/main/java/com/gitee/jenkins/filter/AlreadyBuildCommitFilter.java @@ -0,0 +1,45 @@ +package com.gitee.jenkins.filter; + +import com.gitee.jenkins.entity.PullRequestWebHook; +import com.gitee.jenkins.entity.PushWebHook; +import com.gitee.jenkins.entity.WebHook; +import com.gitee.jenkins.enums.WebHookType; +import com.gitee.jenkins.trigger.GiteeTrigger; +import com.gitee.jenkins.util.BuildUtil; +import hudson.Extension; +import hudson.model.Job; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * 已经构建 commit 过滤器 + */ +@Extension +@Restricted(NoExternalUse.class) +public class AlreadyBuildCommitFilter extends BuildFilter { + + private static final Logger LOGGER = Logger.getLogger(AlreadyBuildCommitFilter.class.getName()); + + @Override + public boolean shouldFilter(WebHookType webHookType) { + return webHookType == WebHookType.PUSH + || webHookType == WebHookType.PULL_REQUEST; + } + + @Override + public boolean doFilter(Job job, GiteeTrigger giteeTrigger, WebHook webHook) { + boolean allowBuild = !giteeTrigger.isSkipLastCommitHasBeenBuild() + || (webHook.getWebHookType() == WebHookType.PUSH && !BuildUtil.hasBeenBuilt(job, ((PushWebHook) webHook).getAfter())) + || (webHook.getWebHookType() == WebHookType.PULL_REQUEST && !BuildUtil.hasBeenBuilt(job, ((PullRequestWebHook) webHook).getMergeCommitSha())); + + if (!allowBuild) { + LOGGER.log(Level.INFO, "Skip the build because ignore last commit has been build"); + } + + return allowBuild; + } + +} diff --git a/src/main/java/com/gitee/jenkins/filter/BranchNameFilter.java b/src/main/java/com/gitee/jenkins/filter/BranchNameFilter.java new file mode 100644 index 0000000..e1a0121 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/filter/BranchNameFilter.java @@ -0,0 +1,67 @@ +package com.gitee.jenkins.filter; + +import com.gitee.jenkins.entity.WebHook; +import com.gitee.jenkins.enums.BranchNameFilterType; +import com.gitee.jenkins.enums.WebHookType; +import com.gitee.jenkins.trigger.GiteeTrigger; +import hudson.Extension; +import hudson.model.Job; +import org.apache.commons.lang3.StringUtils; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; +import org.springframework.util.AntPathMatcher; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * 分支名称过滤器 + */ +@Extension +@Restricted(NoExternalUse.class) +public class BranchNameFilter extends BuildFilter { + + private static final Logger LOGGER = Logger.getLogger(BranchNameFilter.class.getName()); + + private static final AntPathMatcher ANT_PATH_MATCHER = new AntPathMatcher(); + + @Override + public boolean shouldFilter(WebHookType webHookType) { + return webHookType == WebHookType.PUSH + || webHookType == WebHookType.PULL_REQUEST + || webHookType == WebHookType.PULL_REQUEST_COMMENT; + } + + @Override + public boolean doFilter(Job job, GiteeTrigger giteeTrigger, WebHook webHook) { + if (giteeTrigger.getBranchNameFilterType() == BranchNameFilterType.ALL) { + return true; + } + + boolean allowBuild = false; + + if (giteeTrigger.getBranchNameFilterType() == BranchNameFilterType.NAME_FILTER) { + List includeBranchNameList = getNameList(giteeTrigger.getIncludeBranchNames()); + List excludeBranchNameList = getNameList(giteeTrigger.getExcludeBranchNames()); + allowBuild = (includeBranchNameList.isEmpty() || includeBranchNameList.stream().anyMatch(name -> ANT_PATH_MATCHER.match(name, webHook.getTargetBranch()))) + && excludeBranchNameList.stream().noneMatch(name -> ANT_PATH_MATCHER.match(name, webHook.getTargetBranch())); + } else if (giteeTrigger.getBranchNameFilterType() == BranchNameFilterType.REGEX_FILTER) { + allowBuild = StringUtils.isBlank(giteeTrigger.getBranchNameRegex()) + || webHook.getTargetBranch().matches(giteeTrigger.getBranchNameRegex()); + } + + if (!allowBuild) { + LOGGER.log(Level.INFO, "Skip the build because branch name mismatch"); + } + + return allowBuild; + } + + private List getNameList(String names) { + return StringUtils.isBlank(names) ? Collections.emptyList() : Arrays.asList(names.split(",")); + } + +} diff --git a/src/main/java/com/gitee/jenkins/filter/BuildFilter.java b/src/main/java/com/gitee/jenkins/filter/BuildFilter.java new file mode 100644 index 0000000..9da4e19 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/filter/BuildFilter.java @@ -0,0 +1,58 @@ +package com.gitee.jenkins.filter; + +import com.gitee.jenkins.entity.WebHook; +import com.gitee.jenkins.enums.WebHookType; +import com.gitee.jenkins.trigger.GiteeTrigger; +import hudson.ExtensionList; +import hudson.ExtensionPoint; +import hudson.model.Job; + +import java.util.List; + +public abstract class BuildFilter implements ExtensionPoint { + + private static final List BUILD_FILTER_LIST; + + static { + BUILD_FILTER_LIST = ExtensionList.lookup(BuildFilter.class); + } + + /** + * WebHook类型是否需要过滤 + * + * @param webHookType WebHook类型 + * @return + */ + abstract boolean shouldFilter(WebHookType webHookType); + + /** + * 是否允许构建 + * + * @param job 项目 + * @param giteeTrigger gitee触发器 + * @param webHook webHook + * @return 是否允许构建 + */ + abstract boolean doFilter(Job job, GiteeTrigger giteeTrigger, WebHook webHook); + + /** + * 执行过滤 + * + * @param job 项目 + * @param giteeTrigger gitee触发器 + * @param webHook webHook + * @return + */ + public static boolean allowBuild(Job job, GiteeTrigger giteeTrigger, WebHook webHook) { + // 获取所有过滤器 + for (BuildFilter buildFilter : BUILD_FILTER_LIST) { + // 是否需要过滤、是否允许构建 + if (buildFilter.shouldFilter(webHook.getWebHookType()) + && !buildFilter.doFilter(job, giteeTrigger, webHook)) { + return false; + } + } + return true; + } + +} diff --git a/src/main/java/com/gitee/jenkins/filter/BuildInstructionFilter.java b/src/main/java/com/gitee/jenkins/filter/BuildInstructionFilter.java new file mode 100644 index 0000000..ce09960 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/filter/BuildInstructionFilter.java @@ -0,0 +1,67 @@ +package com.gitee.jenkins.filter; + +import com.gitee.jenkins.entity.PullRequestCommentWebHook; +import com.gitee.jenkins.entity.PullRequestWebHook; +import com.gitee.jenkins.entity.PushWebHook; +import com.gitee.jenkins.entity.WebHook; +import com.gitee.jenkins.enums.BuildInstructionFilterType; +import com.gitee.jenkins.enums.WebHookType; +import com.gitee.jenkins.trigger.GiteeTrigger; +import hudson.Extension; +import hudson.model.Job; +import org.apache.commons.collections.CollectionUtils; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * 构建指令过滤器 + */ +@Extension +@Restricted(NoExternalUse.class) +public class BuildInstructionFilter extends BuildFilter { + + private static final Logger LOGGER = Logger.getLogger(BuildInstructionFilter.class.getName()); + + @Override + public boolean shouldFilter(WebHookType webHookType) { + return webHookType == WebHookType.PUSH + || webHookType == WebHookType.PULL_REQUEST + || webHookType == WebHookType.PULL_REQUEST_COMMENT; + } + + @Override + public boolean doFilter(Job job, GiteeTrigger giteeTrigger, WebHook webHook) { + if (giteeTrigger.getBuildInstructionFilterType() == BuildInstructionFilterType.NONE) { + return true; + } + + String body = ""; + if (webHook.getWebHookType() == WebHookType.PUSH) { + PushWebHook pushWebHook = (PushWebHook) webHook; + if (CollectionUtils.isNotEmpty(pushWebHook.getCommits())) { + body = pushWebHook.getCommits().get(pushWebHook.getCommits().size() - 1).getMessage(); + } + } else if (webHook.getWebHookType() == WebHookType.PULL_REQUEST) { + body = ((PullRequestWebHook) webHook).getBody(); + } else if (webHook.getWebHookType() == WebHookType.PULL_REQUEST_COMMENT) { + body = ((PullRequestCommentWebHook) webHook).getPullRequest().getBody(); + } + + boolean allowBuild = false; + if (giteeTrigger.getBuildInstructionFilterType() == BuildInstructionFilterType.CI_SKIP) { + allowBuild = !body.contains(BuildInstructionFilterType.CI_SKIP.getBody()); + } else if (giteeTrigger.getBuildInstructionFilterType() == BuildInstructionFilterType.CI_BUILD) { + allowBuild = body.contains(BuildInstructionFilterType.CI_BUILD.getBody()); + } + + if (!allowBuild) { + LOGGER.log(Level.INFO, "Skip the build because build instruction dissatisfy"); + } + + return allowBuild; + } + +} diff --git a/src/main/java/com/gitee/jenkins/filter/CommentFilter.java b/src/main/java/com/gitee/jenkins/filter/CommentFilter.java new file mode 100644 index 0000000..9a0a53e --- /dev/null +++ b/src/main/java/com/gitee/jenkins/filter/CommentFilter.java @@ -0,0 +1,43 @@ +package com.gitee.jenkins.filter; + +import com.gitee.jenkins.entity.CommitCommentWebHook; +import com.gitee.jenkins.entity.PullRequestCommentWebHook; +import com.gitee.jenkins.entity.WebHook; +import com.gitee.jenkins.enums.WebHookType; +import com.gitee.jenkins.trigger.GiteeTrigger; +import hudson.Extension; +import hudson.model.Job; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * 评论过滤器 + */ +@Extension +@Restricted(NoExternalUse.class) +public class CommentFilter extends BuildFilter { + + private static final Logger LOGGER = Logger.getLogger(CommentFilter.class.getName()); + + @Override + public boolean shouldFilter(WebHookType webHookType) { + return webHookType == WebHookType.PULL_REQUEST_COMMENT + || webHookType == WebHookType.COMMIT_COMMENT; + } + + @Override + public boolean doFilter(Job job, GiteeTrigger giteeTrigger, WebHook webHook) { + boolean allowBuild = (webHook.getWebHookType() == WebHookType.PULL_REQUEST_COMMENT && ((PullRequestCommentWebHook) webHook).getComment().getBody().matches(giteeTrigger.getNoteRegex())) + || (webHook.getWebHookType() == WebHookType.COMMIT_COMMENT && ((CommitCommentWebHook) webHook).getComment().getBody().matches(giteeTrigger.getNoteRegex())); + + if (!allowBuild) { + LOGGER.log(Level.INFO, "Skip the build because the comment mismatch"); + } + + return allowBuild; + } + +} diff --git a/src/main/java/com/gitee/jenkins/filter/ConfigFilter.java b/src/main/java/com/gitee/jenkins/filter/ConfigFilter.java new file mode 100644 index 0000000..378c168 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/filter/ConfigFilter.java @@ -0,0 +1,67 @@ +package com.gitee.jenkins.filter; + +import com.gitee.jenkins.entity.PullRequestWebHook; +import com.gitee.jenkins.entity.PushWebHook; +import com.gitee.jenkins.entity.WebHook; +import com.gitee.jenkins.enums.PullRequestAction; +import com.gitee.jenkins.enums.PullRequestState; +import com.gitee.jenkins.enums.WebHookType; +import com.gitee.jenkins.trigger.GiteeTrigger; +import hudson.Extension; +import hudson.model.Job; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * webhook 配置过滤器 + */ +@Extension +@Restricted(NoExternalUse.class) +public class ConfigFilter extends BuildFilter { + + private static final Logger LOGGER = Logger.getLogger(ConfigFilter.class.getName()); + + private static final String NO_COMMIT = "0000000000000000000000000000000000000000"; + + @Override + public boolean shouldFilter(WebHookType webHookType) { + return true; + } + + @Override + public boolean doFilter(Job job, GiteeTrigger giteeTrigger, WebHook webHook) { + boolean allowBuild = false; + + if (webHook.getWebHookType() == WebHookType.PUSH) { + PushWebHook pushWebHook = (PushWebHook) webHook; + // 是否允许推送触发 且 不是删除推送 + allowBuild = giteeTrigger.isTriggerOnPush() + && !isRemoveBranchPush(pushWebHook); + } else if (webHook.getWebHookType() == WebHookType.PULL_REQUEST) { + PullRequestWebHook pullRequestWebHook = (PullRequestWebHook) webHook; + // 是否允许 PR 相关操作触发 + allowBuild = PullRequestAction.allowAction(giteeTrigger, pullRequestWebHook.getAction(), pullRequestWebHook.getActionDesc()) + && PullRequestState.allowState(giteeTrigger, pullRequestWebHook.getState()); + } else if (webHook.getWebHookType() == WebHookType.PULL_REQUEST_COMMENT) { + // 是否允许评论触发:PR 评论 + allowBuild = giteeTrigger.isTriggerOnNoteRequest(); + } else if (webHook.getWebHookType() == WebHookType.COMMIT_COMMENT) { + // commit 评论 + allowBuild = giteeTrigger.isTriggerOnCommitComment(); + } + + if (!allowBuild) { + LOGGER.log(Level.INFO, "Skip the build because the web hook type configuration is not turned on"); + } + + return allowBuild; + } + + public static boolean isRemoveBranchPush(PushWebHook pushWebHook) { + return pushWebHook.getRef() == null || NO_COMMIT.equals(pushWebHook.getRef()); + } + +} diff --git a/src/main/java/com/gitee/jenkins/filter/PullRequestConflictFilter.java b/src/main/java/com/gitee/jenkins/filter/PullRequestConflictFilter.java new file mode 100644 index 0000000..02fabee --- /dev/null +++ b/src/main/java/com/gitee/jenkins/filter/PullRequestConflictFilter.java @@ -0,0 +1,77 @@ +package com.gitee.jenkins.filter; + +import com.gitee.jenkins.api.client.GiteeClient; +import com.gitee.jenkins.config.GiteeItemConfig; +import com.gitee.jenkins.entity.PullRequest; +import com.gitee.jenkins.entity.PullRequestCommentWebHook; +import com.gitee.jenkins.entity.PullRequestWebHook; +import com.gitee.jenkins.entity.WebHook; +import com.gitee.jenkins.enums.WebHookType; +import com.gitee.jenkins.excetion.GiteeClientRequestException; +import com.gitee.jenkins.publisher.PullRequestBuildStatusPublisher; +import com.gitee.jenkins.trigger.GiteeTrigger; +import hudson.Extension; +import hudson.model.Job; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * PR 冲突过滤器 + */ +@Extension +@Restricted(NoExternalUse.class) +public class PullRequestConflictFilter extends BuildFilter { + + private static final Logger LOGGER = Logger.getLogger(PullRequestConflictFilter.class.getName()); + + @Override + public boolean shouldFilter(WebHookType webHookType) { + return webHookType == WebHookType.PULL_REQUEST || webHookType == WebHookType.PULL_REQUEST_COMMENT; + } + + @Override + public boolean doFilter(Job job, GiteeTrigger giteeTrigger, WebHook webHook) { + if (giteeTrigger.isIgnorePullRequestConflicts()) { + return true; + } + + PullRequest pullRequest = null; + if (webHook.getWebHookType() == WebHookType.PULL_REQUEST) { + pullRequest = ((PullRequestWebHook) webHook).getPullRequest(); + } else if (webHook.getWebHookType() == WebHookType.PULL_REQUEST_COMMENT) { + pullRequest = ((PullRequestCommentWebHook) webHook).getPullRequest(); + } + + boolean allowBuild = pullRequest == null ? false : pullRequest.getMergeable(); + + if (!allowBuild) { + LOGGER.log(Level.INFO, "Skip the build because the Pull Request can\'t be merge"); + + // 发送 PR 冲突评论 + PullRequestBuildStatusPublisher pullRequestBuildStatusPublisher = PullRequestBuildStatusPublisher.getPullRequestBuildStatusPublisher(job); + if (pullRequest != null && pullRequestBuildStatusPublisher != null && !pullRequestBuildStatusPublisher.isOnlyForFailure()) { + GiteeClient giteeClient = GiteeItemConfig.getGiteeClient(job); + if (giteeClient != null) { + try { + String[] path = pullRequest.getBase().getRepo().getPathWithNamespace().split("/"); + giteeClient.submitPullRequestComments( + path[0], + path[1], + pullRequest.getNumber(), + ":bangbang: This pull request can not be merge! The build will not be triggered. Please manual merge conflict." + ); + LOGGER.log(Level.INFO, "send Pull Request conflict message to gitee success"); + } catch (GiteeClientRequestException e) { + LOGGER.log(Level.WARNING, "send Pull Request conflict message error", e); + } + } + } + } + + return allowBuild; + } + +} diff --git a/src/main/java/com/gitee/jenkins/filter/PullRequestTestFilter.java b/src/main/java/com/gitee/jenkins/filter/PullRequestTestFilter.java new file mode 100644 index 0000000..a8aedcd --- /dev/null +++ b/src/main/java/com/gitee/jenkins/filter/PullRequestTestFilter.java @@ -0,0 +1,44 @@ +package com.gitee.jenkins.filter; + +import com.gitee.jenkins.entity.PullRequestCommentWebHook; +import com.gitee.jenkins.entity.PullRequestWebHook; +import com.gitee.jenkins.entity.WebHook; +import com.gitee.jenkins.enums.WebHookType; +import com.gitee.jenkins.trigger.GiteeTrigger; +import hudson.Extension; +import hudson.model.Job; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * PR 是否测试过滤器 + */ +@Extension +@Restricted(NoExternalUse.class) +public class PullRequestTestFilter extends BuildFilter { + + private static final Logger LOGGER = Logger.getLogger(PullRequestTestFilter.class.getName()); + + @Override + public boolean shouldFilter(WebHookType webHookType) { + return webHookType == WebHookType.PULL_REQUEST + || webHookType == WebHookType.PULL_REQUEST_COMMENT; + } + + @Override + public boolean doFilter(Job job, GiteeTrigger giteeTrigger, WebHook webHook) { + boolean allowBuild = !giteeTrigger.isCiSkipFroTestNotRequired() + || (webHook.getWebHookType() == WebHookType.PULL_REQUEST && ((PullRequestWebHook) webHook).getPullRequest().getNeedTest()) + || (webHook.getWebHookType() == WebHookType.PULL_REQUEST_COMMENT && ((PullRequestCommentWebHook) webHook).getPullRequest().getNeedTest()); + + if (!allowBuild) { + LOGGER.log(Level.INFO, "Skip the build because the Pull Request don\'t need test."); + } + + return allowBuild; + } + +} diff --git a/src/main/java/com/gitee/jenkins/gitee/JacksonConfig.java b/src/main/java/com/gitee/jenkins/gitee/JacksonConfig.java deleted file mode 100644 index 77361c1..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/JacksonConfig.java +++ /dev/null @@ -1,26 +0,0 @@ -package com.gitee.jenkins.gitee; - -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; - -import javax.ws.rs.Consumes; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.ext.ContextResolver; -import javax.ws.rs.ext.Provider; - -/** - * @author Robin Müller - */ -@Provider -@Consumes(MediaType.APPLICATION_JSON) -@Produces(MediaType.APPLICATION_JSON) -public class JacksonConfig implements ContextResolver { - public ObjectMapper getContext(Class type) { - return new ObjectMapper() - .setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES) - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) - .configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/GiteeClient.java b/src/main/java/com/gitee/jenkins/gitee/api/GiteeClient.java deleted file mode 100644 index ef71b2e..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/GiteeClient.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.gitee.jenkins.gitee.api; - -import com.gitee.jenkins.gitee.api.model.*; - -public interface GiteeClient { - String getHostUrl(); - - void acceptPullRequest(PullRequest mr, String mergeCommitMessage, boolean shouldRemoveSourceBranch); - - void createPullRequestNote(PullRequest mr, String body); - - User getCurrentUser(); - - -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/GiteeClientBuilder.java b/src/main/java/com/gitee/jenkins/gitee/api/GiteeClientBuilder.java deleted file mode 100644 index 5b691de..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/GiteeClientBuilder.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.gitee.jenkins.gitee.api; - - -import hudson.ExtensionPoint; -import jenkins.model.Jenkins; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - -import javax.annotation.Nonnull; -import java.io.Serializable; -import java.util.ArrayList; -import java.util.List; -import java.util.NoSuchElementException; - -import static java.util.Collections.sort; - -@Restricted(NoExternalUse.class) -public abstract class GiteeClientBuilder implements Comparable, ExtensionPoint, Serializable { - public static GiteeClientBuilder getGiteeClientBuilderById(String id) { - id = "v5"; - for (GiteeClientBuilder provider : getAllGiteeClientBuilders()) { - if (provider.id().equals(id)) { - return provider; - } - } - - throw new NoSuchElementException("unknown client-builder-id: " + id); - } - - public static List getAllGiteeClientBuilders() { - List builders = new ArrayList<>(Jenkins.getInstance().getExtensionList(GiteeClientBuilder.class)); - sort(builders); - return builders; - } - - private final String id; - private final int ordinal; - - protected GiteeClientBuilder(String id, int ordinal) { - this.id = id; - this.ordinal = ordinal; - } - - @Nonnull - public final String id() { - return id; - } - - @Nonnull - public abstract GiteeClient buildClient(String url, String token, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout); - - @Override - public final int compareTo(@Nonnull GiteeClientBuilder other) { - int o = ordinal - other.ordinal; - return o != 0 ? o : id().compareTo(other.id()); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/impl/GiteeApiProxy.java b/src/main/java/com/gitee/jenkins/gitee/api/impl/GiteeApiProxy.java deleted file mode 100644 index b8e015d..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/impl/GiteeApiProxy.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.jenkins.gitee.api.impl; - - -import com.gitee.jenkins.gitee.api.model.*; - - - -interface GiteeApiProxy { - void createPullRequestNote(String owner, String repo, Integer pullRequestId, String body); - void headCurrentUser(); - void acceptPullRequest(String owner, String repo, Integer pullRequestId); - User getCurrentUser(); -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/impl/GiteeV5ApiProxy.java b/src/main/java/com/gitee/jenkins/gitee/api/impl/GiteeV5ApiProxy.java deleted file mode 100644 index c8d49b4..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/impl/GiteeV5ApiProxy.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.gitee.jenkins.gitee.api.impl; - -import com.gitee.jenkins.gitee.api.model.*; -import javax.ws.rs.*; -import javax.ws.rs.core.MediaType; - - -/** - * @author Robin Müller - * @author Yashin Luo - * - */ -@Path("/api/v5") -interface GiteeV5ApiProxy extends GiteeApiProxy { - String ID = "v5"; - @PUT - @Produces(MediaType.APPLICATION_JSON) - @Consumes(MediaType.APPLICATION_FORM_URLENCODED) - @Path("/repos/{ownerPath}/{repoPath}/pulls/{prNumber}/merge") - void acceptPullRequest(@PathParam("ownerPath") String ownerPath, - @PathParam("repoPath") String repoPath, - @PathParam("prNumber") Integer prNumber); - - @POST - @Produces(MediaType.APPLICATION_JSON) - @Consumes(MediaType.APPLICATION_FORM_URLENCODED) - @Path("/repos/{ownerPath}/{repoPath}/pulls/{prNumber}/comments") - void createPullRequestNote(@PathParam("ownerPath") String ownerPath, - @PathParam("repoPath") String repoPath, - @PathParam("prNumber") Integer prNumber, - @FormParam("body") String body); - - @HEAD - @Produces(MediaType.APPLICATION_JSON) - @Path("/user") - void headCurrentUser(); - - @GET - @Produces(MediaType.APPLICATION_JSON) - @Path("/user") - User getCurrentUser(); - -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/impl/GiteeV5ClientBuilder.java b/src/main/java/com/gitee/jenkins/gitee/api/impl/GiteeV5ClientBuilder.java deleted file mode 100644 index 74f62e5..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/impl/GiteeV5ClientBuilder.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.gitee.jenkins.gitee.api.impl; - - -import com.gitee.jenkins.gitee.api.model.PullRequest; -import com.google.common.base.Function; -import hudson.Extension; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - - -@Extension -@Restricted(NoExternalUse.class) -public final class GiteeV5ClientBuilder extends ResteasyGiteeClientBuilder { - private static final int ORDINAL = 3; - private static final Function MERGE_REQUEST_ID_PROVIDER = new Function() { - @Override - public Integer apply(PullRequest pullRequest) { - return pullRequest.getIid(); - } - }; - - public GiteeV5ClientBuilder() { - super(GiteeV5ApiProxy.ID, ORDINAL, GiteeV5ApiProxy.class, MERGE_REQUEST_ID_PROVIDER); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/impl/ResteasyGiteeClient.java b/src/main/java/com/gitee/jenkins/gitee/api/impl/ResteasyGiteeClient.java deleted file mode 100644 index a15dab2..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/impl/ResteasyGiteeClient.java +++ /dev/null @@ -1,41 +0,0 @@ -package com.gitee.jenkins.gitee.api.impl; - - -import com.gitee.jenkins.gitee.api.GiteeClient; -import com.gitee.jenkins.gitee.api.model.*; -import com.google.common.base.Function; - - -final class ResteasyGiteeClient implements GiteeClient { - private final String hostUrl; - private final GiteeApiProxy api; - private final Function pullRequestIdProvider; - - - ResteasyGiteeClient(String hostUrl, GiteeApiProxy api, Function pullRequestIdProvider) { - this.hostUrl = hostUrl; - this.api = api; - this.pullRequestIdProvider = pullRequestIdProvider; - } - - @Override - public final String getHostUrl() { - return hostUrl; - } - - // Gitee v5 don't support commit message and remove source branch - @Override - public void acceptPullRequest(PullRequest mr, String mergeCommitMessage, boolean shouldRemoveSourceBranch) { - api.acceptPullRequest(mr.getRepoOwner(), mr.getRepoPath(), mr.getIid()); - } - - @Override - public void createPullRequestNote(PullRequest mr, String body) { - api.createPullRequestNote(mr.getRepoOwner(), mr.getRepoPath(), mr.getIid(), body); - } - - @Override - public User getCurrentUser() { - return api.getCurrentUser(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/impl/ResteasyGiteeClientBuilder.java b/src/main/java/com/gitee/jenkins/gitee/api/impl/ResteasyGiteeClientBuilder.java deleted file mode 100644 index e2a432b..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/impl/ResteasyGiteeClientBuilder.java +++ /dev/null @@ -1,255 +0,0 @@ -package com.gitee.jenkins.gitee.api.impl; - - -import com.gitee.jenkins.gitee.JacksonConfig; -import com.gitee.jenkins.gitee.api.GiteeClient; -import com.gitee.jenkins.gitee.api.GiteeClientBuilder; -import com.gitee.jenkins.gitee.api.model.PullRequest; -import com.gitee.jenkins.util.JsonUtil; -import com.gitee.jenkins.util.LoggerUtil; -import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider; -import com.google.common.base.Function; -import com.google.common.base.Joiner; -import com.google.common.collect.FluentIterable; -import hudson.ProxyConfiguration; -import hudson.init.InitMilestone; -import hudson.init.Initializer; -import jenkins.model.Jenkins; -import org.apache.commons.io.IOUtils; -import org.apache.commons.lang.StringUtils; -import org.apache.http.auth.AuthScope; -import org.apache.http.auth.UsernamePasswordCredentials; -import org.apache.http.client.CredentialsProvider; -import org.apache.http.impl.client.BasicCredentialsProvider; -import org.apache.http.impl.client.DefaultHttpClient; -import org.jboss.resteasy.client.jaxrs.ClientHttpEngine; -import org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine; -import org.jboss.resteasy.plugins.providers.JaxrsFormProvider; -import org.jboss.resteasy.spi.ResteasyProviderFactory; -import org.kohsuke.accmod.Restricted; -import org.kohsuke.accmod.restrictions.NoExternalUse; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.annotation.Priority; -import javax.ws.rs.Priorities; -import javax.ws.rs.client.ClientRequestContext; -import javax.ws.rs.client.ClientRequestFilter; -import javax.ws.rs.client.ClientResponseContext; -import javax.ws.rs.client.ClientResponseFilter; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.ext.RuntimeDelegate; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.net.InetSocketAddress; -import java.net.MalformedURLException; -import java.net.Proxy; -import java.net.URL; -import java.util.List; -import java.util.Map; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; - -import static java.net.Proxy.Type.HTTP; - - -@Restricted(NoExternalUse.class) -public class ResteasyGiteeClientBuilder extends GiteeClientBuilder { - private static final Logger LOGGER = Logger.getLogger(ResteasyGiteeClientBuilder.class.getName()); - private static final String PRIVATE_TOKEN = "PRIVATE-TOKEN"; - - @Initializer(before = InitMilestone.PLUGINS_STARTED) - public static void setRuntimeDelegate() { - RuntimeDelegate.setInstance(new ResteasyProviderFactory()); - } - - private final Class apiProxyClass; - private final Function pullRequestIdProvider; - - ResteasyGiteeClientBuilder(String id, int ordinal, Class apiProxyClass, Function pullRequestIdProvider) { - super(id, ordinal); - this.apiProxyClass = apiProxyClass; - this.pullRequestIdProvider = pullRequestIdProvider; - } - - @Nonnull - @Override - public final GiteeClient buildClient(String url, String apiToken, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout) { - return buildClient( - url, - apiToken, - Jenkins.getActiveInstance().proxy, - ignoreCertificateErrors, - connectionTimeout, - readTimeout - ); - } - - private GiteeClient buildClient(String url, String apiToken, ProxyConfiguration httpProxyConfig, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout) { - ResteasyClientBuilder builder = new ResteasyClientBuilder(); - - if (ignoreCertificateErrors) { - builder.hostnameVerification(ResteasyClientBuilder.HostnameVerificationPolicy.ANY); - builder.disableTrustManager(); - } - - if (httpProxyConfig != null) { - Proxy proxy = httpProxyConfig.createProxy(getHost(url)); - if (proxy.type() == HTTP) { - InetSocketAddress address = (InetSocketAddress) proxy.address(); - builder.defaultProxy(address.getHostString().replaceFirst("^.*://", ""), - address.getPort(), - address.getHostName().startsWith("https") ? "https" : "http", - httpProxyConfig.getUserName(), - httpProxyConfig.getPassword()); - } - } - - GiteeApiProxy apiProxy = builder - .connectionPoolSize(60) - .maxPooledPerRoute(30) - .establishConnectionTimeout(connectionTimeout, TimeUnit.SECONDS) - .socketTimeout(readTimeout, TimeUnit.SECONDS) - .register(new JacksonJsonProvider()) - .register(new JacksonConfig()) - .register(new ApiHeaderTokenFilter(apiToken)) - .register(new LoggingFilter()) - .register(new RemoveAcceptEncodingFilter()) - .register(new JaxrsFormProvider()) - .build().target(url) - .proxyBuilder(apiProxyClass) - .classloader(apiProxyClass.getClassLoader()) - .build(); - - return new ResteasyGiteeClient(url, apiProxy, pullRequestIdProvider); - } - - private String getHost(String url) { - try { - return new URL(url).getHost(); - } catch (MalformedURLException e) { - return null; - } - } - - @Priority(Priorities.HEADER_DECORATOR) - private static class ApiHeaderTokenFilter implements ClientRequestFilter { - private final String giteeApiToken; - - ApiHeaderTokenFilter(String giteeApiToken) { - this.giteeApiToken = giteeApiToken; - } - - public void filter(ClientRequestContext requestContext) { - requestContext.getHeaders().putSingle(PRIVATE_TOKEN, giteeApiToken); - } - } - - @Priority(Priorities.USER) - private static class LoggingFilter implements ClientRequestFilter, ClientResponseFilter { - @Override - public void filter(ClientRequestContext context) { - if (LOGGER.isLoggable(Level.FINEST)) { - LOGGER.log(Level.FINEST, "Call Gitee:\nHTTP method: {0}\nURL: {1}\nRequest headers: [\n{2}\n]", - LoggerUtil.toArray(context.getMethod(), context.getUri(), toFilteredString(context.getHeaders()))); - } - } - - @Override - public void filter(ClientRequestContext request, ClientResponseContext response) { - if (LOGGER.isLoggable(Level.FINEST)) { - LOGGER.log(Level.FINEST, "Got response from Gitee:\nURL: {0}\nStatus: {1} {2}\nResponse headers: [\n{3}\n]\nResponse body: {4}", - LoggerUtil.toArray(request.getUri(), response.getStatus(), response.getStatusInfo(), toString(response.getHeaders()), - getPrettyPrintResponseBody(response))); - } - } - - private String toFilteredString(MultivaluedMap headers) { - return FluentIterable.from(headers.entrySet()).transform(new HeaderToFilteredString()).join(Joiner.on(",\n")); - } - - private String toString(MultivaluedMap headers) { - return FluentIterable.from(headers.entrySet()).transform(new HeaderToString()).join(Joiner.on(",\n")); - } - - private String getPrettyPrintResponseBody(ClientResponseContext responseContext) { - String responseBody = getResponseBody(responseContext); - if (StringUtils.isNotEmpty(responseBody) && responseContext.getMediaType().equals(MediaType.APPLICATION_JSON_TYPE)) { - return JsonUtil.toPrettyPrint(responseBody); - } - return responseBody; - } - - private String getResponseBody(ClientResponseContext context) { - try (InputStream entityStream = context.getEntityStream()) { - if (entityStream != null) { - byte[] bytes = IOUtils.toByteArray(entityStream); - context.setEntityStream(new ByteArrayInputStream(bytes)); - return new String(bytes); - } - } catch (IOException e) { - LOGGER.log(Level.SEVERE, "Failure during reading the response body", e); - context.setEntityStream(new ByteArrayInputStream(new byte[0])); - } - return ""; - } - - private static class HeaderToFilteredString implements Function>, String> { - @Nullable - @Override - public String apply(@Nullable Map.Entry> input) { - if (input == null) { - return null; - } else if (input.getKey().equals(PRIVATE_TOKEN)) { - return input.getKey() + " = [****FILTERED****]"; - } else { - return input.getKey() + " = [" + Joiner.on(", ").join(input.getValue()) + "]"; - } - } - } - - private static class HeaderToString implements Function>, String> { - @Nullable - @Override - public String apply(@Nullable Map.Entry> input) { - return input == null ? null : input.getKey() + " = [" + Joiner.on(", ").join(input.getValue()) + "]"; - } - } - } - - @Priority(Priorities.HEADER_DECORATOR) - private static class RemoveAcceptEncodingFilter implements ClientRequestFilter { - RemoveAcceptEncodingFilter() {} - @Override - public void filter(ClientRequestContext clientRequestContext) { - clientRequestContext.getHeaders().remove("Accept-Encoding"); - } - } - - private static class ResteasyClientBuilder extends org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder { - private CredentialsProvider proxyCredentials; - - @SuppressWarnings("UnusedReturnValue") - ResteasyClientBuilder defaultProxy(String hostname, int port, final String scheme, String username, String password) { - super.defaultProxy(hostname, port, scheme); - if (username != null && password != null) { - proxyCredentials = new BasicCredentialsProvider(); - proxyCredentials.setCredentials(new AuthScope(hostname, port), new UsernamePasswordCredentials(username, password)); - } - return this; - } - - @SuppressWarnings("deprecation") - @Override - protected ClientHttpEngine initDefaultEngine() { - ApacheHttpClient4Engine httpEngine = (ApacheHttpClient4Engine) super.initDefaultEngine(); - if (proxyCredentials != null) { - ((DefaultHttpClient) httpEngine.getHttpClient()).setCredentialsProvider(proxyCredentials); - } - return httpEngine; - } - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/model/Branch.java b/src/main/java/com/gitee/jenkins/gitee/api/model/Branch.java deleted file mode 100644 index 75f47c7..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/model/Branch.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.gitee.jenkins.gitee.api.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -/** - * @author Robin Müller - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class Branch { - - private String name; - private Boolean protectedBranch; - private Commit commit; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Boolean getProtectedBranch() { - return protectedBranch; - } - - public void setProtectedBranch(Boolean protectedBranch) { - this.protectedBranch = protectedBranch; - } - - public Commit getCommit() { - return commit; - } - - public void setCommit(Commit commit) { - this.commit = commit; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Branch branch = (Branch) o; - return new EqualsBuilder() - .append(name, branch.name) - .append(protectedBranch, branch.protectedBranch) - .append(commit, branch.commit) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(name) - .append(protectedBranch) - .append(commit) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("name", name) - .append("protectedBranch", protectedBranch) - .append("commit", commit) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/model/BuildState.java b/src/main/java/com/gitee/jenkins/gitee/api/model/BuildState.java deleted file mode 100644 index 4686ae5..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/model/BuildState.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.gitee.jenkins.gitee.api.model; - -/** - * @author Robin Müller - */ -public enum BuildState { - pending, running, canceled, success, failed -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/model/Commit.java b/src/main/java/com/gitee/jenkins/gitee/api/model/Commit.java deleted file mode 100644 index 1617566..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/model/Commit.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.gitee.jenkins.gitee.api.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -import java.util.Date; - -/** - * @author Robin Müller - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class Commit { - - private String id; - private String message; - private Date authoredDate; - private String authorName; - private String authorEmail; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public Date getAuthoredDate() { - return authoredDate; - } - - public void setAuthoredDate(Date authoredDate) { - this.authoredDate = authoredDate; - } - - public String getAuthorName() { - return authorName; - } - - public void setAuthorName(String authorName) { - this.authorName = authorName; - } - - public String getAuthorEmail() { - return authorEmail; - } - - public void setAuthorEmail(String authorEmail) { - this.authorEmail = authorEmail; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Commit commit = (Commit) o; - return new EqualsBuilder() - .append(id, commit.id) - .append(message, commit.message) - .append(authoredDate, commit.authoredDate) - .append(authorName, commit.authorName) - .append(authorEmail, commit.authorEmail) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(id) - .append(message) - .append(authoredDate) - .append(authorName) - .append(authorEmail) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("id", id) - .append("message", message) - .append("authoredDate", authoredDate) - .append("authorName", authorName) - .append("authorEmail", authorEmail) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/model/Label.java b/src/main/java/com/gitee/jenkins/gitee/api/model/Label.java deleted file mode 100644 index 69f577d..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/model/Label.java +++ /dev/null @@ -1,118 +0,0 @@ -package com.gitee.jenkins.gitee.api.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -/** - * @author Robin Müller - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class Label { - /* - "name" : "bug", - "color" : "#d9534f", - "description": "Bug reported by user", - "open_issues_count": 1, - "closed_issues_count": 0, - "open_merge_requests_count": 1 - */ - private String name; - private String color; - private String description; - private long openIssuesCount; - private long closedIssuesCount; - private long openPullRequestsCount; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getColor() { - return color; - } - - public void setColor(String color) { - this.color = color; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public long getOpenIssuesCount() { - return openIssuesCount; - } - - public void setOpenIssuesCount(long openIssuesCount) { - this.openIssuesCount = openIssuesCount; - } - - public long getClosedIssuesCount() { - return closedIssuesCount; - } - - public void setClosedIssuesCount(long closedIssuesCount) { - this.closedIssuesCount = closedIssuesCount; - } - - public long getOpenPullRequestsCount() { - return openPullRequestsCount; - } - - public void setOpenPullRequestsCount(long openPullRequestsCount) { - this.openPullRequestsCount = openPullRequestsCount; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Label label = (Label) o; - return new EqualsBuilder() - .append(openIssuesCount, label.openIssuesCount) - .append(closedIssuesCount, label.closedIssuesCount) - .append(openPullRequestsCount, label.openPullRequestsCount) - .append(name, label.name) - .append(color, label.color) - .append(description, label.description) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(name) - .append(color) - .append(description) - .append(openIssuesCount) - .append(closedIssuesCount) - .append(openPullRequestsCount) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("name", name) - .append("color", color) - .append("description", description) - .append("openIssuesCount", openIssuesCount) - .append("closedIssuesCount", closedIssuesCount) - .append("openPullRequestsCount", openPullRequestsCount) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/model/Namespace.java b/src/main/java/com/gitee/jenkins/gitee/api/model/Namespace.java deleted file mode 100644 index 4554868..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/model/Namespace.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.gitee.jenkins.gitee.api.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -/** - * @author Robin Müller - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class Namespace { - - private String path; - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Namespace namespace = (Namespace) o; - return new EqualsBuilder() - .append(path, namespace.path) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(path) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("path", path) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/model/Note.java b/src/main/java/com/gitee/jenkins/gitee/api/model/Note.java deleted file mode 100644 index a78315c..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/model/Note.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.gitee.jenkins.gitee.api.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -import java.util.Date; - - -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class Note { - private Integer id; - private Integer projectId; - private User author; - private Date createdAt; - private Date updatedAt; - private String body; - - public Note() {} - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public Integer getProjectId() { - return projectId; - } - - public void setprojectId(Integer projectId) { - this.projectId = projectId; - } - - public User getAuthor() { - return author; - } - - public void setAuthor(User author) { - this.author = author; - } - - public Date getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(Date createdAt) { - this.createdAt = createdAt; - } - - public Date getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(Date updatedAt) { - this.updatedAt = updatedAt; - } - - public String getBody() { - return body; - } - - public void setBody(String body) { - this.body = body; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Note that = (Note) o; - return new EqualsBuilder() - .append(id, that.id) - .append(projectId, that.projectId) - .append(author, that.author) - .append(createdAt, that.createdAt) - .append(updatedAt, that.updatedAt) - .append(body, that.body) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(id) - .append(projectId) - .append(author) - .append(createdAt) - .append(updatedAt) - .append(body) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("id", id) - .append("projectId", projectId) - .append("author", author) - .append("createdAt", createdAt) - .append("updatedAt", updatedAt) - .append("body", body) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/model/Pipeline.java b/src/main/java/com/gitee/jenkins/gitee/api/model/Pipeline.java deleted file mode 100644 index af13357..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/model/Pipeline.java +++ /dev/null @@ -1,34 +0,0 @@ -package com.gitee.jenkins.gitee.api.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; - -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class Pipeline { - private Integer id; - private String sha; - private String status; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getSha() { - return sha; - } - - public void setSha(String sha) { - this.sha = sha; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/model/Project.java b/src/main/java/com/gitee/jenkins/gitee/api/model/Project.java deleted file mode 100644 index 154d497..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/model/Project.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.gitee.jenkins.gitee.api.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -/** - * @author Robin Müller - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class Project { - - private Integer id; - private String name; - private Namespace namespace; - private String webUrl; - private String sshUrlToRepo; - private String httpUrlToRepo; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Namespace getNamespace() { - return namespace; - } - - public void setNamespace(Namespace namespace) { - this.namespace = namespace; - } - - public String getWebUrl() { - return webUrl; - } - - public void setWebUrl(String webUrl) { - this.webUrl = webUrl; - } - - public String getSshUrlToRepo() { - return sshUrlToRepo; - } - - public void setSshUrlToRepo(String sshUrlToRepo) { - this.sshUrlToRepo = sshUrlToRepo; - } - - public String getHttpUrlToRepo() { - return httpUrlToRepo; - } - - public void setHttpUrlToRepo(String httpUrlToRepo) { - this.httpUrlToRepo = httpUrlToRepo; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Project project = (Project) o; - return new EqualsBuilder() - .append(id, project.id) - .append(name, project.name) - .append(webUrl, project.webUrl) - .append(sshUrlToRepo, project.sshUrlToRepo) - .append(httpUrlToRepo, project.httpUrlToRepo) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(id) - .append(name) - .append(webUrl) - .append(sshUrlToRepo) - .append(httpUrlToRepo) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("id", id) - .append("name", name) - .append("webUrl", webUrl) - .append("sshUrlToRepo", sshUrlToRepo) - .append("httpUrlToRepo", httpUrlToRepo) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/model/PullRequest.java b/src/main/java/com/gitee/jenkins/gitee/api/model/PullRequest.java deleted file mode 100644 index 35f675f..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/model/PullRequest.java +++ /dev/null @@ -1,339 +0,0 @@ -package com.gitee.jenkins.gitee.api.model; - -import com.gitee.jenkins.gitee.hook.model.PullRequestObjectAttributes; -import com.gitee.jenkins.gitee.hook.model.State; -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -import java.util.List; - -/** - * @author Robin Müller - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class PullRequest { - private Integer id; - private Integer iid; - private String sourceBranch; - private String targetBranch; - private Integer projectId; - private String title; - private State state; - private Integer upvotes; - private Integer downvotes; - private User author; - private User assignee; - private Integer sourceProjectId; - private Integer targetProjectId; - private List labels; - private String description; - private Boolean workInProgress; - private Boolean mergeWhenBuildSucceeds; - private String mergeStatus; - private String repoOwner; - private String repoPath; - - public PullRequest() { /* default-constructor for Resteasy-based-api-proxies */ } - - public PullRequest(int id, int iid, String sourceBranch, String targetBranch, String title, - int sourceProjectId, int targetProjectId, - String description, String mergeStatus) { - this.id = id; - this.iid= iid; - this.sourceBranch = sourceBranch; - this.targetBranch = targetBranch; - this.title = title; - this.sourceProjectId = sourceProjectId; - this.projectId = targetProjectId; - this.description = description; - this.mergeStatus = mergeStatus; - } - - public PullRequest(PullRequestObjectAttributes objectAttributes) { - this.id = objectAttributes.getId(); - this.iid= objectAttributes.getNumber(); - this.sourceBranch = objectAttributes.getSourceBranch(); - this.targetBranch = objectAttributes.getTargetBranch(); - this.title = objectAttributes.getTitle(); - this.sourceProjectId = objectAttributes.getSourceProjectId(); - this.projectId = objectAttributes.getTargetProjectId(); - this.description = objectAttributes.getBody(); - this.mergeStatus = objectAttributes.getMergeStatus(); - -// try { - String[] path = objectAttributes.getTarget().getPathWithNamespace().split("/"); - this.repoOwner = path[0]; - this.repoPath = path[1]; -// } catch (Exception e) { -// // do nothing -// } - } - - public PullRequest(int id, int iid, String sourceBranch, String targetBranch, String title, - int sourceProjectId, int targetProjectId, - String description, String mergeStatus, String pathWithNamespace) { - this.id = id; - this.iid= iid; - this.sourceBranch = sourceBranch; - this.targetBranch = targetBranch; - this.title = title; - this.sourceProjectId = sourceProjectId; - this.projectId = targetProjectId; - this.description = description; - this.mergeStatus = mergeStatus; - try { - String[] path = pathWithNamespace.split("/"); - this.repoOwner = path[0]; - this.repoPath = path[1]; - } catch (Exception e) { - // do nothing - } - } - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public Integer getIid() { - return iid; - } - - public void setIid(Integer iid) { - this.iid = iid; - } - - public String getSourceBranch() { - return sourceBranch; - } - - public void setSourceBranch(String sourceBranch) { - this.sourceBranch = sourceBranch; - } - - public String getTargetBranch() { - return targetBranch; - } - - public void setTargetBranch(String targetBranch) { - this.targetBranch = targetBranch; - } - - public Integer getProjectId() { - return projectId; - } - - public void setProjectId(Integer projectId) { - this.projectId = projectId; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public State getState() { - return state; - } - - public void setState(State state) { - this.state = state; - } - - public Integer getUpvotes() { - return upvotes; - } - - public void setUpvotes(Integer upvotes) { - this.upvotes = upvotes; - } - - public Integer getDownvotes() { - return downvotes; - } - - public void setDownvotes(Integer downvotes) { - this.downvotes = downvotes; - } - - public User getAuthor() { - return author; - } - - public void setAuthor(User author) { - this.author = author; - } - - public User getAssignee() { - return assignee; - } - - public void setAssignee(User assignee) { - this.assignee = assignee; - } - - public Integer getSourceProjectId() { - return sourceProjectId; - } - - public void setSourceProjectId(Integer sourceProjectId) { - this.sourceProjectId = sourceProjectId; - } - - public Integer getTargetProjectId() { - return targetProjectId; - } - - public void setTargetProjectId(Integer targetProjectId) { - this.targetProjectId = targetProjectId; - } - - public List getLabels() { - return labels; - } - - public void setLabels(List labels) { - this.labels = labels; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public Boolean getWorkInProgress() { - return workInProgress; - } - - public void setWorkInProgress(Boolean workInProgress) { - this.workInProgress = workInProgress; - } - - public Boolean getMergeWhenBuildSucceeds() { - return mergeWhenBuildSucceeds; - } - - public void setMergeWhenBuildSucceeds(Boolean mergeWhenBuildSucceeds) { - this.mergeWhenBuildSucceeds = mergeWhenBuildSucceeds; - } - - public String getMergeStatus() { - return mergeStatus; - } - - public void setMergeStatus(String mergeStatus) { - this.mergeStatus = mergeStatus; - } - - public String getRepoOwner() { - return repoOwner; - } - - public void setRepoOwner(String repoOwner) { - this.repoOwner = repoOwner; - } - - public String getRepoPath() { - return repoPath; - } - - public void setRepoPath(String repoPath) { - this.repoPath = repoPath; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PullRequest that = (PullRequest) o; - return new EqualsBuilder() - .append(id, that.id) - .append(iid, that.iid) - .append(sourceBranch, that.sourceBranch) - .append(targetBranch, that.targetBranch) - .append(projectId, that.projectId) - .append(title, that.title) - .append(state, that.state) - .append(upvotes, that.upvotes) - .append(downvotes, that.downvotes) - .append(author, that.author) - .append(assignee, that.assignee) - .append(sourceProjectId, that.sourceProjectId) - .append(targetProjectId, that.targetProjectId) - .append(labels, that.labels) - .append(description, that.description) - .append(workInProgress, that.workInProgress) - .append(mergeWhenBuildSucceeds, that.mergeWhenBuildSucceeds) - .append(mergeStatus, that.mergeStatus) - .append(repoPath, that.repoPath) - .append(repoOwner, that.repoOwner) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(id) - .append(iid) - .append(sourceBranch) - .append(targetBranch) - .append(projectId) - .append(title) - .append(state) - .append(upvotes) - .append(downvotes) - .append(author) - .append(assignee) - .append(sourceProjectId) - .append(targetProjectId) - .append(labels) - .append(description) - .append(workInProgress) - .append(mergeWhenBuildSucceeds) - .append(mergeStatus) - .append(repoOwner) - .append(repoPath) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("id", id) - .append("iid", iid) - .append("sourceBranch", sourceBranch) - .append("targetBranch", targetBranch) - .append("projectId", projectId) - .append("title", title) - .append("state", state) - .append("upvotes", upvotes) - .append("downvotes", downvotes) - .append("author", author) - .append("assignee", assignee) - .append("sourceProjectId", sourceProjectId) - .append("targetProjectId", targetProjectId) - .append("labels", labels) - .append("description", description) - .append("workInProgress", workInProgress) - .append("mergeWhenBuildSucceeds", mergeWhenBuildSucceeds) - .append("mergeStatus", mergeStatus) - .append("repoOwner", repoOwner) - .append("repoPath", repoPath) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/api/model/User.java b/src/main/java/com/gitee/jenkins/gitee/api/model/User.java deleted file mode 100644 index 1978710..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/api/model/User.java +++ /dev/null @@ -1,87 +0,0 @@ -package com.gitee.jenkins.gitee.api.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -/** - * @author Robin Müller - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class User { - - private Integer id; - private String name; - private String username; - private String email; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - User user = (User) o; - return new EqualsBuilder() - .append(id, user.id) - .append(name, user.name) - .append(username, user.username) - .append(email, user.email) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(id) - .append(name) - .append(username) - .append(email) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("id", id) - .append("name", name) - .append("username", username) - .append("email", email) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/Action.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/Action.java deleted file mode 100644 index 4a06700..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/Action.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -/** - * @author Robin Müller - */ -public enum Action { - open, update, approved, close, merge, tested -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/ActionDesc.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/ActionDesc.java deleted file mode 100644 index 2e765e5..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/ActionDesc.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -/** - * @author Yashin Luo - */ -public enum ActionDesc { - target_branch_changed, source_branch_changed -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/BranchData.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/BranchData.java deleted file mode 100644 index 5e8e598..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/BranchData.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -/** - * @author Yashin - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class BranchData { - - private String label; - private String ref; - private String sha; - private User user; - private Project repo; - - public String getLabel() { - return label; - } - - public void setLabel(String label) { - this.label = label; - } - - public String getRef() { - return ref; - } - - public void setRef(String ref) { - this.ref = ref; - } - - public String getSha() { - return sha; - } - - public void setSha(String sha) { - this.sha = sha; - } - - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - - public Project getRepo() { - return repo; - } - - public void setRepo(Project repo) { - this.repo = repo; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - BranchData branchData = (BranchData) o; - return new EqualsBuilder() - .append(label, branchData.label) - .append(sha, branchData.sha) - .append(ref, branchData.ref) - .append(user, branchData.user) - .append(repo, branchData.repo) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(label) - .append(sha) - .append(ref) - .append(user) - .append(repo) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("label", label) - .append("sha", sha) - .append("ref", ref) - .append("user", user) - .append("repo", repo) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/Commit.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/Commit.java deleted file mode 100644 index 454aeb1..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/Commit.java +++ /dev/null @@ -1,138 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -import java.util.Date; -import java.util.List; - -/** - * @author Robin Müller - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class Commit { - - private String id; - private String message; - private Date timestamp; - private String url; - private User author; - private List added; - private List modified; - private List removed; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - public String getMessage() { - return message; - } - - public void setMessage(String message) { - this.message = message; - } - - public Date getTimestamp() { - return timestamp; - } - - public void setTimestamp(Date timestamp) { - this.timestamp = timestamp; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public User getAuthor() { - return author; - } - - public void setAuthor(User author) { - this.author = author; - } - - public List getAdded() { - return added; - } - - public void setAdded(List added) { - this.added = added; - } - - public List getModified() { - return modified; - } - - public void setModified(List modified) { - this.modified = modified; - } - - public List getRemoved() { - return removed; - } - - public void setRemoved(List removed) { - this.removed = removed; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Commit commit = (Commit) o; - return new EqualsBuilder() - .append(id, commit.id) - .append(message, commit.message) - .append(timestamp, commit.timestamp) - .append(url, commit.url) - .append(author, commit.author) - .append(added, commit.added) - .append(modified, commit.modified) - .append(removed, commit.removed) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(id) - .append(message) - .append(timestamp) - .append(url) - .append(author) - .append(added) - .append(modified) - .append(removed) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("id", id) - .append("message", message) - .append("timestamp", timestamp) - .append("url", url) - .append("author", author) - .append("added", added) - .append("modified", modified) - .append("removed", removed) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/NoteAction.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/NoteAction.java deleted file mode 100644 index 88d9774..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/NoteAction.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -/** - * @author Yashin Luo - */ -public enum NoteAction { - comment, edited, deleted -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/NoteHook.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/NoteHook.java deleted file mode 100644 index 75571a5..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/NoteHook.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -/** - * @author Nikolay Ustinov - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class NoteHook extends WebHook { - - private User user; - private Project project; - private PullRequestObjectAttributes pullRequest; - private NoteObjectAttributes comment; - private NoteAction action; - - public NoteAction getAction() { - return action; - } - - public void setAction(NoteAction action) { - this.action = action; - } - - public User getUser() { - return user; - } - public void setUser(User user) { - this.user = user; - } - - public Project getProject() { - return project; - } - - public void setProject(Project project) { - this.project = project; - } - - public NoteObjectAttributes getComment() { - return comment; - } - - public void setComment(NoteObjectAttributes comment) { - this.comment = comment; - } - - public PullRequestObjectAttributes getPullRequest() { - return pullRequest; - } - - public void setPullRequest(PullRequestObjectAttributes pullRequest) { - this.pullRequest = pullRequest; - } - - public String getWebHookDescription() { - // 兼容commit评论 - if (pullRequest == null) { - return getHookName() + " commit sha = " + comment.getCommitId(); - } - - return getHookName() + " iid = " + pullRequest.getNumber() + " merge commit sha = " + pullRequest.getMergeCommitSha(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - NoteHook that = (NoteHook) o; - return new EqualsBuilder() - .append(user, that.user) - .append(action, that.action) - .append(project, that.project) - .append(comment, that.comment) - .append(pullRequest, that.pullRequest) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(user) - .append(action) - .append(project) - .append(comment) - .append(pullRequest) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("user", user) - .append("action", action) - .append("project", project) - .append("comment", comment) - .append("pullRequest", pullRequest) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/NoteObjectAttributes.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/NoteObjectAttributes.java deleted file mode 100644 index 9ac2cf1..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/NoteObjectAttributes.java +++ /dev/null @@ -1,149 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -import java.util.Date; - -/** - * @author Nikolay Ustinov - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class NoteObjectAttributes { - - private Integer id; - private String body; - private Integer authorId; - private Integer projectId; - private Date createdAt; - private Date updatedAt; - private String htmlUrl; - private String commitId; - private User user; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public Integer getProjectId() { - return projectId; - } - - public void setProjectId(Integer projectId) { - this.projectId = projectId; - } - - public Integer getAuthorId() { - return authorId; - } - - public void setAuthorId(Integer authorId) { - this.authorId = authorId; - } - - public Date getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(Date createdAt) { - this.createdAt = createdAt; - } - - public Date getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(Date updatedAt) { - this.updatedAt = updatedAt; - } - - public String getBody() { - return body; - } - - public void setBody(String body) { - this.body = body; - } - - public String getHtmlUrl() { - return htmlUrl; - } - - public void setHtmlUrl(String htmlUrl) { - this.htmlUrl = htmlUrl; - } - - public String getCommitId() { - return commitId; - } - - public void setCommitId(String commitId) { - this.commitId = commitId; - } - - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - NoteObjectAttributes that = (NoteObjectAttributes) o; - return new EqualsBuilder() - .append(id, that.id) - .append(body, that.body) - .append(projectId, that.projectId) - .append(authorId, that.authorId) - .append(createdAt, that.createdAt) - .append(updatedAt, that.updatedAt) - .append(htmlUrl, that.htmlUrl) - .append(commitId, that.commitId) - .append(user, that.user) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(id) - .append(body) - .append(projectId) - .append(authorId) - .append(createdAt) - .append(updatedAt) - .append(htmlUrl) - .append(commitId) - .append(user) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("id", id) - .append("body", body) - .append("projectId", projectId) - .append("authorId", authorId) - .append("createdAt", createdAt) - .append("updatedAt", updatedAt) - .append("htmlUrl", htmlUrl) - .append("commitId", commitId) - .append("user", user) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/PipelineEventObjectAttributes.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/PipelineEventObjectAttributes.java deleted file mode 100644 index fd32d24..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/PipelineEventObjectAttributes.java +++ /dev/null @@ -1,166 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -import java.util.Date; -import java.util.List; - -/** - * @author Milena Zachow - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class PipelineEventObjectAttributes { - - private Integer id; - private String ref; - private boolean tag; - private String sha; - private String beforeSha; - private String status; - private List stages; - private Date createdAt; - private Date finishedAt; - private int duration; - - public String getRef() { - return ref; - } - - public void setRef(String ref) { - this.ref = ref; - } - - public boolean getIsTag() { - return tag; - } - - public void setTag(boolean tag) { - this.tag = tag; - } - - public String getSha() { - return sha; - } - - public void setSha(String sha) { - this.sha = sha; - } - - public String getBeforeSha() { - return beforeSha; - } - - public void setBeforeSha(String beforeSha) { - this.beforeSha = beforeSha; - } - - public String getStatus() { - return status; - } - - public void setStatus(String status) { - this.status = status; - } - - public List getStages() { - return stages; - } - - public void setStages(List stages) { - this.stages = stages; - } - - public Date getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(Date createdAt) { - this.createdAt = createdAt; - } - - public Date getFinishedAt() { - return finishedAt; - } - - public void setFinishedAt(Date finishedAt) { - this.finishedAt = finishedAt; - } - - public int getDuration() { - return duration; - } - - public void setDuration(int duration) { - this.duration = duration; - } - - - - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PipelineEventObjectAttributes that = (PipelineEventObjectAttributes) o; - return new EqualsBuilder() - .append(id, that.id) - .append(ref, that.ref) - .append(tag, that.tag) - .append(sha, that.sha) - .append(beforeSha, that.beforeSha) - .append(status, that.status) - .append(stages, that.stages) - .append(createdAt, that.createdAt) - .append(finishedAt, that.finishedAt) - .append(duration, that.duration) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(id) - .append(ref) - .append(tag) - .append(sha) - .append(beforeSha) - .append(status) - .append(stages) - .append(createdAt) - .append(finishedAt) - .append(duration) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("id", id) - .append("ref", ref) - .append("tag", tag) - .append("sha", sha) - .append("beforeSha", beforeSha) - .append("status", status) - .append("stages", stages) - .append("createdAt", createdAt) - .append("finishedAt", finishedAt) - .append("duration", duration) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/PipelineHook.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/PipelineHook.java deleted file mode 100644 index 9dcac01..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/PipelineHook.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -import java.util.List; - - -/** - * @author Milena Zachow - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class PipelineHook extends WebHook { - - private User user; - public Integer projectId; - private List commits; - private Project project; - private PipelineEventObjectAttributes objectAttributes; - - public Integer getProjectId() { - return projectId; - } - - public void setProjectId(Integer projectId) { - this.projectId = projectId; - } - - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - - public List getCommits() { - return commits; - } - - public void setCommits(List commits) { - this.commits = commits; - } - - public Project getProject() { - return project; - } - - public void setProject(Project project) { - this.project = project; - } - - public PipelineEventObjectAttributes getObjectAttributes() { - return objectAttributes; - } - - public void setObjectAttributes(PipelineEventObjectAttributes objectAttributes) { - this.objectAttributes = objectAttributes; - - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PipelineHook that = (PipelineHook) o; - return new EqualsBuilder() - .append(user, that.user) - .append(project, that.project) - .append(projectId, that.projectId) - .append(commits, that.commits) - .append(objectAttributes, that.objectAttributes) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(user) - .append(projectId) - .append(project) - .append(commits) - .append(objectAttributes) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("user", user) - .append("project", project) - .append("projectId", projectId) - .append("objectAttributes", objectAttributes) - .append("commits", commits) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/Project.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/Project.java deleted file mode 100644 index ced474b..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/Project.java +++ /dev/null @@ -1,195 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -/** - * @author Robin Müller - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class Project { - - private Integer id; - private String name; - private String description; - private String webUrl; - private String avatarUrl; - private String namespace; -// private Integer visibilityLevel; - private String pathWithNamespace; - private String defaultBranch; - private String homepage; - private String url; - private String sshUrl; - private String gitHttpUrl; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getWebUrl() { - return webUrl; - } - - public void setWebUrl(String webUrl) { - this.webUrl = webUrl; - } - - public String getAvatarUrl() { - return avatarUrl; - } - - public void setAvatarUrl(String avatarUrl) { - this.avatarUrl = avatarUrl; - } - - public String getNamespace() { - return namespace; - } - - public void setNamespace(String namespace) { - this.namespace = namespace; - } - -// public Integer getVisibilityLevel() { -// return visibilityLevel; -// } - -// public void setVisibilityLevel(Integer visibilityLevel) { -// this.visibilityLevel = visibilityLevel; -// } - - public String getPathWithNamespace() { - return pathWithNamespace; - } - - public void setPathWithNamespace(String pathWithNamespace) { - this.pathWithNamespace = pathWithNamespace; - } - - public String getDefaultBranch() { - return defaultBranch; - } - - public void setDefaultBranch(String defaultBranch) { - this.defaultBranch = defaultBranch; - } - - public String getHomepage() { - return homepage; - } - - public void setHomepage(String homepage) { - this.homepage = homepage; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getSshUrl() { - return sshUrl; - } - - public void setSshUrl(String sshUrl) { - this.sshUrl = sshUrl; - } - - public String getGitHttpUrl() { - return gitHttpUrl; - } - - public void setGitHttpUrl(String gitHttpUrl) { - this.gitHttpUrl = gitHttpUrl; - } - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Project project = (Project) o; - return new EqualsBuilder() - .append(id, project.id) - .append(name, project.name) - .append(description, project.description) - .append(webUrl, project.webUrl) - .append(avatarUrl, project.avatarUrl) - .append(namespace, project.namespace) -// .append(visibilityLevel, project.visibilityLevel) - .append(pathWithNamespace, project.pathWithNamespace) - .append(defaultBranch, project.defaultBranch) - .append(homepage, project.homepage) - .append(url, project.url) - .append(sshUrl, project.sshUrl) - .append(gitHttpUrl, project.gitHttpUrl) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(id) - .append(name) - .append(description) - .append(webUrl) - .append(avatarUrl) - .append(namespace) -// .append(visibilityLevel) - .append(pathWithNamespace) - .append(defaultBranch) - .append(homepage) - .append(url) - .append(sshUrl) - .append(gitHttpUrl) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("id", id) - .append("name", name) - .append("description", description) - .append("webUrl", webUrl) - .append("avatarUrl", avatarUrl) - .append("namespace", namespace) -// .append("visibilityLevel", visibilityLevel) - .append("pathWithNamespace", pathWithNamespace) - .append("defaultBranch", defaultBranch) - .append("homepage", homepage) - .append("url", url) - .append("sshUrl", sshUrl) - .append("gitHttpUrl", gitHttpUrl) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/PullRequestHook.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/PullRequestHook.java deleted file mode 100644 index 80cef03..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/PullRequestHook.java +++ /dev/null @@ -1,143 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -import java.util.List; - -/** - * @author Robin Müller - * @author Yashin Luo - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class PullRequestHook extends WebHook { - - private User user; - private User assignee; - private Project repo; - private Action action; - private ActionDesc actionDesc; - private State state; - private PullRequestObjectAttributes pullRequest; - private List labels; - - public Action getAction() { - return action; - } - - public ActionDesc getActionDesc() { - return actionDesc; - } - - public void setAction(Action action) { - this.action = action; - } - - public void setActionDesc(ActionDesc actionDesc) { - this.actionDesc = actionDesc; - } - - public State getState() { - return this.state; - } - - public void setState(State state) { - this.state = state; - } - - public User getUser() { - return user; - } - - public void setUser(User user) { - this.user = user; - } - - public User getAssignee() { - return assignee; - } - - public void setAssignee(User assignee) { - this.assignee = assignee; - } - - public Project getRepo() { - return repo; - } - - public void setRepo(Project repo) { - this.repo = repo; - } - - public PullRequestObjectAttributes getPullRequest() { - return pullRequest; - } - - public void setPullRequest(PullRequestObjectAttributes pullRequest) { - this.pullRequest = pullRequest; - } - - public List getLabels() { - return labels; - } - - public void setLabels(List labels) { - this.labels = labels; - } - - public String getWebHookDescription() { - return getHookName() + " iid = " + pullRequest.getNumber() + " merge commit sha = " + pullRequest.getMergeCommitSha(); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PullRequestHook that = (PullRequestHook) o; - return new EqualsBuilder() - .append(user, that.user) - .append(assignee, that.assignee) - .append(repo, that.repo) - .append(action, that.action) - .append(actionDesc, that.actionDesc) - .append(state, that.state) - .append(pullRequest, that.pullRequest) - .append(labels, that.labels) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(user) - .append(assignee) - .append(repo) - .append(pullRequest) - .append(labels) - .append(state) - .append(action) - .append(actionDesc) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("user", user) - .append("assignee", assignee) - .append("repo", repo) - .append("state", state) - .append("action", action) - .append("actionDesc", actionDesc) - .append("pullRequest", pullRequest) - .append("labels", labels) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/PullRequestLabel.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/PullRequestLabel.java deleted file mode 100644 index 07f628a..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/PullRequestLabel.java +++ /dev/null @@ -1,173 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -import java.util.Date; - -/** - * @author Benjamin ROBIN - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class PullRequestLabel { - - /* - "id": 206, - "title": "API", - "color": "#ffffff", - "project_id": 14, - "created_at": "2013-12-03T17:15:43Z", - "updated_at": "2013-12-03T17:15:43Z", - "template": false, - "description": "API related issues", - "type": "ProjectLabel", - "group_id": 41 - */ - private Integer id; - private String title; - private String color; - private Integer projectId; - private Date createdAt; - private Date updatedAt; - private Boolean template; - private String description; - private String type; - private Integer groupId; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getColor() { - return color; - } - - public void setColor(String color) { - this.color = color; - } - - public Integer getProjectId() { - return projectId; - } - - public void setProjectId(Integer projectId) { - this.projectId = projectId; - } - - public Date getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(Date createdAt) { - this.createdAt = createdAt; - } - - public Date getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(Date updatedAt) { - this.updatedAt = updatedAt; - } - - public Boolean getTemplate() { - return template; - } - - public void setTemplate(Boolean template) { - this.template = template; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public Integer getGroupId() { - return groupId; - } - - public void setGroupId(Integer groupId) { - this.groupId = groupId; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PullRequestLabel that = (PullRequestLabel) o; - return new EqualsBuilder() - .append(id, that.id) - .append(title, that.title) - .append(color, that.color) - .append(projectId, that.projectId) - .append(createdAt, that.createdAt) - .append(updatedAt, that.updatedAt) - .append(template, that.template) - .append(description, that.description) - .append(type, that.type) - .append(groupId, that.groupId) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(id) - .append(title) - .append(color) - .append(projectId) - .append(createdAt) - .append(updatedAt) - .append(template) - .append(description) - .append(type) - .append(groupId) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("id", id) - .append("title", title) - .append("color", color) - .append("projectId", projectId) - .append("createdAt", createdAt) - .append("updatedAt", updatedAt) - .append("template", template) - .append("description", description) - .append("type", type) - .append("groupId", groupId) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/PullRequestObjectAttributes.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/PullRequestObjectAttributes.java deleted file mode 100644 index cc78785..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/PullRequestObjectAttributes.java +++ /dev/null @@ -1,286 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -import java.util.Date; - -/** - * @author Robin Müller - * @author Yashin - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class PullRequestObjectAttributes { - private Integer id; - private Integer number; - private Integer authorId; - private Integer assigneeId; - private String title; - private Date createdAt; - private Date updatedAt; - private String body; - private BranchData head; - private BranchData base; - private String mergeStatus; - private boolean mergeable; - private boolean needReview; - private boolean needTest; - private String mergeCommitSha; - private String mergeReferenceName; - private String htmlUrl; - private Boolean workInProgress; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public Integer getNumber() { - return number; - } - - public void setNumber(Integer number) { - this.number = number; - } - - public String getSourceBranch() { - return head.getRef(); - } - - public String getTargetBranch() { - return base.getRef(); - } - - public Integer getSourceProjectId() { - return head.getRepo().getId(); - } - - public Integer getTargetProjectId() { - return base.getRepo().getId(); - } - - public Integer getAuthorId() { - return authorId; - } - - public void setAuthorId(Integer authorId) { - this.authorId = authorId; - } - - public Integer getAssigneeId() { - return assigneeId; - } - - public void setAssigneeId(Integer assigneeId) { - this.assigneeId = assigneeId; - } - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public Date getCreatedAt() { - return createdAt; - } - - public void setCreatedAt(Date createdAt) { - this.createdAt = createdAt; - } - - public Date getUpdatedAt() { - return updatedAt; - } - - public void setUpdatedAt(Date updatedAt) { - this.updatedAt = updatedAt; - } - - public String getBody() { - return body; - } - - public void setBody(String body) { - this.body = body; - } - - public Project getSource() { - return head.getRepo(); - } - - public BranchData getHead() { - return head; - } - - public void setHead(BranchData head) { - this.head = head; - } - - public BranchData getBase() { - return base; - } - - public void setBase(BranchData base) { - this.base = base; - } - - public Project getTarget() { - return base.getRepo(); - } - - public boolean getNeedTest() { - return needTest; - } - - public void setNeedTest(boolean needTest) { - this.needTest = needTest; - } - - public boolean getNeedReview() { - return needReview; - } - - public void setNeedReview(boolean needReview) { - this.needReview = needReview; - } - - public String getMergeCommitSha() { - return mergeCommitSha; - } - - public void setMergeCommitSha(String mergeCommitSha) { - this.mergeCommitSha = mergeCommitSha; - } - - public String getMergeReferenceName() { - return mergeReferenceName; - } - - public void setMergeReferenceName(String mergeReferenceName) { - this.mergeReferenceName = mergeReferenceName; - } - - public String getMergeStatus() { - return mergeStatus; - } - - public void setMergeStatus(String mergeStatus) { - this.mergeStatus = mergeStatus; - } - - public String getHtmlUrl() { - return htmlUrl; - } - - public void setHtmlUrl(String htmlUrl) { - this.htmlUrl = htmlUrl; - } - - public Boolean getWorkInProgress() { - return workInProgress; - } - - public void setWorkInProgress(Boolean workInProgress) { - this.workInProgress = workInProgress; - } - - public boolean getMergeable() { - return mergeable; - } - - public void setMergeable(boolean mergeable) { - this.mergeable = mergeable; - } - - public boolean isMergeable() { - return mergeable; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PullRequestObjectAttributes that = (PullRequestObjectAttributes) o; - return new EqualsBuilder() - .append(id, that.id) - .append(number, that.number) - .append(authorId, that.authorId) - .append(assigneeId, that.assigneeId) - .append(title, that.title) - .append(createdAt, that.createdAt) - .append(updatedAt, that.updatedAt) - .append(body, that.body) - .append(head, that.head) - .append(base, that.base) - .append(mergeCommitSha, that.mergeCommitSha) - .append(mergeReferenceName, that.mergeReferenceName) - .append(mergeStatus, that.mergeStatus) - .append(mergeable, that.mergeable) - .append(needReview, that.needReview) - .append(needTest, that.needTest) - .append(htmlUrl, that.htmlUrl) - .append(workInProgress, that.workInProgress) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(id) - .append(number) - .append(authorId) - .append(assigneeId) - .append(title) - .append(createdAt) - .append(updatedAt) - .append(body) - .append(head) - .append(base) - .append(mergeStatus) - .append(mergeable) - .append(needReview) - .append(needTest) - .append(mergeCommitSha) - .append(mergeReferenceName) - .append(htmlUrl) - .append(workInProgress) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("id", id) - .append("number", number) - .append("authorId", authorId) - .append("assigneeId", assigneeId) - .append("title", title) - .append("createdAt", createdAt) - .append("updatedAt", updatedAt) - .append("body", body) - .append("head", head) - .append("base", base) - .append("mergeCommitSha", mergeCommitSha) - .append("mergeReferenceName", mergeReferenceName) - .append("mergeStatus", mergeStatus) - .append("mergeable", mergeable) - .append("needReview", needReview) - .append("needTest", needTest) - .append("htmlUrl", htmlUrl) - .append("workInProgress", workInProgress) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/PushHook.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/PushHook.java deleted file mode 100644 index ed3189d..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/PushHook.java +++ /dev/null @@ -1,194 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -import java.util.List; - -/** - * @author Robin Müller - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class PushHook extends WebHook { - - private String before; - private String after; - private boolean created; - private boolean deleted; - private String ref; - private Integer userId; - private String userName; - private String userEmail; - private String userAvatar; - private Project project; - private List commits; - private Integer totalCommitsCount; - - public String getBefore() { - return before; - } - - public void setBefore(String before) { - this.before = before; - } - - public boolean getCreated() { - return created; - } - - public void setCreated(boolean created) { - this.created = created; - } - - public boolean getDeleted() { - return deleted; - } - - public void setDeleted(boolean deleted) { - this.deleted = deleted; - } - - - public String getAfter() { - return after; - } - - public void setAfter(String after) { - this.after = after; - } - - public String getRef() { - return ref; - } - - public void setRef(String ref) { - this.ref = ref; - } - - public Integer getUserId() { - return userId; - } - - public void setUserId(Integer userId) { - this.userId = userId; - } - - public String getUserName() { - return userName; - } - - public void setUserName(String userName) { - this.userName = userName; - } - - public String getUserEmail() { - return userEmail; - } - - public void setUserEmail(String userEmail) { - this.userEmail = userEmail; - } - - public String getUserAvatar() { - return userAvatar; - } - - public void setUserAvatar(String userAvatar) { - this.userAvatar = userAvatar; - } - - public Integer getProjectId() { - return getProject().getId(); - } - - public Project getProject() { - return project; - } - - public void setProject(Project project) { - this.project = project; - } - - public List getCommits() { - return commits; - } - - public void setCommits(List commits) { - this.commits = commits; - } - - public Integer getTotalCommitsCount() { - return totalCommitsCount; - } - - public void setTotalCommitsCount(Integer totalCommitsCount) { - this.totalCommitsCount = totalCommitsCount; - } - - public String getWebHookDescription() { - return getHookName() + " ref = " + ref + " commit sha = " + after; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PushHook pushHook = (PushHook) o; - return new EqualsBuilder() - .append(before, pushHook.before) - .append(created, pushHook.created) - .append(deleted, pushHook.deleted) - .append(after, pushHook.after) - .append(ref, pushHook.ref) - .append(userId, pushHook.userId) - .append(userName, pushHook.userName) - .append(userEmail, pushHook.userEmail) - .append(userAvatar, pushHook.userAvatar) - .append(project, pushHook.project) - .append(commits, pushHook.commits) - .append(totalCommitsCount, pushHook.totalCommitsCount) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(before) - .append(after) - .append(ref) - .append(created) - .append(deleted) - .append(userId) - .append(userName) - .append(userEmail) - .append(userAvatar) - .append(project) - .append(commits) - .append(totalCommitsCount) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("before", before) - .append("after", after) - .append("ref", ref) - .append("created", created) - .append("deleted", deleted) - .append("userId", userId) - .append("userName", userName) - .append("userEmail", userEmail) - .append("userAvatar", userAvatar) - .append("project", project) - .append("commits", commits) - .append("totalCommitsCount", totalCommitsCount) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/Repository.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/Repository.java deleted file mode 100644 index a19123f..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/Repository.java +++ /dev/null @@ -1,123 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -/** - * @author Robin Müller - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class Repository { - - private String name; - private String description; - private String url; - private String homepage; - private String gitSshUrl; - private String gitHttpUrl; - private Integer visibilityLevel; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getUrl() { - return url; - } - - public void setUrl(String url) { - this.url = url; - } - - public String getHomepage() { - return homepage; - } - - public void setHomepage(String homepage) { - this.homepage = homepage; - } - - public String getGitSshUrl() { - return gitSshUrl; - } - - public void setGitSshUrl(String gitSshUrl) { - this.gitSshUrl = gitSshUrl; - } - - public String getGitHttpUrl() { - return gitHttpUrl; - } - - public void setGitHttpUrl(String gitHttpUrl) { - this.gitHttpUrl = gitHttpUrl; - } - - public Integer getVisibilityLevel() { - return visibilityLevel; - } - - public void setVisibilityLevel(Integer visibilityLevel) { - this.visibilityLevel = visibilityLevel; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Repository that = (Repository) o; - return new EqualsBuilder() - .append(name, that.name) - .append(description, that.description) - .append(url, that.url) - .append(homepage, that.homepage) - .append(gitSshUrl, that.gitSshUrl) - .append(gitHttpUrl, that.gitHttpUrl) - .append(visibilityLevel, that.visibilityLevel) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(name) - .append(description) - .append(url) - .append(homepage) - .append(gitSshUrl) - .append(gitHttpUrl) - .append(visibilityLevel) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("name", name) - .append("description", description) - .append("url", url) - .append("homepage", homepage) - .append("gitSshUrl", gitSshUrl) - .append("gitHttpUrl", gitHttpUrl) - .append("visibilityLevel", visibilityLevel) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/State.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/State.java deleted file mode 100644 index 7e72248..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/State.java +++ /dev/null @@ -1,8 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -/** - * @author Robin Müller - */ -public enum State { - open, opened, reopened, updated, closed, merged -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/User.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/User.java deleted file mode 100644 index 82d4774..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/User.java +++ /dev/null @@ -1,99 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -/** - * @author Robin Müller - */ -@GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") -public class User { - - private Integer id; - private String name; - private String username; - private String email; - private String avatarUrl; - - public Integer getId() { - return id; - } - - public void setId(Integer id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - - public String getEmail() { - return email; - } - - public void setEmail(String email) { - this.email = email; - } - - public String getAvatarUrl() { - return avatarUrl; - } - - public void setAvatarUrl(String avatarUrl) { - this.avatarUrl = avatarUrl; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - User user = (User) o; - return new EqualsBuilder() - .append(id, user.id) - .append(name, user.name) - .append(username, user.username) - .append(email, user.email) - .append(avatarUrl, user.avatarUrl) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(id) - .append(name) - .append(username) - .append(email) - .append(avatarUrl) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("id", id) - .append("name", name) - .append("username", username) - .append("email", email) - .append("avatarUrl", avatarUrl) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/gitee/hook/model/WebHook.java b/src/main/java/com/gitee/jenkins/gitee/hook/model/WebHook.java deleted file mode 100644 index 60abcde..0000000 --- a/src/main/java/com/gitee/jenkins/gitee/hook/model/WebHook.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.gitee.jenkins.gitee.hook.model; - -import org.apache.commons.lang.builder.EqualsBuilder; -import org.apache.commons.lang.builder.HashCodeBuilder; -import org.apache.commons.lang.builder.ToStringBuilder; - -/** - * @author Robin Müller - * @author Yashin Luo - */ -public abstract class WebHook { - - private Repository repository; - private String objectKind; - private String hookName; - private String jsonBody; - - public String getJsonBody() { return this.jsonBody; } - - public void setJsonBody(String json) { this.jsonBody = json; } - - public String getHookName() { - return this.hookName; - } - - public void setHookName(String hookName) { - this.hookName = hookName; - } - - public String getObjectKind() { - return objectKind; - } - - public void setObjectKind(String objectKind) { - this.objectKind = objectKind; - } - - public Repository getRepository() { - return repository; - } - - public void setRepository(Repository repository) { - this.repository = repository; - } - - public String getWebHookDescription() { - return hookName; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - WebHook webHook = (WebHook) o; - return new EqualsBuilder() - .append(repository, webHook.repository) - .append(objectKind, webHook.objectKind) - .append(hookName, webHook.hookName) - .isEquals(); - } - - @Override - public int hashCode() { - return new HashCodeBuilder(17, 37) - .append(repository) - .append(hookName) - .append(objectKind) - .toHashCode(); - } - - @Override - public String toString() { - return new ToStringBuilder(this) - .append("repository", repository) - .append("hookName", hookName) - .append("objectKind", objectKind) - .toString(); - } -} diff --git a/src/main/java/com/gitee/jenkins/handler/CommitCommentHandler.java b/src/main/java/com/gitee/jenkins/handler/CommitCommentHandler.java new file mode 100644 index 0000000..9f446d6 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/handler/CommitCommentHandler.java @@ -0,0 +1,75 @@ +package com.gitee.jenkins.handler; + +import com.gitee.jenkins.cause.GiteeWebHookCauseData; +import com.gitee.jenkins.entity.CommitComment; +import com.gitee.jenkins.entity.CommitCommentWebHook; +import com.gitee.jenkins.enums.WebHookType; +import com.gitee.jenkins.excetion.NoRevisionToBuildException; +import hudson.Extension; +import hudson.plugins.git.GitSCM; +import hudson.plugins.git.RevisionParameterAction; +import org.eclipse.jgit.transport.URIish; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import java.util.Optional; + +/** + * commit comment handler + */ +@Extension +@Restricted(NoExternalUse.class) +public class CommitCommentHandler extends GiteeWebHookHandler { + + @Override + protected WebHookType handleWebHookType() { + return WebHookType.COMMIT_COMMENT; + } + + @Override + protected RevisionParameterAction createRevisionParameterAction(GitSCM gitSCM, CommitCommentWebHook webHook) throws NoRevisionToBuildException { + URIish urIish = retrieveUrIish(retrieveGitRepositoryRemoteConfig(gitSCM, webHook)); + return urIish == null ? new RevisionParameterAction(retrieveRevisionToBuild(webHook)) : new RevisionParameterAction(retrieveRevisionToBuild(webHook), urIish); + } + + @Override + protected String retrieveRevisionToBuild(CommitCommentWebHook webHook) throws NoRevisionToBuildException { + return Optional.ofNullable(webHook) + .map(CommitCommentWebHook::getComment) + .map(CommitComment::getCommitId) + .orElseThrow(NoRevisionToBuildException::new); + } + + @Override + protected GiteeWebHookCauseData createGiteeWebHookCauseData(CommitCommentWebHook webHook) { + return GiteeWebHookCauseData.builder() + .webHookType(webHook.getWebHookType()) + .userName(webHook.getComment().getUser().getName()) + .userEmail(webHook.getComment().getUser().getEmail()) + .sourceProjectId(webHook.getProject().getId()) + .targetProjectId(webHook.getProject().getId()) + .pathWithNamespace(webHook.getProject().getPathWithNamespace()) + .branch("") + .sourceBranch("") + .sourceRepoHomepage(webHook.getProject().getHomepage()) + .sourceRepoName(webHook.getProject().getName()) + .sourceNamespace(webHook.getProject().getNamespace()) + .sourceRepoUrl(webHook.getProject().getUrl()) + .sourceRepoSshUrl(webHook.getProject().getSshUrl()) + .sourceRepoHttpUrl(webHook.getProject().getGitHttpUrl()) + .targetBranch("") + .targetRepoName(webHook.getProject().getName()) + .targetNamespace(webHook.getProject().getNamespace()) + .targetProjectUrl(webHook.getProject().getUrl()) + .targetRepoSshUrl(webHook.getProject().getSshUrl()) + .targetRepoHttpUrl(webHook.getProject().getGitHttpUrl()) + .pullRequestTitle("") + .sha(webHook.getComment().getCommitId()) + .jsonBody(webHook.getJsonBody()) + .noteBody(webHook.getComment().getBody()) + .triggerPhrase(webHook.getComment().getBody()) + .triggeredByUser(webHook.getComment().getUser().getName()) + .build(); + } + +} diff --git a/src/main/java/com/gitee/jenkins/handler/GiteeWebHookHandler.java b/src/main/java/com/gitee/jenkins/handler/GiteeWebHookHandler.java new file mode 100644 index 0000000..60dd5ed --- /dev/null +++ b/src/main/java/com/gitee/jenkins/handler/GiteeWebHookHandler.java @@ -0,0 +1,175 @@ +package com.gitee.jenkins.handler; + +import com.gitee.jenkins.cause.GiteeWebHookCause; +import com.gitee.jenkins.cause.GiteeWebHookCauseData; +import com.gitee.jenkins.entity.WebHook; +import com.gitee.jenkins.entity.WebHookAction; +import com.gitee.jenkins.enums.WebHookType; +import com.gitee.jenkins.excetion.NoRevisionToBuildException; +import com.gitee.jenkins.filter.BuildFilter; +import com.gitee.jenkins.trigger.GiteeTrigger; +import hudson.ExtensionList; +import hudson.ExtensionPoint; +import hudson.model.Action; +import hudson.model.CauseAction; +import hudson.model.Job; +import hudson.plugins.git.GitSCM; +import hudson.plugins.git.RevisionParameterAction; +import hudson.security.ACL; +import hudson.security.ACLContext; +import hudson.util.HttpResponses; +import hudson.util.Secret; +import jenkins.model.ParameterizedJobMixIn; +import jenkins.triggers.SCMTriggerItem; +import org.eclipse.jgit.transport.RemoteConfig; +import org.eclipse.jgit.transport.URIish; + +import javax.servlet.http.HttpServletResponse; +import java.net.URISyntaxException; +import java.util.*; +import java.util.function.Function; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; + +/** + * Abstract webHook handler + */ +public abstract class GiteeWebHookHandler implements ExtensionPoint { + + private static final Logger LOGGER = Logger.getLogger(GiteeWebHookHandler.class.getName()); + + private static final Map GITEE_WEB_HOOK_HANDLER_MAP; + + static { + GITEE_WEB_HOOK_HANDLER_MAP = ExtensionList.lookup(GiteeWebHookHandler.class).stream() + .collect(Collectors.toMap(GiteeWebHookHandler::handleWebHookType, Function.identity())); + } + + public static void handler(WebHookAction webHookAction) { + GITEE_WEB_HOOK_HANDLER_MAP.get(webHookAction.getWebHook().getWebHookType()) + .handler(webHookAction.getJob(), webHookAction.getWebHook(), webHookAction.getSecretToken()); + } + + private void handler(Job job, + T webHook, + String secretToken) { + try (ACLContext ctx = ACL.as2(ACL.SYSTEM2)) { + GiteeTrigger giteeTrigger = Optional.ofNullable(GiteeTrigger.getGiteeTrigger(job)) + .orElseThrow(() -> HttpResponses.errorWithoutStack(HttpServletResponse.SC_BAD_REQUEST, "Gitee trigger not configured")); + checkSecretToken(giteeTrigger, secretToken); + if (BuildFilter.allowBuild(job, giteeTrigger, webHook)) { + cancelIncompleteBuildIfNecessary(job, giteeTrigger, webHook); + LOGGER.log(Level.INFO, "{0} triggered for {1}", new Object[]{job.getFullName(), webHook.getWebHookType()}); + ParameterizedJobMixIn.scheduleBuild2(job, -1, createActions(job, webHook)); + } + } + } + + /** + * 校验 secretToken + * + * @param giteeTrigger + * @param secretToken + */ + private void checkSecretToken(GiteeTrigger giteeTrigger, String secretToken) { + Optional.ofNullable(giteeTrigger.getSecretToken()) + .map(Secret::getPlainText) + .filter(s -> s.equals(secretToken)) + .orElseThrow(() -> { + LOGGER.log(Level.INFO, "Invalid token"); + return HttpResponses.errorWithoutStack(HttpServletResponse.SC_UNAUTHORIZED, "Invalid token"); + }); + } + + /** + * 创建与构建相关的各种动作 + * + * @return + */ + protected Action[] createActions(Job job, T webHook) { + ArrayList actions = new ArrayList<>(); + actions.add(new CauseAction(new GiteeWebHookCause(createGiteeWebHookCauseData(webHook)))); + try { + GitSCM gitSCM = Optional.ofNullable(SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(job)) + .map(SCMTriggerItem::getSCMs) + .map(scms -> (GitSCM) scms.stream().filter(scm -> scm instanceof GitSCM).findFirst().orElse(null)) + .orElse(null); + actions.add(createRevisionParameterAction(gitSCM, webHook)); + } catch (NoRevisionToBuildException e) { + LOGGER.log(Level.WARNING, "Unknown handled situation, dont know what revision to build for req {0} for job {1}", new Object[]{webHook, job.getFullName()}); + } + return actions.toArray(new Action[actions.size()]); + } + + protected RemoteConfig retrieveGitRepositoryRemoteConfig(GitSCM gitSCM, T webHook) { + if (gitSCM == null || webHook.getRepository() == null) { + return null; + } + try { + Set set = new HashSet<>(); + set.add(new URIish(webHook.getRepository().getUrl())); + set.add(new URIish(webHook.getRepository().getGitHttpUrl())); + set.add(new URIish(webHook.getRepository().getGitSshUrl())); + for (RemoteConfig remoteConfig : gitSCM.getRepositories()) { + for (URIish remoteURL : remoteConfig.getURIs()) { + if (set.contains(remoteURL)) { + return remoteConfig; + } + } + } + } catch (URISyntaxException e) { + LOGGER.log(Level.WARNING, "Can\'t parse URL"); + } + return null; + } + + protected URIish retrieveUrIish(RemoteConfig remoteConfig) { + return Optional.ofNullable(remoteConfig) + .map(config -> config.getURIs().get(0)) + .orElse(null); + } + + /** + * 获取 Handler 处理 WebHook 类型 + * + * @return + */ + protected abstract WebHookType handleWebHookType(); + + /** + * 取消未完成构建 + * + * @param job + * @param giteeTrigger + * @param webhook + */ + protected void cancelIncompleteBuildIfNecessary(Job job, GiteeTrigger giteeTrigger, T webhook) { + } + + /** + * git 构建参数 + * + * @param gitSCM + * @param webHook + * @return + */ + protected abstract RevisionParameterAction createRevisionParameterAction(GitSCM gitSCM, T webHook) throws NoRevisionToBuildException; + + /** + * 获取构建版本 + * + * @param webHook + * @return + */ + protected abstract String retrieveRevisionToBuild(T webHook) throws NoRevisionToBuildException; + + /** + * gitee 参数 + * + * @param webHook + * @return + */ + protected abstract GiteeWebHookCauseData createGiteeWebHookCauseData(T webHook); + +} diff --git a/src/main/java/com/gitee/jenkins/handler/PullRequestCommentHandler.java b/src/main/java/com/gitee/jenkins/handler/PullRequestCommentHandler.java new file mode 100644 index 0000000..0a86475 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/handler/PullRequestCommentHandler.java @@ -0,0 +1,112 @@ +package com.gitee.jenkins.handler; + +import com.gitee.jenkins.cause.GiteeWebHookCauseData; +import com.gitee.jenkins.entity.PullRequest; +import com.gitee.jenkins.entity.PullRequestCommentWebHook; +import com.gitee.jenkins.entity.User; +import com.gitee.jenkins.enums.WebHookType; +import com.gitee.jenkins.excetion.NoRevisionToBuildException; +import com.gitee.jenkins.trigger.GiteeTrigger; +import com.gitee.jenkins.util.BuildUtil; +import hudson.Extension; +import hudson.model.Job; +import hudson.plugins.git.GitSCM; +import hudson.plugins.git.RevisionParameterAction; +import org.eclipse.jgit.transport.URIish; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import java.util.Optional; + +/** + * PR comment handler + */ +@Extension +@Restricted(NoExternalUse.class) +public class PullRequestCommentHandler extends GiteeWebHookHandler { + + @Override + protected WebHookType handleWebHookType() { + return WebHookType.PULL_REQUEST_COMMENT; + } + + @Override + public void cancelIncompleteBuildIfNecessary(Job job, GiteeTrigger giteeTrigger, PullRequestCommentWebHook webhook) { + if (!giteeTrigger.isCancelIncompleteBuildOnSamePullRequest()) { + return; + } + BuildUtil.doStop(job, webhook.getPullRequest()); + } + + @Override + protected RevisionParameterAction createRevisionParameterAction(GitSCM gitSCM, PullRequestCommentWebHook webHook) throws NoRevisionToBuildException { + // 没有配置git源码管理 + if (gitSCM == null) { + return new RevisionParameterAction(retrieveRevisionToBuild(webHook)); + } + URIish urIish = retrieveUrIish(retrieveGitRepositoryRemoteConfig(gitSCM, webHook)); + // webhook与git源码管理仓库对不上 + if (urIish == null) { + return new RevisionParameterAction(retrieveRevisionToBuild2(webHook)); + } + return new RevisionParameterAction(retrieveRevisionToBuild(webHook), urIish); + } + + @Override + protected String retrieveRevisionToBuild(PullRequestCommentWebHook webHook) throws NoRevisionToBuildException { + return Optional.ofNullable(webHook) + .map(PullRequestCommentWebHook::getPullRequest) + .map(PullRequest::getMergeCommitSha) + .orElse(retrieveRevisionToBuild2(webHook)); + } + + private String retrieveRevisionToBuild2(PullRequestCommentWebHook webHook) throws NoRevisionToBuildException { + return Optional.ofNullable(webHook) + .map(PullRequestCommentWebHook::getPullRequest) + .map(PullRequest::getMergeReferenceName) + .orElseThrow(NoRevisionToBuildException::new); + } + + @Override + protected GiteeWebHookCauseData createGiteeWebHookCauseData(PullRequestCommentWebHook webHook) { + return GiteeWebHookCauseData.builder() + .webHookType(webHook.getWebHookType()) + .userName(webHook.getPullRequest().getHead().getUser().getName()) + .userEmail(webHook.getPullRequest().getHead().getUser().getEmail()) + .sourceProjectId(webHook.getPullRequest().getHead().getRepo().getId()) + .targetProjectId(webHook.getPullRequest().getBase().getRepo().getId()) + .pathWithNamespace(webHook.getPullRequest().getBase().getRepo().getPathWithNamespace()) + .branch(webHook.getPullRequest().getHead().getRef()) + .sourceBranch(webHook.getPullRequest().getHead().getRef()) + .sourceRepoHomepage(webHook.getPullRequest().getHead().getRepo().getHomepage()) + .sourceRepoName(webHook.getPullRequest().getHead().getRepo().getName()) + .sourceNamespace(webHook.getPullRequest().getHead().getRepo().getNamespace()) + .sourceRepoUrl(webHook.getPullRequest().getHead().getRepo().getUrl()) + .sourceRepoSshUrl(webHook.getPullRequest().getHead().getRepo().getSshUrl()) + .sourceRepoHttpUrl(webHook.getPullRequest().getHead().getRepo().getGitHttpUrl()) + .targetBranch(webHook.getPullRequest().getBase().getRef()) + .targetRepoName(webHook.getPullRequest().getBase().getRepo().getName()) + .targetNamespace(webHook.getPullRequest().getBase().getRepo().getNamespace()) + .targetProjectUrl(webHook.getPullRequest().getBase().getRepo().getUrl()) + .targetRepoSshUrl(webHook.getPullRequest().getBase().getRepo().getSshUrl()) + .targetRepoHttpUrl(webHook.getPullRequest().getBase().getRepo().getGitHttpUrl()) + .pullRequestTitle(webHook.getPullRequest().getTitle()) + .pullRequestDescription(webHook.getPullRequest().getBody()) + .pullRequestId(webHook.getPullRequest().getId()) + .pullRequestIid(webHook.getPullRequest().getNumber()) + .pullRequestState(webHook.getPullRequest().getState().getValue()) + .mergedByUser(webHook.getPullRequest().getUpdatedBy().getName()) + .pullRequestAssignee(webHook.getPullRequest().getAssignees().stream().findFirst().map(User::getName).orElse(null)) + .pullRequestTargetProjectId(webHook.getPullRequest().getBase().getRepo().getId()) + .after(webHook.getPullRequest().getMergeCommitSha()) + .lastCommit(webHook.getPullRequest().getMergeCommitSha()) + .ref(webHook.getPullRequest().getMergeReferenceName()) + .sha(webHook.getPullRequest().getMergeCommitSha()) + .jsonBody(webHook.getJsonBody()) + .noteBody(webHook.getComment().getBody()) + .triggerPhrase(webHook.getComment().getBody()) + .triggeredByUser(webHook.getPullRequest().getHead().getUser().getName()) + .build(); + } + +} diff --git a/src/main/java/com/gitee/jenkins/handler/PullRequestHandler.java b/src/main/java/com/gitee/jenkins/handler/PullRequestHandler.java new file mode 100644 index 0000000..e3ab65b --- /dev/null +++ b/src/main/java/com/gitee/jenkins/handler/PullRequestHandler.java @@ -0,0 +1,111 @@ +package com.gitee.jenkins.handler; + +import com.gitee.jenkins.cause.GiteeWebHookCauseData; +import com.gitee.jenkins.entity.PullRequest; +import com.gitee.jenkins.entity.PullRequestWebHook; +import com.gitee.jenkins.entity.User; +import com.gitee.jenkins.enums.WebHookType; +import com.gitee.jenkins.excetion.NoRevisionToBuildException; +import com.gitee.jenkins.trigger.GiteeTrigger; +import com.gitee.jenkins.util.BuildUtil; +import hudson.Extension; +import hudson.model.Job; +import hudson.plugins.git.GitSCM; +import hudson.plugins.git.RevisionParameterAction; +import org.eclipse.jgit.transport.URIish; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import java.util.Optional; + +/** + * PR handler + */ +@Extension +@Restricted(NoExternalUse.class) +public class PullRequestHandler extends GiteeWebHookHandler { + + @Override + protected WebHookType handleWebHookType() { + return WebHookType.PULL_REQUEST; + } + + @Override + public void cancelIncompleteBuildIfNecessary(Job job, GiteeTrigger giteeTrigger, PullRequestWebHook webhook) { + if (!giteeTrigger.isCancelIncompleteBuildOnSamePullRequest()) { + return; + } + BuildUtil.doStop(job, webhook.getPullRequest()); + } + + @Override + protected RevisionParameterAction createRevisionParameterAction(GitSCM gitSCM, PullRequestWebHook webHook) throws NoRevisionToBuildException { + // 没有配置git源码管理 + if (gitSCM == null) { + return new RevisionParameterAction(retrieveRevisionToBuild(webHook)); + } + URIish urIish = retrieveUrIish(retrieveGitRepositoryRemoteConfig(gitSCM, webHook)); + // webhook与git源码管理仓库对不上 + if (urIish == null) { + return new RevisionParameterAction(retrieveRevisionToBuild2(webHook)); + } + return new RevisionParameterAction(retrieveRevisionToBuild(webHook), urIish); + } + + @Override + protected String retrieveRevisionToBuild(PullRequestWebHook webHook) throws NoRevisionToBuildException { + return Optional.ofNullable(webHook) + .map(PullRequestWebHook::getPullRequest) + .map(PullRequest::getMergeCommitSha) + .orElse(retrieveRevisionToBuild2(webHook)); + } + + private String retrieveRevisionToBuild2(PullRequestWebHook webHook) throws NoRevisionToBuildException { + return Optional.ofNullable(webHook) + .map(PullRequestWebHook::getPullRequest) + .map(PullRequest::getMergeReferenceName) + .orElseThrow(NoRevisionToBuildException::new); + } + + + @Override + protected GiteeWebHookCauseData createGiteeWebHookCauseData(PullRequestWebHook webHook) { + return GiteeWebHookCauseData.builder() + .webHookType(webHook.getWebHookType()) + .userName(webHook.getPullRequest().getHead().getUser().getName()) + .userEmail(webHook.getPullRequest().getHead().getUser().getEmail()) + .sourceProjectId(webHook.getPullRequest().getHead().getRepo().getId()) + .targetProjectId(webHook.getPullRequest().getBase().getRepo().getId()) + .pathWithNamespace(webHook.getProject().getPathWithNamespace()) + .branch(webHook.getPullRequest().getHead().getRef()) + .sourceBranch(webHook.getPullRequest().getHead().getRef()) + .sourceRepoHomepage(webHook.getPullRequest().getHead().getRepo().getHomepage()) + .sourceRepoName(webHook.getPullRequest().getHead().getRepo().getName()) + .sourceNamespace(webHook.getPullRequest().getHead().getRepo().getNamespace()) + .sourceRepoUrl(webHook.getPullRequest().getHead().getRepo().getUrl()) + .sourceRepoSshUrl(webHook.getPullRequest().getHead().getRepo().getSshUrl()) + .sourceRepoHttpUrl(webHook.getPullRequest().getHead().getRepo().getGitHttpUrl()) + .targetBranch(webHook.getPullRequest().getBase().getRef()) + .targetRepoName(webHook.getPullRequest().getBase().getRepo().getName()) + .targetNamespace(webHook.getPullRequest().getBase().getRepo().getNamespace()) + .targetProjectUrl(webHook.getPullRequest().getBase().getRepo().getUrl()) + .targetRepoSshUrl(webHook.getPullRequest().getBase().getRepo().getSshUrl()) + .targetRepoHttpUrl(webHook.getPullRequest().getBase().getRepo().getGitHttpUrl()) + .pullRequestTitle(webHook.getPullRequest().getTitle()) + .pullRequestDescription(webHook.getPullRequest().getBody()) + .pullRequestId(webHook.getPullRequest().getId()) + .pullRequestIid(webHook.getPullRequest().getNumber()) + .pullRequestState(webHook.getState().getValue()) + .mergedByUser(webHook.getPullRequest().getUpdatedBy().getName()) + .pullRequestAssignee(webHook.getPullRequest().getAssignees().stream().findFirst().map(User::getName).orElse(null)) + .pullRequestTargetProjectId(webHook.getPullRequest().getBase().getRepo().getId()) + .after(webHook.getPullRequest().getMergeCommitSha()) + .lastCommit(webHook.getPullRequest().getMergeCommitSha()) + .ref(webHook.getPullRequest().getMergeReferenceName()) + .sha(webHook.getPullRequest().getMergeCommitSha()) + .jsonBody(webHook.getJsonBody()) + .triggeredByUser(webHook.getPullRequest().getHead().getUser().getName()) + .build(); + } + +} diff --git a/src/main/java/com/gitee/jenkins/handler/PushHandler.java b/src/main/java/com/gitee/jenkins/handler/PushHandler.java new file mode 100644 index 0000000..6917310 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/handler/PushHandler.java @@ -0,0 +1,93 @@ +package com.gitee.jenkins.handler; + +import com.gitee.jenkins.cause.GiteeWebHookCauseData; +import com.gitee.jenkins.entity.PushWebHook; +import com.gitee.jenkins.enums.WebHookType; +import com.gitee.jenkins.excetion.NoRevisionToBuildException; +import com.gitee.jenkins.filter.ConfigFilter; +import hudson.Extension; +import hudson.plugins.git.GitSCM; +import hudson.plugins.git.RevisionParameterAction; +import org.eclipse.jgit.transport.RemoteConfig; +import org.kohsuke.accmod.Restricted; +import org.kohsuke.accmod.restrictions.NoExternalUse; + +import java.util.Optional; + +/** + * Push handler + */ +@Extension +@Restricted(NoExternalUse.class) +public class PushHandler extends GiteeWebHookHandler { + + @Override + protected WebHookType handleWebHookType() { + return WebHookType.PUSH; + } + + @Override + protected RevisionParameterAction createRevisionParameterAction(GitSCM gitSCM, PushWebHook webHook) throws NoRevisionToBuildException { + RemoteConfig remoteConfig = retrieveGitRepositoryRemoteConfig(gitSCM, webHook); + if (remoteConfig == null) { + return new RevisionParameterAction(retrieveRevisionToBuild(webHook)); + } + return new RevisionParameterAction(retrieveRevisionToBuild2(webHook, remoteConfig.getName()), retrieveUrIish(remoteConfig)); + } + + @Override + protected String retrieveRevisionToBuild(PushWebHook webHook) throws NoRevisionToBuildException { + return Optional.ofNullable(webHook) + .filter(w -> !ConfigFilter.isRemoveBranchPush(w)) + .map(PushWebHook::getAfter) + .orElseThrow(NoRevisionToBuildException::new); + } + + private String retrieveRevisionToBuild2(PushWebHook webHook, String repositoryId) throws NoRevisionToBuildException { + return Optional.ofNullable(webHook) + .filter(w -> !ConfigFilter.isRemoveBranchPush(w)) + .map(w -> w.getRef().replaceFirst("^refs/heads", "remotes/" + repositoryId)) + .orElse(retrieveRevisionToBuild(webHook)); + } + + @Override + protected GiteeWebHookCauseData createGiteeWebHookCauseData(PushWebHook webHook) { + String branch = Optional.ofNullable(webHook) + .map(PushWebHook::getRef) + .map(s -> s.replaceFirst("^refs/heads/", "")) + .orElse(null); + + return GiteeWebHookCauseData.builder() + .webHookType(webHook.getWebHookType()) + .userName(webHook.getUserName()) + .sourceProjectId(webHook.getProject().getId()) + .targetProjectId(webHook.getProject().getId()) + .pathWithNamespace(webHook.getProject().getPathWithNamespace()) + .branch(branch) + .sourceBranch(branch) + .sourceRepoHomepage(webHook.getProject().getHomepage()) + .sourceRepoName(webHook.getProject().getName()) + .sourceNamespace(webHook.getProject().getNamespace()) + .sourceRepoUrl(webHook.getProject().getUrl()) + .sourceRepoSshUrl(webHook.getProject().getSshUrl()) + .sourceRepoHttpUrl(webHook.getProject().getGitHttpUrl()) + .targetBranch(branch) + .targetRepoName(webHook.getProject().getName()) + .targetNamespace(webHook.getProject().getNamespace()) + .targetProjectUrl(webHook.getProject().getUrl()) + .targetRepoSshUrl(webHook.getProject().getSshUrl()) + .targetRepoHttpUrl(webHook.getProject().getGitHttpUrl()) + .pullRequestTitle("") + .before(webHook.getBefore()) + .after(webHook.getAfter()) + .lastCommit(webHook.getAfter()) + .ref(webHook.getRef()) + .sha(webHook.getAfter()) + .created(webHook.getCreated()) + .deleted(webHook.getDeleted()) + .jsonBody(webHook.getJsonBody()) + .triggeredByUser(webHook.getUserName()) + .build(); + } + +} diff --git a/src/main/java/com/gitee/jenkins/listener/GiteeBuildDescriptionRunListener.java b/src/main/java/com/gitee/jenkins/listener/GiteeBuildDescriptionRunListener.java index 7b8901a..3691b1b 100644 --- a/src/main/java/com/gitee/jenkins/listener/GiteeBuildDescriptionRunListener.java +++ b/src/main/java/com/gitee/jenkins/listener/GiteeBuildDescriptionRunListener.java @@ -1,30 +1,29 @@ package com.gitee.jenkins.listener; -import com.gitee.jenkins.trigger.GiteePushTrigger; import com.gitee.jenkins.cause.GiteeWebHookCause; +import com.gitee.jenkins.trigger.GiteeTrigger; import hudson.Extension; import hudson.model.Cause; import hudson.model.Run; import hudson.model.TaskListener; import hudson.model.listeners.RunListener; +import org.apache.commons.lang3.StringUtils; import java.io.IOException; /** * RunListener that will be called when a build starts and completes. * Will lookup trigger and call set the build description if necessary. - * - * @author Robin Müller */ @Extension public class GiteeBuildDescriptionRunListener extends RunListener> { @Override public void onStarted(Run build, TaskListener listener) { - GiteePushTrigger trigger = GiteePushTrigger.getFromJob(build.getParent()); - if (trigger != null && trigger.getSetBuildDescription()) { + GiteeTrigger giteeTrigger = GiteeTrigger.getGiteeTrigger(build.getParent()); + if (giteeTrigger != null) { Cause cause = build.getCause(GiteeWebHookCause.class); - if (cause != null && !cause.getShortDescription().isEmpty()) { + if (cause != null && StringUtils.isNotBlank(cause.getShortDescription())) { try { build.setDescription(cause.getShortDescription()); } catch (IOException e) { diff --git a/src/main/java/com/gitee/jenkins/publisher/AcceptPullRequestPublisher.java b/src/main/java/com/gitee/jenkins/publisher/AcceptPullRequestPublisher.java new file mode 100644 index 0000000..e042986 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/publisher/AcceptPullRequestPublisher.java @@ -0,0 +1,56 @@ +package com.gitee.jenkins.publisher; + +import com.gitee.jenkins.api.client.GiteeClient; +import com.gitee.jenkins.cause.GiteeWebHookCauseData; +import com.gitee.jenkins.excetion.GiteeClientRequestException; +import hudson.Extension; +import hudson.model.AbstractProject; +import hudson.model.Result; +import hudson.model.Run; +import hudson.model.TaskListener; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Publisher; +import lombok.NoArgsConstructor; +import org.kohsuke.stapler.DataBoundConstructor; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * 合并 PR 订阅 + */ +@NoArgsConstructor(onConstructor = @_(@DataBoundConstructor)) +public class AcceptPullRequestPublisher extends PullRequestNotifier { + + private static final Logger LOGGER = Logger.getLogger(AcceptPullRequestPublisher.class.getName()); + + @Override + protected void perform(Run build, TaskListener listener, GiteeClient giteeClient, GiteeWebHookCauseData giteeWebHookCauseData) { + if (build.getResult() == Result.SUCCESS) { + String[] path = giteeWebHookCauseData.getPathWithNamespace().split("/"); + try { + giteeClient.mergerPullRequest(path[0], path[1], giteeWebHookCauseData.getPullRequestIid()); + LOGGER.log(Level.INFO, "Accept Pull Request success"); + } catch (GiteeClientRequestException e) { + listener.getLogger().printf("Failed to accept pull request for project '%s': %s%n", path[1], e.getMessage()); + LOGGER.log(Level.SEVERE, String.format("Failed to accept pull request for project '%s'", path[1]), e); + } + } + } + + @Extension + public static class DescriptorImpl extends BuildStepDescriptor { + + @Override + public boolean isApplicable(Class aClass) { + return true; + } + + @Override + public String getDisplayName() { + return Messages.AcceptPullRequestPublisher_DisplayName(); + } + + } + +} diff --git a/src/main/java/com/gitee/jenkins/publisher/GiteeAcceptPullRequestPublisher.java b/src/main/java/com/gitee/jenkins/publisher/GiteeAcceptPullRequestPublisher.java deleted file mode 100644 index a61575e..0000000 --- a/src/main/java/com/gitee/jenkins/publisher/GiteeAcceptPullRequestPublisher.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.gitee.jenkins.publisher; - - -import com.gitee.jenkins.gitee.api.GiteeClient; -import com.gitee.jenkins.gitee.api.model.PullRequest; -import hudson.Extension; -import hudson.model.AbstractProject; -import hudson.model.Result; -import hudson.model.Run; -import hudson.model.TaskListener; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.BuildStepMonitor; -import hudson.tasks.Publisher; -import org.kohsuke.stapler.DataBoundConstructor; - -import javax.ws.rs.ProcessingException; -import javax.ws.rs.WebApplicationException; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * @author Robin Müller - */ -public class GiteeAcceptPullRequestPublisher extends PullRequestNotifier { - private static final Logger LOGGER = Logger.getLogger(GiteeAcceptPullRequestPublisher.class.getName()); - - @DataBoundConstructor - public GiteeAcceptPullRequestPublisher() { } - - public BuildStepMonitor getRequiredMonitorService() { - return BuildStepMonitor.NONE; - } - - @Extension - public static class DescriptorImpl extends BuildStepDescriptor { - - @Override - public boolean isApplicable(Class aClass) { - return true; - } - - @Override - public String getDisplayName() { - return Messages.GiteeAcceptPullRequestPublisher_DisplayName(); - } - } - - @Override - protected void perform(Run build, TaskListener listener, GiteeClient client, PullRequest pullRequest) { - try { - if (build.getResult() == Result.SUCCESS) { - client.acceptPullRequest(pullRequest, "Pull Request accepted by jenkins build success", false); - } - } catch (WebApplicationException | ProcessingException e) { - listener.getLogger().printf("Failed to accept pull request for project '%s': %s%n", pullRequest.getProjectId(), e.getMessage()); - LOGGER.log(Level.SEVERE, String.format("Failed to accept pull request for project '%s'", pullRequest.getProjectId()), e); - } - } -} diff --git a/src/main/java/com/gitee/jenkins/publisher/GiteeMessagePublisher.java b/src/main/java/com/gitee/jenkins/publisher/GiteeMessagePublisher.java deleted file mode 100644 index 0fa6026..0000000 --- a/src/main/java/com/gitee/jenkins/publisher/GiteeMessagePublisher.java +++ /dev/null @@ -1,247 +0,0 @@ -package com.gitee.jenkins.publisher; - - -import com.gitee.jenkins.gitee.api.GiteeClient; -import com.gitee.jenkins.gitee.api.model.PullRequest; -import com.gitee.jenkins.trigger.GiteePushTrigger; -import hudson.Extension; -import hudson.Util; -import hudson.model.*; -import hudson.tasks.BuildStepDescriptor; -import hudson.tasks.Notifier; -import hudson.tasks.Publisher; -import hudson.triggers.Trigger; -import jenkins.model.Jenkins; -import jenkins.model.ParameterizedJobMixIn; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.DataBoundSetter; - -import javax.ws.rs.ProcessingException; -import javax.ws.rs.WebApplicationException; -import java.text.MessageFormat; -import java.util.HashMap; -import java.util.Map; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * @author Nikolay Ustinov - */ -public class GiteeMessagePublisher extends PullRequestNotifier { - private static final Logger LOGGER = Logger.getLogger(GiteeMessagePublisher.class.getName()); - private boolean onlyForFailure = false; - private boolean replaceSuccessNote = false; - private boolean replaceFailureNote = false; - private boolean replaceAbortNote = false; - private boolean replaceUnstableNote = false; - private String successNoteText; - private String failureNoteText; - private String abortNoteText; - private String unstableNoteText; - - /** - * @deprecated use {@link #GiteeMessagePublisher()} with setters to configure an instance of this class. - */ - @Deprecated - public GiteeMessagePublisher(boolean onlyForFailure, boolean replaceSuccessNote, boolean replaceFailureNote, boolean replaceAbortNote, boolean replaceUnstableNote, - String successNoteText, String failureNoteText, String abortNoteText, String unstableNoteText) { - this.onlyForFailure = onlyForFailure; - this.replaceSuccessNote = replaceSuccessNote; - this.replaceFailureNote = replaceFailureNote; - this.replaceAbortNote = replaceAbortNote; - this.replaceUnstableNote = replaceUnstableNote; - this.successNoteText = successNoteText; - this.failureNoteText = failureNoteText; - this.abortNoteText = abortNoteText; - this.unstableNoteText = unstableNoteText; - } - - @DataBoundConstructor - public GiteeMessagePublisher() { } - - public static GiteeMessagePublisher getFromJob(Job job) { - GiteeMessagePublisher publisher = null; - if (job instanceof ParameterizedJobMixIn.ParameterizedJob) { - AbstractProject p = (AbstractProject) job; - Map, Publisher> map = p.getPublishersList().toMap(); - for (Publisher n : map.values()) { - if (n instanceof GiteeMessagePublisher) { - publisher = (GiteeMessagePublisher) n; - } - } - } - return publisher; - } - - public boolean isOnlyForFailure() { - return onlyForFailure; - } - - public boolean isReplaceSuccessNote() { - return replaceSuccessNote; - } - - public boolean isReplaceFailureNote() { - return replaceFailureNote; - } - - public boolean isReplaceAbortNote() { - return replaceAbortNote; - } - - public boolean isReplaceUnstableNote() { - return replaceUnstableNote; - } - - public String getSuccessNoteText() { - return this.successNoteText == null ? "" : this.successNoteText; - } - - public String getFailureNoteText() { - return this.failureNoteText == null ? "" : this.failureNoteText; - } - - public String getAbortNoteText() { - return this.abortNoteText == null ? "" : this.abortNoteText; - } - - public String getUnstableNoteText() { - return this.unstableNoteText == null ? "" : this.unstableNoteText; - } - - @DataBoundSetter - public void setOnlyForFailure(boolean onlyForFailure) { - this.onlyForFailure = onlyForFailure; - } - - @DataBoundSetter - public void setReplaceSuccessNote(boolean replaceSuccessNote) { - this.replaceSuccessNote = replaceSuccessNote; - } - - @DataBoundSetter - public void setReplaceFailureNote(boolean replaceFailureNote) { - this.replaceFailureNote = replaceFailureNote; - } - - @DataBoundSetter - public void setReplaceAbortNote(boolean replaceAbortNote) { - this.replaceAbortNote = replaceAbortNote; - } - - @DataBoundSetter - public void setReplaceUnstableNote(boolean replaceUnstableNote) { - this.replaceUnstableNote = replaceUnstableNote; - } - - @DataBoundSetter - public void setSuccessNoteText(String successNoteText) { - this.successNoteText = successNoteText; - } - - @DataBoundSetter - public void setFailureNoteText(String failureNoteText) { - this.failureNoteText = failureNoteText; - } - - @DataBoundSetter - public void setAbortNoteText(String abortNoteText) { - this.abortNoteText = abortNoteText; - } - - @DataBoundSetter - public void setUnstableNoteText(String unstableNoteText) { - this.unstableNoteText = unstableNoteText; - } - - @Extension - public static class DescriptorImpl extends BuildStepDescriptor { - - @Override - public boolean isApplicable(Class aClass) { - return true; - } - - @Override - public String getDisplayName() { - return Messages.GiteeMessagePublisher_DisplayName(); - } - - @Override - public String getHelpFile() { - return "/plugin/gitee/help/help-messagesOnResult.html"; - } - } - - @Override - protected void perform(Run build, TaskListener listener, GiteeClient client, PullRequest pullRequest) { - try { - if (!onlyForFailure || build.getResult() == Result.FAILURE || build.getResult() == Result.UNSTABLE) { - client.createPullRequestNote(pullRequest, getNote(build, listener)); - } - } catch (WebApplicationException | ProcessingException e) { - listener.getLogger().printf("Failed to add comment on Pull Request for project '%s': %s%n", pullRequest.getProjectId(), e.getMessage()); - LOGGER.log(Level.SEVERE, String.format("Failed to add comment on Pull Request for project '%s'", pullRequest.getProjectId()), e); - } - } - - private String getResultIcon(Result result) { - if (result == Result.SUCCESS) { - return ":white_check_mark:"; - } else if (result == Result.ABORTED) { - return ":point_up:"; - } else if (result == Result.UNSTABLE) { - return ":warning:"; - } else { - return ":x:"; - } - } - - private static String replaceMacros(Run build, TaskListener listener, String inputString) { - String returnString = inputString; - if (build != null && inputString != null) { - try { - Map messageEnvVars = getEnvVars(build, listener); - returnString = Util.replaceMacro(inputString, messageEnvVars); - - } catch (Exception e) { - listener.getLogger().printf("Couldn't replace macros in message: %s%n", e.getMessage()); - LOGGER.log(Level.WARNING, "Couldn't replace macros in message", e); - } - } - return returnString; - } - - private static Map getEnvVars(Run build, TaskListener listener) { - Map messageEnvVars = new HashMap<>(); - if (build != null) { - messageEnvVars.putAll(build.getCharacteristicEnvVars()); - try { - messageEnvVars.putAll(build.getEnvironment(listener)); - } catch (Exception e) { - listener.getLogger().printf("Couldn't get Env Variables: %s%n", e.getMessage()); - LOGGER.log(Level.WARNING, "Couldn't get Env Variables", e); - } - } - return messageEnvVars; - } - - private String getNote(Run build, TaskListener listener) { - String message; - if (this.replaceSuccessNote && build.getResult() == Result.SUCCESS) { - message = replaceMacros(build, listener, this.getSuccessNoteText()); - } else if (this.replaceAbortNote && build.getResult() == Result.ABORTED) { - message = replaceMacros(build, listener, this.getAbortNoteText()); - } else if (this.replaceUnstableNote && build.getResult() == Result.UNSTABLE) { - message = replaceMacros(build, listener, this.getUnstableNoteText()); - } else if (this.replaceFailureNote && build.getResult() == Result.FAILURE) { - message = replaceMacros(build, listener, this.getFailureNoteText()); - } else { - String icon = getResultIcon(build.getResult()); - String buildUrl = Jenkins.getInstance().getRootUrl() + build.getUrl(); - message = MessageFormat.format("{0} Jenkins Build {1}\n\nResults available at: [Jenkins [{2} # {3}]]({4})", - icon, build.getResult().toString(), build.getParent().getDisplayName(), build.getNumber(), buildUrl); - } - return message; - } -} diff --git a/src/main/java/com/gitee/jenkins/publisher/PullRequestBuildStatusPublisher.java b/src/main/java/com/gitee/jenkins/publisher/PullRequestBuildStatusPublisher.java new file mode 100644 index 0000000..0ae5534 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/publisher/PullRequestBuildStatusPublisher.java @@ -0,0 +1,180 @@ +package com.gitee.jenkins.publisher; + +import com.gitee.jenkins.api.client.GiteeClient; +import com.gitee.jenkins.cause.GiteeWebHookCauseData; +import com.gitee.jenkins.excetion.GiteeClientRequestException; +import hudson.Extension; +import hudson.Util; +import hudson.model.*; +import hudson.tasks.BuildStepDescriptor; +import hudson.tasks.Publisher; +import jenkins.model.Jenkins; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.kohsuke.stapler.DataBoundConstructor; +import org.kohsuke.stapler.DataBoundSetter; + +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * PR 构建状态订阅 + */ +@Getter +@Setter(onMethod = @_(@DataBoundSetter)) +@NoArgsConstructor(onConstructor = @_(@DataBoundConstructor)) +public class PullRequestBuildStatusPublisher extends PullRequestNotifier { + + private static final Logger LOGGER = Logger.getLogger(PullRequestBuildStatusPublisher.class.getName()); + + /** + * 是否仅为构建失败发表评论 + */ + private boolean onlyForFailure; + + /** + * 是否为构建成功自定义评论内容 + */ + private boolean replaceSuccessNote; + + /** + * 是否为构建失败自定义评论内容 + */ + private boolean replaceFailureNote; + + /** + * 是否为构建中断自定义评论内容 + */ + private boolean replaceAbortNote; + + /** + * 是否为构建不稳定自定义评论内容 + */ + private boolean replaceUnstableNote; + + /** + * 构建成功自定义评论内容 + */ + private String successNoteText; + + /** + * 构建失败自定义评论内容 + */ + private String failureNoteText; + + /** + * 构建不稳定自定义评论内容 + */ + private String abortNoteText; + + /** + * 构建不稳定自定义评论内容 + */ + private String unstableNoteText; + + @Override + protected void perform(Run build, TaskListener listener, GiteeClient giteeClient, GiteeWebHookCauseData giteeWebHookCauseData) { + if (!onlyForFailure || build.getResult() == Result.FAILURE || build.getResult() == Result.UNSTABLE) { + String[] path = giteeWebHookCauseData.getPathWithNamespace().split("/"); + try { + giteeClient.submitPullRequestComments(path[0], path[1], giteeWebHookCauseData.getPullRequestIid(), getNode(build, listener)); + LOGGER.log(Level.INFO, "send Pull Request build status to gitee success"); + } catch (GiteeClientRequestException e) { + listener.getLogger().printf("Failed to add comment on Pull Request for project '%s': %s%n", giteeWebHookCauseData.getTargetProjectId(), e.getMessage()); + LOGGER.log(Level.WARNING, String.format("Failed to add comment on Pull Request for project '%s'", giteeWebHookCauseData.getTargetProjectId()), e); + } + } + } + + private String getNode(Run build, TaskListener listener) { + String icon = ":x:"; + if (build.getResult() == Result.SUCCESS) { + if (replaceSuccessNote) { + return replaceNode(build, listener, successNoteText); + } + icon = ":white_check_mark:"; + } else if (build.getResult() == Result.FAILURE) { + if (replaceFailureNote) { + return replaceNode(build, listener, failureNoteText); + } + } else if (build.getResult() == Result.ABORTED) { + if (replaceAbortNote) { + return replaceNode(build, listener, abortNoteText); + } + icon = ":point_up:"; + } else if (build.getResult() == Result.UNSTABLE) { + if (replaceUnstableNote) { + return replaceNode(build, listener, unstableNoteText); + } + icon = ":warning:"; + } + return MessageFormat.format( + "{0} Jenkins Build {1}\n\nResults available at: [Jenkins [{2} # {3}]]({4})", + icon, + build.getResult().toString(), + build.getParent().getDisplayName(), + build.getNumber(), + Jenkins.get().getRootUrl() + build.getUrl() + ); + } + + private String replaceNode(Run build, TaskListener listener, String inputStr) { + if (inputStr != null) { + Map messageEnvVars = new HashMap<>(); + if (build != null) { + messageEnvVars.putAll(build.getCharacteristicEnvVars()); + try { + messageEnvVars.putAll(build.getEnvironment(listener)); + } catch (Exception e) { + listener.getLogger().printf("Couldn't get Env Variables: %s%n", e.getMessage()); + LOGGER.log(Level.WARNING, "Couldn't get Env Variables", e); + } + } + + try { + return Util.replaceMacro(inputStr, messageEnvVars); + } catch (Exception e) { + listener.getLogger().printf("Couldn't replace macros in message: %s%n", e.getMessage()); + LOGGER.log(Level.WARNING, "Couldn't replace macros in message", e); + } + } + return null; + } + + public static PullRequestBuildStatusPublisher getPullRequestBuildStatusPublisher(Job job) { + if (job instanceof AbstractProject) { + AbstractProject abstractProject = (AbstractProject) job; + PullRequestBuildStatusPublisher pullRequestBuildStatusPublisher = (PullRequestBuildStatusPublisher) abstractProject.getPublishersList().get(PullRequestBuildStatusPublisher.class); + if (pullRequestBuildStatusPublisher != null) { + return pullRequestBuildStatusPublisher; + } + } + LOGGER.log(Level.INFO, "project: {0} gitee Pull Request Build Status Publisher not configured", job.getFullName()); + return null; + } + + @Extension + public static class DescriptorImpl extends BuildStepDescriptor { + + @Override + public boolean isApplicable(Class aClass) { + return true; + } + + @Override + public String getDisplayName() { + return Messages.PullRequestBuildStatusPublisher_DisplayName(); + } + + @Override + public String getHelpFile() { + return "/plugin/gitee/help/help-pullRequestBuildStatus.html"; + } + + } + +} diff --git a/src/main/java/com/gitee/jenkins/publisher/PullRequestNotifier.java b/src/main/java/com/gitee/jenkins/publisher/PullRequestNotifier.java index b36180a..13e5168 100644 --- a/src/main/java/com/gitee/jenkins/publisher/PullRequestNotifier.java +++ b/src/main/java/com/gitee/jenkins/publisher/PullRequestNotifier.java @@ -1,8 +1,9 @@ package com.gitee.jenkins.publisher; +import com.gitee.jenkins.api.client.GiteeClient; import com.gitee.jenkins.cause.GiteeWebHookCause; -import com.gitee.jenkins.gitee.api.GiteeClient; -import com.gitee.jenkins.gitee.api.model.PullRequest; +import com.gitee.jenkins.cause.GiteeWebHookCauseData; +import com.gitee.jenkins.config.GiteeItemConfig; import hudson.Launcher; import hudson.matrix.MatrixAggregatable; import hudson.matrix.MatrixAggregator; @@ -16,46 +17,38 @@ import hudson.tasks.Notifier; import java.io.IOException; -import static com.gitee.jenkins.connection.GiteeConnectionProperty.getClient; - -/** - * @author Robin Müller - */ public abstract class PullRequestNotifier extends Notifier implements MatrixAggregatable { + + @Override public BuildStepMonitor getRequiredMonitorService() { return BuildStepMonitor.NONE; } @Override - public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { - GiteeClient client = getClient(build); - if (client == null) { - listener.getLogger().println("No Gitee connection configured"); - return true; - } - - PullRequest pullRequest = getPullRequest(build); - if (pullRequest != null) { - perform(build, listener, client, pullRequest); - } - return true; - } - - public MatrixAggregator createAggregator(MatrixBuild build, Launcher launcher, BuildListener listener) { - return new MatrixAggregator(build, launcher, listener) { + public MatrixAggregator createAggregator(MatrixBuild matrixBuild, Launcher launcher, BuildListener buildListener) { + return new MatrixAggregator(matrixBuild, launcher, buildListener) { @Override public boolean endBuild() throws InterruptedException, IOException { - perform(build, launcher, listener); + perform(matrixBuild, launcher, buildListener); return super.endBuild(); } }; } - protected abstract void perform(Run build, TaskListener listener, GiteeClient client, PullRequest pullRequest); - - PullRequest getPullRequest(Run run) { - GiteeWebHookCause cause = run.getCause(GiteeWebHookCause.class); - return cause == null ? null : cause.getData().getPullRequest(); - + @Override + public boolean perform(AbstractBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException { + GiteeClient giteeClient = GiteeItemConfig.getGiteeClient(build.getParent()); + if (giteeClient != null) { + GiteeWebHookCause giteeWebHookCause = build.getCause(GiteeWebHookCause.class); + if (giteeWebHookCause != null && giteeWebHookCause.getData().getPullRequestId() != null) { + perform(build, listener, giteeClient, giteeWebHookCause.getData()); + } + } else { + listener.getLogger().println("No Gitee connection configured"); + } + return true; } + + protected abstract void perform(Run build, TaskListener listener, GiteeClient giteeClient, GiteeWebHookCauseData giteeWebHookCauseData); + } diff --git a/src/main/java/com/gitee/jenkins/trigger/GiteePushTrigger.java b/src/main/java/com/gitee/jenkins/trigger/GiteePushTrigger.java deleted file mode 100644 index 1888fe7..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/GiteePushTrigger.java +++ /dev/null @@ -1,687 +0,0 @@ -package com.gitee.jenkins.trigger; - - -import com.gitee.jenkins.connection.GiteeConnection; -import com.gitee.jenkins.connection.GiteeConnectionConfig; -import com.gitee.jenkins.connection.GiteeConnectionProperty; -import com.gitee.jenkins.gitee.hook.model.PullRequestHook; -import com.gitee.jenkins.gitee.hook.model.NoteHook; -import com.gitee.jenkins.gitee.hook.model.PipelineHook; -import com.gitee.jenkins.gitee.hook.model.PushHook; -import com.gitee.jenkins.publisher.GiteeAcceptPullRequestPublisher; -import com.gitee.jenkins.publisher.GiteeMessagePublisher; -import com.gitee.jenkins.trigger.filter.*; -import com.gitee.jenkins.trigger.filter.PullRequestLabelFilterConfig; -import com.gitee.jenkins.trigger.handler.pull.PullRequestHookTriggerHandler; -import com.gitee.jenkins.trigger.handler.note.NoteHookTriggerHandler; -import com.gitee.jenkins.trigger.handler.pipeline.PipelineHookTriggerHandler; -import com.gitee.jenkins.trigger.handler.push.PushHookTriggerHandler; -import com.gitee.jenkins.webhook.GiteeWebHook; -import hudson.Extension; -import hudson.Util; -import hudson.init.InitMilestone; -import hudson.init.Initializer; -import hudson.model.AbstractProject; -import hudson.model.Item; -import hudson.model.Job; -import hudson.triggers.Trigger; -import hudson.triggers.TriggerDescriptor; -import hudson.util.Secret; -import hudson.util.SequentialExecutionQueue; -import jenkins.model.Jenkins; -import jenkins.model.ParameterizedJobMixIn; -import jenkins.triggers.SCMTriggerItem.SCMTriggerItems; -import net.karneim.pojobuilder.GeneratePojoBuilder; -import net.sf.json.JSONObject; -import org.jenkinsci.Symbol; -import org.kohsuke.stapler.Ancestor; -import org.kohsuke.stapler.AncestorInPath; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.Stapler; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -import java.io.IOException; -import java.io.ObjectStreamException; -import java.security.SecureRandom; - -import static com.gitee.jenkins.trigger.filter.BranchFilterConfig.BranchFilterConfigBuilder.branchFilterConfig; -import static com.gitee.jenkins.trigger.handler.pull.PullRequestHookTriggerHandlerFactory.newPullRequestHookTriggerHandler; -import static com.gitee.jenkins.trigger.handler.note.NoteHookTriggerHandlerFactory.newNoteHookTriggerHandler; -import static com.gitee.jenkins.trigger.handler.pipeline.PipelineHookTriggerHandlerFactory.newPipelineHookTriggerHandler; -import static com.gitee.jenkins.trigger.handler.push.PushHookTriggerHandlerFactory.newPushHookTriggerHandler; - - -/** - * Triggers a build when we receive a Gitee WebHook. - * - * @author Daniel Brooks - * @author Yashin Luo - * - */ -public class GiteePushTrigger extends Trigger> { - - private static final SecureRandom RANDOM = new SecureRandom(); - - private boolean triggerOnPush = true; - private boolean triggerOnCommitComment = false; - private boolean triggerOnOpenPullRequest = true; - private boolean triggerOnPipelineEvent = false; - private boolean triggerOnAcceptedPullRequest = false; - private String triggerOnUpdatePullRequest = "3"; - private boolean triggerOnClosedPullRequest = false; - private boolean triggerOnApprovedPullRequest = false; - private boolean triggerOnTestedPullRequest = false; - private boolean triggerOnNoteRequest = true; - private String noteRegex = ""; - private transient boolean ciSkip = true; - private BuildInstructionFilterType buildInstructionFilterType = BuildInstructionFilterType.NONE; - private boolean skipWorkInProgressPullRequest; - private boolean ciSkipFroTestNotRequired; - private boolean skipLastCommitHasBeenBuild; - private boolean setBuildDescription = true; - private transient boolean addNoteOnPullRequest; - private transient boolean addCiMessage; - private transient boolean addVoteOnPullRequest; - private transient boolean allowAllBranches = false; - private transient String branchFilterName; - private BranchFilterType branchFilterType; - private String includeBranchesSpec; - private String excludeBranchesSpec; - private String targetBranchRegex; - private PullRequestLabelFilterConfig pullRequestLabelFilterConfig; - private volatile Secret secretToken; - private String pendingBuildName; - private boolean cancelPendingBuildsOnUpdate; - private boolean cancelIncompleteBuildOnSamePullRequest; - private boolean ignorePullRequestConflicts; - - private transient BranchFilter branchFilter; - private transient PushHookTriggerHandler pushHookTriggerHandler; - private transient PullRequestHookTriggerHandler pullRequestHookTriggerHandler; - private transient NoteHookTriggerHandler noteHookTriggerHandler; - private transient PipelineHookTriggerHandler pipelineTriggerHandler; - private transient boolean acceptPullRequestOnSuccess; - private transient PullRequestLabelFilter pullRequestLabelFilter; - - /** - * @deprecated use {@link #GiteePushTrigger()} with setters to configure an instance of this class. - */ - @Deprecated - @GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") - public GiteePushTrigger(boolean triggerOnPush, - boolean triggerOnCommitComment, - boolean triggerOnOpenPullRequest, - String triggerOnUpdatePullRequest, - boolean triggerOnAcceptedPullRequest, - boolean triggerOnClosedPullRequest, - boolean triggerOnNoteRequest, String noteRegex, - boolean skipWorkInProgressPullRequest, boolean ciSkip, - BuildInstructionFilterType buildInstructionFilterType, - boolean setBuildDescription, boolean addNoteOnPullRequest, boolean addCiMessage, boolean addVoteOnPullRequest, - boolean acceptPullRequestOnSuccess, BranchFilterType branchFilterType, - String includeBranchesSpec, String excludeBranchesSpec, String targetBranchRegex, - PullRequestLabelFilterConfig pullRequestLabelFilterConfig, String secretToken, boolean triggerOnPipelineEvent, - boolean triggerOnApprovedPullRequest, String pendingBuildName, boolean cancelPendingBuildsOnUpdate, - boolean cancelIncompleteBuildOnSamePullRequest, - boolean ignorePullRequestConflicts) { - this.triggerOnPush = triggerOnPush; - this.triggerOnCommitComment = triggerOnCommitComment; - this.triggerOnOpenPullRequest = triggerOnOpenPullRequest; - this.triggerOnUpdatePullRequest = triggerOnUpdatePullRequest; - this.triggerOnAcceptedPullRequest = triggerOnAcceptedPullRequest; - this.triggerOnClosedPullRequest = triggerOnClosedPullRequest; - this.triggerOnNoteRequest = triggerOnNoteRequest; - this.noteRegex = noteRegex; - this.triggerOnPipelineEvent = triggerOnPipelineEvent; - this.ciSkip = ciSkip; - this.buildInstructionFilterType = buildInstructionFilterType; - this.skipWorkInProgressPullRequest = skipWorkInProgressPullRequest; - this.setBuildDescription = setBuildDescription; - this.addNoteOnPullRequest = addNoteOnPullRequest; - this.addCiMessage = addCiMessage; - this.addVoteOnPullRequest = addVoteOnPullRequest; - this.branchFilterType = branchFilterType; - this.includeBranchesSpec = includeBranchesSpec; - this.excludeBranchesSpec = excludeBranchesSpec; - this.targetBranchRegex = targetBranchRegex; - this.acceptPullRequestOnSuccess = acceptPullRequestOnSuccess; - this.pullRequestLabelFilterConfig = pullRequestLabelFilterConfig; - this.secretToken = Secret.fromString(secretToken); - this.triggerOnApprovedPullRequest = triggerOnApprovedPullRequest; - this.pendingBuildName = pendingBuildName; - this.cancelPendingBuildsOnUpdate = cancelPendingBuildsOnUpdate; - this.cancelIncompleteBuildOnSamePullRequest = cancelIncompleteBuildOnSamePullRequest; - this.ignorePullRequestConflicts = ignorePullRequestConflicts; - - initializeTriggerHandler(); - initializeBranchFilter(); - initializePullRequestLabelFilter(); - } - - @DataBoundConstructor - public GiteePushTrigger() { } - - @Initializer(after = InitMilestone.JOB_LOADED) - public static void migrateJobs() throws IOException { - GiteePushTrigger.DescriptorImpl oldConfig = Trigger.all().get(GiteePushTrigger.DescriptorImpl.class); - if (!oldConfig.jobsMigrated) { - GiteeConnectionConfig giteeConfig = (GiteeConnectionConfig) Jenkins.getInstance().getDescriptor(GiteeConnectionConfig.class); - giteeConfig.getConnections().add(new GiteeConnection( - oldConfig.giteeHostUrl, - oldConfig.giteeHostUrl, - oldConfig.GiteeApiToken, - "autodetect", - oldConfig.ignoreCertificateErrors, - 10, - 10)); - - String defaultConnectionName = giteeConfig.getConnections().get(0).getName(); - for (AbstractProject project : Jenkins.getInstance().getAllItems(AbstractProject.class)) { - GiteePushTrigger trigger = project.getTrigger(GiteePushTrigger.class); - if (trigger != null) { - project.addProperty(new GiteeConnectionProperty(defaultConnectionName)); - project.save(); - } - } - giteeConfig.save(); - oldConfig.jobsMigrated = true; - oldConfig.save(); - } - if (!oldConfig.jobsMigrated2) { - for (AbstractProject project : Jenkins.getInstance().getAllItems(AbstractProject.class)) { - GiteePushTrigger trigger = project.getTrigger(GiteePushTrigger.class); - if (trigger != null) { - if (trigger.addNoteOnPullRequest) { - project.getPublishersList().add(new GiteeMessagePublisher()); - } - if (trigger.acceptPullRequestOnSuccess) { - project.getPublishersList().add(new GiteeAcceptPullRequestPublisher()); - } - project.save(); - } - } - oldConfig.jobsMigrated2 = true; - oldConfig.save(); - } - - // 兼容构建指令升级 - if (!oldConfig.jobsMigrated4) { - for (AbstractProject project : Jenkins.getInstance().getAllItems(AbstractProject.class)) { - GiteePushTrigger trigger = project.getTrigger(GiteePushTrigger.class); - if (trigger != null) { - if (trigger.getCiSkip()) { - trigger.setBuildInstructionFilterType(BuildInstructionFilterType.CI_SKIP); - } else if (trigger.getBuildInstructionFilterType() == null) { - trigger.setBuildInstructionFilterType(BuildInstructionFilterType.NONE); - } - project.save(); - } - } - oldConfig.jobsMigrated3 = false; - oldConfig.jobsMigrated4 = true; - oldConfig.save(); - } - - } - - public boolean getAddNoteOnPullRequest() { return addNoteOnPullRequest; } - - public boolean getTriggerOnPush() { - return triggerOnPush; - } - - public boolean isTriggerOnCommitComment() { - return triggerOnCommitComment; - } - - public boolean getTriggerOnOpenPullRequest() { - return triggerOnOpenPullRequest; - } - - public boolean getTriggerOnTestedPullRequest() { - return triggerOnTestedPullRequest; - } - - public String getTriggerOnUpdatePullRequest() { - return triggerOnUpdatePullRequest; - } - - public boolean isTriggerOnAcceptedPullRequest() { - return triggerOnAcceptedPullRequest; - } - - public boolean isTriggerOnApprovedPullRequest() { - return triggerOnApprovedPullRequest; - } - - public boolean isTriggerOnClosedPullRequest() { - return triggerOnClosedPullRequest; - } - - public boolean getTriggerOnNoteRequest() { - return triggerOnNoteRequest; - } - - public boolean getTriggerOnPipelineEvent() { return triggerOnPipelineEvent; } - - public String getNoteRegex() { - return this.noteRegex == null ? "" : this.noteRegex; - } - - public boolean getSetBuildDescription() { - return setBuildDescription; - } - - public boolean getCiSkip() { - return ciSkip; - } - - public BuildInstructionFilterType getBuildInstructionFilterType() { - return buildInstructionFilterType; - } - - public boolean getCiSkipFroTestNotRequired() { - return ciSkipFroTestNotRequired; - } - - public boolean getSkipLastCommitHasBeenBuild() { - return skipLastCommitHasBeenBuild; - } - - public boolean isSkipWorkInProgressPullRequest() { - return skipWorkInProgressPullRequest; - } - - public boolean isSkipLastCommitHasBuild() { - return skipLastCommitHasBeenBuild; - } - - public boolean isSkipFroTestNotRequired() { - return ciSkipFroTestNotRequired; - } - - public BranchFilterType getBranchFilterType() { - return branchFilterType; - } - - public String getIncludeBranchesSpec() { - return includeBranchesSpec; - } - - public String getExcludeBranchesSpec() { - return excludeBranchesSpec; - } - - public String getTargetBranchRegex() { - return targetBranchRegex; - } - - public PullRequestLabelFilterConfig getPullRequestLabelFilterConfig() { - return pullRequestLabelFilterConfig; - } - - public String getSecretToken() { - return secretToken == null ? null : secretToken.getPlainText(); - } - - public String getPendingBuildName() { - return pendingBuildName; - } - - public boolean getCancelPendingBuildsOnUpdate() { - return this.cancelPendingBuildsOnUpdate; - } - - public boolean isCancelIncompleteBuildOnSamePullRequest() { - return cancelIncompleteBuildOnSamePullRequest; - } - - public boolean isIgnorePullRequestConflicts() { - return ignorePullRequestConflicts; - } - - @DataBoundSetter - public void setTriggerOnPush(boolean triggerOnPush) { - this.triggerOnPush = triggerOnPush; - } - - @DataBoundSetter - public void setTriggerOnCommitComment(boolean triggerOnCommitComment) { - this.triggerOnCommitComment = triggerOnCommitComment; - } - - @DataBoundSetter - public void setTriggerOnApprovedPullRequest(boolean triggerOnApprovedPullRequest) { - this.triggerOnApprovedPullRequest = triggerOnApprovedPullRequest; - } - - @DataBoundSetter - public void setTriggerOnTestedPullRequest(boolean triggerOnTestedPullRequest) { - this.triggerOnTestedPullRequest = triggerOnTestedPullRequest; - } - - @DataBoundSetter - public void setTriggerOnOpenPullRequest(boolean triggerOnOpenPullRequest) { - this.triggerOnOpenPullRequest = triggerOnOpenPullRequest; - } - - @DataBoundSetter - public void setTriggerOnAcceptedPullRequest(boolean triggerOnAcceptedPullRequest) { - this.triggerOnAcceptedPullRequest = triggerOnAcceptedPullRequest; - } - - @DataBoundSetter - public void setTriggerOnClosedPullRequest(boolean triggerOnClosedPullRequest) { - this.triggerOnClosedPullRequest = triggerOnClosedPullRequest; - } - - @DataBoundSetter - public void setTriggerOnNoteRequest(boolean triggerOnNoteRequest) { - this.triggerOnNoteRequest = triggerOnNoteRequest; - } - - @DataBoundSetter - public void setNoteRegex(String noteRegex) { - this.noteRegex = noteRegex; - } - - @DataBoundSetter - public void setCiSkip(boolean ciSkip) { - this.ciSkip = ciSkip; - } - - @DataBoundSetter - public void setBuildInstructionFilterType(BuildInstructionFilterType buildInstructionFilterType) { - this.buildInstructionFilterType = buildInstructionFilterType; - } - - @DataBoundSetter - public void setCiSkipFroTestNotRequired(boolean ciSkipFroTestNotRequired) { - this.ciSkipFroTestNotRequired = ciSkipFroTestNotRequired; - } - - @DataBoundSetter - public void setSkipWorkInProgressPullRequest(boolean skipWorkInProgressPullRequest) { - this.skipWorkInProgressPullRequest = skipWorkInProgressPullRequest; - } - - @DataBoundSetter - public void setSkipLastCommitHasBeenBuild(boolean skipLastCommitHasBeenBuild) { - this.skipLastCommitHasBeenBuild = skipLastCommitHasBeenBuild; - } - - - - @DataBoundSetter - public void setSetBuildDescription(boolean setBuildDescription) { - this.setBuildDescription = setBuildDescription; - } - - @DataBoundSetter - public void setAddNoteOnPullRequest(boolean addNoteOnPullRequest) { - this.addNoteOnPullRequest = addNoteOnPullRequest; - } - - @DataBoundSetter - public void setAddCiMessage(boolean addCiMessage) { - this.addCiMessage = addCiMessage; - } - - @DataBoundSetter - public void setAddVoteOnPullRequest(boolean addVoteOnPullRequest) { - this.addVoteOnPullRequest = addVoteOnPullRequest; - } - - @DataBoundSetter - public void setBranchFilterName(String branchFilterName) { - this.branchFilterName = branchFilterName; - } - - @DataBoundSetter - public void setBranchFilterType(BranchFilterType branchFilterType) { - this.branchFilterType = branchFilterType; - } - - @DataBoundSetter - public void setIncludeBranchesSpec(String includeBranchesSpec) { - this.includeBranchesSpec = includeBranchesSpec; - } - - @DataBoundSetter - public void setExcludeBranchesSpec(String excludeBranchesSpec) { - this.excludeBranchesSpec = excludeBranchesSpec; - } - - @DataBoundSetter - public void setTargetBranchRegex(String targetBranchRegex) { - this.targetBranchRegex = targetBranchRegex; - } - - @DataBoundSetter - public void setPullRequestLabelFilterConfig(PullRequestLabelFilterConfig pullRequestLabelFilterConfig) { - this.pullRequestLabelFilterConfig = pullRequestLabelFilterConfig; - } - - @DataBoundSetter - public void setSecretToken(String secretToken) { - this.secretToken = Secret.fromString(secretToken); - } - - @DataBoundSetter - public void setAcceptPullRequestOnSuccess(boolean acceptPullRequestOnSuccess) { - this.acceptPullRequestOnSuccess = acceptPullRequestOnSuccess; - } - - @DataBoundSetter - public void setTriggerOnUpdatePullRequest(String triggerOnUpdatePullRequest) { - this.triggerOnUpdatePullRequest = triggerOnUpdatePullRequest; - } - - @DataBoundSetter - public void setTriggerOnPipelineEvent(boolean triggerOnPipelineEvent) { - this.triggerOnPipelineEvent = triggerOnPipelineEvent; - } - - @DataBoundSetter - public void setPendingBuildName(String pendingBuildName) { - this.pendingBuildName = pendingBuildName; - } - - @DataBoundSetter - public void setCancelPendingBuildsOnUpdate(boolean cancelPendingBuildsOnUpdate) { - this.cancelPendingBuildsOnUpdate = cancelPendingBuildsOnUpdate; - } - - @DataBoundSetter - public void setCancelIncompleteBuildOnSamePullRequest(boolean cancelIncompleteBuildOnSamePullRequest) { - this.cancelIncompleteBuildOnSamePullRequest = cancelIncompleteBuildOnSamePullRequest; - } - - @DataBoundSetter - public void setIgnorePullRequestConflicts(boolean ignorePullRequestConflicts) { - this.ignorePullRequestConflicts = ignorePullRequestConflicts; - } - - // executes when the Trigger receives a push request - public void onPost(final PushHook hook) { - if (branchFilter == null) { - initializeBranchFilter(); - } - if (pullRequestLabelFilter == null) { - initializePullRequestLabelFilter(); - } - if (pushHookTriggerHandler == null) { - initializeTriggerHandler(); - } - pushHookTriggerHandler.handle(job, hook, buildInstructionFilterType, skipLastCommitHasBeenBuild, branchFilter, pullRequestLabelFilter); - } - - // executes when the Trigger receives a pull request - public void onPost(final PullRequestHook hook) { - if (branchFilter == null) { - initializeBranchFilter(); - } - if (pullRequestLabelFilter == null) { - initializePullRequestLabelFilter(); - } - if (pullRequestHookTriggerHandler == null) { - initializeTriggerHandler(); - } - pullRequestHookTriggerHandler.handle(job, hook, buildInstructionFilterType, skipLastCommitHasBeenBuild, branchFilter, pullRequestLabelFilter); - } - - // executes when the Trigger receives a note request - public void onPost(final NoteHook hook) { - if (branchFilter == null) { - initializeBranchFilter(); - } - if (pullRequestLabelFilter == null) { - initializePullRequestLabelFilter(); - } - if (noteHookTriggerHandler == null) { - initializeTriggerHandler(); - } - noteHookTriggerHandler.handle(job, hook, buildInstructionFilterType, skipLastCommitHasBeenBuild, branchFilter, pullRequestLabelFilter); - } - - // executes when the Trigger receives a pipeline event - public void onPost(final PipelineHook hook) { - if (pipelineTriggerHandler == null) { - initializeTriggerHandler(); - } - pipelineTriggerHandler.handle(job, hook, buildInstructionFilterType, skipLastCommitHasBeenBuild, branchFilter, pullRequestLabelFilter); - } - - private void initializeTriggerHandler() { - pullRequestHookTriggerHandler = newPullRequestHookTriggerHandler(triggerOnOpenPullRequest, - triggerOnUpdatePullRequest, triggerOnAcceptedPullRequest, triggerOnClosedPullRequest, - skipWorkInProgressPullRequest, triggerOnApprovedPullRequest, triggerOnTestedPullRequest, cancelPendingBuildsOnUpdate, ciSkipFroTestNotRequired, - cancelIncompleteBuildOnSamePullRequest, - ignorePullRequestConflicts - ); - noteHookTriggerHandler = newNoteHookTriggerHandler(triggerOnCommitComment, triggerOnNoteRequest, noteRegex, ciSkipFroTestNotRequired, cancelIncompleteBuildOnSamePullRequest, ignorePullRequestConflicts); - pushHookTriggerHandler = newPushHookTriggerHandler(triggerOnPush, skipWorkInProgressPullRequest); - pipelineTriggerHandler = newPipelineHookTriggerHandler(triggerOnPipelineEvent); - } - - private void initializeBranchFilter() { - if (branchFilterType == null) { - branchFilterType = BranchFilterType.All; - } - - branchFilter = BranchFilterFactory.newBranchFilter(branchFilterConfig() - .withIncludeBranchesSpec(includeBranchesSpec) - .withExcludeBranchesSpec(excludeBranchesSpec) - .withTargetBranchRegex(targetBranchRegex) - .build(branchFilterType)); - } - - private void initializePullRequestLabelFilter() { - pullRequestLabelFilter = PullRequestLabelFilterFactory.newPullRequestLabelFilter(pullRequestLabelFilterConfig); - } - - @Override - protected Object readResolve() throws ObjectStreamException { - initializeTriggerHandler(); - initializeBranchFilter(); - initializePullRequestLabelFilter(); - return super.readResolve(); - } - - public static GiteePushTrigger getFromJob(Job job) { - GiteePushTrigger trigger = null; - if (job instanceof ParameterizedJobMixIn.ParameterizedJob) { - ParameterizedJobMixIn.ParameterizedJob p = (ParameterizedJobMixIn.ParameterizedJob) job; - for (Trigger t : p.getTriggers().values()) { - if (t instanceof GiteePushTrigger) { - trigger = (GiteePushTrigger) t; - } - } - } - return trigger; - } - - @Extension - @Symbol("gitee") - public static class DescriptorImpl extends TriggerDescriptor { - - private transient final SequentialExecutionQueue queue = new SequentialExecutionQueue(Jenkins.MasterComputer.threadPoolForRemoting); - private boolean jobsMigrated = false; - private boolean jobsMigrated2 = false; - private boolean jobsMigrated3 = false; - private boolean jobsMigrated4 = false; - private String GiteeApiToken; - private String giteeHostUrl = ""; - private boolean ignoreCertificateErrors = false; - - public DescriptorImpl() { - load(); - } - - @Override - public boolean isApplicable(Item item) { - return item instanceof Job - && SCMTriggerItems.asSCMTriggerItem(item) != null - && item instanceof ParameterizedJobMixIn.ParameterizedJob; - } - - @Override - public String getDisplayName() { - Job project = retrieveCurrentJob(); - if (project != null) { - try { - return Messages.Build_Gitee_WebHook(retrieveProjectUrl(project)); -// return "Build when a change is pushed to Gitee"; - } catch (IllegalStateException e) { - // nothing to do - } - } - return "Build when a change is pushed to Gitee, unknown URL"; - } - - private StringBuilder retrieveProjectUrl(Job project) { - return new StringBuilder() - .append(Jenkins.getInstance().getRootUrl()) - .append(GiteeWebHook.WEBHOOK_URL) - .append(retrieveParentUrl(project)) - .append('/').append(Util.rawEncode(project.getName())); - } - - private StringBuilder retrieveParentUrl(Item item) { - if (item.getParent() instanceof Item) { - Item parent = (Item) item.getParent(); - return retrieveParentUrl(parent).append('/').append(Util.rawEncode(parent.getName())); - } else { - return new StringBuilder(); - } - } - - private Job retrieveCurrentJob() { - StaplerRequest request = Stapler.getCurrentRequest(); - if (request != null) { - Ancestor ancestor = request.findAncestor(Job.class); - return ancestor == null ? null : (Job) ancestor.getObject(); - } - return null; - } - - @Override - public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { - save(); - return super.configure(req, formData); - } - - public void doGenerateSecretToken(@AncestorInPath final Job project, StaplerResponse response) { - byte[] random = new byte[16]; // 16x8=128bit worth of randomness, since we use md5 digest as the API token - RANDOM.nextBytes(random); - String secretToken = Util.toHexString(random); - response.setHeader("script", "document.getElementById('giteeSecretToken').value='" + secretToken + "'"); - } - - public void doClearSecretToken(@AncestorInPath final Job project, StaplerResponse response) {; - response.setHeader("script", "document.getElementById('giteeSecretToken').value=''"); - } - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/GiteeTrigger.java b/src/main/java/com/gitee/jenkins/trigger/GiteeTrigger.java new file mode 100644 index 0000000..5999e89 --- /dev/null +++ b/src/main/java/com/gitee/jenkins/trigger/GiteeTrigger.java @@ -0,0 +1,290 @@ +package com.gitee.jenkins.trigger; + +import com.gitee.jenkins.GiteeWebHook; +import com.gitee.jenkins.enums.BranchNameFilterType; +import com.gitee.jenkins.enums.BuildInstructionFilterType; +import com.gitee.jenkins.enums.PullRequestUpdateType; +import hudson.Extension; +import hudson.Util; +import hudson.init.InitMilestone; +import hudson.init.Initializer; +import hudson.model.AbstractProject; +import hudson.model.Item; +import hudson.model.Job; +import hudson.triggers.Trigger; +import hudson.triggers.TriggerDescriptor; +import hudson.util.Secret; +import jenkins.model.Jenkins; +import jenkins.model.ParameterizedJobMixIn; +import jenkins.triggers.SCMTriggerItem; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import net.sf.json.JSONObject; +import org.jenkinsci.Symbol; +import org.jenkinsci.plugins.workflow.job.WorkflowJob; +import org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty; +import org.kohsuke.stapler.*; + +import java.io.IOException; +import java.security.SecureRandom; + +/** + * gitee触发器 + */ +@Getter +@Setter(onMethod = @_(@DataBoundSetter)) +@NoArgsConstructor(onConstructor = @_(@DataBoundConstructor)) +public class GiteeTrigger extends Trigger> { + + /** + * 推送触发 + */ + private boolean triggerOnPush; + + /** + * 提交评论触发 + */ + private boolean triggerOnCommitComment; + + /** + * 新建 PR 触发 + */ + private boolean triggerOnOpenPullRequest; + + /** + * 更新 PR 触发 + */ + private PullRequestUpdateType triggerOnUpdatePullRequest; + + /** + * 接受 PR 触发 + */ + private boolean triggerOnAcceptedPullRequest; + + /** + * 关闭 PR 触发 + */ + private boolean triggerOnClosedPullRequest; + + /** + * PR 审查通过触发 + */ + private boolean triggerOnApprovedPullRequest; + + /** + * PR 测试通过触发 + */ + private boolean triggerOnTestedPullRequest; + + /** + * 评论 PR 触发 + */ + private boolean triggerOnNoteRequest; + + /** + * 评论正则表达式 + */ + private String noteRegex; + + /** + * 是否通过 [ci-skip] 跳过构建 + * + * @deprecated 旧版本遗留选项 + */ + @Deprecated + private transient boolean ciSkip; + + /** + * 构建指令过滤 + */ + private BuildInstructionFilterType buildInstructionFilterType; + + /** + * PR 不要求必须测试时过滤构建 + */ + private boolean ciSkipFroTestNotRequired; + + /** + * 过滤已经构建的 Commit 版本 + */ + private boolean skipLastCommitHasBeenBuild; + + /** + * 取消相同 PR 未完成构建 + */ + private boolean cancelIncompleteBuildOnSamePullRequest; + + /** + * 忽略 PR 代码冲突 + */ + private boolean ignorePullRequestConflicts; + + /** + * 允许触发构建的分支 + */ + private BranchNameFilterType branchNameFilterType; + + /** + * 包含分支 + */ + private String includeBranchNames; + + /** + * 排除分支 + */ + private String excludeBranchNames; + + /** + * 分支正则表达式 + */ + private String branchNameRegex; + + /** + * Gitee WebHook 密码 + */ + private volatile Secret secretToken; + + /** + * 获取触发器 + * + * @param job + * @return + */ + public static GiteeTrigger getGiteeTrigger(Job job) { + if (job instanceof ParameterizedJobMixIn.ParameterizedJob) { + ParameterizedJobMixIn.ParameterizedJob parameterizedJob = (ParameterizedJobMixIn.ParameterizedJob) job; + GiteeTrigger giteeTrigger = (GiteeTrigger) parameterizedJob.getTriggers().get(Trigger.all().get(GiteeTrigger.DescriptorImpl.class)); + if (giteeTrigger != null) { + return giteeTrigger; + } + } + return null; + } + + /** + * 老版本兼容操作 + * + * @throws IOException + */ + @Initializer(after = InitMilestone.JOB_LOADED) + public static void migrate() throws IOException { + GiteeTrigger.DescriptorImpl oldConfig = Trigger.all().get(GiteeTrigger.DescriptorImpl.class); + if (oldConfig == null) { + return; + } + + if (!oldConfig.migrated) { + for (Job job : Jenkins.get().getAllItems(Job.class)) { + if (job instanceof AbstractProject) { + GiteeTrigger giteeTrigger = ((AbstractProject) job).getTrigger(GiteeTrigger.class); + if (migratedCiSkip(giteeTrigger)) { + job.save(); + } + } else if (job instanceof WorkflowJob) { + PipelineTriggersJobProperty jobProperty = job.getProperty(PipelineTriggersJobProperty.class); + if (jobProperty != null) { + GiteeTrigger giteeTrigger = (GiteeTrigger) jobProperty.getTriggerForDescriptor(oldConfig); + if (migratedCiSkip(giteeTrigger)) { + job.save(); + } + } + } + } + } + oldConfig.migrated = true; + oldConfig.save(); + } + + /** + * 兼容 ci-skip 升级 + * + * @param giteeTrigger + */ + private static boolean migratedCiSkip(GiteeTrigger giteeTrigger) { + if (giteeTrigger != null && giteeTrigger.getBuildInstructionFilterType() == null) { + if (giteeTrigger.isCiSkip()) { + giteeTrigger.setBuildInstructionFilterType(BuildInstructionFilterType.CI_SKIP); + } else { + giteeTrigger.setBuildInstructionFilterType(BuildInstructionFilterType.NONE); + } + return true; + } + return false; + } + + @Extension + @Symbol("gitee") + public static class DescriptorImpl extends TriggerDescriptor { + + private static final SecureRandom RANDOM = new SecureRandom(); + + private boolean migrated = false; + + @Override + public boolean isApplicable(Item item) { + return item instanceof Job + && SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(item) != null + && item instanceof ParameterizedJobMixIn.ParameterizedJob; + } + + @Override + public boolean configure(StaplerRequest req, JSONObject formData) throws FormException { + save(); + return super.configure(req, formData); + } + + @Override + public String getDisplayName() { + Job project = retrieveCurrentJob(); + if (project != null) { + try { + return Messages.Build_Gitee_WebHook(retrieveProjectUrl(project)); + } catch (IllegalStateException e) { + } + } + return "Build when a change is pushed to Gitee, unknown URL"; + } + + private StringBuilder retrieveProjectUrl(Job project) { + return new StringBuilder() + .append(Jenkins.get().getRootUrl()) + .append(GiteeWebHook.WEBHOOK_URL) + .append(retrieveParentUrl(project)) + .append('/') + .append(Util.rawEncode(project.getName())); + } + + private StringBuilder retrieveParentUrl(Item item) { + if (item.getParent() instanceof Item) { + Item parent = (Item) item.getParent(); + return retrieveParentUrl(parent).append('/').append(Util.rawEncode(parent.getName())); + } else { + return new StringBuilder(); + } + } + + private Job retrieveCurrentJob() { + StaplerRequest request = Stapler.getCurrentRequest(); + if (request != null) { + Ancestor ancestor = request.findAncestor(Job.class); + return ancestor == null ? null : (Job) ancestor.getObject(); + } + return null; + } + + public void doGenerateSecretToken(@AncestorInPath final Job project, StaplerResponse response) { + // 16x8=128bit worth of randomness, since we use md5 digest as the API token + byte[] random = new byte[16]; + RANDOM.nextBytes(random); + String secretToken = Util.toHexString(random); + response.setHeader("script", "document.getElementById('secretToken').value='" + secretToken + "'"); + } + + public void doClearSecretToken(@AncestorInPath final Job project, StaplerResponse response) { + response.setHeader("script", "document.getElementById('secretToken').value=''"); + } + + } + +} diff --git a/src/main/java/com/gitee/jenkins/trigger/branch/AntPathMatcherSet.java b/src/main/java/com/gitee/jenkins/trigger/branch/AntPathMatcherSet.java deleted file mode 100644 index 297aeb7..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/branch/AntPathMatcherSet.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.gitee.jenkins.trigger.branch; - -import org.springframework.util.AntPathMatcher; - -import java.util.Collection; -import java.util.HashSet; - -/** - * @author Robin Müller - */ -class AntPathMatcherSet extends HashSet { - - private transient final AntPathMatcher matcher = new AntPathMatcher(); - - public AntPathMatcherSet(Collection c) { - super(c); - } - - @Override - public boolean contains(Object o) { - for (String s : this) { - if (matcher.match(o.toString(), s)) { - return true; - } - } - return false; - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/exception/NoRevisionToBuildException.java b/src/main/java/com/gitee/jenkins/trigger/exception/NoRevisionToBuildException.java deleted file mode 100644 index 7c90dbc..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/exception/NoRevisionToBuildException.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.gitee.jenkins.trigger.exception; - -/** - * @author Robin Müller - */ -public class NoRevisionToBuildException extends Exception { -} diff --git a/src/main/java/com/gitee/jenkins/trigger/filter/AllBranchesFilter.java b/src/main/java/com/gitee/jenkins/trigger/filter/AllBranchesFilter.java deleted file mode 100644 index 9ace6d9..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/filter/AllBranchesFilter.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.gitee.jenkins.trigger.filter; - -/** - * @author Robin Müller - */ -class AllBranchesFilter implements BranchFilter { - @Override - public boolean isBranchAllowed(String branchName) { - return true; - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/filter/BranchFilter.java b/src/main/java/com/gitee/jenkins/trigger/filter/BranchFilter.java deleted file mode 100644 index 90b80ef..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/filter/BranchFilter.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gitee.jenkins.trigger.filter; - -/** - * @author Robin Müller - */ -public interface BranchFilter { - - boolean isBranchAllowed(String branchName); -} diff --git a/src/main/java/com/gitee/jenkins/trigger/filter/BranchFilterConfig.java b/src/main/java/com/gitee/jenkins/trigger/filter/BranchFilterConfig.java deleted file mode 100644 index 64e1964..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/filter/BranchFilterConfig.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.gitee.jenkins.trigger.filter; - -/** - * @author Robin Müller - */ -public final class BranchFilterConfig { - - private final BranchFilterType type; - private final String includeBranchesSpec; - private final String excludeBranchesSpec; - private final String targetBranchRegex; - - private BranchFilterConfig(BranchFilterType type, String includeBranchesSpec, String excludeBranchesSpec, String targetBranchRegex) { - this.type = type; - this.includeBranchesSpec = includeBranchesSpec; - this.excludeBranchesSpec = excludeBranchesSpec; - this.targetBranchRegex = targetBranchRegex; - } - - public BranchFilterType getType() { - return type; - } - - String getIncludeBranchesSpec() { - return includeBranchesSpec; - } - - String getExcludeBranchesSpec() { - return excludeBranchesSpec; - } - - String getTargetBranchRegex() { - return targetBranchRegex; - } - - public static class BranchFilterConfigBuilder { - private String includeBranchesSpec; - private String excludeBranchesSpec; - private String targetBranchRegex; - - public static BranchFilterConfigBuilder branchFilterConfig() { - return new BranchFilterConfigBuilder(); - } - - public BranchFilterConfigBuilder withIncludeBranchesSpec(String includeBranchesSpec) { - this.includeBranchesSpec = includeBranchesSpec; - return this; - } - - public BranchFilterConfigBuilder withExcludeBranchesSpec(String excludeBranchesSpec) { - this.excludeBranchesSpec = excludeBranchesSpec; - return this; - } - - public BranchFilterConfigBuilder withTargetBranchRegex(String targetBranchRegex) { - this.targetBranchRegex = targetBranchRegex; - return this; - } - - public BranchFilterConfig build(BranchFilterType type) { - return new BranchFilterConfig(type, includeBranchesSpec, excludeBranchesSpec, targetBranchRegex); - } - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/filter/BranchFilterFactory.java b/src/main/java/com/gitee/jenkins/trigger/filter/BranchFilterFactory.java deleted file mode 100644 index 1b69bbe..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/filter/BranchFilterFactory.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.gitee.jenkins.trigger.filter; - -/** - * @author Robin Müller - */ -public final class BranchFilterFactory { - - private BranchFilterFactory() { } - - public static BranchFilter newBranchFilter(BranchFilterConfig config) { - - if(config == null) - return new AllBranchesFilter(); - - switch (config.getType()) { - case NameBasedFilter: - return new NameBasedFilter(config.getIncludeBranchesSpec(), config.getExcludeBranchesSpec()); - case RegexBasedFilter: - return new RegexBasedFilter(config.getTargetBranchRegex()); - default: - return new AllBranchesFilter(); - } - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/filter/BranchFilterType.java b/src/main/java/com/gitee/jenkins/trigger/filter/BranchFilterType.java deleted file mode 100644 index d70308b..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/filter/BranchFilterType.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.gitee.jenkins.trigger.filter; - -/** - * @author Robin Müller - */ -public enum BranchFilterType { - All, - NameBasedFilter, - RegexBasedFilter -} diff --git a/src/main/java/com/gitee/jenkins/trigger/filter/BuildInstructionFilter.java b/src/main/java/com/gitee/jenkins/trigger/filter/BuildInstructionFilter.java deleted file mode 100644 index 69c7e2e..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/filter/BuildInstructionFilter.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.gitee.jenkins.trigger.filter; - -/** - * @author zhanggx - */ -public interface BuildInstructionFilter { - - /** - * 是否触发构建 - * - * @param body - * @return - */ - boolean isBuildAllow(String body); - -} diff --git a/src/main/java/com/gitee/jenkins/trigger/filter/BuildInstructionFilterType.java b/src/main/java/com/gitee/jenkins/trigger/filter/BuildInstructionFilterType.java deleted file mode 100644 index e13ed51..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/filter/BuildInstructionFilterType.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.gitee.jenkins.trigger.filter; - -/** - * @author zhanggx - */ -public enum BuildInstructionFilterType implements BuildInstructionFilter { - - /** - * 无操作 - */ - NONE("") { - @Override - public boolean isBuildAllow(String body) { - return true; - } - }, - /** - * 包含 [ci-skip] 时跳过构建 - */ - CI_SKIP("[ci-skip]") { - @Override - public boolean isBuildAllow(String body) { - return body == null ? true : !body.contains(getBody()); - } - }, - /** - * 包含 [ci-build] 时触发构建 - */ - CI_BUILD("[ci-build]") { - @Override - public boolean isBuildAllow(String body) { - return body == null ? false : body.contains(getBody()); - } - }; - - private String body; - - BuildInstructionFilterType(String body) { - this.body = body; - } - - public String getBody() { - return body; - } - -} diff --git a/src/main/java/com/gitee/jenkins/trigger/filter/NameBasedFilter.java b/src/main/java/com/gitee/jenkins/trigger/filter/NameBasedFilter.java deleted file mode 100644 index a9f78bf..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/filter/NameBasedFilter.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.gitee.jenkins.trigger.filter; - -import com.google.common.base.Splitter; -import org.springframework.util.AntPathMatcher; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * @author Robin Müller - */ -class NameBasedFilter implements BranchFilter { - - private final List includedBranches; - private final List excludedBranches; - - public NameBasedFilter(String includedBranches, String excludedBranches) { - this.includedBranches = convert(includedBranches); - this.excludedBranches = convert(excludedBranches); - } - - @Override - public boolean isBranchAllowed(String branchName) { - return hasNoBranchSpecs() || (isBranchNotExcluded(branchName) && isBranchIncluded(branchName)); - } - - private boolean hasNoBranchSpecs() { - return includedBranches.isEmpty() && excludedBranches.isEmpty(); - } - - private boolean isBranchNotExcluded(String branchName) { - AntPathMatcher matcher = new AntPathMatcher(); - for (String excludePattern : excludedBranches) { - if (matcher.match(excludePattern, branchName)) { - return false; - } - } - return true; - } - - private boolean isBranchIncluded(String branchName) { - AntPathMatcher matcher = new AntPathMatcher(); - for (String includePattern : includedBranches) { - if (matcher.match(includePattern, branchName)) { - return true; - } - } - return includedBranches.isEmpty(); - } - - private List convert(String commaSeparatedString) { - if (commaSeparatedString == null) - return Collections.EMPTY_LIST; - - ArrayList result = new ArrayList<>(); - for (String s : Splitter.on(',').omitEmptyStrings().trimResults().split(commaSeparatedString)) { - result.add(s); - } - return result; - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/filter/NopPullRequestLabelFilter.java b/src/main/java/com/gitee/jenkins/trigger/filter/NopPullRequestLabelFilter.java deleted file mode 100644 index 6f15e33..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/filter/NopPullRequestLabelFilter.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.jenkins.trigger.filter; - -import java.util.Collection; - -/** - * @author Robin Müller - */ -class NopPullRequestLabelFilter implements PullRequestLabelFilter { - @Override - public boolean isPullRequestAllowed(Collection labels) { - return true; - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/filter/PullRequestLabelFilter.java b/src/main/java/com/gitee/jenkins/trigger/filter/PullRequestLabelFilter.java deleted file mode 100644 index bbff02b..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/filter/PullRequestLabelFilter.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.gitee.jenkins.trigger.filter; - -import java.util.Collection; - -/** - * @author Robin Müller - */ -public interface PullRequestLabelFilter { - boolean isPullRequestAllowed(Collection labels); -} diff --git a/src/main/java/com/gitee/jenkins/trigger/filter/PullRequestLabelFilterConfig.java b/src/main/java/com/gitee/jenkins/trigger/filter/PullRequestLabelFilterConfig.java deleted file mode 100644 index c67e171..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/filter/PullRequestLabelFilterConfig.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.gitee.jenkins.trigger.filter; - -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.DataBoundSetter; - -/** - * @author Robin Müller - */ -public class PullRequestLabelFilterConfig { - - private String include; - private String exclude; - - /** - * @deprecated use {@link #PullRequestLabelFilterConfig()} with setters to configure an instance of this class. - */ - @Deprecated - public PullRequestLabelFilterConfig(String include, String exclude) { - this.include = include; - this.exclude = exclude; - } - - @DataBoundConstructor - public PullRequestLabelFilterConfig() { } - - public String getInclude() { - return include; - } - - public String getExclude() { - return exclude; - } - - @DataBoundSetter - public void setInclude(String include) { - this.include = include; - } - - @DataBoundSetter - public void setExclude(String exclude) { - this.exclude = exclude; - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/filter/PullRequestLabelFilterFactory.java b/src/main/java/com/gitee/jenkins/trigger/filter/PullRequestLabelFilterFactory.java deleted file mode 100644 index 161c3e1..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/filter/PullRequestLabelFilterFactory.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gitee.jenkins.trigger.filter; - -/** - * @author Robin Müller - */ -public class PullRequestLabelFilterFactory { - - private PullRequestLabelFilterFactory() { } - - public static PullRequestLabelFilter newPullRequestLabelFilter(PullRequestLabelFilterConfig config) { - if (config == null) { - return new NopPullRequestLabelFilter(); - } else { - return new PullRequestLabelFilterImpl(config.getInclude(), config.getExclude()); - } - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/filter/PullRequestLabelFilterImpl.java b/src/main/java/com/gitee/jenkins/trigger/filter/PullRequestLabelFilterImpl.java deleted file mode 100644 index 0adbb5f..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/filter/PullRequestLabelFilterImpl.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.gitee.jenkins.trigger.filter; - -import com.google.common.base.Splitter; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -/** - * @author Robin Müller - */ -class PullRequestLabelFilterImpl implements PullRequestLabelFilter { - - private final Set includeLabels; - private final Set excludeLabels; - - public PullRequestLabelFilterImpl(String includeLabels, String excludeLabels) { - this.includeLabels = convert(includeLabels); - this.excludeLabels = convert(excludeLabels); - } - - @Override - public boolean isPullRequestAllowed(Collection labels) { - return containsNoExcludeLabel(labels) && containsIncludeLabel(labels); - } - - private boolean containsNoExcludeLabel(Collection labels) { - for (String excludeLabel : excludeLabels) { - if (labels != null && labels.contains(excludeLabel)) { - return false; - } - } - return true; - } - - private boolean containsIncludeLabel(Collection labels) { - for (String includeLabel : includeLabels) { - if (labels != null && labels.contains(includeLabel)) { - return true; - } - } - return includeLabels.isEmpty(); - } - - private Set convert(String commaSeparatedString) { - Set result = new HashSet<>(); - for (String s : Splitter.on(',').omitEmptyStrings().trimResults().split(commaSeparatedString)) { - result.add(s); - } - return result; - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/filter/RegexBasedFilter.java b/src/main/java/com/gitee/jenkins/trigger/filter/RegexBasedFilter.java deleted file mode 100644 index da3ecee..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/filter/RegexBasedFilter.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.gitee.jenkins.trigger.filter; - -import org.apache.commons.lang.StringUtils; - -/** - * @author Robin Müller - */ -class RegexBasedFilter implements BranchFilter { - - private final String regex; - - public RegexBasedFilter(String regex) { - this.regex = regex; - } - - @Override - public boolean isBranchAllowed(String branchName) { - return StringUtils.isEmpty(branchName) || StringUtils.isEmpty(regex) || branchName.matches(regex); - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/AbstractWebHookTriggerHandler.java b/src/main/java/com/gitee/jenkins/trigger/handler/AbstractWebHookTriggerHandler.java deleted file mode 100644 index d86220e..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/AbstractWebHookTriggerHandler.java +++ /dev/null @@ -1,186 +0,0 @@ -package com.gitee.jenkins.trigger.handler; - -import com.gitee.jenkins.cause.CauseData; -import com.gitee.jenkins.cause.GiteeWebHookCause; -import com.gitee.jenkins.gitee.hook.model.WebHook; -import com.gitee.jenkins.trigger.exception.NoRevisionToBuildException; -import com.gitee.jenkins.trigger.filter.BranchFilter; -import com.gitee.jenkins.trigger.filter.BuildInstructionFilter; -import com.gitee.jenkins.trigger.filter.PullRequestLabelFilter; -import com.gitee.jenkins.util.LoggerUtil; -import hudson.model.*; -import hudson.plugins.git.GitSCM; -import hudson.plugins.git.RevisionParameterAction; -import hudson.scm.SCM; -import jenkins.model.ParameterizedJobMixIn; -import jenkins.triggers.SCMTriggerItem; -import net.karneim.pojobuilder.GeneratePojoBuilder; -import org.eclipse.jgit.transport.RemoteConfig; -import org.eclipse.jgit.transport.URIish; -import org.jenkinsci.plugins.workflow.job.WorkflowRun; - -import javax.servlet.ServletException; -import java.io.IOException; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * @author Robin Müller - */ -public abstract class AbstractWebHookTriggerHandler implements WebHookTriggerHandler { - - private static final Logger LOGGER = Logger.getLogger(AbstractWebHookTriggerHandler.class.getName()); - protected PendingBuildsHandler pendingBuildsHandler = new PendingBuildsHandler(); - - @Override - public void handle(Job job, H hook, BuildInstructionFilter buildInstructionFilter, boolean skipLastCommitHasBeenBuild, BranchFilter branchFilter, PullRequestLabelFilter pullRequestLabelFilter) { - if (isCiSkip(hook, buildInstructionFilter)) { - LOGGER.log(Level.INFO, "Skipping due to ci-skip."); - return; - } - - if (skipLastCommitHasBeenBuild && isCommitSkip(job, hook)) { - LOGGER.log(Level.INFO, "Skipping due to ignore last commit has been build."); - return; - } - - String targetBranch = getTargetBranch(hook); - if (branchFilter.isBranchAllowed(targetBranch)) { - LOGGER.log(Level.INFO, "{0} triggered for {1}.", LoggerUtil.toArray(job.getFullName(), getTriggerType())); - cancelPendingBuildsIfNecessary(job, hook); - cancelIncompleteBuildIfNecessary(job, hook); - scheduleBuild(job, createActions(job, hook)); - } else { - LOGGER.log(Level.INFO, "branch {0} is not allowed", targetBranch); - } - } - - protected abstract String getTriggerType(); - - protected abstract boolean isCiSkip(H hook, BuildInstructionFilter buildInstructionFilter); - protected abstract boolean isCommitSkip(Job job, H hook); - - protected Action[] createActions(Job job, H hook) { - ArrayList actions = new ArrayList<>(); - actions.add(new CauseAction(new GiteeWebHookCause(retrieveCauseData(hook)))); - try { - SCMTriggerItem item = SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(job); - GitSCM gitSCM = getGitSCM(item); - actions.add(createRevisionParameter(hook, gitSCM)); - } catch (NoRevisionToBuildException e) { - LOGGER.log(Level.WARNING, "unknown handled situation, dont know what revision to build for req {0} for job {1}", - new Object[]{hook, (job != null ? job.getFullName() : null)}); - } - return actions.toArray(new Action[actions.size()]); - } - - protected void cancelPendingBuildsIfNecessary(Job job, H hook) {} - - protected void cancelIncompleteBuildIfNecessary(Job job, H hook) {} - - protected abstract CauseData retrieveCauseData(H hook); - - protected abstract String getTargetBranch(H hook); - - protected abstract RevisionParameterAction createRevisionParameter(H hook, GitSCM gitSCM) throws NoRevisionToBuildException; - - protected abstract BuildStatusUpdate retrieveBuildStatusUpdate(H hook); - - protected URIish retrieveUrIish(WebHook hook, GitSCM gitSCM) { - if (hook.getRepository() == null || gitSCM == null) { - return null; - } - try { - Set set = new HashSet<>(); - set.add(new URIish(hook.getRepository().getUrl())); - set.add(new URIish(hook.getRepository().getGitHttpUrl())); - set.add(new URIish(hook.getRepository().getGitSshUrl())); - // uri 需与当前项目仓库个url一致,避免触发多个构建 - for (RemoteConfig remote : gitSCM.getRepositories()) { - for (URIish remoteURL : remote.getURIs()) { - if (set.contains(remoteURL)) { - return remoteURL; - } - } - } - } catch (URISyntaxException e) { - LOGGER.log(Level.WARNING, "could not parse URL"); - } - return null; - } - - protected void scheduleBuild(Job job, Action[] actions) { - int projectBuildDelay = 0; - if (job instanceof ParameterizedJobMixIn.ParameterizedJob) { - ParameterizedJobMixIn.ParameterizedJob abstractProject = (ParameterizedJobMixIn.ParameterizedJob) job; - if (abstractProject.getQuietPeriod() > projectBuildDelay) { - projectBuildDelay = abstractProject.getQuietPeriod(); - } - } - retrieveScheduleJob(job).scheduleBuild2(projectBuildDelay, actions); - } - - private ParameterizedJobMixIn retrieveScheduleJob(final Job job) { - // TODO 1.621+ use standard method - return new ParameterizedJobMixIn() { - @Override - protected Job asJob() { - return job; - } - }; - } - - private GitSCM getGitSCM(SCMTriggerItem item) { - if (item != null) { - for (SCM scm : item.getSCMs()) { - if (scm instanceof GitSCM) { - return (GitSCM) scm; - } - } - } - return null; - } - - protected void doStop(Run build) throws IOException, ServletException { - if (build.isBuilding()) { - if (build instanceof AbstractBuild) { - ((AbstractBuild) build).doStop(); - LOGGER.log(Level.WARNING, "Abort incomplete build"); - } else if (build instanceof WorkflowRun) { - ((WorkflowRun) build).doStop(); - LOGGER.log(Level.WARNING, "Abort incomplete build"); - } else { - LOGGER.log(Level.WARNING, "Unable to abort incomplete build, build type not found: " + build.getClass().getName()); - } - } - } - - public static class BuildStatusUpdate { - private final Integer projectId; - private final String sha; - private final String ref; - - @GeneratePojoBuilder(intoPackage = "*.builder.generated", withFactoryMethod = "*") - public BuildStatusUpdate(Integer projectId, String sha, String ref) { - this.projectId = projectId; - this.sha = sha; - this.ref = ref; - } - - public Integer getProjectId() { - return projectId; - } - - public String getSha() { - return sha; - } - - public String getRef() { - return ref; - } - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/PendingBuildsHandler.java b/src/main/java/com/gitee/jenkins/trigger/handler/PendingBuildsHandler.java deleted file mode 100644 index 440b527..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/PendingBuildsHandler.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.gitee.jenkins.trigger.handler; - -import com.gitee.jenkins.cause.CauseData; -import com.gitee.jenkins.cause.GiteeWebHookCause; -import com.gitee.jenkins.util.LoggerUtil; -import hudson.model.Cause; -import hudson.model.Job; -import hudson.model.Queue; -import jenkins.model.Jenkins; - -import java.util.logging.Level; -import java.util.logging.Logger; - -public class PendingBuildsHandler { - - private static final Logger LOGGER = Logger.getLogger(PendingBuildsHandler.class.getName()); - - public void cancelPendingBuilds(Job job, Integer projectId, String branch) { - Queue queue = Jenkins.getInstance().getQueue(); - for (Queue.Item item : queue.getItems()) { - if (!job.getName().equals(item.task.getName())) { - continue; - } - GiteeWebHookCause queueItemGiteeWebHookCause = getGiteeWebHookCauseData(item); - if (queueItemGiteeWebHookCause == null) { - continue; - } - CauseData queueItemCauseData = queueItemGiteeWebHookCause.getData(); - if (!projectId.equals(queueItemCauseData.getSourceProjectId())) { - continue; - } - if (branch.equals(queueItemCauseData.getBranch())) { - cancel(item, queue, branch); - } - } - } - - private GiteeWebHookCause getGiteeWebHookCauseData(Queue.Item item) { - for (Cause cause : item.getCauses()) { - if (cause instanceof GiteeWebHookCause) { - return (GiteeWebHookCause) cause; - } - } - return null; - } - - private void cancel(Queue.Item item, Queue queue, String branch) { - try { - LOGGER.log(Level.INFO, "Cancelling job {0} for branch {1}", LoggerUtil.toArray(item.task.getName(), branch)); - queue.cancel(item); - } catch (Exception e) { - LOGGER.log(Level.SEVERE, "Error cancelling queued build", e); - } - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/WebHookTriggerHandler.java b/src/main/java/com/gitee/jenkins/trigger/handler/WebHookTriggerHandler.java deleted file mode 100644 index c2f1944..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/WebHookTriggerHandler.java +++ /dev/null @@ -1,16 +0,0 @@ -package com.gitee.jenkins.trigger.handler; - -import com.gitee.jenkins.gitee.hook.model.WebHook; -import com.gitee.jenkins.trigger.filter.BranchFilter; -import com.gitee.jenkins.trigger.filter.BuildInstructionFilter; -import com.gitee.jenkins.trigger.filter.PullRequestLabelFilter; -import hudson.model.Job; - -/** - * @author Robin Müller - */ -public interface WebHookTriggerHandler { - - void handle(Job job, H hook, BuildInstructionFilter buildInstructionFilter, boolean skipLastCommitHasBeenBuild, BranchFilter branchFilter, PullRequestLabelFilter pullRequestLabelFilter); - -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/note/NopNoteHookTriggerHandler.java b/src/main/java/com/gitee/jenkins/trigger/handler/note/NopNoteHookTriggerHandler.java deleted file mode 100644 index 1c6ca01..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/note/NopNoteHookTriggerHandler.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gitee.jenkins.trigger.handler.note; - -import com.gitee.jenkins.gitee.hook.model.NoteHook; -import com.gitee.jenkins.trigger.filter.BranchFilter; -import com.gitee.jenkins.trigger.filter.BuildInstructionFilter; -import com.gitee.jenkins.trigger.filter.PullRequestLabelFilter; -import hudson.model.Job; - -/** - * @author Robin Müller - */ -class NopNoteHookTriggerHandler implements NoteHookTriggerHandler { - @Override - public void handle(Job job, NoteHook hook, BuildInstructionFilter buildInstructionFilter, boolean skipLastCommitHasBeenBuild, BranchFilter branchFilter, PullRequestLabelFilter pullRequestLabelFilter) { - // nothing to do - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/note/NoteHookTriggerHandler.java b/src/main/java/com/gitee/jenkins/trigger/handler/note/NoteHookTriggerHandler.java deleted file mode 100644 index c82c751..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/note/NoteHookTriggerHandler.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gitee.jenkins.trigger.handler.note; - -import com.gitee.jenkins.gitee.hook.model.NoteHook; -import com.gitee.jenkins.trigger.handler.WebHookTriggerHandler; - -/** - * @author Nikolay Ustinov - */ -public interface NoteHookTriggerHandler extends WebHookTriggerHandler { } diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/note/NoteHookTriggerHandlerFactory.java b/src/main/java/com/gitee/jenkins/trigger/handler/note/NoteHookTriggerHandlerFactory.java deleted file mode 100644 index 63b27f3..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/note/NoteHookTriggerHandlerFactory.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gitee.jenkins.trigger.handler.note; - -/** - * @author Nikolay Ustinov - */ -public final class NoteHookTriggerHandlerFactory { - - private NoteHookTriggerHandlerFactory() {} - - public static NoteHookTriggerHandler newNoteHookTriggerHandler(boolean triggerOnCommitComment, boolean triggerOnNoteRequest, String noteRegex, boolean ciSkipFroTestNotRequired, boolean cancelIncompleteBuildOnSamePullRequest, boolean ignorePullRequestConflicts) { - if (triggerOnCommitComment || triggerOnNoteRequest) { - return new NoteHookTriggerHandlerImpl(triggerOnCommitComment, triggerOnNoteRequest, noteRegex, ciSkipFroTestNotRequired, cancelIncompleteBuildOnSamePullRequest, ignorePullRequestConflicts); - } else { - return new NopNoteHookTriggerHandler(); - } - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/note/NoteHookTriggerHandlerImpl.java b/src/main/java/com/gitee/jenkins/trigger/handler/note/NoteHookTriggerHandlerImpl.java deleted file mode 100644 index 4eb48f7..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/note/NoteHookTriggerHandlerImpl.java +++ /dev/null @@ -1,283 +0,0 @@ -package com.gitee.jenkins.trigger.handler.note; - -import com.gitee.jenkins.cause.CauseData; -import com.gitee.jenkins.cause.GiteeWebHookCause; -import com.gitee.jenkins.gitee.api.GiteeClient; -import com.gitee.jenkins.gitee.api.model.PullRequest; -import com.gitee.jenkins.gitee.hook.model.*; -import com.gitee.jenkins.publisher.GiteeMessagePublisher; -import com.gitee.jenkins.trigger.exception.NoRevisionToBuildException; -import com.gitee.jenkins.trigger.filter.BranchFilter; -import com.gitee.jenkins.trigger.filter.BuildInstructionFilter; -import com.gitee.jenkins.trigger.filter.PullRequestLabelFilter; -import com.gitee.jenkins.trigger.handler.AbstractWebHookTriggerHandler; -import hudson.model.*; -import hudson.plugins.git.GitSCM; -import hudson.plugins.git.RevisionParameterAction; -import org.apache.commons.lang.StringUtils; -import org.eclipse.jgit.transport.URIish; - -import javax.servlet.ServletException; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.regex.Pattern; - -import static com.gitee.jenkins.cause.CauseDataBuilder.causeData; -import static com.gitee.jenkins.connection.GiteeConnectionProperty.getClient; -import static com.gitee.jenkins.trigger.handler.builder.generated.BuildStatusUpdateBuilder.buildStatusUpdate; - -/** - * @author Nikolay Ustinov - * @author Yashin Luo - */ -class NoteHookTriggerHandlerImpl extends AbstractWebHookTriggerHandler implements NoteHookTriggerHandler { - - private static final Logger LOGGER = Logger.getLogger(NoteHookTriggerHandlerImpl.class.getName()); - - private final boolean triggerOnCommitComment; - private final boolean triggerOnNoteRequest; - private final String noteRegex; - private final boolean ciSkipFroTestNotRequired; - private final boolean cancelIncompleteBuildOnSamePullRequest; - private boolean ignorePullRequestConflicts; - - NoteHookTriggerHandlerImpl(boolean triggerOnCommitComment, boolean triggerOnNoteRequest, String noteRegex, boolean ciSkipFroTestNotRequired, boolean cancelIncompleteBuildOnSamePullRequest, boolean ignorePullRequestConflicts) { - this.triggerOnCommitComment = triggerOnCommitComment; - this.triggerOnNoteRequest = triggerOnNoteRequest; - this.noteRegex = noteRegex; - this.ciSkipFroTestNotRequired = ciSkipFroTestNotRequired; - this.cancelIncompleteBuildOnSamePullRequest = cancelIncompleteBuildOnSamePullRequest; - this.ignorePullRequestConflicts = ignorePullRequestConflicts; - } - - @Override - public void handle(Job job, NoteHook hook, BuildInstructionFilter buildInstructionFilter, boolean skipLastCommitHasBeenBuild, BranchFilter branchFilter, PullRequestLabelFilter pullRequestLabelFilter) { - if (isValidTrigger(hook)) { - // 若pr不可自动合并则评论至pr - PullRequestObjectAttributes objectAttributes = hook.getPullRequest(); - if (!ignorePullRequestConflicts && objectAttributes != null && !objectAttributes.isMergeable()) { - LOGGER.log(Level.INFO, "This pull request can not be merge"); - // fixme 无法获取 publisher - // java.lang.ClassCastException: org.jenkinsci.plugins.workflow.job.WorkflowJob cannot be cast to hudson.model.AbstractProject - // at com.gitee.jenkins.publisher.GiteeMessagePublisher.getFromJob(GiteeMessagePublisher.java:65) - // at com.gitee.jenkins.trigger.handler.note.NoteHookTriggerHandlerImpl.handle(NoteHookTriggerHandlerImpl.java:47) - GiteeMessagePublisher publisher = GiteeMessagePublisher.getFromJob(job); - GiteeClient client = getClient(job); - if (publisher != null && client != null) { - PullRequest pullRequest = new PullRequest(objectAttributes); - LOGGER.log(Level.INFO, "sending message to gitee....."); - client.createPullRequestNote(pullRequest, ":bangbang: This pull request can not be merge! The build will not be triggered. Please manual merge conflict."); - } - return; - } - - // 若PR不需要测试,且有设定值,则跳过构建 - if (objectAttributes != null && ciSkipFroTestNotRequired && !objectAttributes.getNeedTest()) { - LOGGER.log(Level.INFO, "Skip because this pull don't need test."); - return; - } - - - super.handle(job, hook, buildInstructionFilter, skipLastCommitHasBeenBuild, branchFilter, pullRequestLabelFilter); - } - } - - @Override - protected boolean isCiSkip(NoteHook hook, BuildInstructionFilter buildInstructionFilter) { - if (buildInstructionFilter != null && hook.getPullRequest() != null) { - return !buildInstructionFilter.isBuildAllow(hook.getPullRequest().getBody()); - } - return false; - } - - @Override - protected boolean isCommitSkip(Job project, NoteHook hook) { - return false; - } - - @Override - protected void cancelIncompleteBuildIfNecessary(Job job, NoteHook hook) { - if (!cancelIncompleteBuildOnSamePullRequest || hook.getPullRequest() == null) { - return; - } - - for (Run build : job.getBuilds()) { - if (!job.isBuilding()) { - break; - } - - if (!build.isBuilding()) { - continue; - } - - CauseAction causeAction = build.getAction(CauseAction.class); - GiteeWebHookCause giteeWebHookCause = null; - for (Cause cause : causeAction.getCauses()) { - if (cause instanceof GiteeWebHookCause) { - giteeWebHookCause = (GiteeWebHookCause) cause; - break; - } - } - - if (giteeWebHookCause == null) { - continue; - } - CauseData causeData = giteeWebHookCause.getData(); - if (causeData.getSourceRepoHttpUrl().equals(hook.getPullRequest().getSource().getGitHttpUrl()) - && causeData.getTargetRepoHttpUrl().equals(hook.getPullRequest().getTarget().getGitHttpUrl()) - && causeData.getRef().equals(hook.getPullRequest().getMergeReferenceName())) { - try { - doStop(build); - } catch (ServletException | IOException e) { - LOGGER.log(Level.WARNING, "Unable to abort incomplete build", e); - } - } - } - } - - @Override - protected String getTargetBranch(NoteHook hook) { - return hook.getPullRequest() == null ? null : hook.getPullRequest().getTargetBranch(); - } - - @Override - protected String getTriggerType() { - return "note"; - } - - @Override - protected CauseData retrieveCauseData(NoteHook hook) { - // 兼容来自commit的评论 - if (hook.getPullRequest() == null) { - return causeData() - .withActionType(CauseData.ActionType.COMMIT_COMMENT) - .withUserName(hook.getComment().getUser().getUsername()) - .withUserEmail(hook.getComment().getUser().getEmail()) - .withPullRequestTitle("") - .withBranch("") - .withSourceBranch("") - .withSourceProjectId(hook.getProject().getId()) - .withSourceRepoHomepage(hook.getProject().getHomepage()) - .withSourceRepoName(hook.getProject().getName()) - .withSourceNamespace(hook.getProject().getNamespace()) - .withSourceRepoUrl(hook.getProject().getUrl()) - .withSourceRepoSshUrl(hook.getProject().getSshUrl()) - .withSourceRepoHttpUrl(hook.getProject().getGitHttpUrl()) - .withTargetBranch("") - .withTargetProjectId(hook.getProject().getId()) - .withTargetRepoName(hook.getProject().getName()) - .withTargetNamespace(hook.getProject().getNamespace()) - .withTargetRepoSshUrl(hook.getProject().getSshUrl()) - .withTargetRepoHttpUrl(hook.getProject().getGitHttpUrl()) - .withTriggeredByUser(hook.getComment().getUser().getName()) - .withTriggerPhrase(hook.getComment().getBody()) - .withSha(hook.getComment().getCommitId()) - .withPathWithNamespace(hook.getProject().getPathWithNamespace()) - .build(); - } - - return causeData() - .withActionType(CauseData.ActionType.NOTE) - .withSourceProjectId(hook.getPullRequest().getSourceProjectId()) - .withTargetProjectId(hook.getPullRequest().getTargetProjectId()) - .withBranch(hook.getPullRequest().getSourceBranch()) - .withSourceBranch(hook.getPullRequest().getSourceBranch()) - .withUserName(hook.getPullRequest().getHead().getUser().getName()) - .withUserEmail(hook.getPullRequest().getHead().getUser().getEmail()) - .withSourceRepoHomepage(hook.getPullRequest().getSource().getHomepage()) - .withSourceRepoName(hook.getPullRequest().getSource().getName()) - .withSourceNamespace(hook.getPullRequest().getSource().getNamespace()) - .withSourceRepoUrl(hook.getPullRequest().getSource().getUrl()) - .withSourceRepoSshUrl(hook.getPullRequest().getSource().getSshUrl()) - .withSourceRepoHttpUrl(hook.getPullRequest().getSource().getGitHttpUrl()) - .withPullRequestTitle(hook.getPullRequest().getTitle()) - .withPullRequestDescription(hook.getPullRequest().getBody()) - .withPullRequestId(hook.getPullRequest().getId()) - .withPullRequestIid(hook.getPullRequest().getNumber()) - .withPullRequestTargetProjectId(hook.getPullRequest().getTargetProjectId()) - .withTargetBranch(hook.getPullRequest().getTargetBranch()) - .withTargetRepoName(hook.getPullRequest().getTarget().getName()) - .withTargetNamespace(hook.getPullRequest().getTarget().getNamespace()) - .withTargetRepoSshUrl(hook.getPullRequest().getTarget().getSshUrl()) - .withTargetRepoHttpUrl(hook.getPullRequest().getTarget().getGitHttpUrl()) - .withTriggeredByUser(hook.getPullRequest().getHead().getUser().getName()) - .withLastCommit(hook.getPullRequest().getMergeCommitSha()) - .withSha(hook.getPullRequest().getMergeCommitSha()) - .withAfter(hook.getPullRequest().getMergeCommitSha()) - .withRef(hook.getPullRequest().getMergeReferenceName()) - .withTargetProjectUrl(hook.getPullRequest().getTarget().getUrl()) - .withTriggerPhrase(hook.getComment().getBody()) - .withPathWithNamespace(hook.getPullRequest().getBase().getRepo().getPathWithNamespace()) - .withJsonBody(hook.getJsonBody()) - .withNoteBody(hook.getComment().getBody()) - .build(); - } - - @Override - protected RevisionParameterAction createRevisionParameter(NoteHook hook, GitSCM gitSCM) throws NoRevisionToBuildException { - // 没有配置git源码管理 - if (gitSCM == null) { - return new RevisionParameterAction(retrieveRevisionToBuild(hook)); - } - URIish urIish = retrieveUrIish(hook, gitSCM); - // webhook与git源码管理仓库对不上 - if (urIish == null) { - return new RevisionParameterAction(retrieveRevisionToBuild2(hook)); - } - return new RevisionParameterAction(retrieveRevisionToBuild(hook), urIish); - } - - @Override - protected BuildStatusUpdate retrieveBuildStatusUpdate(NoteHook hook) { - return buildStatusUpdate() - .withProjectId(hook.getPullRequest().getSourceProjectId()) - .withSha(hook.getPullRequest().getMergeCommitSha()) - .withRef(hook.getPullRequest().getTargetBranch()) - .build(); - } - - private String retrieveRevisionToBuild(NoteHook hook) throws NoRevisionToBuildException { - if (hook.getPullRequest() != null) { - if (hook.getPullRequest().getMergeCommitSha() != null) { - return hook.getPullRequest().getMergeCommitSha(); - } - } - - return retrieveRevisionToBuild2(hook); - } - - private String retrieveRevisionToBuild2(NoteHook hook) throws NoRevisionToBuildException { - if (hook.getPullRequest() != null) { - if (hook.getPullRequest().getMergeReferenceName() != null) { - return hook.getPullRequest().getMergeReferenceName(); - } - } - - // 兼容来自commit的评论 - if (hook.getComment() != null - && StringUtils.isNotBlank(hook.getComment().getCommitId())) { - return hook.getComment().getCommitId(); - } - - throw new NoRevisionToBuildException(); - } - - private boolean isValidTrigger(NoteHook hook) { - // commit评论pullRequest为null - return ((triggerOnCommitComment && hook.getPullRequest() == null) || (triggerOnNoteRequest && hook.getPullRequest() != null)) - && (isValidTriggerPhrase(hook.getComment().getBody()) && isValidTriggerAction(hook.getAction())); - } - - private boolean isValidTriggerAction(NoteAction action) { - return action == NoteAction.comment; - } - - private boolean isValidTriggerPhrase(String note) { - if (StringUtils.isEmpty(this.noteRegex)) { - return false; - } - final Pattern pattern = Pattern.compile(this.noteRegex); - return pattern.matcher(note).matches(); - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/pipeline/NopPipelineHookTriggerHandler.java b/src/main/java/com/gitee/jenkins/trigger/handler/pipeline/NopPipelineHookTriggerHandler.java deleted file mode 100644 index 77eb3ba..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/pipeline/NopPipelineHookTriggerHandler.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.gitee.jenkins.trigger.handler.pipeline; - -import com.gitee.jenkins.gitee.hook.model.PipelineHook; -import com.gitee.jenkins.trigger.filter.BranchFilter; -import com.gitee.jenkins.trigger.filter.BuildInstructionFilter; -import com.gitee.jenkins.trigger.filter.PullRequestLabelFilter; -import hudson.model.Job; - -/** - * @author Milena Zachow - */ -class NopPipelineHookTriggerHandler implements PipelineHookTriggerHandler { - - @Override - public void handle(Job job, PipelineHook hook, BuildInstructionFilter buildInstructionFilter, boolean skipLastCommitHasBeenBuild, BranchFilter branchFilter, PullRequestLabelFilter pullRequestLabelFilter) { - - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/pipeline/PipelineHookTriggerHandler.java b/src/main/java/com/gitee/jenkins/trigger/handler/pipeline/PipelineHookTriggerHandler.java deleted file mode 100644 index 7220145..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/pipeline/PipelineHookTriggerHandler.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gitee.jenkins.trigger.handler.pipeline; - -import com.gitee.jenkins.gitee.hook.model.PipelineHook; -import com.gitee.jenkins.trigger.handler.WebHookTriggerHandler; - -/** - * @author Milena Zachow - */ -public interface PipelineHookTriggerHandler extends WebHookTriggerHandler { } diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/pipeline/PipelineHookTriggerHandlerFactory.java b/src/main/java/com/gitee/jenkins/trigger/handler/pipeline/PipelineHookTriggerHandlerFactory.java deleted file mode 100644 index e95b952..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/pipeline/PipelineHookTriggerHandlerFactory.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.gitee.jenkins.trigger.handler.pipeline; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Milena Zachow - */ -public final class PipelineHookTriggerHandlerFactory { - - public static final String SUCCESS = "success"; - - private PipelineHookTriggerHandlerFactory() { - } - - public static PipelineHookTriggerHandler newPipelineHookTriggerHandler(boolean triggerOnPipelineEvent) { - if (triggerOnPipelineEvent) { - return new PipelineHookTriggerHandlerImpl(retrieve(triggerOnPipelineEvent)); - } else { - return new NopPipelineHookTriggerHandler(); - } - } - - - private static List retrieve(boolean triggerOnPipelineEvent) { - List result = new ArrayList<>(); - if (triggerOnPipelineEvent) { - result.add(SUCCESS); - } - return result; - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/pipeline/PipelineHookTriggerHandlerImpl.java b/src/main/java/com/gitee/jenkins/trigger/handler/pipeline/PipelineHookTriggerHandlerImpl.java deleted file mode 100644 index 247307e..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/pipeline/PipelineHookTriggerHandlerImpl.java +++ /dev/null @@ -1,168 +0,0 @@ -package com.gitee.jenkins.trigger.handler.pipeline; - - -import com.gitee.jenkins.cause.CauseData; -import com.gitee.jenkins.connection.GiteeConnectionProperty; -import com.gitee.jenkins.gitee.api.GiteeClient; -import com.gitee.jenkins.gitee.hook.model.PipelineEventObjectAttributes; -import com.gitee.jenkins.gitee.hook.model.PipelineHook; -import com.gitee.jenkins.trigger.exception.NoRevisionToBuildException; -import com.gitee.jenkins.trigger.filter.BranchFilter; -import com.gitee.jenkins.trigger.filter.BuildInstructionFilter; -import com.gitee.jenkins.trigger.filter.PullRequestLabelFilter; -import com.gitee.jenkins.trigger.handler.AbstractWebHookTriggerHandler; -import com.gitee.jenkins.util.BuildUtil; -import com.gitee.jenkins.util.LoggerUtil; -import hudson.model.AbstractProject; -import hudson.model.Job; -import hudson.model.Run; -import hudson.plugins.git.GitSCM; -import hudson.plugins.git.RevisionParameterAction; - -import javax.ws.rs.WebApplicationException; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -import static com.gitee.jenkins.cause.CauseDataBuilder.causeData; -import static com.gitee.jenkins.trigger.handler.builder.generated.BuildStatusUpdateBuilder.buildStatusUpdate; - -/** - * @author Milena Zachow - * @author Yashin Luo - * - */ - -// fixme ???? -class PipelineHookTriggerHandlerImpl extends AbstractWebHookTriggerHandler implements PipelineHookTriggerHandler { - - private static final Logger LOGGER = Logger.getLogger(PipelineHookTriggerHandlerImpl.class.getName()); - - private final List allowedStates; - - PipelineHookTriggerHandlerImpl(List allowedStates) { - this.allowedStates = allowedStates; - } - - @Override - public void handle(Job job, PipelineHook hook, BuildInstructionFilter buildInstructionFilter, boolean skipLastCommitHasBeenBuild, BranchFilter branchFilter, PullRequestLabelFilter pullRequestLabelFilter) { - PipelineEventObjectAttributes objectAttributes = hook.getObjectAttributes(); - try { - if (job instanceof AbstractProject) { - GiteeConnectionProperty property = job.getProperty(GiteeConnectionProperty.class); - - if (property != null && property.getClient() != null) { - GiteeClient client = property.getClient(); - } - } - } catch (WebApplicationException e) { - LOGGER.log(Level.WARNING, "Failed to communicate with gitee server to determine project id: " + e.getMessage(), e); - } - if (allowedStates.contains(objectAttributes.getStatus()) && !isLastAlreadyBuild(job,hook)) { - if (isCiSkip(hook, buildInstructionFilter)) { - LOGGER.log(Level.INFO, "Skipping due to ci-skip."); - return; - } - //we do not call super here, since we do not want the status to be changed - //in case of pipeline events that could lead to a deadlock - String targetBranch = getTargetBranch(hook); - if (branchFilter.isBranchAllowed(targetBranch)) { - LOGGER.log(Level.INFO, "{0} triggered for {1}.", LoggerUtil.toArray(job.getFullName(), getTriggerType())); - - super.scheduleBuild(job, createActions(job, hook)); - } else { - LOGGER.log(Level.INFO, "branch {0} is not allowed", targetBranch); - } - - } - } - - @Override - protected boolean isCiSkip(PipelineHook hook, BuildInstructionFilter buildInstructionFilter) { - //we don't get a commit message or suchlike that could contain ci-skip - return false; - } - - @Override - protected boolean isCommitSkip(Job project, PipelineHook hook) { - return false; - } - - @Override - protected String getTargetBranch(PipelineHook hook) { - return hook.getObjectAttributes().getRef() == null ? null : hook.getObjectAttributes().getRef().replaceFirst("^refs/heads/", ""); - } - - @Override - protected String getTriggerType() { - return "pipeline event"; - } - - @Override - protected CauseData retrieveCauseData(PipelineHook hook) { - return causeData() - .withActionType(CauseData.ActionType.PIPELINE) - .withSourceProjectId(hook.getProjectId()) - .withBranch(getTargetBranch(hook)==null?"":getTargetBranch(hook)) - .withSourceBranch(getTargetBranch(hook)==null?"":getTargetBranch(hook)) - .withUserName(hook.getUser()==null||hook.getUser().getName()==null?"":hook.getUser().getName()) - .withSourceRepoName(hook.getRepository()==null||hook.getRepository().getName()==null?"":hook.getRepository().getName()) - .withSourceNamespace(hook.getProject()==null||hook.getProject().getNamespace()==null?"":hook.getProject().getNamespace()) - .withSourceRepoSshUrl(hook.getRepository()==null||hook.getRepository().getGitSshUrl()==null?"":hook.getRepository().getGitSshUrl()) - .withSourceRepoHttpUrl(hook.getRepository()==null||hook.getRepository()==null?"":hook.getRepository().getGitHttpUrl()) - .withPullRequestTitle("") - .withTargetProjectId(hook.getProjectId()) - .withTargetBranch(getTargetBranch(hook)==null?"":getTargetBranch(hook)) - .withTargetRepoName("") - .withTargetNamespace("") - .withTargetRepoSshUrl("") - .withTargetRepoHttpUrl("") - .withLastCommit(hook.getObjectAttributes().getSha()) - .withTriggeredByUser(hook.getUser()==null||hook.getUser().getName()==null?"":hook.getUser().getName()) - .withRef(hook.getObjectAttributes().getRef()==null?"":hook.getObjectAttributes().getRef()) - .withSha(hook.getObjectAttributes().getSha()==null?"":hook.getObjectAttributes().getSha()) - .withBeforeSha(hook.getObjectAttributes().getBeforeSha()==null?"":hook.getObjectAttributes().getBeforeSha()) - .withStatus(hook.getObjectAttributes().getStatus()==null?"":hook.getObjectAttributes().getStatus().toString()) - .withStages(hook.getObjectAttributes().getStages()==null?"":hook.getObjectAttributes().getStages().toString()) - .withCreatedAt(hook.getObjectAttributes().getCreatedAt()==null?"":hook.getObjectAttributes().getCreatedAt().toString()) - .withFinishedAt(hook.getObjectAttributes().getFinishedAt()==null?"":hook.getObjectAttributes().getFinishedAt().toString()) - .withBuildDuration(String.valueOf(hook.getObjectAttributes().getDuration())) - .withJsonBody(hook.getJsonBody()) - .build(); - } - - @Override - protected RevisionParameterAction createRevisionParameter(PipelineHook hook, GitSCM gitSCM) throws NoRevisionToBuildException { - return new RevisionParameterAction(retrieveRevisionToBuild(hook), retrieveUrIish(hook, gitSCM)); - } - - @Override - protected BuildStatusUpdate retrieveBuildStatusUpdate(PipelineHook hook) { - return buildStatusUpdate() - .withProjectId(hook.getProjectId()) - .withSha(hook.getObjectAttributes().getSha()) - .withRef(hook.getObjectAttributes().getRef()) - .build(); - } - - private String retrieveRevisionToBuild(PipelineHook hook) throws NoRevisionToBuildException { - if (hook.getObjectAttributes() != null - && hook.getObjectAttributes().getSha() != null) { - return hook.getObjectAttributes().getSha(); - } else { - throw new NoRevisionToBuildException(); - } - } - - private boolean isLastAlreadyBuild(Job project, PipelineHook hook) { - PipelineEventObjectAttributes objectAttributes = hook.getObjectAttributes(); - if (objectAttributes != null && objectAttributes.getSha() != null) { - Run lastBuild = BuildUtil.getBuildBySHA1IncludingMergeBuilds(project, objectAttributes.getSha()); - if (lastBuild != null) { - LOGGER.log(Level.INFO, "Last commit has already been built in build #" + lastBuild.getNumber()); - return true; - } - } - return false; - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/pull/NopPullRequestHookTriggerHandler.java b/src/main/java/com/gitee/jenkins/trigger/handler/pull/NopPullRequestHookTriggerHandler.java deleted file mode 100644 index a430087..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/pull/NopPullRequestHookTriggerHandler.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gitee.jenkins.trigger.handler.pull; - -import com.gitee.jenkins.gitee.hook.model.PullRequestHook; -import com.gitee.jenkins.trigger.filter.BranchFilter; -import com.gitee.jenkins.trigger.filter.BuildInstructionFilter; -import com.gitee.jenkins.trigger.filter.PullRequestLabelFilter; -import hudson.model.Job; - -/** - * @author Robin Müller - */ -class NopPullRequestHookTriggerHandler implements PullRequestHookTriggerHandler { - @Override - public void handle(Job job, PullRequestHook hook, BuildInstructionFilter buildInstructionFilter, boolean skipLastCommitHasBeenBuild, BranchFilter branchFilter, PullRequestLabelFilter pullRequestLabelFilter) { - // nothing to do - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/pull/PullRequestHookTriggerHandler.java b/src/main/java/com/gitee/jenkins/trigger/handler/pull/PullRequestHookTriggerHandler.java deleted file mode 100644 index 72178ba..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/pull/PullRequestHookTriggerHandler.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gitee.jenkins.trigger.handler.pull; - -import com.gitee.jenkins.gitee.hook.model.PullRequestHook; -import com.gitee.jenkins.trigger.handler.WebHookTriggerHandler; - -/** - * @author Robin Müller - */ -public interface PullRequestHookTriggerHandler extends WebHookTriggerHandler { } diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/pull/PullRequestHookTriggerHandlerFactory.java b/src/main/java/com/gitee/jenkins/trigger/handler/pull/PullRequestHookTriggerHandlerFactory.java deleted file mode 100644 index fd76b25..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/pull/PullRequestHookTriggerHandlerFactory.java +++ /dev/null @@ -1,145 +0,0 @@ -package com.gitee.jenkins.trigger.handler.pull; - -import com.gitee.jenkins.gitee.hook.model.Action; -import com.gitee.jenkins.gitee.hook.model.ActionDesc; -import com.gitee.jenkins.gitee.hook.model.State; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Robin Müller - */ -public final class PullRequestHookTriggerHandlerFactory { - - private PullRequestHookTriggerHandlerFactory() {} - - public static PullRequestHookTriggerHandler newPullRequestHookTriggerHandler(boolean triggerOnOpenPullRequest, - String triggerOnUpdatePullRequest, - boolean triggerOnAcceptedPullRequest, - boolean triggerOnClosedPullRequest, - boolean skipWorkInProgressPullRequest, - boolean triggerOnApprovedPullRequest, - boolean triggerOnTestedPullRequest, - boolean cancelPendingBuildsOnUpdate, - boolean ciSkipFroTestNotRequired, - boolean cancelIncompleteBuildOnSamePullRequest, - boolean ignorePullRequestConflicts) { - if (triggerOnOpenPullRequest - || !("0".equals(triggerOnUpdatePullRequest) || "false".equals(triggerOnUpdatePullRequest)) - || triggerOnAcceptedPullRequest - || triggerOnClosedPullRequest - || triggerOnApprovedPullRequest - || triggerOnTestedPullRequest) { - - return new PullRequestHookTriggerHandlerImpl( - retrieveAllowedStates(triggerOnOpenPullRequest, - triggerOnUpdatePullRequest, - triggerOnAcceptedPullRequest, - triggerOnClosedPullRequest, - triggerOnApprovedPullRequest, - triggerOnTestedPullRequest), - retrieveAllowedActions(triggerOnOpenPullRequest, - triggerOnUpdatePullRequest, - triggerOnAcceptedPullRequest, - triggerOnClosedPullRequest, - triggerOnApprovedPullRequest, - triggerOnTestedPullRequest), - retrieveAllowedActionDesces(triggerOnUpdatePullRequest), - skipWorkInProgressPullRequest, - cancelPendingBuildsOnUpdate, - ciSkipFroTestNotRequired, - cancelIncompleteBuildOnSamePullRequest, - ignorePullRequestConflicts); - } else { - return new NopPullRequestHookTriggerHandler(); - } - } - - - private static List retrieveAllowedActionDesces(String triggerOnUpdatePullRequest) { - List allowedActionDesces =new ArrayList<>(); - - switch(triggerOnUpdatePullRequest){ - case "1": - allowedActionDesces.add(ActionDesc.source_branch_changed); - break; - case "2": - allowedActionDesces.add(ActionDesc.target_branch_changed); - break; - case "3": - allowedActionDesces.add(ActionDesc.source_branch_changed); - allowedActionDesces.add(ActionDesc.target_branch_changed); - break; - case "true": - allowedActionDesces.add(ActionDesc.source_branch_changed); - allowedActionDesces.add(ActionDesc.target_branch_changed); - break; - } - return allowedActionDesces; - } - - - private static List retrieveAllowedActions(boolean triggerOnOpenPullRequest, - String triggerOnUpdatePullRequest, - boolean triggerOnAcceptedPullRequest, - boolean triggerOnClosedPullRequest, - boolean triggerOnApprovedPullRequest, - boolean triggerOnTestedPullRequest) { - List allowedActions =new ArrayList<>(); - - if (triggerOnOpenPullRequest) { - allowedActions.add(Action.open); - } - - if (!("0".equals(triggerOnUpdatePullRequest) || "false".equals(triggerOnUpdatePullRequest))) { - allowedActions.add(Action.update); - } - - if (triggerOnAcceptedPullRequest) { - allowedActions.add(Action.merge); - } - - if (triggerOnClosedPullRequest) { - allowedActions.add(Action.close); - } - - if (triggerOnApprovedPullRequest) { - allowedActions.add(Action.approved); - } - - if (triggerOnTestedPullRequest) { - allowedActions.add(Action.tested); - } - - return allowedActions; - } - - private static List retrieveAllowedStates(boolean triggerOnOpenPullRequest, - String triggerOnUpdatePullRequest, - boolean triggerOnAcceptedPullRequest, - boolean triggerOnClosedPullRequest, - boolean triggerOnApprovedPullRequest, - boolean triggerOnTestedPullRequest) { - List result = new ArrayList<>(); - if (triggerOnOpenPullRequest - || !("0".equals(triggerOnUpdatePullRequest) || "false".equals(triggerOnUpdatePullRequest)) - || triggerOnApprovedPullRequest - || triggerOnTestedPullRequest) { - - result.add(State.opened); - result.add(State.open); - result.add(State.reopened); - result.add(State.updated); - } - - if (triggerOnAcceptedPullRequest) { - result.add(State.merged); - } - if (triggerOnClosedPullRequest) { - result.add(State.closed); - } - - return result; - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/pull/PullRequestHookTriggerHandlerImpl.java b/src/main/java/com/gitee/jenkins/trigger/handler/pull/PullRequestHookTriggerHandlerImpl.java deleted file mode 100644 index 0b0a193..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/pull/PullRequestHookTriggerHandlerImpl.java +++ /dev/null @@ -1,303 +0,0 @@ -package com.gitee.jenkins.trigger.handler.pull; - -import com.gitee.jenkins.cause.CauseData; -import com.gitee.jenkins.cause.GiteeWebHookCause; -import com.gitee.jenkins.gitee.api.GiteeClient; -import com.gitee.jenkins.gitee.api.model.PullRequest; -import com.gitee.jenkins.gitee.hook.model.*; -import com.gitee.jenkins.gitee.hook.model.Action; -import com.gitee.jenkins.gitee.hook.model.PullRequestHook; -import com.gitee.jenkins.publisher.GiteeMessagePublisher; -import com.gitee.jenkins.trigger.exception.NoRevisionToBuildException; -import com.gitee.jenkins.trigger.filter.BranchFilter; -import com.gitee.jenkins.trigger.filter.BuildInstructionFilter; -import com.gitee.jenkins.trigger.filter.PullRequestLabelFilter; -import com.gitee.jenkins.trigger.handler.AbstractWebHookTriggerHandler; -import com.gitee.jenkins.util.BuildUtil; -import hudson.model.*; -import hudson.plugins.git.GitSCM; -import hudson.plugins.git.RevisionParameterAction; -import org.apache.commons.lang.StringUtils; -import org.eclipse.jgit.transport.URIish; - -import javax.servlet.ServletException; -import java.io.IOException; -import java.util.Collection; -import java.util.ArrayList; -import java.util.List; -import java.util.EnumSet; -import java.util.logging.Level; -import java.util.logging.Logger; - -import static com.gitee.jenkins.cause.CauseDataBuilder.causeData; -import static com.gitee.jenkins.trigger.handler.builder.generated.BuildStatusUpdateBuilder.buildStatusUpdate; -import static com.gitee.jenkins.connection.GiteeConnectionProperty.getClient; - -/** - * @author Robin Müller - * @author Yashin Luo - */ -class PullRequestHookTriggerHandlerImpl extends AbstractWebHookTriggerHandler implements PullRequestHookTriggerHandler { - - private static final Logger LOGGER = Logger.getLogger(PullRequestHookTriggerHandlerImpl.class.getName()); - - private final Collection allowedStates; - private final boolean skipWorkInProgressPullRequest; - private final boolean ciSkipFroTestNotRequired; - private final Collection allowedActions; - private final Collection allowedActionDesces; - private final boolean cancelPendingBuildsOnUpdate; - private final boolean cancelIncompleteBuildOnSamePullRequest; - private boolean ignorePullRequestConflicts; - - PullRequestHookTriggerHandlerImpl(Collection allowedStates, boolean skipWorkInProgressPullRequest, boolean cancelPendingBuildsOnUpdate, boolean ciSkipFroTestNotRequired, boolean cancelIncompleteBuildOnSamePullRequest, boolean ignorePullRequestConflicts) { - this(allowedStates, EnumSet.allOf(Action.class), EnumSet.allOf(ActionDesc.class), skipWorkInProgressPullRequest, cancelPendingBuildsOnUpdate, ciSkipFroTestNotRequired, cancelIncompleteBuildOnSamePullRequest, ignorePullRequestConflicts); - } - - PullRequestHookTriggerHandlerImpl(Collection allowedStates, Collection allowedActions, Collection allowedActionDesces, boolean skipWorkInProgressPullRequest, boolean cancelPendingBuildsOnUpdate, boolean ciSkipFroTestNotRequired, boolean cancelIncompleteBuildOnSamePullRequest, boolean ignorePullRequestConflicts) { - this.allowedStates = allowedStates; - this.allowedActions = allowedActions; - this.allowedActionDesces = allowedActionDesces; - this.skipWorkInProgressPullRequest = skipWorkInProgressPullRequest; - this.cancelPendingBuildsOnUpdate = cancelPendingBuildsOnUpdate; - this.ciSkipFroTestNotRequired = ciSkipFroTestNotRequired; - this.cancelIncompleteBuildOnSamePullRequest = cancelIncompleteBuildOnSamePullRequest; - this.ignorePullRequestConflicts = ignorePullRequestConflicts; - } - - @Override - public void handle(Job job, PullRequestHook hook, BuildInstructionFilter buildInstructionFilter, boolean skipLastCommitHasBeenBuild, BranchFilter branchFilter, PullRequestLabelFilter pullRequestLabelFilter) { - PullRequestObjectAttributes objectAttributes = hook.getPullRequest(); - - try { - LOGGER.log(Level.INFO, "request hook state=" + hook.getState() + ", action = " + hook.getAction() + " pr iid = " + objectAttributes.getNumber() + " hook name = " + hook.getHookName()); - if (isAllowedByConfig(hook) - && isNotSkipWorkInProgressPullRequest(objectAttributes)) { - List labelsNames = new ArrayList<>(); - if (hook.getLabels() != null) { - for (PullRequestLabel label : hook.getLabels()) { - labelsNames.add(label.getTitle()); - } - } - - // 若pr不可自动合并则评论至pr - if (!ignorePullRequestConflicts && !objectAttributes.isMergeable()) { - LOGGER.log(Level.INFO, "This pull request can not be merge"); - GiteeMessagePublisher publisher = GiteeMessagePublisher.getFromJob(job); - GiteeClient client = getClient(job); - - if (publisher != null && client != null) { - PullRequest pullRequest = new PullRequest(objectAttributes); - LOGGER.log(Level.INFO, "sending message to gitee....."); - client.createPullRequestNote(pullRequest, ":bangbang: This pull request can not be merge! The build will not be triggered. Please manual merge conflict."); - } - return; - } - - // 若PR不需要测试,且有设定值,则跳过构建 - if ( ciSkipFroTestNotRequired && !objectAttributes.getNeedTest()) { - LOGGER.log(Level.INFO, "Skip because this pull don't need test."); - return; - } - - if (pullRequestLabelFilter.isPullRequestAllowed(labelsNames)) { - super.handle(job, hook, buildInstructionFilter, skipLastCommitHasBeenBuild, branchFilter, pullRequestLabelFilter); - } - } - else { - LOGGER.log(Level.INFO, "request is not allow, hook state=" + hook.getState() + ", action = " + hook.getAction() + ", action desc = " + hook.getActionDesc()); - } - } catch (Exception e) { - LOGGER.log(Level.INFO, "request is not allow, hook ----- #" + hook.toString()); - throw e; - } - - } - - @Override - protected boolean isCiSkip(PullRequestHook hook, BuildInstructionFilter buildInstructionFilter) { - if (buildInstructionFilter != null && hook.getPullRequest() != null) { - return !buildInstructionFilter.isBuildAllow(hook.getPullRequest().getBody()); - } - return false; - } - - @Override - protected boolean isCommitSkip(Job project, PullRequestHook hook) { - PullRequestObjectAttributes objectAttributes = hook.getPullRequest(); - - if (objectAttributes != null && objectAttributes.getMergeCommitSha() != null) { - Run mergeBuild = BuildUtil.getBuildBySHA1IncludingMergeBuilds(project, objectAttributes.getMergeCommitSha()); - if (mergeBuild != null && StringUtils.equals(getTargetBranchFromBuild(mergeBuild), objectAttributes.getTargetBranch())) { - LOGGER.log(Level.INFO, "Last commit in Pull Request has already been built in build #" + mergeBuild.getNumber()); - return true; - } - } - return false; - } - - @Override - protected void cancelPendingBuildsIfNecessary(Job job, PullRequestHook hook) { - if (!this.cancelPendingBuildsOnUpdate) { - return; - } - if (!hook.getAction().equals(Action.update)) { - return; - } - this.pendingBuildsHandler.cancelPendingBuilds(job, hook.getPullRequest().getSourceProjectId(), hook.getPullRequest().getSourceBranch()); - } - - @Override - protected void cancelIncompleteBuildIfNecessary(Job job, PullRequestHook hook) { - if (!cancelIncompleteBuildOnSamePullRequest) { - return; - } - - for (Run build : job.getBuilds()) { - if (!job.isBuilding()) { - break; - } - - if (!build.isBuilding()) { - continue; - } - - CauseAction causeAction = build.getAction(CauseAction.class); - GiteeWebHookCause giteeWebHookCause = null; - for (Cause cause : causeAction.getCauses()) { - if (cause instanceof GiteeWebHookCause) { - giteeWebHookCause = (GiteeWebHookCause) cause; - break; - } - } - - if (giteeWebHookCause == null) { - continue; - } - CauseData causeData = giteeWebHookCause.getData(); - if (causeData.getSourceRepoHttpUrl().equals(hook.getPullRequest().getSource().getGitHttpUrl()) - && causeData.getTargetRepoHttpUrl().equals(hook.getPullRequest().getTarget().getGitHttpUrl()) - && causeData.getRef().equals(hook.getPullRequest().getMergeReferenceName())) { - try { - doStop(build); - } catch (ServletException | IOException e) { - LOGGER.log(Level.WARNING, "Unable to abort incomplete build", e); - } - } - - } - - } - - @Override - protected String getTargetBranch(PullRequestHook hook) { - return hook.getPullRequest() == null ? null : hook.getPullRequest().getTargetBranch(); - } - - @Override - protected String getTriggerType() { - return "pull request"; - } - - @Override - protected CauseData retrieveCauseData(PullRequestHook hook) { - return causeData() - .withActionType(CauseData.ActionType.MERGE) - .withSourceProjectId(hook.getPullRequest().getSourceProjectId()) - .withTargetProjectId(hook.getPullRequest().getTargetProjectId()) - .withBranch(hook.getPullRequest().getSourceBranch()) - .withSourceBranch(hook.getPullRequest().getSourceBranch()) - .withUserName(hook.getPullRequest().getHead().getUser().getName()) - .withUserEmail(hook.getPullRequest().getHead().getUser().getEmail()) - .withSourceRepoHomepage(hook.getPullRequest().getSource().getHomepage()) - .withSourceRepoName(hook.getPullRequest().getSource().getName()) - .withSourceNamespace(hook.getPullRequest().getSource().getNamespace()) - .withSourceRepoUrl(hook.getPullRequest().getSource().getUrl()) - .withSourceRepoSshUrl(hook.getPullRequest().getSource().getSshUrl()) - .withSourceRepoHttpUrl(hook.getPullRequest().getSource().getGitHttpUrl()) - .withPullRequestTitle(hook.getPullRequest().getTitle()) - .withPullRequestDescription(hook.getPullRequest().getBody()) - .withPullRequestId(hook.getPullRequest().getId()) - .withPullRequestIid(hook.getPullRequest().getNumber()) - .withPullRequestState(hook.getState().toString()) - .withMergedByUser(hook.getUser() == null ? null : hook.getUser().getUsername()) - .withPullRequestAssignee(hook.getAssignee() == null ? null : hook.getAssignee().getUsername()) - .withPullRequestTargetProjectId(hook.getPullRequest().getTargetProjectId()) - .withTargetBranch(hook.getPullRequest().getTargetBranch()) - .withTargetRepoName(hook.getPullRequest().getTarget().getName()) - .withTargetNamespace(hook.getPullRequest().getTarget().getNamespace()) - .withTargetRepoSshUrl(hook.getPullRequest().getTarget().getSshUrl()) - .withTargetRepoHttpUrl(hook.getPullRequest().getTarget().getGitHttpUrl()) - .withTriggeredByUser(hook.getPullRequest().getHead().getUser().getName()) - .withLastCommit(hook.getPullRequest().getMergeCommitSha()) - .withSha(hook.getPullRequest().getMergeCommitSha()) - .withAfter(hook.getPullRequest().getMergeCommitSha()) - .withRef(hook.getPullRequest().getMergeReferenceName()) - .withTargetProjectUrl(hook.getPullRequest().getTarget().getUrl()) - .withPathWithNamespace(hook.getRepo().getPathWithNamespace()) - .withJsonBody(hook.getJsonBody()) - .build(); - } - - @Override - protected RevisionParameterAction createRevisionParameter(PullRequestHook hook, GitSCM gitSCM) throws NoRevisionToBuildException { - // 没有配置git源码管理 - if (gitSCM == null) { - return new RevisionParameterAction(retrieveRevisionToBuild(hook)); - } - URIish urIish = retrieveUrIish(hook, gitSCM); - // webhook与git源码管理仓库对不上 - if (urIish == null) { - return new RevisionParameterAction(retrieveRevisionToBuild2(hook)); - } - return new RevisionParameterAction(retrieveRevisionToBuild(hook), urIish); - } - - @Override - protected BuildStatusUpdate retrieveBuildStatusUpdate(PullRequestHook hook) { - return buildStatusUpdate() - .withProjectId(hook.getPullRequest().getSourceProjectId()) - .withSha(hook.getPullRequest().getMergeCommitSha()) - .withRef(hook.getPullRequest().getSourceBranch()) - .build(); - } - - private String retrieveRevisionToBuild(PullRequestHook hook) throws NoRevisionToBuildException { - if (hook.getPullRequest() != null) { - if (hook.getPullRequest().getMergeCommitSha() != null) { - return hook.getPullRequest().getMergeCommitSha(); - } - } - return retrieveRevisionToBuild2(hook); - } - - private String retrieveRevisionToBuild2(PullRequestHook hook) throws NoRevisionToBuildException { - if (hook.getPullRequest() != null) { - if (hook.getPullRequest().getMergeReferenceName() != null) { - return hook.getPullRequest().getMergeReferenceName(); - } - } - throw new NoRevisionToBuildException(); - } - - private String getTargetBranchFromBuild(Run mergeBuild) { - GiteeWebHookCause cause = mergeBuild.getCause(GiteeWebHookCause.class); - return cause == null ? null : cause.getData().getTargetBranch(); - } - - private boolean isAllowedByConfig(PullRequestHook hook) { - return allowedStates.contains(hook.getState()) - && allowedActions.contains(hook.getAction()) - && (hook.getAction() != Action.update || allowedActionDesces.contains(hook.getActionDesc())); - } - - // Gitee 无此状态,暂时屏蔽 - private boolean isNotSkipWorkInProgressPullRequest(PullRequestObjectAttributes objectAttributes) { -// Boolean workInProgress = objectAttributes.getWorkInProgress(); -// if (skipWorkInProgressPullRequest && workInProgress != null && workInProgress) { -// LOGGER.log(Level.INFO, "Skip WIP Pull Request #{0} ({1})", toArray(objectAttributes.getNumber(), objectAttributes.getTitle())); -// return false; -// } - return true; - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/push/NopPushHookTriggerHandler.java b/src/main/java/com/gitee/jenkins/trigger/handler/push/NopPushHookTriggerHandler.java deleted file mode 100644 index 4099998..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/push/NopPushHookTriggerHandler.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.gitee.jenkins.trigger.handler.push; - -import com.gitee.jenkins.gitee.hook.model.PushHook; -import com.gitee.jenkins.trigger.filter.BranchFilter; -import com.gitee.jenkins.trigger.filter.BuildInstructionFilter; -import com.gitee.jenkins.trigger.filter.PullRequestLabelFilter; -import hudson.model.Job; - -/** - * @author Robin Müller - */ -class NopPushHookTriggerHandler implements PushHookTriggerHandler { - @Override - public void handle(Job job, PushHook hook, BuildInstructionFilter buildInstructionFilter, boolean skipLastCommitHasBeenBuild, BranchFilter branchFilter, PullRequestLabelFilter pullRequestLabelFilter) { - // nothing to do - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/push/PushHookTriggerHandler.java b/src/main/java/com/gitee/jenkins/trigger/handler/push/PushHookTriggerHandler.java deleted file mode 100644 index bdfd2a3..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/push/PushHookTriggerHandler.java +++ /dev/null @@ -1,9 +0,0 @@ -package com.gitee.jenkins.trigger.handler.push; - -import com.gitee.jenkins.gitee.hook.model.PushHook; -import com.gitee.jenkins.trigger.handler.WebHookTriggerHandler; - -/** - * @author Robin Müller - */ -public interface PushHookTriggerHandler extends WebHookTriggerHandler { } diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/push/PushHookTriggerHandlerFactory.java b/src/main/java/com/gitee/jenkins/trigger/handler/push/PushHookTriggerHandlerFactory.java deleted file mode 100644 index 92f4111..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/push/PushHookTriggerHandlerFactory.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.gitee.jenkins.trigger.handler.push; - -import java.util.ArrayList; -import java.util.List; - -/** - * @author Robin Müller - */ -public final class PushHookTriggerHandlerFactory { - - private PushHookTriggerHandlerFactory() {} - - public static PushHookTriggerHandler newPushHookTriggerHandler(boolean triggerOnPush, boolean skipWorkInProgressPullRequest) { - if (triggerOnPush) { - return new PushHookTriggerHandlerList(retrieveHandlers(triggerOnPush, skipWorkInProgressPullRequest)); - } else { - return new NopPushHookTriggerHandler(); - } - } - - private static List retrieveHandlers(boolean triggerOnPush, boolean skipWorkInProgressPullRequest) { - List result = new ArrayList<>(); - if (triggerOnPush) { - result.add(new PushHookTriggerHandlerImpl()); - } - - return result; - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/push/PushHookTriggerHandlerImpl.java b/src/main/java/com/gitee/jenkins/trigger/handler/push/PushHookTriggerHandlerImpl.java deleted file mode 100644 index a66fb82..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/push/PushHookTriggerHandlerImpl.java +++ /dev/null @@ -1,172 +0,0 @@ -package com.gitee.jenkins.trigger.handler.push; - -import com.gitee.jenkins.cause.CauseData; -import com.gitee.jenkins.cause.GiteeWebHookCause; -import com.gitee.jenkins.gitee.hook.model.Commit; -import com.gitee.jenkins.gitee.hook.model.PushHook; -import com.gitee.jenkins.trigger.exception.NoRevisionToBuildException; -import com.gitee.jenkins.trigger.filter.BranchFilter; -import com.gitee.jenkins.trigger.filter.BuildInstructionFilter; -import com.gitee.jenkins.trigger.filter.PullRequestLabelFilter; -import com.gitee.jenkins.trigger.handler.AbstractWebHookTriggerHandler; -import hudson.model.Job; -import hudson.model.Run; -import hudson.plugins.git.GitSCM; -import hudson.plugins.git.RevisionParameterAction; -import com.gitee.jenkins.util.BuildUtil; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.List; -import org.apache.commons.lang.StringUtils; -import static com.gitee.jenkins.cause.CauseDataBuilder.causeData; -import static com.gitee.jenkins.trigger.handler.builder.generated.BuildStatusUpdateBuilder.buildStatusUpdate; - -/** - * @author Robin MüllerPushHookTriggerHandlerImpl - * @author Yashin Luo - */ -class PushHookTriggerHandlerImpl extends AbstractWebHookTriggerHandler implements PushHookTriggerHandler { - - private static final Logger LOGGER = Logger.getLogger(PushHookTriggerHandlerImpl.class.getName()); - - private static final String NO_COMMIT = "0000000000000000000000000000000000000000"; - - @Override - public void handle(Job job, PushHook hook, BuildInstructionFilter buildInstructionFilter, boolean skipLastCommitHasBeenBuild, BranchFilter branchFilter, PullRequestLabelFilter pullRequestLabelFilter) { - if (isNoRemoveBranchPush(hook)) { - super.handle(job, hook, buildInstructionFilter, skipLastCommitHasBeenBuild, branchFilter, pullRequestLabelFilter); - } - } - - @Override - protected boolean isCiSkip(PushHook hook, BuildInstructionFilter buildInstructionFilter) { - List commits = hook.getCommits(); - if (buildInstructionFilter!= null && commits != null && !commits.isEmpty()) { - return !buildInstructionFilter.isBuildAllow(commits.get(commits.size() - 1).getMessage()); - } - return false; - } - - @Override - protected boolean isCommitSkip(Job project, PushHook hook) { - String sha = hook.getAfter(); - if (hook != null && sha != null) { - Run pushBuild = BuildUtil.getBuildBySHA1IncludingMergeBuilds(project, sha); - if (pushBuild != null && StringUtils.equals(getRefFromBuild(pushBuild), hook.getRef())) { - LOGGER.log(Level.INFO, "Last commit in push has already been built sha=" + sha); - return true; - } - } - return false; - } - - @Override - protected CauseData retrieveCauseData(PushHook hook) { -// fixme 判断是否push tag,Gitee 钩子未有相关数据 -// CauseData.ActionType actionType = hook.getObjectKind().equals("tag_push") ? CauseData.ActionType.TAG_PUSH : CauseData.ActionType.PUSH; - CauseData.ActionType actionType = CauseData.ActionType.PUSH; - return causeData() - .withActionType(actionType) - .withSourceProjectId(hook.getProjectId()) - .withTargetProjectId(hook.getProjectId()) - .withBranch(getTargetBranch(hook)) - .withSourceBranch(getTargetBranch(hook)) - .withUserName(hook.getUserName()) - .withUserEmail(hook.getUserEmail()) - .withSourceRepoHomepage(hook.getProject().getHomepage()) - .withSourceRepoName(hook.getProject().getName()) - .withSourceNamespace(hook.getProject().getNamespace()) - .withSourceRepoUrl(hook.getProject().getUrl()) - .withSourceRepoSshUrl(hook.getProject().getSshUrl()) - .withSourceRepoHttpUrl(hook.getProject().getGitHttpUrl()) - .withPullRequestTitle("") - .withPullRequestDescription("") - .withPullRequestId(null) - .withPullRequestIid(null) - .withPullRequestState(null) - .withMergedByUser("") - .withPullRequestAssignee("") - .withPullRequestTargetProjectId(null) - .withTargetBranch(getTargetBranch(hook)) - .withTargetRepoName("") - .withTargetNamespace("") - .withTargetRepoSshUrl("") - .withTargetRepoHttpUrl("") - .withTriggeredByUser(retrievePushedBy(hook)) - .withBefore(hook.getBefore()) - .withAfter(hook.getAfter()) - .withRef(hook.getRef()) - .withLastCommit(hook.getAfter()) - .withSha(hook.getAfter()) - .withCreated(hook.getCreated()) - .withDeleted(hook.getDeleted()) - .withTargetProjectUrl(hook.getProject().getUrl()) - .withJsonBody(hook.getJsonBody()) - .build(); - } - - @Override - protected String getTargetBranch(PushHook hook) { - return hook.getRef() == null ? null : hook.getRef().replaceFirst("^refs/heads/", ""); - } - - @Override - protected String getTriggerType() { - return "push"; - } - - @Override - protected RevisionParameterAction createRevisionParameter(PushHook hook, GitSCM gitSCM) throws NoRevisionToBuildException { - return new RevisionParameterAction(retrieveRevisionToBuild(hook, gitSCM), retrieveUrIish(hook, gitSCM)); - } - - @Override - protected BuildStatusUpdate retrieveBuildStatusUpdate(PushHook hook) { - return buildStatusUpdate() - .withProjectId(hook.getProjectId()) - .withSha(hook.getAfter()) - .withRef(getTargetBranch(hook)) - .build(); - } - - private String retrievePushedBy(final PushHook hook) { - - final String userName = hook.getUserName(); - if (StringUtils.isNotBlank(userName)) { - return userName; - } - - final List commits = hook.getCommits(); - if (commits != null && !commits.isEmpty()) { - return commits.get(commits.size() - 1).getAuthor().getName(); - } - - return null; - } - - private String retrieveRevisionToBuild(PushHook hook, GitSCM gitSCM) throws NoRevisionToBuildException { - if (inNoBranchDelete(hook)) { - if (gitSCM != null && gitSCM.getRepositories().size() == 1) { - String repositoryName = gitSCM.getRepositories().get(0).getName(); - return hook.getRef().replaceFirst("^refs/heads", "remotes/" + repositoryName); - } else { - return hook.getAfter(); - } - } else { - throw new NoRevisionToBuildException(); - } - } - - private boolean inNoBranchDelete(PushHook hook) { - return hook.getAfter() != null && !hook.getAfter().equals(NO_COMMIT); - } - - private boolean isNoRemoveBranchPush(PushHook hook) { - return hook.getAfter() != null && !hook.getAfter().equals(NO_COMMIT); - } - - private String getRefFromBuild(Run pushBuild) { - GiteeWebHookCause cause = pushBuild.getCause(GiteeWebHookCause.class); - return cause == null ? null : cause.getData().getRef(); - } -} diff --git a/src/main/java/com/gitee/jenkins/trigger/handler/push/PushHookTriggerHandlerList.java b/src/main/java/com/gitee/jenkins/trigger/handler/push/PushHookTriggerHandlerList.java deleted file mode 100644 index 2ecf9d2..0000000 --- a/src/main/java/com/gitee/jenkins/trigger/handler/push/PushHookTriggerHandlerList.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.gitee.jenkins.trigger.handler.push; - -import com.gitee.jenkins.gitee.hook.model.PushHook; -import com.gitee.jenkins.trigger.filter.BranchFilter; -import com.gitee.jenkins.trigger.filter.BuildInstructionFilter; -import com.gitee.jenkins.trigger.filter.PullRequestLabelFilter; -import hudson.model.Job; - -import java.util.List; - -/** - * @author Robin Müller - */ -class PushHookTriggerHandlerList implements PushHookTriggerHandler { - - private final List handlers; - - PushHookTriggerHandlerList(List handlers) { - this.handlers = handlers; - } - - @Override - public void handle(Job job, PushHook hook, BuildInstructionFilter buildInstructionFilter, boolean skipLastCommitHasBeenBuild, BranchFilter branchFilter, PullRequestLabelFilter pullRequestLabelFilter) { - for (PushHookTriggerHandler handler : handlers) { - handler.handle(job, hook, buildInstructionFilter, skipLastCommitHasBeenBuild, branchFilter, pullRequestLabelFilter); - } - } -} diff --git a/src/main/java/com/gitee/jenkins/util/ACLUtil.java b/src/main/java/com/gitee/jenkins/util/ACLUtil.java deleted file mode 100644 index 38108b3..0000000 --- a/src/main/java/com/gitee/jenkins/util/ACLUtil.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.gitee.jenkins.util; - -import hudson.security.ACL; -import org.acegisecurity.Authentication; - -/** - * @author Robin Müller - */ -public class ACLUtil { - - public static T impersonate(Authentication auth, final Function function) { - final ObjectHolder holder = new ObjectHolder(); - ACL.impersonate(auth, new Runnable() { - public void run() { - holder.setValue(function.invoke()); - } - }); - return holder.getValue(); - } - - public interface Function { - T invoke(); - } - - private static class ObjectHolder { - private T value; - - public T getValue() { - return value; - } - - public void setValue(T value) { - this.value = value; - } - } -} diff --git a/src/main/java/com/gitee/jenkins/util/BuildUtil.java b/src/main/java/com/gitee/jenkins/util/BuildUtil.java index 983cf08..b6d53f6 100644 --- a/src/main/java/com/gitee/jenkins/util/BuildUtil.java +++ b/src/main/java/com/gitee/jenkins/util/BuildUtil.java @@ -1,61 +1,92 @@ package com.gitee.jenkins.util; +import com.gitee.jenkins.cause.GiteeWebHookCause; +import com.gitee.jenkins.cause.GiteeWebHookCauseData; +import com.gitee.jenkins.entity.PullRequest; +import hudson.model.AbstractBuild; import hudson.model.Job; import hudson.model.Run; -import hudson.plugins.git.Branch; import hudson.plugins.git.util.BuildData; -import hudson.plugins.git.util.MergeRecord; +import org.eclipse.jgit.lib.ObjectId; +import org.jenkinsci.plugins.workflow.job.WorkflowRun; + +import javax.servlet.ServletException; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; -/** - * @author Robin Müller - */ public class BuildUtil { - public static Run getBuildByBranch(Job project, String branchName) { - for (Run build : project.getBuilds()) { - BuildData data = build.getAction(BuildData.class); - MergeRecord merge = build.getAction(MergeRecord.class); - if (hasLastBuild(data) && isNoMergeBuild(data, merge)) { - for (Branch branch : data.lastBuild.getRevision().getBranches()) { - if (branch.getName().endsWith("/" + branchName)) { - return build; + + private static final Logger LOGGER = Logger.getLogger(BuildUtil.class.getName()); + + private BuildUtil() { + } + + /** + * 判断是否存在相同 sha1 的构建 + * + * @param job + * @param sha1 + * @return + */ + public static boolean hasBeenBuilt(Job job, String sha1) { + if (sha1 != null) { + for (Run build : job.getBuilds()) { + for (BuildData buildData : build.getActions(BuildData.class)) { + if (buildData.hasBeenBuilt(ObjectId.fromString(sha1))) { + return true; } } } } - return null; + return false; } - public static Run getBuildBySHA1WithoutMergeBuilds(Job project, String sha1) { - for (Run build : project.getBuilds()) { - MergeRecord merge = build.getAction(MergeRecord.class); - for(BuildData data : build.getActions(BuildData.class)) { - if (hasLastBuild(data) && isNoMergeBuild(data, merge) && data.lastBuild.isFor(sha1)) { - return build; + /** + * 中止未完成构建 + * + * @param job + * @param pullRequest + */ + public static void doStop(Job job, PullRequest pullRequest) { + for (Run build : job.getBuilds()) { + if (!job.isBuilding()) { + break; + } + + GiteeWebHookCause giteeWebHookCause = build.getCause(GiteeWebHookCause.class); + if (build.isBuilding() && giteeWebHookCause != null) { + GiteeWebHookCauseData causeData = giteeWebHookCause.getData(); + if (causeData.getSourceRepoHttpUrl().equals(pullRequest.getHead().getRepo().getGitHttpUrl()) + && causeData.getTargetRepoHttpUrl().equals(pullRequest.getBase().getRepo().getGitHttpUrl()) + && causeData.getRef().equals(pullRequest.getMergeReferenceName())) { + doStop(build); } } } - return null; } - public static Run getBuildBySHA1IncludingMergeBuilds(Job project, String sha1) { - for (Run build : project.getBuilds()) { - for(BuildData data : build.getActions(BuildData.class)) { - if (data != null - && data.lastBuild != null - && data.lastBuild.getMarked() != null - && data.lastBuild.getMarked().getSha1String().equals(sha1)) { - return build; + /** + * 中止未完成构建 + * + * @param build + */ + private static void doStop(Run build) { + if (build.isBuilding()) { + if (build instanceof AbstractBuild) { + try { + ((AbstractBuild) build).doStop(); + LOGGER.log(Level.WARNING, "Abort incomplete build"); + } catch (IOException | ServletException e) { + LOGGER.log(Level.WARNING, "Abort incomplete build error"); } + } else if (build instanceof WorkflowRun) { + ((WorkflowRun) build).doStop(); + LOGGER.log(Level.WARNING, "Abort incomplete build"); + } else { + LOGGER.log(Level.WARNING, "Unable to abort incomplete build, build type not found: {0}", build.getClass().getName()); } } - return null; } - private static boolean isNoMergeBuild(BuildData data, MergeRecord merge) { - return merge == null || merge.getSha1().equals(data.lastBuild.getMarked().getSha1String()); - } - - private static boolean hasLastBuild(BuildData data) { - return data != null && data.lastBuild != null && data.lastBuild.getRevision() != null; - } } diff --git a/src/main/java/com/gitee/jenkins/util/JsonUtil.java b/src/main/java/com/gitee/jenkins/util/JsonUtil.java index b423ea2..b138cc3 100644 --- a/src/main/java/com/gitee/jenkins/util/JsonUtil.java +++ b/src/main/java/com/gitee/jenkins/util/JsonUtil.java @@ -1,71 +1,148 @@ package com.gitee.jenkins.util; -import com.fasterxml.jackson.databind.DeserializationContext; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.PropertyNamingStrategy; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.databind.module.SimpleModule; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.*; +import org.apache.commons.lang3.StringUtils; -import java.io.IOException; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.Locale; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.logging.Level; +import java.util.logging.Logger; -/** - * @author Robin Müller - */ -public final class JsonUtil { +public class JsonUtil { - private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper() - .setPropertyNamingStrategy(PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES) - .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) - .configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true) - .configure(SerializationFeature.INDENT_OUTPUT, true) - .registerModule(new DateModule()); + private static final Logger LOGGER = Logger.getLogger(JsonUtil.class.getName()); - private JsonUtil() { } + private static final ObjectMapper OBJECT_MAPPER; + + static { + OBJECT_MAPPER = new ObjectMapper() + // 加载所有字段 + .setSerializationInclusion(JsonInclude.Include.ALWAYS) + // 下划线转驼峰 + .setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE) + // 忽略空bean错误 + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, Boolean.FALSE) + // 忽略实体类不存在字段错误 + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, Boolean.FALSE); + } + + private JsonUtil() { + } + + /** + * 实体类转json字符串 + * + * @param obj bean + * @return json字符串 + */ + public static String obj2String(Object obj) { + if (obj == null) { + return null; + } + + if (obj instanceof String) { + return (String) obj; + } - public static String toPrettyPrint(String json) { try { - return OBJECT_MAPPER.writeValueAsString(OBJECT_MAPPER.readValue(json, Object.class)); - } catch (IOException e) { - throw new RuntimeException(e); + return OBJECT_MAPPER.writeValueAsString(obj); + } catch (JsonProcessingException e) { + LOGGER.log(Level.WARNING, "JsonUtil obj2String error:", e); + return null; } } - public static T read(String json, Class type) { + /** + * 实体类转格式化json字符串 + * + * @param obj 实体类 + * @return 格式化json字符串 + */ + public static String obj2StringPretty(Object obj) { + if (obj == null) { + return null; + } + + if (obj instanceof String) { + return (String) obj; + } + try { - return OBJECT_MAPPER.readValue(json, type); - } catch (IOException e) { - throw new RuntimeException(e); + return OBJECT_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(obj); + } catch (JsonProcessingException e) { + LOGGER.log(Level.WARNING, "JsonUtil obj2StringPretty error:", e); + return null; } } - private static class DateModule extends SimpleModule { - private static final String[] DATE_FORMATS = new String[] { - "yyyy-MM-dd HH:mm:ss Z", "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", "yyyy-MM-dd'T'HH:mm:ssX", "yyyy-MM-dd'T'HH:mm:ss.SSSX", "yyyy-MM-dd'T'HH:mm:ss.SSSZ" - }; + /** + * json字符串转实体类 + * + * @param jsonStr json字符串 + * @param clazz 实体类类型 + * @param 返回类型 + * @return 实体类 + */ + public static T string2Obj(String jsonStr, Class clazz) { + if (StringUtils.isBlank(jsonStr) || clazz == null) { + return null; + } - private DateModule() { - addDeserializer(Date.class, new com.fasterxml.jackson.databind.JsonDeserializer() { - @Override - public Date deserialize(com.fasterxml.jackson.core.JsonParser p, DeserializationContext ctxt) throws IOException { - for (String format : DATE_FORMATS) { - try { - return new SimpleDateFormat(format, Locale.US) - .parse(p.getValueAsString()); - } catch (ParseException e) { - // nothing to do - } - } - throw new IOException("Unparseable date: \"" - + p.getValueAsString() + "\". Supported formats: " - + Arrays.toString(DATE_FORMATS)); - } - }); + if (String.class.equals(clazz)) { + return (T) jsonStr; + } + + try { + return OBJECT_MAPPER.readValue(jsonStr, clazz); + } catch (JsonProcessingException e) { + LOGGER.log(Level.WARNING, "JsonUtil string2Obj error:", e); + return null; } } + + /** + * json字符串转实体类列表 + * + * @param jsonStr json字符串 + * @param clazz 实体类类型 + * @param 返回类型 + * @return 实体类列表 + */ + public static List string2List(String jsonStr, Class clazz) { + if (StringUtils.isBlank(jsonStr) || clazz == null) { + return Collections.emptyList(); + } + + try { + return OBJECT_MAPPER.readValue(jsonStr, OBJECT_MAPPER.getTypeFactory().constructParametricType(List.class, clazz)); + } catch (JsonProcessingException e) { + LOGGER.log(Level.WARNING, "JsonUtil string2List error:", e); + return Collections.emptyList(); + } + } + + /** + * 判断 json 字符串是否含有指定字段名 + * + * @param jsonStr + * @return + */ + public static boolean has(String jsonStr, String fieldName) { + if (StringUtils.isBlank(jsonStr) || Objects.isNull(fieldName)) { + return false; + } + + try { + JsonNode jsonNode = OBJECT_MAPPER.readTree(jsonStr); + return jsonNode.has(fieldName); + } catch (JsonProcessingException e) { + LOGGER.log(Level.WARNING, "JsonUtil has error:", e); + } + + return false; + } + } diff --git a/src/main/java/com/gitee/jenkins/util/LoggerUtil.java b/src/main/java/com/gitee/jenkins/util/LoggerUtil.java deleted file mode 100644 index d8fa7d4..0000000 --- a/src/main/java/com/gitee/jenkins/util/LoggerUtil.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.jenkins.util; - -/** - * @author Robin Müller - */ -public final class LoggerUtil { - - private LoggerUtil() {} - - public static Object[] toArray(Object... objects) { - return objects; - } -} diff --git a/src/main/java/com/gitee/jenkins/util/ProjectIdUtil.java b/src/main/java/com/gitee/jenkins/util/ProjectIdUtil.java deleted file mode 100644 index 4c351d1..0000000 --- a/src/main/java/com/gitee/jenkins/util/ProjectIdUtil.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.gitee.jenkins.util; - - -import com.gitee.jenkins.gitee.api.GiteeClient; -import org.eclipse.jgit.transport.URIish; - -import java.net.URISyntaxException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * @author Robin Müller - */ -public final class ProjectIdUtil { - - private static final Pattern PROJECT_ID_PATTERN = Pattern.compile("^/?(?.*?)(\\.git)?$"); - - private ProjectIdUtil() { } - - public static String retrieveProjectId(GiteeClient client, String remoteUrl) throws ProjectIdResolutionException { - try { - String baseUri = client.getHostUrl(); - String projectId; - if (baseUri != null && remoteUrl.startsWith(baseUri)) { - projectId = new URIish(remoteUrl.substring(baseUri.length(), remoteUrl.length())).getPath(); - } else { - projectId = new URIish(remoteUrl).getPath(); - } - if (projectId.startsWith(":")) { - projectId = projectId.substring(1); - } - - Matcher matcher = PROJECT_ID_PATTERN.matcher(projectId); - if (matcher.matches()) { - return matcher.group("projectId"); - } else { - throw new ProjectIdResolutionException(String.format("Failed to retrieve Gitee projectId for %s", remoteUrl)); - } - } catch (URISyntaxException e) { - throw new ProjectIdResolutionException(String.format("Failed to retrieve Gitee projectId for %s", remoteUrl), e); - } - } - - public static class ProjectIdResolutionException extends Exception { - public ProjectIdResolutionException(String message, Throwable cause) { - super(message, cause); - } - - public ProjectIdResolutionException(String message) { - super(message); - } - } -} diff --git a/src/main/java/com/gitee/jenkins/webhook/ActionResolver.java b/src/main/java/com/gitee/jenkins/webhook/ActionResolver.java deleted file mode 100644 index fee9856..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/ActionResolver.java +++ /dev/null @@ -1,158 +0,0 @@ -package com.gitee.jenkins.webhook; - -import com.gitee.jenkins.util.ACLUtil; -import com.gitee.jenkins.webhook.build.PullRequestBuildAction; -import com.gitee.jenkins.webhook.build.NoteBuildAction; -import com.gitee.jenkins.webhook.build.PipelineBuildAction; -import com.gitee.jenkins.webhook.build.PushBuildAction; -import com.gitee.jenkins.webhook.status.BranchBuildPageRedirectAction; -import com.gitee.jenkins.webhook.status.BranchStatusPngAction; -import com.gitee.jenkins.webhook.status.CommitBuildPageRedirectAction; -import com.gitee.jenkins.webhook.status.CommitStatusPngAction; -import com.gitee.jenkins.webhook.status.StatusJsonAction; -import com.google.common.base.Joiner; -import com.google.common.base.Splitter; -import hudson.model.Item; -import hudson.model.ItemGroup; -import hudson.model.Job; -import hudson.security.ACL; -import hudson.util.HttpResponses; -import jenkins.model.Jenkins; -import jenkins.scm.api.SCMSourceOwner; -import org.apache.commons.io.IOUtils; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -import java.io.IOException; -import java.nio.charset.Charset; -import java.util.Iterator; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.gitee.jenkins.util.LoggerUtil.toArray; -import static java.nio.charset.StandardCharsets.UTF_8; - -/** - * @author Robin Müller - * @author Yashin - */ -public class ActionResolver { - - private static final Logger LOGGER = Logger.getLogger(ActionResolver.class.getName()); - private static final Pattern COMMIT_STATUS_PATTERN = - Pattern.compile("^(refs/[^/]+/)?(commits|builds)/(?[0-9a-fA-F]+)(?/status.json)?$"); - - public WebHookAction resolve(final String projectName, StaplerRequest request) { - Iterator restOfPathParts = Splitter.on('/').omitEmptyStrings().split(request.getRestOfPath()).iterator(); - Item project = resolveProject(projectName, restOfPathParts); - if (project == null) { - throw HttpResponses.notFound(); - } - return resolveAction(project, Joiner.on('/').join(restOfPathParts), request); - } - - private WebHookAction resolveAction(Item project, String restOfPath, StaplerRequest request) { - String method = request.getMethod(); - if (method.equals("POST")) { - return onPost(project, request); - } else if (method.equals("GET")) { - if (project instanceof Job) { - return onGet((Job) project, restOfPath, request); - } else { - LOGGER.log(Level.FINE, "GET is not supported for this project {0}", project.getName()); - return new NoopAction(); - } - } - LOGGER.log(Level.FINE, "Unsupported HTTP method: {0}", method); - return new NoopAction(); - } - - private WebHookAction onGet(Job project, String restOfPath, StaplerRequest request) { - Matcher commitMatcher = COMMIT_STATUS_PATTERN.matcher(restOfPath); - if (restOfPath.isEmpty() && request.hasParameter("ref")) { - return new BranchBuildPageRedirectAction(project, request.getParameter("ref")); - } else if (restOfPath.endsWith("status.png")) { - return onGetStatusPng(project, request); - } else if (commitMatcher.matches()) { - return onGetCommitStatus(project, commitMatcher.group("sha1"), commitMatcher.group("statusJson")); - } - LOGGER.log(Level.FINE, "Unknown GET request: {0}", restOfPath); - return new NoopAction(); - } - - private WebHookAction onGetCommitStatus(Job project, String sha1, String statusJson) { - if (statusJson == null) { - return new CommitBuildPageRedirectAction(project, sha1); - } else { - return new StatusJsonAction(project, sha1); - } - } - - private WebHookAction onGetStatusPng(Job project, StaplerRequest request) { - if (request.hasParameter("ref")) { - return new BranchStatusPngAction(project, request.getParameter("ref")); - } else { - return new CommitStatusPngAction(project, request.getParameter("sha1")); - } - } - - private WebHookAction onPost(Item project, StaplerRequest request) { - String eventHeader = request.getHeader("X-Gitee-Event"); - if (eventHeader == null) { - LOGGER.log(Level.FINE, "Missing X-Gitee-Event header"); - return new NoopAction(); - } - String tokenHeader = request.getHeader("X-Gitee-Token"); - switch (eventHeader) { - case "Merge Request Hook": - return new PullRequestBuildAction(project, getRequestBody(request), tokenHeader); - case "Push Hook": - case "Tag Push Hook": - return new PushBuildAction(project, getRequestBody(request), tokenHeader); - case "Note Hook": - return new NoteBuildAction(project, getRequestBody(request), tokenHeader); - case "Pipeline Hook": - return new PipelineBuildAction(project, getRequestBody(request), tokenHeader); - default: - LOGGER.log(Level.FINE, "Unsupported X-Gitee-Event header: {0}", eventHeader); - return new NoopAction(); - } - } - - private String getRequestBody(StaplerRequest request) { - String requestBody; - try { - Charset charset = request.getCharacterEncoding() == null ? UTF_8 : Charset.forName(request.getCharacterEncoding()); - requestBody = IOUtils.toString(request.getInputStream(), charset); - } catch (IOException e) { - throw HttpResponses.error(500, "Failed to read request body"); - } - return requestBody; - } - - private Item resolveProject(final String projectName, final Iterator restOfPathParts) { - return ACLUtil.impersonate(ACL.SYSTEM, new ACLUtil.Function() { - public Item invoke() { - final Jenkins jenkins = Jenkins.getInstance(); - if (jenkins != null) { - Item item = jenkins.getItemByFullName(projectName); - while (item instanceof ItemGroup && !(item instanceof Job || item instanceof SCMSourceOwner) && restOfPathParts.hasNext()) { - item = jenkins.getItem(restOfPathParts.next(), (ItemGroup) item); - } - if (item instanceof Job || item instanceof SCMSourceOwner) { - return item; - } - } - LOGGER.log(Level.FINE, "No project found: {0}, {1}", toArray(projectName, Joiner.on('/').join(restOfPathParts))); - return null; - } - }); - } - - static class NoopAction implements WebHookAction { - public void execute(StaplerResponse response) { - } - } -} diff --git a/src/main/java/com/gitee/jenkins/webhook/GiteeOldWebHook.java b/src/main/java/com/gitee/jenkins/webhook/GiteeOldWebHook.java deleted file mode 100644 index c32c63e..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/GiteeOldWebHook.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.gitee.jenkins.webhook; - -import hudson.Extension; -import hudson.model.UnprotectedRootAction; -import hudson.security.csrf.CrumbExclusion; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * @author Daniel Brooks - * @author Yashin Luo - */ - -@Extension -public class GiteeOldWebHook implements UnprotectedRootAction { - - public static final String WEBHOOK_URL = "project"; - - private static final Logger LOGGER = Logger.getLogger(GiteeOldWebHook.class.getName()); - - private transient final ActionResolver actionResolver = new ActionResolver(); - - public String getIconFileName() { - return null; - } - - public String getDisplayName() { - return null; - } - - public String getUrlName() { - return WEBHOOK_URL; - } - - public void getDynamic(final String projectName, final StaplerRequest request, StaplerResponse response) { - LOGGER.log(Level.INFO, "WebHook called with url: {0}", request.getRequestURIWithQueryString()); - actionResolver.resolve(projectName, request).execute(response); - } - - @Extension - public static class GiteeWebHookCrumbExclusion extends CrumbExclusion { - @Override - public boolean process(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws IOException, ServletException { - String pathInfo = req.getPathInfo(); - if (pathInfo != null && pathInfo.startsWith('/' + WEBHOOK_URL + '/')) { - chain.doFilter(req, resp); - return true; - } - return false; - } - } -} diff --git a/src/main/java/com/gitee/jenkins/webhook/GiteeWebHook.java b/src/main/java/com/gitee/jenkins/webhook/GiteeWebHook.java deleted file mode 100644 index d0a970d..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/GiteeWebHook.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.gitee.jenkins.webhook; - -import hudson.Extension; -import hudson.model.UnprotectedRootAction; -import hudson.security.csrf.CrumbExclusion; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; - -import javax.servlet.FilterChain; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * @author Daniel Brooks - * @author Yashin Luo - */ - -@Extension -public class GiteeWebHook implements UnprotectedRootAction { - - public static final String WEBHOOK_URL = "gitee-project"; - - private static final Logger LOGGER = Logger.getLogger(GiteeWebHook.class.getName()); - - private transient final ActionResolver actionResolver = new ActionResolver(); - - public String getIconFileName() { - return null; - } - - public String getDisplayName() { - return null; - } - - public String getUrlName() { - return WEBHOOK_URL; - } - - public void getDynamic(final String projectName, final StaplerRequest request, StaplerResponse response) { - LOGGER.log(Level.INFO, "WebHook called with url: {0}", request.getRequestURIWithQueryString()); - actionResolver.resolve(projectName, request).execute(response); - } - - @Extension - public static class GiteeWebHookCrumbExclusion extends CrumbExclusion { - @Override - public boolean process(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws IOException, ServletException { - String pathInfo = req.getPathInfo(); - if (pathInfo != null && pathInfo.startsWith('/' + WEBHOOK_URL + '/')) { - chain.doFilter(req, resp); - return true; - } - return false; - } - } -} diff --git a/src/main/java/com/gitee/jenkins/webhook/WebHookAction.java b/src/main/java/com/gitee/jenkins/webhook/WebHookAction.java deleted file mode 100644 index cd7800c..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/WebHookAction.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.gitee.jenkins.webhook; - -import org.kohsuke.stapler.StaplerResponse; - -/** - * @author Robin Müller - */ -public interface WebHookAction { - void execute(StaplerResponse response); -} diff --git a/src/main/java/com/gitee/jenkins/webhook/build/BuildWebHookAction.java b/src/main/java/com/gitee/jenkins/webhook/build/BuildWebHookAction.java deleted file mode 100644 index 4cac8e0..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/build/BuildWebHookAction.java +++ /dev/null @@ -1,86 +0,0 @@ -package com.gitee.jenkins.webhook.build; - -import java.io.IOException; -import java.util.logging.Logger; - -import com.gitee.jenkins.gitee.hook.model.WebHook; -import hudson.model.Item; -import hudson.model.Job; -import hudson.security.Messages; -import hudson.security.Permission; -import hudson.util.HttpResponses; -import jenkins.model.Jenkins; -import org.acegisecurity.Authentication; -import org.apache.commons.lang.StringUtils; -import org.kohsuke.stapler.StaplerRequest; -import org.kohsuke.stapler.StaplerResponse; -import com.gitee.jenkins.trigger.GiteePushTrigger; -import com.gitee.jenkins.connection.GiteeConnectionConfig; -import com.gitee.jenkins.webhook.WebHookAction; - -import javax.servlet.ServletException; - -/** - * @author Xinran Xiao - * @author Yashin Luo - */ -abstract class BuildWebHookAction implements WebHookAction { - - private final static Logger LOGGER = Logger.getLogger(BuildWebHookAction.class.getName()); - - abstract void processForCompatibility(); - - abstract void execute(); - - public final void execute(StaplerResponse response) { - processForCompatibility(); - execute(); - } - - public static HttpResponses.HttpResponseException responseWithHook(final WebHook webHook) { - return new HttpResponses.HttpResponseException() { - public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object node) throws IOException, ServletException { - String text = webHook.getWebHookDescription() + " has been accepted."; - rsp.setContentType("text/plain;charset=UTF-8"); - rsp.getWriter().println(text); - } - }; - } - - protected abstract static class TriggerNotifier implements Runnable { - - private final Item project; - private final String secretToken; - private final Authentication authentication; - - public TriggerNotifier(Item project, String secretToken, Authentication authentication) { - this.project = project; - this.secretToken = secretToken; - this.authentication = authentication; - } - - public void run() { - GiteePushTrigger trigger = GiteePushTrigger.getFromJob((Job) project); - if (trigger != null) { - if (StringUtils.isEmpty(trigger.getSecretToken())) { - checkPermission(Item.BUILD); - } else if (!StringUtils.equals(trigger.getSecretToken(), secretToken)) { - throw HttpResponses.errorWithoutStack(401, "Invalid token"); - } - performOnPost(trigger); - } - } - - private void checkPermission(Permission permission) { - if (((GiteeConnectionConfig) Jenkins.getInstance().getDescriptor(GiteeConnectionConfig.class)).isUseAuthenticatedEndpoint()) { - if (!Jenkins.getActiveInstance().getACL().hasPermission(authentication, permission)) { - String message = Messages.AccessDeniedException2_MissingPermission(authentication.getName(), permission.group.title+"/"+permission.name); - LOGGER.finest("Unauthorized (Did you forget to add API Token to the web hook ?)"); - throw HttpResponses.errorWithoutStack(403, message); - } - } - } - - protected abstract void performOnPost(GiteePushTrigger trigger); - } -} diff --git a/src/main/java/com/gitee/jenkins/webhook/build/NoteBuildAction.java b/src/main/java/com/gitee/jenkins/webhook/build/NoteBuildAction.java deleted file mode 100644 index c706360..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/build/NoteBuildAction.java +++ /dev/null @@ -1,55 +0,0 @@ -package com.gitee.jenkins.webhook.build; - -import com.gitee.jenkins.trigger.GiteePushTrigger; -import com.gitee.jenkins.gitee.hook.model.NoteHook; -import com.gitee.jenkins.util.JsonUtil; -import com.gitee.jenkins.webhook.WebHookAction; -import hudson.model.Item; -import hudson.model.Job; -import hudson.security.ACL; -import hudson.util.HttpResponses; -import jenkins.model.Jenkins; -import org.kohsuke.stapler.StaplerResponse; - -import java.util.logging.Level; -import java.util.logging.Logger; - -import static com.gitee.jenkins.util.JsonUtil.toPrettyPrint; - -/** - * @author Nikolay Ustinov - */ -public class NoteBuildAction extends BuildWebHookAction { - - private final static Logger LOGGER = Logger.getLogger(NoteBuildAction.class.getName()); - private Item project; - private NoteHook noteHook; - private final String secretToken; - - public NoteBuildAction(Item project, String json, String secretToken) { - LOGGER.log(Level.FINE, "Note: {0}", toPrettyPrint(json)); - this.project = project; - this.noteHook = JsonUtil.read(json, NoteHook.class); - this.noteHook.setJsonBody(json); - this.secretToken = secretToken; - } - - @Override - void processForCompatibility() { - - } - - @Override - public void execute() { - if (!(project instanceof Job)) { - throw HttpResponses.errorWithoutStack(409, "Note Hook is not supported for this project"); - } - ACL.impersonate(ACL.SYSTEM, new BuildWebHookAction.TriggerNotifier(project, secretToken, Jenkins.getAuthentication()) { - @Override - protected void performOnPost(GiteePushTrigger trigger) { - trigger.onPost(noteHook); - } - }); - throw responseWithHook(noteHook); - } -} diff --git a/src/main/java/com/gitee/jenkins/webhook/build/PipelineBuildAction.java b/src/main/java/com/gitee/jenkins/webhook/build/PipelineBuildAction.java deleted file mode 100644 index 8d67b24..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/build/PipelineBuildAction.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.gitee.jenkins.webhook.build; - -import com.gitee.jenkins.trigger.GiteePushTrigger; -import com.gitee.jenkins.gitee.hook.model.*; -import com.gitee.jenkins.util.JsonUtil; -import hudson.model.Item; -import hudson.model.Job; -import hudson.security.ACL; -import hudson.util.HttpResponses; -import jenkins.model.Jenkins; -import org.apache.commons.lang.StringUtils; - -import java.net.MalformedURLException; -import java.net.URL; -import java.util.logging.Level; -import java.util.logging.Logger; - -import static com.gitee.jenkins.util.JsonUtil.toPrettyPrint; - -/** - * @author Milena Zachow - */ -public class PipelineBuildAction extends BuildWebHookAction { - - private final static Logger LOGGER = Logger.getLogger(PipelineBuildAction.class.getName()); - private Item project; - private PipelineHook pipelineBuildHook; - private final String secretToken; - - public PipelineBuildAction(Item project, String json, String secretToken) { - LOGGER.log(Level.FINE, "Pipeline event: {0}", toPrettyPrint(json)); - this.project = project; - this.pipelineBuildHook = JsonUtil.read(json, PipelineHook.class); - this.pipelineBuildHook.setJsonBody(json); - this.secretToken = secretToken; - } - - void processForCompatibility() { - //if no project is defined, set it here - if (this.pipelineBuildHook.getProject() == null && this.pipelineBuildHook.getRepository() != null) { - try { - String path = new URL(this.pipelineBuildHook.getRepository().getGitHttpUrl()).getPath(); - if (StringUtils.isNotBlank(path)) { - Project project = new Project(); - project.setNamespace(path.replaceFirst("/", "").substring(0, path.lastIndexOf("/"))); - this.pipelineBuildHook.setProject(project); - } else { - LOGGER.log(Level.WARNING, "Could not find suitable namespace."); - } - } catch (MalformedURLException ignored) { - LOGGER.log(Level.WARNING, "Invalid repository url found while building namespace."); - } - } - } - - void execute() { - if (!(project instanceof Job)) { - throw HttpResponses.errorWithoutStack(409, "Pipeline Hook is not supported for this project"); - } - ACL.impersonate(ACL.SYSTEM, new TriggerNotifier(project, secretToken, Jenkins.getAuthentication()) { - @Override - protected void performOnPost(GiteePushTrigger trigger) { - trigger.onPost(pipelineBuildHook); - } - }); - throw responseWithHook(pipelineBuildHook); - } - -} - diff --git a/src/main/java/com/gitee/jenkins/webhook/build/PullRequestBuildAction.java b/src/main/java/com/gitee/jenkins/webhook/build/PullRequestBuildAction.java deleted file mode 100644 index 15d379c..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/build/PullRequestBuildAction.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.gitee.jenkins.webhook.build; - -import com.gitee.jenkins.gitee.hook.model.PullRequestHook; -import com.gitee.jenkins.trigger.GiteePushTrigger; -import com.gitee.jenkins.gitee.hook.model.PullRequestObjectAttributes; -import com.gitee.jenkins.gitee.hook.model.Project; -import com.gitee.jenkins.util.JsonUtil; -import hudson.model.Item; -import hudson.model.Job; -import hudson.security.ACL; -import hudson.util.HttpResponses; -import jenkins.model.Jenkins; - -import java.util.logging.Level; -import java.util.logging.Logger; - -import static com.gitee.jenkins.util.JsonUtil.toPrettyPrint; - -/** - * @author Robin Müller - */ -public class PullRequestBuildAction extends BuildWebHookAction { - - private final static Logger LOGGER = Logger.getLogger(PullRequestBuildAction.class.getName()); - private Item project; - private PullRequestHook pullRequestHook; - private final String secretToken; - - public PullRequestBuildAction(Item project, String json, String secretToken) { - LOGGER.log(Level.FINE, "PullRequest: {0}", toPrettyPrint(json)); - this.project = project; - this.pullRequestHook = JsonUtil.read(json, PullRequestHook.class); - this.pullRequestHook.setJsonBody(json); - this.secretToken = secretToken; - } - - void processForCompatibility() { - final PullRequestObjectAttributes attributes = this.pullRequestHook.getPullRequest(); - if (attributes != null) { - final Project source = attributes.getSource(); - if (source != null && source.getGitHttpUrl() != null) { - if (source.getUrl() == null) { - source.setUrl(source.getGitHttpUrl()); - } - if (source.getHomepage() == null) { - source.setHomepage(source.getGitHttpUrl().substring(0, source.getGitHttpUrl().lastIndexOf(".git"))); - } - } - - // The PullRequestHookTriggerHandlerImpl is looking for Project - if (pullRequestHook.getRepo() == null && attributes.getTarget() != null) { - pullRequestHook.setRepo(attributes.getTarget()); - } - } - } - - public void execute() { - if (!(project instanceof Job)) { - throw HttpResponses.errorWithoutStack(409, "Merge Request Hook is not supported for this project"); - } - ACL.impersonate(ACL.SYSTEM, new TriggerNotifier(project, secretToken, Jenkins.getAuthentication()) { - @Override - protected void performOnPost(GiteePushTrigger trigger) { - trigger.onPost(pullRequestHook); - } - }); - throw responseWithHook(pullRequestHook); - } -} diff --git a/src/main/java/com/gitee/jenkins/webhook/build/PushBuildAction.java b/src/main/java/com/gitee/jenkins/webhook/build/PushBuildAction.java deleted file mode 100644 index f47f053..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/build/PushBuildAction.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.gitee.jenkins.webhook.build; - -import com.gitee.jenkins.trigger.GiteePushTrigger; -import com.gitee.jenkins.gitee.hook.model.Project; -import com.gitee.jenkins.gitee.hook.model.PushHook; -import com.gitee.jenkins.util.JsonUtil; -import hudson.model.Item; -import hudson.model.Job; -import hudson.security.ACL; -import hudson.util.HttpResponses; -import jenkins.model.Jenkins; -import jenkins.plugins.git.GitSCMSource; -import jenkins.scm.api.SCMSource; -import jenkins.scm.api.SCMSourceOwner; -import org.apache.commons.lang.StringUtils; -import org.eclipse.jgit.transport.URIish; -import java.net.MalformedURLException; -import java.net.URISyntaxException; -import java.net.URL; -import java.util.logging.Level; -import java.util.logging.Logger; - -import static com.gitee.jenkins.util.JsonUtil.toPrettyPrint; -import static com.gitee.jenkins.util.LoggerUtil.toArray; - -/** - * @author Robin Müller - */ -public class PushBuildAction extends BuildWebHookAction { - - private final static Logger LOGGER = Logger.getLogger(PushBuildAction.class.getName()); - private final Item project; - private PushHook pushHook; - private final String secretToken; - - public PushBuildAction(Item project, String json, String secretToken) { - LOGGER.log(Level.FINE, "Push: {0}", toPrettyPrint(json)); - this.project = project; - this.pushHook = JsonUtil.read(json, PushHook.class); - this.pushHook.setJsonBody(json); - this.secretToken = secretToken; - } - - void processForCompatibility() { - // Fill in project if it's not defined. - if (this.pushHook.getProject() == null && this.pushHook.getRepository() != null) { - try { - String path = new URL(this.pushHook.getRepository().getGitHttpUrl()).getPath(); - if (StringUtils.isNotBlank(path)) { - Project project = new Project(); - project.setNamespace(path.replaceFirst("/", "").substring(0, path.lastIndexOf("/"))); - this.pushHook.setProject(project); - } else { - LOGGER.log(Level.WARNING, "Could not find suitable namespace."); - } - } catch (MalformedURLException ignored) { - LOGGER.log(Level.WARNING, "Invalid repository url found while building namespace."); - } - } - } - - public void execute() { - if (pushHook.getRepository() != null && pushHook.getRepository().getUrl() == null) { - LOGGER.log(Level.WARNING, "No repository url found."); - return; - } - - if (project instanceof Job) { - ACL.impersonate(ACL.SYSTEM, new TriggerNotifier(project, secretToken, Jenkins.getAuthentication()) { - @Override - protected void performOnPost(GiteePushTrigger trigger) { - trigger.onPost(pushHook); - } - }); - throw responseWithHook(pushHook); - } - if (project instanceof SCMSourceOwner) { - ACL.impersonate(ACL.SYSTEM, new SCMSourceOwnerNotifier()); - throw responseWithHook(pushHook); - } - throw HttpResponses.errorWithoutStack(409, "Push Hook is not supported for this project"); - } - - private class SCMSourceOwnerNotifier implements Runnable { - public void run() { - for (SCMSource scmSource : ((SCMSourceOwner) project).getSCMSources()) { - if (scmSource instanceof GitSCMSource) { - GitSCMSource gitSCMSource = (GitSCMSource) scmSource; - try { - if (new URIish(gitSCMSource.getRemote()).equals(new URIish(gitSCMSource.getRemote()))) { - if (!gitSCMSource.isIgnoreOnPushNotifications()) { - LOGGER.log(Level.FINE, "Notify scmSourceOwner {0} about changes for {1}", - toArray(project.getName(), gitSCMSource.getRemote())); - ((SCMSourceOwner) project).onSCMSourceUpdated(scmSource); - } else { - LOGGER.log(Level.FINE, "Ignore on push notification for scmSourceOwner {0} about changes for {1}", - toArray(project.getName(), gitSCMSource.getRemote())); - } - } - } catch (URISyntaxException e) { - // nothing to do - } - } - } - } - } - -} diff --git a/src/main/java/com/gitee/jenkins/webhook/status/BranchBuildPageRedirectAction.java b/src/main/java/com/gitee/jenkins/webhook/status/BranchBuildPageRedirectAction.java deleted file mode 100644 index b7eb40f..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/status/BranchBuildPageRedirectAction.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.jenkins.webhook.status; - -import com.gitee.jenkins.util.BuildUtil; -import hudson.model.Job; - -/** - * @author Robin Müller - */ -public class BranchBuildPageRedirectAction extends BuildPageRedirectAction { - public BranchBuildPageRedirectAction(Job project, String branchName) { - super(BuildUtil.getBuildByBranch(project, branchName)); - } -} diff --git a/src/main/java/com/gitee/jenkins/webhook/status/BranchStatusPngAction.java b/src/main/java/com/gitee/jenkins/webhook/status/BranchStatusPngAction.java deleted file mode 100644 index 88e5334..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/status/BranchStatusPngAction.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.jenkins.webhook.status; - -import com.gitee.jenkins.util.BuildUtil; -import hudson.model.Job; - -/** - * @author Robin Müller - */ -public class BranchStatusPngAction extends StatusPngAction { - public BranchStatusPngAction(Job project, String branchName) { - super(project, BuildUtil.getBuildByBranch(project, branchName)); - } -} diff --git a/src/main/java/com/gitee/jenkins/webhook/status/BuildPageRedirectAction.java b/src/main/java/com/gitee/jenkins/webhook/status/BuildPageRedirectAction.java deleted file mode 100644 index 478cce8..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/status/BuildPageRedirectAction.java +++ /dev/null @@ -1,35 +0,0 @@ -package com.gitee.jenkins.webhook.status; - -import com.gitee.jenkins.webhook.WebHookAction; -import hudson.model.Run; -import hudson.util.HttpResponses; -import jenkins.model.Jenkins; -import org.kohsuke.stapler.StaplerResponse; - -import java.io.IOException; - -/** - * @author Robin Müller - */ -abstract class BuildPageRedirectAction implements WebHookAction { - - private Run build; - - protected BuildPageRedirectAction(Run build) { - this.build = build; - } - - public void execute(StaplerResponse response) { - if (build != null) { - try { - response.sendRedirect2(Jenkins.getInstance().getRootUrl() + build.getUrl()); - } catch (IOException e) { - try { - response.sendRedirect2(Jenkins.getInstance().getRootUrl() + build.getBuildStatusUrl()); - } catch (IOException e1) { - throw HttpResponses.error(500, "Failed to redirect to build page"); - } - } - } - } -} diff --git a/src/main/java/com/gitee/jenkins/webhook/status/BuildStatusAction.java b/src/main/java/com/gitee/jenkins/webhook/status/BuildStatusAction.java deleted file mode 100644 index c4edd59..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/status/BuildStatusAction.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.gitee.jenkins.webhook.status; - -import com.gitee.jenkins.webhook.WebHookAction; -import hudson.model.Job; -import hudson.model.Result; -import hudson.model.Run; -import hudson.plugins.git.GitSCM; -import hudson.scm.SCM; -import hudson.util.HttpResponses; -import jenkins.triggers.SCMTriggerItem; -import org.kohsuke.stapler.StaplerResponse; - -/** - * @author Robin Müller - */ -abstract class BuildStatusAction implements WebHookAction { - - private final Job project; - private Run build; - - protected BuildStatusAction(Job project, Run build) { - this.project = project; - this.build = build; - } - - public void execute(StaplerResponse response) { - SCMTriggerItem item = SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(project); - if (!hasGitSCM(item)) { - throw HttpResponses.error(409, "The project has no GitSCM configured"); - } - writeStatusBody(response, build, getStatus(build)); - } - - protected abstract void writeStatusBody(StaplerResponse response, Run build, BuildStatus status); - - private boolean hasGitSCM(SCMTriggerItem item) { - if (item != null) { - for (SCM scm : item.getSCMs()) { - if (scm instanceof GitSCM) { - return true; - } - } - } - return false; - } - - private BuildStatus getStatus(Run build) { - if (build == null) { - return BuildStatus.NOT_FOUND; - } else if (build.isBuilding()) { - return BuildStatus.RUNNING; - } else if (build.getResult() == Result.ABORTED) { - return BuildStatus.CANCELED; - } else if (build.getResult() == Result.SUCCESS) { - return BuildStatus.SUCCESS; - } else if (build.getResult() == Result.UNSTABLE) { - return BuildStatus.UNSTABLE; - } else { - return BuildStatus.FAILED; - } - } - - protected enum BuildStatus { - NOT_FOUND("not_found"), RUNNING("running"), CANCELED("canceled"), SUCCESS("success"), FAILED("failed"), UNSTABLE("failed"); - - private String value; - - BuildStatus(String value) { - this.value = value; - } - - public String getValue() { - return value; - } - } -} diff --git a/src/main/java/com/gitee/jenkins/webhook/status/CommitBuildPageRedirectAction.java b/src/main/java/com/gitee/jenkins/webhook/status/CommitBuildPageRedirectAction.java deleted file mode 100644 index feb5743..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/status/CommitBuildPageRedirectAction.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.jenkins.webhook.status; - -import com.gitee.jenkins.util.BuildUtil; -import hudson.model.Job; - -/** - * @author Robin Müller - */ -public class CommitBuildPageRedirectAction extends BuildPageRedirectAction { - public CommitBuildPageRedirectAction(Job project, String sha1) { - super(BuildUtil.getBuildBySHA1IncludingMergeBuilds(project, sha1)); - } -} diff --git a/src/main/java/com/gitee/jenkins/webhook/status/CommitStatusPngAction.java b/src/main/java/com/gitee/jenkins/webhook/status/CommitStatusPngAction.java deleted file mode 100644 index 785c711..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/status/CommitStatusPngAction.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.gitee.jenkins.webhook.status; - -import com.gitee.jenkins.util.BuildUtil; -import hudson.model.Job; - -/** - * @author Robin Müller - */ -public class CommitStatusPngAction extends StatusPngAction { - public CommitStatusPngAction(Job project, String sha1) { - super(project, BuildUtil.getBuildBySHA1WithoutMergeBuilds(project, sha1)); - } -} diff --git a/src/main/java/com/gitee/jenkins/webhook/status/StatusJsonAction.java b/src/main/java/com/gitee/jenkins/webhook/status/StatusJsonAction.java deleted file mode 100644 index ea233b8..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/status/StatusJsonAction.java +++ /dev/null @@ -1,47 +0,0 @@ -package com.gitee.jenkins.webhook.status; - -import com.gitee.jenkins.util.BuildUtil; -import hudson.model.Job; -import hudson.model.Run; -import hudson.util.HttpResponses; -import net.sf.json.JSONObject; -import org.kohsuke.stapler.StaplerResponse; - -import java.io.IOException; -import java.io.PrintWriter; - -/** - * @author Robin Müller - */ -public class StatusJsonAction extends BuildStatusAction { - - private String sha1; - - public StatusJsonAction(Job project, String sha1) { - super(project, BuildUtil.getBuildBySHA1IncludingMergeBuilds(project, sha1)); - this.sha1 = sha1; - } - - @Override - protected void writeStatusBody(StaplerResponse response, Run build, BuildStatus status) { - try { - JSONObject object = new JSONObject(); - object.put("sha", sha1); - if (build != null) { - object.put("id", build.getNumber()); - } - object.put("status", status.getValue()); - writeBody(response, object); - } catch (IOException e) { - throw HttpResponses.error(500, "Failed to generate response"); - } - } - - private void writeBody(StaplerResponse response, JSONObject body) throws IOException { - response.setContentType("application/json"); - PrintWriter writer = response.getWriter(); - writer.write(body.toString()); - writer.flush(); - writer.close(); - } -} diff --git a/src/main/java/com/gitee/jenkins/webhook/status/StatusPngAction.java b/src/main/java/com/gitee/jenkins/webhook/status/StatusPngAction.java deleted file mode 100644 index d24ebd1..0000000 --- a/src/main/java/com/gitee/jenkins/webhook/status/StatusPngAction.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.gitee.jenkins.webhook.status; - -import hudson.model.Job; -import hudson.model.Run; -import hudson.util.HttpResponses; -import org.apache.commons.io.IOUtils; -import org.kohsuke.stapler.StaplerResponse; - -import java.io.InputStream; - -/** - * @author Robin Müller - */ -class StatusPngAction extends BuildStatusAction { - protected StatusPngAction(Job project, Run build) { - super(project, build); - } - - @Override - protected void writeStatusBody(StaplerResponse response, Run build, BuildStatus status) { - try { - response.setHeader("Expires", "Fri, 01 Jan 1984 00:00:00 GMT"); - response.setHeader("Cache-Control", "no-cache, private"); - response.setHeader("Content-Type", "image/png"); - IOUtils.copy(getStatusImage(status), response.getOutputStream()); - response.flushBuffer(); - } catch (Exception e) { - throw HttpResponses.error(500, "Could not generate response."); - } - } - - private InputStream getStatusImage(BuildStatus status) { - switch (status) { - case RUNNING: - return getClass().getResourceAsStream("running.png"); - case SUCCESS: - return getClass().getResourceAsStream("success.png"); - case FAILED: - return getClass().getResourceAsStream("failed.png"); - case UNSTABLE: - return getClass().getResourceAsStream("unstable.png"); - default: - return getClass().getResourceAsStream("unknown.png"); - } - } -} diff --git a/src/main/java/com/gitee/jenkins/workflow/AcceptGiteePullRequestStep.java b/src/main/java/com/gitee/jenkins/workflow/AcceptGiteePullRequestStep.java deleted file mode 100644 index c4cb50b..0000000 --- a/src/main/java/com/gitee/jenkins/workflow/AcceptGiteePullRequestStep.java +++ /dev/null @@ -1,141 +0,0 @@ -package com.gitee.jenkins.workflow; - -import static com.gitee.jenkins.connection.GiteeConnectionProperty.getClient; - -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.ws.rs.ProcessingException; -import javax.ws.rs.WebApplicationException; - -import org.apache.commons.lang.StringUtils; -import org.jenkinsci.plugins.workflow.steps.*; - -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.export.ExportedBean; - -import com.gitee.jenkins.cause.GiteeWebHookCause; -import com.gitee.jenkins.gitee.api.GiteeClient; -import com.gitee.jenkins.gitee.api.model.PullRequest; -import com.google.common.collect.ImmutableSet; - -import hudson.Extension; -import hudson.model.Run; -import hudson.model.TaskListener; - -/** - * @author Robin Müller - */ -@ExportedBean -public class AcceptGiteePullRequestStep extends Step { - - private static final Logger LOGGER = Logger.getLogger(AcceptGiteePullRequestStep.class.getName()); - - private String mergeCommitMessage; - - @DataBoundConstructor - public AcceptGiteePullRequestStep(String mergeCommitMessage) { - this.mergeCommitMessage = StringUtils.isEmpty(mergeCommitMessage) ? null : mergeCommitMessage; - } - - @Override - public StepExecution start(StepContext context) throws Exception { - return new AcceptGiteePullRequestStepExecution(context, this); - } - - public String getMergeCommitMessage() { - return mergeCommitMessage; - } - - @DataBoundSetter - public void setMergeCommitMessage(String mergeCommitMessage) { - this.mergeCommitMessage = StringUtils.isEmpty(mergeCommitMessage) ? null : mergeCommitMessage; - } - - public static class AcceptGiteePullRequestStepExecution extends AbstractSynchronousStepExecution { - private static final long serialVersionUID = 1; - - private final transient Run run; - - private final transient AcceptGiteePullRequestStep step; - - AcceptGiteePullRequestStepExecution(StepContext context, AcceptGiteePullRequestStep step) throws Exception { - super(context); - this.step = step; - run = context.get(Run.class); - } - - @Override - protected Void run() throws Exception { - GiteeWebHookCause cause = run.getCause(GiteeWebHookCause.class); - if (cause != null) { - PullRequest pullRequest = cause.getData().getPullRequest(); - if (pullRequest != null) { - GiteeClient client = getClient(run); - if (client == null) { - println("No Gitee connection configured"); - } else { - try { - client.acceptPullRequest(pullRequest, step.mergeCommitMessage, false); - } catch (WebApplicationException | ProcessingException e) { - printf("Failed to accept pull request for project '%s': %s%n", pullRequest.getProjectId(), e.getMessage()); - LOGGER.log(Level.SEVERE, String.format("Failed to accept pull request for project '%s'", pullRequest.getProjectId()), e); - } - } - } - } - return null; - } - - private void println(String message) { - TaskListener listener = getTaskListener(); - if (listener == null) { - LOGGER.log(Level.FINE, "failed to print message {0} due to null TaskListener", message); - } else { - listener.getLogger().println(message); - } - } - - private void printf(String message, Object... args) { - TaskListener listener = getTaskListener(); - if (listener == null) { - LOGGER.log(Level.FINE, "failed to print message {0} due to null TaskListener", String.format(message, args)); - } else { - listener.getLogger().printf(message, args); - } - } - - private TaskListener getTaskListener() { - StepContext context = getContext(); - if (!context.isReady()) { - return null; - } - try { - return context.get(TaskListener.class); - } catch (Exception x) { - return null; - } - } - } - - @Extension - public static final class DescriptorImpl extends StepDescriptor { - - @Override - public String getDisplayName() { - return "Accept Gitee Pull Request"; - } - - @Override - public String getFunctionName() { - return "acceptGiteeMR"; - } - - @Override - public Set> getRequiredContext() { - return ImmutableSet.of(TaskListener.class, Run.class); - } - } -} diff --git a/src/main/java/com/gitee/jenkins/workflow/AddGiteePullRequestCommentStep.java b/src/main/java/com/gitee/jenkins/workflow/AddGiteePullRequestCommentStep.java deleted file mode 100644 index 2d91164..0000000 --- a/src/main/java/com/gitee/jenkins/workflow/AddGiteePullRequestCommentStep.java +++ /dev/null @@ -1,144 +0,0 @@ -package com.gitee.jenkins.workflow; - -import static com.gitee.jenkins.connection.GiteeConnectionProperty.getClient; - -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -import javax.ws.rs.ProcessingException; -import javax.ws.rs.WebApplicationException; - -import com.gitee.jenkins.gitee.api.model.PullRequest; -import org.apache.commons.lang.StringUtils; -import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousStepExecution; -import org.jenkinsci.plugins.workflow.steps.Step; -import org.jenkinsci.plugins.workflow.steps.StepContext; -import org.jenkinsci.plugins.workflow.steps.StepDescriptor; -import org.jenkinsci.plugins.workflow.steps.StepExecution; -import org.kohsuke.stapler.DataBoundConstructor; -import org.kohsuke.stapler.DataBoundSetter; -import org.kohsuke.stapler.export.ExportedBean; - -import com.gitee.jenkins.cause.GiteeWebHookCause; -import com.gitee.jenkins.gitee.api.GiteeClient; -import com.google.common.collect.ImmutableSet; - -import hudson.Extension; -import hudson.model.Run; -import hudson.model.TaskListener; - -/** - * @author Robin Müller - */ -@ExportedBean -public class AddGiteePullRequestCommentStep extends Step { - - private static final Logger LOGGER = Logger.getLogger(AddGiteePullRequestCommentStep.class.getName()); - - private String comment; - - @DataBoundConstructor - public AddGiteePullRequestCommentStep(String comment) { - this.comment = StringUtils.isEmpty(comment) ? null : comment; - } - - @Override - public StepExecution start(StepContext context) throws Exception { - return new AddGiteePullRequestCommentStepExecution(context, this); - } - - public String getComment() { - return comment; - } - - @DataBoundSetter - public void setComment(String comment) { - this.comment = StringUtils.isEmpty(comment) ? null : comment; - } - - public static class AddGiteePullRequestCommentStepExecution extends AbstractSynchronousStepExecution { - private static final long serialVersionUID = 1; - - private final transient Run run; - - private final transient AddGiteePullRequestCommentStep step; - - AddGiteePullRequestCommentStepExecution(StepContext context, AddGiteePullRequestCommentStep step) throws Exception { - super(context); - this.step = step; - run = context.get(Run.class); - } - - @Override - protected Void run() throws Exception { - GiteeWebHookCause cause = run.getCause(GiteeWebHookCause.class); - if (cause != null) { - PullRequest pullRequest = cause.getData().getPullRequest(); - if (pullRequest != null) { - GiteeClient client = getClient(run); - if (client == null) { - println("No Gitee connection configured"); - } else { - try { - client.createPullRequestNote(pullRequest, step.getComment()); - } catch (WebApplicationException | ProcessingException e) { - printf("Failed to add comment on Pull Request for project '%s': %s%n", pullRequest.getProjectId(), e.getMessage()); - LOGGER.log(Level.SEVERE, String.format("Failed to add comment on Pull Request for project '%s'", pullRequest.getProjectId()), e); - } - } - } - } - return null; - } - - private void println(String message) { - TaskListener listener = getTaskListener(); - if (listener == null) { - LOGGER.log(Level.FINE, "failed to print message {0} due to null TaskListener", message); - } else { - listener.getLogger().println(message); - } - } - - private void printf(String message, Object... args) { - TaskListener listener = getTaskListener(); - if (listener == null) { - LOGGER.log(Level.FINE, "failed to print message {0} due to null TaskListener", String.format(message, args)); - } else { - listener.getLogger().printf(message, args); - } - } - - private TaskListener getTaskListener() { - StepContext context = getContext(); - if (!context.isReady()) { - return null; - } - try { - return context.get(TaskListener.class); - } catch (Exception x) { - return null; - } - } - } - - @Extension - public static final class DescriptorImpl extends StepDescriptor { - - @Override - public String getDisplayName() { - return "Add comment on Gitee Pull Request"; - } - - @Override - public String getFunctionName() { - return "addGiteeMRComment"; - } - - @Override - public Set> getRequiredContext() { - return ImmutableSet.of(TaskListener.class, Run.class); - } - } -} diff --git a/src/main/resources/com/gitee/jenkins/cause/GiteeWebHookCause/description.jelly b/src/main/resources/com/gitee/jenkins/cause/GiteeWebHookCause/description.jelly index 37e85ef..acde758 100644 --- a/src/main/resources/com/gitee/jenkins/cause/GiteeWebHookCause/description.jelly +++ b/src/main/resources/com/gitee/jenkins/cause/GiteeWebHookCause/description.jelly @@ -1,4 +1,6 @@ - + + + diff --git a/src/main/resources/com/gitee/jenkins/config/GiteeApiTokenConfig/credentials.jelly b/src/main/resources/com/gitee/jenkins/config/GiteeApiTokenConfig/credentials.jelly new file mode 100644 index 0000000..1af5b85 --- /dev/null +++ b/src/main/resources/com/gitee/jenkins/config/GiteeApiTokenConfig/credentials.jelly @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/src/main/resources/com/gitee/jenkins/connection/GiteeApiTokenImpl/credentials.properties b/src/main/resources/com/gitee/jenkins/config/GiteeApiTokenConfig/credentials.properties similarity index 100% rename from src/main/resources/com/gitee/jenkins/connection/GiteeApiTokenImpl/credentials.properties rename to src/main/resources/com/gitee/jenkins/config/GiteeApiTokenConfig/credentials.properties diff --git a/src/main/resources/com/gitee/jenkins/connection/GiteeApiTokenImpl/credentials_zh_CN.properties b/src/main/resources/com/gitee/jenkins/config/GiteeApiTokenConfig/credentials_zh_CN.properties similarity index 100% rename from src/main/resources/com/gitee/jenkins/connection/GiteeApiTokenImpl/credentials_zh_CN.properties rename to src/main/resources/com/gitee/jenkins/config/GiteeApiTokenConfig/credentials_zh_CN.properties diff --git a/src/main/resources/com/gitee/jenkins/config/GiteeConnectionConfig/config.jelly b/src/main/resources/com/gitee/jenkins/config/GiteeConnectionConfig/config.jelly new file mode 100644 index 0000000..9599106 --- /dev/null +++ b/src/main/resources/com/gitee/jenkins/config/GiteeConnectionConfig/config.jelly @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/gitee/jenkins/connection/GiteeConnectionConfig/config.properties b/src/main/resources/com/gitee/jenkins/config/GiteeConnectionConfig/config.properties similarity index 81% rename from src/main/resources/com/gitee/jenkins/connection/GiteeConnectionConfig/config.properties rename to src/main/resources/com/gitee/jenkins/config/GiteeConnectionConfig/config.properties index 544c0c5..1d12a0b 100644 --- a/src/main/resources/com/gitee/jenkins/connection/GiteeConnectionConfig/config.properties +++ b/src/main/resources/com/gitee/jenkins/config/GiteeConnectionConfig/config.properties @@ -1,5 +1,3 @@ -Gitee.connections=Gitee connections -Enable.authentication.end.point=Enable authentication for '/project' end-point Connection.name=Connection name Gitee.host.URL=Gitee host URL Gitee.host.desc=The complete URL to the Gitee server (e.g. http://gitee.com) @@ -12,4 +10,3 @@ Read.timeout.seconds=Read timeout (in seconds) Read.timeout.desc=The time to wait while receiving the response Test.Connection=Test Connection Testing=Testing... -Gitee.config=Gitee Configuration diff --git a/src/main/resources/com/gitee/jenkins/connection/GiteeConnectionConfig/config_zh_CN.properties b/src/main/resources/com/gitee/jenkins/config/GiteeConnectionConfig/config_zh_CN.properties similarity index 84% rename from src/main/resources/com/gitee/jenkins/connection/GiteeConnectionConfig/config_zh_CN.properties rename to src/main/resources/com/gitee/jenkins/config/GiteeConnectionConfig/config_zh_CN.properties index aee8561..cf1c34f 100644 --- a/src/main/resources/com/gitee/jenkins/connection/GiteeConnectionConfig/config_zh_CN.properties +++ b/src/main/resources/com/gitee/jenkins/config/GiteeConnectionConfig/config_zh_CN.properties @@ -1,5 +1,3 @@ -Gitee.connections=Gitee \u94FE\u63A5 -Enable.authentication.end.point=\u5F00\u542F '/project' \u8DEF\u7531\u9A8C\u8BC1 Connection.name=\u94FE\u63A5\u540D Gitee.host.URL=Gitee \u57DF\u540D URL Gitee.host.desc=Gitee \u57DF\u540D\u5B8C\u6574URL\u5730\u5740 (\u4F8B\u5982 https://gitee.com) @@ -12,4 +10,3 @@ Read.timeout.seconds=\u8BFB\u53D6\u8D85\u65F6\u65F6\u95F4\uFF0C\u5355\u4F4D\u79D Read.timeout.desc=\u94FE\u63A5\u8BFB\u53D6\u8D85\u65F6\u65F6\u95F4 Test.Connection=\u6D4B\u8BD5\u94FE\u63A5 Testing=\u6D4B\u8BD5\u4E2D... -Gitee.config=Gitee \u914D\u7F6E diff --git a/src/main/resources/com/gitee/jenkins/config/GiteeGlobalConfig/config.jelly b/src/main/resources/com/gitee/jenkins/config/GiteeGlobalConfig/config.jelly new file mode 100644 index 0000000..ffee4d2 --- /dev/null +++ b/src/main/resources/com/gitee/jenkins/config/GiteeGlobalConfig/config.jelly @@ -0,0 +1,15 @@ + + + + + + +
+ +
+
+
+
+
+
diff --git a/src/main/resources/com/gitee/jenkins/config/GiteeGlobalConfig/config.properties b/src/main/resources/com/gitee/jenkins/config/GiteeGlobalConfig/config.properties new file mode 100644 index 0000000..74bc838 --- /dev/null +++ b/src/main/resources/com/gitee/jenkins/config/GiteeGlobalConfig/config.properties @@ -0,0 +1,2 @@ +Gitee.config=Gitee Configuration +Gitee.connections=Gitee connections diff --git a/src/main/resources/com/gitee/jenkins/config/GiteeGlobalConfig/config_zh_CN.properties b/src/main/resources/com/gitee/jenkins/config/GiteeGlobalConfig/config_zh_CN.properties new file mode 100644 index 0000000..8faea5b --- /dev/null +++ b/src/main/resources/com/gitee/jenkins/config/GiteeGlobalConfig/config_zh_CN.properties @@ -0,0 +1,3 @@ +Gitee.config=Gitee \u914D\u7F6E +Gitee.connections=Gitee \u94FE\u63A5 + diff --git a/src/main/resources/com/gitee/jenkins/config/GiteeItemConfig/config.jelly b/src/main/resources/com/gitee/jenkins/config/GiteeItemConfig/config.jelly new file mode 100644 index 0000000..f5ec809 --- /dev/null +++ b/src/main/resources/com/gitee/jenkins/config/GiteeItemConfig/config.jelly @@ -0,0 +1,6 @@ + + + + + + diff --git a/src/main/resources/com/gitee/jenkins/connection/GiteeConnectionProperty/config.properties b/src/main/resources/com/gitee/jenkins/config/GiteeItemConfig/config.properties similarity index 100% rename from src/main/resources/com/gitee/jenkins/connection/GiteeConnectionProperty/config.properties rename to src/main/resources/com/gitee/jenkins/config/GiteeItemConfig/config.properties diff --git a/src/main/resources/com/gitee/jenkins/connection/GiteeConnectionProperty/config_zh_CN.properties b/src/main/resources/com/gitee/jenkins/config/GiteeItemConfig/config_zh_CN.properties similarity index 100% rename from src/main/resources/com/gitee/jenkins/connection/GiteeConnectionProperty/config_zh_CN.properties rename to src/main/resources/com/gitee/jenkins/config/GiteeItemConfig/config_zh_CN.properties diff --git a/src/main/resources/com/gitee/jenkins/connection/Messages.properties b/src/main/resources/com/gitee/jenkins/config/Messages.properties similarity index 91% rename from src/main/resources/com/gitee/jenkins/connection/Messages.properties rename to src/main/resources/com/gitee/jenkins/config/Messages.properties index 8d56ee0..af3e17d 100644 --- a/src/main/resources/com/gitee/jenkins/connection/Messages.properties +++ b/src/main/resources/com/gitee/jenkins/config/Messages.properties @@ -6,4 +6,4 @@ connectionTimeout.required=Connection timeout is required readTimeout.required=Read timeout is required connection.success=Success connection.error=Client error: {0} -GiteeApiToken.name=Gitee API token +GiteeApiToken.name=Gitee API token \ No newline at end of file diff --git a/src/main/resources/com/gitee/jenkins/connection/Messages_zh_CN.properties b/src/main/resources/com/gitee/jenkins/config/Messages_zh_CN.properties similarity index 100% rename from src/main/resources/com/gitee/jenkins/connection/Messages_zh_CN.properties rename to src/main/resources/com/gitee/jenkins/config/Messages_zh_CN.properties diff --git a/src/main/resources/com/gitee/jenkins/connection/GiteeApiTokenImpl/credentials.jelly b/src/main/resources/com/gitee/jenkins/connection/GiteeApiTokenImpl/credentials.jelly deleted file mode 100644 index 2950378..0000000 --- a/src/main/resources/com/gitee/jenkins/connection/GiteeApiTokenImpl/credentials.jelly +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/src/main/resources/com/gitee/jenkins/connection/GiteeConnectionConfig/config.jelly b/src/main/resources/com/gitee/jenkins/connection/GiteeConnectionConfig/config.jelly deleted file mode 100644 index 5d59bf8..0000000 --- a/src/main/resources/com/gitee/jenkins/connection/GiteeConnectionConfig/config.jelly +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
-
-
-
-
diff --git a/src/main/resources/com/gitee/jenkins/connection/GiteeConnectionProperty/config.jelly b/src/main/resources/com/gitee/jenkins/connection/GiteeConnectionProperty/config.jelly deleted file mode 100644 index 3966a73..0000000 --- a/src/main/resources/com/gitee/jenkins/connection/GiteeConnectionProperty/config.jelly +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/main/resources/com/gitee/jenkins/cause/Messages.properties b/src/main/resources/com/gitee/jenkins/enums/Messages.properties similarity index 80% rename from src/main/resources/com/gitee/jenkins/cause/Messages.properties rename to src/main/resources/com/gitee/jenkins/enums/Messages.properties index a1311ab..fdd7905 100644 --- a/src/main/resources/com/gitee/jenkins/cause/Messages.properties +++ b/src/main/resources/com/gitee/jenkins/enums/Messages.properties @@ -5,5 +5,3 @@ GiteeWebHookCause.ShortDescription.PullRequestHook_plain=Triggered by Gitee Pull GiteeWebHookCause.ShortDescription.NoteHook_html=Triggered by {0} Gitee Pull Request #{1}: {2} => {3} GiteeWebHookCause.ShortDescription.NoteHook_plain=Triggered by {0} Gitee Pull Request #{1}: {2} => {3} GiteeWebHookCause.ShortDescription.Commit_comment=Started by Gitee comment by {0} -GiteeWebHookCause.ShortDescription.PipelineHook_noStatus=Started by Gitee Pipeline event -GiteeWebHookCause.ShortDescription.PipelineHook=Started by Gitee Pipeline event {0} diff --git a/src/main/resources/com/gitee/jenkins/cause/Messages_zh_CN.properties b/src/main/resources/com/gitee/jenkins/enums/Messages_zh_CN.properties similarity index 82% rename from src/main/resources/com/gitee/jenkins/cause/Messages_zh_CN.properties rename to src/main/resources/com/gitee/jenkins/enums/Messages_zh_CN.properties index b86ca36..66e735e 100644 --- a/src/main/resources/com/gitee/jenkins/cause/Messages_zh_CN.properties +++ b/src/main/resources/com/gitee/jenkins/enums/Messages_zh_CN.properties @@ -5,5 +5,3 @@ GiteeWebHookCause.ShortDescription.PullRequestHook_plain=\u7531 Gitee Pull Reque GiteeWebHookCause.ShortDescription.NoteHook_html=\u7531 {0} Gitee Pull Request #{1}: {2} => {3} \u89E6\u53D1 GiteeWebHookCause.ShortDescription.NoteHook_plain=\u7531 {0} Gitee Pull Request #{1}: {2} => {3} \u89E6\u53D1 GiteeWebHookCause.ShortDescription.Commit_comment=Gitee \u7528\u6237 {0} \u8BC4\u8BBA\u63D0\u4EA4\u89E6\u53D1\u6784\u5EFA -GiteeWebHookCause.ShortDescription.PipelineHook_noStatus=\u7531 Gitee Pipeline \u89E6\u53D1 -GiteeWebHookCause.ShortDescription.PipelineHook=\u7531 Gitee Pipeline {0} \u89E6\u53D1 diff --git a/src/main/resources/com/gitee/jenkins/publisher/GiteeCommitStatusPublisher/config.jelly b/src/main/resources/com/gitee/jenkins/publisher/GiteeCommitStatusPublisher/config.jelly deleted file mode 100644 index 017a824..0000000 --- a/src/main/resources/com/gitee/jenkins/publisher/GiteeCommitStatusPublisher/config.jelly +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/main/resources/com/gitee/jenkins/publisher/GiteeMessagePublisher/config.jelly b/src/main/resources/com/gitee/jenkins/publisher/GiteeMessagePublisher/config.jelly deleted file mode 100644 index 5975a96..0000000 --- a/src/main/resources/com/gitee/jenkins/publisher/GiteeMessagePublisher/config.jelly +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/com/gitee/jenkins/publisher/Messages.properties b/src/main/resources/com/gitee/jenkins/publisher/Messages.properties index a31e300..a48b9f5 100644 --- a/src/main/resources/com/gitee/jenkins/publisher/Messages.properties +++ b/src/main/resources/com/gitee/jenkins/publisher/Messages.properties @@ -1,4 +1,2 @@ -GiteeCommitStatusPublisher.DisplayName=Publish build status to Gitee -name.required=Build name required. -GiteeMessagePublisher.DisplayName=Add note with build status on Gitee pull requests -GiteeAcceptPullRequestPublisher.DisplayName=Accept Gitee pull request on success +PullRequestBuildStatusPublisher.DisplayName=Add note with build status on Gitee pull requests +AcceptPullRequestPublisher.DisplayName=Accept Gitee pull request on success \ No newline at end of file diff --git a/src/main/resources/com/gitee/jenkins/publisher/Messages_zh_CN.properties b/src/main/resources/com/gitee/jenkins/publisher/Messages_zh_CN.properties index 9c79e1a..82a68ed 100644 --- a/src/main/resources/com/gitee/jenkins/publisher/Messages_zh_CN.properties +++ b/src/main/resources/com/gitee/jenkins/publisher/Messages_zh_CN.properties @@ -1,4 +1,2 @@ -GiteeCommitStatusPublisher.DisplayName=\u53D1\u5E03\u6784\u5EFA\u72B6\u6001\u5230 Gitee -name.required=\u8BF7\u8F93\u5165\u6784\u5EFA\u540D\u79F0\u3002 -GiteeMessagePublisher.DisplayName=\u5C06\u6784\u5EFA\u72B6\u6001\u8BC4\u8BBA\u5230 Gitee Pull Request \u4E2D -GiteeAcceptPullRequestPublisher.DisplayName=\u5F53\u6784\u5EFA\u6210\u529F\u81EA\u52A8\u5408\u5E76 Gitee \u7684 Pull Request +PullRequestBuildStatusPublisher.DisplayName=\u5C06\u6784\u5EFA\u72B6\u6001\u8BC4\u8BBA\u5230 Gitee Pull Request \u4E2D +AcceptPullRequestPublisher.DisplayName=\u5F53\u6784\u5EFA\u6210\u529F\u81EA\u52A8\u5408\u5E76 Gitee \u7684 Pull Request diff --git a/src/main/resources/com/gitee/jenkins/publisher/PullRequestBuildStatusPublisher/config.jelly b/src/main/resources/com/gitee/jenkins/publisher/PullRequestBuildStatusPublisher/config.jelly new file mode 100644 index 0000000..e1b5e53 --- /dev/null +++ b/src/main/resources/com/gitee/jenkins/publisher/PullRequestBuildStatusPublisher/config.jelly @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/com/gitee/jenkins/publisher/GiteeMessagePublisher/config.properties b/src/main/resources/com/gitee/jenkins/publisher/PullRequestBuildStatusPublisher/config.properties similarity index 100% rename from src/main/resources/com/gitee/jenkins/publisher/GiteeMessagePublisher/config.properties rename to src/main/resources/com/gitee/jenkins/publisher/PullRequestBuildStatusPublisher/config.properties diff --git a/src/main/resources/com/gitee/jenkins/publisher/GiteeMessagePublisher/config_zh_CN.properties b/src/main/resources/com/gitee/jenkins/publisher/PullRequestBuildStatusPublisher/config_zh_CN.properties similarity index 100% rename from src/main/resources/com/gitee/jenkins/publisher/GiteeMessagePublisher/config_zh_CN.properties rename to src/main/resources/com/gitee/jenkins/publisher/PullRequestBuildStatusPublisher/config_zh_CN.properties diff --git a/src/main/resources/com/gitee/jenkins/trigger/GiteePushTrigger/config.jelly b/src/main/resources/com/gitee/jenkins/trigger/GiteePushTrigger/config.jelly deleted file mode 100644 index e189b88..0000000 --- a/src/main/resources/com/gitee/jenkins/trigger/GiteePushTrigger/config.jelly +++ /dev/null @@ -1,120 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- - - - - -
-
-
diff --git a/src/main/resources/com/gitee/jenkins/trigger/GiteeTrigger/config.jelly b/src/main/resources/com/gitee/jenkins/trigger/GiteeTrigger/config.jelly new file mode 100644 index 0000000..6364eb5 --- /dev/null +++ b/src/main/resources/com/gitee/jenkins/trigger/GiteeTrigger/config.jelly @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + +
+
+
\ No newline at end of file diff --git a/src/main/resources/com/gitee/jenkins/trigger/GiteePushTrigger/config.properties b/src/main/resources/com/gitee/jenkins/trigger/GiteeTrigger/config.properties similarity index 53% rename from src/main/resources/com/gitee/jenkins/trigger/GiteePushTrigger/config.properties rename to src/main/resources/com/gitee/jenkins/trigger/GiteeTrigger/config.properties index 390c563..c48ee04 100644 --- a/src/main/resources/com/gitee/jenkins/trigger/GiteePushTrigger/config.properties +++ b/src/main/resources/com/gitee/jenkins/trigger/GiteeTrigger/config.properties @@ -1,45 +1,29 @@ -Secret.Token=Secret Token for Gitee WebHook -Generate=Generate -Clear=Clear +Enabled.Gitee.Triggers=Enabled Gitee triggers Push=Push Events Commit.Comment=Commit Comment Events -Enable.CI.Skip=Enable [ci-skip] +Opened.Pull.Request=Opened Pull Requests Events +Updated.Pull.Request=Updated Pull Requests Events +Accepted.Pull.Request=Accepted Pull Requests Events +Closed.Pull.Request=Closed Pull Requests Events +Approved.Pull.Request=Approved Pull Requests +Tested.Pull.Request=Tested Pull Requests +Comments=Comment Pull Requests +Comment.Regex=Comment (regex) for triggering a build Build.Instruction.Filter=Build instruction filter Build.Instruction.Filter.None=None Build.Instruction.Filter.CiSkip=[ci-skip] skip build Build.Instruction.Filter.CiBuild=[ci-build] trigger build Enable.CI.SkipFroTestNotRequired=Skip ci when test not required -Enabled.Gitee.Triggers=Enabled Gitee triggers -Approved.Pull.Request=Approved Pull Requests -Tested.Pull.Request=Tested Pull Requests -Closed.Pull.Request=Closed Pull Requests Events -Accepted.Pull.Request=Accepted Pull Requests Events -Opened.Pull.Request=Opened Pull Requests Events -Updated.Pull.Request=Updated Pull Requests Events -Set.Build.Desctiption=Set build description to build cause (eg. Merge request or Git Push ) -Ignore.WIP.Merge.Requests=Ignore WIP Pull Requests -CommitNotifier.Success=Build {0} succeeded in {1} -CommitNotifier.Unstable=Build {0} found unstable in {1} -CommitNotifier.Failed=Build {0} failed in {1} -GitHubCommitNotifier.SettingCommitStatus=Setting commit status on Gitee for {0} -GiteePushTrigger.BranchesNotFound=Following patterns don''t match any branch in source repository: {0} -GiteePushTrigger.BranchesMatched=Matching {0} branch{0,choice,1#|2#s}. -GiteePushTrigger.CannotCheckBranches=Cannot connect to Gitee to check whether selected branches exist. -GiteePushTrigger.CannotConnectToGitee=Cannot connect to Gitee: {0} -GiteePushTrigger.NoSourceRepository=Repository url must be saved first. -GiteePushTrigger.LabelsNotFound=Following labels doesn''t exist in source repository: {0} -GiteePushTrigger.LabelsMatched=Matching {0} label{0,choice,1#|2#s}. +Ignore.Last.Commit.Has.Build=Ignore last commit has been build +Cancel.Same.Pull.Request.Incomplete.Build=Cancel incomplete build on same Pull Requests +Ignore.Pull.Request.Conflicts=Ignore Pull Request conflicts Allowed.branches=Allowed branches Allow.all.branches=Allow all branches to trigger this job Filter.branches.by.name=Filter branches by name Filter.branches.by.regex=Filter branches by regex -Target.Branch.Regex=Target Branch Regex -Filter.merge.request.by.label=Filter pull request by label Exclude=Exclude Include=Include -Ignore.Last.Commit.Has.Build=Ignore last commit has been build -Cancel.Same.Pull.Request.Incomplete.Build=Cancel incomplete build on same Pull Requests -Ignore.Pull.Request.Conflicts=Ignore Pull Request conflicts -Comments=Comment Pull Requests -Comment.Regex=Comment (regex) for triggering a build -Retry.Text=Jenkins please retry a build +Target.Branch.Regex=Target Branch Regex +Secret.Token=Secret Token for Gitee WebHook +Generate=Generate +Clear=Clear \ No newline at end of file diff --git a/src/main/resources/com/gitee/jenkins/trigger/GiteePushTrigger/config_zh_CN.properties b/src/main/resources/com/gitee/jenkins/trigger/GiteeTrigger/config_zh_CN.properties similarity index 54% rename from src/main/resources/com/gitee/jenkins/trigger/GiteePushTrigger/config_zh_CN.properties rename to src/main/resources/com/gitee/jenkins/trigger/GiteeTrigger/config_zh_CN.properties index 4a1e266..dd135a9 100644 --- a/src/main/resources/com/gitee/jenkins/trigger/GiteePushTrigger/config_zh_CN.properties +++ b/src/main/resources/com/gitee/jenkins/trigger/GiteeTrigger/config_zh_CN.properties @@ -1,45 +1,29 @@ -Secret.Token=Gitee WebHook \u5BC6\u7801 -Generate=\u751F\u6210 -Clear=\u6E05\u9664 +Enabled.Gitee.Triggers=Gitee \u89E6\u53D1\u6784\u5EFA\u7B56\u7565 Push=\u63A8\u9001\u4EE3\u7801 Commit.Comment=\u8BC4\u8BBA\u63D0\u4EA4\u8BB0\u5F55 -Enable.CI.Skip=\u652F\u6301 [ci-skip] \u6307\u4EE4\u8FC7\u6EE4\u6784\u5EFA -Enable.CI.SkipFroTestNotRequired=PR \u4E0D\u8981\u6C42\u5FC5\u987B\u6D4B\u8BD5\u65F6\u8FC7\u6EE4\u6784\u5EFA +Opened.Pull.Request=\u65B0\u5EFA Pull Requests +Updated.Pull.Request=\u66F4\u65B0 Pull Requests +Accepted.Pull.Request=\u63A5\u53D7 Pull Requests +Closed.Pull.Request=\u5173\u95ED Pull Requests +Approved.Pull.Request=\u5BA1\u67E5\u901A\u8FC7 Pull Requests +Tested.Pull.Request=\u6D4B\u8BD5\u901A\u8FC7 Pull Requests +Comments=\u8BC4\u8BBA Pull Requests +Comment.Regex=\u8BC4\u8BBA\u5185\u5BB9\u7684\u6B63\u5219\u8868\u8FBE\u5F0F Build.Instruction.Filter=\u6784\u5EFA\u6307\u4EE4\u8FC7\u6EE4 Build.Instruction.Filter.None=\u65E0 Build.Instruction.Filter.CiSkip=[ci-skip] \u6307\u4EE4\u8DF3\u8FC7\u6784\u5EFA Build.Instruction.Filter.CiBuild=[ci-build] \u6307\u4EE4\u89E6\u53D1\u6784\u5EFA -Enabled.Gitee.Triggers=Gitee \u89E6\u53D1\u6784\u5EFA\u7B56\u7565 -Approved.Pull.Request=\u5BA1\u67E5\u901A\u8FC7 Pull Requests -Tested.Pull.Request=\u6D4B\u8BD5\u901A\u8FC7 Pull Requests -Closed.Pull.Request=\u5173\u95ED Pull Requests -Accepted.Pull.Request=\u63A5\u53D7 Pull Requests -Opened.Pull.Request=\u65B0\u5EFA Pull Requests -Updated.Pull.Request=\u66F4\u65B0 Pull Requests -Ignore.WIP.Merge.Requests=\u8FC7\u6EE4\u6B63\u5728\u8FDB\u884C\u6784\u5EFA\u7684Pull Requests -Set.Build.Desctiption=\u8BBE\u7F6E\u6784\u5EFA\u63CF\u8FF0 -CommitNotifier.Success=\u6784\u5EFA {0} \u6210\u529F\u4E8E {1} -CommitNotifier.Unstable=\u6784\u5EFA {0} \u53D1\u73B0 {1} \u4E0D\u7A33\u5B9A -CommitNotifier.Failed=\u6784\u5EFA {0} \u5931\u8D25\u4E8E {1} -GitHubCommitNotifier.SettingCommitStatus=\u6B63\u5728\u4E3A {0} \u8BBE\u7F6E\u63D0\u4EA4\u72B6\u6001 -GiteePushTrigger.BranchesNotFound=\u4EE5\u4E0B\u6A21\u5F0F\u5339\u914D\u4E0D\u5230\u76EE\u6807\u4ED3\u5E93\u7684\u4EFB\u610F\u5206\u652F\uFF1A{0} -GiteePushTrigger.BranchesMatched=\u5339\u914D {0} \u5206\u652F {0,choice,1#|2#s}\u3002 -GiteePushTrigger.CannotCheckBranches=\u65E0\u6CD5\u94FE\u63A5\u5230 Gitee \u68C0\u67E5\u6240\u9009\u5206\u652F\u662F\u5426\u5B58\u5728\u3002 -GiteePushTrigger.CannotConnectToGitee=\u65E0\u6CD5\u94FE\u63A5\u5230 Gitee \uFF1A {0} -GiteePushTrigger.NoSourceRepository=\u8BF7\u5148\u4FDD\u5B58\u4ED3\u5E93 URL \u5730\u5740\u3002 -GiteePushTrigger.LabelsNotFound=\u4EE5\u4E0B\u6807\u7B7E\u4E0D\u5728\u76EE\u6807\u4ED3\u5E93\u4E2D \uFF1A{0} -GiteePushTrigger.LabelsMatched=\u5339\u914D {0} \u6807\u7B7E {0,choice,1#|2#s} \u3002 +Enable.CI.SkipFroTestNotRequired=PR \u4E0D\u8981\u6C42\u5FC5\u987B\u6D4B\u8BD5\u65F6\u8FC7\u6EE4\u6784\u5EFA +Ignore.Last.Commit.Has.Build=\u8FC7\u6EE4\u5DF2\u7ECF\u6784\u5EFA\u7684 Commit \u7248\u672C +Cancel.Same.Pull.Request.Incomplete.Build=\u53D6\u6D88\u76F8\u540C Pull Requests \u672A\u5B8C\u6210\u6784\u5EFA +Ignore.Pull.Request.Conflicts=\u5FFD\u7565 Pull Request \u51B2\u7A81 Allowed.branches=\u5141\u8BB8\u89E6\u53D1\u6784\u5EFA\u7684\u5206\u652F Allow.all.branches=\u5141\u8BB8\u6240\u6709\u5206\u652F\u89E6\u53D1\u6784\u5EFA Filter.branches.by.name=\u6839\u636E\u5206\u652F\u540D\u8FC7\u6EE4 Filter.branches.by.regex=\u6839\u636E\u6B63\u5219\u8868\u8FBE\u5F0F\u8FC7\u6EE4\u5206\u652F -Target.Branch.Regex=\u76EE\u6807\u5206\u652F\u7684\u6B63\u5219\u8868\u8FBE\u5F0F -Filter.merge.request.by.label=\u6839\u636E\u6807\u7B7E\u8FC7\u6EE4PR Exclude=\u6392\u9664 Include=\u5305\u62EC -Ignore.Last.Commit.Has.Build=\u8FC7\u6EE4\u5DF2\u7ECF\u6784\u5EFA\u7684 Commit \u7248\u672C -Cancel.Same.Pull.Request.Incomplete.Build=\u53D6\u6D88\u76F8\u540C Pull Requests \u672A\u5B8C\u6210\u6784\u5EFA -Ignore.Pull.Request.Conflicts=\u5FFD\u7565 Pull Request \u51B2\u7A81 -Comments=\u8BC4\u8BBA Pull Requests -Comment.Regex=\u8BC4\u8BBA\u5185\u5BB9\u7684\u6B63\u5219\u8868\u8FBE\u5F0F -Retry.Text=Jenkins please retry a build +Target.Branch.Regex=\u76EE\u6807\u5206\u652F\u7684\u6B63\u5219\u8868\u8FBE\u5F0F +Secret.Token=Gitee WebHook \u5BC6\u7801 +Generate=\u751F\u6210 +Clear=\u6E05\u9664 \ No newline at end of file diff --git a/src/main/resources/com/gitee/jenkins/trigger/GiteeWebHookPollingAction/index.jelly b/src/main/resources/com/gitee/jenkins/trigger/GiteeWebHookPollingAction/index.jelly deleted file mode 100644 index 0d244e6..0000000 --- a/src/main/resources/com/gitee/jenkins/trigger/GiteeWebHookPollingAction/index.jelly +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - -

${%Last Gitee Push}

- - - - ${%Polling has not run yet.} - - -
-            
-            ${it.writeLogTo(output)}
-          
-
-
-
-
-
diff --git a/src/main/resources/com/gitee/jenkins/trigger/help.jelly b/src/main/resources/com/gitee/jenkins/trigger/help.jelly index 786ede9..bb61128 100644 --- a/src/main/resources/com/gitee/jenkins/trigger/help.jelly +++ b/src/main/resources/com/gitee/jenkins/trigger/help.jelly @@ -1,4 +1,4 @@
- Configure Gitee to deliver a POST request to your Jenkins instance like Gitee CI. + Configure Gitee to deliver a POST request to your Jenkins instance like Gitee CI.
diff --git a/src/main/resources/com/gitee/jenkins/webhook/status/failed.png b/src/main/resources/com/gitee/jenkins/webhook/status/failed.png deleted file mode 100644 index e751ade..0000000 Binary files a/src/main/resources/com/gitee/jenkins/webhook/status/failed.png and /dev/null differ diff --git a/src/main/resources/com/gitee/jenkins/webhook/status/running.png b/src/main/resources/com/gitee/jenkins/webhook/status/running.png deleted file mode 100644 index 2398b4d..0000000 Binary files a/src/main/resources/com/gitee/jenkins/webhook/status/running.png and /dev/null differ diff --git a/src/main/resources/com/gitee/jenkins/webhook/status/success.png b/src/main/resources/com/gitee/jenkins/webhook/status/success.png deleted file mode 100644 index 83eef5c..0000000 Binary files a/src/main/resources/com/gitee/jenkins/webhook/status/success.png and /dev/null differ diff --git a/src/main/resources/com/gitee/jenkins/webhook/status/unknown.png b/src/main/resources/com/gitee/jenkins/webhook/status/unknown.png deleted file mode 100644 index 04a43e8..0000000 Binary files a/src/main/resources/com/gitee/jenkins/webhook/status/unknown.png and /dev/null differ diff --git a/src/main/resources/com/gitee/jenkins/webhook/status/unstable.png b/src/main/resources/com/gitee/jenkins/webhook/status/unstable.png deleted file mode 100644 index bd5f526..0000000 Binary files a/src/main/resources/com/gitee/jenkins/webhook/status/unstable.png and /dev/null differ diff --git a/src/main/resources/com/gitee/jenkins/workflow/AddGiteePullRequestCommentStep/config.jelly b/src/main/resources/com/gitee/jenkins/workflow/AddGiteePullRequestCommentStep/config.jelly deleted file mode 100644 index 081a387..0000000 --- a/src/main/resources/com/gitee/jenkins/workflow/AddGiteePullRequestCommentStep/config.jelly +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/src/main/webapp/help/help-messagesOnResult_zh_CN.html b/src/main/webapp/help/help-messagesOnResult_zh_CN.html deleted file mode 100644 index b9e81cc..0000000 --- a/src/main/webapp/help/help-messagesOnResult_zh_CN.html +++ /dev/null @@ -1,4 +0,0 @@ -
-

允许评论构建结构到 Gitee Pull Request.

-

您可以构建成功,失败或者中断自定义评论信息。

-
diff --git a/src/main/webapp/help/help-messagesOnResult.html b/src/main/webapp/help/help-pullRequestBuildStatus.html similarity index 66% rename from src/main/webapp/help/help-messagesOnResult.html rename to src/main/webapp/help/help-pullRequestBuildStatus.html index de90c52..ad9fdc9 100644 --- a/src/main/webapp/help/help-messagesOnResult.html +++ b/src/main/webapp/help/help-pullRequestBuildStatus.html @@ -1,4 +1,4 @@
-

Enable sending message to Gitee Pull Request.

+

Enable sending build status to Gitee Pull Request.

You can change default message on success, failure and abort. (with support environment variables)

diff --git a/src/main/webapp/help/help-pullRequestBuildStatus_zh_CN.html b/src/main/webapp/help/help-pullRequestBuildStatus_zh_CN.html new file mode 100644 index 0000000..a57cdeb --- /dev/null +++ b/src/main/webapp/help/help-pullRequestBuildStatus_zh_CN.html @@ -0,0 +1,4 @@ +
+

允许评论构建结果到 Gitee Pull Request.

+

您可以自定义构建成功,失败或者中断自定义评论信息。(支持环境变量)

+
diff --git a/src/main/webapp/help/help-send-result-to-gitee.html b/src/main/webapp/help/help-send-result-to-gitee.html deleted file mode 100644 index ca108cf..0000000 --- a/src/main/webapp/help/help-send-result-to-gitee.html +++ /dev/null @@ -1,3 +0,0 @@ -
- Send build result to Gitee. It will be visible in the commit and/or pull request UI as appropriate. You must have at least one Gitee connection/server configured in the Jenkins global configuration. If you have more than one, select the appropriate one from the 'Gitee connection' dropdown menu in the job configuration. -
diff --git a/src/main/webapp/help/help-send-result-to-gitee_zh_CN.html b/src/main/webapp/help/help-send-result-to-gitee_zh_CN.html deleted file mode 100644 index 6f2644f..0000000 --- a/src/main/webapp/help/help-send-result-to-gitee_zh_CN.html +++ /dev/null @@ -1,6 +0,0 @@ -
- Send build result to Gitee. - It will be visible in the commit and/or pull request UI as appropriate. - You must have at least one Gitee connection/server configured in the Jenkins global configuration. - If you have more than one, select the appropriate one from the 'Gitee connection' dropdown menu in the job configuration. -
diff --git a/src/main/webapp/help/help-wip-pull-request.html b/src/main/webapp/help/help-wip-pull-request.html deleted file mode 100644 index 04ff1d7..0000000 --- a/src/main/webapp/help/help-wip-pull-request.html +++ /dev/null @@ -1,3 +0,0 @@ -
- Ignore WIP Pull Requests -
diff --git a/src/main/webapp/help/help-wip-pull-request_zh_CN.html b/src/main/webapp/help/help-wip-pull-request_zh_CN.html deleted file mode 100644 index 92184b4..0000000 --- a/src/main/webapp/help/help-wip-pull-request_zh_CN.html +++ /dev/null @@ -1,3 +0,0 @@ -
- 过滤正在进行构建的 Pull Request,防止同一个 PR 同时进行多次构建。 -
diff --git a/src/main/webapp/images/24x24/gitlab.png b/src/main/webapp/images/24x24/gitlab.png deleted file mode 100644 index bc2ef60..0000000 Binary files a/src/main/webapp/images/24x24/gitlab.png and /dev/null differ