support /project/PROJECT_NAME?ref=BRANCH_NAME

fix #21 and #25
partial fix for #18
This commit is contained in:
Dimitris Stafylarakis 2014-11-30 15:33:17 +01:00
parent b00afa10ea
commit 6ad6804cb4
3 changed files with 77 additions and 30 deletions

View File

@ -9,13 +9,12 @@ This plugin emulates Jenkins as a GitlabCI Web Service to be used with GitlabHQ.
Current Supported GitLabCI Functions
=====================
* `/project/PROJECT_NAME/builds/COMMIT_SHA1/status.json`
* `/project/PROJECT_NAME/builds/status.png?ref=BRANCH_NAME`
* `/project/PROJECT_NAME/builds/status.png?sha1=COMMIT_SHA1`
* `/project/PROJECT_NAME/builds/COMMIT_SHA1` redirects to build page.
* `/project/PROJECT_NAME` In order for it to build properly on push you need to add this as a seperate web hook for just merge requests.
* `/project/PROJECT_NAME/builds/COMMIT_SHA1/status.json` (used for Merge Request pages) returns build result for Merge Request build with `COMMIT_SHA1` as last commit
* `/project/PROJECT_NAME/builds/status.png?ref=BRANCH_NAME` returns build status icon for latest build for `BRANCH_NAME`
* `/project/PROJECT_NAME/builds/status.png?sha1=COMMIT_SHA1` returns build status icon for latest build for `COMMIT_SHA1` as last commit
* `/project/PROJECT_NAME/builds/COMMIT_SHA1` redirects to build page of the last build containing `COMMIT_SHA1` as last commit
* `/project/PROJECT_NAME?ref=BRANCH_NAME` redirects to build page of the last build for `BRANCH_NAME`
* `/project/PROJECT_NAME` triggers a build, type (Merge Request or Push) depending on payload
Major Help Needed
=====================

View File

