Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for the GitLab 8.1 commit API #127

Merged
merged 5 commits into from
Nov 11, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`` <br/>
**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`` <br/>
**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*
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
<dependency>
<groupId>org.gitlab</groupId>
<artifactId>java-gitlab-api</artifactId>
<version>1.1.9</version>
<version>1.1.11</version>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand Down Expand Up @@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the commit status api documentation for the optional ref it says

ref (optional) - The ref (branch or tag) to which the status refers

But here the commit id is assigned to it again.
Shouldn't it be objectAttributes.getSourceBranch()?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thommy101 can you comment on the above?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@EmteZogaf can you submit a PR for this so it doesn't get lost as just a comment on the source? Thanks!
EDIT: nevermind, you DID open one. Thanks :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@EmteZogaf @omehegan , I'm using the commit id as it's the closest I could find to match the default behavior of GitLab CI itself.
I haven't used the official CI myself (only using Java at the moment). I've looked at the blog post (https://about.gitlab.com/2015/09/22/gitlab-8-0-released/) and they are using the commit id.

}
} catch (IOException e) {
e.printStackTrace();
}

return null;
}

public static class ObjectAttributes {

private Integer id;
Expand Down
25 changes: 18 additions & 7 deletions src/main/java/com/dabsquared/gitlabjenkins/GitLabPushCause.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same as in GitlabMergeRequest.java: Why is this.checkout_sha passed as refparameter instead of this.ref?

}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

private String before;
private String after;
Expand Down
95 changes: 74 additions & 21 deletions src/main/java/com/dabsquared/gitlabjenkins/GitLabPushTrigger.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -82,21 +81,23 @@ public class GitLabPushTrigger extends Trigger<Job<?, ?>> {
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;
private final String excludeBranchesSpec;
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;
Expand Down Expand Up @@ -132,6 +133,10 @@ public boolean getAllowAllBranches() {
return allowAllBranches;
}

public boolean getAddCiMessage() {
return addCiMessage;
}

public boolean getCiSkip() {
return ciSkip;
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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<ParameterValue> listValues = new ArrayList<ParameterValue>(values.values());

ParametersAction parametersAction = new ParametersAction(listValues);
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to the commit status api documentation the status must be one of the following values:

state (required) - The state of the status. Can be: pending, running, success, failed, canceled

"failure" should be "failed"

}
}

private void onCompleteMergeRequest(Run run,GitLabMergeCause cause){
if (acceptMergeRequestOnSuccess && run.getResult() == Result.SUCCESS) {
try {
Expand Down Expand Up @@ -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());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment above.

"failure" should be "failed"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll make a pull request to fix this one ;)

--EDIT--
Created pull request #134

}
}

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) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -51,4 +53,6 @@ public Date deserialize(JsonElement jsonElement, Type typeOF,
}
}

public abstract GitlabCommitStatus createCommitStatus(GitlabAPI api, String status, String targetUrl);

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
</f:entry>
<f:entry title="Add note with build status on merge requests" field="addNoteOnMergeRequest">
<f:checkbox default="true" />
</f:entry>
<f:entry title="Use GitLab CI features (GitLab 8.1 required!)" field="addCiMessage" help="/plugin/gitlab-plugin/help/help-gitlab8.1CI.html">
<f:checkbox default="false"/>
</f:entry>
<f:entry title="Vote added to note with build status on merge requests" field="addVoteOnMergeRequest">
<f:checkbox default="true" />
Expand Down
3 changes: 3 additions & 0 deletions src/main/webapp/help/help-gitlab8.1CI.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<div>
Enable GitLab 8.1 Continuous Integration feature. <b>DO NOT ENABLE IF YOU'RE USING A VERSION BEFORE GITLAB 8.1</b>.
</div>