diff --git a/README.md b/README.md
index 7af13d5..ca5282a 100644
--- a/README.md
+++ b/README.md
@@ -100,6 +100,8 @@ The plugin will contribute some environment variables to the build.
* **gitlabSourceProjectId**
* **gitlabTargetProjectId**
* **gitlabLastCommitId**
+* **gitlabMergeRequestAuthorEmail**
+* **gitlabMergeRequestAssigneeEmail**
## Contributing
diff --git a/pom.xml b/pom.xml
index 7d5d397..5956d5c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -77,6 +77,11 @@
java-gitlab-api
4.0.0
+
+ org.jenkins-ci.plugins.workflow
+ workflow-step-api
+ 2.14
+
diff --git a/src/main/java/org/jenkinsci/plugins/gitlab/GitLabEnvironmentContributor.java b/src/main/java/org/jenkinsci/plugins/gitlab/GitLabEnvironmentContributor.java
index 657d16e..2c705d5 100644
--- a/src/main/java/org/jenkinsci/plugins/gitlab/GitLabEnvironmentContributor.java
+++ b/src/main/java/org/jenkinsci/plugins/gitlab/GitLabEnvironmentContributor.java
@@ -22,6 +22,9 @@ public void buildEnvironmentFor(@Nonnull Run r, @Nonnull EnvVars envs,
Map variables = new HashMap<>();
variables.put("gitlabMergeRequestId", cause.getMergeRequestId() + "");
variables.put("gitlabMergeRequestIid", cause.getMergeRequestIid() + "");
+ variables.put("gitlabMergeRequestState", cause.getMergeRequestState() + "");
+ variables.put("gitlabMergeRequestAuthorEmail", cause.getAuthorEmail());
+ variables.put("gitlabMergeRequestAssigneeEmail", cause.getAssigneeEmail());
variables.put("gitlabSourceName", cause.getSourceName());
variables.put("gitlabSourceRepository", cause.getSourceRepository());
variables.put("gitlabSourceBranch", cause.getSourceBranch());
diff --git a/src/main/java/org/jenkinsci/plugins/gitlab/Gitlab.java b/src/main/java/org/jenkinsci/plugins/gitlab/Gitlab.java
index 4d9be52..f1e5054 100644
--- a/src/main/java/org/jenkinsci/plugins/gitlab/Gitlab.java
+++ b/src/main/java/org/jenkinsci/plugins/gitlab/Gitlab.java
@@ -31,7 +31,11 @@ public GitlabAPI get() {
}
public synchronized GitlabCommitStatus changeCommitStatus(Integer projectId, String branch, String commitHash, String commitStatus, String targetUrl) throws IOException {
- GitlabProject project = get().getProject(projectId);
- return get().createCommitStatus(project, commitHash, commitStatus, branch, "jenkins", targetUrl, null);
+ return changeCommitStatus(projectId, branch, commitHash, "Jenkins", "Gitlab MR Builder", commitStatus, targetUrl);
+ }
+
+ public synchronized GitlabCommitStatus changeCommitStatus(Integer projectId, String branch, String commitHash, String name, String description, String commitStatus, String targetUrl) throws IOException {
+ GitlabProject project = get().getProject(projectId);
+ return get().createCommitStatus(project, commitHash, commitStatus, branch, name, targetUrl, description);
}
}
diff --git a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabBuildListener.java b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabBuildListener.java
index 8cbce2f..7fd76f7 100644
--- a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabBuildListener.java
+++ b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabBuildListener.java
@@ -1,33 +1,122 @@
package org.jenkinsci.plugins.gitlab;
+import hudson.EnvVars;
import hudson.Extension;
-import hudson.model.AbstractBuild;
+import hudson.model.Result;
+import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.model.listeners.RunListener;
+import jenkins.model.Jenkins;
+import org.gitlab.api.models.GitlabMergeRequest;
+
+import java.io.IOException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
@Extension
-public class GitlabBuildListener extends RunListener {
+public class GitlabBuildListener extends RunListener> {
- @Override
- public void onStarted(AbstractBuild abstractBuild, TaskListener listener) {
- GitlabBuildTrigger trigger = GitlabBuildTrigger.getTrigger(abstractBuild.getProject());
+ private static final Logger LOGGER = Logger.getLogger(GitlabBuildListener.class.getName());
+
+ private String getRootUrl() {
+ Jenkins instance = Jenkins.getInstance();
+ return instance == null ? "" : instance.getRootUrl();
+ }
- if (trigger == null) {
+ @Override
+ public void onStarted(Run, ?> build, TaskListener listener) {
+ GitlabCause gitlabCause = build.getCause(GitlabCause.class);
+ if (gitlabCause == null || gitlabCause.getMergeRequestState().equals(GitlabMergeRequest.STATUS_MERGED)) {
return;
}
+ Gitlab gitlab = GitlabBuildTrigger.DESCRIPTOR.getGitlab();
+ try {
+ build.setDescription("" + gitlabCause.getShortDescription() + "");
+ String url = getRootUrl() + build.getUrl();
+
+ LOGGER.log(Level.INFO, "Send running status to commit: " + gitlabCause.getLastCommitId() + ", url:" + url);
+ gitlab.changeCommitStatus(gitlabCause.getTargetProjectId(), gitlabCause.getSourceBranch(), gitlabCause.getLastCommitId(), "running", url);
- trigger.getBuilder().getBuilds().onStarted(abstractBuild);
-
+ if (gitlabCause.getTrigger().getPublishBuildProgressMessages()) {
+ GitlabMergeRequestWrapper.createNote(gitlabCause.getMergeRequestId(),
+ gitlabCause.getMergeRequestIid(),
+ gitlabCause.getSourceProjectId(), "Build Started: " + "[" + url + "](" + url + ")", false, false);
+ }
+ } catch (IOException e) {
+ LOGGER.log(Level.SEVERE, "Can't update build description", e);
+ }
}
@Override
- public void onCompleted(AbstractBuild abstractBuild, TaskListener listener) {
- GitlabBuildTrigger trigger = GitlabBuildTrigger.getTrigger(abstractBuild.getProject());
-
- if (trigger == null) {
+ public void onCompleted(Run, ?> build, TaskListener listener) {
+ GitlabCause gitlabCause = build.getCause(GitlabCause.class);
+ if (gitlabCause == null || gitlabCause.getMergeRequestState().equals(GitlabMergeRequest.STATUS_MERGED)) {
return;
}
+ Gitlab gitlab = GitlabBuildTrigger.DESCRIPTOR.getGitlab();
+ try {
+ boolean stable = false;
+ StringBuilder stringBuilder = new StringBuilder();
+ Result result = build.getResult();
+ EnvVars envVars = build.getEnvironment(listener);
+ if (result == Result.SUCCESS) {
+ stable = true;
+ if (envVars.containsKey("gitlabSuccessMessage")) {
+ stringBuilder.append(envVars.get("gitlabSuccessMessage"));
+ } else {
+ stringBuilder.append(GitlabBuildTrigger.DESCRIPTOR.getSuccessMessage());
+ }
+ } else if (result == Result.UNSTABLE) {
+ if (envVars.containsKey("gitlabUnstableMessage")) {
+ stringBuilder.append(envVars.get("gitlabUnstableMessage"));
+ } else {
+ stringBuilder.append(GitlabBuildTrigger.DESCRIPTOR.getUnstableMessage());
+ }
+ } else {
+ if (envVars.containsKey("gitlabFailureMessage")) {
+ stringBuilder.append(envVars.get("gitlabFailureMessage"));
+ } else {
+ stringBuilder.append(GitlabBuildTrigger.DESCRIPTOR.getFailureMessage());
+ }
+ }
+
+ if (!gitlabCause.getTrigger().getDescriptor().isEnableBuildTriggeredMessage()) {
+ GitlabBuilds.withCustomParameters(stringBuilder, gitlabCause.getCustomParameters());
+ }
+
+ String buildUrl = getRootUrl() + build.getUrl();
+ stringBuilder
+ .append("\nBuild results available at: ")
+ .append("[")
+ .append(buildUrl)
+ .append("](")
+ .append(buildUrl)
+ .append(")"); // Link in markdown format
+
+ boolean shouldClose = false;
+ if (!stable && gitlabCause.getTrigger().getAutoCloseFailed()) {
+ shouldClose = true;
+ }
- trigger.getBuilder().getBuilds().onCompleted(abstractBuild);
+ boolean shouldMerge = false;
+ if (stable && gitlabCause.getTrigger().getAutoMergePassed()) {
+ shouldMerge = true;
+ }
+
+ if (gitlabCause.getTrigger().getPublishBuildProgressMessages() || !stable) {
+ GitlabMergeRequestWrapper.createNote(gitlabCause.getMergeRequestId(),
+ gitlabCause.getMergeRequestIid(),
+ gitlabCause.getSourceProjectId(),
+ stringBuilder.toString(),
+ shouldClose,
+ shouldMerge);
+ }
+
+ String status = (result == Result.SUCCESS) ? "success" : ((result == Result.ABORTED) ? "canceled" : "failed");
+ LOGGER.log(Level.INFO, "Send " + status + " status to commit: " + gitlabCause.getLastCommitId() + ", url:" + buildUrl);
+ gitlab.changeCommitStatus(gitlabCause.getTargetProjectId(), gitlabCause.getSourceBranch(), gitlabCause.getLastCommitId(), status, buildUrl);
+ } catch (IOException | InterruptedException e) {
+ LOGGER.log(Level.SEVERE, "Can't update build description", e);
+ }
}
}
diff --git a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabBuildTrigger.java b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabBuildTrigger.java
index 95e5d91..b58e4d4 100755
--- a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabBuildTrigger.java
+++ b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabBuildTrigger.java
@@ -8,6 +8,8 @@
import hudson.triggers.TriggerDescriptor;
import hudson.util.FormValidation;
import hudson.util.Secret;
+import jenkins.model.Jenkins;
+import jenkins.model.ParameterizedJobMixIn;
import net.sf.json.JSONObject;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
@@ -20,11 +22,12 @@
import java.util.logging.Level;
import java.util.logging.Logger;
-public final class GitlabBuildTrigger extends Trigger> {
+public final class GitlabBuildTrigger extends Trigger> {
private static final Logger LOGGER = Logger.getLogger(GitlabBuildTrigger.class.getName());
private final String projectPath;
+ private final String sourceBranchRegex;
private final String targetBranchRegex;
private final boolean useHttpUrl;
private final String assigneeFilter;
@@ -38,6 +41,7 @@ public final class GitlabBuildTrigger extends Trigger> {
@DataBoundConstructor
public GitlabBuildTrigger(String cron,
String projectPath,
+ String sourceBranchRegex,
String targetBranchRegex,
boolean useHttpUrl,
String assigneeFilter,
@@ -49,6 +53,7 @@ public GitlabBuildTrigger(String cron,
super(cron);
this.projectPath = projectPath;
+ this.sourceBranchRegex = sourceBranchRegex;
this.targetBranchRegex = targetBranchRegex;
this.useHttpUrl = useHttpUrl;
this.assigneeFilter = assigneeFilter;
@@ -60,7 +65,7 @@ public GitlabBuildTrigger(String cron,
}
@Override
- public void start(AbstractProject, ?> project, boolean newInstance) {
+ public void start(Job, ?> project, boolean newInstance) {
try {
GitlabWebhooks.addTrigger(this);
@@ -82,6 +87,9 @@ public QueueTaskFuture> startJob(GitlabCause cause) {
values.put("gitlabMergeRequestId", new StringParameterValue("gitlabMergeRequestId", String.valueOf(cause.getMergeRequestId())));
values.put("gitlabMergeRequestIid", new StringParameterValue("gitlabMergeRequestIid", String.valueOf(cause.getMergeRequestIid())));
+ values.put("gitlabMergeRequestState", new StringParameterValue("gitlabMergeRequestState", String.valueOf(cause.getMergeRequestState())));
+ values.put("gitlabMergeRequestAssigneeEmail", new StringParameterValue("gitlabMergeRequestAssigneeEmail", cause.getAssigneeEmail()));
+ values.put("gitlabMergeRequestAuthorEmail", new StringParameterValue("gitlabMergeRequestAuthorEmail", cause.getAuthorEmail()));
values.put("gitlabSourceName", new StringParameterValue("gitlabSourceName", cause.getSourceName()));
values.put("gitlabSourceRepository", new StringParameterValue("gitlabSourceRepository", cause.getSourceRepository()));
values.put("gitlabSourceBranch", new StringParameterValue("gitlabSourceBranch", cause.getSourceBranch()));
@@ -93,11 +101,19 @@ public QueueTaskFuture> startJob(GitlabCause cause) {
}
List listValues = new ArrayList<>(values.values());
- if (job == null) {
- return null;
- } else {
- return job.scheduleBuild2(0, cause, new ParametersAction(listValues));
- }
+
+ ParameterizedJobMixIn scheduledJob = new ParameterizedJobMixIn() {
+ @Override
+ protected Job asJob() {
+ return job;
+ }
+ };
+
+ return scheduledJob.scheduleBuild2(
+ 0,
+ new CauseAction(cause),
+ new ParametersAction(listValues)
+ );
}
private Map getDefaultParameters() {
@@ -172,6 +188,10 @@ public String getTargetBranchRegex() {
return targetBranchRegex;
}
+ public String getSourceBranchRegex() {
+ return sourceBranchRegex;
+ }
+
public boolean getUseHttpUrl() {
return useHttpUrl;
}
@@ -235,7 +255,7 @@ public GitlabBuildTriggerDescriptor() {
@Override
public boolean isApplicable(Item item) {
- return item instanceof AbstractProject;
+ return true;
}
@Override
diff --git a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabBuilds.java b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabBuilds.java
index 1a0d1b5..a17e362 100755
--- a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabBuilds.java
+++ b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabBuilds.java
@@ -1,10 +1,6 @@
package org.jenkinsci.plugins.gitlab;
-import hudson.model.AbstractBuild;
-import hudson.model.Cause;
-import hudson.model.Result;
import hudson.model.queue.QueueTaskFuture;
-import jenkins.model.Jenkins;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -43,7 +39,15 @@ public String build(GitlabCause cause, Map customParameters, Git
String triggerComment = trigger.getTriggerComment();
GitlabNote lastNote = getLastNote(mergeRequest, api);
- if (isAllowedByTargetBranchRegex(cause.getTargetBranch())) {
+ if (isAllowedBySourceBranchRegex(cause.getSourceBranch())) {
+ LOGGER.log(Level.INFO, "The source regex matches the source branch {" + cause.getSourceBranch() + "}. Target branch {" + cause.getTargetBranch() + "}");
+ shouldRun = true;
+ } else {
+ LOGGER.log(Level.INFO, "The source regex did not match the source branch {" + cause.getSourceBranch() + "}. Not triggering this job. Target branch {" + cause.getTargetBranch() + "}");
+ shouldRun = false;
+ }
+
+ if (shouldRun && isAllowedByTargetBranchRegex(cause.getTargetBranch())) {
LOGGER.log(Level.INFO, "The target regex matches the target branch {" + cause.getTargetBranch() + "}. Source branch {" + cause.getSourceBranch() + "}");
shouldRun = true;
} else {
@@ -51,12 +55,20 @@ public String build(GitlabCause cause, Map customParameters, Git
shouldRun = false;
}
- if (hasCommitStatus(project, cause.getLastCommitId(), api)) {
+ LOGGER.log(Level.INFO, "The merge request state: " + mergeRequest.getState() + ", " + cause.getMergeRequestState());
+ // state is close
+ if (mergeRequest.isClosed()) {
+ LOGGER.log(Level.INFO, "The merge request " + cause.getTitle() + " has been closed.");
shouldRun = false;
}
+ if (hasCommitStatus(project, cause.getLastCommitId(), api)) {
+ LOGGER.log(Level.WARNING, "The merge request " + cause.getTitle() + " has running/pending pipelines.");
+// shouldRun = false;
+ }
+
if (lastNote != null && lastNote.getBody().equals(triggerComment)) {
- LOGGER.info("Trigger comment found");
+ LOGGER.log(Level.INFO, "Trigger comment found the merge request " + cause.getTitle());
shouldRun = true;
}
@@ -90,7 +102,8 @@ public String build(GitlabCause cause, Map customParameters, Git
if (build == null) {
LOGGER.log(Level.SEVERE, "Job failed to start.");
}
- return withCustomParameters(new StringBuilder("Build triggered."), customParameters).toString();
+
+ return GitlabBuilds.withCustomParameters(new StringBuilder("Build triggered."), customParameters).toString();
} else {
LOGGER.info("Build is not supposed to run");
return "";
@@ -119,6 +132,16 @@ public boolean isAllowedByTargetBranchRegex(String branchName) {
return pattern.matcher(branchName).matches();
}
+ public boolean isAllowedBySourceBranchRegex(String branchName) {
+ String regex = trigger.getSourceBranchRegex();
+ // Allow when no pattern has been specified. (default behavior)
+ if (StringUtils.isEmpty(regex)) {
+ return true;
+ }
+ Pattern pattern = Pattern.compile(regex);
+ return pattern.matcher(branchName).matches();
+ }
+
/**
* synchronized so that there can't be a race condition here.
*
@@ -130,14 +153,19 @@ public boolean isAllowedByTargetBranchRegex(String branchName) {
*/
private synchronized boolean hasCommitStatus(GitlabProject project, String commitHash, GitlabAPI api) throws IOException {
try {
+ boolean hasPendingOrRunningStatus = false;
List statuses = api.getCommitStatuses(project, commitHash);
-
+ // pending, running,
for (GitlabCommitStatus status : statuses) {
LOGGER.fine("Status of " + commitHash + " -> " + status.getStatus());
+ if (status.getStatus().equals("pending") || status.getStatus().equals("running")) {
+ hasPendingOrRunningStatus = true;
+ }
}
// Return true if there are some statuses
- return !statuses.isEmpty();
+// return !statuses.isEmpty();
+ return hasPendingOrRunningStatus;
} catch (FileNotFoundException ex) {
// Can ignore this one because it just means that there is no status for a commit
@@ -209,7 +237,7 @@ private boolean filterMatch(String filter, String target[], String type) {
return shouldRun;
}
- private StringBuilder withCustomParameters(StringBuilder sb, Map customParameters) {
+ public static StringBuilder withCustomParameters(StringBuilder sb, Map customParameters) {
if (customParameters.isEmpty()) {
return sb;
}
@@ -225,127 +253,4 @@ private StringBuilder withCustomParameters(StringBuilder sb, Map
sb.append("\n\n");
return sb;
}
-
- private GitlabCause getCause(AbstractBuild build) {
- Cause cause = build.getCause(GitlabCause.class);
-
- if (cause == null || !(cause instanceof GitlabCause)) {
- return null;
- }
-
- return (GitlabCause) cause;
- }
-
- private Result getResult(AbstractBuild build) {
- return build.getResult();
- }
-
- private String getRootUrl() {
- Jenkins instance = Jenkins.getInstance();
- return instance == null ? "" : instance.getRootUrl();
- }
-
- private boolean isEnableBuildTriggeredMessage() {
- return trigger.getBuilder().isEnableBuildTriggeredMessage();
- }
-
- private boolean isPublishBuildProgressMessages() {
- return trigger.getPublishBuildProgressMessages();
- }
-
- /**
- *
- * @param build AbstractBuild
- */
- public void onStarted(AbstractBuild build) {
- GitlabCause cause = getCause(build);
-
- if (cause == null) {
- return;
- }
-
- try {
- build.setDescription("" + getOnStartedMessage(cause) + "");
- } catch (IOException e) {
- LOGGER.log(Level.SEVERE, "Can't update build description", e);
- }
-
- String url = getRootUrl() + build.getUrl();
-
- if (isPublishBuildProgressMessages()) {
- repository.createNote(cause.getMergeRequestId(), "Build Started: " + "[" + url + "](" + url + ")", false, false);
- }
-
- repository.changeCommitStatus(cause.getMergeRequestId(), cause.getLastCommitId(), "running", url);
- }
-
- /**
- * @param build AbstractBuild
- */
- public void onCompleted(AbstractBuild build) {
- GitlabCause cause = getCause(build);
-
- if (cause == null) {
- return;
- }
-
- boolean stable = false;
- StringBuilder stringBuilder = new StringBuilder();
- Result result = getResult(build);
-
- if (result == Result.SUCCESS) {
- stable = true;
- if (build.getBuildVariables().containsKey("gitlabSuccessMessage")) {
- stringBuilder.append(build.getBuildVariables().get("gitlabSuccessMessage"));
- } else {
- stringBuilder.append(trigger.getDescriptor().getSuccessMessage());
- }
- } else if (result == Result.UNSTABLE) {
- if (build.getBuildVariables().containsKey("gitlabUnstableMessage")) {
- stringBuilder.append(build.getBuildVariables().get("gitlabUnstableMessage"));
- } else {
- stringBuilder.append(trigger.getDescriptor().getUnstableMessage());
- }
- } else {
- if (build.getBuildVariables().containsKey("gitlabFailureMessage")) {
- stringBuilder.append(build.getBuildVariables().get("gitlabFailureMessage"));
- } else {
- stringBuilder.append(trigger.getDescriptor().getFailureMessage());
- }
- }
-
- if (!isEnableBuildTriggeredMessage()) {
- withCustomParameters(stringBuilder, cause.getCustomParameters());
- }
-
- String buildUrl = getRootUrl() + build.getUrl();
- stringBuilder
- .append("\nBuild results available at: ")
- .append("[")
- .append(buildUrl)
- .append("](")
- .append(buildUrl)
- .append(")"); // Link in markdown format
-
- boolean shouldClose = false;
- if (!stable && trigger.getAutoCloseFailed()) {
- shouldClose = true;
- }
-
- boolean shouldMerge = false;
- if (stable && trigger.getAutoMergePassed()) {
- shouldMerge = true;
- }
-
- if (isPublishBuildProgressMessages() || !stable) {
- repository.createNote(cause.getMergeRequestId(), stringBuilder.toString(), shouldClose, shouldMerge);
- }
-
- String status = (result == Result.SUCCESS) ? "success" : "failed";
- repository.changeCommitStatus(cause.getMergeRequestId(), cause.getLastCommitId(), status, buildUrl);
- }
-
- private String getOnStartedMessage(GitlabCause cause) {
- return cause.getShortDescription();
- }
}
diff --git a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabCause.java b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabCause.java
index ac5e2fb..4442add 100755
--- a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabCause.java
+++ b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabCause.java
@@ -7,6 +7,9 @@
public class GitlabCause extends Cause {
private final Integer mergeRequestId;
private final Integer mergeRequestIid;
+ private final String mergeRequestState;
+ private final String assigneeEmail;
+ private final String authorEmail;
private final String sourceName;
private final String sourceRepository;
private final String sourceBranch;
@@ -17,9 +20,15 @@ public class GitlabCause extends Cause {
private final Integer sourceProjectId;
private final Integer targetProjectId;
private final String lastCommitId;
+ private final String webUrl;
+
+ private GitlabBuildTrigger trigger;
public GitlabCause(Integer mergeRequestId,
Integer mergeRequestIid,
+ String mergeRequestState,
+ String authorEmail,
+ String assigneeEmail,
String sourceName,
String sourceRepository,
String sourceBranch,
@@ -29,10 +38,14 @@ public GitlabCause(Integer mergeRequestId,
String description,
Integer sourceProjectId,
Integer targetProjectId,
- String lastCommitId) {
+ String lastCommitId,
+ String webUrl) {
this.mergeRequestId = mergeRequestId;
this.mergeRequestIid = mergeRequestIid;
+ this.mergeRequestState = mergeRequestState;
+ this.assigneeEmail = assigneeEmail;
+ this.authorEmail = authorEmail;
this.sourceName = sourceName;
this.sourceRepository = sourceRepository;
this.sourceBranch = sourceBranch;
@@ -43,10 +56,11 @@ public GitlabCause(Integer mergeRequestId,
this.sourceProjectId = sourceProjectId;
this.targetProjectId = targetProjectId;
this.lastCommitId = lastCommitId;
+ this.webUrl = webUrl;
}
@Override
public String getShortDescription() {
- return "Gitlab Merge Request #" + mergeRequestIid + " : " + sourceName + "/" + sourceBranch +
+ return "Gitlab Merge Request #" + mergeRequestIid + "(" + this.getAuthorEmail() + ")" + " : " + sourceName + "/" + sourceBranch +
" => " + targetBranch;
}
@@ -97,4 +111,28 @@ public Integer getTargetProjectId() {
public String getLastCommitId() {
return lastCommitId;
}
+
+ public String getAssigneeEmail() {
+ return assigneeEmail;
+ }
+
+ public String getAuthorEmail() {
+ return authorEmail;
+ }
+
+ public String getWebUrl() {
+ return webUrl;
+ }
+
+ public GitlabBuildTrigger getTrigger() {
+ return trigger;
+ }
+
+ public void setTrigger(GitlabBuildTrigger trigger) {
+ this.trigger = trigger;
+ }
+
+ public String getMergeRequestState() {
+ return mergeRequestState;
+ }
}
diff --git a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabMergeRequestAddCommentStep.java b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabMergeRequestAddCommentStep.java
new file mode 100644
index 0000000..4a55dac
--- /dev/null
+++ b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabMergeRequestAddCommentStep.java
@@ -0,0 +1,102 @@
+package org.jenkinsci.plugins.gitlab;
+/*
+ *
+ * Edward Chen
+ * edward_chen@gemdata.net
+ * 2019-07-22 14:56
+ *
+ * Copyright (c) 2016-2018, GemData. All Right Reserved, http://www.gemdata.net
+ */
+
+import com.google.common.collect.ImmutableSet;
+import hudson.Extension;
+import hudson.model.Run;
+import hudson.model.TaskListener;
+import hudson.util.ListBoxModel;
+import org.apache.commons.lang.StringUtils;
+import org.jenkinsci.plugins.gitlab.models.webhook.BuildState;
+import org.jenkinsci.plugins.workflow.steps.*;
+import org.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.DataBoundSetter;
+import org.kohsuke.stapler.export.ExportedBean;
+
+import java.util.EnumSet;
+import java.util.Set;
+import java.util.logging.Logger;
+
+@ExportedBean
+public class GitlabMergeRequestAddCommentStep extends Step {
+
+ private String comment;
+
+ @DataBoundConstructor
+ public GitlabMergeRequestAddCommentStep(String comment) {
+ this.comment = StringUtils.isEmpty(comment) ? null : comment;
+ }
+
+ @Override
+ public StepExecution start(StepContext context) throws Exception {
+ return new AddGitLabCommentStepExecution(context, this);
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ @DataBoundSetter
+ public void setComment(String comment) {
+ this.comment = StringUtils.isEmpty(comment) ? null : comment;
+ }
+
+
+ public static class AddGitLabCommentStepExecution extends SynchronousStepExecution {
+ private static final Logger LOGGER = Logger.getLogger(GitlabWebhooks.class.getName());
+
+ private static final long serialVersionUID = 1;
+
+ private final transient Run, ?> run;
+
+ private final transient GitlabMergeRequestAddCommentStep step;
+
+ AddGitLabCommentStepExecution(StepContext context, GitlabMergeRequestAddCommentStep step) throws Exception {
+ super(context);
+ this.step = step;
+ run = context.get(Run.class);
+ }
+
+ @Override
+ protected Void run() throws Exception {
+ final String comment = StringUtils.isEmpty(step.comment) ? "" : step.comment;
+ GitlabCause gitlabCause = run.getCause(GitlabCause.class);
+ if (gitlabCause != null) {
+ LOGGER.info(String.format("Add comment for mr %d:%d:%d", gitlabCause.getMergeRequestId(), gitlabCause.getMergeRequestIid(), gitlabCause.getSourceProjectId()));
+ GitlabMergeRequestWrapper.createNote(gitlabCause.getMergeRequestId(),
+ gitlabCause.getMergeRequestIid(),
+ gitlabCause.getSourceProjectId(),
+ comment,
+ false,
+ false);
+ }
+
+ return null;
+ }
+ }
+
+ @Extension
+ public static final class DescriptorImpl extends StepDescriptor {
+ @Override
+ public String getDisplayName() {
+ return "[GitlabMRBuilder] Add comment to the merge request in GitLab";
+ }
+
+ @Override
+ public String getFunctionName() {
+ return "addGitlabMRNote";
+ }
+
+ @Override
+ public Set> getRequiredContext() {
+ return ImmutableSet.of(TaskListener.class, Run.class);
+ }
+ }
+}
diff --git a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabMergeRequestBuilder.java b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabMergeRequestBuilder.java
index 0adb20a..1aa3079 100755
--- a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabMergeRequestBuilder.java
+++ b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabMergeRequestBuilder.java
@@ -1,12 +1,13 @@
package org.jenkinsci.plugins.gitlab;
import hudson.model.AbstractProject;
+import hudson.model.Job;
import java.util.Map;
public class GitlabMergeRequestBuilder {
- private AbstractProject, ?> project;
+ private Job, ?> project;
private GitlabBuildTrigger trigger;
private Map mergeRequests;
private GitlabBuilds builds;
@@ -37,7 +38,7 @@ public GitlabBuildTrigger getTrigger() {
return trigger;
}
- public GitlabMergeRequestBuilder setProject(AbstractProject, ?> project) {
+ public GitlabMergeRequestBuilder setProject(Job, ?> project) {
this.project = project;
return this;
}
diff --git a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabMergeRequestCommitStatusUpdaterStep.java b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabMergeRequestCommitStatusUpdaterStep.java
new file mode 100644
index 0000000..42a1928
--- /dev/null
+++ b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabMergeRequestCommitStatusUpdaterStep.java
@@ -0,0 +1,125 @@
+package org.jenkinsci.plugins.gitlab;
+/*
+ *
+ * Edward Chen
+ * edward_chen@gemdata.net
+ * 2019-07-22 14:56
+ *
+ * Copyright (c) 2016-2018, GemData. All Right Reserved, http://www.gemdata.net
+ */
+
+import java.util.EnumSet;
+import java.util.Set;
+
+import org.jenkinsci.plugins.gitlab.models.webhook.BuildState;
+import org.jenkinsci.plugins.workflow.steps.*;
+
+import org.apache.commons.lang.StringUtils;
+import org.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.DataBoundSetter;
+import org.kohsuke.stapler.export.ExportedBean;
+
+import com.google.common.collect.ImmutableSet;
+
+import hudson.Extension;
+import hudson.model.Run;
+import hudson.model.TaskListener;
+import hudson.util.ListBoxModel;
+
+@ExportedBean
+public class GitlabMergeRequestCommitStatusUpdaterStep extends Step {
+
+ private String name;
+ private BuildState state;
+ private String url;
+
+ @DataBoundConstructor
+ public GitlabMergeRequestCommitStatusUpdaterStep(String name, BuildState state, String url) {
+ this.name = StringUtils.isEmpty(name) ? null : name;
+ this.state = state;
+ this.url = url;
+ }
+
+ @Override
+ public StepExecution start(StepContext context) throws Exception {
+ return new UpdateGitLabCommitStatusStepExecution(context, this);
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @DataBoundSetter
+ public void setName(String name) {
+ this.name = StringUtils.isEmpty(name) ? null : name;
+ }
+
+ public BuildState getState() {
+ return state;
+ }
+
+ @DataBoundSetter
+ public void setState(BuildState state) {
+ this.state = state;
+ }
+
+ public String getUrl() {
+ return url;
+ }
+
+ @DataBoundSetter
+ public void setUrl(String sonarqubeUrl) {
+ this.url = sonarqubeUrl;
+ }
+
+ public static class UpdateGitLabCommitStatusStepExecution extends SynchronousStepExecution {
+ private static final long serialVersionUID = 1;
+
+ private final transient Run, ?> run;
+
+ private final transient GitlabMergeRequestCommitStatusUpdaterStep step;
+
+ UpdateGitLabCommitStatusStepExecution(StepContext context, GitlabMergeRequestCommitStatusUpdaterStep step) throws Exception {
+ super(context);
+ this.step = step;
+ run = context.get(Run.class);
+ }
+
+ @Override
+ protected Void run() throws Exception {
+ final String name = StringUtils.isEmpty(step.name) ? "jenkins" : step.name;
+ Gitlab gitlab = GitlabBuildTrigger.DESCRIPTOR.getGitlab();
+ GitlabCause gitlabCause = run.getCause(GitlabCause.class);
+ if (gitlabCause != null) {
+ gitlab.changeCommitStatus(gitlabCause.getTargetProjectId(), gitlabCause.getSourceBranch(), gitlabCause.getLastCommitId(), name, "", step.state.toString(), step.url);
+ }
+ return null;
+ }
+ }
+
+ @Extension
+ public static final class DescriptorImpl extends StepDescriptor {
+ @Override
+ public String getDisplayName() {
+ return "[GitlabMRBuilder] Update the merge request latest commit status in GitLab";
+ }
+
+ @Override
+ public String getFunctionName() {
+ return "updateGitlabMRCommitStatus";
+ }
+
+ public ListBoxModel doFillStateItems() {
+ ListBoxModel options = new ListBoxModel();
+ for (BuildState buildState : EnumSet.allOf(BuildState.class)) {
+ options.add(buildState.name());
+ }
+ return options;
+ }
+
+ @Override
+ public Set> getRequiredContext() {
+ return ImmutableSet.of(TaskListener.class, Run.class);
+ }
+ }
+}
diff --git a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabMergeRequestWrapper.java b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabMergeRequestWrapper.java
index ba4a0b1..a8af395 100755
--- a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabMergeRequestWrapper.java
+++ b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabMergeRequestWrapper.java
@@ -102,10 +102,10 @@ public void check(GitlabMergeRequest gitlabMergeRequest) {
GitlabAPI api = builder.getGitlab().get();
GitlabCommit latestCommit = getLatestCommit(gitlabMergeRequest, api);
- if (latestCommit == null) { // the source branch has been removed
+ if (latestCommit == null) { // the source branch has been removed and is not merged
return;
}
-
+
Map customParameters = getSpecifiedCustomParameters(gitlabMergeRequest, api);
build(customParameters, latestCommit.getId(), gitlabMergeRequest);
} catch (IOException e) {
@@ -156,7 +156,21 @@ public int compare(GitlabCommit o1, GitlabCommit o2) {
if (commits.isEmpty()) {
LOGGER.log(Level.SEVERE, "Merge Request without commits.");
- return null;
+ if (gitlabMergeRequest.isMerged()) {
+ // get target branch latest commit id
+ commits = api.getLastCommits(gitlabMergeRequest.getTargetProjectId(), gitlabMergeRequest.getTargetBranch());
+ Collections.sort(commits, new Comparator() {
+ public int compare(GitlabCommit o1, GitlabCommit o2) {
+ return o2.getCreatedAt().compareTo(o1.getCreatedAt());
+ }
+ });
+ if (commits.isEmpty()) {
+ LOGGER.log(Level.SEVERE, "Merge Request's project branch has no commits.");
+ return null;
+ }
+ } else {
+ return null;
+ }
}
return commits.get(0);
@@ -206,29 +220,30 @@ public String getTargetBranch() {
return targetBranch;
}
- public GitlabNote createNote(String message, boolean shouldClose, boolean shouldMerge) {
+ public static GitlabNote createNote(Integer id, Integer iid, Integer pid, String message, boolean shouldClose, boolean shouldMerge) {
GitlabMergeRequest mergeRequest = new GitlabMergeRequest();
mergeRequest.setId(id);
mergeRequest.setIid(iid);
- mergeRequest.setProjectId(project.getId());
+ mergeRequest.setProjectId(pid);
+ Gitlab gitlab = GitlabBuildTrigger.DESCRIPTOR.getGitlab();
try {
if (shouldClose || shouldMerge) {
String tailUrl = "";
if (shouldClose) {
- tailUrl = GitlabProject.URL + "/" + project.getId() + "/merge_request/" + iid + "?state_event=close";
+ tailUrl = GitlabProject.URL + "/" + pid + "/merge_requests/" + iid + "?state_event=close";
}
if (shouldMerge) {
- tailUrl = GitlabProject.URL + "/" + project.getId() + "/merge_request/" + iid + "/merge";
+ tailUrl = GitlabProject.URL + "/" + pid + "/merge_requests/" + iid + "/merge";
}
- builder.getGitlab().get().retrieve().method("PUT").to(tailUrl, Void.class);
+ gitlab.get().retrieve().method("PUT").to(tailUrl, Void.class);
}
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Failed to automatically merge/close the merge request " + iid, e);
}
try {
- return builder.getGitlab().get().createNote(mergeRequest, message);
+ return gitlab.get().createNote(mergeRequest, message);
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Failed to create note for merge request " + iid, e);
return null;
@@ -236,24 +251,27 @@ public GitlabNote createNote(String message, boolean shouldClose, boolean should
}
- public GitlabCommitStatus changeCommitStatus(String commitHash, String commitStatus, String targetUrl) {
-
- try {
- GitlabAPI api = builder.getGitlab().get();
- GitlabMergeRequest mergeRequest = api.getMergeRequest(project, iid);
-
- return builder.getGitlab().changeCommitStatus(project.getId(), mergeRequest.getSourceBranch(), commitHash, commitStatus, targetUrl);
- } catch (IOException e) {
- LOGGER.log(Level.SEVERE, "Failed to change status for merge request commit " + commitHash, e);
- }
-
- return null;
- }
+// public GitlabCommitStatus changeCommitStatus(String commitHash, String commitStatus, String targetUrl) {
+//
+// try {
+// GitlabAPI api = builder.getGitlab().get();
+// GitlabMergeRequest mergeRequest = api.getMergeRequest(project, iid);
+//
+// return builder.getGitlab().changeCommitStatus(project.getId(), mergeRequest.getSourceBranch(), commitHash, commitStatus, targetUrl);
+// } catch (IOException e) {
+// LOGGER.log(Level.SEVERE, "Failed to change status for merge request commit " + commitHash, e);
+// }
+//
+// return null;
+// }
private void build(Map customParameters, String commitHash, GitlabMergeRequest mergeRequest) {
GitlabCause cause = new GitlabCause(
this.getId(),
this.getIid(),
+ mergeRequest.getState(),
+ mergeRequest.getAuthor().getEmail(),
+ mergeRequest.getAssignee().getEmail(),
this.getSourceName(),
this.getSourceRepository(),
this.getSourceBranch(),
@@ -263,19 +281,24 @@ private void build(Map customParameters, String commitHash, Gitl
this.getDescription(),
this.sourceProject.getId(),
project.getId(),
- commitHash);
+ commitHash,
+ mergeRequest.getWebUrl());
try {
+ cause.setTrigger(builder.getTrigger());
+
String message = builder.getBuilds().build(cause, customParameters, project, mergeRequest);
if (builder.isEnableBuildTriggeredMessage() && StringUtils.isNotBlank(message)) {
- createNote(message, false, false);
+ GitlabMergeRequestWrapper.createNote(this.id, this.iid, this.project.getId(), message, false, false);
LOGGER.log(Level.INFO, message);
}
} catch (IOException e) {
- // TODO Auto-generated catch block
e.printStackTrace();
}
}
+ public GitlabProject getProject() {
+ return project;
+ }
}
diff --git a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabQueueListener.java b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabQueueListener.java
index c6c54ac..be657e3 100755
--- a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabQueueListener.java
+++ b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabQueueListener.java
@@ -1,6 +1,7 @@
package org.jenkinsci.plugins.gitlab;
import java.io.IOException;
+import java.util.logging.Level;
import java.util.logging.Logger;
import jenkins.model.Jenkins;
@@ -8,24 +9,28 @@
import hudson.model.Cause;
import hudson.model.Queue;
import hudson.model.queue.QueueListener;
+import org.gitlab.api.models.GitlabMergeRequest;
@Extension
public class GitlabQueueListener extends QueueListener {
private static final Logger LOGGER = Logger.getLogger(GitlabQueueListener.class.getName());
- public void onEnterWaiting(Queue.WaitingItem wi) {
- for (Cause c : wi.getCauses()) {
+ public void onEnterBuildable(Queue.BuildableItem bi) {
+ for (Cause c : bi.getCauses()) {
if (c instanceof GitlabCause) {
- Gitlab gitlab = new Gitlab();
- GitlabCause cause = (GitlabCause) c;
- Jenkins instance = Jenkins.getInstance();
- String rootUrl = instance == null ? "/" : instance.getRootUrl();
- String url = rootUrl + wi.getUrl();
- try {
- gitlab.changeCommitStatus(cause.getTargetProjectId(), cause.getSourceBranch(), cause.getLastCommitId(), "pending", url);
- } catch (IOException e) {
- LOGGER.info("error trying to set pending status");
+ if (((GitlabCause) c).getMergeRequestState().equals(GitlabMergeRequest.STATUS_OPENED)) {
+ Gitlab gitlab = GitlabBuildTrigger.DESCRIPTOR.getGitlab();
+ GitlabCause cause = (GitlabCause) c;
+ Jenkins instance = Jenkins.getInstance();
+ String rootUrl = instance == null ? "/" : instance.getRootUrl();
+ String url = rootUrl + bi.getUrl();
+ try {
+ LOGGER.log(Level.INFO, "Send pending status to commit: " + cause.getLastCommitId());
+ gitlab.changeCommitStatus(cause.getTargetProjectId(), cause.getSourceBranch(), cause.getLastCommitId(), "pending", url);
+ } catch (IOException e) {
+ LOGGER.info("error trying to set pending status");
+ }
}
}
}
diff --git a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabRepository.java b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabRepository.java
index 0a4578c..4348c28 100755
--- a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabRepository.java
+++ b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabRepository.java
@@ -105,33 +105,33 @@ private GitlabProject getProjectForPath(String path) {
return null;
}
- public String getProjectUrl() {
- try {
- return builder.getGitlab().get().getUrl(project.getPathWithNamespace()).toString();
- } catch (IOException e) {
- return null;
- }
- }
-
- public String getMergeRequestUrl(Integer mergeRequestIid) {
- return getProjectUrl() + GitlabMergeRequest.URL + "/" + mergeRequestIid;
- }
-
- public GitlabNote createNote(Integer mergeRequestId, String message, boolean shouldClose, boolean shouldMerge) {
- GitlabMergeRequestWrapper gitlabMergeRequestWrapper = mergeRequests.get(mergeRequestId);
- return gitlabMergeRequestWrapper.createNote(message, shouldClose, shouldMerge);
- }
-
- public GitlabCommitStatus changeCommitStatus(Integer mergeRequestId, String commitHash, String commitStatus, String targetUrl) {
- if (commitHash != null) {
-
- GitlabMergeRequestWrapper gitlabMergeRequestWrapper = mergeRequests.get(mergeRequestId);
-
- LOGGER.info("Sending Status: " + commitStatus);
-
- return gitlabMergeRequestWrapper.changeCommitStatus(commitHash, commitStatus, targetUrl);
- } else {
- return null;
- }
- }
+// public String getProjectUrl() {
+// try {
+// return builder.getGitlab().get().getUrl(project.getPathWithNamespace()).toString();
+// } catch (IOException e) {
+// return null;
+// }
+// }
+
+// public String getMergeRequestUrl(Integer mergeRequestIid) {
+// return getProjectUrl() + GitlabMergeRequest.URL + "/" + mergeRequestIid;
+// }
+//
+// public GitlabNote createNote(Integer mergeRequestId, String message, boolean shouldClose, boolean shouldMerge) {
+// GitlabMergeRequestWrapper wrapper = mergeRequests.get(mergeRequestId);
+// return GitlabMergeRequestWrapper.createNote(wrapper.getId(), wrapper.getIid(), wrapper.getProject().getId(), message, shouldClose, shouldMerge);
+// }
+
+// public GitlabCommitStatus changeCommitStatus(Integer mergeRequestId, String commitHash, String commitStatus, String targetUrl) {
+// if (commitHash != null) {
+//
+// GitlabMergeRequestWrapper gitlabMergeRequestWrapper = mergeRequests.get(mergeRequestId);
+//
+// LOGGER.info("Sending Status: " + commitStatus);
+//
+// return gitlabMergeRequestWrapper.changeCommitStatus(commitHash, commitStatus, targetUrl);
+// } else {
+// return null;
+// }
+// }
}
diff --git a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabWebhooks.java b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabWebhooks.java
index f60b270..9de41a1 100755
--- a/src/main/java/org/jenkinsci/plugins/gitlab/GitlabWebhooks.java
+++ b/src/main/java/org/jenkinsci/plugins/gitlab/GitlabWebhooks.java
@@ -4,9 +4,11 @@
import hudson.Extension;
import hudson.model.UnprotectedRootAction;
import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang.StringUtils;
import org.gitlab.api.GitlabAPI;
import org.gitlab.api.models.GitlabMergeRequest;
import org.gitlab.api.models.GitlabProject;
+import org.gitlab.api.models.GitlabUser;
import org.jenkinsci.plugins.gitlab.models.webhook.MergeRequest;
import org.jenkinsci.plugins.gitlab.models.webhook.Note;
import org.jenkinsci.plugins.gitlab.models.webhook.OnlyType;
@@ -66,7 +68,7 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object nod
};
try {
String requestBodyString = IOUtils.toString(request.getInputStream(), "UTF-8");
- LOGGER.fine(requestBodyString);
+// LOGGER.info(requestBodyString);
OnlyType hookObjectKind = OnlyType.fromJson(requestBodyString);
MergeRequest mergeRequest = null;
switch (hookObjectKind.object_kind) {
@@ -79,13 +81,27 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object nod
break;
default: {}
}
- LOGGER.fine(String.format("MergeRequest is %s", mergeRequest));
+ LOGGER.info(String.format("MergeRequest is %s", mergeRequest));
GitlabBuildTrigger trigger = mergeRequest != null ? findTrigger(mergeRequest) : null;
if (trigger != null) {
GitlabMergeRequestBuilder currentBuilder = trigger.getBuilder();
GitlabAPI api = currentBuilder.getGitlab().get();
GitlabProject project = api.getProject(mergeRequest.getTarget_project_id());
- GitlabMergeRequest gitlabMergeRequest = api.getMergeRequest(project, mergeRequest.getId());
+ GitlabMergeRequest gitlabMergeRequest = api.getMergeRequest(project, mergeRequest.getIid());
+ // make sure author email exists
+ GitlabUser author = gitlabMergeRequest.getAuthor();
+ GitlabUser assignee = gitlabMergeRequest.getAssignee();
+ if (StringUtils.isEmpty(author.getEmail())) {
+ String tailUrl = GitlabUser.URL + "/" + author.getId();
+ author = api.getUser(author.getId());
+ gitlabMergeRequest.getAuthor().setEmail(author.getEmail());
+ }
+ if (StringUtils.isEmpty(assignee.getEmail())) {
+ String tailUrl = GitlabUser.URL + "/" + assignee.getId();
+ assignee = api.getUser(assignee.getId());
+ gitlabMergeRequest.getAssignee().setEmail(assignee.getEmail());
+ }
+ LOGGER.info(String.format("MergeRequest %s author is %s:%s, assignee %s:%s", author.getId(), author.getName(), author.getEmail(), assignee.getName(), assignee.getEmail()));
GitlabMergeRequestWrapper mergeRequestWrapper;
Map mergeRequestWrapperMap = currentBuilder.getMergeRequests();
@@ -105,12 +121,12 @@ public void generateResponse(StaplerRequest req, StaplerResponse rsp, Object nod
}
} catch (IOException ex) {
- LOGGER.severe("There was an error");
+ LOGGER.severe("There was an error: " + ex.toString());
LOGGER.throwing("GitlabWebhooks", "doStart", ex);
} catch (JsonSyntaxException e) {
LOGGER.warning(e.toString());
} catch (Exception e) {
- LOGGER.severe(String.format("%s on run doStart", e));
+ LOGGER.throwing("GitlabWebhooks", "doStart", e);
}
return response;
}
diff --git a/src/main/java/org/jenkinsci/plugins/gitlab/models/webhook/BuildState.java b/src/main/java/org/jenkinsci/plugins/gitlab/models/webhook/BuildState.java
new file mode 100644
index 0000000..849bc6e
--- /dev/null
+++ b/src/main/java/org/jenkinsci/plugins/gitlab/models/webhook/BuildState.java
@@ -0,0 +1,13 @@
+package org.jenkinsci.plugins.gitlab.models.webhook;
+/*
+ *
+ * Edward Chen
+ * edward_chen@gemdata.net
+ * 2019-07-22 15:04
+ *
+ * Copyright (c) 2016-2018, GemData. All Right Reserved, http://www.gemdata.net
+ */
+
+public enum BuildState {
+ pending, running, canceled, success, failed
+}
diff --git a/src/main/resources/META-INF/hudson.remoting.ClassFilter b/src/main/resources/META-INF/hudson.remoting.ClassFilter
new file mode 100644
index 0000000..67437a4
--- /dev/null
+++ b/src/main/resources/META-INF/hudson.remoting.ClassFilter
@@ -0,0 +1,6 @@
+org.gitlab.api.models.GitlabProject
+org.gitlab.api.models.GitlabNamespace
+org.gitlab.api.models.GitlabPermission
+org.gitlab.api.models.GitlabUser
+org.gitlab.api.models.GitlabProjectAccessLevel
+org.gitlab.api.models.GitlabProjectSharedGroup
\ No newline at end of file
diff --git a/src/main/resources/org/jenkinsci/plugins/gitlab/GitlabBuildTrigger/config.jelly b/src/main/resources/org/jenkinsci/plugins/gitlab/GitlabBuildTrigger/config.jelly
index 008bab5..5fe805c 100644
--- a/src/main/resources/org/jenkinsci/plugins/gitlab/GitlabBuildTrigger/config.jelly
+++ b/src/main/resources/org/jenkinsci/plugins/gitlab/GitlabBuildTrigger/config.jelly
@@ -4,9 +4,13 @@
description="The full path including namespace to the project">
+
+
+
-
+
diff --git a/src/main/resources/org/jenkinsci/plugins/gitlab/GitlabBuildTrigger/global.jelly b/src/main/resources/org/jenkinsci/plugins/gitlab/GitlabBuildTrigger/global.jelly
index 04fcac6..61073d2 100755
--- a/src/main/resources/org/jenkinsci/plugins/gitlab/GitlabBuildTrigger/global.jelly
+++ b/src/main/resources/org/jenkinsci/plugins/gitlab/GitlabBuildTrigger/global.jelly
@@ -14,7 +14,7 @@
-
+
diff --git a/src/main/resources/org/jenkinsci/plugins/gitlab/GitlabMergeRequestAddCommentStep/config.jelly b/src/main/resources/org/jenkinsci/plugins/gitlab/GitlabMergeRequestAddCommentStep/config.jelly
new file mode 100644
index 0000000..081a387
--- /dev/null
+++ b/src/main/resources/org/jenkinsci/plugins/gitlab/GitlabMergeRequestAddCommentStep/config.jelly
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/src/main/resources/org/jenkinsci/plugins/gitlab/GitlabMergeRequestCommitStatusUpdaterStep/config.jelly b/src/main/resources/org/jenkinsci/plugins/gitlab/GitlabMergeRequestCommitStatusUpdaterStep/config.jelly
new file mode 100644
index 0000000..bece8c3
--- /dev/null
+++ b/src/main/resources/org/jenkinsci/plugins/gitlab/GitlabMergeRequestCommitStatusUpdaterStep/config.jelly
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/java/com/jenkinsci/plugins/gitlab/GitlabBuilds_build_Test.java b/src/test/java/com/jenkinsci/plugins/gitlab/GitlabBuilds_build_Test.java
index 72c48dd..9ee7879 100755
--- a/src/test/java/com/jenkinsci/plugins/gitlab/GitlabBuilds_build_Test.java
+++ b/src/test/java/com/jenkinsci/plugins/gitlab/GitlabBuilds_build_Test.java
@@ -36,8 +36,10 @@ public class GitlabBuilds_build_Test {
GitlabProject project;
@Injectable
GitlabUser user;
- @Injectable
- GitlabMergeRequest mergeRequest;
+
+ //@Injectable
+
+ GitlabMergeRequest mergeRequest = new GitlabMergeRequest();
@Injectable
GitlabBuildTrigger trigger;
@@ -47,10 +49,12 @@ public class GitlabBuilds_build_Test {
@Tested
GitlabBuilds subject;
-
GitlabCause cause = new GitlabCause(
1,
2,
+ "opened",
+ "authorEmail",
+ "assigneeEmail",
"sourceName",
"sourceRepo",
"sourceBranch",
@@ -60,10 +64,12 @@ public class GitlabBuilds_build_Test {
"description",
3,
4,
- "commitHash"
+ "commitHash",
+ "http://web_url"
);
- List statuses = Arrays.asList(new GitlabCommitStatus());
+ GitlabCommitStatus status = new GitlabCommitStatus();
+ List statuses = Arrays.asList(status);
@BeforeClass
public static void beforeClass() {
@@ -84,6 +90,8 @@ Secret fromString(String data) {
@Before
public void before() throws Exception {
+ status.setStatus("running");
+
user.setUsername("username");
mergeRequest.setAssignee(user);
@@ -107,12 +115,10 @@ public void build() throws IOException {
}
@Test
- public void doesNotBuild_branchPattern() throws IOException {
+ public void doesNotBuild_MergeRequestClosed() throws IOException {
- new NonStrictExpectations() {{
- trigger.getTargetBranchRegex();
- result = "thisisafakepattern";
- }};
+ String stateStr = mergeRequest.getState();
+ mergeRequest.setState("closed");
subject.build(cause, new HashMap(), project, mergeRequest);
@@ -120,15 +126,15 @@ public void doesNotBuild_branchPattern() throws IOException {
trigger.startJob((GitlabCause) any);
times = 0;
}};
+
+ mergeRequest.setState(stateStr);
}
@Test
- public void doesNotBuild_hasCommitStatus() throws IOException {
+ public void doesNotBuild_MergeRequestMerged() throws IOException {
- new NonStrictExpectations() {{
- api.getCommitStatuses(project, cause.getLastCommitId());
- result = statuses;
- }};
+ String stateStr = mergeRequest.getState();
+ mergeRequest.setState("merged");
subject.build(cause, new HashMap(), project, mergeRequest);
@@ -136,14 +142,16 @@ public void doesNotBuild_hasCommitStatus() throws IOException {
trigger.startJob((GitlabCause) any);
times = 0;
}};
+
+ mergeRequest.setState(stateStr);
}
@Test
- public void doesNotBuild_notMatchingAssigneeFilter() throws IOException {
+ public void doesNotBuild_SourceBranchPattern() throws IOException {
new NonStrictExpectations() {{
- trigger.getAssigneeFilter();
- result = "jenkins";
+ trigger.getSourceBranchRegex();
+ result = "thisisafakepattern";
}};
subject.build(cause, new HashMap(), project, mergeRequest);
@@ -155,11 +163,11 @@ public void doesNotBuild_notMatchingAssigneeFilter() throws IOException {
}
@Test
- public void doesNotBuild_notMatchingTagFilter() throws IOException {
+ public void doesNotBuild_TargetBranchPattern() throws IOException {
new NonStrictExpectations() {{
- trigger.getTagFilter();
- result = "Build";
+ trigger.getTargetBranchRegex();
+ result = "thisisafakepattern";
}};
subject.build(cause, new HashMap(), project, mergeRequest);
@@ -171,123 +179,171 @@ public void doesNotBuild_notMatchingTagFilter() throws IOException {
}
@Test
- public void onStart_notMuted(@Mocked final AbstractBuild build) {
-
- new NonStrictExpectations(subject) {{
- invoke(subject, "getCause", (AbstractBuild) build);
- result = cause;
-
- invoke(subject, "getRootUrl");
- result = "http://git.example.com";
-
- invoke(subject, "isPublishBuildProgressMessages");
- result = true;
- }};
-
- subject.onStarted(build);
-
- new Verifications() {{
- repository.createNote(anyInt, anyString, anyBoolean, anyBoolean);
- times = 1;
- }};
- }
-
- @Test
- public void onStart_muted(@Mocked final AbstractBuild build) {
-
- new NonStrictExpectations(subject) {{
- invoke(subject, "getCause", (AbstractBuild) build);
- result = cause;
-
- invoke(subject, "getRootUrl");
- result = "http://git.example.com";
+ public void doesNotBuild_hasCommitStatus() throws IOException {
- invoke(subject, "isPublishBuildProgressMessages");
- result = false;
+ new NonStrictExpectations() {{
+ api.getCommitStatuses(project, cause.getLastCommitId());
+ result = statuses;
}};
- subject.onStarted(build);
+ subject.build(cause, new HashMap(), project, mergeRequest);
new Verifications() {{
- repository.createNote(anyInt, anyString, anyBoolean, anyBoolean);
+ trigger.startJob((GitlabCause) any);
times = 0;
}};
}
@Test
- public void onCompleted_notMuted(@Mocked final AbstractBuild build) {
-
- new NonStrictExpectations(subject) {{
- invoke(subject, "getCause", (AbstractBuild) build);
- result = cause;
-
- invoke(subject, "getResult", (AbstractBuild) build);
- result = Result.SUCCESS;
-
- invoke(subject, "getRootUrl");
- result = "http://git.example.com";
+ public void doesNotBuild_notMatchingAssigneeFilter() throws IOException {
- invoke(subject, "isPublishBuildProgressMessages");
- result = true;
+ new NonStrictExpectations() {{
+ trigger.getAssigneeFilter();
+ result = "jenkins";
}};
- subject.onCompleted(build);
+ subject.build(cause, new HashMap(), project, mergeRequest);
new Verifications() {{
- repository.createNote(anyInt, anyString, anyBoolean, anyBoolean);
- times = 1;
+ trigger.startJob((GitlabCause) any);
+ times = 0;
}};
}
@Test
- public void onCompleted_muted(@Mocked final AbstractBuild build) {
-
- new NonStrictExpectations(subject) {{
- invoke(subject, "getCause", (AbstractBuild) build);
- result = cause;
-
- invoke(subject, "getResult", (AbstractBuild) build);
- result = Result.SUCCESS;
-
- invoke(subject, "getRootUrl");
- result = "http://git.example.com";
+ public void doesNotBuild_notMatchingTagFilter() throws IOException {
- invoke(subject, "isPublishBuildProgressMessages");
- result = false;
+ new NonStrictExpectations() {{
+ trigger.getTagFilter();
+ result = "Build";
}};
- subject.onCompleted(build);
+ subject.build(cause, new HashMap(), project, mergeRequest);
new Verifications() {{
- repository.createNote(anyInt, anyString, anyBoolean, anyBoolean);
+ trigger.startJob((GitlabCause) any);
times = 0;
}};
}
- @Test
- public void onCompleted_mutedButBuildFailed(@Mocked final AbstractBuild build) {
-
- new NonStrictExpectations(subject) {{
- invoke(subject, "getCause", (AbstractBuild) build);
- result = cause;
-
- invoke(subject, "getResult", (AbstractBuild) build);
- result = Result.FAILURE;
-
- invoke(subject, "getRootUrl");
- result = "http://git.example.com";
-
- invoke(subject, "isPublishBuildProgressMessages");
- result = false;
- }};
-
- subject.onCompleted(build);
-
- new Verifications() {{
- repository.createNote(anyInt, anyString, anyBoolean, anyBoolean);
- times = 1;
- }};
- }
+// @Test
+// public void onStart_notMuted(@Mocked final AbstractBuild build) {
+//
+// new NonStrictExpectations(subject) {{
+// invoke(subject, "getCause", (AbstractBuild) build);
+// result = cause;
+//
+// invoke(subject, "getRootUrl");
+// result = "http://git.example.com";
+//
+// invoke(subject, "isPublishBuildProgressMessages");
+// result = true;
+// }};
+//
+// subject.onStarted(build);
+//
+// new Verifications() {{
+// repository.createNote(anyInt, anyString, anyBoolean, anyBoolean);
+// times = 1;
+// }};
+// }
+//
+// @Test
+// public void onStart_muted(@Mocked final AbstractBuild build) {
+//
+// new NonStrictExpectations(subject) {{
+// invoke(subject, "getCause", (AbstractBuild) build);
+// result = cause;
+//
+// invoke(subject, "getRootUrl");
+// result = "http://git.example.com";
+//
+// invoke(subject, "isPublishBuildProgressMessages");
+// result = false;
+// }};
+//
+// subject.onStarted(build);
+//
+// new Verifications() {{
+// repository.createNote(anyInt, anyString, anyBoolean, anyBoolean);
+// times = 0;
+// }};
+// }
+
+// @Test
+// public void onCompleted_notMuted(@Mocked final AbstractBuild build) {
+//
+// new NonStrictExpectations(subject) {{
+// invoke(subject, "getCause", (AbstractBuild) build);
+// result = cause;
+//
+// invoke(subject, "getResult", (AbstractBuild) build);
+// result = Result.SUCCESS;
+//
+// invoke(subject, "getRootUrl");
+// result = "http://git.example.com";
+//
+// invoke(subject, "isPublishBuildProgressMessages");
+// result = true;
+// }};
+//
+// subject.onCompleted(build);
+//
+// new Verifications() {{
+// repository.createNote(anyInt, anyString, anyBoolean, anyBoolean);
+// times = 1;
+// }};
+// }
+//
+// @Test
+// public void onCompleted_muted(@Mocked final AbstractBuild build) {
+//
+// new NonStrictExpectations(subject) {{
+// invoke(subject, "getCause", (AbstractBuild) build);
+// result = cause;
+//
+// invoke(subject, "getResult", (AbstractBuild) build);
+// result = Result.SUCCESS;
+//
+// invoke(subject, "getRootUrl");
+// result = "http://git.example.com";
+//
+// invoke(subject, "isPublishBuildProgressMessages");
+// result = false;
+// }};
+//
+// subject.onCompleted(build);
+//
+// new Verifications() {{
+// repository.createNote(anyInt, anyString, anyBoolean, anyBoolean);
+// times = 0;
+// }};
+// }
+
+// @Test
+// public void onCompleted_mutedButBuildFailed(@Mocked final AbstractBuild build) {
+//
+// new NonStrictExpectations(subject) {{
+// invoke(subject, "getCause", (AbstractBuild) build);
+// result = cause;
+//
+// invoke(subject, "getResult", (AbstractBuild) build);
+// result = Result.FAILURE;
+//
+// invoke(subject, "getRootUrl");
+// result = "http://git.example.com";
+//
+// invoke(subject, "isPublishBuildProgressMessages");
+// result = false;
+// }};
+//
+// subject.onCompleted(build);
+//
+// new Verifications() {{
+// repository.createNote(anyInt, anyString, anyBoolean, anyBoolean);
+// times = 1;
+// }};
+// }
@Test
public void WorkInProgressRespect()