diff --git a/src/main/java/com/dabsquared/gitlabjenkins/gitlab/api/GitLabApi.java b/src/main/java/com/dabsquared/gitlabjenkins/gitlab/api/GitLabApi.java
index e21598a..cf49ad2 100644
--- a/src/main/java/com/dabsquared/gitlabjenkins/gitlab/api/GitLabApi.java
+++ b/src/main/java/com/dabsquared/gitlabjenkins/gitlab/api/GitLabApi.java
@@ -100,6 +100,13 @@ public interface GitLabApi {
@QueryParam("merge_commit_message") String mergeCommitMessage,
@QueryParam("should_remove_source_branch") boolean shouldRemoveSourceBranch);
+ @POST
+ @Produces(MediaType.APPLICATION_JSON)
+ @Path("/projects/{projectId}/merge_requests/{mergeRequestId}/notes")
+ void createMergeRequestNote(@PathParam("projectId") Integer projectId,
+ @PathParam("mergeRequestId") Integer mergeRequestId,
+ @QueryParam("body") String body);
+
@POST
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/merge_requests/{mergeRequestId}/notes")
diff --git a/src/main/java/com/dabsquared/gitlabjenkins/workflow/AddGitLabMergeRequestCommentStep.java b/src/main/java/com/dabsquared/gitlabjenkins/workflow/AddGitLabMergeRequestCommentStep.java
new file mode 100644
index 0000000..35af13e
--- /dev/null
+++ b/src/main/java/com/dabsquared/gitlabjenkins/workflow/AddGitLabMergeRequestCommentStep.java
@@ -0,0 +1,123 @@
+package com.dabsquared.gitlabjenkins.workflow;
+
+import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
+import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
+import hudson.Extension;
+import hudson.model.Run;
+import hudson.model.TaskListener;
+import org.apache.commons.lang.StringUtils;
+import org.jenkinsci.plugins.workflow.steps.AbstractStepDescriptorImpl;
+import org.jenkinsci.plugins.workflow.steps.AbstractStepImpl;
+import org.jenkinsci.plugins.workflow.steps.AbstractSynchronousStepExecution;
+import org.jenkinsci.plugins.workflow.steps.StepContext;
+import org.jenkinsci.plugins.workflow.steps.StepContextParameter;
+import org.kohsuke.stapler.DataBoundConstructor;
+import org.kohsuke.stapler.export.ExportedBean;
+
+import javax.inject.Inject;
+import javax.ws.rs.ProcessingException;
+import javax.ws.rs.WebApplicationException;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty.getClient;
+
+/**
+ * @author Robin Müller
+ */
+@ExportedBean
+public class AddGitLabMergeRequestCommentStep extends AbstractStepImpl {
+
+ private static final Logger LOGGER = Logger.getLogger(AddGitLabMergeRequestCommentStep.class.getName());
+
+ private String comment;
+
+ @DataBoundConstructor
+ public AddGitLabMergeRequestCommentStep(String comment) {
+ this.comment = StringUtils.isEmpty(comment) ? null : comment;
+ }
+
+ public String getComment() {
+ return comment;
+ }
+
+ public static class Execution extends AbstractSynchronousStepExecution {
+ private static final long serialVersionUID = 1;
+
+ @StepContextParameter
+ private transient Run, ?> run;
+
+ @Inject
+ private transient AddGitLabMergeRequestCommentStep step;
+
+ @Override
+ protected Void run() throws Exception {
+ GitLabWebHookCause cause = run.getCause(GitLabWebHookCause.class);
+ if (cause != null) {
+ Integer projectId = cause.getData().getTargetProjectId();
+ Integer mergeRequestId = cause.getData().getMergeRequestId();
+ if (projectId != null && mergeRequestId != null) {
+ GitLabApi client = getClient(run);
+ if (client == null) {
+ println("No GitLab connection configured");
+ } else {
+ try {
+ client.createMergeRequestNote(projectId, mergeRequestId, step.getComment());
+ } catch (WebApplicationException | ProcessingException e) {
+ printf("Failed to add comment on Merge Request for project '%s': %s%n", projectId, e.getMessage());
+ LOGGER.log(Level.SEVERE, String.format("Failed to add comment on Merge Request for project '%s'", projectId), 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 AbstractStepDescriptorImpl {
+ public DescriptorImpl() {
+ super(Execution.class);
+ }
+
+ @Override
+ public String getDisplayName() {
+ return "Add comment on GitLab Merge Request";
+ }
+
+ @Override
+ public String getFunctionName() {
+ return "addGitLabMRComment";
+ }
+ }
+}
diff --git a/src/main/resources/com/dabsquared/gitlabjenkins/workflow/AddGitLabMergeRequestCommentStep/config.jelly b/src/main/resources/com/dabsquared/gitlabjenkins/workflow/AddGitLabMergeRequestCommentStep/config.jelly
new file mode 100644
index 0000000..081a387
--- /dev/null
+++ b/src/main/resources/com/dabsquared/gitlabjenkins/workflow/AddGitLabMergeRequestCommentStep/config.jelly
@@ -0,0 +1,6 @@
+
+
+
+
+
+