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 Current Supported GitLabCI Functions
===================== =====================
* `/project/PROJECT_NAME/builds/COMMIT_SHA1/status.json` * `/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` * `/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` * `/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. * `/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
* `/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.
Major Help Needed Major Help Needed
===================== =====================

View File

@ -114,7 +114,9 @@ public class GitLabPushTrigger extends Trigger<AbstractProject<?, ?>> {
values.put("gitlabSourceBranch", new StringParameterValue("gitlabSourceBranch", branch)); values.put("gitlabSourceBranch", new StringParameterValue("gitlabSourceBranch", branch));
values.put("gitlabTargetBranch", new StringParameterValue("gitlabTargetBranch", branch)); values.put("gitlabTargetBranch", new StringParameterValue("gitlabTargetBranch", branch));
values.put("gitlabBranch", new StringParameterValue("gitlabBranch", 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()); List<ParameterValue> listValues = new ArrayList<ParameterValue>(values.values());
ParametersAction parametersAction = new ParametersAction(listValues); 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("gitlabSourceBranch", new StringParameterValue("gitlabSourceBranch", getSourceBranch(req)));
values.put("gitlabTargetBranch", new StringParameterValue("gitlabTargetBranch", req.getObjectAttribute().getTargetBranch())); values.put("gitlabTargetBranch", new StringParameterValue("gitlabTargetBranch", req.getObjectAttribute().getTargetBranch()));
String sourceRepoName = "origin"; String sourceRepoName = getDesc().getSourceRepoNameDefault();
String sourceRepoURL = getDesc().getSourceRepoURLDefault().toString(); String sourceRepoURL = getDesc().getSourceRepoURLDefault().toString();
if (!getDescriptor().getGitlabHostUrl().isEmpty()) { if (!getDescriptor().getGitlabHostUrl().isEmpty()) {
@ -335,6 +337,27 @@ public class GitLabPushTrigger extends Trigger<AbstractProject<?, ?>> {
} }
return url; 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) { public FormValidation doCheckGitlabHostUrl(@QueryParameter String value) {
if (value == null || value.isEmpty()) { 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) { 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 Iterator<String> restOfPathParts = Splitter.on('/').omitEmptyStrings().split(req.getRestOfPath()).iterator();
final AbstractProject<?, ?>[] projectHolder = new AbstractProject<?, ?>[] { null }; final AbstractProject<?, ?>[] projectHolder = new AbstractProject<?, ?>[] { null };
ACL.impersonate(ACL.SYSTEM, new Runnable() { ACL.impersonate(ACL.SYSTEM, new Runnable() {
@ -109,8 +109,15 @@ public class GitLabWebHook implements UnprotectedRootAction {
String theString = writer.toString(); String theString = writer.toString();
if(paths.size() == 0) { if(paths.size() == 0) {
this.generateBuild(theString, project, req, res); if (req.getParameter("ref") != null){
throw HttpResponses.ok(); // 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); 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")) { } else if(firstPath.equals("builds") && !lastPath.equals("status.json")) {
AbstractBuild build = this.getBuildBySHA1(project, lastPath, true); AbstractBuild build = this.getBuildBySHA1(project, lastPath, true);
if(build != null) { redirectToBuildPage(res, build);
try {
res.sendRedirect2(Jenkins.getInstance().getRootUrl() + build.getUrl());
} catch (IOException e) {
try {
res.sendRedirect2(Jenkins.getInstance().getRootUrl() + build.getBuildStatusUrl());
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
} }
throw HttpResponses.ok(); 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) { private void generateStatusJSON(String commitSHA1, AbstractProject project, StaplerRequest req, StaplerResponse rsp) {
SCM scm = project.getScm(); SCM scm = project.getScm();
if(!(scm instanceof GitSCM)) { if(!(scm instanceof GitSCM)) {
@ -177,7 +188,7 @@ public class GitLabWebHook implements UnprotectedRootAction {
BallColor currentBallColor = mainBuild.getIconColor().noAnime(); 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()) { if(mainBuild.isBuilding()) {
object.put("status", "running"); object.put("status", "running");
}else if(currentBallColor == BallColor.BLUE) { }else if(currentBallColor == BallColor.BLUE) {
@ -351,22 +362,36 @@ public class GitLabWebHook implements UnprotectedRootAction {
* @param commitSHA1 * @param commitSHA1
* @return * @return
*/ */
private AbstractBuild getBuildBySHA1(AbstractProject project, String commitSHA1, boolean isMergeRequest) { private AbstractBuild getBuildBySHA1(AbstractProject project, String commitSHA1, boolean triggeredByMergeRequest) {
AbstractBuild mainBuild = null; AbstractBuild mainBuild = null;
List<AbstractBuild> builds = project.getBuilds(); List<AbstractBuild> builds = project.getBuilds();
for(AbstractBuild build : builds) { for(AbstractBuild build : builds) {
BuildData data = build.getAction(BuildData.class); 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)) { if (data.getLastBuiltRevision().getSha1String().contains(commitSHA1)) {
mainBuild = build; mainBuild = build;
break; break;
} }
} else { } else {
if(data.hasBeenBuilt(ObjectId.fromString(commitSHA1))) { if (!isMergeRequestBuild)
mainBuild = build; // skip Push builds
break; continue;
if (data.getLastBuiltRevision().getSha1String().contains(commitSHA1)) {
mainBuild = build;
break;
} }
} }
} }