diff --git a/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/gitlab/GitlabPublisher.java b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/gitlab/GitlabPublisher.java index 47daa9f5..5cb0a103 100644 --- a/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/gitlab/GitlabPublisher.java +++ b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/gitlab/GitlabPublisher.java @@ -13,6 +13,16 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import jetbrains.buildServer.commitPublisher.gitlab.data.GitLabMRInfo; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.io.IOException; +import java.util.*; + import java.util.Collections; import java.util.Map; @@ -83,7 +93,6 @@ public boolean buildInterrupted(@NotNull SFinishedBuild build, @NotNull BuildRev return true; } - private void publish(@NotNull SBuild build, @NotNull BuildRevision revision, @NotNull GitlabBuildStatus status, @@ -98,6 +107,28 @@ private void publish(@NotNull SBuild build, throw new PublisherException("Cannot parse repository URL from VCS root " + root.getName()); String message = createMessage(status, build, revision, myLinks.getViewResultsUrl(build), description); + + Pattern r = Pattern.compile("/merge-requests/([0-9]+)/"); + Matcher m = r.matcher(revision.getRepositoryVersion().getVcsBranch()); + if (m.find( )) { + String mr_number = m.group(1); + + String url = GitlabSettings.getProjectsUrl(getApiUrl(), repository.owner(), repository.repositoryName()) + "/merge_requests/" + mr_number; + + MRInfoResponseProcessor processorMR = new MRInfoResponseProcessor(); + + try { + HttpHelper.get(url, null, null, Collections.singletonMap("PRIVATE-TOKEN", getPrivateToken()), BaseCommitStatusPublisher.DEFAULT_CONNECTION_TIMEOUT, processorMR); + } catch (Exception ex) { + throw new PublisherException(String.format("GitLab publisher has failed to connect to %s/%s repository", repository.owner(), repository.repositoryName()), ex); + } + + String urlCommit = getApiUrl() + "/projects/" + processorMR.source_project_id() + "/statuses/" + revision.getRevision(); + postAsync(urlCommit, null, null, message, ContentType.APPLICATION_JSON, Collections.singletonMap("PRIVATE-TOKEN", getPrivateToken()), LogUtil.describe(build)); + + return; + } + try { publish(revision.getRevision(), message, repository, LogUtil.describe(build)); } catch (Exception e) { @@ -160,4 +191,72 @@ private String getPrivateToken() { return myParams.get(Constants.GITLAB_TOKEN); } +private abstract class JsonResponseProcessor extends DefaultHttpResponseProcessor { + + private final Class myInfoClass; + private T myInfo; + + JsonResponseProcessor(Class infoClass) { + myInfoClass = infoClass; + } + + T getInfo() { + return myInfo; + } + + @Override + public void processResponse(HttpResponse response) throws HttpPublisherException, IOException { + + super.processResponse(response); + + final HttpEntity entity = response.getEntity(); + if (null == entity) { + throw new HttpPublisherException("GitLab publisher has received no response"); + } + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + entity.writeTo(bos); + final String json = bos.toString("utf-8"); + myInfo = myGson.fromJson(json, myInfoClass); + } +} + +private class MRInfoResponseProcessor extends JsonResponseProcessor { + + private String _id; + private String _iid; + private String _source_project_id; + private String _target_project_id; + + + MRInfoResponseProcessor() { + super(GitLabMRInfo.class); + } + + String id() { + return _id; + } + String iid() { + return _iid; + } + String source_project_id() { + return _source_project_id; + } + String target_project_id() { + return _target_project_id; + } + + @Override + public void processResponse(HttpResponse response) throws HttpPublisherException, IOException { + super.processResponse(response); + GitLabMRInfo userInfo = getInfo(); + if (null == userInfo || null == userInfo.id) { + throw new HttpPublisherException("GitLab publisher has received a malformed response"); + } + _id = userInfo.id; + _iid = userInfo.iid; + _source_project_id = userInfo.source_project_id; + _target_project_id = userInfo.target_project_id; + } +} + } diff --git a/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/gitlab/data/GitLabMRInfo.java b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/gitlab/data/GitLabMRInfo.java new file mode 100644 index 00000000..ca870012 --- /dev/null +++ b/commit-status-publisher-server/src/main/java/jetbrains/buildServer/commitPublisher/gitlab/data/GitLabMRInfo.java @@ -0,0 +1,8 @@ +package jetbrains.buildServer.commitPublisher.gitlab.data; + +public class GitLabMRInfo { + public String id; + public String iid; + public String source_project_id; + public String target_project_id; +}