From 9cf8a38e014f08604a9b7a120ae5bb7b48b81aa5 Mon Sep 17 00:00:00 2001 From: Jamie Tanna Date: Thu, 14 Apr 2022 08:09:48 +0100 Subject: [PATCH 1/3] Capitalise the `Folder` As it's a `Folder` object we're referencing, so this makes it a bit clearer. --- .../javaposse/jobdsl/plugin/JenkinsJobManagementSpec.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 705c5457f..77cd8fedb 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 @@ -641,7 +641,7 @@ class JenkinsJobManagementSpec extends Specification { e.message == 'Type of item "my-job" does not match existing type, item type can not be changed' } - def 'createOrUpdateConfig should preserve credentials if they exist on a folder'() { + def 'createOrUpdateConfig should preserve credentials if they exist on a Folder'() { setup: Folder folder = jenkinsRule.createProject(Folder, 'folder') folder.addProperty(createCredentialProperty()) @@ -654,7 +654,7 @@ class JenkinsJobManagementSpec extends Specification { actual.properties.size() == 1 } - def 'createOrUpdateConfig should ignore other properties on the folder'() { + def 'createOrUpdateConfig should ignore other properties on the Folder'() { setup: Folder folder = jenkinsRule.createProject(Folder, 'folder') folder.addProperty(new FakeProperty()) From 0390db7f9680c20efc66fcc1e8d98eec605fd3a3 Mon Sep 17 00:00:00 2001 From: Jamie Tanna Date: Thu, 14 Apr 2022 09:08:21 +0100 Subject: [PATCH 2/3] Fix: Don't destroy credentials when re-creating organization folders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to 8d8ea63fcefe0028c5168dffd9210955c41fe773, we should be able to support organization folders not losing their credentials. This requires we bump our dependency of `credentials` to pick up the `branch-api` dependency. We need to handle the various bits of metadata available in the `OrganizationFolder`s, so our tests are slightly more complex than we usually have. Co-authored-by: Jean-François Roche Closes JENKINS-44681. --- job-dsl-plugin/build.gradle | 3 +- .../jobdsl/plugin/JenkinsJobManagement.java | 19 +++++++--- .../plugin/JenkinsJobManagementSpec.groovy | 38 +++++++++++++++++++ .../src/test/resources/organizationfolder.xml | 9 +++++ 4 files changed, 63 insertions(+), 6 deletions(-) create mode 100644 job-dsl-plugin/src/test/resources/organizationfolder.xml 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 + + + + From 4b940e8d40361a7836e994e70ea8f8c6b9e62e21 Mon Sep 17 00:00:00 2001 From: Jamie Tanna Date: Fri, 1 Jul 2022 15:41:46 +0100 Subject: [PATCH 3/3] Add release notes for 1.80.0 --- docs/Home.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/Home.md b/docs/Home.md index 40f98947b..afc29860a 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -32,6 +32,8 @@ scripts, including [[tests for DSL scripts|Testing DSL Scripts]] and [[IDE Suppo Browse the Jenkins issue tracker to see any [open issues](https://issues.jenkins-ci.org/issues/?filter=15140). ## Release Notes +* 1.80.0 (July 1 2022) + * Don't destroy credentials when re-creating organization folders ([GH-1251](https://github.com/jenkinsci/job-dsl-plugin/pull/1251) [JENKINS-44681](https://issues.jenkins.io/browse/JENKINS-44681)) * 1.79.0 (April 14 2022) * Allow using classes not supported by `structs` for `DescribableContext` ([GH-1202](https://github.com/jenkinsci/job-dsl-plugin/pull/1202) [JENKINS-57435](https://issues.jenkins-ci.org/browse/JENKINS-57435)) ** Note that this has the potential to be unsafe and can lead to source-controlled secrets. Please be **very cautious** when embedding secrets into source control!