Merge pull request #552 from axls/master

Use GitLab's host url to calculate project's ID
This commit is contained in:
Owen Mehegan 2017-08-31 11:24:05 -07:00 committed by GitHub
commit 1e66e387af
9 changed files with 456 additions and 280 deletions

View File

@ -0,0 +1,134 @@
package com.dabsquared.gitlabjenkins.gitlab;
import java.util.List;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApiClient;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Branch;
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Label;
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Project;
import com.dabsquared.gitlabjenkins.gitlab.api.model.User;
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
/**
* Implements {@link GitLabApi} by delegating REST-client calls to RESTEasy proxy.
*
* @author Alexander Leshkin
*
*/
class GitLabApiExtension implements GitLabApi {
private GitLabApiClient client;
private String gitlabHostUrl;
public GitLabApiExtension(GitLabApiClient client, String gitlabHostUrl) {
this.client = client;
this.gitlabHostUrl = gitlabHostUrl;
}
@Override
public String getGitLabHostUrl() {
return gitlabHostUrl;
}
@Override
public Project createProject(String projectName) {
return client.createProject(projectName);
}
@Override
public MergeRequest createMergeRequest(Integer projectId, String sourceBranch, String targetBranch, String title) {
return client.createMergeRequest(projectId, sourceBranch, targetBranch, title);
}
@Override
public Project getProject(String projectName) {
return client.getProject(projectName);
}
@Override
public Project updateProject(String projectId, String name, String path) {
return client.updateProject(projectId, name, path);
}
@Override
public void deleteProject(String projectId) {
client.deleteProject(projectId);
}
@Override
public void addProjectHook(String projectId, String url, Boolean pushEvents, Boolean mergeRequestEvents,
Boolean noteEvents) {
client.addProjectHook(projectId, url, pushEvents, mergeRequestEvents, noteEvents);
}
@Override
public void changeBuildStatus(String projectId, String sha, BuildState state, String ref, String context,
String targetUrl, String description) {
client.changeBuildStatus(projectId, sha, state, ref, context, targetUrl, description);
}
@Override
public void changeBuildStatus(Integer projectId, String sha, BuildState state, String ref, String context,
String targetUrl, String description) {
client.changeBuildStatus(projectId, sha, state, ref, context, targetUrl, description);
}
@Override
public void getCommit(String projectId, String sha) {
client.getCommit(projectId, sha);
}
@Override
public void acceptMergeRequest(Integer projectId, Integer mergeRequestId, String mergeCommitMessage,
boolean shouldRemoveSourceBranch) {
client.acceptMergeRequest(projectId, mergeRequestId, mergeCommitMessage, shouldRemoveSourceBranch);
}
@Override
public void createMergeRequestNote(Integer projectId, Integer mergeRequestId, String body) {
client.createMergeRequestNote(projectId, mergeRequestId, body);
}
@Override
public List<MergeRequest> getMergeRequests(String projectId, State state, int page, int perPage) {
return client.getMergeRequests(projectId, state, page, perPage);
}
@Override
public List<Branch> getBranches(String projectId) {
return client.getBranches(projectId);
}
@Override
public Branch getBranch(String projectId, String branch) {
return client.getBranch(projectId, branch);
}
@Override
public void headCurrentUser() {
client.headCurrentUser();
}
@Override
public User getCurrentUser() {
return client.getCurrentUser();
}
@Override
public User addUser(String email, String username, String name, String password) {
return client.addUser(email, username, name, password);
}
@Override
public User updateUser(String userId, String email, String username, String name, String password) {
return client.updateUser(userId, email, username, name, password);
}
@Override
public List<Label> getLabels(String projectId) {
return client.getLabels(projectId);
}
}

View File

