支持构建成功回评PR

This commit is contained in:
yashin 2018-07-02 16:58:27 +08:00
parent b87f0b6e15
commit 966f9f80c4
41 changed files with 191 additions and 2154 deletions

View File

@ -9,11 +9,9 @@ import com.dabsquared.gitlabjenkins.gitlab.hook.model.NoteHook;
import com.dabsquared.gitlabjenkins.gitlab.hook.model.PipelineHook; import com.dabsquared.gitlabjenkins.gitlab.hook.model.PipelineHook;
import com.dabsquared.gitlabjenkins.gitlab.hook.model.PushHook; import com.dabsquared.gitlabjenkins.gitlab.hook.model.PushHook;
import com.dabsquared.gitlabjenkins.publisher.GitLabAcceptMergeRequestPublisher; import com.dabsquared.gitlabjenkins.publisher.GitLabAcceptMergeRequestPublisher;
import com.dabsquared.gitlabjenkins.publisher.GitLabCommitStatusPublisher;
import com.dabsquared.gitlabjenkins.publisher.GitLabMessagePublisher; import com.dabsquared.gitlabjenkins.publisher.GitLabMessagePublisher;
import com.dabsquared.gitlabjenkins.publisher.GitLabVotePublisher; import com.dabsquared.gitlabjenkins.publisher.GitLabVotePublisher;
import com.dabsquared.gitlabjenkins.trigger.TriggerOpenMergeRequest; import com.dabsquared.gitlabjenkins.trigger.TriggerOpenMergeRequest;
import com.dabsquared.gitlabjenkins.trigger.branch.ProjectBranchesProvider;
import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilter; import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilter;
import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilterFactory; import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilterFactory;
import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilterType; import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilterType;
@ -24,7 +22,6 @@ import com.dabsquared.gitlabjenkins.trigger.handler.merge.MergeRequestHookTrigge
import com.dabsquared.gitlabjenkins.trigger.handler.note.NoteHookTriggerHandler; import com.dabsquared.gitlabjenkins.trigger.handler.note.NoteHookTriggerHandler;
import com.dabsquared.gitlabjenkins.trigger.handler.pipeline.PipelineHookTriggerHandler; import com.dabsquared.gitlabjenkins.trigger.handler.pipeline.PipelineHookTriggerHandler;
import com.dabsquared.gitlabjenkins.trigger.handler.push.PushHookTriggerHandler; import com.dabsquared.gitlabjenkins.trigger.handler.push.PushHookTriggerHandler;
import com.dabsquared.gitlabjenkins.trigger.label.ProjectLabelsProvider;
import com.dabsquared.gitlabjenkins.webhook.GitLabWebHook; import com.dabsquared.gitlabjenkins.webhook.GitLabWebHook;
import hudson.Extension; import hudson.Extension;
import hudson.Util; import hudson.Util;
@ -175,9 +172,6 @@ public class GitLabPushTrigger extends Trigger<Job<?, ?>> {
for (AbstractProject<?, ?> project : Jenkins.getInstance().getAllItems(AbstractProject.class)) { for (AbstractProject<?, ?> project : Jenkins.getInstance().getAllItems(AbstractProject.class)) {
GitLabPushTrigger trigger = project.getTrigger(GitLabPushTrigger.class); GitLabPushTrigger trigger = project.getTrigger(GitLabPushTrigger.class);
if (trigger != null) { if (trigger != null) {
if (trigger.addCiMessage) {
project.getPublishersList().add(new GitLabCommitStatusPublisher("jenkins", false));
}
project.addProperty(new GitLabConnectionProperty(defaultConnectionName)); project.addProperty(new GitLabConnectionProperty(defaultConnectionName));
project.save(); project.save();
} }
@ -572,43 +566,12 @@ public class GitLabPushTrigger extends Trigger<Job<?, ?>> {
return super.configure(req, formData); return super.configure(req, formData);
} }
public ListBoxModel doFillTriggerOpenMergeRequestOnPushItems(@QueryParameter String triggerOpenMergeRequestOnPush) { // public ListBoxModel doFillTriggerOpenMergeRequestOnPushItems(@QueryParameter String triggerOpenMergeRequestOnPush) {
return new ListBoxModel(new Option("Never", "never", triggerOpenMergeRequestOnPush.matches("never")), // return new ListBoxModel(new Option("Never", "never", triggerOpenMergeRequestOnPush.matches("never")),
new Option("On push to source branch", "source", triggerOpenMergeRequestOnPush.matches("source")), // new Option("On push to source branch", "source", triggerOpenMergeRequestOnPush.matches("source")),
new Option("On push to source or target branch", "both", triggerOpenMergeRequestOnPush.matches("both"))); // new Option("On push to source or target branch", "both", triggerOpenMergeRequestOnPush.matches("both")));
} // }
public AutoCompletionCandidates doAutoCompleteIncludeBranchesSpec(@AncestorInPath final Job<?, ?> job, @QueryParameter final String value) {
return ProjectBranchesProvider.instance().doAutoCompleteBranchesSpec(job, value);
}
public AutoCompletionCandidates doAutoCompleteExcludeBranchesSpec(@AncestorInPath final Job<?, ?> job, @QueryParameter final String value) {
return ProjectBranchesProvider.instance().doAutoCompleteBranchesSpec(job, value);
}
public FormValidation doCheckIncludeBranchesSpec(@AncestorInPath final Job<?, ?> project, @QueryParameter final String value) {
return ProjectBranchesProvider.instance().doCheckBranchesSpec(project, value);
}
public FormValidation doCheckExcludeBranchesSpec(@AncestorInPath final Job<?, ?> project, @QueryParameter final String value) {
return ProjectBranchesProvider.instance().doCheckBranchesSpec(project, value);
}
public AutoCompletionCandidates doAutoCompleteIncludeMergeRequestLabels(@AncestorInPath final Job<?, ?> job, @QueryParameter final String value) {
return ProjectLabelsProvider.instance().doAutoCompleteLabels(job, value);
}
public AutoCompletionCandidates doAutoCompleteExcludeMergeRequestLabels(@AncestorInPath final Job<?, ?> job, @QueryParameter final String value) {
return ProjectLabelsProvider.instance().doAutoCompleteLabels(job, value);
}
public FormValidation doCheckIncludeMergeRequestLabels(@AncestorInPath final Job<?, ?> project, @QueryParameter final String value) {
return ProjectLabelsProvider.instance().doCheckLabels(project, value);
}
public FormValidation doCheckExcludeMergeRequestLabels(@AncestorInPath final Job<?, ?> project, @QueryParameter final String value) {
return ProjectLabelsProvider.instance().doCheckLabels(project, value);
}
public void doGenerateSecretToken(@AncestorInPath final Job<?, ?> project, StaplerResponse response) { public void doGenerateSecretToken(@AncestorInPath final Job<?, ?> project, StaplerResponse response) {
byte[] random = new byte[16]; // 16x8=128bit worth of randomness, since we use md5 digest as the API token byte[] random = new byte[16]; // 16x8=128bit worth of randomness, since we use md5 digest as the API token

View File

@ -21,6 +21,7 @@ public final class CauseData {
private final Integer sourceProjectId; private final Integer sourceProjectId;
private final Integer targetProjectId; private final Integer targetProjectId;
private final String branch; private final String branch;
private final String pathWithNamespace;
private final String sourceBranch; private final String sourceBranch;
private final String userName; private final String userName;
private final String userEmail; private final String userEmail;
@ -66,7 +67,7 @@ public final class CauseData {
Integer mergeRequestIid, Integer mergeRequestTargetProjectId, String targetBranch, String targetRepoName, String targetNamespace, String targetRepoSshUrl, Integer mergeRequestIid, Integer mergeRequestTargetProjectId, String targetBranch, String targetRepoName, String targetNamespace, String targetRepoSshUrl,
String targetRepoHttpUrl, String triggeredByUser, String before, String after, String lastCommit, String targetProjectUrl, String targetRepoHttpUrl, String triggeredByUser, String before, String after, String lastCommit, String targetProjectUrl,
String triggerPhrase, String mergeRequestState, String mergedByUser, String mergeRequestAssignee, String ref, String isTag, String triggerPhrase, String mergeRequestState, String mergedByUser, String mergeRequestAssignee, String ref, String isTag,
String sha, String beforeSha, String status, String stages, String createdAt, String finishedAt, String buildDuration) { String sha, String beforeSha, String status, String stages, String createdAt, String finishedAt, String buildDuration, String pathWithNamespace) {
this.actionType = checkNotNull(actionType, "actionType must not be null."); this.actionType = checkNotNull(actionType, "actionType must not be null.");
this.sourceProjectId = checkNotNull(sourceProjectId, "sourceProjectId must not be null."); this.sourceProjectId = checkNotNull(sourceProjectId, "sourceProjectId must not be null.");
this.targetProjectId = checkNotNull(targetProjectId, "targetProjectId must not be null."); this.targetProjectId = checkNotNull(targetProjectId, "targetProjectId must not be null.");
@ -108,6 +109,7 @@ public final class CauseData {
this.createdAt = createdAt; this.createdAt = createdAt;
this.finishedAt = finishedAt; this.finishedAt = finishedAt;
this.buildDuration = buildDuration; this.buildDuration = buildDuration;
this.pathWithNamespace = pathWithNamespace;
} }
public Map<String, String> getBuildVariables() { public Map<String, String> getBuildVariables() {
@ -212,6 +214,8 @@ public final class CauseData {
return mergeRequestDescription; return mergeRequestDescription;
} }
public String getPathWithNamespace() { return pathWithNamespace; }
public Integer getMergeRequestId() { public Integer getMergeRequestId() {
return mergeRequestId; return mergeRequestId;
} }
@ -305,7 +309,7 @@ public final class CauseData {
} }
return new MergeRequest(mergeRequestId, mergeRequestIid, sourceBranch, targetBranch, mergeRequestTitle, return new MergeRequest(mergeRequestId, mergeRequestIid, sourceBranch, targetBranch, mergeRequestTitle,
sourceProjectId, targetProjectId, mergeRequestDescription, mergeRequestState); sourceProjectId, targetProjectId, mergeRequestDescription, mergeRequestState, pathWithNamespace);
} }
@Override @Override
@ -358,6 +362,7 @@ public final class CauseData {
.append(createdAt, causeData.getCreatedAt()) .append(createdAt, causeData.getCreatedAt())
.append(finishedAt, causeData.getFinishedAt()) .append(finishedAt, causeData.getFinishedAt())
.append(buildDuration, causeData.getBuildDuration()) .append(buildDuration, causeData.getBuildDuration())
.append(pathWithNamespace, causeData.getPathWithNamespace())
.isEquals(); .isEquals();
} }
@ -404,6 +409,7 @@ public final class CauseData {
.append(createdAt) .append(createdAt)
.append(finishedAt) .append(finishedAt)
.append(buildDuration) .append(buildDuration)
.append(pathWithNamespace)
.toHashCode(); .toHashCode();
} }
@ -450,6 +456,7 @@ public final class CauseData {
.append("createdAt", createdAt) .append("createdAt", createdAt)
.append("finishedAt", finishedAt) .append("finishedAt", finishedAt)
.append("duration", buildDuration) .append("duration", buildDuration)
.append("pathWithNamespace", pathWithNamespace)
.toString(); .toString();
} }

View File

