From 46b32a36ab600a1aad783f758ad5465f3435bc29 Mon Sep 17 00:00:00 2001 From: Nicolas De Loof Date: Tue, 19 Dec 2017 17:14:52 +0100 Subject: [PATCH] configure global libraries --- README.md | 2 + demos/workflow-cps-global-lib/README.md | 16 ++++++++ pom.xml | 7 ++++ .../plugins/casc/BaseConfigurator.java | 4 +- .../jenkinsci/plugins/casc/Configurator.java | 2 +- .../plugins/casc/DataBoundConfigurator.java | 1 + .../plugins/casc/JenkinsConfigurator.java | 4 ++ .../plugins/casc/GlobalLibrariesTest.java | 40 +++++++++++++++++++ .../plugins/casc/GlobalLibrariesTest.yml | 8 ++++ 9 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 demos/workflow-cps-global-lib/README.md create mode 100644 src/test/java/org/jenkinsci/plugins/casc/GlobalLibrariesTest.java create mode 100644 src/test/resources/org/jenkinsci/plugins/casc/GlobalLibrariesTest.yml diff --git a/README.md b/README.md index a0b7b5b7..f394a077 100644 --- a/README.md +++ b/README.md @@ -11,8 +11,10 @@ Here is a list of plugin we have successfuly tested to support configuration-as- - [x] active directory plugin ([details](demos/credentials/README.md)) - [x] artifactory plugin ([details](demos/artifactory/README.md)) - [x] credentials plugin ([details](demos/credentials/README.md)) + - [x] docker plugin ([details](demos/docker/README.md)) - [x] git plugin ([details](demos/git/README.md)) - [x] ldap plugin ([details](demos/ldap/README.md)) - [x] mailer plugin with some limitations ([details](demos/mailer/README.md)) - [x] tfs plugin with some limitations ([details](demos/tfs/README.md)) + - [x] workflow-cps-global-lib _aka_ "global libraries" ([details](demos/workflow-cps-global-lib/README.md)) - [ ] more to come soon... diff --git a/demos/workflow-cps-global-lib/README.md b/demos/workflow-cps-global-lib/README.md new file mode 100644 index 00000000..2849eeda --- /dev/null +++ b/demos/workflow-cps-global-lib/README.md @@ -0,0 +1,16 @@ +# configure global libraries plugin + +## sample configuration + +```yaml +globalLibraries: + libraries: + - name: "awesome-lib" + retriever: + modernSCM: + scm: + git: + remote: "https://github.com/jenkins-infra/pipeline-library.git" +``` + + diff --git a/pom.xml b/pom.xml index c4564ff1..9c77fb1c 100644 --- a/pom.xml +++ b/pom.xml @@ -130,6 +130,13 @@ 2.0.16 test + + + org.jenkins-ci.plugins.workflow + workflow-cps-global-lib + 2.9 + test + diff --git a/src/main/java/org/jenkinsci/plugins/casc/BaseConfigurator.java b/src/main/java/org/jenkinsci/plugins/casc/BaseConfigurator.java index 5fdd3b93..dc5e09e5 100644 --- a/src/main/java/org/jenkinsci/plugins/casc/BaseConfigurator.java +++ b/src/main/java/org/jenkinsci/plugins/casc/BaseConfigurator.java @@ -45,6 +45,7 @@ public abstract class BaseConfigurator extends Configurator { // FIXME move this all into cleaner logic to discover property type Type type = setter.getGenericParameterTypes()[0]; Attribute attribute = detectActualType(name, type); + if (attribute == null) continue; attributes.add(attribute); @@ -136,7 +137,8 @@ public abstract class BaseConfigurator extends Configurator { Attribute attribute; if (!c.isPrimitive() && !c.isEnum() && Modifier.isAbstract(c.getModifiers())) { if (!Describable.class.isAssignableFrom(c)) { - throw new IllegalStateException("Configuration-as-Code can't manage abstract attributes which are not Describable."); + // Not a Describable, so probably not an attribute expected to be selected as sub-component + return null; } attribute = new DescribableAttribute(name, c); } else { diff --git a/src/main/java/org/jenkinsci/plugins/casc/Configurator.java b/src/main/java/org/jenkinsci/plugins/casc/Configurator.java index 7a612649..f97ec1ce 100644 --- a/src/main/java/org/jenkinsci/plugins/casc/Configurator.java +++ b/src/main/java/org/jenkinsci/plugins/casc/Configurator.java @@ -38,7 +38,7 @@ public abstract class Configurator implements ExtensionPoint { public static Configurator lookupRootElement(String name) { for (RootElementConfigurator c : RootElementConfigurator.all()) { - if (c.getName().equals(name)) { + if (c.getName().equalsIgnoreCase(name)) { return (Configurator) c; } } diff --git a/src/main/java/org/jenkinsci/plugins/casc/DataBoundConfigurator.java b/src/main/java/org/jenkinsci/plugins/casc/DataBoundConfigurator.java index ae97e41b..47fa4acd 100644 --- a/src/main/java/org/jenkinsci/plugins/casc/DataBoundConfigurator.java +++ b/src/main/java/org/jenkinsci/plugins/casc/DataBoundConfigurator.java @@ -141,6 +141,7 @@ public class DataBoundConfigurator extends BaseConfigurator { final Parameter p = parameters[i]; final Attribute a = detectActualType(names[i], p.getParameterizedType()); + if (a == null) continue; attributes.add(a); } } diff --git a/src/main/java/org/jenkinsci/plugins/casc/JenkinsConfigurator.java b/src/main/java/org/jenkinsci/plugins/casc/JenkinsConfigurator.java index 7f0473df..4a4b8112 100644 --- a/src/main/java/org/jenkinsci/plugins/casc/JenkinsConfigurator.java +++ b/src/main/java/org/jenkinsci/plugins/casc/JenkinsConfigurator.java @@ -53,14 +53,18 @@ public class JenkinsConfigurator extends BaseConfigurator implements Ro @Override public void setValue(Jenkins jenkins, Object value) throws Exception { List jobs = (List) value; + // FIXME not pleasant we have to re-implement jenkins.createProject logic here for (TopLevelItem item : jobs) { final String name = item.getName(); if (jenkins.getItem(name) == null) { + item.onCreatedFromScratch(); + item.save(); jenkins.add(item, name); } else { // FIXME re-configure ? remove/replace ? } } + Jenkins.getInstance().rebuildDependencyGraphAsync(); } }.multiple(true)); diff --git a/src/test/java/org/jenkinsci/plugins/casc/GlobalLibrariesTest.java b/src/test/java/org/jenkinsci/plugins/casc/GlobalLibrariesTest.java new file mode 100644 index 00000000..361471e0 --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/casc/GlobalLibrariesTest.java @@ -0,0 +1,40 @@ +package org.jenkinsci.plugins.casc; + +import com.nirima.jenkins.plugins.docker.DockerCloud; +import com.nirima.jenkins.plugins.docker.DockerTemplate; +import io.jenkins.docker.connector.DockerComputerAttachConnector; +import jenkins.plugins.git.GitSCMSource; +import jenkins.scm.api.SCMSource; +import org.jenkinsci.plugins.workflow.libs.GlobalLibraries; +import org.jenkinsci.plugins.workflow.libs.LibraryConfiguration; +import org.jenkinsci.plugins.workflow.libs.LibraryRetriever; +import org.jenkinsci.plugins.workflow.libs.SCMSourceRetriever; +import org.junit.Rule; +import org.junit.Test; +import org.jvnet.hudson.test.JenkinsRule; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +/** + * @author Nicolas De Loof + */ +public class GlobalLibrariesTest { + + + @Rule + public JenkinsRule j = new JenkinsRule(); + + @Test + public void configure_global_library() throws Exception { + ConfigurationAsCode.configure(getClass().getResourceAsStream("GlobalLibrariesTest.yml")); + + assertEquals(1, GlobalLibraries.get().getLibraries().size()); + final LibraryConfiguration library = GlobalLibraries.get().getLibraries().get(0); + assertEquals("awesome-lib", library.getName()); + final SCMSourceRetriever retriever = (SCMSourceRetriever) library.getRetriever(); + final GitSCMSource scm = (GitSCMSource) retriever.getScm(); + assertEquals("https://github.com/jenkins-infra/pipeline-library.git", scm.getRemote()); + + } +} diff --git a/src/test/resources/org/jenkinsci/plugins/casc/GlobalLibrariesTest.yml b/src/test/resources/org/jenkinsci/plugins/casc/GlobalLibrariesTest.yml new file mode 100644 index 00000000..c3e027b3 --- /dev/null +++ b/src/test/resources/org/jenkinsci/plugins/casc/GlobalLibrariesTest.yml @@ -0,0 +1,8 @@ +globalLibraries: + libraries: + - name: "awesome-lib" + retriever: + modernSCM: + scm: + git: + remote: "https://github.com/jenkins-infra/pipeline-library.git" \ No newline at end of file