@ -6,6 +6,7 @@ import com.cloudbees.plugins.credentials.domains.DomainRequirement;
import com.dabsquared.gitlabjenkins.connection.GitLabApiToken;
import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApiClient;
import com.dabsquared.gitlabjenkins.util.JsonUtil;
import com.dabsquared.gitlabjenkins.util.LoggerUtil;
import com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider;
@ -82,7 +83,7 @@ public class GitLabClientBuilder {
proxyConfiguration.getPassword());
}
return builder
GitLabApiClient apiClient = builder
.connectionPoolSize(60)
.maxPooledPerRoute(30)
.establishConnectionTimeout(connectionTimeout, TimeUnit.SECONDS)
@ -94,9 +95,10 @@ public class GitLabClientBuilder {
.register(new RemoveAcceptEncodingFilter())
.register(new JaxrsFormProvider())
.build().target(gitlabHostUrl)
.proxyBuilder(GitLabApi.class)
.classloader(GitLabApi.class.getClassLoader())
.proxyBuilder(GitLabApiClient.class)
.classloader(GitLabApiClient.class.getClassLoader())
.build();
return new GitLabApiExtension(apiClient, gitlabHostUrl);
}
public static GitLabApi buildClient(GitLabConnection connection) {

View File

@ -1,173 +1,14 @@
package com.dabsquared.gitlabjenkins.gitlab.api;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Branch;
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Label;
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Project;
import com.dabsquared.gitlabjenkins.gitlab.api.model.User;
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.List;
/**
* @author Robin Müller
* Extends REST-client interface to provide additional methods for plugin's code.
*
* @author Alexander Leshkin
*
*/
@Path("/api/v3")
public interface GitLabApi {
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects")
Project createProject(@FormParam("name") String projectName);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/merge_requests")
MergeRequest createMergeRequest(
@PathParam("projectId") Integer projectId,
@FormParam("source_branch") String sourceBranch,
@FormParam("target_branch") String targetBranch,
@FormParam("title") String title);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectName}")
Project getProject(@PathParam("projectName") String projectName);
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}")
Project updateProject(@PathParam("projectId") String projectId,
@FormParam("name") String name,
@FormParam("path") String path);
@DELETE
@Path("/projects/{projectId}")
void deleteProject(@PathParam("projectId") String projectId);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/hooks")
void addProjectHook(@PathParam("projectId") String projectId,
@FormParam("url") String url,
@FormParam("push_events") Boolean pushEvents,
@FormParam("merge_requests_events") Boolean mergeRequestEvents,
@FormParam("note_events") Boolean noteEvents);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/statuses/{sha}")
void changeBuildStatus(@PathParam("projectId") String projectId,
@PathParam("sha") String sha,
@FormParam("state") BuildState state,
@FormParam("ref") String ref,
@FormParam("context") String context,
@FormParam("target_url") String targetUrl,
@FormParam("description") String description);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/statuses/{sha}")
void changeBuildStatus(@PathParam("projectId") Integer projectId,
@PathParam("sha") String sha,
@FormParam("state") BuildState state,
@FormParam("ref") String ref,
@FormParam("context") String context,
@FormParam("target_url") String targetUrl,
@FormParam("description") String description);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/repository/commits/{sha}")
void getCommit(@PathParam("projectId") String projectId, @PathParam("sha") String sha);
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/merge_requests/{mergeRequestId}/merge")
void acceptMergeRequest(@PathParam("projectId") Integer projectId,
@PathParam("mergeRequestId") Integer mergeRequestId,
@FormParam("merge_commit_message") String mergeCommitMessage,
@FormParam("should_remove_source_branch") boolean shouldRemoveSourceBranch);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/merge_requests/{mergeRequestId}/notes")
void createMergeRequestNote(@PathParam("projectId") Integer projectId,
@PathParam("mergeRequestId") Integer mergeRequestId,
@FormParam("body") String body);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/merge_requests")
List<MergeRequest> getMergeRequests(@PathParam("projectId") String projectId,
@QueryParam("state") State state,
@QueryParam("page") int page,
@QueryParam("per_page") int perPage);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/repository/branches")
List<Branch> getBranches(@PathParam("projectId") String projectId);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/repository/branches/{branch}")
Branch getBranch(@PathParam("projectId") String projectId,
@PathParam("branch") String branch);
@HEAD
@Produces(MediaType.APPLICATION_JSON)
@Path("/user")
void headCurrentUser();
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/user")
User getCurrentUser();
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/users")
User addUser(@FormParam("email") String email,
@FormParam("username") String username,
@FormParam("name") String name,
@FormParam("password") String password);
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/users/{userId}")
User updateUser(@PathParam("userId") String userId,
@FormParam("email") String email,
@FormParam("username") String username,
@FormParam("name") String name,
@FormParam("password") String password);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/labels")
List<Label> getLabels(@PathParam("projectId") String projectId);
public interface GitLabApi extends GitLabApiClient {
/**
* Returns GitLab host base url from plugin confugruation.
*/
String getGitLabHostUrl();
}

View File