@ -11,7 +11,7 @@ import com.cloudbees.plugins.credentials.domains.Domain;
import com.cloudbees.plugins.credentials.domains.DomainRequirement; import com.cloudbees.plugins.credentials.domains.DomainRequirement;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient; import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder; import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder;
import com.dabsquared.gitlabjenkins.gitlab.api.impl.AutodetectGitLabClientBuilder; import com.dabsquared.gitlabjenkins.gitlab.api.impl.GiteeV5ClientBuilder;
import hudson.init.InitMilestone; import hudson.init.InitMilestone;
import hudson.init.Initializer; import hudson.init.Initializer;
import hudson.model.Item; import hudson.model.Item;
@ -52,7 +52,7 @@ public class GitLabConnection {
name, name,
url, url,
apiTokenId, apiTokenId,
new AutodetectGitLabClientBuilder(), new GiteeV5ClientBuilder(),
ignoreCertificateErrors, ignoreCertificateErrors,
connectionTimeout, connectionTimeout,
readTimeout readTimeout
@ -137,10 +137,10 @@ public class GitLabConnection {
protected GitLabConnection readResolve() { protected GitLabConnection readResolve() {
if (connectionTimeout == null || readTimeout == null) { if (connectionTimeout == null || readTimeout == null) {
return new GitLabConnection(name, url, apiTokenId, new AutodetectGitLabClientBuilder(), ignoreCertificateErrors, 10, 10); return new GitLabConnection(name, url, apiTokenId, new GiteeV5ClientBuilder(), ignoreCertificateErrors, 10, 10);
} }
if (clientBuilder == null) { if (clientBuilder == null) {
return new GitLabConnection(name, url, apiTokenId, new AutodetectGitLabClientBuilder(), ignoreCertificateErrors, connectionTimeout, readTimeout); return new GitLabConnection(name, url, apiTokenId, new GiteeV5ClientBuilder(), ignoreCertificateErrors, connectionTimeout, readTimeout);
} }
return this; return this;

View File

@ -8,41 +8,11 @@ import java.util.List;
public interface GitLabClient { public interface GitLabClient {
String getHostUrl(); String getHostUrl();
Project createProject(String projectName);
MergeRequest createMergeRequest(Integer projectId, String sourceBranch, String targetBranch, String title);
Project getProject(String projectName);
Project updateProject(String projectId, String name, String path);
void deleteProject(String projectId);
void addProjectHook(String projectId, String url, Boolean pushEvents, Boolean mergeRequestEvents, Boolean noteEvents);
void changeBuildStatus(String projectId, String sha, BuildState state, String ref, String context, String targetUrl, String description);
void changeBuildStatus(Integer projectId, String sha, BuildState state, String ref, String context, String targetUrl, String description);
void getCommit(String projectId, String sha);
void acceptMergeRequest(MergeRequest mr, String mergeCommitMessage, boolean shouldRemoveSourceBranch); void acceptMergeRequest(MergeRequest mr, String mergeCommitMessage, boolean shouldRemoveSourceBranch);
void createMergeRequestNote(MergeRequest mr, String body); void createMergeRequestNote(MergeRequest mr, String body);
List<MergeRequest> getMergeRequests(String projectId, State state, int page, int perPage);
List<Branch> getBranches(String projectId);
Branch getBranch(String projectId, String branch);
User getCurrentUser(); User getCurrentUser();
User addUser(String email, String username, String name, String password);
User updateUser(String userId, String email, String username, String name, String password);
List<Label> getLabels(String projectId);
List<Pipeline> getPipelines(String projectName);
} }

View File

@ -1,29 +0,0 @@
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder;
import hudson.Extension;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Collection;
@Extension
@Restricted(NoExternalUse.class)
public final class AutodetectGitLabClientBuilder extends GitLabClientBuilder {
public AutodetectGitLabClientBuilder() {
super("autodetect", 0);
}
@Override
@Nonnull
public GitLabClient buildClient(String url, String token, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout) {
Collection<GitLabClientBuilder> candidates = new ArrayList<>(getAllGitLabClientBuilders());
candidates.remove(this);
return new AutodetectingGitLabClient(candidates, url, token, ignoreCertificateErrors, connectionTimeout, readTimeout);
}
}

View File

@ -1,309 +0,0 @@
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClientBuilder;
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
import javax.ws.rs.NotFoundException;
import java.util.List;
import java.util.NoSuchElementException;
final class AutodetectingGitLabClient implements GitLabClient {
private final Iterable<GitLabClientBuilder> builders;
private final String url;
private final String token;
private final boolean ignoreCertificateErrors;
private final int connectionTimeout;
private final int readTimeout;
private GitLabClient delegate;
AutodetectingGitLabClient(Iterable<GitLabClientBuilder> builders, String url, String token, boolean ignoreCertificateErrors, int connectionTimeout, int readTimeout) {
this.builders = builders;
this.url = url;
this.token = token;
this.ignoreCertificateErrors = ignoreCertificateErrors;
this.connectionTimeout = connectionTimeout;
this.readTimeout = readTimeout;
}
@Override
public String getHostUrl() {
return url;
}
@Override
public Project createProject(final String projectName) {
return execute(
new GitLabOperation<Project>() {
@Override
Project execute(GitLabClient client) {
return client.createProject(projectName);
}
});
}
@Override
public MergeRequest createMergeRequest(final Integer projectId, final String sourceBranch, final String targetBranch, final String title) {
return execute(
new GitLabOperation<MergeRequest>() {
@Override
MergeRequest execute(GitLabClient client) {
return client.createMergeRequest(projectId, sourceBranch, targetBranch, title);
}
});
}
@Override
public Project getProject(final String projectName) {
return execute(
new GitLabOperation<Project>() {
@Override
Project execute(GitLabClient client) {
return client.getProject(projectName);
}
});
}
@Override
public Project updateProject(final String projectId, final String name, final String path) {
return execute(
new GitLabOperation<Project>() {
@Override
Project execute(GitLabClient client) {
return client.updateProject(projectId, name, path);
}
});
}
@Override
public void deleteProject(final String projectId) {
execute(
new GitLabOperation<Void>() {
@Override
Void execute(GitLabClient client) {
client.deleteProject(projectId);
return null;
}
});
}
@Override
public void addProjectHook(final String projectId, final String url, final Boolean pushEvents, final Boolean mergeRequestEvents, final Boolean noteEvents) {
execute(
new GitLabOperation<Void>() {
@Override
Void execute(GitLabClient client) {
client.addProjectHook(projectId, url, pushEvents, mergeRequestEvents, noteEvents);
return null;
}
});
}
@Override
public void changeBuildStatus(final String projectId, final String sha, final BuildState state, final String ref, final String context, final String targetUrl, final String description) {
execute(
new GitLabOperation<Void>() {
@Override
Void execute(GitLabClient client) {
client.changeBuildStatus(projectId, sha, state, ref, context, targetUrl, description);
return null;
}
});
}
@Override
public void changeBuildStatus(final Integer projectId, final String sha, final BuildState state, final String ref, final String context, final String targetUrl, final String description) {
execute(
new GitLabOperation<Void>() {
@Override
Void execute(GitLabClient client) {
client.changeBuildStatus(projectId, sha, state, ref, context, targetUrl, description);
return null;
}
});
}
@Override
public void getCommit(final String projectId, final String sha) {
execute(
new GitLabOperation<Void>() {
@Override
Void execute(GitLabClient client) {
client.getCommit(projectId, sha);
return null;
}
});
}
@Override
public void acceptMergeRequest(final MergeRequest mr, final String mergeCommitMessage, final boolean shouldRemoveSourceBranch) {
execute(
new GitLabOperation<Void>() {
@Override
Void execute(GitLabClient client) {
client.acceptMergeRequest(mr, mergeCommitMessage, shouldRemoveSourceBranch);
return null;
}
}
);
}
@Override
public void createMergeRequestNote(final MergeRequest mr, final String body) {
execute(
new GitLabOperation<Void>() {
@Override
Void execute(GitLabClient client) {
client.createMergeRequestNote(mr, body);
return null;
}
}
);
}
@Override
public List<MergeRequest> getMergeRequests(final String projectId, final State state, final int page, final int perPage) {
return execute(
new GitLabOperation<List<MergeRequest>>() {
@Override
List<MergeRequest> execute(GitLabClient client) {
return client.getMergeRequests(projectId, state, page, perPage);
}
});
}
@Override
public List<Branch> getBranches(final String projectId) {
return execute(
new GitLabOperation<List<Branch>>() {
@Override
List<Branch> execute(GitLabClient client) {
return client.getBranches(projectId);
}
});
}
@Override
public Branch getBranch(final String projectId, final String branch) {
return execute(
new GitLabOperation<Branch>() {
@Override
Branch execute(GitLabClient client) {
return client.getBranch(projectId, branch);
}
});
}
@Override
public User getCurrentUser() {
return execute(
new GitLabOperation<User>() {
@Override
User execute(GitLabClient client) {
return client.getCurrentUser();
}
});
}
@Override
public User addUser(final String email, final String username, final String name, final String password) {
return execute(
new GitLabOperation<User>() {
@Override
User execute(GitLabClient client) {
return client.addUser(email, username, name, password);
}
});
}
@Override
public User updateUser(final String userId, final String email, final String username, final String name, final String password) {
return execute(
new GitLabOperation<User>() {
@Override
User execute(GitLabClient client) {
return client.updateUser(userId, email, username, name, password);
}
});
}
@Override
public List<Label> getLabels(final String projectId) {
return execute(
new GitLabOperation<List<Label>>() {
@Override
List<Label> execute(GitLabClient client) {
return client.getLabels(projectId);
}
});
}
@Override
public List<Pipeline> getPipelines(final String projectName) {
return execute(
new GitLabOperation<List<Pipeline>>() {
@Override
List<Pipeline> execute(GitLabClient client) {
return client.getPipelines(projectName);
}
});
}
private GitLabClient delegate(boolean reset) {
if (reset || delegate == null) {
delegate = autodetectOrDie();
}
return delegate;
}
private GitLabClient autodetectOrDie() {
GitLabClient client = autodetect();
if (client != null) {
return client;
}
throw new NoSuchElementException("no client-builder found that supports server at " + url);
}
private GitLabClient autodetect() {
for (GitLabClientBuilder candidate : builders) {
GitLabClient client = candidate.buildClient(url, token, ignoreCertificateErrors, connectionTimeout, readTimeout);
try {
client.getCurrentUser();
return client;
} catch (NotFoundException ignored) {
// api-endpoint not found (== api-level not supported by this client)
}
}
return null;
}
private <R> R execute(GitLabOperation<R> operation) {
return operation.execute(false);
}
private abstract class GitLabOperation<R> {
private R execute(boolean reset) {
try {
return execute(delegate(reset));
} catch (NotFoundException e) {
if (reset) {
throw e;
}
return execute(true);
}
}
abstract R execute(GitLabClient client);
}
}

View File

@ -1,50 +0,0 @@
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
import java.util.List;
interface GitLabApiProxy {
Project createProject(String projectName);
MergeRequest createMergeRequest(Integer projectId, String sourceBranch, String targetBranch, String title);
Project getProject(String projectName);
Project updateProject(String projectId, String name, String path);
void deleteProject(String projectId);
void addProjectHook(String projectId, String url, Boolean pushEvents, Boolean mergeRequestEvents, Boolean noteEvents);
void changeBuildStatus(String projectId, String sha, BuildState state, String ref, String context, String targetUrl, String description);
void changeBuildStatus(Integer projectId, String sha, BuildState state, String ref, String context, String targetUrl, String description);
void getCommit(String projectId, String sha);
void acceptMergeRequest(Integer projectId, Integer mergeRequestId, String mergeCommitMessage, boolean shouldRemoveSourceBranch);
void createMergeRequestNote(Integer projectId, Integer mergeRequestId, String body);
List<MergeRequest> getMergeRequests(String projectId, State state, int page, int perPage);
List<Branch> getBranches(String projectId);
Branch getBranch(String projectId, String branch);
void headCurrentUser();
User getCurrentUser();
User addUser(String email, String username, String name, String password);
User updateUser(String userId, String email, String username, String name, String password);
List<Label> getLabels(String projectId);
List<Pipeline> getPipelines(String projectName);
}

View File

@ -0,0 +1,13 @@
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
interface GiteeApiProxy {
void createMergeRequestNote(String owner, String repo, Integer mergeRequestId, String body);
void headCurrentUser();
void acceptMergeRequest(Integer projectId, Integer mergeRequestId, String mergeCommitMessage, boolean shouldRemoveSourceBranch);
User getCurrentUser();
}

View File

@ -0,0 +1,44 @@
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
/**
* @author Robin Müller
* @author Yashin Luo
*
*/
@Path("/api/v5")
interface GiteeV5ApiProxy extends GiteeApiProxy {
String ID = "v5";
@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("/repos/{ownerPath}/{repoPath}/pulls/{prNumber}/comments")
void createMergeRequestNote(@PathParam("ownerPath") String ownerPath,
@PathParam("repoPath") String repoPath,
@PathParam("prNumber") Integer prNumber,
@FormParam("body") String body);
@HEAD
@Produces(MediaType.APPLICATION_JSON)
@Path("/user")
void headCurrentUser();
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/user")
User getCurrentUser();
}

View File

@ -10,8 +10,8 @@ import org.kohsuke.accmod.restrictions.NoExternalUse;
@Extension @Extension
@Restricted(NoExternalUse.class) @Restricted(NoExternalUse.class)
public final class V4GitLabClientBuilder extends ResteasyGitLabClientBuilder { public final class GiteeV5ClientBuilder extends ResteasyGiteeClientBuilder {
private static final int ORDINAL = 1; private static final int ORDINAL = 3;
private static final Function<MergeRequest, Integer> MERGE_REQUEST_ID_PROVIDER = new Function<MergeRequest, Integer>() { private static final Function<MergeRequest, Integer> MERGE_REQUEST_ID_PROVIDER = new Function<MergeRequest, Integer>() {
@Override @Override
public Integer apply(MergeRequest mergeRequest) { public Integer apply(MergeRequest mergeRequest) {
@ -19,7 +19,7 @@ public final class V4GitLabClientBuilder extends ResteasyGitLabClientBuilder {
} }
}; };
public V4GitLabClientBuilder() { public GiteeV5ClientBuilder() {
super(V4GitLabApiProxy.ID, ORDINAL, V4GitLabApiProxy.class, MERGE_REQUEST_ID_PROVIDER); super(GiteeV5ApiProxy.ID, ORDINAL, GiteeV5ApiProxy.class, MERGE_REQUEST_ID_PROVIDER);
} }
} }

View File

@ -1,122 +0,0 @@
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
import com.google.common.base.Function;
import java.util.List;
final class ResteasyGitLabClient implements GitLabClient {
private final String hostUrl;
private final GitLabApiProxy api;
private final Function<MergeRequest, Integer> mergeRequestIdProvider;
ResteasyGitLabClient(String hostUrl, GitLabApiProxy api, Function<MergeRequest, Integer> mergeRequestIdProvider) {
this.hostUrl = hostUrl;
this.api = api;
this.mergeRequestIdProvider = mergeRequestIdProvider;
}
@Override
public final String getHostUrl() {
return hostUrl;
}
@Override
public Project createProject(String projectName) {
return api.createProject(projectName);
}
@Override
public MergeRequest createMergeRequest(Integer projectId, String sourceBranch, String targetBranch, String title) {
return api.createMergeRequest(projectId, sourceBranch, targetBranch, title);
}
@Override
public Project getProject(String projectName) {
return api.getProject(projectName);
}
@Override
public Project updateProject(String projectId, String name, String path) {
return api.updateProject(projectId, name, path);
}
@Override
public void deleteProject(String projectId) {
api.deleteProject(projectId);
}
@Override
public void addProjectHook(String projectId, String url, Boolean pushEvents, Boolean mergeRequestEvents, Boolean noteEvents) {
api.addProjectHook(projectId, url, pushEvents, mergeRequestEvents, noteEvents);
}
@Override
public void changeBuildStatus(String projectId, String sha, BuildState state, String ref, String context, String targetUrl, String description) {
api.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) {
api.changeBuildStatus(projectId, sha, state, ref, context, targetUrl, description);
}
@Override
public void getCommit(String projectId, String sha) {
api.getCommit(projectId, sha);
}
@Override
public void acceptMergeRequest(MergeRequest mr, String mergeCommitMessage, boolean shouldRemoveSourceBranch) {
api.acceptMergeRequest(mr.getProjectId(), mergeRequestIdProvider.apply(mr), mergeCommitMessage, shouldRemoveSourceBranch);
}
@Override
public void createMergeRequestNote(MergeRequest mr, String body) {
api.createMergeRequestNote(mr.getProjectId(), mergeRequestIdProvider.apply(mr), body);
}
@Override
public List<MergeRequest> getMergeRequests(String projectId, State state, int page, int perPage) {
return api.getMergeRequests(projectId, state, page, perPage);
}
@Override
public List<Branch> getBranches(String projectId) {
return api.getBranches(projectId);
}
@Override
public Branch getBranch(String projectId, String branch) {
return api.getBranch(projectId, branch);
}
@Override
public User getCurrentUser() {
return api.getCurrentUser();
}
@Override
public User addUser(String email, String username, String name, String password) {
return api.addUser(email, username, name, password);
}
@Override
public User updateUser(String userId, String email, String username, String name, String password) {
return api.updateUser(userId, email, username, name, password);
}
@Override
public List<Label> getLabels(String projectId) {
return api.getLabels(projectId);
}
@Override
public List<Pipeline> getPipelines(String projectName) {
return api.getPipelines(projectName);
}
}

View File

@ -0,0 +1,45 @@
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
import com.google.common.base.Function;
import java.util.List;
final class ResteasyGiteeClient implements GitLabClient {
private final String hostUrl;
private final GiteeApiProxy api;
private final Function<MergeRequest, Integer> mergeRequestIdProvider;
ResteasyGiteeClient(String hostUrl, GiteeApiProxy api, Function<MergeRequest, Integer> mergeRequestIdProvider) {
this.hostUrl = hostUrl;
this.api = api;
this.mergeRequestIdProvider = mergeRequestIdProvider;
}
@Override
public final String getHostUrl() {
return hostUrl;
}
@Override
public void acceptMergeRequest(MergeRequest mr, String mergeCommitMessage, boolean shouldRemoveSourceBranch) {
api.acceptMergeRequest(mr.getProjectId(), mergeRequestIdProvider.apply(mr), mergeCommitMessage, shouldRemoveSourceBranch);
}
@Override
public void createMergeRequestNote(MergeRequest mr, String body) {
api.createMergeRequestNote(mr.getRepoOwner(), mr.getRepoPath(), mergeRequestIdProvider.apply(mr), body);
}
@Override
public User getCurrentUser() {
return api.getCurrentUser();
}
}

View File

@ -57,8 +57,8 @@ import static java.net.Proxy.Type.HTTP;
@Restricted(NoExternalUse.class) @Restricted(NoExternalUse.class)
public class ResteasyGitLabClientBuilder extends GitLabClientBuilder { public class ResteasyGiteeClientBuilder extends GitLabClientBuilder {
private static final Logger LOGGER = Logger.getLogger(ResteasyGitLabClientBuilder.class.getName()); private static final Logger LOGGER = Logger.getLogger(ResteasyGiteeClientBuilder.class.getName());
private static final String PRIVATE_TOKEN = "PRIVATE-TOKEN"; private static final String PRIVATE_TOKEN = "PRIVATE-TOKEN";
@Initializer(before = InitMilestone.PLUGINS_STARTED) @Initializer(before = InitMilestone.PLUGINS_STARTED)
@ -66,10 +66,10 @@ public class ResteasyGitLabClientBuilder extends GitLabClientBuilder {
RuntimeDelegate.setInstance(new ResteasyProviderFactory()); RuntimeDelegate.setInstance(new ResteasyProviderFactory());
} }
private final Class<? extends GitLabApiProxy> apiProxyClass; private final Class<? extends GiteeApiProxy> apiProxyClass;
private final Function<MergeRequest, Integer> mergeRequestIdProvider; private final Function<MergeRequest, Integer> mergeRequestIdProvider;
ResteasyGitLabClientBuilder(String id, int ordinal, Class<? extends GitLabApiProxy> apiProxyClass, Function<MergeRequest, Integer> mergeRequestIdProvider) { ResteasyGiteeClientBuilder(String id, int ordinal, Class<? extends GiteeApiProxy> apiProxyClass, Function<MergeRequest, Integer> mergeRequestIdProvider) {
super(id, ordinal); super(id, ordinal);
this.apiProxyClass = apiProxyClass; this.apiProxyClass = apiProxyClass;
this.mergeRequestIdProvider = mergeRequestIdProvider; this.mergeRequestIdProvider = mergeRequestIdProvider;
@ -108,7 +108,7 @@ public class ResteasyGitLabClientBuilder extends GitLabClientBuilder {
} }
} }
GitLabApiProxy apiProxy = builder GiteeApiProxy apiProxy = builder
.connectionPoolSize(60) .connectionPoolSize(60)
.maxPooledPerRoute(30) .maxPooledPerRoute(30)
.establishConnectionTimeout(connectionTimeout, TimeUnit.SECONDS) .establishConnectionTimeout(connectionTimeout, TimeUnit.SECONDS)
@ -124,7 +124,7 @@ public class ResteasyGitLabClientBuilder extends GitLabClientBuilder {
.classloader(apiProxyClass.getClassLoader()) .classloader(apiProxyClass.getClassLoader())
.build(); .build();
return new ResteasyGitLabClient(url, apiProxy, mergeRequestIdProvider); return new ResteasyGiteeClient(url, apiProxy, mergeRequestIdProvider);
} }
private String getHost(String url) { private String getHost(String url) {

View File

@ -1,198 +0,0 @@
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
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;
import static com.dabsquared.gitlabjenkins.gitlab.api.impl.V3GitLabApiProxy.ID;
/**
* @author Robin Müller
*/
@Path("/api/" + ID)
interface V3GitLabApiProxy extends GitLabApiProxy {
String ID = "v3";
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects")
@Override
Project createProject(@FormParam("name") String projectName);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/merge_requests")
@Override
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}")
@Override
Project getProject(@PathParam("projectName") String projectName);
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}")
@Override
Project updateProject(@PathParam("projectId") String projectId,
@FormParam("name") String name,
@FormParam("path") String path);
@DELETE
@Path("/projects/{projectId}")
@Override
void deleteProject(@PathParam("projectId") String projectId);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/hooks")
@Override
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}")
@Override
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}")
@Override
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}")
@Override
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")
@Override
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}/pull_request/{mergeRequestId}/comments")
@Override
void createMergeRequestNote(@PathParam("projectId") Integer projectId,
@PathParam("mergeRequestId") Integer mergeRequestId,
@FormParam("note") String note);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/merge_requests")
@Override
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")
@Override
List<Branch> getBranches(@PathParam("projectId") String projectId);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/repository/branches/{branch}")
@Override
Branch getBranch(@PathParam("projectId") String projectId,
@PathParam("branch") String branch);
@HEAD
@Produces(MediaType.APPLICATION_JSON)
@Path("/user")
@Override
void headCurrentUser();
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/user")
@Override
User getCurrentUser();
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/users")
@Override
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}")
@Override
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")
@Override
List<Label> getLabels(@PathParam("projectId") String projectId);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/pipelines")
@Override
List<Pipeline> getPipelines(@PathParam("projectId") String projectId);
}

