Compare commits

...

33 Commits

Author SHA1 Message Date
Stefan Spieker 9ea946218b
Added demo for thinBackup (#2722) 2025-10-06 21:37:39 +00:00
renovate[bot] 4cb0061076
Update dependency org.jenkins-ci.plugins:plugin to v5.26 (#2719)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-06 02:02:25 +00:00
Tim Jacomb 3e50e6e9d9
Modernise UI (#2717) 2025-10-02 15:34:19 +00:00
renovate[bot] 9d0cb94803
Update dependency org.jenkins-ci.plugins:jira to v3.19 (#2714)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-29 01:31:02 +00:00
renovate[bot] 79e7ab3f2b
Update dependency com.puppycrawl.tools:checkstyle to v11.1.0 (#2713)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-29 01:26:09 +00:00
Jesse Glick 540b50aeb0
Produce an empty map if so directed (#2712) 2025-09-24 21:50:17 +01:00
renovate[bot] c7ecb73353
Update dependency io.jenkins.tools.incrementals:git-changelist-maven-extension to v1.13 (#2711)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 02:52:37 +00:00
renovate[bot] cfc7ccf56a
Update dependency com.puppycrawl.tools:checkstyle to v11.0.1 (#2710)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 02:49:36 +00:00
renovate[bot] 78fa992790
Update plugin-bom.version to v5294 (#2709)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-25 02:00:08 +00:00
renovate[bot] f52729ed71
Update dependency org.jenkins-ci.plugins:plugin to v5.24 (#2708)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-25 01:59:35 +00:00
renovate[bot] 4a0374188a
Update plugin-bom.version to v5252 (#2706)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-18 01:42:09 +00:00
renovate[bot] 7e9161ca55
Update dependency org.jenkins-ci.plugins:plugin to v5.22 (#2705)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-18 01:41:39 +00:00
renovate[bot] bc02e8d8da
Update dependency com.puppycrawl.tools:checkstyle to v11 (#2703)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-11 01:39:56 +00:00
renovate[bot] 92b9b6ae08
Update dependency org.jenkins-ci.plugins:plugin to v5.19 (#2702)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-11 01:39:07 +00:00
renovate[bot] 9848733a3e
Update dependency io.jenkins.tools.bom:bom-2.504.x to v5208 (#2699)
* Update dependency io.jenkins.tools.bom:bom-2.504.x to v5208

* Update pom.xml

* Update pom.xml

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Tim Jacomb <21194782+timja@users.noreply.github.com>
2025-08-08 22:36:05 +00:00
Basil Crow dda32d0c4e
Upgrade Commons Lang from 2 to 3 (#2700) 2025-07-30 07:17:33 +01:00
renovate[bot] e5bec4ed25
Update dependency org.jenkins-ci.main:jenkins-war to v2.516.1 (#2698)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-28 04:50:13 +00:00
renovate[bot] 17b4e31d83
Update plugin-bom.version to v5054 (#2697)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-21 02:32:32 +00:00
renovate[bot] bd01acb73b
Update dependency io.vavr:vavr to v0.10.7 (#2696)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-21 02:29:39 +00:00
renovate[bot] 369e37f0c7
Update plugin-bom.version to v5043 (#2695)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-14 01:37:12 +00:00
renovate[bot] 866bc39acd
Update dependency org.jenkins-ci.plugins:plugin to v5.18 (#2694)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-14 01:35:53 +00:00
renovate[bot] ac0078beb8
Update dependency io.jenkins.tools.incrementals:git-changelist-maven-extension to v1.10 (#2692)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-07 02:37:18 +00:00
renovate[bot] e3f7834ad1
Update dependency org.jenkins-ci.plugins:jira to v3.18 (#2693)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-07-07 02:34:58 +00:00
renovate[bot] b0372008f1
Update dependency com.puppycrawl.tools:checkstyle to v10.26.1 (#2691)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 01:18:18 +00:00
renovate[bot] 54ca3ed186
Update dependency org.jenkins-ci.main:jenkins-war to v2.504.3 (#2690)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-30 01:15:03 +00:00
renovate[bot] afe745b57c
Update dependency com.puppycrawl.tools:checkstyle to v10.25.1 (#2687)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-23 02:45:44 +00:00
renovate[bot] c7949ea687
Update dependency org.jenkins-ci.plugins:jira to v3.17 (#2688)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-23 02:44:13 +00:00
renovate[bot] ab8a572674
Update dependency com.puppycrawl.tools:checkstyle to v10.25.0 (#2686)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-09 02:32:16 +00:00
renovate[bot] f7ffe5922a
Update dependency org.jenkins-ci.main:jenkins-war to v2.504.2 (#2685)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-06-09 02:32:08 +00:00
Vincent Latombe f9280461ea
Remove dependency on org.jetbrains:annotations through test-harness (#2683)
It has been removed from the Jenkins plugins parent pom a while ago, and
shouldn't be transitive.
2025-05-27 07:47:38 +01:00
renovate[bot] 49650da651
Update dependency org.jenkins-ci.plugins:plugin to v5.17 (#2681)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-19 04:31:24 +00:00
renovate[bot] 2447dde6ae
Update dependency com.github.erosb:everit-json-schema to v1.14.6 (#2680)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-19 04:31:05 +00:00
renovate[bot] 8b2b421500
Update plugin-bom.version to v4740 (#2679)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-05-12 03:13:32 +00:00
33 changed files with 190 additions and 135 deletions

View File

@ -2,6 +2,6 @@
<extension>
<groupId>io.jenkins.tools.incrementals</groupId>
<artifactId>git-changelist-maven-extension</artifactId>
<version>1.8</version>
<version>1.13</version>
</extension>
</extensions>

View File

@ -0,0 +1,30 @@
# Configure ThinBackup
Requires `thin-backup` >= 2.0
Basic configuration of [ThinBackup](https://plugins.jenkins.io/thinBackup/) plugin.
## Sample configuration
```yaml
unclassified:
thinBackup:
backupAdditionalFiles: false
backupAdditionalFilesRegex: "^.*\\.(txt)$"
backupBuildArchive: false
backupBuildResults: true
backupBuildsToKeepOnly: false
backupConfigHistory: false
backupNextBuildNumber: false
backupPath: "c:\\temp\\thin-backup"
backupPluginArchives: false
backupUserContents: false
cleanupDiff: false
diffBackupSchedule: "0 12 * * 1-5"
excludedFilesRegex: "^.*\\.(log)$"
failFast: true
forceQuietModeTimeout: 120
fullBackupSchedule: "0 12 * * 1"
moveOldBackupsToZipFile: false
nrMaxStoredFull: -1
waitForIdle: true
```

View File

@ -3,7 +3,7 @@
The plugin supports exporting existing configurations as YAML.
This can be achieved with the following options:
* Accessing the `http://[your_jenkins_url]/configuration-as-code/` URL as a Jenkins administrators and pressing `Download Configuration`
* Accessing the `http://[your_jenkins_url]/configuration-as-code/` URL as a Jenkins administrator, and clicking `Export configuration`
* Running the following in a Groovy script (not recommended, uses internal APIs):
import io.jenkins.plugins.casc.ConfigurationAsCode
@ -11,9 +11,8 @@ This can be achieved with the following options:
ConfigurationAsCode.get().export(stream)
println stream.toString()
Export feature is **NOT** intended to offer a directly usable jenkins.yaml configuration.
It can be used for inspiration writing your own production-ready YAML, but be aware that export can be partial,
or fail for some components.
Export may not offer a directly usable jenkins.yaml configuration.
It is normally better when you copy the relevant sections you need instead of the entire file.
## Security notice
@ -21,14 +20,14 @@ Jenkins configuration may include various sensitive information,
including, but not limited to, credentials, secrets, administrative information about the instance and user personal data.
The Configuration-as-Code plugin tracks secrets and represents them safely in the exported YAMLs,
but it cannot prevent secrets from being exported in all cases.
Ultimately, it is a responsibility of Jenkins administrators to ensure that the generated YAML files
Ultimately, it is the responsibility of Jenkins administrators to ensure that the generated YAML files
do not include sensitive information.
See more information about the masking logic below.
## Data to be exported
Currently the plugin does not have a way to define which data should be exported.
The plugin does not have a way to define which data should be exported.
The following data is exported:
* System configuration under the _Manage Jenkins_ link
@ -36,8 +35,9 @@ The following data is exported:
* Agent configurations
* Views
* Credentials
* Users - Only if using the security realm "Jenkins own user database"
Jobs and users are NOT exported by the plugin.
The plugin does NOT export Jobs.
## Secret masking

View File

@ -13,14 +13,15 @@
<properties>
<!-- no need to be deployed during release, this is a test-only module -->
<maven.deploy.skip>true</maven.deploy.skip>
<jenkins.version>2.504.1</jenkins.version>
<jenkins.baseline>2.516</jenkins.baseline>
<jenkins.version>${jenkins.baseline}.1</jenkins.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.jenkins.tools.bom</groupId>
<artifactId>bom-2.479.x</artifactId>
<artifactId>bom-${jenkins.baseline}.x</artifactId>
<version>${plugin-bom.version}</version>
<type>pom</type>
<scope>import</scope>
@ -208,7 +209,7 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>jira</artifactId>
<version>3.15</version>
<version>3.19</version>
<scope>test</scope>
</dependency>
<dependency>
@ -314,6 +315,11 @@
<version>2.0.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jvnet.hudson.plugins</groupId>
<artifactId>thinBackup</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>

View File

@ -0,0 +1,47 @@
package io.jenkins.plugins.casc;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import io.jenkins.plugins.casc.misc.ConfiguredWithReadme;
import io.jenkins.plugins.casc.misc.JenkinsConfiguredWithReadmeRule;
import org.junit.Rule;
import org.junit.Test;
import org.jvnet.hudson.plugins.thinbackup.ThinBackupPluginImpl;
public class ThinBackupTest {
@Rule
public JenkinsConfiguredWithReadmeRule j = new JenkinsConfiguredWithReadmeRule();
@Test
@ConfiguredWithReadme("thin-backup/README.md")
public void configure_thinbackup() {
ThinBackupPluginImpl thinBackupPluginConfig = ThinBackupPluginImpl.get();
final String backupPath = thinBackupPluginConfig.getBackupPath();
// test strings
assertEquals("c:\\temp\\thin-backup", backupPath);
assertEquals("0 12 * * 1-5", thinBackupPluginConfig.getDiffBackupSchedule());
assertEquals("0 12 * * 1", thinBackupPluginConfig.getFullBackupSchedule());
assertEquals("^.*\\.(log)$", thinBackupPluginConfig.getExcludedFilesRegex());
assertEquals("^.*\\.(txt)$", thinBackupPluginConfig.getBackupAdditionalFilesRegex());
// test numbers
assertEquals(120, thinBackupPluginConfig.getForceQuietModeTimeout());
assertEquals(-1, thinBackupPluginConfig.getNrMaxStoredFull());
// test booleans
assertTrue(thinBackupPluginConfig.isWaitForIdle());
assertTrue(thinBackupPluginConfig.isBackupBuildResults());
assertTrue(thinBackupPluginConfig.isFailFast());
assertFalse(thinBackupPluginConfig.isCleanupDiff());
assertFalse(thinBackupPluginConfig.isMoveOldBackupsToZipFile());
assertFalse(thinBackupPluginConfig.isBackupBuildArchive());
assertFalse(thinBackupPluginConfig.isBackupPluginArchives());
assertFalse(thinBackupPluginConfig.isBackupUserContents());
assertFalse(thinBackupPluginConfig.isBackupConfigHistory());
assertFalse(thinBackupPluginConfig.isBackupAdditionalFiles());
assertFalse(thinBackupPluginConfig.isBackupNextBuildNumber());
assertFalse(thinBackupPluginConfig.isBackupBuildsToKeepOnly());
}
}

View File

@ -2,7 +2,10 @@ cache:
size: 100
ttl: 30
configurations:
- inhibitInferRootDN: false
- groupMembershipStrategy:
fromGroupSearch: {
}
inhibitInferRootDN: false
rootDN: "dc=acme,dc=fr"
server: "ldap.acme.com"
disableMailAddressResolver: false

View File

@ -62,6 +62,10 @@
<groupId>io.jenkins.plugins</groupId>
<artifactId>caffeine-api</artifactId>
</dependency>
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>commons-lang3-api</artifactId>
</dependency>
<dependency>
<groupId>io.jenkins.plugins</groupId>
<artifactId>commons-text-api</artifactId>
@ -81,7 +85,7 @@
<dependency>
<groupId>io.vavr</groupId>
<artifactId>vavr</artifactId>
<version>0.10.6</version>
<version>0.10.7</version>
</dependency>
<dependency>
<groupId>com.github.stefanbirkner</groupId>

View File

@ -26,7 +26,7 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.kohsuke.accmod.AccessRestriction;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;

View File

@ -33,7 +33,7 @@ import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.kohsuke.accmod.AccessRestriction;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.Beta;

View File

@ -77,7 +77,7 @@ import jenkins.model.Jenkins;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.QueryParameter;
@ -632,9 +632,6 @@ public class ConfigurationAsCode extends ManagementLink {
}
tuples.add(new NodeTuple(new ScalarNode(Tag.STR, entry.getKey(), null, null, PLAIN), valueNode));
}
if (tuples.isEmpty()) {
return null;
}
return new MappingNode(Tag.MAP, tuples, BLOCK);

View File

@ -7,7 +7,7 @@ import io.jenkins.plugins.casc.model.CNode;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.kohsuke.stapler.Stapler;
/**

View File

@ -33,7 +33,7 @@ import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.jenkinsci.Symbol;
/**

View File

@ -16,7 +16,7 @@ import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Stream;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringSubstitutor;
import org.apache.commons.text.TextStringBuilder;
import org.apache.commons.text.lookup.StringLookup;

View File

@ -16,7 +16,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.DataBoundConstructor;

View File

@ -16,13 +16,14 @@ import io.jenkins.plugins.casc.RootElementConfigurator;
import io.jenkins.plugins.casc.model.CNode;
import io.jenkins.plugins.casc.model.Mapping;
import io.jenkins.plugins.casc.model.Scalar;
import io.jenkins.plugins.casc.model.Sequence;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import jenkins.model.GlobalConfigurationCategory;
import jenkins.model.Jenkins;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.jenkinsci.Symbol;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
@ -109,6 +110,11 @@ public class GlobalConfigurationCategoryConfigurator extends BaseConfigurator<Gl
Jenkins.get().getExtensionList(Descriptor.class).stream()
.filter(this::filterDescriptors)
.forEach(d -> describe(d, mapping, context));
mapping.entrySet()
.removeIf(e -> e.getValue() instanceof Mapping m
&& m.keySet().equals(Set.of("installations"))
&& m.get("installations") instanceof Sequence s
&& s.isEmpty());
return mapping;
}

View File

@ -8,7 +8,7 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
/**
* {@link SecretSource} implementation relying on <a href="https://docs.docker.com/engine/swarm/secrets">docker secrets</a>.

View File

@ -3,7 +3,7 @@ package io.jenkins.plugins.casc.impl.secrets;
import hudson.Extension;
import io.jenkins.plugins.casc.SecretSource;
import java.util.Optional;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;

View File

@ -19,16 +19,16 @@ package io.jenkins.plugins.casc.util;
import edu.umd.cs.findbugs.annotations.CheckForNull;
import java.lang.reflect.Field;
import java.util.Iterator;
import org.apache.commons.lang.ClassUtils;
import org.apache.commons.lang3.ClassUtils;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
/**
* Extends {@link org.apache.commons.lang.reflect.FieldUtils} by adding
* Extends {@link org.apache.commons.lang3.reflect.FieldUtils} by adding
* some utility methods.
*/
@Restricted(NoExternalUse.class)
public class ExtraFieldUtils extends org.apache.commons.lang.reflect.FieldUtils {
public class ExtraFieldUtils extends org.apache.commons.lang3.reflect.FieldUtils {
/**
* Gets an accessible <code>Field</code> by name without breaking scope.

View File

@ -4,7 +4,7 @@ import hudson.ExtensionList;
import java.util.Optional;
import javax.annotation.Nonnull;
import jenkins.model.Jenkins;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.StringUtils;
public class MergeStrategyFactory {
private static MergeStrategy getMergeStrategy(@Nonnull String name) {

View File

@ -8,7 +8,7 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import org.apache.commons.collections.map.AbstractMapDecorator;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.constructor.AbstractConstruct;
import org.yaml.snakeyaml.constructor.Construct;

View File

@ -2,8 +2,20 @@
<j:jelly xmlns:j="jelly:core" xmlns:l="/lib/layout" xmlns:f="/lib/form" xmlns:i="jelly:fmt" xmlns:st="jelly:stapler">
<l:layout type="one-column" title="${%Configuration as Code}" permissions="${app.MANAGE_AND_SYSTEM_READ}">
<l:main-panel>
<st:adjunct includes="io.jenkins.plugins.casc.assets.index"/>
<h1>${%Configuration as Code}</h1>
<l:app-bar title="${%Configuration as Code}">
<f:form method="post" action="reload" name="reload">
<l:hasAdministerOrManage>
<f:submit icon="symbol-refresh" primary="false" name="reload"
value="${%Reload existing configuration}"/>
</l:hasAdministerOrManage>
</f:form>
<f:form method="post" action="viewExport" name="viewExport">
<l:hasPermission permission="${app.SYSTEM_READ}">
<f:submit primary="false" name="viewExport" value="${%Export configuration}"/>
</l:hasPermission>
</f:form>
</l:app-bar>
<j:choose>
<j:when test="${empty it.sources}">
@ -17,7 +29,7 @@
</j:forEach>
</ul>
<p>${%Last time applied :} <i:formatDate value="${it.lastTimeLoaded}" type="both" dateStyle="medium" timeStyle="long"/></p>
<p>${%Last time applied:} <i:formatDate value="${it.lastTimeLoaded}" type="both" dateStyle="medium" timeStyle="long"/></p>
</j:otherwise>
</j:choose>
@ -25,7 +37,7 @@
<l:isAdmin>
<f:form method="post" action="replace" name="replace">
<h2>${%Replace configuration source with:}</h2>
<f:entry title="${%Path or URL}" field="newSource" >
<f:entry title="${%Path or URL}" field="newSource" class="jenkins-form-item--small" >
<f:textbox checkUrl="checkNewSource" checkDependsOn="newSource"/>
</f:entry>
<f:block>
@ -33,25 +45,8 @@
</f:block>
</f:form>
</l:isAdmin>
<h2>${%Actions}</h2>
<l:hasAdministerOrManage>
<f:form method="post" action="reload" name="reload">
<f:submit name="reload" value="${%Reload existing configuration}"/>
</f:form>
</l:hasAdministerOrManage>
<l:hasPermission permission="${app.SYSTEM_READ}">
<f:form method="post" action="export" name="export">
<f:submit name="export" value="${%Download Configuration}"/>
</f:form>
<f:form method="post" action="viewExport" name="viewExport">
<f:submit name="viewExport" value="${%View Configuration}"/>
</f:form>
<div class="alert alert-warning clear-action-forms">
<l:icon class="icon-warning icon-sm"/>
${%exportWarning}
</div>
<h2>${%Reference}</h2>
<dt>
<dl><a href="reference">${%Documentation}</a></dl>

View File

@ -1,3 +0,0 @@
exportWarning=Export is not intended to offer a directly usable jenkins.yaml configuration. \
It can be used for inspiration writing your own, be aware export can be partial, \
or fail for some components.

View File

@ -1,37 +1,17 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler">
<st:contentType value="text/html;charset=UTF-8"/>
<j:new var="h" className="hudson.Functions"/>
<j:invoke on="${h}" method="initPageVariables">
<j:arg value="${context}"/>
</j:invoke>
<html><head>
<link href='https://jenkins.io/assets/bower/bootstrap/css/bootstrap.min.css' media='screen' rel='stylesheet'/>
<link href='https://jenkins.io/assets/bower/tether/css/tether.min.css' media='screen' rel='stylesheet'/>
<link href='https://jenkins.io/css/font-icons.css' media='screen' rel='stylesheet'/>
<link href='https://jenkins.io/css/jenkins.css' media='screen' rel='stylesheet'/>
<link href='https://jenkins.io/assets/bower/ionicons/css/ionicons.min.css' media='screen' rel='stylesheet'/>
<link href='https://jenkins.io/css/footer.css' media='screen' rel='stylesheet'/>
<link href='https://jenkins.io/css/font-awesome.min.css' media='screen' rel='stylesheet'/>
<link href='${rootURL}/plugin/configuration-as-code/css/reference.css' rel='stylesheet'/>
</head>
<body class='syntax'>
<div class='container'>
<div class='row body'>
<div class='section'>
<h2>${%Jenkins Configuration as Code Reference}</h2>
<div class='sect3'>
<j:set var="casc" value="${it}"/>
<j:forEach items="${it.configurators}" var="c">
<st:include page="documentation.jelly" it="${c}" optional="true"/>
</j:forEach>
</div>
</div>
</div>
</div>
</body>
</html>
<j:jelly xmlns:j="jelly:core" xmlns:l="/lib/layout" xmlns:st="jelly:stapler">
<l:layout type="one-column" title="${%Reference}" permissions="${app.MANAGE_AND_SYSTEM_READ}">
<l:breadcrumb title="${%Reference}"/>
<l:main-panel>
<link href='${rootURL}/plugin/configuration-as-code/css/reference.css' rel='stylesheet'/>
<l:app-bar title="${%Reference}"/>
<div class='sect3'>
<j:set var="casc" value="${it}"/>
<j:forEach items="${it.configurators}" var="c">
<st:include page="documentation.jelly" it="${c}" optional="true"/>
</j:forEach>
</div>
</l:main-panel>
</l:layout>
</j:jelly>

View File

@ -1,10 +1,22 @@
<?jelly escape-by-default='true'?>
<j:jelly xmlns:j="jelly:core" xmlns:l="/lib/layout" xmlns:st="jelly:stapler" xmlns:p="/prism">
<l:layout type="one-column" title="${%Configuration as Code}">
<l:breadcrumb title="${%View}" />
<j:jelly xmlns:j="jelly:core" xmlns:l="/lib/layout" xmlns:st="jelly:stapler" xmlns:p="/prism"
xmlns:f="/lib/form">
<l:layout type="one-column" title="${%Exported configuration}">
<l:breadcrumb title="${%Exported configuration}" />
<l:main-panel>
<st:adjunct includes="io.jenkins.plugins.casc.assets.viewExport" />
<l:app-bar title="${%Exported configuration}">
<f:form method="post" action="export" name="export">
<f:submit icon="symbol-download" primary="false" name="export" value="${%Download}"/>
</f:form>
</l:app-bar>
<div class="jenkins-alert jenkins-alert-info">
${%exportWarning}
</div>
<p:prism configuration="${it.prismConfiguration}" />
<pre>
<code class="language-yaml">${export}</code>

View File

@ -0,0 +1,2 @@
exportWarning=Export may not offer a directly usable jenkins.yaml configuration. \
It is normally better when you copy the relevant sections you need instead of the entire file.

View File

@ -1,26 +0,0 @@
form[name='replace'] input[name='_.newSource'] {
width: 32em;
}
form[name='reload'] {
margin-bottom: 10px;
}
form[name='export'] {
float: left;
margin-right: 20px;
margin-bottom: 10px;
}
form[name='viewExport'] {
float: left;
}
td {
vertical-align: middle;
}
.clear-action-forms {
margin-top: 10px;
clear: both;
}

View File

@ -8,13 +8,13 @@
.configurator-pointer {
font-size: 0.5em;
color: #454545;
color: var(--text-color-secondary);
font-weight: 100;
}
.root-configurator-pointer {
font-size: 0.5em;
color: #7f5200;
color: var(--orange);
font-weight: 100;
}
@ -27,7 +27,7 @@
display: flex;
flex-grow: 1;
margin-left: 25px;
border-left: 1px solid #ccc;
border-left: var(--jenkins-border);
line-height: 24px;
}
@ -70,7 +70,7 @@
}
.attribute-type {
color: #454545;
color: var(--text-color-secondary);
}
.attribute-type__list {

View File

@ -1,8 +1,7 @@
package io.jenkins.plugins.casc.permissions;
public enum Action {
VIEW_CONFIGURATION("View Configuration"),
DOWNLOAD_CONFIGURATION("Download Configuration"),
VIEW_CONFIGURATION("Export configuration"),
APPLY_NEW_CONFIGURATION("Apply new configuration"),
RELOAD_EXISTING_CONFIGURATION("Reload existing configuration"),
;

View File

@ -1,7 +1,6 @@
package io.jenkins.plugins.casc.permissions;
import static io.jenkins.plugins.casc.permissions.Action.APPLY_NEW_CONFIGURATION;
import static io.jenkins.plugins.casc.permissions.Action.DOWNLOAD_CONFIGURATION;
import static io.jenkins.plugins.casc.permissions.Action.RELOAD_EXISTING_CONFIGURATION;
import static io.jenkins.plugins.casc.permissions.Action.VIEW_CONFIGURATION;
import static java.lang.String.format;
@ -62,7 +61,6 @@ class PermissionsTest {
SYSTEM_READER,
ImmutableMap.<Action, Boolean>builder()
.put(VIEW_CONFIGURATION, true)
.put(DOWNLOAD_CONFIGURATION, true)
.put(APPLY_NEW_CONFIGURATION, false)
.put(RELOAD_EXISTING_CONFIGURATION, false)
.build());
@ -106,7 +104,6 @@ class PermissionsTest {
ADMIN,
ImmutableMap.<Action, Boolean>builder()
.put(VIEW_CONFIGURATION, true)
.put(DOWNLOAD_CONFIGURATION, true)
.put(APPLY_NEW_CONFIGURATION, true)
.put(RELOAD_EXISTING_CONFIGURATION, true)
.build());

View File

@ -4,7 +4,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>5.16</version>
<version>5.26</version>
<relativePath />
</parent>
@ -42,7 +42,7 @@
<jenkins.baseline>2.504</jenkins.baseline>
<jenkins.version>${jenkins.baseline}.1</jenkins.version>
<tagNameFormat>configuration-as-code-@{project.version}</tagNameFormat>
<plugin-bom.version>4710.v016f0a_07e34d</plugin-bom.version>
<plugin-bom.version>5294.va_d2e144c80e1</plugin-bom.version>
<spotless.check.skip>false</spotless.check.skip>
</properties>
@ -71,7 +71,7 @@
<dependency>
<groupId>com.puppycrawl.tools</groupId>
<artifactId>checkstyle</artifactId>
<version>10.23.1</version>
<version>11.1.0</version>
</dependency>
</dependencies>
</plugin>

View File

@ -32,7 +32,7 @@
<dependency>
<groupId>com.github.erosb</groupId>
<artifactId>everit-json-schema</artifactId>
<version>1.14.5</version>
<version>1.14.6</version>
</dependency>
<dependency>
<groupId>com.github.stefanbirkner</groupId>
@ -49,6 +49,12 @@
<groupId>com.vladsch.flexmark</groupId>
<artifactId>flexmark-all</artifactId>
<version>0.64.8</version>
<exclusions>
<exclusion>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.jenkins</groupId>

View File

@ -10,7 +10,6 @@ import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.hamcrest.core.StringContains;
/**
@ -49,7 +48,8 @@ public class JenkinsConfiguredWithCodeRule extends JenkinsConfiguredRule {
if (!configuredWithCode.expected().isInstance(t)) {
throw new AssertionError("Unexpected exception ", t);
} else {
if (!StringUtils.isBlank(configuredWithCode.message())) {
if (configuredWithCode.message() != null
&& !configuredWithCode.message().isBlank()) {
boolean match = new StringContains(false, configuredWithCode.message()).matches(t.getMessage());
if (!match) {
throw new AssertionError("Exception did not contain the expected string: "

View File

@ -28,7 +28,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.commons.lang.StringUtils;
import org.hamcrest.core.StringContains;
/**
@ -73,7 +72,8 @@ public class JenkinsConfiguredWithReadmeRule extends JenkinsConfiguredRule {
if (!configuredWithReadme.expected().isInstance(t)) {
throw new AssertionError("Unexpected exception ", t);
} else {
if (!StringUtils.isBlank(configuredWithReadme.message())) {
if (configuredWithReadme.message() != null
&& !configuredWithReadme.message().isBlank()) {
boolean match =
new StringContains(false, configuredWithReadme.message()).matches(t.getMessage());
if (!match) {