@ -0,0 +1,173 @@
package com.dabsquared.gitlabjenkins.gitlab.api;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Branch;
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Label;
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Project;
import com.dabsquared.gitlabjenkins.gitlab.api.model.User;
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.HEAD;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;
import java.util.List;
/**
* @author Robin Müller
*/
@Path("/api/v3")
public interface GitLabApiClient {
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects")
Project createProject(@FormParam("name") String projectName);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/merge_requests")
MergeRequest createMergeRequest(
@PathParam("projectId") Integer projectId,
@FormParam("source_branch") String sourceBranch,
@FormParam("target_branch") String targetBranch,
@FormParam("title") String title);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectName}")
Project getProject(@PathParam("projectName") String projectName);
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}")
Project updateProject(@PathParam("projectId") String projectId,
@FormParam("name") String name,
@FormParam("path") String path);
@DELETE
@Path("/projects/{projectId}")
void deleteProject(@PathParam("projectId") String projectId);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/hooks")
void addProjectHook(@PathParam("projectId") String projectId,
@FormParam("url") String url,
@FormParam("push_events") Boolean pushEvents,
@FormParam("merge_requests_events") Boolean mergeRequestEvents,
@FormParam("note_events") Boolean noteEvents);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/statuses/{sha}")
void changeBuildStatus(@PathParam("projectId") String projectId,
@PathParam("sha") String sha,
@FormParam("state") BuildState state,
@FormParam("ref") String ref,
@FormParam("context") String context,
@FormParam("target_url") String targetUrl,
@FormParam("description") String description);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/statuses/{sha}")
void changeBuildStatus(@PathParam("projectId") Integer projectId,
@PathParam("sha") String sha,
@FormParam("state") BuildState state,
@FormParam("ref") String ref,
@FormParam("context") String context,
@FormParam("target_url") String targetUrl,
@FormParam("description") String description);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/repository/commits/{sha}")
void getCommit(@PathParam("projectId") String projectId, @PathParam("sha") String sha);
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/merge_requests/{mergeRequestId}/merge")
void acceptMergeRequest(@PathParam("projectId") Integer projectId,
@PathParam("mergeRequestId") Integer mergeRequestId,
@FormParam("merge_commit_message") String mergeCommitMessage,
@FormParam("should_remove_source_branch") boolean shouldRemoveSourceBranch);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/merge_requests/{mergeRequestId}/notes")
void createMergeRequestNote(@PathParam("projectId") Integer projectId,
@PathParam("mergeRequestId") Integer mergeRequestId,
@FormParam("body") String body);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/merge_requests")
List<MergeRequest> getMergeRequests(@PathParam("projectId") String projectId,
@QueryParam("state") State state,
@QueryParam("page") int page,
@QueryParam("per_page") int perPage);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/repository/branches")
List<Branch> getBranches(@PathParam("projectId") String projectId);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/repository/branches/{branch}")
Branch getBranch(@PathParam("projectId") String projectId,
@PathParam("branch") String branch);
@HEAD
@Produces(MediaType.APPLICATION_JSON)
@Path("/user")
void headCurrentUser();
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/user")
User getCurrentUser();
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/users")
User addUser(@FormParam("email") String email,
@FormParam("username") String username,
@FormParam("name") String name,
@FormParam("password") String password);
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/users/{userId}")
User updateUser(@PathParam("userId") String userId,
@FormParam("email") String email,
@FormParam("username") String username,
@FormParam("name") String name,
@FormParam("password") String password);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/labels")
List<Label> getLabels(@PathParam("projectId") String projectId);
}

View File