View File

@ -1,25 +0,0 @@
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
import com.google.common.base.Function;
import hudson.Extension;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
@Extension
@Restricted(NoExternalUse.class)
public final class V3GitLabClientBuilder extends ResteasyGitLabClientBuilder {
private static final int ORDINAL = 2;
private static final Function<MergeRequest, Integer> MERGE_REQUEST_ID_PROVIDER = new Function<MergeRequest, Integer>() {
@Override
public Integer apply(MergeRequest mergeRequest) {
return mergeRequest.getId();
}
};
public V3GitLabClientBuilder() {
super(V3GitLabApiProxy.ID, ORDINAL, V3GitLabApiProxy.class, MERGE_REQUEST_ID_PROVIDER);
}
}

View File

@ -1,198 +0,0 @@
package com.dabsquared.gitlabjenkins.gitlab.api.impl;
import com.dabsquared.gitlabjenkins.gitlab.api.model.*;
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;
import static com.dabsquared.gitlabjenkins.gitlab.api.impl.V4GitLabApiProxy.ID;
/**
* @author Robin Müller
*/
@Path("/api/" + ID)
interface V4GitLabApiProxy extends GitLabApiProxy {
String ID = "v4";
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects")
@Override
Project createProject(@FormParam("name") String projectName);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/merge_requests")
@Override
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}")
@Override
Project getProject(@PathParam("projectName") String projectName);
@PUT
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}")
@Override
Project updateProject(@PathParam("projectId") String projectId,
@FormParam("name") String name,
@FormParam("path") String path);
@DELETE
@Path("/projects/{projectId}")
@Override
void deleteProject(@PathParam("projectId") String projectId);
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/projects/{projectId}/hooks")
@Override
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}")
@Override
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}")
@Override
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}")
@Override
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/{mergeRequestIid}/merge")
@Override
void acceptMergeRequest(@PathParam("projectId") Integer projectId,
@PathParam("mergeRequestIid") Integer mergeRequestIid,
@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/{mergeRequestIid}/notes")
@Override
void createMergeRequestNote(@PathParam("projectId") Integer projectId,
@PathParam("mergeRequestIid") Integer mergeRequestIid,
@FormParam("body") String body);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/merge_requests")
@Override
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")
@Override
List<Branch> getBranches(@PathParam("projectId") String projectId);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/repository/branches/{branch}")
@Override
Branch getBranch(@PathParam("projectId") String projectId,
@PathParam("branch") String branch);
@HEAD
@Produces(MediaType.APPLICATION_JSON)
@Path("/user")
@Override
void headCurrentUser();
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/user")
@Override
User getCurrentUser();
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@Path("/users")
@Override
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}")
@Override
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")
@Override
List<Label> getLabels(@PathParam("projectId") String projectId);
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path("/projects/{projectId}/pipelines")
@Override
List<Pipeline> getPipelines(@PathParam("projectId") String projectId);
}

