Skip to content

Commit

Permalink
JENKINS-57252: Optional support for shelving projects instead of dele…
Browse files Browse the repository at this point in the history
…ting them
  • Loading branch information
cpfeiffer committed Aug 15, 2019
1 parent b7eb906 commit 81186ed
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 4 deletions.
6 changes: 4 additions & 2 deletions job-dsl-plugin/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,12 @@ dependencies {
optionalJenkinsPlugins 'org.jenkins-ci.plugins:config-file-provider:2.15.4'
optionalJenkinsPlugins 'org.jenkinsci.plugins:managed-scripts:1.3'
optionalJenkinsPlugins 'io.jenkins:configuration-as-code:1.15'
optionalJenkinsPlugins 'org.jenkins-ci.plugins:shelve-project-plugin:2.4'
jenkinsTest 'io.jenkins:configuration-as-code:1.15'
jenkinsTest 'io.jenkins:configuration-as-code:1.15:tests'
jenkinsTest 'org.jenkins-ci.plugins:cloudbees-folder:5.14'
jenkinsTest 'org.jenkins-ci.plugins:cloudbees-folder:6.5.1'
jenkinsTest 'org.jenkins-ci.plugins:matrix-auth:1.3'
jenkinsTest 'org.jenkins-ci.plugins:nested-view:1.14'
jenkinsTest 'org.jenkins-ci.plugins:credentials:2.1.10'
jenkinsTest 'org.jenkins-ci.plugins:credentials:2.1.11'
jenkinsTest 'org.jenkins-ci.plugins:shelve-project-plugin:2.4'
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ public void setTemplateJobMap(Multimap<String, SeedReference> templateJobMap) {
public ListBoxModel doFillRemovedJobActionItems() {
ListBoxModel items = new ListBoxModel();
for (RemovedJobAction action : RemovedJobAction.values()) {
if (action == RemovedJobAction.SHELVE && Jenkins.get().getPlugin(ExecuteDslScripts.SHELVE_PLUGIN_ID) == null) {
continue;
}
items.add(action.getDisplayName(), action.name());
}
return items;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import hudson.Util;
import hudson.model.AbstractBuild;
import hudson.model.AbstractItem;
import hudson.model.BuildableItem;
import hudson.model.Descriptor;
import hudson.model.Item;
import hudson.model.ItemGroup;
Expand Down Expand Up @@ -51,6 +52,7 @@
import org.jenkinsci.plugins.scriptsecurity.scripts.ApprovalContext;
import org.jenkinsci.plugins.scriptsecurity.scripts.ScriptApproval;
import org.jenkinsci.plugins.scriptsecurity.scripts.languages.GroovyLanguage;
import org.jvnet.hudson.plugins.shelveproject.ShelveProjectTask;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.DataBoundSetter;

Expand Down Expand Up @@ -79,6 +81,8 @@ public class ExecuteDslScripts extends Builder implements SimpleBuildStep {

private static volatile boolean rebootRequired;

public static final String SHELVE_PLUGIN_ID = "shelve-project-plugin";

/**
* Newline-separated list of locations to load as dsl scripts.
*/
Expand Down Expand Up @@ -457,6 +461,7 @@ private void updateGeneratedJobs(final Job seedJob, TaskListener listener,
Set<GeneratedJob> existing = Sets.intersection(generatedJobs, freshJobs);
Set<GeneratedJob> unreferenced = Sets.difference(generatedJobs, freshJobs);
Set<GeneratedJob> removed = new HashSet<>();
Set<GeneratedJob> shelved = new HashSet<>();
Set<GeneratedJob> disabled = new HashSet<>();

logItems(listener, "Added items", added);
Expand All @@ -470,6 +475,9 @@ private void updateGeneratedJobs(final Job seedJob, TaskListener listener,
if (removedJobAction == RemovedJobAction.DELETE) {
removedItem.delete();
removed.add(unreferencedJob);
} else if (removedJobAction == RemovedJobAction.SHELVE) {
shelve(removedItem);
shelved.add(unreferencedJob);
} else {
if (removedItem instanceof ParameterizedJob) {
ParameterizedJob project = (ParameterizedJob) removedItem;
Expand All @@ -484,10 +492,25 @@ private void updateGeneratedJobs(final Job seedJob, TaskListener listener,
// print what happened with unreferenced jobs
logItems(listener, "Disabled items", disabled);
logItems(listener, "Removed items", removed);
logItems(listener, "Shelved items", shelved);

updateGeneratedJobMap(seedJob, Sets.union(added, existing), unreferenced);
}

private void shelve(Item project) {
Jenkins jenkins = Jenkins.get();
if (! (project instanceof BuildableItem)) {
LOGGER.log(Level.WARNING, "Unable to shelve " + project + " since it is not a BuildableItem");
return;
}
BuildableItem item = (BuildableItem) project;
if (jenkins.getPlugin(SHELVE_PLUGIN_ID) == null) {
LOGGER.log(Level.WARNING, "Unable to shelve project " + item + " since the " + SHELVE_PLUGIN_ID + " plugin is not installed.");
return;
}
jenkins.getQueue().schedule(new ShelveProjectTask(item), 0);
}

private void updateGeneratedJobMap(Job seedJob, Set<GeneratedJob> createdOrUpdatedJobs,
Set<GeneratedJob> removedJobs) throws IOException {
DescriptorImpl descriptor = Jenkins.get().getDescriptorByType(DescriptorImpl.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ package javaposse.jobdsl.plugin
enum RemovedJobAction {
IGNORE('Ignore'),
DISABLE('Disable'),
DELETE('Delete')
DELETE('Delete'),
SHELVE('Shelve')

final String displayName

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<div>
Specifies what to do when a previously generated job is not referenced anymore.
<p>If the <a href="https://plugins.jenkins.io/shelve-project-plugin">Shelve Project"</a> plugin is installed, projects may be archived instead of permanently deleted.</p>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,21 @@ folder('folder-a/folder-b') {
executeDslScripts.removedJobAction == RemovedJobAction.DELETE
}

@WithoutJenkins
def 'removed job action shelve'() {
setup:
ExecuteDslScripts executeDslScripts = new ExecuteDslScripts()

expect:
executeDslScripts.removedJobAction == RemovedJobAction.IGNORE

when:
executeDslScripts.removedJobAction = RemovedJobAction.SHELVE

then:
executeDslScripts.removedJobAction == RemovedJobAction.SHELVE
}

@WithoutJenkins
def 'removed view action'() {
setup:
Expand Down Expand Up @@ -579,7 +594,31 @@ folder('folder-a/folder-b') {
jenkinsRule.jenkins.getItemByFullName('/folder/test-job') == null
}
def 'only use last build to calculate items to be deleted'() {
def 'shelve a project instead of deleting it'() {
setup:
FreeStyleProject job = jenkinsRule.createFreeStyleProject('seed')
when:
String script1 = 'job("test-job")'
ExecuteDslScripts builder1 = new ExecuteDslScripts(script1)
builder1.removedJobAction = RemovedJobAction.DELETE
runBuild(job, builder1)
then:
jenkinsRule.jenkins.getItemByFullName('test-job') instanceof FreeStyleProject
when:
String script2 = 'job("different-job")'
ExecuteDslScripts builder2 = new ExecuteDslScripts(script2)
builder2.removedJobAction = RemovedJobAction.SHELVE
runBuild(job, builder2)
then:
jenkinsRule.jenkins.getItemByFullName('different-job') instanceof FreeStyleProject
// jenkinsRule.jenkins.getItemByFullName('test-job') == null
}
def 'only use last build to calculate items to be deleted'() {
setup:
FreeStyleProject job = jenkinsRule.createFreeStyleProject('seed')
Expand Down

0 comments on commit 81186ed

Please sign in to comment.