@ -65,7 +65,7 @@ public class GitLabProjectBranchesService {
@Override
public List<String> call() throws Exception {
List<String> result = new ArrayList<>();
String projectId = ProjectIdUtil.retrieveProjectId(sourceRepository);
String projectId = ProjectIdUtil.retrieveProjectId(client, sourceRepository);
for (Branch branch : client.getBranches(projectId)) {
result.add(branch.getName());
}

View File

@ -65,7 +65,7 @@ public class GitLabProjectLabelsService {
@Override
public List<String> call() throws Exception {
List<String> result = new ArrayList<>();
String projectId = ProjectIdUtil.retrieveProjectId(sourceRepository);
String projectId = ProjectIdUtil.retrieveProjectId(client, sourceRepository);
for (Label label : client.getLabels(projectId)) {
result.add(label.getName());
}

View File

@ -50,7 +50,7 @@ public class CommitStatusUpdater {
try {
final String buildUrl = getBuildUrl(build);
for (final GitLabBranchBuild gitLabBranchBuild : retrieveGitlabProjectIds(build, build.getEnvironment(listener))) {
try {
if (existsCommit(client, gitLabBranchBuild.getProjectId(), gitLabBranchBuild.getRevisionHash())) {
@ -101,114 +101,114 @@ public class CommitStatusUpdater {
return Jenkins.getInstance().getRootUrl() + build.getUrl();
}
private static List<GitLabBranchBuild> retrieveGitlabProjectIds(Run<?, ?> build, EnvVars environment) {
LOGGER.log(Level.INFO, "Retrieving gitlab project ids");
final List<GitLabBranchBuild> result = new ArrayList<>();
private static List<GitLabBranchBuild> retrieveGitlabProjectIds(Run<?, ?> build, EnvVars environment) {
LOGGER.log(Level.INFO, "Retrieving gitlab project ids");
final List<GitLabBranchBuild> result = new ArrayList<>();
GitLabWebHookCause cause = build.getCause(GitLabWebHookCause.class);
if (cause != null) {
return Collections.singletonList(new GitLabBranchBuild(cause.getData().getSourceProjectId().toString(),
cause.getData().getLastCommit()));
}
GitLabWebHookCause cause = build.getCause(GitLabWebHookCause.class);
if (cause != null) {
return Collections.singletonList(new GitLabBranchBuild(cause.getData().getSourceProjectId().toString(),
cause.getData().getLastCommit()));
}
final GitLabApi gitLabClient = getClient(build);
if (gitLabClient == null) {
LOGGER.log(Level.WARNING, "No gitlab client found.");
return result;
}
final GitLabApi gitLabClient = getClient(build);
if (gitLabClient == null) {
LOGGER.log(Level.WARNING, "No gitlab client found.");
return result;
}
final List<BuildData> buildDatas = build.getActions(BuildData.class);
if (CollectionUtils.isEmpty(buildDatas)) {
LOGGER.log(Level.INFO, "Build does not contain build data.");
return result;
}
final List<BuildData> buildDatas = build.getActions(BuildData.class);
if (CollectionUtils.isEmpty(buildDatas)) {
LOGGER.log(Level.INFO, "Build does not contain build data.");
return result;
}
if (buildDatas.size() == 1) {
addGitLabBranchBuild(result, getBuildRevision(build), buildDatas.get(0).getRemoteUrls(), environment, gitLabClient);
} else {
final SCMRevisionAction scmRevisionAction = build.getAction(SCMRevisionAction.class);
if (buildDatas.size() == 1) {
addGitLabBranchBuild(result, getBuildRevision(build), buildDatas.get(0).getRemoteUrls(), environment, gitLabClient);
} else {
final SCMRevisionAction scmRevisionAction = build.getAction(SCMRevisionAction.class);
if (scmRevisionAction == null) {
LOGGER.log(Level.INFO, "Build does not contain SCM revision action.");
return result;
}
if (scmRevisionAction == null) {
LOGGER.log(Level.INFO, "Build does not contain SCM revision action.");
return result;
}
final SCMRevision scmRevision = scmRevisionAction.getRevision();
final SCMRevision scmRevision = scmRevisionAction.getRevision();
String scmRevisionHash = null;
if (scmRevision instanceof AbstractGitSCMSource.SCMRevisionImpl) {
scmRevisionHash = ((AbstractGitSCMSource.SCMRevisionImpl) scmRevision).getHash();
}
String scmRevisionHash = null;
if (scmRevision instanceof AbstractGitSCMSource.SCMRevisionImpl) {
scmRevisionHash = ((AbstractGitSCMSource.SCMRevisionImpl) scmRevision).getHash();
}
for (final BuildData buildData : buildDatas) {
for (final Entry<String, Build> buildByBranchName : buildData.getBuildsByBranchName().entrySet()) {
if (buildByBranchName.getValue().getSHA1().equals(ObjectId.fromString(scmRevisionHash))) {
addGitLabBranchBuild(result, scmRevisionHash, buildData.getRemoteUrls(), environment, gitLabClient);
}
}
}
}
for (final BuildData buildData : buildDatas) {
for (final Entry<String, Build> buildByBranchName : buildData.getBuildsByBranchName().entrySet()) {
if (buildByBranchName.getValue().getSHA1().equals(ObjectId.fromString(scmRevisionHash))) {
addGitLabBranchBuild(result, scmRevisionHash, buildData.getRemoteUrls(), environment, gitLabClient);
}
}
}
}
return result;
}
return result;
}
private static String getBuildRevision(Run<?, ?> build) {
GitLabWebHookCause cause = build.getCause(GitLabWebHookCause.class);
if (cause != null) {
return cause.getData().getLastCommit();
}
private static String getBuildRevision(Run<?, ?> build) {
GitLabWebHookCause cause = build.getCause(GitLabWebHookCause.class);
if (cause != null) {
return cause.getData().getLastCommit();
}
BuildData action = build.getAction(BuildData.class);
if (action == null) {
throw new IllegalStateException("No (git-plugin) BuildData associated to current build");
}
Revision lastBuiltRevision = action.getLastBuiltRevision();
BuildData action = build.getAction(BuildData.class);
if (action == null) {
throw new IllegalStateException("No (git-plugin) BuildData associated to current build");
}
Revision lastBuiltRevision = action.getLastBuiltRevision();
if (lastBuiltRevision == null) {
throw new IllegalStateException("Last build has no associated commit");
}
if (lastBuiltRevision == null) {
throw new IllegalStateException("Last build has no associated commit");
}
return action.getLastBuild(lastBuiltRevision.getSha1()).getMarked().getSha1String();
}
return action.getLastBuild(lastBuiltRevision.getSha1()).getMarked().getSha1String();
}
private static void addGitLabBranchBuild(List<GitLabBranchBuild> result, String scmRevisionHash,
Set<String> remoteUrls, EnvVars environment, GitLabApi gitLabClient) {
for (String remoteUrl : remoteUrls) {
try {
LOGGER.log(Level.INFO, "Retrieving the gitlab project id from remote url {0}", remoteUrl);
final String projectNameWithNameSpace = ProjectIdUtil.retrieveProjectId(environment.expand(remoteUrl));
if (StringUtils.isNotBlank(projectNameWithNameSpace)) {
String projectId = projectNameWithNameSpace;
if (projectNameWithNameSpace.contains(".")) {
try {
projectId = gitLabClient.getProject(projectNameWithNameSpace).getId().toString();
} catch (WebApplicationException | ProcessingException e) {
LOGGER.log(Level.SEVERE, String.format("Failed to retrieve projectId for project '%s'",
projectNameWithNameSpace), e);
}
}
result.add(new GitLabBranchBuild(projectId, scmRevisionHash));
}
} catch (ProjectIdUtil.ProjectIdResolutionException e) {
}
}
}
private static void addGitLabBranchBuild(List<GitLabBranchBuild> result, String scmRevisionHash,
Set<String> remoteUrls, EnvVars environment, GitLabApi gitLabClient) {
for (String remoteUrl : remoteUrls) {
try {
LOGGER.log(Level.INFO, "Retrieving the gitlab project id from remote url {0}", remoteUrl);
final String projectNameWithNameSpace = ProjectIdUtil.retrieveProjectId(gitLabClient, environment.expand(remoteUrl));
if (StringUtils.isNotBlank(projectNameWithNameSpace)) {
String projectId = projectNameWithNameSpace;
if (projectNameWithNameSpace.contains(".")) {
try {
projectId = gitLabClient.getProject(projectNameWithNameSpace).getId().toString();
} catch (WebApplicationException | ProcessingException e) {
LOGGER.log(Level.SEVERE, String.format("Failed to retrieve projectId for project '%s'",
projectNameWithNameSpace), e);
}
}
result.add(new GitLabBranchBuild(projectId, scmRevisionHash));
}
} catch (ProjectIdUtil.ProjectIdResolutionException e) {
}
}
}
public static class GitLabBranchBuild {
private final String projectId;
private final String revisionHash;
public GitLabBranchBuild(final String projectId, final String revisionHash) {
this.projectId = projectId;
this.revisionHash = revisionHash;
}
public String getProjectId() {
return this.projectId;
}
public String getRevisionHash() {
return this.revisionHash;
}
private final String projectId;
private final String revisionHash;
public GitLabBranchBuild(final String projectId, final String revisionHash) {
this.projectId = projectId;
this.revisionHash = revisionHash;
}
public String getProjectId() {
return this.projectId;
}
public String getRevisionHash() {
return this.revisionHash;
}
}
}

View File

@ -2,6 +2,8 @@ package com.dabsquared.gitlabjenkins.util;
import org.eclipse.jgit.transport.URIish;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
import java.net.URISyntaxException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@ -11,13 +13,23 @@ import java.util.regex.Pattern;
*/
public final class ProjectIdUtil {
private static final Pattern PROJECT_ID_PATTERN = Pattern.compile("^/?(.*/)?(?<projectId>.*/.*)(\\.git)$");
private static final Pattern PROJECT_ID_PATTERN = Pattern.compile("^/?(?<projectId>.*)(\\.git)$");
private ProjectIdUtil() { }
public static String retrieveProjectId(String remoteUrl) throws ProjectIdResolutionException {
public static String retrieveProjectId(GitLabApi client, String remoteUrl) throws ProjectIdResolutionException {
try {
String projectId = new URIish(remoteUrl).getPath();
String projectId = null;
String baseUri = client.getGitLabHostUrl();
if (baseUri != null && remoteUrl.startsWith(baseUri)) {
projectId = new URIish(remoteUrl.substring(baseUri.length(), remoteUrl.length())).getPath();
} else {
projectId = new URIish(remoteUrl).getPath();
}
if (projectId.startsWith(":")) {
projectId = projectId.substring(1);
}
Matcher matcher = PROJECT_ID_PATTERN.matcher(projectId);
if (matcher.matches()) {
return matcher.group("projectId");

View File

@ -1,13 +1,17 @@
package com.dabsquared.gitlabjenkins.util;
import static com.dabsquared.gitlabjenkins.util.ProjectIdUtilTest.TestData.forRemoteUrl;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;
import static com.dabsquared.gitlabjenkins.util.ProjectIdUtilTest.TestData.forRemoteUrl;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabApi;
/**
* @author Robin Müller
@ -17,14 +21,22 @@ public class ProjectIdUtilTest {
@DataPoints
public static TestData[] testData = {
forRemoteUrl("git@gitlab.com:test/project.git").expectProjectId("test/project"),
forRemoteUrl("https://gitlab.com/test/project.git").expectProjectId("test/project"),
forRemoteUrl("https://myurl.com/gitlab/group/project.git").expectProjectId("group/project")
forRemoteUrl("git@gitlab.com", "git@gitlab.com:test/project.git").expectProjectId("test/project"),
forRemoteUrl("https://gitlab.com", "https://gitlab.com/test/project.git").expectProjectId("test/project"),
forRemoteUrl("https://myurl.com/gitlab", "https://myurl.com/gitlab/group/project.git").expectProjectId("group/project"),
forRemoteUrl("git@gitlab.com", "git@gitlab.com:group/subgroup/project.git").expectProjectId("group/subgroup/project"),
forRemoteUrl("https://myurl.com/gitlab", "https://myurl.com/gitlab/group/subgroup/project.git").expectProjectId("group/subgroup/project"),
forRemoteUrl("https://myurl.com", "https://myurl.com/group/subgroup/project.git").expectProjectId("group/subgroup/project"),
forRemoteUrl("https://myurl.com", "https://myurl.com/group/subgroup/subsubgroup/project.git").expectProjectId("group/subgroup/subsubgroup/project"),
forRemoteUrl("git@gitlab.com", "git@gitlab.com:group/subgroup/subsubgroup/project.git").expectProjectId("group/subgroup/subsubgroup/project"),
};
@Theory
public void retrieveProjectId(TestData testData) throws ProjectIdUtil.ProjectIdResolutionException {
String projectId = ProjectIdUtil.retrieveProjectId(testData.remoteUrl);
GitLabApi client = mock(GitLabApi.class);
when(client.getGitLabHostUrl()).thenReturn(testData.baseUrl);
String projectId = ProjectIdUtil.retrieveProjectId(client, testData.remoteUrl);
assertThat(projectId, is(testData.expectedProjectId));
}
@ -32,10 +44,12 @@ public class ProjectIdUtilTest {
static final class TestData {
private final String baseUrl;
private final String remoteUrl;
private String expectedProjectId;
private TestData(String remoteUrl) {
private TestData(String baseUrl, String remoteUrl) {
this.baseUrl = baseUrl;
this.remoteUrl = remoteUrl;
}
@ -49,8 +63,8 @@ public class ProjectIdUtilTest {
return remoteUrl;
}
static TestData forRemoteUrl(String remoteUrl) {
return new TestData(remoteUrl);
static TestData forRemoteUrl(String baseUrl, String remoteUrl) {
return new TestData(baseUrl, remoteUrl);
}
}
}