View File

@ -31,6 +31,8 @@ public class MergeRequest {
private Boolean workInProgress; private Boolean workInProgress;
private Boolean mergeWhenBuildSucceeds; private Boolean mergeWhenBuildSucceeds;
private String mergeStatus; private String mergeStatus;
private String repoOwner;
private String repoPath;
public MergeRequest() { /* default-constructor for Resteasy-based-api-proxies */ } public MergeRequest() { /* default-constructor for Resteasy-based-api-proxies */ }
@ -48,6 +50,29 @@ public class MergeRequest {
this.mergeStatus = mergeStatus; this.mergeStatus = mergeStatus;
} }
public MergeRequest(int id, int iid, String sourceBranch, String targetBranch, String title,
int sourceProjectId, int targetProjectId,
String description, String mergeStatus, String pathWithNamespace) {
this.id = id;
this.iid= iid;
this.sourceBranch = sourceBranch;
this.targetBranch = targetBranch;
this.title = title;
this.sourceProjectId = sourceProjectId;
this.projectId = targetProjectId;
this.description = description;
this.mergeStatus = mergeStatus;
try {
String[] path = pathWithNamespace.split("/");
String repoOwner = path[0];
String repoPath = path[1];
this.repoOwner = repoOwner;
this.repoPath = repoPath;
} catch (Exception e) {
// do nothing
}
}
public Integer getId() { public Integer getId() {
return id; return id;
} }
@ -192,6 +217,22 @@ public class MergeRequest {
this.mergeStatus = mergeStatus; this.mergeStatus = mergeStatus;
} }
public String getRepoOwner() {
return repoOwner;
}
public void setRepoOwner(String repoOwner) {
this.repoOwner = repoOwner;
}
public String getRepoPath() {
return repoPath;
}
public void setRepoPath(String repoPath) {
this.repoPath = repoPath;
}
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) { if (this == o) {
@ -220,6 +261,8 @@ public class MergeRequest {
.append(workInProgress, that.workInProgress) .append(workInProgress, that.workInProgress)
.append(mergeWhenBuildSucceeds, that.mergeWhenBuildSucceeds) .append(mergeWhenBuildSucceeds, that.mergeWhenBuildSucceeds)
.append(mergeStatus, that.mergeStatus) .append(mergeStatus, that.mergeStatus)
.append(repoPath, that.repoPath)
.append(repoOwner, that.repoOwner)
.isEquals(); .isEquals();
} }
@ -244,6 +287,8 @@ public class MergeRequest {
.append(workInProgress) .append(workInProgress)
.append(mergeWhenBuildSucceeds) .append(mergeWhenBuildSucceeds)
.append(mergeStatus) .append(mergeStatus)
.append(repoOwner)
.append(repoPath)
.toHashCode(); .toHashCode();
} }
@ -268,6 +313,8 @@ public class MergeRequest {
.append("workInProgress", workInProgress) .append("workInProgress", workInProgress)
.append("mergeWhenBuildSucceeds", mergeWhenBuildSucceeds) .append("mergeWhenBuildSucceeds", mergeWhenBuildSucceeds)
.append("mergeStatus", mergeStatus) .append("mergeStatus", mergeStatus)
.append("repoOwner", repoOwner)
.append("repoPath", repoPath)
.toString(); .toString();
} }
} }

View File

@ -1,112 +0,0 @@
package com.dabsquared.gitlabjenkins.publisher;
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
import com.dabsquared.gitlabjenkins.util.CommitStatusUpdater;
import hudson.Extension;
import hudson.Launcher;
import hudson.matrix.MatrixAggregatable;
import hudson.matrix.MatrixAggregator;
import hudson.matrix.MatrixBuild;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.Result;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.BuildStepMonitor;
import hudson.tasks.Notifier;
import hudson.tasks.Publisher;
import hudson.util.FormValidation;
import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
import java.io.IOException;
/**
* @author Robin Müller
*/
public class GitLabCommitStatusPublisher extends Notifier implements MatrixAggregatable {
private String name;
private boolean markUnstableAsSuccess;
@DataBoundConstructor
public GitLabCommitStatusPublisher(String name, boolean markUnstableAsSuccess) {
this.name = name;
this.markUnstableAsSuccess = markUnstableAsSuccess;
}
public BuildStepMonitor getRequiredMonitorService() {
return BuildStepMonitor.NONE;
}
@Override
public boolean prebuild(AbstractBuild<?, ?> build, BuildListener listener) {
CommitStatusUpdater.updateCommitStatus(build, listener, BuildState.running, name);
return true;
}
@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
Result buildResult = build.getResult();
if (buildResult == Result.SUCCESS || (buildResult == Result.UNSTABLE && markUnstableAsSuccess)) {
CommitStatusUpdater.updateCommitStatus(build, listener, BuildState.success, name);
} else if (buildResult == Result.ABORTED) {
CommitStatusUpdater.updateCommitStatus(build, listener, BuildState.canceled, name);
} else {
CommitStatusUpdater.updateCommitStatus(build, listener, BuildState.failed, name);
}
return true;
}
public String getName() {
return name;
}
public boolean isMarkUnstableAsSuccess() {
return markUnstableAsSuccess;
}
protected GitLabCommitStatusPublisher readResolve() {
if (name == null) {
name = "jenkins";
}
return this;
}
public MatrixAggregator createAggregator(MatrixBuild build, Launcher launcher, BuildListener listener) {
return new MatrixAggregator(build, launcher, listener) {
@Override
public boolean endBuild() throws InterruptedException, IOException {
perform(build, launcher, listener);
return super.endBuild();
}
};
}
@Extension
public static class DescriptorImpl extends BuildStepDescriptor<Publisher> {
@Override
public boolean isApplicable(Class<? extends AbstractProject> aClass) {
return true;
}
@Override
public String getDisplayName() {
return Messages.GitLabCommitStatusPublisher_DisplayName();
}
@Override
public String getHelpFile() {
return "/plugin/gitlab-plugin/help/help-send-result-to-gitlab.html";
}
public FormValidation doCheckName(@QueryParameter String value) {
if (StringUtils.isEmpty(value)) {
return FormValidation.error(Messages.name_required());
}
return FormValidation.ok();
}
}
}

View File

@ -1,77 +0,0 @@
package com.dabsquared.gitlabjenkins.service;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Branch;
import com.dabsquared.gitlabjenkins.util.LoggerUtil;
import com.dabsquared.gitlabjenkins.util.ProjectIdUtil;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public class GitLabProjectBranchesService {
private static final Logger LOGGER = Logger.getLogger(GitLabProjectBranchesService.class.getName());
private static transient GitLabProjectBranchesService gitLabProjectBranchesService;
private final Cache<String, List<String>> projectBranchCache;
GitLabProjectBranchesService() {
this.projectBranchCache = CacheBuilder.<String, String>newBuilder()
.maximumSize(1000)
.expireAfterWrite(5, TimeUnit.SECONDS)
.build();
}
public static GitLabProjectBranchesService instance() {
if (gitLabProjectBranchesService == null) {
gitLabProjectBranchesService = new GitLabProjectBranchesService();
}
return gitLabProjectBranchesService;
}
public List<String> getBranches(GitLabClient client, String sourceRepositoryString) {
synchronized (projectBranchCache) {
try {
return projectBranchCache.get(sourceRepositoryString, new BranchNamesLoader(client, sourceRepositoryString));
} catch (ExecutionException e) {
throw new BranchLoadingException(e);
}
}
}
public static class BranchLoadingException extends RuntimeException {
BranchLoadingException(Throwable cause) {
super(cause);
}
}
private static class BranchNamesLoader implements Callable<List<String>> {
private final GitLabClient client;
private final String sourceRepository;
private BranchNamesLoader(GitLabClient client, String sourceRepository) {
this.client = client;
this.sourceRepository = sourceRepository;
}
@Override
public List<String> call() throws Exception {
List<String> result = new ArrayList<>();
String projectId = ProjectIdUtil.retrieveProjectId(client, sourceRepository);
for (Branch branch : client.getBranches(projectId)) {
result.add(branch.getName());
}
LOGGER.log(Level.FINEST, "found these branches for repo {0} : {1}", LoggerUtil.toArray(sourceRepository, result));
return result;
}
}
}

View File

@ -1,77 +0,0 @@
package com.dabsquared.gitlabjenkins.service;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Label;
import com.dabsquared.gitlabjenkins.util.LoggerUtil;
import com.dabsquared.gitlabjenkins.util.ProjectIdUtil;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
public class GitLabProjectLabelsService {
private static final Logger LOGGER = Logger.getLogger(GitLabProjectLabelsService.class.getName());
private static transient GitLabProjectLabelsService instance;
private final Cache<String, List<String>> projectLabelsCache;
GitLabProjectLabelsService() {
this.projectLabelsCache = CacheBuilder.<String, String>newBuilder()
.maximumSize(1000)
.expireAfterWrite(5, TimeUnit.SECONDS)
.build();
}
public static GitLabProjectLabelsService instance() {
if (instance == null) {
instance = new GitLabProjectLabelsService();
}
return instance;
}
public List<String> getLabels(GitLabClient client, String sourceRepositoryString) {
synchronized (projectLabelsCache) {
try {
return projectLabelsCache.get(sourceRepositoryString, new LabelNamesLoader(client, sourceRepositoryString));
} catch (ExecutionException e) {
throw new LabelLoadingException(e);
}
}
}
public static class LabelLoadingException extends RuntimeException {
LabelLoadingException(Throwable cause) {
super(cause);
}
}
private static class LabelNamesLoader implements Callable<List<String>> {
private final GitLabClient client;
private final String sourceRepository;
private LabelNamesLoader(GitLabClient client, String sourceRepository) {
this.client = client;
this.sourceRepository = sourceRepository;
}
@Override
public List<String> call() throws Exception {
List<String> result = new ArrayList<>();
String projectId = ProjectIdUtil.retrieveProjectId(client, sourceRepository);
for (Label label : client.getLabels(projectId)) {
result.add(label.getName());
}
LOGGER.log(Level.FINEST, "found these labels for repo {0} : {1}", LoggerUtil.toArray(sourceRepository, result));
return result;
}
}
}

View File

