diff --git a/job-dsl-plugin/build.gradle b/job-dsl-plugin/build.gradle index 492fe9cd6..1da18c142 100644 --- a/job-dsl-plugin/build.gradle +++ b/job-dsl-plugin/build.gradle @@ -109,6 +109,7 @@ dependencies { compile(project(':job-dsl-core')) { exclude group: 'org.jvnet.hudson', module:'xstream' } + implementation 'org.jenkins-ci.plugins:branch-api:2.4.0' implementation 'org.jenkins-ci.plugins:cloudbees-folder:5.14' implementation 'org.jenkins-ci.plugins:structs:1.19' implementation 'org.jenkins-ci.plugins:script-security:1.54' @@ -123,5 +124,5 @@ dependencies { testImplementation 'io.jenkins:configuration-as-code:1.15:tests' testImplementation 'org.jenkins-ci.plugins:matrix-auth:1.3' testImplementation 'org.jenkins-ci.plugins:nested-view:1.14' - testImplementation 'org.jenkins-ci.plugins:credentials:2.1.10' + testImplementation 'org.jenkins-ci.plugins:credentials:2.1.11' } diff --git a/job-dsl-plugin/src/main/groovy/javaposse/jobdsl/plugin/JenkinsJobManagement.java b/job-dsl-plugin/src/main/groovy/javaposse/jobdsl/plugin/JenkinsJobManagement.java index e2eeeb716..e595b5767 100644 --- a/job-dsl-plugin/src/main/groovy/javaposse/jobdsl/plugin/JenkinsJobManagement.java +++ b/job-dsl-plugin/src/main/groovy/javaposse/jobdsl/plugin/JenkinsJobManagement.java @@ -39,6 +39,7 @@ import javaposse.jobdsl.dsl.NameNotProvidedException; import javaposse.jobdsl.dsl.UserContent; import javaposse.jobdsl.plugin.ExtensionPointHelper.DslExtension; +import jenkins.branch.OrganizationFolder; import jenkins.model.DirectlyModifiableTopLevelItemGroup; import jenkins.model.Jenkins; import jenkins.model.ModifiableTopLevelItemGroup; @@ -587,17 +588,25 @@ private void renameJob(Job from, String to) throws IOException { } private void mergeCredentials(AbstractItem item, javaposse.jobdsl.dsl.Item dslItem) { + Optional> maybeProperty = Optional.empty(); if (item instanceof Folder) { Folder folder = (Folder) item; - Optional> maybeProperty = + maybeProperty = folder.getProperties().stream() .filter(p -> p instanceof FolderCredentialsProperty) .findFirst(); - if (maybeProperty.isPresent()) { - LOGGER.log(Level.FINE, format("Merging credentials for %s", item.getName())); - DslItemConfigurer.mergeCredentials(maybeProperty.get(), dslItem); - } + } + if (item instanceof OrganizationFolder) { + OrganizationFolder folder = (OrganizationFolder) item; + maybeProperty = + folder.getProperties().stream() + .filter(p -> p instanceof FolderCredentialsProperty) + .findFirst(); + } + if (maybeProperty.isPresent()) { + LOGGER.log(Level.FINE, format("Merging credentials for %s", item.getName())); + DslItemConfigurer.mergeCredentials(maybeProperty.get(), dslItem); } } diff --git a/job-dsl-plugin/src/test/groovy/javaposse/jobdsl/plugin/JenkinsJobManagementSpec.groovy b/job-dsl-plugin/src/test/groovy/javaposse/jobdsl/plugin/JenkinsJobManagementSpec.groovy index 77cd8fedb..3d77fd634 100644 --- a/job-dsl-plugin/src/test/groovy/javaposse/jobdsl/plugin/JenkinsJobManagementSpec.groovy +++ b/job-dsl-plugin/src/test/groovy/javaposse/jobdsl/plugin/JenkinsJobManagementSpec.groovy @@ -1,5 +1,6 @@ package javaposse.jobdsl.plugin +import jenkins.branch.OrganizationFolder import com.cloudbees.hudson.plugins.folder.AbstractFolder import com.cloudbees.hudson.plugins.folder.AbstractFolderProperty import com.cloudbees.hudson.plugins.folder.AbstractFolderPropertyDescriptor @@ -667,6 +668,43 @@ class JenkinsJobManagementSpec extends Specification { actual.properties.size() == 0 } + def 'createOrUpdateConfig should preserve credentials if they exist on an OrganizationFolder'() { + setup: + OrganizationFolder folder = jenkinsRule.createProject(OrganizationFolder, 'org') + // `OrganizationFolder`s include a lot of existing metadata that is appended, regardless of how few we already + // set, so we should calculate expected as the default computed properties + int defaultProperties = folder.properties.size() + + def property = createCredentialProperty() + folder.addProperty(property) + + when: + jobManagement.createOrUpdateConfig(createItem('org', '/organizationfolder.xml'), false) + + then: + def actualItem = jenkinsRule.jenkins.getItem('org') + def actual = (AbstractFolder) actualItem + actual.properties.size() == defaultProperties + 1 + } + + def 'createOrUpdateConfig should ignore other properties on the OrganizationFolder'() { + setup: + OrganizationFolder folder = jenkinsRule.createProject(OrganizationFolder, 'org') + // `OrganizationFolder`s include a lot of existing metadata that is appended, regardless of how few we already + // set, so we should calculate expected as the default computed properties + int defaultProperties = folder.properties.size() + + folder.addProperty(new FakeProperty()) + + when: + jobManagement.createOrUpdateConfig(createItem('org', '/organizationfolder.xml'), false) + folder.writeConfigDotXml(System.out) + + then: + def actual = jenkinsRule.jenkins.getItem('org') + actual.properties.size() == defaultProperties + } + def 'createOrUpdateView should work if view type changes'() { setup: jenkinsRule.jenkins.addView(new AllView('foo')) diff --git a/job-dsl-plugin/src/test/resources/organizationfolder.xml b/job-dsl-plugin/src/test/resources/organizationfolder.xml new file mode 100644 index 000000000..8105f9dcb --- /dev/null +++ b/job-dsl-plugin/src/test/resources/organizationfolder.xml @@ -0,0 +1,9 @@ + + + + + false + + + +