@ -114,7 +114,9 @@ public class GitLabPushTrigger extends Trigger<AbstractProject<?, ?>> {
values.put("gitlabSourceBranch", new StringParameterValue("gitlabSourceBranch", branch));
values.put("gitlabTargetBranch", new StringParameterValue("gitlabTargetBranch", branch));
values.put("gitlabBranch", new StringParameterValue("gitlabBranch", branch));
values.put("gitlabSourceRepoName", new StringParameterValue("gitlabSourceRepoName", getDesc().getSourceRepoNameDefault()));
values.put("gitlabSourceRepoURL", new StringParameterValue("gitlabSourceRepoURL", getDesc().getSourceRepoURLDefault().toString()));
List<ParameterValue> listValues = new ArrayList<ParameterValue>(values.values());
ParametersAction parametersAction = new ParametersAction(listValues);
@ -163,7 +165,7 @@ public class GitLabPushTrigger extends Trigger<AbstractProject<?, ?>> {
values.put("gitlabSourceBranch", new StringParameterValue("gitlabSourceBranch", getSourceBranch(req)));
values.put("gitlabTargetBranch", new StringParameterValue("gitlabTargetBranch", req.getObjectAttribute().getTargetBranch()));
String sourceRepoName = "origin";
String sourceRepoName = getDesc().getSourceRepoNameDefault();
String sourceRepoURL = getDesc().getSourceRepoURLDefault().toString();
if (!getDescriptor().getGitlabHostUrl().isEmpty()) {
@ -335,6 +337,27 @@ public class GitLabPushTrigger extends Trigger<AbstractProject<?, ?>> {
}
return url;
}
/**
* Get the Name of the first declared repository in the project configuration.
* Use this as default source repository Name.
*
* @return String with the default name of the source repository
*/
protected String getSourceRepoNameDefault() {
String result = null;
SCM scm = project.getScm();
if(!(scm instanceof GitSCM)) {
throw new IllegalArgumentException("This repo does not use git.");
}
if (scm instanceof GitSCM) {
List<RemoteConfig> repositories = ((GitSCM) scm).getRepositories();
if (!repositories.isEmpty()){
result = repositories.get(repositories.size()-1).getName();
}
}
return result;
}
public FormValidation doCheckGitlabHostUrl(@QueryParameter String value) {
if (value == null || value.isEmpty()) {

View File

@ -65,7 +65,7 @@ public class GitLabWebHook implements UnprotectedRootAction {
}
public void getDynamic(final String projectName, final StaplerRequest req, StaplerResponse res) {
LOGGER.log(Level.FINE, "WebHook called.");
LOGGER.log(Level.WARNING, "WebHook called.");
final Iterator<String> restOfPathParts = Splitter.on('/').omitEmptyStrings().split(req.getRestOfPath()).iterator();
final AbstractProject<?, ?>[] projectHolder = new AbstractProject<?, ?>[] { null };
ACL.impersonate(ACL.SYSTEM, new Runnable() {
@ -109,8 +109,15 @@ public class GitLabWebHook implements UnprotectedRootAction {
String theString = writer.toString();
if(paths.size() == 0) {
this.generateBuild(theString, project, req, res);
throw HttpResponses.ok();
if (req.getParameter("ref") != null){
// support /project/PROJECT_NAME?ref=BRANCH_NAME
// link on project activity page - build status
AbstractBuild build = this.getBuildByBranch(project, req.getParameter("ref"));
redirectToBuildPage(res, build);
} else {
this.generateBuild(theString, project, req, res);
}
throw HttpResponses.ok();
}
String lastPath = paths.get(paths.size()-1);
@ -134,23 +141,27 @@ public class GitLabWebHook implements UnprotectedRootAction {
}
} else if(firstPath.equals("builds") && !lastPath.equals("status.json")) {
AbstractBuild build = this.getBuildBySHA1(project, lastPath, true);
if(build != null) {
try {
res.sendRedirect2(Jenkins.getInstance().getRootUrl() + build.getUrl());
} catch (IOException e) {
try {
res.sendRedirect2(Jenkins.getInstance().getRootUrl() + build.getBuildStatusUrl());
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
redirectToBuildPage(res, build);
}
throw HttpResponses.ok();
}
private void redirectToBuildPage(StaplerResponse res, AbstractBuild build) {
if(build != null) {
try {
res.sendRedirect2(Jenkins.getInstance().getRootUrl() + build.getUrl());
} catch (IOException e) {
try {
res.sendRedirect2(Jenkins.getInstance().getRootUrl() + build.getBuildStatusUrl());
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
private void generateStatusJSON(String commitSHA1, AbstractProject project, StaplerRequest req, StaplerResponse rsp) {
SCM scm = project.getScm();
if(!(scm instanceof GitSCM)) {
@ -177,7 +188,7 @@ public class GitLabWebHook implements UnprotectedRootAction {
BallColor currentBallColor = mainBuild.getIconColor().noAnime();
//TODO: add staus of pending when we figure it out.
//TODO: add status of pending when we figure it out.
if(mainBuild.isBuilding()) {
object.put("status", "running");
}else if(currentBallColor == BallColor.BLUE) {
@ -351,22 +362,36 @@ public class GitLabWebHook implements UnprotectedRootAction {
* @param commitSHA1
* @return
*/
private AbstractBuild getBuildBySHA1(AbstractProject project, String commitSHA1, boolean isMergeRequest) {
private AbstractBuild getBuildBySHA1(AbstractProject project, String commitSHA1, boolean triggeredByMergeRequest) {
AbstractBuild mainBuild = null;
List<AbstractBuild> builds = project.getBuilds();
for(AbstractBuild build : builds) {
BuildData data = build.getAction(BuildData.class);
if (!isMergeRequest) {
//Determine if build was triggered by a Merge Request event
ParametersAction params = build.getAction(ParametersAction.class);
StringParameterValue sourceBranch = (StringParameterValue) params.getParameter("gitlabSourceBranch");
StringParameterValue targetBranch = (StringParameterValue) params.getParameter("gitlabTargetBranch");
boolean isMergeRequestBuild = !sourceBranch.value.equals(targetBranch.value);
if (!triggeredByMergeRequest) {
if (isMergeRequestBuild)
// skip Merge Request builds
continue;
if (data.getLastBuiltRevision().getSha1String().contains(commitSHA1)) {
mainBuild = build;
break;
}
} else {
if(data.hasBeenBuilt(ObjectId.fromString(commitSHA1))) {
mainBuild = build;
break;
if (!isMergeRequestBuild)
// skip Push builds
continue;
if (data.getLastBuiltRevision().getSha1String().contains(commitSHA1)) {
mainBuild = build;
break;
}
}
}