@ -1,159 +0,0 @@
package com.dabsquared.gitlabjenkins.trigger.branch;
import com.dabsquared.gitlabjenkins.Messages;
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
import com.dabsquared.gitlabjenkins.service.GitLabProjectBranchesService;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import hudson.model.AutoCompletionCandidates;
import hudson.model.Item;
import hudson.model.Job;
import hudson.plugins.git.GitSCM;
import hudson.scm.SCM;
import hudson.util.FormValidation;
import jenkins.model.Jenkins;
import jenkins.triggers.SCMTriggerItem;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.URIish;
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.QueryParameter;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author Robin Müller
*/
public final class ProjectBranchesProvider {
private static final Logger LOGGER = Logger.getLogger(ProjectBranchesProvider.class.getName());
private static final ProjectBranchesProvider INSTANCE = new ProjectBranchesProvider();
private ProjectBranchesProvider() {
}
public static ProjectBranchesProvider instance() {
return INSTANCE;
}
private List<String> getProjectBranches(Job<?, ?> project) {
final URIish sourceRepository = getSourceRepoURLDefault(project);
GitLabConnectionProperty connectionProperty = project.getProperty(GitLabConnectionProperty.class);
if (connectionProperty != null && connectionProperty.getClient() != null) {
return GitLabProjectBranchesService.instance().getBranches(connectionProperty.getClient(), sourceRepository.toString());
} else {
LOGGER.log(Level.WARNING, "getProjectBranches: gitlabHostUrl hasn't been configured globally. Job {0}.", project.getFullName());
return Collections.emptyList();
}
}
public AutoCompletionCandidates doAutoCompleteBranchesSpec(Job<?, ?> job, String query) {
AutoCompletionCandidates result = new AutoCompletionCandidates();
// show all suggestions for short strings
if (query.length() < 2) {
result.add(getProjectBranchesAsArray(job));
} else {
for (String branch : getProjectBranchesAsArray(job)) {
if (branch.toLowerCase().contains(query.toLowerCase())) {
result.add(branch);
}
}
}
return result;
}
public FormValidation doCheckBranchesSpec(@AncestorInPath final Job<?, ?> project, @QueryParameter final String value) {
if (!project.hasPermission(Item.CONFIGURE) || containsNoBranches(value)) {
return FormValidation.ok();
}
try {
return checkMatchingBranches(value, getProjectBranches(project));
} catch (GitLabProjectBranchesService.BranchLoadingException e) {
return FormValidation.warning(project.hasPermission(Jenkins.ADMINISTER) ? e : null, Messages.GitLabPushTrigger_CannotCheckBranches());
}
}
private FormValidation checkMatchingBranches(@QueryParameter String value, List<String> projectBranches) {
Set<String> matchingSpecs = new HashSet<>();
Set<String> unknownSpecs = new HashSet<>();
AntPathMatcherSet projectBranchesMatcherSet = new AntPathMatcherSet(projectBranches);
for (String branchSpec : Splitter.on(',').omitEmptyStrings().trimResults().split(value)) {
if (projectBranchesMatcherSet.contains(branchSpec)) {
matchingSpecs.add(branchSpec);
} else {
unknownSpecs.add(branchSpec);
}
}
if (unknownSpecs.isEmpty()) {
return FormValidation.ok(Messages.GitLabPushTrigger_BranchesMatched(matchingSpecs.size()));
} else {
return FormValidation.warning(Messages.GitLabPushTrigger_BranchesNotFound(Joiner.on(", ").join(unknownSpecs)));
}
}
private boolean containsNoBranches(@QueryParameter String value) {
return StringUtils.isEmpty(value) || StringUtils.containsOnly(value, new char[]{',', ' '});
}
private String[] getProjectBranchesAsArray(Job<?, ?> job) {
try {
List<String> branches = getProjectBranches(job);
return branches.toArray(new String[branches.size()]);
} catch (GitLabProjectBranchesService.BranchLoadingException e) {
LOGGER.log(Level.FINEST, "Failed to load branch names from GitLab. Please check the logs and your configuration.", e);
}
return new String[0];
}
/**
* Get the URL of the first declared repository in the project configuration.
* Use this as default source repository url.
*
* @return URIish the default value of the source repository url
* @throws IllegalStateException Project does not use git scm.
*/
private URIish getSourceRepoURLDefault(Job<?, ?> job) {
SCMTriggerItem item = SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(job);
GitSCM gitSCM = getGitSCM(item);
if (gitSCM == null) {
LOGGER.log(Level.WARNING, "Could not find GitSCM for project. Project = {1}, next build = {2}",
array(job.getName(), String.valueOf(job.getNextBuildNumber())));
throw new IllegalStateException("This project does not use git:" + job.getName());
}
return getFirstRepoURL(gitSCM.getRepositories());
}
private URIish getFirstRepoURL(List<RemoteConfig> repositories) {
if (!repositories.isEmpty()) {
List<URIish> uris = repositories.get(repositories.size() - 1).getURIs();
if (!uris.isEmpty()) {
return uris.get(uris.size() - 1);
}
}
throw new IllegalStateException(Messages.GitLabPushTrigger_NoSourceRepository());
}
private GitSCM getGitSCM(SCMTriggerItem item) {
if (item != null) {
for (SCM scm : item.getSCMs()) {
if (scm instanceof GitSCM) {
return (GitSCM) scm;
}
}
}
return null;
}
private Object[] array(Object... objects) {
return objects;
}
}

View File

@ -49,7 +49,6 @@ public abstract class AbstractWebHookTriggerHandler<H extends WebHook> implement
if (branchFilter.isBranchAllowed(targetBranch)) { if (branchFilter.isBranchAllowed(targetBranch)) {
LOGGER.log(Level.INFO, "{0} triggered for {1}.", LoggerUtil.toArray(job.getFullName(), getTriggerType())); LOGGER.log(Level.INFO, "{0} triggered for {1}.", LoggerUtil.toArray(job.getFullName(), getTriggerType()));
cancelPendingBuildsIfNecessary(job, hook); cancelPendingBuildsIfNecessary(job, hook);
setCommitStatusPendingIfNecessary(job, hook);
scheduleBuild(job, createActions(job, hook)); scheduleBuild(job, createActions(job, hook));
} else { } else {
LOGGER.log(Level.INFO, "branch {0} is not allowed", targetBranch); LOGGER.log(Level.INFO, "branch {0} is not allowed", targetBranch);
@ -60,25 +59,6 @@ public abstract class AbstractWebHookTriggerHandler<H extends WebHook> implement
protected abstract boolean isCiSkip(H hook); protected abstract boolean isCiSkip(H hook);
private void setCommitStatusPendingIfNecessary(Job<?, ?> job, H hook) {
String buildName = PendingBuildsHandler.resolvePendingBuildName(job);
if (StringUtils.isNotBlank(buildName)) {
GitLabClient client = job.getProperty(GitLabConnectionProperty.class).getClient();
BuildStatusUpdate buildStatusUpdate = retrieveBuildStatusUpdate(hook);
try {
if (client == null) {
LOGGER.log(Level.SEVERE, "No GitLab connection configured");
} else {
String targetUrl = DisplayURLProvider.get().getJobURL(job);
client.changeBuildStatus(buildStatusUpdate.getProjectId(), buildStatusUpdate.getSha(),
BuildState.pending, buildStatusUpdate.getRef(), buildName, targetUrl, BuildState.pending.name());
}
} catch (WebApplicationException | ProcessingException e) {
LOGGER.log(Level.SEVERE, "Failed to set build state to pending", e);
}
}
}
protected Action[] createActions(Job<?, ?> job, H hook) { protected Action[] createActions(Job<?, ?> job, H hook) {
ArrayList<Action> actions = new ArrayList<>(); ArrayList<Action> actions = new ArrayList<>();
actions.add(new CauseAction(new GiteeWebHookCause(retrieveCauseData(hook)))); actions.add(new CauseAction(new GiteeWebHookCause(retrieveCauseData(hook))));

View File

@ -3,18 +3,12 @@ package com.dabsquared.gitlabjenkins.trigger.handler;
import com.dabsquared.gitlabjenkins.GitLabPushTrigger; import com.dabsquared.gitlabjenkins.GitLabPushTrigger;
import com.dabsquared.gitlabjenkins.cause.CauseData; import com.dabsquared.gitlabjenkins.cause.CauseData;
import com.dabsquared.gitlabjenkins.cause.GiteeWebHookCause; import com.dabsquared.gitlabjenkins.cause.GiteeWebHookCause;
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
import com.dabsquared.gitlabjenkins.publisher.GitLabCommitStatusPublisher;
import com.dabsquared.gitlabjenkins.util.LoggerUtil; import com.dabsquared.gitlabjenkins.util.LoggerUtil;
import hudson.model.AbstractProject; import hudson.model.AbstractProject;
import hudson.model.Cause; import hudson.model.Cause;
import hudson.model.Job; import hudson.model.Job;
import hudson.model.Queue; import hudson.model.Queue;
import jenkins.model.Jenkins; import jenkins.model.Jenkins;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.displayurlapi.DisplayURLProvider;
import org.jenkinsci.plugins.workflow.job.WorkflowJob; import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import java.util.logging.Level; import java.util.logging.Level;
@ -40,7 +34,6 @@ public class PendingBuildsHandler {
} }
if (branch.equals(queueItemCauseData.getBranch())) { if (branch.equals(queueItemCauseData.getBranch())) {
cancel(item, queue, branch); cancel(item, queue, branch);
setCommitStatusCancelledIfNecessary(queueItemCauseData, job);
} }
} }
} }
@ -62,35 +55,4 @@ public class PendingBuildsHandler {
LOGGER.log(Level.SEVERE, "Error cancelling queued build", e); LOGGER.log(Level.SEVERE, "Error cancelling queued build", e);
} }
} }
private void setCommitStatusCancelledIfNecessary(CauseData causeData, Job<?, ?> job) {
String buildName = resolvePendingBuildName(job);
if (StringUtils.isBlank(buildName)) {
return;
}
String targetUrl = DisplayURLProvider.get().getJobURL(job);
GitLabClient client = job.getProperty(GitLabConnectionProperty.class).getClient();
try {
client.changeBuildStatus(causeData.getSourceProjectId(), causeData.getLastCommit(), BuildState.canceled,
causeData.getSourceBranch(), buildName, targetUrl, BuildState.canceled.name());
} catch (Exception e) {
LOGGER.log(Level.SEVERE, "Failed to set build state to pending", e);
}
}
public static String resolvePendingBuildName(Job<?, ?> job) {
if (job instanceof AbstractProject) {
GitLabCommitStatusPublisher publisher =
(GitLabCommitStatusPublisher) ((AbstractProject) job).getPublishersList().get(GitLabCommitStatusPublisher.class);
if (publisher != null) {
return publisher.getName();
}
} else if (job instanceof WorkflowJob) {
GitLabPushTrigger trigger = GitLabPushTrigger.getFromJob(job);
if (trigger != null) {
return trigger.getPendingBuildName();
}
}
return null;
}
} }

View File

@ -143,6 +143,7 @@ class MergeRequestHookTriggerHandlerImpl extends AbstractWebHookTriggerHandler<M
.withTriggeredByUser(hook.getObjectAttributes().getHead().getUser().getName()) .withTriggeredByUser(hook.getObjectAttributes().getHead().getUser().getName())
.withLastCommit(hook.getObjectAttributes().getMergeCommitSha()) .withLastCommit(hook.getObjectAttributes().getMergeCommitSha())
.withTargetProjectUrl(hook.getObjectAttributes().getTarget().getWebUrl()) .withTargetProjectUrl(hook.getObjectAttributes().getTarget().getWebUrl())
.withPathWithNamespace(hook.getProject().getPathWithNamespace())
.build(); .build();
} }

View File

