Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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,
Expand All @@ -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());
Copy link
Contributor

@karanagai karanagai Sep 6, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return value of getVcsBranch() is marked as @Nullable

if (m.find( )) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is minor, but worth noticing: GitLab branch name may contain slashes, so it seems using find() you in theory may match a branch name that is not a merge request, but its name just contain something that is matched by the pattern.

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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The HTTP request is made synchronously within the CommitStatusPublisherListener event handlers execution. It may cause the control not to be returned to the code thatr calls these event handlers promptly enough, which is not desirable.

} 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) {
Expand Down Expand Up @@ -160,4 +191,72 @@ private String getPrivateToken() {
return myParams.get(Constants.GITLAB_TOKEN);
}

private abstract class JsonResponseProcessor<T> extends DefaultHttpResponseProcessor {

private final Class<T> myInfoClass;
private T myInfo;

JsonResponseProcessor(Class<T> 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<GitLabMRInfo> {

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;
}
}

}
Original file line number Diff line number Diff line change
@@ -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;
}