diff --git a/README.md b/README.md index 1ca775c26..dd5dd66be 100644 --- a/README.md +++ b/README.md @@ -60,15 +60,16 @@ Using it With A Job * In GitLab go to you primary repository's project *Settings* * Click on *Web Hooks* * Add a Web Hook for *Merge Request Events* and *Push Events* to ``http://JENKINS_URL/project/PROJECT_NAME``
- **Note:** Currently GitLab 8.0 does not have a commit status api. Once this is added we should be able to add the commit status to Gitlab. If you plan to use forked repositories, you will need to enable the GitLab CI integration on **each fork**. * Go to the Settings page in each developer's fork * Click on *Services* * Click on *Web Hooks* * Add a Web Hook for *Merge Request Events* and *Push Events* to ``http://JENKINS_URL/project/PROJECT_NAME``
- **Note:** Currently GitLab 8.0 does not have a commit status api. Once this is added we should be able to add the commit status to Gitlab. **Note:** You do not need to select any "Trigger Events" as the Web Hook for Merge Request Events will alert Jenkins. +## Gitlab Configuration (≥ 8.1) +GitLab 8.1 uses the same configuration as GitLab 8.0 +* GitLab 8.1 has implemented a commit status api. To enable this check the ``Use GitLab CI features`` under the project settings. ### GitLab Configuration (< 8.0) * In GitLab go to you primary repository's project *Settings* diff --git a/pom.xml b/pom.xml index c609c15d1..9f62979d8 100644 --- a/pom.xml +++ b/pom.xml @@ -140,7 +140,7 @@ org.gitlab java-gitlab-api - 1.1.9 + 1.1.11 diff --git a/src/main/java/com/dabsquared/gitlabjenkins/GitLabMergeRequest.java b/src/main/java/com/dabsquared/gitlabjenkins/GitLabMergeRequest.java index f46b311fc..2ad927417 100644 --- a/src/main/java/com/dabsquared/gitlabjenkins/GitLabMergeRequest.java +++ b/src/main/java/com/dabsquared/gitlabjenkins/GitLabMergeRequest.java @@ -5,6 +5,9 @@ import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; +import org.gitlab.api.GitlabAPI; +import org.gitlab.api.models.GitlabCommitStatus; +import org.gitlab.api.models.GitlabMergeRequest; import org.gitlab.api.models.GitlabProject; /** @@ -60,6 +63,18 @@ public String toString() { return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE); } + public GitlabCommitStatus createCommitStatus(GitlabAPI api, String status, String targetUrl) { + try { + if(objectAttributes.lastCommit!=null) { + return api.createCommitStatus(sourceProject, objectAttributes.getLastCommit().getId(), status, objectAttributes.getLastCommit().getId(), "Jenkins", targetUrl, null); + } + } catch (IOException e) { + e.printStackTrace(); + } + + return null; + } + public static class ObjectAttributes { private Integer id; diff --git a/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushCause.java b/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushCause.java index cee56430d..ddd310dff 100644 --- a/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushCause.java +++ b/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushCause.java @@ -10,24 +10,35 @@ */ public class GitLabPushCause extends SCMTrigger.SCMTriggerCause { - private final String pushedBy; + private final GitLabPushRequest pushRequest; - public GitLabPushCause(String pushedBy) { - this.pushedBy = pushedBy; + public GitLabPushCause(GitLabPushRequest pushRequest) { + this.pushRequest=pushRequest; } - public GitLabPushCause(String pushedBy, File logFile) throws IOException { + public GitLabPushCause(GitLabPushRequest pushRequest, File logFile) throws IOException{ super(logFile); - this.pushedBy = pushedBy; + this.pushRequest=pushRequest; } - public GitLabPushCause(String pushedBy, String pollingLog) { + public GitLabPushCause(GitLabPushRequest pushRequest, String pollingLog) { super(pollingLog); - this.pushedBy = pushedBy; + this.pushRequest=pushRequest; + } + + public GitLabPushRequest getPushRequest() { + return pushRequest; } @Override public String getShortDescription() { + String pushedBy; + if (pushRequest.getCommits().size() > 0){ + pushedBy = pushRequest.getCommits().get(0).getAuthor().getName(); + } else { + pushedBy = pushRequest.getUser_name(); + } + if (pushedBy == null) { return "Started by GitLab push"; } else { diff --git a/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushRequest.java b/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushRequest.java index 50689af11..fbf2556db 100644 --- a/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushRequest.java +++ b/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushRequest.java @@ -1,9 +1,13 @@ package com.dabsquared.gitlabjenkins; +import java.io.IOException; import java.util.List; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; +import org.gitlab.api.GitlabAPI; +import org.gitlab.api.models.GitlabCommitStatus; +import org.gitlab.api.models.GitlabProject; /** * Represents for WebHook payload @@ -23,6 +27,25 @@ public static GitLabPushRequest create(String payload) { public GitLabPushRequest() { } + private GitlabProject sourceProject = null; + + public GitlabProject getSourceProject (GitLab api) throws IOException { + if (sourceProject == null) { + sourceProject = api.instance().getProject(project_id); + } + return sourceProject; + } + + public GitlabCommitStatus createCommitStatus(GitlabAPI api, String status, String targetUrl) { + try { + if(getLastCommit()!=null) { + return api.createCommitStatus(sourceProject, checkout_sha, status, checkout_sha, "Jenkins", targetUrl, null); + } + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } private String before; private String after; diff --git a/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushTrigger.java b/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushTrigger.java index 42e5c63a2..9e10b10c6 100644 --- a/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushTrigger.java +++ b/src/main/java/com/dabsquared/gitlabjenkins/GitLabPushTrigger.java @@ -40,7 +40,6 @@ import jenkins.triggers.SCMTriggerItem; import jenkins.triggers.SCMTriggerItem.SCMTriggerItems; import net.sf.json.JSONObject; -import javax.annotation.Nullable; import org.apache.commons.lang.StringUtils; import org.eclipse.jgit.transport.RemoteConfig; @@ -82,6 +81,7 @@ public class GitLabPushTrigger extends Trigger> { private boolean ciSkip = true; private boolean setBuildDescription = true; private boolean addNoteOnMergeRequest = true; + private boolean addCiMessage = false; private boolean addVoteOnMergeRequest = true; private boolean allowAllBranches = false; private final String includeBranchesSpec; @@ -89,14 +89,15 @@ public class GitLabPushTrigger extends Trigger> { private boolean acceptMergeRequestOnSuccess = false; @DataBoundConstructor - public GitLabPushTrigger(boolean triggerOnPush, boolean triggerOnMergeRequest, String triggerOpenMergeRequestOnPush, boolean ciSkip, boolean setBuildDescription, boolean addNoteOnMergeRequest, boolean addVoteOnMergeRequest, boolean acceptMergeRequestOnSuccess, boolean allowAllBranches, + public GitLabPushTrigger(boolean triggerOnPush, boolean triggerOnMergeRequest, String triggerOpenMergeRequestOnPush, boolean ciSkip, boolean setBuildDescription, boolean addNoteOnMergeRequest, boolean addCiMessage, boolean addVoteOnMergeRequest, boolean acceptMergeRequestOnSuccess, boolean allowAllBranches, String includeBranchesSpec, String excludeBranchesSpec) { this.triggerOnPush = triggerOnPush; this.triggerOnMergeRequest = triggerOnMergeRequest; this.triggerOpenMergeRequestOnPush = triggerOpenMergeRequestOnPush; this.ciSkip = ciSkip; this.setBuildDescription = setBuildDescription; - this.addNoteOnMergeRequest = addNoteOnMergeRequest; + this.addNoteOnMergeRequest = addNoteOnMergeRequest; + this.addCiMessage = addCiMessage; this.addVoteOnMergeRequest = addVoteOnMergeRequest; this.allowAllBranches = allowAllBranches; this.includeBranchesSpec = includeBranchesSpec; @@ -132,6 +133,10 @@ public boolean getAllowAllBranches() { return allowAllBranches; } + public boolean getAddCiMessage() { + return addCiMessage; + } + public boolean getCiSkip() { return ciSkip; } @@ -200,20 +205,18 @@ public void run() { } else { LOGGER.log(Level.INFO, "GitLab Push Request detected in {0}. Job is already in the queue.", job.getName()); } + + if(addCiMessage) { + req.createCommitStatus(getDescriptor().getGitlab().instance(), "pending", Jenkins.getInstance().getRootUrl() + job.getUrl()); + } } private GitLabPushCause createGitLabPushCause(GitLabPushRequest req) { GitLabPushCause cause; - String triggeredByUser; - if (req.getCommits().size() > 0){ - triggeredByUser = req.getCommits().get(0).getAuthor().getName(); - } else { - triggeredByUser = req.getUser_name(); - } try { - cause = new GitLabPushCause(triggeredByUser, getLogFile()); + cause = new GitLabPushCause(req, getLogFile()); } catch (IOException ex) { - cause = new GitLabPushCause(triggeredByUser); + cause = new GitLabPushCause(req); } return cause; } @@ -230,15 +233,25 @@ private Action[] createActions(GitLabPushRequest req) { values.put("gitlabTargetBranch", new StringParameterValue("gitlabTargetBranch", branch)); values.put("gitlabBranch", new StringParameterValue("gitlabBranch", branch)); - if (job instanceof AbstractProject){ - LOGGER.log(Level.INFO, "Trying to get name and URL for job: {0} using project {1} (push)", new String[]{job.getName(), ((AbstractProject) job).getRootProject().getName()}); - }else{ - LOGGER.log(Level.INFO, "Trying to get name and URL for job: {0} (push)", new String[]{job.getName()}); - } - values.put("gitlabSourceRepoName", new StringParameterValue("gitlabSourceRepoName", getDesc().getSourceRepoNameDefault(job))); - values.put("gitlabSourceRepoURL", new StringParameterValue("gitlabSourceRepoURL", getDesc().getSourceRepoURLDefault(job).toString())); values.put("gitlabActionType", new StringParameterValue("gitlabActionType", "PUSH")); + LOGGER.log(Level.INFO, "Trying to get name and URL for job: {0}", job.getName()); + String sourceRepoName = getDesc().getSourceRepoNameDefault(job); + String sourceRepoURL = getDesc().getSourceRepoURLDefault(job).toString(); + + 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(); + } catch (IOException ex) { + LOGGER.log(Level.WARNING, "Could not fetch source project''s data from Gitlab. '('{0}':' {1}')'", new String[]{ex.toString(), ex.getMessage()}); + } + } + + values.put("gitlabSourceRepoName", new StringParameterValue("gitlabSourceRepoName", sourceRepoName)); + values.put("gitlabSourceRepoURL", new StringParameterValue("gitlabSourceRepoURL", sourceRepoURL)); + List listValues = new ArrayList(values.values()); ParametersAction parametersAction = new ParametersAction(listValues); @@ -296,6 +309,10 @@ protected Job asJob() { } else { LOGGER.log(Level.INFO, "GitLab Merge Request detected in {0}. Job is already in the queue.", job.getName()); } + + if(addCiMessage) { + req.createCommitStatus(getDescriptor().getGitlab().instance(), "pending", Jenkins.getInstance().getRootUrl() + job.getUrl()); + } } private GitLabMergeCause createGitLabMergeCause(GitLabMergeRequest req) { @@ -379,14 +396,25 @@ private void setBuildCauseInJob(Run run){ } } - public void onCompleted(Run build){ - Cause mCause= build.getCause(GitLabMergeCause.class); + public void onCompleted(Run run){ + Cause mCause= run.getCause(GitLabMergeCause.class); if (mCause != null && mCause instanceof GitLabMergeCause) { - onCompleteMergeRequest(build,(GitLabMergeCause) mCause); + onCompleteMergeRequest(run, (GitLabMergeCause) mCause); + } + + Cause pCause= run.getCause(GitLabPushCause.class); + if (pCause != null && pCause instanceof GitLabPushCause) { + onCompletedPushRequest(run, (GitLabPushCause) pCause); } } + private void onCompletedPushRequest(Run run, GitLabPushCause cause) { + if(addCiMessage) { + cause.getPushRequest().createCommitStatus(this.getDescriptor().getGitlab().instance(), run.getResult()==Result.SUCCESS?"success":"failure", Jenkins.getInstance().getRootUrl() + run.getUrl()); + } + } + private void onCompleteMergeRequest(Run run,GitLabMergeCause cause){ if (acceptMergeRequestOnSuccess && run.getResult() == Result.SUCCESS) { try { @@ -423,10 +451,35 @@ private void onCompleteMergeRequest(Run run,GitLabMergeCause cause){ } } + if(addCiMessage) { + cause.getMergeRequest().createCommitStatus(this.getDescriptor().getGitlab().instance(), run.getResult()==Result.SUCCESS?"success":"failure", Jenkins.getInstance().getRootUrl() + run.getUrl()); + } } public void onStarted(Run run) { setBuildCauseInJob(run); + + Cause mCause= run.getCause(GitLabMergeCause.class); + if (mCause != null && mCause instanceof GitLabMergeCause) { + onStartedMergeRequest(run, (GitLabMergeCause) mCause); + } + + Cause pCause= run.getCause(GitLabPushCause.class); + if (pCause != null && pCause instanceof GitLabPushCause) { + onStartedPushRequest(run, (GitLabPushCause) pCause); + } + } + + private void onStartedPushRequest(Run run, GitLabPushCause cause) { + if(addCiMessage) { + cause.getPushRequest().createCommitStatus(this.getDescriptor().getGitlab().instance(), "running", Jenkins.getInstance().getRootUrl() + run.getUrl()); + } + } + + private void onStartedMergeRequest(Run run, GitLabMergeCause cause) { + if(addCiMessage) { + cause.getMergeRequest().createCommitStatus(this.getDescriptor().getGitlab().instance(), "running", Jenkins.getInstance().getRootUrl() + run.getUrl()); + } } private String getSourceBranch(GitLabRequest req) { diff --git a/src/main/java/com/dabsquared/gitlabjenkins/GitLabRequest.java b/src/main/java/com/dabsquared/gitlabjenkins/GitLabRequest.java index 19eb166b3..8621f33a6 100644 --- a/src/main/java/com/dabsquared/gitlabjenkins/GitLabRequest.java +++ b/src/main/java/com/dabsquared/gitlabjenkins/GitLabRequest.java @@ -14,8 +14,10 @@ import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; +import org.gitlab.api.GitlabAPI; +import org.gitlab.api.models.GitlabCommitStatus; -public class GitLabRequest { +public abstract class GitLabRequest { protected enum Builder { INSTANCE; private final Gson gson; @@ -51,4 +53,6 @@ public Date deserialize(JsonElement jsonElement, Type typeOF, } } + public abstract GitlabCommitStatus createCommitStatus(GitlabAPI api, String status, String targetUrl); + } diff --git a/src/main/resources/com/dabsquared/gitlabjenkins/GitLabPushTrigger/config.jelly b/src/main/resources/com/dabsquared/gitlabjenkins/GitLabPushTrigger/config.jelly index 3655f8f00..6ffef10d8 100644 --- a/src/main/resources/com/dabsquared/gitlabjenkins/GitLabPushTrigger/config.jelly +++ b/src/main/resources/com/dabsquared/gitlabjenkins/GitLabPushTrigger/config.jelly @@ -17,6 +17,9 @@ + + + diff --git a/src/main/webapp/help/help-gitlab8.1CI.html b/src/main/webapp/help/help-gitlab8.1CI.html new file mode 100644 index 000000000..c6d03717d --- /dev/null +++ b/src/main/webapp/help/help-gitlab8.1CI.html @@ -0,0 +1,3 @@ +
+ Enable GitLab 8.1 Continuous Integration feature. DO NOT ENABLE IF YOU'RE USING A VERSION BEFORE GITLAB 8.1. +
\ No newline at end of file