@ -29,6 +29,8 @@ import static com.dabsquared.gitlabjenkins.trigger.handler.builder.generated.Bui
/** /**
* @author Milena Zachow * @author Milena Zachow
*/ */
// fixme
class PipelineHookTriggerHandlerImpl extends AbstractWebHookTriggerHandler<PipelineHook> implements PipelineHookTriggerHandler { class PipelineHookTriggerHandlerImpl extends AbstractWebHookTriggerHandler<PipelineHook> implements PipelineHookTriggerHandler {
private static final Logger LOGGER = Logger.getLogger(PipelineHookTriggerHandlerImpl.class.getName()); private static final Logger LOGGER = Logger.getLogger(PipelineHookTriggerHandlerImpl.class.getName());
@ -48,8 +50,6 @@ class PipelineHookTriggerHandlerImpl extends AbstractWebHookTriggerHandler<Pipel
if (property != null && property.getClient() != null) { if (property != null && property.getClient() != null) {
GitLabClient client = property.getClient(); GitLabClient client = property.getClient();
com.dabsquared.gitlabjenkins.gitlab.api.model.Project projectForName = client.getProject(hook.getProject().getPathWithNamespace());
hook.setProjectId(projectForName.getId());
} }
} }
} catch (WebApplicationException e) { } catch (WebApplicationException e) {

View File

@ -1,198 +0,0 @@
package com.dabsquared.gitlabjenkins.trigger.handler.push;
import com.dabsquared.gitlabjenkins.GitLabPushTrigger;
import com.dabsquared.gitlabjenkins.cause.CauseData;
import com.dabsquared.gitlabjenkins.cause.GiteeWebHookCause;
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Branch;
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Project;
import com.dabsquared.gitlabjenkins.gitlab.hook.model.PushHook;
import com.dabsquared.gitlabjenkins.gitlab.hook.model.State;
import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilter;
import com.dabsquared.gitlabjenkins.trigger.filter.MergeRequestLabelFilter;
import com.dabsquared.gitlabjenkins.util.LoggerUtil;
import com.dabsquared.gitlabjenkins.trigger.handler.PendingBuildsHandler;
import hudson.model.Action;
import hudson.model.CauseAction;
import hudson.model.Job;
import hudson.plugins.git.RevisionParameterAction;
import hudson.triggers.Trigger;
import jenkins.model.ParameterizedJobMixIn;
import jenkins.model.ParameterizedJobMixIn.ParameterizedJob;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jgit.transport.URIish;
import org.jenkinsci.plugins.displayurlapi.DisplayURLProvider;
import javax.ws.rs.ProcessingException;
import javax.ws.rs.WebApplicationException;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.dabsquared.gitlabjenkins.cause.CauseDataBuilder.causeData;
import static com.dabsquared.gitlabjenkins.util.LoggerUtil.toArray;
/**
* @author Robin Müller
*/
class OpenMergeRequestPushHookTriggerHandler implements PushHookTriggerHandler {
private final static Logger LOGGER = Logger.getLogger(OpenMergeRequestPushHookTriggerHandler.class.getName());
private final boolean skipWorkInProgressMergeRequest;
OpenMergeRequestPushHookTriggerHandler(boolean skipWorkInProgressMergeRequest) {
this.skipWorkInProgressMergeRequest = skipWorkInProgressMergeRequest;
}
@Override
public void handle(Job<?, ?> job, PushHook hook, boolean ciSkip, BranchFilter branchFilter, MergeRequestLabelFilter mergeRequestLabelFilter) {
try {
if (job instanceof ParameterizedJobMixIn.ParameterizedJob) {
ParameterizedJob project = (ParameterizedJobMixIn.ParameterizedJob) job;
GitLabConnectionProperty property = job.getProperty(GitLabConnectionProperty.class);
for (Trigger t : project.getTriggers().values()) {
if (t instanceof GitLabPushTrigger) {
final GitLabPushTrigger trigger = (GitLabPushTrigger) t;
Integer projectId = hook.getProjectId();
if (property != null && property.getClient() != null && projectId != null && trigger != null) {
GitLabClient client = property.getClient();
for (MergeRequest mergeRequest : getOpenMergeRequests(client, projectId.toString())) {
if (mergeRequestLabelFilter.isMergeRequestAllowed(mergeRequest.getLabels())) {
handleMergeRequest(job, hook, ciSkip, branchFilter, client, mergeRequest);
}
}
}
}
}
} else {
LOGGER.log(Level.FINE, "Not a ParameterizedJob: {0}",LoggerUtil.toArray(job.getClass().getName()));
}
} catch (WebApplicationException | ProcessingException e) {
LOGGER.log(Level.WARNING, "Failed to communicate with gitlab server to determine if this is an update for a merge request: " + e.getMessage(), e);
}
}
private List<MergeRequest> getOpenMergeRequests(GitLabClient client, String projectId) {
List<MergeRequest> result = new ArrayList<>();
Integer page = 1;
do {
List<MergeRequest> mergeRequests = client.getMergeRequests(projectId, State.opened, page, 100);
result.addAll(mergeRequests);
page = mergeRequests.isEmpty() ? null : page + 1;
} while (page != null);
return result;
}
private void handleMergeRequest(Job<?, ?> job, PushHook hook, boolean ciSkip, BranchFilter branchFilter, GitLabClient client, MergeRequest mergeRequest) {
if (ciSkip && mergeRequest.getDescription() != null && mergeRequest.getDescription().contains("[ci-skip]")) {
LOGGER.log(Level.INFO, "Skipping MR " + mergeRequest.getTitle() + " due to ci-skip.");
return;
}
Boolean workInProgress = mergeRequest.getWorkInProgress();
if (skipWorkInProgressMergeRequest && workInProgress != null && workInProgress) {
LOGGER.log(Level.INFO, "Skip WIP Merge Request #{0} ({1})", toArray(mergeRequest.getIid(), mergeRequest.getTitle()));
return;
}
String targetBranch = mergeRequest.getTargetBranch();
String sourceBranch = mergeRequest.getSourceBranch();
if (targetBranch != null && branchFilter.isBranchAllowed(targetBranch) && hook.getRef().equals("refs/heads/"+targetBranch) && sourceBranch != null) {
LOGGER.log(Level.INFO, "{0} triggered for push to target branch of open merge request #{1}.",
LoggerUtil.toArray(job.getFullName(), mergeRequest.getId()));
Branch branch = client.getBranch(mergeRequest.getSourceProjectId().toString(), sourceBranch);
Project project = client.getProject(mergeRequest.getSourceProjectId().toString());
String commit = branch.getCommit().getId();
setCommitStatusPendingIfNecessary(job, mergeRequest.getSourceProjectId(), commit, branch.getName());
List<Action> actions = Arrays.<Action>asList(new CauseAction(new GiteeWebHookCause(retrieveCauseData(hook, project, mergeRequest, branch))),
new RevisionParameterAction(commit, retrieveUrIish(hook)));
scheduleBuild(job, actions.toArray(new Action[actions.size()]));
}
}
private CauseData retrieveCauseData(PushHook hook, Project project, MergeRequest mergeRequest, Branch branch) {
return causeData()
.withActionType(CauseData.ActionType.MERGE)
.withSourceProjectId(mergeRequest.getSourceProjectId())
.withTargetProjectId(hook.getProjectId())
.withBranch(branch.getName())
.withSourceBranch(branch.getName())
.withUserName(branch.getCommit().getAuthorName())
.withUserEmail(branch.getCommit().getAuthorEmail())
.withSourceRepoHomepage(project.getWebUrl())
.withSourceRepoName(project.getName())
.withSourceNamespace(project.getNamespace().getPath())
.withSourceRepoUrl(project.getSshUrlToRepo())
.withSourceRepoSshUrl(project.getSshUrlToRepo())
.withSourceRepoHttpUrl(project.getHttpUrlToRepo())
.withMergeRequestTitle(mergeRequest.getTitle())
.withMergeRequestDescription(mergeRequest.getDescription())
.withMergeRequestId(mergeRequest.getId())
.withMergeRequestIid(mergeRequest.getIid())
.withMergeRequestTargetProjectId(mergeRequest.getTargetProjectId())
.withTargetBranch(mergeRequest.getTargetBranch())
.withTargetRepoName(hook.getRepository().getName())
.withTargetNamespace(hook.getProject().getNamespace())
.withTargetRepoSshUrl(hook.getRepository().getGitSshUrl())
.withTargetRepoHttpUrl(hook.getRepository().getGitHttpUrl())
.withTriggeredByUser(hook.getCommits().get(0).getAuthor().getName())
.withLastCommit(branch.getCommit().getId())
.withTargetProjectUrl(project.getWebUrl())
.build();
}
private void setCommitStatusPendingIfNecessary(Job<?, ?> job, Integer projectId, String commit, String ref) {
String buildName = PendingBuildsHandler.resolvePendingBuildName(job);
if (StringUtils.isNotBlank(buildName)) {
GitLabClient client = job.getProperty(GitLabConnectionProperty.class).getClient();
try {
String targetUrl = DisplayURLProvider.get().getJobURL(job);
client.changeBuildStatus(projectId, commit, BuildState.pending, ref, buildName, targetUrl, BuildState.pending.name());
} catch (WebApplicationException | ProcessingException e) {
LOGGER.log(Level.SEVERE, "Failed to set build state to pending", e);
}
}
}
private void scheduleBuild(Job<?, ?> job, Action[] actions) {
int projectBuildDelay = 0;
if (job instanceof ParameterizedJobMixIn.ParameterizedJob) {
ParameterizedJobMixIn.ParameterizedJob abstractProject = (ParameterizedJobMixIn.ParameterizedJob) job;
if (abstractProject.getQuietPeriod() > projectBuildDelay) {
projectBuildDelay = abstractProject.getQuietPeriod();
}
}
retrieveScheduleJob(job).scheduleBuild2(projectBuildDelay, actions);
}
private ParameterizedJobMixIn retrieveScheduleJob(final Job<?, ?> job) {
// TODO 1.621+ use standard method
return new ParameterizedJobMixIn() {
@Override
protected Job asJob() {
return job;
}
};
}
private URIish retrieveUrIish(PushHook hook) {
try {
if (hook.getRepository() != null) {
return new URIish(hook.getRepository().getUrl());
}
} catch (URISyntaxException e) {
LOGGER.log(Level.WARNING, "could not parse URL");
}
return null;
}
}

View File

@ -29,9 +29,7 @@ public final class PushHookTriggerHandlerFactory {
if (triggerOnPush) { if (triggerOnPush) {
result.add(new PushHookTriggerHandlerImpl()); result.add(new PushHookTriggerHandlerImpl());
} }
if (triggerOpenMergeRequestOnPush == TriggerOpenMergeRequest.both) {
result.add(new OpenMergeRequestPushHookTriggerHandler(skipWorkInProgressMergeRequest));
}
return result; return result;
} }
} }

View File

@ -1,157 +0,0 @@
package com.dabsquared.gitlabjenkins.trigger.label;
import com.dabsquared.gitlabjenkins.Messages;
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
import com.dabsquared.gitlabjenkins.service.GitLabProjectBranchesService;
import com.dabsquared.gitlabjenkins.service.GitLabProjectLabelsService;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import hudson.model.AutoCompletionCandidates;
import hudson.model.Item;
import hudson.model.Job;
import hudson.plugins.git.GitSCM;
import hudson.scm.SCM;
import hudson.util.FormValidation;
import jenkins.model.Jenkins;
import jenkins.triggers.SCMTriggerItem;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.URIish;
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.QueryParameter;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* @author Robin Müller
*/
public final class ProjectLabelsProvider {
private static final Logger LOGGER = Logger.getLogger(ProjectLabelsProvider.class.getName());
private static final ProjectLabelsProvider INSTANCE = new ProjectLabelsProvider();
private ProjectLabelsProvider() {
}
public static ProjectLabelsProvider instance() {
return INSTANCE;
}
private List<String> getProjectLabels(Job<?, ?> project) {
final URIish sourceRepository = getSourceRepoURLDefault(project);
GitLabConnectionProperty connectionProperty = project.getProperty(GitLabConnectionProperty.class);
if (connectionProperty != null && connectionProperty.getClient() != null) {
return GitLabProjectLabelsService.instance().getLabels(connectionProperty.getClient(), sourceRepository.toString());
} else {
LOGGER.log(Level.WARNING, "getProjectLabels: gitlabHostUrl hasn't been configured globally. Job {0}.", project.getFullName());
return Collections.emptyList();
}
}
public AutoCompletionCandidates doAutoCompleteLabels(Job<?, ?> job, String query) {
AutoCompletionCandidates result = new AutoCompletionCandidates();
// show all suggestions for short strings
if (query.length() < 2) {
result.add(getProjectLabelsAsArray(job));
} else {
for (String branch : getProjectLabelsAsArray(job)) {
if (branch.toLowerCase().contains(query.toLowerCase())) {
result.add(branch);
}
}
}
return result;
}
public FormValidation doCheckLabels(@AncestorInPath final Job<?, ?> project, @QueryParameter final String value) {
if (!project.hasPermission(Item.CONFIGURE) || containsNoLabel(value)) {
return FormValidation.ok();
}
try {
return checkMatchingLabels(value, getProjectLabels(project));
} catch (GitLabProjectBranchesService.BranchLoadingException e) {
return FormValidation.warning(project.hasPermission(Jenkins.ADMINISTER) ? e : null, Messages.GitLabPushTrigger_CannotCheckBranches());
}
}
private FormValidation checkMatchingLabels(@QueryParameter String value, List<String> labels) {
Set<String> matchingLabels = new HashSet<>();
Set<String> unknownLabels = new HashSet<>();
for (String label : Splitter.on(',').omitEmptyStrings().trimResults().split(value)) {
if (labels.contains(label)) {
matchingLabels.add(label);
} else {
unknownLabels.add(label);
}
}
if (unknownLabels.isEmpty()) {
return FormValidation.ok(Messages.GitLabPushTrigger_LabelsMatched(matchingLabels.size()));
} else {
return FormValidation.warning(Messages.GitLabPushTrigger_LabelsNotFound(Joiner.on(", ").join(unknownLabels)));
}
}
private boolean containsNoLabel(@QueryParameter String value) {
return StringUtils.isEmpty(value) || StringUtils.containsOnly(value, new char[]{',', ' '});
}
private String[] getProjectLabelsAsArray(Job<?, ?> job) {
try {
List<String> labels = getProjectLabels(job);
return labels.toArray(new String[labels.size()]);
} catch (GitLabProjectLabelsService.LabelLoadingException e) {
LOGGER.log(Level.FINEST, "Failed to load labels from GitLab. Please check the logs and your configuration.", e);
}
return new String[0];
}
/**
* Get the URL of the first declared repository in the project configuration.
* Use this as default source repository url.
*
* @return URIish the default value of the source repository url
* @throws IllegalStateException Project does not use git scm.
*/
private URIish getSourceRepoURLDefault(Job<?, ?> job) {
SCMTriggerItem item = SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(job);
GitSCM gitSCM = getGitSCM(item);
if (gitSCM == null) {
LOGGER.log(Level.WARNING, "Could not find GitSCM for project. Project = {1}, next build = {2}",
array(job.getName(), String.valueOf(job.getNextBuildNumber())));
throw new IllegalStateException("This project does not use git:" + job.getName());
}
return getFirstRepoURL(gitSCM.getRepositories());
}
private URIish getFirstRepoURL(List<RemoteConfig> repositories) {
if (!repositories.isEmpty()) {
List<URIish> uris = repositories.get(repositories.size() - 1).getURIs();
if (!uris.isEmpty()) {
return uris.get(uris.size() - 1);
}
}
throw new IllegalStateException(Messages.GitLabPushTrigger_NoSourceRepository());
}
private GitSCM getGitSCM(SCMTriggerItem item) {
if (item != null) {
for (SCM scm : item.getSCMs()) {
if (scm instanceof GitSCM) {
return (GitSCM) scm;
}
}
}
return null;
}
private Object[] array(Object... objects) {
return objects;
}
}

View File

@ -1,243 +0,0 @@
package com.dabsquared.gitlabjenkins.util;
import com.dabsquared.gitlabjenkins.cause.GiteeWebHookCause;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
import hudson.EnvVars;
import hudson.model.Cause;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.model.Cause.UpstreamCause;
import hudson.plugins.git.Revision;
import hudson.plugins.git.util.Build;
import hudson.plugins.git.util.BuildData;
import jenkins.model.Jenkins;
import jenkins.plugins.git.AbstractGitSCMSource;
import jenkins.scm.api.SCMRevision;
import jenkins.scm.api.SCMRevisionAction;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jgit.lib.ObjectId;
import org.jenkinsci.plugins.displayurlapi.DisplayURLProvider;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.ProcessingException;
import javax.ws.rs.WebApplicationException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import static com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty.getClient;
/**
* @author Robin Müller
*/
public class CommitStatusUpdater {
private final static Logger LOGGER = Logger.getLogger(CommitStatusUpdater.class.getName());
public static void updateCommitStatus(Run<?, ?> build, TaskListener listener, BuildState state, String name) {
GitLabClient client = getClient(build);
if (client == null) {
println(listener, "No GitLab connection configured");
return;
}
try {
final String buildUrl = getBuildUrl(build);
for (final GitLabBranchBuild gitLabBranchBuild : retrieveGitlabProjectIds(build, build.getEnvironment(listener))) {
try {
if (existsCommit(client, gitLabBranchBuild.getProjectId(), gitLabBranchBuild.getRevisionHash())) {
client.changeBuildStatus(gitLabBranchBuild.getProjectId(), gitLabBranchBuild.getRevisionHash(), state, getBuildBranch(build), name, buildUrl, state.name());
}
} catch (WebApplicationException | ProcessingException e) {
printf(listener, "Failed to update Gitlab commit status for project '%s': %s%n", gitLabBranchBuild.getProjectId(), e.getMessage());
LOGGER.log(Level.SEVERE, String.format("Failed to update Gitlab commit status for project '%s'", gitLabBranchBuild.getProjectId()), e);
}
}
} catch (IOException | InterruptedException | IllegalStateException e) {
printf(listener, "Failed to update Gitlab commit status: %s%n", e.getMessage());
}
}
private static void println(TaskListener listener, String message) {
if (listener == null) {
LOGGER.log(Level.FINE, "failed to print message {0} due to null TaskListener", message);
} else {
listener.getLogger().println(message);
}
}
private static void printf(TaskListener listener, String message, Object... args) {
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 static boolean existsCommit(GitLabClient client, String gitlabProjectId, String commitHash) {
try {
client.getCommit(gitlabProjectId, commitHash);
return true;
} catch (NotFoundException e) {
LOGGER.log(Level.FINE, String.format("Project (%s) and commit (%s) combination not found", gitlabProjectId, commitHash));
return false;
}
}
private static String getBuildBranch(Run<?, ?> build) {
GiteeWebHookCause cause = build.getCause(GiteeWebHookCause.class);
return cause == null ? null : cause.getData().getSourceBranch();
}
private static String getBuildUrl(Run<?, ?> build) {
return DisplayURLProvider.get().getRunURL(build);
}
private static List<GitLabBranchBuild> retrieveGitlabProjectIds(Run<?, ?> build, EnvVars environment) {
LOGGER.log(Level.INFO, "Retrieving gitlab project ids");
final List<GitLabBranchBuild> result = new ArrayList<>();
GiteeWebHookCause gitlabCause = build.getCause(GiteeWebHookCause.class);
if (gitlabCause != null) {
return Collections.singletonList(new GitLabBranchBuild(
gitlabCause.getData().getSourceProjectId().toString(), gitlabCause.getData().getLastCommit()));
}
// Check upstream causes for GiteeWebHookCause
List<GitLabBranchBuild> builds = findBuildsFromUpstreamCauses(build.getCauses());
if (!builds.isEmpty()) {
return builds;
}
final GitLabClient 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;
}
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;
}
final SCMRevision scmRevision = scmRevisionAction.getRevision();
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);
}
}
}
}
return result;
}
private static String getBuildRevision(Run<?, ?> build) {
GiteeWebHookCause cause = build.getCause(GiteeWebHookCause.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();
if (lastBuiltRevision == null) {
throw new IllegalStateException("Last build has no associated commit");
}
return action.getLastBuild(lastBuiltRevision.getSha1()).getMarked().getSha1String();
}
private static void addGitLabBranchBuild(List<GitLabBranchBuild> result, String scmRevisionHash,
Set<String> remoteUrls, EnvVars environment, GitLabClient 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) {
LOGGER.log(Level.WARNING, "Did not match project id in remote url.");
}
}
}
private static List<GitLabBranchBuild> findBuildsFromUpstreamCauses(List<Cause> causes) {
for (Cause cause : causes) {
if (cause instanceof UpstreamCause) {
List<Cause> upCauses = ((UpstreamCause) cause).getUpstreamCauses(); // Non null, returns empty list when none are set
for (Cause upCause : upCauses) {
if (upCause instanceof GiteeWebHookCause) {
GiteeWebHookCause gitlabCause = (GiteeWebHookCause) upCause;
return Collections.singletonList(
new GitLabBranchBuild(gitlabCause.getData().getSourceProjectId().toString(),
gitlabCause.getData().getLastCommit()));
}
}
List<GitLabBranchBuild> builds = findBuildsFromUpstreamCauses(upCauses);
if (!builds.isEmpty()) {
return builds;
}
}
}
return Collections.emptyList();
}
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;
}
}
}

View File

