Skip to content

Commit

Permalink
Add functionality to configure multiple GitLab instances
Browse files Browse the repository at this point in the history
  • Loading branch information
coder-hugo committed Feb 27, 2016
1 parent d9961be commit 5c49504
Show file tree
Hide file tree
Showing 14 changed files with 427 additions and 151 deletions.
19 changes: 12 additions & 7 deletions src/main/java/com/dabsquared/gitlabjenkins/GitLab.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import java.util.logging.Level;
import java.util.logging.Logger;

import com.dabsquared.gitlabjenkins.connection.GitLabConnection;
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionConfig;
import hudson.model.Descriptor;
import jenkins.model.Jenkins;
import org.gitlab.api.GitlabAPI;

public class GitLab {
Expand All @@ -12,12 +16,13 @@ public class GitLab {

public GitlabAPI instance() {
if (api == null) {
String token = GitLabPushTrigger.getDesc().getGitlabApiToken();
String url = GitLabPushTrigger.getDesc().getGitlabHostUrl();
boolean ignoreCertificateErrors = GitLabPushTrigger.getDesc().getIgnoreCertificateErrors();
LOGGER.log(Level.FINE, "Connecting to Gitlab server ({0})", url);
api = GitlabAPI.connect(url, token);
api.ignoreCertificateErrors(ignoreCertificateErrors);
// Use the first configured connection as work around for the GitLabProjectBranchesService
GitLabConnectionConfig connectionConfig = (GitLabConnectionConfig) Jenkins.getInstance().getDescriptor(GitLabConnectionConfig.class);
if (connectionConfig != null && connectionConfig.getConnections().size() > 0) {
GitLabConnection connection = connectionConfig.getConnections().get(0);
api = GitlabAPI.connect(connection.getUrl(), connection.getApiToken());
api.ignoreCertificateErrors(connection.isIgnoreCertificateErrors());
}
}

return api;
Expand All @@ -29,4 +34,4 @@ public static boolean checkConnection (String token, String url, boolean ignoreC
testApi.getProjects();
return true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
import com.dabsquared.gitlabjenkins.data.ObjectAttributes;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.gitlab.api.GitlabAPI;
import org.gitlab.api.models.GitlabProject;
import org.gitlab.api.models.GitlabUser;

import java.io.IOException;

Expand Down Expand Up @@ -32,9 +32,9 @@ public GitLabMergeRequest() {
private ObjectAttributes objectAttributes;
private GitlabProject sourceProject = null;

public GitlabProject getSourceProject (GitLab api) throws IOException {
public GitlabProject getSourceProject(GitlabAPI gitlabAPI) throws IOException {
if (sourceProject == null) {
sourceProject = api.instance().getProject(objectAttributes.getSourceProjectId());
sourceProject = gitlabAPI.getProject(objectAttributes.getSourceProjectId());
}
return sourceProject;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.dabsquared.gitlabjenkins.data.Repository;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.gitlab.api.GitlabAPI;
import org.gitlab.api.models.GitlabProject;

import java.io.IOException;
Expand All @@ -29,9 +30,9 @@ public GitLabPushRequest() {

private GitlabProject sourceProject = null;

public GitlabProject getSourceProject (GitLab api) throws IOException {
public GitlabProject getSourceProject(GitlabAPI gitlabAPI) throws IOException {
if (sourceProject == null) {
sourceProject = api.instance().getProject(project_id);
sourceProject = gitlabAPI.getProject(project_id);
}
return sourceProject;
}
Expand Down
48 changes: 14 additions & 34 deletions src/main/java/com/dabsquared/gitlabjenkins/GitLabPushTrigger.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.dabsquared.gitlabjenkins.cause.GitLabMergeCause;
import com.dabsquared.gitlabjenkins.cause.GitLabPushCause;
import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
import hudson.Extension;
import hudson.Util;
import hudson.model.Action;
Expand Down Expand Up @@ -46,7 +47,7 @@
import org.apache.commons.lang.StringUtils;
import org.eclipse.jgit.transport.RemoteConfig;
import org.eclipse.jgit.transport.URIish;
import org.gitlab.api.models.GitlabProject;
import org.gitlab.api.GitlabAPI;
import org.kohsuke.stapler.AncestorInPath;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
Expand Down Expand Up @@ -300,8 +301,12 @@ private Action[] createActions(GitLabPushRequest req) {
if (!getDescriptor().getGitlabHostUrl().isEmpty()) {
// Get source repository if communication to Gitlab is possible
try {
sourceRepoName = req.getSourceProject(getDesc().getGitlab()).getPathWithNamespace();
sourceRepoURL = req.getSourceProject(getDesc().getGitlab()).getSshUrl();
GitLabConnectionProperty property = job.getProperty(GitLabConnectionProperty.class);
if (property != null && property.getClient() != null) {
GitlabAPI client = property.getClient();
sourceRepoName = req.getSourceProject(client).getPathWithNamespace();
sourceRepoURL = req.getSourceProject(client).getSshUrl();
}
} catch (IOException ex) {
LOGGER.log(Level.WARNING, "Could not fetch source project''s data from Gitlab. '('{0}':' {1}')'", new String[]{ex.toString(), ex.getMessage()});
}
Expand Down Expand Up @@ -426,8 +431,12 @@ private Action[] createActions(GitLabMergeRequest req) {
if (!getDescriptor().getGitlabHostUrl().isEmpty()) {
// Get source repository if communication to Gitlab is possible
try {
sourceRepoName = req.getSourceProject(getDesc().getGitlab()).getPathWithNamespace();
sourceRepoURL = req.getSourceProject(getDesc().getGitlab()).getSshUrl();
GitLabConnectionProperty property = job.getProperty(GitLabConnectionProperty.class);
if (property != null && property.getClient() != null) {
GitlabAPI client = property.getClient();
sourceRepoName = req.getSourceProject(client).getPathWithNamespace();
sourceRepoURL = req.getSourceProject(client).getSshUrl();
}
} catch (IOException ex) {
LOGGER.log(Level.WARNING, "Could not fetch source project''s data from Gitlab. '('{0}':' {1}')'", new String[]{ex.toString(), ex.getMessage()});
}
Expand Down Expand Up @@ -617,9 +626,6 @@ public String getDisplayName() {

@Override
public boolean configure(StaplerRequest req, JSONObject formData) throws FormException {
gitlabApiToken = formData.getString("gitlabApiToken");
gitlabHostUrl = formData.getString("gitlabHostUrl");
ignoreCertificateErrors = formData.getBoolean("ignoreCertificateErrors");
save();
gitlab = new GitLab();
return super.configure(req, formData);
Expand Down Expand Up @@ -809,32 +815,6 @@ protected String getSourceRepoNameDefault(Job job) {
return result;
}

public FormValidation doCheckGitlabHostUrl(@QueryParameter String value) {
if (value == null || value.isEmpty()) {
return FormValidation.error("Gitlab host URL required.");
}

return FormValidation.ok();
}

public FormValidation doCheckGitlabApiToken(@QueryParameter String value) {
if (value == null || value.isEmpty()) {
return FormValidation.error("API Token for Gitlab access required");
}

return FormValidation.ok();
}

public FormValidation doTestConnection(@QueryParameter("gitlabHostUrl") final String hostUrl,
@QueryParameter("gitlabApiToken") final String token, @QueryParameter("ignoreCertificateErrors") final boolean ignoreCertificateErrors) throws IOException {
try {
GitLab.checkConnection(token, hostUrl, ignoreCertificateErrors);
return FormValidation.ok("Success");
} catch (IOException e) {
return FormValidation.error("Client error : "+e.getMessage());
}
}

public GitLab getGitlab() {
if (gitlab == null) {
gitlab = new GitLab();
Expand Down
121 changes: 63 additions & 58 deletions src/main/java/com/dabsquared/gitlabjenkins/GitLabWebHook.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.dabsquared.gitlabjenkins;

import com.dabsquared.gitlabjenkins.connection.GitLabConnectionProperty;
import com.dabsquared.gitlabjenkins.data.LastCommit;
import com.dabsquared.gitlabjenkins.data.ObjectAttributes;
import com.google.common.base.Joiner;
Expand Down Expand Up @@ -27,6 +28,7 @@
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.eclipse.jgit.lib.ObjectId;
import org.gitlab.api.GitlabAPI;
import org.gitlab.api.models.GitlabBranch;
import org.gitlab.api.models.GitlabCommit;
import org.gitlab.api.models.GitlabMergeRequest;
Expand Down Expand Up @@ -379,71 +381,74 @@ public void generatePushBuild(String json, Job project, StaplerRequest req, Stap

if (!trigger.getTriggerOpenMergeRequestOnPush().equals("never")) {
// Fetch and build open merge requests with the same source branch
buildOpenMergeRequests(trigger, request.getProject_id(), request.getRef());
buildOpenMergeRequests(trigger, request.getProject_id(), request.getRef(), project);
}
} finally {
SecurityContextHolder.getContext().setAuthentication(old);
}
}

protected void buildOpenMergeRequests(GitLabPushTrigger trigger, Integer projectId, String projectRef) {
protected void buildOpenMergeRequests(GitLabPushTrigger trigger, Integer projectId, String projectRef, Job<?, ?> project) {
try {
GitLab api = new GitLab();
List<GitlabMergeRequest> mergeRequests = api.instance().getOpenMergeRequests(projectId);

for (org.gitlab.api.models.GitlabMergeRequest mr : mergeRequests) {
if (projectRef.endsWith(mr.getSourceBranch()) ||
(trigger.getTriggerOpenMergeRequestOnPush().equals("both") && projectRef.endsWith(mr.getTargetBranch()))) {

if (trigger.getCiSkip() && mr.getDescription().contains("[ci-skip]")) {
LOGGER.log(Level.INFO, "Skipping MR " + mr.getTitle() + " due to ci-skip.");
continue;
}
GitlabBranch branch = api.instance().getBranch(api.instance().getProject(projectId), mr.getSourceBranch());
LastCommit lastCommit = new LastCommit();
lastCommit.setId(branch.getCommit().getId());
lastCommit.setMessage(branch.getCommit().getMessage());
lastCommit.setUrl(GitlabProject.URL + "/" + projectId + "/repository" + GitlabCommit.URL + "/"
+ branch.getCommit().getId());

LOGGER.log(Level.FINE,
"Generating new merge trigger from "
+ mr.toString() + "\n source: "
+ mr.getSourceBranch() + "\n target: "
+ mr.getTargetBranch() + "\n state: "
+ mr.getState() + "\n assign: "
+ mr.getAssignee().getName() + "\n author: "
+ mr.getAuthor().getName() + "\n id: "
+ mr.getId() + "\n iid: "
+ mr.getIid() + "\n last commit: "
+ lastCommit.getId() + "\n\n");
GitLabMergeRequest newReq = new GitLabMergeRequest();
newReq.setObject_kind("merge_request");
newReq.setObjectAttribute(new ObjectAttributes());
if (mr.getAssignee() != null)
newReq.getObjectAttribute().setAssignee(mr.getAssignee());
if (mr.getAuthor() != null)
newReq.getObjectAttribute().setAuthor(mr.getAuthor());
newReq.getObjectAttribute().setDescription(mr.getDescription());
newReq.getObjectAttribute().setId(mr.getId());
newReq.getObjectAttribute().setIid(mr.getIid());
newReq.getObjectAttribute().setMergeStatus(mr.getState());
newReq.getObjectAttribute().setSourceBranch(mr.getSourceBranch());
newReq.getObjectAttribute().setSourceProjectId(mr.getSourceProjectId());
newReq.getObjectAttribute().setTargetBranch(mr.getTargetBranch());
newReq.getObjectAttribute().setTargetProjectId(projectId);
newReq.getObjectAttribute().setTitle(mr.getTitle());
newReq.getObjectAttribute().setLastCommit(lastCommit);

Authentication old = SecurityContextHolder.getContext().getAuthentication();
SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM);
try {
trigger.onPost(newReq);
} finally {
SecurityContextHolder.getContext().setAuthentication(old);
}
}
}
GitLabConnectionProperty property = project.getProperty(GitLabConnectionProperty.class);
if (property != null && property.getClient() != null) {
GitlabAPI client = property.getClient();
List<GitlabMergeRequest> mergeRequests = client.getOpenMergeRequests(projectId);

for (org.gitlab.api.models.GitlabMergeRequest mr : mergeRequests) {
if (projectRef.endsWith(mr.getSourceBranch()) ||
(trigger.getTriggerOpenMergeRequestOnPush().equals("both") && projectRef.endsWith(mr.getTargetBranch()))) {

if (trigger.getCiSkip() && mr.getDescription().contains("[ci-skip]")) {
LOGGER.log(Level.INFO, "Skipping MR " + mr.getTitle() + " due to ci-skip.");
continue;
}
GitlabBranch branch = client.getBranch(client.getProject(projectId), mr.getSourceBranch());
LastCommit lastCommit = new LastCommit();
lastCommit.setId(branch.getCommit().getId());
lastCommit.setMessage(branch.getCommit().getMessage());
lastCommit.setUrl(GitlabProject.URL + "/" + projectId + "/repository" + GitlabCommit.URL + "/"
+ branch.getCommit().getId());

LOGGER.log(Level.FINE,
"Generating new merge trigger from "
+ mr.toString() + "\n source: "
+ mr.getSourceBranch() + "\n target: "
+ mr.getTargetBranch() + "\n state: "
+ mr.getState() + "\n assign: "
+ mr.getAssignee().getName() + "\n author: "
+ mr.getAuthor().getName() + "\n id: "
+ mr.getId() + "\n iid: "
+ mr.getIid() + "\n last commit: "
+ lastCommit.getId() + "\n\n");
GitLabMergeRequest newReq = new GitLabMergeRequest();
newReq.setObject_kind("merge_request");
newReq.setObjectAttribute(new ObjectAttributes());
if (mr.getAssignee() != null)
newReq.getObjectAttribute().setAssignee(mr.getAssignee());
if (mr.getAuthor() != null)
newReq.getObjectAttribute().setAuthor(mr.getAuthor());
newReq.getObjectAttribute().setDescription(mr.getDescription());
newReq.getObjectAttribute().setId(mr.getId());
newReq.getObjectAttribute().setIid(mr.getIid());
newReq.getObjectAttribute().setMergeStatus(mr.getState());
newReq.getObjectAttribute().setSourceBranch(mr.getSourceBranch());
newReq.getObjectAttribute().setSourceProjectId(mr.getSourceProjectId());
newReq.getObjectAttribute().setTargetBranch(mr.getTargetBranch());
newReq.getObjectAttribute().setTargetProjectId(projectId);
newReq.getObjectAttribute().setTitle(mr.getTitle());
newReq.getObjectAttribute().setLastCommit(lastCommit);

Authentication old = SecurityContextHolder.getContext().getAuthentication();
SecurityContextHolder.getContext().setAuthentication(ACL.SYSTEM);
try {
trigger.onPost(newReq);
} finally {
SecurityContextHolder.getContext().setAuthentication(old);
}
}
}
}
} catch (Exception e) {
LOGGER.warning("failed to communicate with gitlab server to determine is this is an update for a merge request: "
+ e.getMessage());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.dabsquared.gitlabjenkins.connection;

import org.kohsuke.stapler.DataBoundConstructor;

/**
* @author Robin Müller
*/
public class GitLabConnection {

private final String name;
private final String url;
private final String apiToken;
private final boolean ignoreCertificateErrors;

@DataBoundConstructor
public GitLabConnection(String name, String url, String apiToken, boolean ignoreCertificateErrors) {
this.name = name;
this.url = url;
this.apiToken = apiToken;
this.ignoreCertificateErrors = ignoreCertificateErrors;
}

public String getName() {
return name;
}

public String getUrl() {
return url;
}

public String getApiToken() {
return apiToken;
}

public boolean isIgnoreCertificateErrors() {
return ignoreCertificateErrors;
}
}
Loading

0 comments on commit 5c49504

Please sign in to comment.