diff --git a/src/main/java/com/cloudbees/hudson/plugins/folder/Folder.java b/src/main/java/com/cloudbees/hudson/plugins/folder/Folder.java index fb4b84b6..bb4d9321 100644 --- a/src/main/java/com/cloudbees/hudson/plugins/folder/Folder.java +++ b/src/main/java/com/cloudbees/hudson/plugins/folder/Folder.java @@ -68,6 +68,9 @@ import org.kohsuke.stapler.StaplerResponse2; import org.kohsuke.stapler.verb.POST; +import com.cloudbees.hudson.plugins.folder.SaveAllJobsAction; + + /** * A mutable folder. */ @@ -414,7 +417,7 @@ public DescriptorImpl getDescriptor() { @Override public void remove(TopLevelItem item) throws IOException, IllegalArgumentException { items.remove(item.getName()); } - + @Extension public static class DescriptorImpl extends AbstractFolderDescriptor { diff --git a/src/main/java/com/cloudbees/hudson/plugins/folder/SaveAllJobsAction.java b/src/main/java/com/cloudbees/hudson/plugins/folder/SaveAllJobsAction.java new file mode 100644 index 00000000..f02972ce --- /dev/null +++ b/src/main/java/com/cloudbees/hudson/plugins/folder/SaveAllJobsAction.java @@ -0,0 +1,44 @@ +package com.cloudbees.hudson.plugins.folder; + +import hudson.model.Action; +import hudson.model.Job; +import java.io.IOException; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; + +public class SaveAllJobsAction implements Action { + + private final Folder folder; + + public SaveAllJobsAction(Folder folder) { + this.folder = folder; + } + + @Override + public String getIconFileName() { + return "save.png"; // small save icon + } + + @Override + public String getDisplayName() { + return "Save All Jobs"; + } + + @Override + public String getUrlName() { + return "save-all-jobs"; + } + + // Called when the form is submitted + public void doIndex(StaplerRequest req, StaplerResponse rsp) throws IOException { + doSaveAll(); + rsp.sendRedirect2("../"); // redirect back to folder page after saving + } + + // Actual saving logic + public void doSaveAll() throws IOException { + for (Job job : folder.getAllJobs()) { + job.save(); + } + } +} diff --git a/src/main/java/com/cloudbees/hudson/plugins/folder/SaveAllJobsAction/index.jelly b/src/main/java/com/cloudbees/hudson/plugins/folder/SaveAllJobsAction/index.jelly new file mode 100644 index 00000000..0fe3df19 --- /dev/null +++ b/src/main/java/com/cloudbees/hudson/plugins/folder/SaveAllJobsAction/index.jelly @@ -0,0 +1,12 @@ + + + + +

Save All Jobs in Folder

+ + + + +
+
+
diff --git a/src/main/java/com/cloudbees/hudson/plugins/folder/SaveAllJobsActionFactory.java b/src/main/java/com/cloudbees/hudson/plugins/folder/SaveAllJobsActionFactory.java new file mode 100644 index 00000000..94fd8bf7 --- /dev/null +++ b/src/main/java/com/cloudbees/hudson/plugins/folder/SaveAllJobsActionFactory.java @@ -0,0 +1,21 @@ +package com.cloudbees.hudson.plugins.folder; + +import hudson.Extension; +import hudson.model.Action; +import jenkins.model.TransientActionFactory; +import java.util.Collection; +import java.util.Collections; + +@Extension +public class SaveAllJobsActionFactory extends TransientActionFactory { + + @Override + public Class type() { + return Folder.class; + } + + @Override + public Collection createFor(Folder target) { + return Collections.singletonList(new SaveAllJobsAction(target)); + } +} diff --git a/src/test/java/com/cloudbees/hudson/plugins/folder/FolderTest.java b/src/test/java/com/cloudbees/hudson/plugins/folder/FolderTest.java index a2c8cd47..3ef1a511 100644 --- a/src/test/java/com/cloudbees/hudson/plugins/folder/FolderTest.java +++ b/src/test/java/com/cloudbees/hudson/plugins/folder/FolderTest.java @@ -29,6 +29,7 @@ import com.cloudbees.hudson.plugins.folder.health.FolderHealthMetricDescriptor; import com.cloudbees.hudson.plugins.folder.properties.FolderCredentialsProvider; import com.cloudbees.plugins.credentials.domains.DomainCredentials; +import com.cloudbees.hudson.plugins.folder.SaveAllJobsAction; import org.htmlunit.HttpMethod; import org.htmlunit.WebRequest; import org.htmlunit.html.*; @@ -398,6 +399,19 @@ public void interruptOnDelete() throws Exception { f.addAction(a); assertNotNull(f.getAction(WhoAmI.class)); } + + @Test public void testSaveAllJobsActionAppears() throws Exception { + Folder f = createFolder(); + SaveAllJobsAction action = new SaveAllJobsAction(f); + + // Check action is not null + assertNotNull(action); + + // Check URL mapping and display name + assertEquals("save-all-jobs", action.getUrlName()); + assertEquals("Save All Jobs", action.getDisplayName()); + } + @Issue("JENKINS-32487") @Test public void shouldAssignPropertyOwnerOnCreationAndReload() throws Exception {