@ -8,7 +8,6 @@ import javax.annotation.Nonnull;
import org.jenkinsci.plugins.workflow.steps.BodyExecution; import org.jenkinsci.plugins.workflow.steps.BodyExecution;
import org.jenkinsci.plugins.workflow.steps.BodyExecutionCallback; import org.jenkinsci.plugins.workflow.steps.BodyExecutionCallback;
import org.jenkinsci.plugins.workflow.steps.FlowInterruptedException;
import org.jenkinsci.plugins.workflow.steps.Step; import org.jenkinsci.plugins.workflow.steps.Step;
import org.jenkinsci.plugins.workflow.steps.StepContext; import org.jenkinsci.plugins.workflow.steps.StepContext;
import org.jenkinsci.plugins.workflow.steps.StepDescriptor; import org.jenkinsci.plugins.workflow.steps.StepDescriptor;
@ -17,8 +16,6 @@ import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter; import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.export.ExportedBean;
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
import com.dabsquared.gitlabjenkins.util.CommitStatusUpdater;
import com.google.common.base.Splitter; import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
@ -81,9 +78,6 @@ public class GitLabBuildsStep extends Step {
.withCallback(new BodyExecutionCallback() { .withCallback(new BodyExecutionCallback() {
@Override @Override
public void onStart(StepContext context) { public void onStart(StepContext context) {
for (String name : step.builds) {
CommitStatusUpdater.updateCommitStatus(run, getTaskListener(context), BuildState.pending, name);
}
run.addAction(new PendingBuildsAction(new ArrayList<>(step.builds))); run.addAction(new PendingBuildsAction(new ArrayList<>(step.builds)));
} }
@ -101,13 +95,6 @@ public class GitLabBuildsStep extends Step {
@Override @Override
public void onFailure(StepContext context, Throwable t) { public void onFailure(StepContext context, Throwable t) {
PendingBuildsAction action = run.getAction(PendingBuildsAction.class);
if (action != null) {
BuildState state = t instanceof FlowInterruptedException ? BuildState.canceled : BuildState.failed;
for (String name : action.getBuilds()) {
CommitStatusUpdater.updateCommitStatus(run, getTaskListener(context), state, name);
}
}
context.onFailure(t); context.onFailure(t);
} }
}) })
@ -119,12 +106,6 @@ public class GitLabBuildsStep extends Step {
public void stop(@Nonnull Throwable cause) throws Exception { public void stop(@Nonnull Throwable cause) throws Exception {
// should be no need to do anything special (but verify in JENKINS-26148) // should be no need to do anything special (but verify in JENKINS-26148)
if (body != null) { if (body != null) {
PendingBuildsAction action = run.getAction(PendingBuildsAction.class);
if (action != null) {
for (String name : action.getBuilds()) {
CommitStatusUpdater.updateCommitStatus(run, null, BuildState.canceled, name);
}
}
body.cancel(cause); body.cancel(cause);
} }
} }

View File

@ -17,7 +17,6 @@ import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.export.ExportedBean;
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState; import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
import com.dabsquared.gitlabjenkins.util.CommitStatusUpdater;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import hudson.Extension; import hudson.Extension;
@ -73,7 +72,6 @@ public class GitLabCommitStatusStep extends Step {
.withCallback(new BodyExecutionCallback() { .withCallback(new BodyExecutionCallback() {
@Override @Override
public void onStart(StepContext context) { public void onStart(StepContext context) {
CommitStatusUpdater.updateCommitStatus(run, getTaskListener(context), BuildState.running, name);
PendingBuildsAction action = run.getAction(PendingBuildsAction.class); PendingBuildsAction action = run.getAction(PendingBuildsAction.class);
if (action != null) { if (action != null) {
action.startBuild(name); action.startBuild(name);
@ -82,14 +80,11 @@ public class GitLabCommitStatusStep extends Step {
@Override @Override
public void onSuccess(StepContext context, Object result) { public void onSuccess(StepContext context, Object result) {
CommitStatusUpdater.updateCommitStatus(run, getTaskListener(context), BuildState.success, name);
context.onSuccess(result); context.onSuccess(result);
} }
@Override @Override
public void onFailure(StepContext context, Throwable t) { public void onFailure(StepContext context, Throwable t) {
BuildState state = t instanceof FlowInterruptedException ? BuildState.canceled : BuildState.failed;
CommitStatusUpdater.updateCommitStatus(run, getTaskListener(context), state, name);
context.onFailure(t); context.onFailure(t);
} }
}) })
@ -101,8 +96,6 @@ public class GitLabCommitStatusStep extends Step {
public void stop(@Nonnull Throwable cause) throws Exception { public void stop(@Nonnull Throwable cause) throws Exception {
// should be no need to do anything special (but verify in JENKINS-26148) // should be no need to do anything special (but verify in JENKINS-26148)
if (body != null) { if (body != null) {
String name = StringUtils.isEmpty(step.name) ? "jenkins" : step.name;
CommitStatusUpdater.updateCommitStatus(run, null, BuildState.canceled, name);
body.cancel(cause); body.cancel(cause);
} }
} }

View File

@ -14,7 +14,6 @@ import org.kohsuke.stapler.DataBoundSetter;
import org.kohsuke.stapler.export.ExportedBean; import org.kohsuke.stapler.export.ExportedBean;
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState; import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
import com.dabsquared.gitlabjenkins.util.CommitStatusUpdater;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import hudson.Extension; import hudson.Extension;
@ -76,7 +75,6 @@ public class UpdateGitLabCommitStatusStep extends Step {
@Override @Override
protected Void run() throws Exception { protected Void run() throws Exception {
final String name = StringUtils.isEmpty(step.name) ? "jenkins" : step.name; final String name = StringUtils.isEmpty(step.name) ? "jenkins" : step.name;
CommitStatusUpdater.updateCommitStatus(run, null, step.state, name);
PendingBuildsAction action = run.getAction(PendingBuildsAction.class); PendingBuildsAction action = run.getAction(PendingBuildsAction.class);
if (action != null) { if (action != null) {
action.startBuild(name); action.startBuild(name);

View File

@ -8,7 +8,6 @@ import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
import com.cloudbees.plugins.credentials.domains.Domain; import com.cloudbees.plugins.credentials.domains.Domain;
import com.dabsquared.gitlabjenkins.GitLabPushTrigger; import com.dabsquared.gitlabjenkins.GitLabPushTrigger;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient; import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
import com.dabsquared.gitlabjenkins.gitlab.api.impl.V3GitLabClientBuilder;
import hudson.ProxyConfiguration; import hudson.ProxyConfiguration;
import hudson.model.FreeStyleProject; import hudson.model.FreeStyleProject;
import hudson.model.Item; import hudson.model.Item;

View File

@ -1,9 +1,6 @@
package com.dabsquared.gitlabjenkins.gitlab.api; package com.dabsquared.gitlabjenkins.gitlab.api;
import com.dabsquared.gitlabjenkins.gitlab.api.impl.AutodetectGitLabClientBuilder;
import com.dabsquared.gitlabjenkins.gitlab.api.impl.V3GitLabClientBuilder;
import com.dabsquared.gitlabjenkins.gitlab.api.impl.V4GitLabClientBuilder;
import org.junit.Rule; import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.jvnet.hudson.test.JenkinsRule; import org.jvnet.hudson.test.JenkinsRule;
@ -24,7 +21,7 @@ public class GitLabClientBuilderTest {
@Test @Test
public void getAllGitLabClientBuilders_list_is_sorted_by_ordinal() { public void getAllGitLabClientBuilders_list_is_sorted_by_ordinal() {
List<GitLabClientBuilder> builders = getAllGitLabClientBuilders(); List<GitLabClientBuilder> builders = getAllGitLabClientBuilders();
assertThat(builders.get(0), instanceOf(AutodetectGitLabClientBuilder.class)); assertThat(builders.get(0), instanceOf(AutodetectGiteeClientBuilder.class));
assertThat(builders.get(1), instanceOf(V4GitLabClientBuilder.class)); assertThat(builders.get(1), instanceOf(V4GitLabClientBuilder.class));
assertThat(builders.get(2), instanceOf(V3GitLabClientBuilder.class)); assertThat(builders.get(2), instanceOf(V3GitLabClientBuilder.class));
} }

View File

@ -19,7 +19,7 @@ import static org.junit.Assert.fail;
import static org.mockserver.matchers.Times.exactly; import static org.mockserver.matchers.Times.exactly;
import static org.mockserver.matchers.Times.once; import static org.mockserver.matchers.Times.once;
public class AutodetectingGitLabClientTest { public class AutodetectingGiteeClientTest {
@Rule @Rule
public MockServerRule mockServer = new MockServerRule(this); public MockServerRule mockServer = new MockServerRule(this);
@Rule @Rule
@ -27,7 +27,7 @@ public class AutodetectingGitLabClientTest {
private MockServerClient mockServerClient; private MockServerClient mockServerClient;
private String gitLabUrl; private String gitLabUrl;
private GitLabClientBuilder clientBuilder; private GitLabClientBuilder clientBuilder;
private AutodetectingGitLabClient api; private AutodetectingGiteeClient api;
private HttpRequest v3Request; private HttpRequest v3Request;
private HttpRequest v4Request; private HttpRequest v4Request;
@ -37,7 +37,7 @@ public class AutodetectingGitLabClientTest {
addGitLabApiToken(); addGitLabApiToken();
List<GitLabClientBuilder> builders = Arrays.<GitLabClientBuilder>asList(new V3GitLabClientBuilder(), new V4GitLabClientBuilder()); List<GitLabClientBuilder> builders = Arrays.<GitLabClientBuilder>asList(new V3GitLabClientBuilder(), new V4GitLabClientBuilder());
api = new AutodetectingGitLabClient(builders, gitLabUrl, API_TOKEN, true, 10, 10); api = new AutodetectingGiteeClient(builders, gitLabUrl, API_TOKEN, true, 10, 10);
v3Request = versionRequest(V3GitLabApiProxy.ID); v3Request = versionRequest(V3GitLabApiProxy.ID);
v4Request = versionRequest(V4GitLabApiProxy.ID); v4Request = versionRequest(V4GitLabApiProxy.ID);

View File

@ -13,7 +13,7 @@ import static com.dabsquared.gitlabjenkins.gitlab.api.impl.TestUtility.buildClie
import static junit.framework.TestCase.assertNotNull; import static junit.framework.TestCase.assertNotNull;
public class ResteasyGitLabClientBuilderTest { public class ResteasyGiteeClientBuilderTest {
@Rule @Rule
public MockServerRule mockServer = new MockServerRule(this); public MockServerRule mockServer = new MockServerRule(this);
@Rule @Rule
@ -21,14 +21,14 @@ public class ResteasyGitLabClientBuilderTest {
@Test @Test
public void buildClient() throws Exception { public void buildClient() throws Exception {
GitLabClientBuilder clientBuilder = new ResteasyGitLabClientBuilder("test", 0, V3GitLabApiProxy.class, null); GitLabClientBuilder clientBuilder = new ResteasyGiteeClientBuilder("test", 0, V3GitLabApiProxy.class, null);
assertApiImpl(buildClientWithDefaults(clientBuilder, "http://localhost/"), V3GitLabApiProxy.class); assertApiImpl(buildClientWithDefaults(clientBuilder, "http://localhost/"), V3GitLabApiProxy.class);
} }
@Test @Test
public void buildClientWithProxy() throws Exception { public void buildClientWithProxy() throws Exception {
jenkins.getInstance().proxy = new ProxyConfiguration("example.com", 8080, "test", "test", "*localhost*"); jenkins.getInstance().proxy = new ProxyConfiguration("example.com", 8080, "test", "test", "*localhost*");
GitLabClientBuilder clientBuilder = new ResteasyGitLabClientBuilder("test", 0, V3GitLabApiProxy.class, null); GitLabClientBuilder clientBuilder = new ResteasyGiteeClientBuilder("test", 0, V3GitLabApiProxy.class, null);
assertNotNull(buildClientWithDefaults(clientBuilder, "http://localhost")); assertNotNull(buildClientWithDefaults(clientBuilder, "http://localhost"));
} }

View File

@ -65,13 +65,13 @@ class TestUtility {
return clientBuilder.buildClient(url, API_TOKEN, IGNORE_CERTIFICATE_ERRORS, CONNECTION_TIMEOUT, READ_TIMEOUT); return clientBuilder.buildClient(url, API_TOKEN, IGNORE_CERTIFICATE_ERRORS, CONNECTION_TIMEOUT, READ_TIMEOUT);
} }
static void assertApiImpl(GitLabClient client, Class<? extends GitLabApiProxy> apiImplClass) throws Exception { static void assertApiImpl(GitLabClient client, Class<? extends GiteeApiProxy> apiImplClass) throws Exception {
Field apiField = ((ResteasyGitLabClient) client).getClass().getDeclaredField("api"); Field apiField = ((ResteasyGiteeClient) client).getClass().getDeclaredField("api");
apiField.setAccessible(true); apiField.setAccessible(true);
assertThat(apiField.get(client), instanceOf(apiImplClass)); assertThat(apiField.get(client), instanceOf(apiImplClass));
} }
static void assertApiImpl(AutodetectingGitLabClient api, Class<? extends GitLabApiProxy> apiImplClass) throws Exception { static void assertApiImpl(AutodetectingGiteeClient api, Class<? extends GiteeApiProxy> apiImplClass) throws Exception {
Field delegate = api.getClass().getDeclaredField("delegate"); Field delegate = api.getClass().getDeclaredField("delegate");
delegate.setAccessible(true); delegate.setAccessible(true);
assertApiImpl((GitLabClient) delegate.get(api), apiImplClass); assertApiImpl((GitLabClient) delegate.get(api), apiImplClass);

View File

@ -9,8 +9,6 @@ import com.cloudbees.plugins.credentials.domains.Domain;
import com.dabsquared.gitlabjenkins.connection.GitLabConnection; import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig; import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig;
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty; import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
import com.dabsquared.gitlabjenkins.gitlab.api.impl.V3GitLabClientBuilder;
import com.dabsquared.gitlabjenkins.gitlab.api.impl.V4GitLabClientBuilder;
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest; import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
import hudson.Launcher; import hudson.Launcher;
import hudson.matrix.MatrixAggregatable; import hudson.matrix.MatrixAggregatable;

View File

@ -10,7 +10,6 @@ import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig; import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig;
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty; import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient; import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
import com.dabsquared.gitlabjenkins.gitlab.api.impl.V3GitLabClientBuilder;
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest; import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Pipeline; import com.dabsquared.gitlabjenkins.gitlab.api.model.Pipeline;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Project; import com.dabsquared.gitlabjenkins.gitlab.api.model.Project;
@ -22,8 +21,6 @@ import org.junit.rules.TestRule;
import org.junit.runner.Description; import org.junit.runner.Description;
import org.junit.runners.model.Statement; import org.junit.runners.model.Statement;
import javax.ws.rs.client.ClientRequestContext;
import javax.ws.rs.client.ClientRequestFilter;
import java.io.IOException; import java.io.IOException;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;

View File

@ -4,7 +4,6 @@ package com.dabsquared.gitlabjenkins.testing.integration;
import com.dabsquared.gitlabjenkins.GitLabPushTrigger; import com.dabsquared.gitlabjenkins.GitLabPushTrigger;
import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest; import com.dabsquared.gitlabjenkins.gitlab.api.model.MergeRequest;
import com.dabsquared.gitlabjenkins.gitlab.api.model.Pipeline; import com.dabsquared.gitlabjenkins.gitlab.api.model.Pipeline;
import com.dabsquared.gitlabjenkins.publisher.GitLabCommitStatusPublisher;
import com.dabsquared.gitlabjenkins.testing.gitlab.rule.GitLabRule; import com.dabsquared.gitlabjenkins.testing.gitlab.rule.GitLabRule;
import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilterType; import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilterType;
import hudson.Launcher; import hudson.Launcher;

View File

@ -6,7 +6,6 @@ import com.dabsquared.gitlabjenkins.gitlab.api.GitLabClient;
import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState; import com.dabsquared.gitlabjenkins.gitlab.api.model.BuildState;
import com.dabsquared.gitlabjenkins.gitlab.hook.model.*; import com.dabsquared.gitlabjenkins.gitlab.hook.model.*;
import com.dabsquared.gitlabjenkins.gitlab.hook.model.builder.generated.*; import com.dabsquared.gitlabjenkins.gitlab.hook.model.builder.generated.*;
import com.dabsquared.gitlabjenkins.publisher.GitLabCommitStatusPublisher;
import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilterType; import com.dabsquared.gitlabjenkins.trigger.filter.BranchFilterType;
import hudson.model.FreeStyleProject; import hudson.model.FreeStyleProject;
import hudson.model.ItemGroup; import hudson.model.ItemGroup;