Fix to support NameSpace or ProjectName with dot in it
According to Rails documentation(http://guides.rubyonrails.org/v3.1.3/routing.html section 3.2 Dynamic Segments) Rail use a dot as separator for formatted routes. In this case if we have dot in ProjectId constructed from(namespace + projectname) all request except getSingleProject(http://docs.gitlab.com/ce/api/projects.html#get-single-project) fail with message "Failed to update Gitlab commit status for project Name.Test/Repo': HTTP 500 Internal Server Error" To support This case we check if projectId have dot inside of it if it has execute getSingleProject request and extract Integer projectId to operate with if it hasn't use prepared projectId(Namespace + ProjectName)
This commit is contained in:
parent
1adc6830ba
commit
fad9c5cfcd
|
@ -4,20 +4,24 @@ import com.dabsquared.gitlabjenkins.cause.GitLabWebHookCause;
|
|||
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
|
||||
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
|
||||
import hudson.EnvVars;
|
||||
import hudson.model.Run;
|
||||
import hudson.model.TaskListener;
|
||||
import hudson.plugins.git.util.BuildData;
|
||||
import jenkins.model.Jenkins;
|
||||
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.ws.rs.NotFoundException;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
|
||||
import hudson.EnvVars;
|
||||
import hudson.model.Run;
|
||||
import hudson.model.TaskListener;
|
||||
import hudson.plugins.git.util.BuildData;
|
||||
import jenkins.model.Jenkins;
|
||||
|
||||
/**
|
||||
* @author Robin Müller
|
||||
*/
|
||||
|
@ -26,15 +30,17 @@ public class CommitStatusUpdater {
|
|||
private final static Logger LOGGER = Logger.getLogger(CommitStatusUpdater.class.getName());
|
||||
|
||||
public static void updateCommitStatus(Run<?, ?> build, TaskListener listener, BuildState state) {
|
||||
GitLabApi client = getClient(build);
|
||||
if (client == null) {
|
||||
println(listener, "No GitLab connection configured");
|
||||
return;
|
||||
}
|
||||
String commitHash = getBuildRevision(build);
|
||||
String buildUrl = getBuildUrl(build);
|
||||
try {
|
||||
for (String gitlabProjectId : retrieveGitlabProjectIds(build, build.getEnvironment(listener))) {
|
||||
try {
|
||||
GitLabApi client = getClient(build);
|
||||
if (client == null) {
|
||||
println(listener, "No GitLab connection configured");
|
||||
} else if (existsCommit(client, gitlabProjectId, commitHash)) {
|
||||
if (existsCommit(client, gitlabProjectId, commitHash)) {
|
||||
client.changeBuildStatus(gitlabProjectId, commitHash, state, getBuildBranch(build), "jenkins", buildUrl, null);
|
||||
}
|
||||
} catch (WebApplicationException e) {
|
||||
|
@ -98,9 +104,20 @@ public class CommitStatusUpdater {
|
|||
|
||||
private static List<String> retrieveGitlabProjectIds(Run<?, ?> build, EnvVars environment) {
|
||||
List<String> result = new ArrayList<>();
|
||||
GitLabApi gitLabClient = getClient(build);
|
||||
if (gitLabClient == null) {
|
||||
return result;
|
||||
}
|
||||
for (String remoteUrl : build.getAction(BuildData.class).getRemoteUrls()) {
|
||||
try {
|
||||
result.add(ProjectIdUtil.retrieveProjectId(environment.expand(remoteUrl)));
|
||||
String projectNameWithNameSpace = ProjectIdUtil.retrieveProjectId(environment.expand(remoteUrl));
|
||||
if (StringUtils.isNotBlank(projectNameWithNameSpace)) {
|
||||
String projectId = projectNameWithNameSpace;
|
||||
if (projectNameWithNameSpace.contains(".")) {
|
||||
projectId = gitLabClient.getProject(projectNameWithNameSpace).getId().toString();
|
||||
}
|
||||
result.add(projectId);
|
||||
}
|
||||
} catch (ProjectIdUtil.ProjectIdResolutionException e) {
|
||||
// nothing to do
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ import hudson.plugins.git.util.Build;
|
|||
import hudson.plugins.git.util.BuildData;
|
||||
import hudson.util.Secret;
|
||||
import jenkins.model.Jenkins;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl;
|
||||
|
@ -34,6 +36,7 @@ import org.mockito.stubbing.Answer;
|
|||
import org.mockserver.client.server.MockServerClient;
|
||||
import org.mockserver.junit.MockServerRule;
|
||||
import org.mockserver.model.HttpRequest;
|
||||
import org.mockserver.model.HttpResponse;
|
||||
import org.mockserver.verify.VerificationTimes;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
@ -94,8 +97,8 @@ public class GitLabCommitStatusPublisherTest {
|
|||
@Test
|
||||
public void running() throws UnsupportedEncodingException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareExistsCommitWithSuccessResponse("test/project", "123abc"),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", "123abc", jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running)
|
||||
prepareExistsCommitWithSuccessResponse("test/project", "123abc"),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("test/project", "123abc", jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running)
|
||||
};
|
||||
AbstractBuild build = mockBuild("123abc", "/build/123", GIT_LAB_CONNECTION, null, "test/project");
|
||||
|
||||
|
@ -105,6 +108,21 @@ public class GitLabCommitStatusPublisherTest {
|
|||
mockServerClient.verify(requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runningWithDotInProjectId() throws IOException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
prepareGetProjectResponse("test/project.test",1),
|
||||
prepareExistsCommitWithSuccessResponse("1", "123abc"),
|
||||
prepareUpdateCommitStatusWithSuccessResponse("1", "123abc", jenkins.getInstance().getRootUrl() + "/build/123", BuildState.running)
|
||||
};
|
||||
AbstractBuild build = mockBuild("123abc", "/build/123", GIT_LAB_CONNECTION, null, "test/project.test");
|
||||
|
||||
GitLabCommitStatusPublisher publisher = new GitLabCommitStatusPublisher();
|
||||
publisher.prebuild(build, listener);
|
||||
|
||||
mockServerClient.verify(requests);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void canceled() throws IOException, InterruptedException {
|
||||
HttpRequest[] requests = new HttpRequest[] {
|
||||
|
@ -198,6 +216,7 @@ public class GitLabCommitStatusPublisherTest {
|
|||
return updateCommitStatus;
|
||||
}
|
||||
|
||||
|
||||
private HttpRequest prepareUpdateCommitStatus(String projectId, String sha, String targetUrl, BuildState state) throws UnsupportedEncodingException {
|
||||
return request()
|
||||
.withPath("/gitlab/api/v3/projects/" + URLEncoder.encode(projectId, "UTF-8") + "/statuses/" + sha)
|
||||
|
@ -221,6 +240,19 @@ public class GitLabCommitStatusPublisherTest {
|
|||
.withHeader("PRIVATE-TOKEN", "secret");
|
||||
}
|
||||
|
||||
private HttpRequest prepareGetProjectResponse(String projectName, int projectId) throws IOException {
|
||||
HttpRequest request= request()
|
||||
.withPath("/gitlab/api/v3/projects/" + URLEncoder.encode(projectName, "UTF-8"))
|
||||
.withMethod("GET")
|
||||
. withHeader("PRIVATE-TOKEN", "secret");
|
||||
|
||||
HttpResponse response = response().withBody(getSingleProjectJson("GetSingleProject.json",projectName,projectId));
|
||||
|
||||
response.withHeader("Content-Type", "application/json");
|
||||
mockServerClient.when(request).respond(response.withStatusCode(200));
|
||||
return request;
|
||||
}
|
||||
|
||||
private AbstractBuild mockBuild(String sha, String buildUrl, String gitLabConnection, Result result, String... remoteUrls) {
|
||||
AbstractBuild build = mock(AbstractBuild.class);
|
||||
BuildData buildData = mock(BuildData.class);
|
||||
|
@ -251,4 +283,12 @@ public class GitLabCommitStatusPublisherTest {
|
|||
}
|
||||
return build;
|
||||
}
|
||||
private String getSingleProjectJson(String name,String projectNameWithNamespace, int porjectId) throws IOException {
|
||||
String nameSpace = projectNameWithNamespace.split("/")[0];
|
||||
String projectName = projectNameWithNamespace.split("/")[1];
|
||||
return IOUtils.toString(getClass().getResourceAsStream(name))
|
||||
.replace("${projectId}", porjectId + "")
|
||||
.replace("${nameSpace}", nameSpace)
|
||||
.replace("${projectName}", projectName);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
{
|
||||
"id": "${projectId}",
|
||||
"description": "",
|
||||
"default_branch": "master",
|
||||
"tag_list": [],
|
||||
"public": false,
|
||||
"archived": false,
|
||||
"visibility_level": 10,
|
||||
"ssh_url_to_repo": "git@localhost:${nameSpace}/${projectName}.git",
|
||||
"http_url_to_repo": "https://localhost/${nameSpace}/${projectName}.git",
|
||||
"web_url": "https://localhost/${nameSpace}/${projectName}",
|
||||
"name": "${projectName}",
|
||||
"name_with_namespace": "${nameSpace} / ${projectName}",
|
||||
"path": "${projectName}",
|
||||
"path_with_namespace": "${nameSpace}/${projectName}",
|
||||
"issues_enabled": true,
|
||||
"merge_requests_enabled": true,
|
||||
"wiki_enabled": true,
|
||||
"builds_enabled": true,
|
||||
"snippets_enabled": false,
|
||||
"created_at": "2016-04-08T13:20:40.951Z",
|
||||
"last_activity_at": "2016-05-18T12:55:15.322Z",
|
||||
"shared_runners_enabled": true,
|
||||
"creator_id": 1,
|
||||
"namespace": {
|
||||
"id": 159,
|
||||
"name": "${nameSpace}",
|
||||
"path": "${nameSpace}",
|
||||
"owner_id": null,
|
||||
"created_at": "2016-04-08T13:18:08.233Z",
|
||||
"updated_at": "2016-04-08T13:18:08.233Z",
|
||||
"description": "",
|
||||
"avatar": {
|
||||
"url": null
|
||||
},
|
||||
"share_with_group_lock": false,
|
||||
"visibility_level": 20
|
||||
},
|
||||
"avatar_url": null,
|
||||
"star_count": 2,
|
||||
"forks_count": 0,
|
||||
"open_issues_count": 0,
|
||||
"runners_token": "nR-uhvbge5MTFyBimJ7D",
|
||||
"public_builds": true,
|
||||
"permissions": {
|
||||
"project_access": {
|
||||
"access_level": 40,
|
||||
"notification_level": 3
|
||||
},
|
||||
"group_access": null
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue