JENKINS-36278# Fixed Link generation of Multibranch project
Fixes: - Link generation of multi branch project nested inside a folder - BlueMultiBranchPipeline is a BluePipelineFolder now - branches are reachable via /pipelines/:id/branches/:id or /pipelines/:id/pipelines/:id. This makes it consistent with generic folder as multibranch project is really a folder.
This commit is contained in:
parent
5b7e4a4dc2
commit
317a9b1b35
|
@ -15,11 +15,12 @@ import java.util.List;
|
|||
*/
|
||||
public class BranchContainerImpl extends BluePipelineContainer {
|
||||
private final MultiBranchPipelineImpl pipeline;
|
||||
private final Link self;
|
||||
|
||||
public BranchContainerImpl(MultiBranchPipelineImpl pipeline) {
|
||||
public BranchContainerImpl(MultiBranchPipelineImpl pipeline, Link self) {
|
||||
this.pipeline = pipeline;
|
||||
this.self = self;
|
||||
}
|
||||
|
||||
//TODO: implement rest of the methods
|
||||
@Override
|
||||
public BluePipeline get(String name) {
|
||||
|
@ -42,6 +43,6 @@ public class BranchContainerImpl extends BluePipelineContainer {
|
|||
|
||||
@Override
|
||||
public Link getLink() {
|
||||
return pipeline.getLink().rel("branches");
|
||||
return self;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ public class BranchImpl extends PipelineImpl {
|
|||
private final Link parent;
|
||||
|
||||
public BranchImpl(Job job, Link parent) {
|
||||
super(job, parent);
|
||||
super(job);
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
|
|
|
@ -108,6 +108,21 @@ public class MultiBranchPipelineImpl extends BlueMultiBranchPipeline {
|
|||
return countRunStatus(Result.SUCCESS, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BluePipelineContainer getPipelines() {
|
||||
return new BranchContainerImpl(this, getLink().rel("pipelines"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getNumberOfFolders() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer getNumberOfPipelines() {
|
||||
return getTotalNumberOfBranches();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Integer getWeatherScore(){
|
||||
|
@ -168,7 +183,7 @@ public class MultiBranchPipelineImpl extends BlueMultiBranchPipeline {
|
|||
@Override
|
||||
@Navigable
|
||||
public BluePipelineContainer getBranches() {
|
||||
return new BranchContainerImpl(this);
|
||||
return new BranchContainerImpl(this, getLink().rel("branches"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
package io.jenkins.blueocean.service.embedded.rest;
|
||||
|
||||
import hudson.model.BuildableItem;
|
||||
import hudson.model.Item;
|
||||
import hudson.model.ItemGroup;
|
||||
import hudson.model.Job;
|
||||
import io.jenkins.blueocean.commons.ServiceException;
|
||||
import io.jenkins.blueocean.rest.Reachable;
|
||||
import io.jenkins.blueocean.rest.hal.Link;
|
||||
import io.jenkins.blueocean.rest.model.BluePipeline;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineContainer;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineFactory;
|
||||
import jenkins.branch.MultiBranchProject;
|
||||
import jenkins.model.Jenkins;
|
||||
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.ArrayList;
|
||||
|
@ -24,18 +21,27 @@ import java.util.List;
|
|||
*/
|
||||
public class PipelineContainerImpl extends BluePipelineContainer {
|
||||
private final @Nonnull ItemGroup itemGroup;
|
||||
private final Link self;
|
||||
|
||||
public PipelineContainerImpl() {
|
||||
this.itemGroup = Jenkins.getInstance();
|
||||
this(Jenkins.getInstance(),null);
|
||||
}
|
||||
|
||||
public PipelineContainerImpl(ItemGroup itemGroup) {
|
||||
this.itemGroup = itemGroup;
|
||||
this(itemGroup,null);
|
||||
}
|
||||
|
||||
public PipelineContainerImpl(ItemGroup itemGroup, Reachable parent) {
|
||||
this.itemGroup = itemGroup;
|
||||
if(parent!=null){
|
||||
this.self = parent.getLink().rel("pipelines");
|
||||
}else{
|
||||
this.self = OrganizationImpl.INSTANCE.getLink().rel("pipelines");
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Link getLink() {
|
||||
return OrganizationImpl.INSTANCE.getLink().rel("pipelines");
|
||||
return self;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -49,39 +55,31 @@ public class PipelineContainerImpl extends BluePipelineContainer {
|
|||
return get(item);
|
||||
}
|
||||
|
||||
public BluePipeline get(Item item){
|
||||
for(BluePipelineFactory factory:BluePipelineFactory.all()){
|
||||
BluePipeline pipeline = factory.getPipeline(item, this);
|
||||
if( pipeline!= null){
|
||||
return pipeline;
|
||||
}
|
||||
}
|
||||
// TODO: I'm going to turn this into a decorator annotation
|
||||
throw new ServiceException.NotFoundException(String.format("Pipeline %s not found", item.getName()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterator<BluePipeline> iterator() {
|
||||
return getPipelines(itemGroup.getItems());
|
||||
}
|
||||
|
||||
protected static boolean isMultiBranchProjectJob(BuildableItem item){
|
||||
return item instanceof WorkflowJob && item.getParent() instanceof MultiBranchProject;
|
||||
}
|
||||
|
||||
protected Iterator<BluePipeline> getPipelines(Collection<? extends Item> items){
|
||||
List<BluePipeline> pipelines = new ArrayList<>();
|
||||
for (Item item : items) {
|
||||
if(item instanceof MultiBranchProject){
|
||||
pipelines.add(new MultiBranchPipelineImpl((MultiBranchProject) item, getLink()));
|
||||
}else if(item instanceof BuildableItem && !isMultiBranchProjectJob((BuildableItem) item)
|
||||
&& item instanceof Job){
|
||||
pipelines.add(new PipelineImpl((Job) item, getLink()));
|
||||
}else if(item instanceof ItemGroup){
|
||||
pipelines.add(new PipelineFolderImpl((ItemGroup) item, getLink()));
|
||||
BluePipeline pipeline = get(item);
|
||||
if(pipeline != null){
|
||||
pipelines.add(pipeline);
|
||||
}
|
||||
}
|
||||
return pipelines.iterator();
|
||||
}
|
||||
|
||||
private BluePipeline get(Item item){
|
||||
|
||||
for(BluePipelineFactory factory:BluePipelineFactory.all()){
|
||||
BluePipeline pipeline = factory.getPipeline(item, this);
|
||||
if( pipeline!= null){
|
||||
return pipeline;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ public class PipelineFolderImpl extends BluePipelineFolder {
|
|||
|
||||
@Override
|
||||
public BluePipelineContainer getPipelines() {
|
||||
return new PipelineContainerImpl(folder);
|
||||
return new PipelineContainerImpl(folder, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -2,9 +2,7 @@ package io.jenkins.blueocean.service.embedded.rest;
|
|||
|
||||
import hudson.Extension;
|
||||
import hudson.model.Action;
|
||||
import hudson.model.BuildableItem;
|
||||
import hudson.model.Item;
|
||||
import hudson.model.ItemGroup;
|
||||
import hudson.model.Job;
|
||||
import io.jenkins.blueocean.commons.ServiceException;
|
||||
import io.jenkins.blueocean.rest.Navigable;
|
||||
|
@ -17,7 +15,6 @@ import io.jenkins.blueocean.rest.model.BlueQueueContainer;
|
|||
import io.jenkins.blueocean.rest.model.BlueRun;
|
||||
import io.jenkins.blueocean.rest.model.BlueRunContainer;
|
||||
import io.jenkins.blueocean.service.embedded.util.FavoriteUtil;
|
||||
import jenkins.branch.MultiBranchProject;
|
||||
import org.kohsuke.stapler.Stapler;
|
||||
import org.kohsuke.stapler.WebMethod;
|
||||
import org.kohsuke.stapler.export.ExportedBean;
|
||||
|
@ -29,8 +26,6 @@ import java.util.ArrayList;
|
|||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import static io.jenkins.blueocean.service.embedded.rest.PipelineContainerImpl.isMultiBranchProjectJob;
|
||||
|
||||
/**
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
|
@ -38,23 +33,10 @@ import static io.jenkins.blueocean.service.embedded.rest.PipelineContainerImpl.i
|
|||
public class PipelineImpl extends BluePipeline {
|
||||
/*package*/ final Job job;
|
||||
|
||||
private final ItemGroup folder;
|
||||
|
||||
private final Link parent;
|
||||
|
||||
protected PipelineImpl(ItemGroup folder, Job job, Link parent) {
|
||||
protected PipelineImpl(Job job) {
|
||||
this.job = job;
|
||||
this.folder = folder;
|
||||
this.parent = null;
|
||||
}
|
||||
|
||||
public PipelineImpl(ItemGroup folder, Link parent) {
|
||||
this(folder, null,parent);
|
||||
}
|
||||
|
||||
public PipelineImpl(Job job, Link parent) {
|
||||
this(null, job, parent);
|
||||
}
|
||||
@Override
|
||||
public String getOrganization() {
|
||||
return OrganizationImpl.INSTANCE.getName();
|
||||
|
@ -134,25 +116,6 @@ public class PipelineImpl extends BluePipeline {
|
|||
return job.getFullName();
|
||||
}
|
||||
|
||||
public BluePipeline getPipelines(String name){
|
||||
assert folder != null;
|
||||
return getPipeline(folder, name);
|
||||
}
|
||||
|
||||
private BluePipeline getPipeline(ItemGroup itemGroup, String name){
|
||||
Item item = itemGroup.getItem(name);
|
||||
if(item instanceof BuildableItem){
|
||||
if(item instanceof MultiBranchProject){
|
||||
return new MultiBranchPipelineImpl((MultiBranchProject) item, getLink());
|
||||
}else if(!isMultiBranchProjectJob((BuildableItem) item) && item instanceof Job){
|
||||
return new PipelineImpl(itemGroup, (Job) item, parent);
|
||||
}
|
||||
}else if(item instanceof ItemGroup){
|
||||
return new PipelineImpl((ItemGroup) item, null);
|
||||
}
|
||||
throw new ServiceException.NotFoundException(String.format("Pipeline %s not found", name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Link getLink() {
|
||||
return OrganizationImpl.INSTANCE.getLink().rel("pipelines").rel(getRecursivePathFromFullName(this));
|
||||
|
@ -183,7 +146,7 @@ public class PipelineImpl extends BluePipeline {
|
|||
@Override
|
||||
public BluePipeline getPipeline(Item item, Reachable parent) {
|
||||
if (item instanceof Job) {
|
||||
return new PipelineImpl((Job) item, parent.getLink());
|
||||
return new PipelineImpl((Job) item);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.junit.ClassRule;
|
|||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.jvnet.hudson.test.BuildWatcher;
|
||||
import org.jvnet.hudson.test.MockFolder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
@ -75,6 +76,26 @@ public class MultiBranchTest extends BaseTest{
|
|||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void getMultiBranchPipelineInsideFolder() throws IOException, ExecutionException, InterruptedException {
|
||||
MockFolder folder1 = j.createFolder("folder1");
|
||||
WorkflowMultiBranchProject mp = folder1.createProject(WorkflowMultiBranchProject.class, "p");
|
||||
|
||||
mp.getSourcesList().add(new BranchSource(new GitSCMSource(null, sampleRepo.toString(), "", "*", "", false),
|
||||
new DefaultBranchPropertyStrategy(new BranchProperty[0])));
|
||||
for (SCMSource source : mp.getSCMSources()) {
|
||||
assertEquals(mp, source.getOwner());
|
||||
}
|
||||
|
||||
mp.scheduleBuild2(0).getFuture().get();
|
||||
|
||||
Map r = get("/organizations/jenkins/pipelines/folder1/pipelines/p/");
|
||||
|
||||
validateMultiBranchPipeline(mp, r, 3);
|
||||
Assert.assertEquals("/blue/rest/organizations/jenkins/pipelines/folder1/pipelines/p/",
|
||||
((Map)((Map)r.get("_links")).get("self")).get("href"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getBranchWithEncodedPath() throws IOException, ExecutionException, InterruptedException {
|
||||
WorkflowMultiBranchProject mp = j.jenkins.createProject(WorkflowMultiBranchProject.class, "p");
|
||||
|
|
|
@ -12,7 +12,6 @@ import hudson.model.CauseAction;
|
|||
import hudson.model.FreeStyleBuild;
|
||||
import hudson.model.FreeStyleProject;
|
||||
import hudson.model.Item;
|
||||
import hudson.model.ItemGroup;
|
||||
import hudson.model.Job;
|
||||
import hudson.model.ParametersAction;
|
||||
import hudson.model.ParametersDefinitionProperty;
|
||||
|
@ -26,7 +25,6 @@ import hudson.tasks.Shell;
|
|||
import hudson.tasks.junit.JUnitResultArchiver;
|
||||
import hudson.tasks.junit.TestResultAction;
|
||||
import io.jenkins.blueocean.rest.Reachable;
|
||||
import io.jenkins.blueocean.rest.hal.Link;
|
||||
import io.jenkins.blueocean.rest.model.BluePipeline;
|
||||
import io.jenkins.blueocean.rest.model.BluePipelineFactory;
|
||||
import io.jenkins.blueocean.service.embedded.rest.PipelineImpl;
|
||||
|
@ -560,7 +558,7 @@ public class PipelineApiTest extends BaseTest {
|
|||
@Override
|
||||
public BluePipeline getPipeline(Item item, Reachable parent) {
|
||||
if(item instanceof Job){
|
||||
return new TestPipelineImpl(null, (Job)item, parent.getLink());
|
||||
return new TestPipelineImpl((Job)item);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
@ -568,8 +566,8 @@ public class PipelineApiTest extends BaseTest {
|
|||
|
||||
public static class TestPipelineImpl extends PipelineImpl {
|
||||
|
||||
public TestPipelineImpl(ItemGroup folder, Job job, Link parent) {
|
||||
super(folder, job, parent);
|
||||
public TestPipelineImpl(Job job) {
|
||||
super(job);
|
||||
}
|
||||
|
||||
@Exported(name = "hello")
|
||||
|
|
|
@ -13,7 +13,7 @@ import java.util.Iterator;
|
|||
*
|
||||
* @author Vivek Pandey
|
||||
*/
|
||||
public abstract class BlueMultiBranchPipeline extends BluePipeline{
|
||||
public abstract class BlueMultiBranchPipeline extends BluePipelineFolder{
|
||||
public static final String TOTAL_NUMBER_OF_BRANCHES="totalNumberOfBranches";
|
||||
public static final String NUMBER_OF_FAILING_BRANCHES="numberOfFailingBranches";
|
||||
public static final String NUMBER_OF_SUCCESSFULT_BRANCHES="numberOfSuccessfulBranches";
|
||||
|
|
Loading…
Reference in New Issue