From efc581d4d84fbf1dfbb35c4a1eed35f9e6ba5f60 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Thu, 16 Oct 2025 14:22:30 +0100 Subject: [PATCH 01/18] Init --- .../workflow/cps/replay/ReplayAction.java | 35 ++++++++++++++++++- pom.xml | 4 +-- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java index a9ec43a81..0d3a02dc4 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java @@ -65,6 +65,11 @@ import jenkins.model.Jenkins; import jenkins.model.ParameterizedJobMixIn; import jenkins.model.TransientActionFactory; +import jenkins.model.menu.Group; +import jenkins.model.menu.Semantic; +import jenkins.model.menu.event.DropdownEvent; +import jenkins.model.menu.event.Event; +import jenkins.model.menu.event.LinkEvent; import jenkins.scm.api.SCMRevisionAction; import net.sf.json.JSON; import net.sf.json.JSONObject; @@ -115,6 +120,33 @@ public String getUrlName() { return isEnabled() || isRebuildEnabled() ? "replay" : null; } + public Group getGroup() { + return Group.FIRST_IN_APP_BAR; + } + + public Event getEvent() { + String urlName = getUrlName(); + return DropdownEvent.of(LinkEvent.of(urlName), List.of(new Action() { + @Override + public String getIconFileName() { + return "symbol-arrow-redo-outline plugin-ionicons-api"; + } + + @Override + public String getDisplayName() { + return "Edit Pipeline and replay"; + } + + public Event getEvent() { + return LinkEvent.of(urlName); + } + })); + } + + public Semantic getSemantic() { + return Semantic.BUILD; + } + /** Poke for an execution without blocking - may be null if run is very fresh or has not lazy-loaded yet. */ private @CheckForNull CpsFlowExecution getExecutionLazy() { FlowExecutionOwner owner = ((FlowExecutionOwner.Executable) run).asFlowExecutionOwner(); @@ -448,7 +480,8 @@ public Class type() { @Override public Collection createFor(Run run) { return run instanceof FlowExecutionOwner.Executable - && run.getParent() instanceof ParameterizedJobMixIn.ParameterizedJob + && run.getParent() instanceof ParameterizedJobMixIn.ParameterizedJob + || !run.isBuilding() ? Collections.singleton(new ReplayAction(run)) : Collections.emptySet(); } diff --git a/pom.xml b/pom.xml index a737db184..f34768829 100644 --- a/pom.xml +++ b/pom.xml @@ -35,8 +35,8 @@ 999999-SNAPSHOT jenkinsci/${project.artifactId}-plugin - 2.504 - ${jenkins.baseline}.3 + 2.516 + 2.533-SNAPSHOT 2.4.21 false From bc8e1b0a791862debe09d9d2e23396c8f2be39d3 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Wed, 29 Oct 2025 15:21:19 +0000 Subject: [PATCH 02/18] Update ReplayAction.java --- .../jenkinsci/plugins/workflow/cps/replay/ReplayAction.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java index 0d3a02dc4..76a4bc534 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java @@ -480,8 +480,8 @@ public Class type() { @Override public Collection createFor(Run run) { return run instanceof FlowExecutionOwner.Executable - && run.getParent() instanceof ParameterizedJobMixIn.ParameterizedJob - || !run.isBuilding() + && run.getParent() instanceof ParameterizedJobMixIn.ParameterizedJob + && !run.isBuilding() ? Collections.singleton(new ReplayAction(run)) : Collections.emptySet(); } From d40bb2fac5131c472a2d50814fac9378d30a7b44 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Thu, 26 Mar 2026 10:41:12 +0000 Subject: [PATCH 03/18] Push --- .../plugins/workflow/cps/replay/ReplayAction.java | 9 +++++++-- pom.xml | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java index 76a4bc534..87d8f3e0f 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java @@ -67,9 +67,9 @@ import jenkins.model.TransientActionFactory; import jenkins.model.menu.Group; import jenkins.model.menu.Semantic; -import jenkins.model.menu.event.DropdownEvent; import jenkins.model.menu.event.Event; import jenkins.model.menu.event.LinkEvent; +import jenkins.model.menu.event.SplitButtonEvent; import jenkins.scm.api.SCMRevisionAction; import net.sf.json.JSON; import net.sf.json.JSONObject; @@ -126,7 +126,7 @@ public Group getGroup() { public Event getEvent() { String urlName = getUrlName(); - return DropdownEvent.of(LinkEvent.of(urlName), List.of(new Action() { + return SplitButtonEvent.of(LinkEvent.of(urlName), List.of(new Action() { @Override public String getIconFileName() { return "symbol-arrow-redo-outline plugin-ionicons-api"; @@ -137,6 +137,11 @@ public String getDisplayName() { return "Edit Pipeline and replay"; } + @Override + public String getUrlName() { + return "urlName"; + } + public Event getEvent() { return LinkEvent.of(urlName); } diff --git a/pom.xml b/pom.xml index 2d968caef..d01c5259e 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ jenkinsci/${project.artifactId}-plugin 2.516 - 2.533-SNAPSHOT + 2.556 2.4.21 false From 11f2a0bc9a8482fb755d5beae61549c71e22be00 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Thu, 26 Mar 2026 11:36:29 +0000 Subject: [PATCH 04/18] Push --- .../replay/EditPipelineAndReplayAction.java | 61 ++++++++++++++++++ .../workflow/cps/replay/RebuildAction.java | 62 +++++++++++++++++++ .../workflow/cps/replay/ReplayAction.java | 24 ++----- .../replay/ReplayActionMenuContributor.java | 45 ++++++++++++++ .../cps/replay/RestartFromStageAction.java | 62 +++++++++++++++++++ 5 files changed, 236 insertions(+), 18 deletions(-) create mode 100644 plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java create mode 100644 plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java create mode 100644 plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayActionMenuContributor.java create mode 100644 plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java new file mode 100644 index 000000000..0bf629f4d --- /dev/null +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java @@ -0,0 +1,61 @@ +/* + * The MIT License + * + * Copyright 2026, Jan Faracik + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.jenkinsci.plugins.workflow.cps.replay; + +import hudson.Extension; +import hudson.model.Action; +import hudson.model.Run; +import org.jspecify.annotations.NonNull; + +import java.util.Collection; +import java.util.List; + +@Extension +public class EditPipelineAndReplayAction extends ReplayActionMenuContributor { + + @Override + public @NonNull Collection getActions(Run run) { + return List.of(new Action() { + @Override + public String getIconFileName() { + return "symbol-arrow-redo-outline plugin-ionicons-api"; + } + + @Override + public String getDisplayName() { + return "Replay"; + } + + public String getDescription() { + return "Edit Pipeline and replay"; + } + + @Override + public String getUrlName() { + return "replay"; + } + }); + } +} diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java new file mode 100644 index 000000000..9ef5029c8 --- /dev/null +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java @@ -0,0 +1,62 @@ +/* + * The MIT License + * + * Copyright 2026, Jan Faracik + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.jenkinsci.plugins.workflow.cps.replay; + +import hudson.Extension; +import hudson.model.Action; +import hudson.model.Run; +import org.jspecify.annotations.NonNull; + +import java.util.Collection; +import java.util.List; + +// TODO - To be moved to the right plugin +@Extension +public class RebuildAction extends ReplayActionMenuContributor { + + @Override + public @NonNull Collection getActions(Run run) { + return List.of(new Action() { + @Override + public String getIconFileName() { + return "symbol-play-outline plugin-ionicons-api"; + } + + @Override + public String getDisplayName() { + return "Rebuild"; + } + + public String getDescription() { + return "Edit parameters and rebuild"; + } + + @Override + public String getUrlName() { + return "rebuild/parameterized"; + } + }); + } +} diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java index 87d8f3e0f..93c2d8842 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java @@ -126,26 +126,14 @@ public Group getGroup() { public Event getEvent() { String urlName = getUrlName(); - return SplitButtonEvent.of(LinkEvent.of(urlName), List.of(new Action() { - @Override - public String getIconFileName() { - return "symbol-arrow-redo-outline plugin-ionicons-api"; - } - @Override - public String getDisplayName() { - return "Edit Pipeline and replay"; - } + // Allow for plugins to add additional build options + List actions = ReplayActionMenuContributor.all() + .stream() + .flatMap(e -> e.getActions(run).stream()) + .toList(); - @Override - public String getUrlName() { - return "urlName"; - } - - public Event getEvent() { - return LinkEvent.of(urlName); - } - })); + return SplitButtonEvent.of(LinkEvent.of(urlName, LinkEvent.LinkEventType.POST), actions); } public Semantic getSemantic() { diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayActionMenuContributor.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayActionMenuContributor.java new file mode 100644 index 000000000..6f782fdf3 --- /dev/null +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayActionMenuContributor.java @@ -0,0 +1,45 @@ +/* + * The MIT License + * + * Copyright 2026, Jan Faracik + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.jenkinsci.plugins.workflow.cps.replay; + +import edu.umd.cs.findbugs.annotations.NonNull; +import hudson.ExtensionList; +import hudson.ExtensionPoint; +import hudson.model.Action; +import hudson.model.Run; + +import java.util.Collection; + +/** + * Allows plugins to contribute additional entries to the {@link ReplayAction} split button. + */ +public abstract class ReplayActionMenuContributor implements ExtensionPoint { + + public abstract @NonNull Collection getActions(Run run); + + public static @NonNull ExtensionList all() { + return ExtensionList.lookup(ReplayActionMenuContributor.class); + } +} diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java new file mode 100644 index 000000000..d51994571 --- /dev/null +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java @@ -0,0 +1,62 @@ +/* + * The MIT License + * + * Copyright 2026, Jan Faracik + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +package org.jenkinsci.plugins.workflow.cps.replay; + +import hudson.Extension; +import hudson.model.Action; +import hudson.model.Run; +import org.jspecify.annotations.NonNull; + +import java.util.Collection; +import java.util.List; + +// TODO - To be moved to the right plugin +@Extension +public class RestartFromStageAction extends ReplayActionMenuContributor { + + @Override + public @NonNull Collection getActions(Run run) { + return List.of(new Action() { + @Override + public String getIconFileName() { + return "symbol-refresh-outline plugin-ionicons-api"; + } + + @Override + public String getDisplayName() { + return "Restart from Stage"; + } + + public String getDescription() { + return "Restart Pipeline from a specific Stage"; + } + + @Override + public String getUrlName() { + return "restart"; + } + }); + } +} From 36db794796105f60e7db6059266c652d7539738d Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Thu, 26 Mar 2026 12:02:30 +0000 Subject: [PATCH 05/18] Push --- .../workflow/cps/replay/EditPipelineAndReplayAction.java | 1 + .../jenkinsci/plugins/workflow/cps/replay/RebuildAction.java | 1 + .../plugins/workflow/cps/replay/RestartFromStageAction.java | 1 + .../jenkinsci/plugins/workflow/cps/replay/Messages.properties | 2 +- pom.xml | 2 +- 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java index 0bf629f4d..496bbcb84 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java @@ -48,6 +48,7 @@ public String getDisplayName() { return "Replay"; } + @Override public String getDescription() { return "Edit Pipeline and replay"; } diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java index 9ef5029c8..23d6d2bd0 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java @@ -49,6 +49,7 @@ public String getDisplayName() { return "Rebuild"; } + @Override public String getDescription() { return "Edit parameters and rebuild"; } diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java index d51994571..cc1d57903 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java @@ -49,6 +49,7 @@ public String getDisplayName() { return "Restart from Stage"; } + @Override public String getDescription() { return "Restart Pipeline from a specific Stage"; } diff --git a/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/replay/Messages.properties b/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/replay/Messages.properties index 1039bed0a..b1ba07eb1 100644 --- a/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/replay/Messages.properties +++ b/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/replay/Messages.properties @@ -1,5 +1,5 @@ Replay.permission.description=Ability to perform a new Pipeline build with an edited script. ReplayCommand.shortDescription=Replay a Pipeline build with edited script taken from standard input -ReplayAction.displayName=Replay +ReplayAction.displayName=Rerun ReplayAction.rebuild.displayName=Rebuild ReplayCause.shortDescription=Replayed #{0} diff --git a/pom.xml b/pom.xml index d01c5259e..83896bb35 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ jenkinsci/${project.artifactId}-plugin 2.516 - 2.556 + 2.557-SNAPSHOT 2.4.21 false From 1e3392d753d73b7bfd6fc26be019afcddec6a9b4 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Thu, 26 Mar 2026 14:12:11 +0000 Subject: [PATCH 06/18] Push --- .../cps/replay/EditPipelineAndReplayAction.java | 10 +++++----- .../plugins/workflow/cps/replay/RebuildAction.java | 14 +++++++++----- .../plugins/workflow/cps/replay/ReplayAction.java | 8 +++++--- .../cps/replay/ReplayActionMenuContributor.java | 5 ++--- .../cps/replay/RestartFromStageAction.java | 14 +++++++++----- 5 files changed, 30 insertions(+), 21 deletions(-) diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java index 496bbcb84..819befcae 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java @@ -27,17 +27,17 @@ import hudson.Extension; import hudson.model.Action; import hudson.model.Run; -import org.jspecify.annotations.NonNull; - -import java.util.Collection; import java.util.List; +import java.util.Set; + +import org.jspecify.annotations.NonNull; @Extension public class EditPipelineAndReplayAction extends ReplayActionMenuContributor { @Override - public @NonNull Collection getActions(Run run) { - return List.of(new Action() { + public @NonNull Set getActions(Run run) { + return Set.of(new Action() { @Override public String getIconFileName() { return "symbol-arrow-redo-outline plugin-ionicons-api"; diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java index 23d6d2bd0..3b59c276c 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java @@ -26,19 +26,23 @@ import hudson.Extension; import hudson.model.Action; +import hudson.model.ParametersDefinitionProperty; import hudson.model.Run; -import org.jspecify.annotations.NonNull; +import java.util.Set; -import java.util.Collection; -import java.util.List; +import org.jspecify.annotations.NonNull; // TODO - To be moved to the right plugin @Extension public class RebuildAction extends ReplayActionMenuContributor { @Override - public @NonNull Collection getActions(Run run) { - return List.of(new Action() { + public @NonNull Set getActions(Run run) { + if (run.getParent().getProperty(ParametersDefinitionProperty.class) == null) { + return Set.of(); + } + + return Set.of(new Action() { @Override public String getIconFileName() { return "symbol-play-outline plugin-ionicons-api"; diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java index 93c2d8842..e0cc7e8bd 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java @@ -120,22 +120,24 @@ public String getUrlName() { return isEnabled() || isRebuildEnabled() ? "replay" : null; } + @Override public Group getGroup() { return Group.FIRST_IN_APP_BAR; } + @Override public Event getEvent() { String urlName = getUrlName(); // Allow for plugins to add additional build options - List actions = ReplayActionMenuContributor.all() - .stream() + List actions = ReplayActionMenuContributor.all().stream() .flatMap(e -> e.getActions(run).stream()) .toList(); - return SplitButtonEvent.of(LinkEvent.of(urlName, LinkEvent.LinkEventType.POST), actions); + return SplitButtonEvent.of(LinkEvent.of(urlName + "/run", LinkEvent.LinkEventType.POST), actions); } + @Override public Semantic getSemantic() { return Semantic.BUILD; } diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayActionMenuContributor.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayActionMenuContributor.java index 6f782fdf3..95dbb3899 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayActionMenuContributor.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayActionMenuContributor.java @@ -29,15 +29,14 @@ import hudson.ExtensionPoint; import hudson.model.Action; import hudson.model.Run; - -import java.util.Collection; +import java.util.Set; /** * Allows plugins to contribute additional entries to the {@link ReplayAction} split button. */ public abstract class ReplayActionMenuContributor implements ExtensionPoint { - public abstract @NonNull Collection getActions(Run run); + public abstract @NonNull Set getActions(Run run); public static @NonNull ExtensionList all() { return ExtensionList.lookup(ReplayActionMenuContributor.class); diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java index cc1d57903..a87920071 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java @@ -27,18 +27,22 @@ import hudson.Extension; import hudson.model.Action; import hudson.model.Run; -import org.jspecify.annotations.NonNull; +import java.util.Set; -import java.util.Collection; -import java.util.List; +import org.jspecify.annotations.NonNull; // TODO - To be moved to the right plugin @Extension public class RestartFromStageAction extends ReplayActionMenuContributor { @Override - public @NonNull Collection getActions(Run run) { - return List.of(new Action() { + public @NonNull Set getActions(Run run) { +// RestartDeclarativePipelineAction action = run.getAction(RestartDeclarativePipelineAction.class); +// if (action == null) { +// return Set.of(); +// } + + return Set.of(new Action() { @Override public String getIconFileName() { return "symbol-refresh-outline plugin-ionicons-api"; From be9c3888461592b9522c92245c520edd912808b8 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Thu, 26 Mar 2026 14:53:33 +0000 Subject: [PATCH 07/18] Working replay --- .../replay/EditPipelineAndReplayAction.java | 2 +- .../workflow/cps/replay/ReplayAction.java | 10 ++++--- .../workflow/cps/replay/Messages.properties | 2 +- plugin/src/main/webapp/js/replay.js | 27 +++++++++++++++++++ 4 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 plugin/src/main/webapp/js/replay.js diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java index 819befcae..641b0dd95 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java @@ -45,7 +45,7 @@ public String getIconFileName() { @Override public String getDisplayName() { - return "Replay"; + return "Edit and replay"; } @Override diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java index e0cc7e8bd..800a2fc5f 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java @@ -68,7 +68,7 @@ import jenkins.model.menu.Group; import jenkins.model.menu.Semantic; import jenkins.model.menu.event.Event; -import jenkins.model.menu.event.LinkEvent; +import jenkins.model.menu.event.JavaScriptEvent; import jenkins.model.menu.event.SplitButtonEvent; import jenkins.scm.api.SCMRevisionAction; import net.sf.json.JSON; @@ -127,14 +127,18 @@ public Group getGroup() { @Override public Event getEvent() { - String urlName = getUrlName(); + String urlName = getUrlName() + "/rebuild"; + + JavaScriptEvent primaryEvent = JavaScriptEvent.of(Map.of("type", "replay", "href", urlName, + "buildSuccess", "Build scheduled", "buildFailure", "Failed to schedule build. Reload the page and try again."), + "plugin/workflow-cps/js/replay.js"); // Allow for plugins to add additional build options List actions = ReplayActionMenuContributor.all().stream() .flatMap(e -> e.getActions(run).stream()) .toList(); - return SplitButtonEvent.of(LinkEvent.of(urlName + "/run", LinkEvent.LinkEventType.POST), actions); + return SplitButtonEvent.of(primaryEvent, actions); } @Override diff --git a/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/replay/Messages.properties b/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/replay/Messages.properties index b1ba07eb1..1039bed0a 100644 --- a/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/replay/Messages.properties +++ b/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/replay/Messages.properties @@ -1,5 +1,5 @@ Replay.permission.description=Ability to perform a new Pipeline build with an edited script. ReplayCommand.shortDescription=Replay a Pipeline build with edited script taken from standard input -ReplayAction.displayName=Rerun +ReplayAction.displayName=Replay ReplayAction.rebuild.displayName=Rebuild ReplayCause.shortDescription=Replayed #{0} diff --git a/plugin/src/main/webapp/js/replay.js b/plugin/src/main/webapp/js/replay.js new file mode 100644 index 000000000..033a44fac --- /dev/null +++ b/plugin/src/main/webapp/js/replay.js @@ -0,0 +1,27 @@ +/** + * Attaches click behavior to "Replay" buttons to trigger a POST + * request and show a success or error notification. + */ +Behaviour.specify( + "button[data-type='replay']", + "button-replay", + 999, + (button) => { + button.addEventListener("click", function (event) { + let success = button.dataset.buildSuccess; + let failure = button.dataset.buildFailure; + + fetch(button.dataset.baseUrl + button.dataset.href, { + method: "post", + headers: crumb.wrap({}), + }).then((rsp) => { + if (rsp.status === 200) { + notificationBar.show(success, notificationBar.SUCCESS); + } else { + notificationBar.show(failure, notificationBar.ERROR); + } + }); + event.preventDefault(); + }); + }, +); From fc07a7de7b1847825dae33b3d400576e38855fb2 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Thu, 26 Mar 2026 14:53:57 +0000 Subject: [PATCH 08/18] Spotless --- .../cps/replay/EditPipelineAndReplayAction.java | 2 -- .../plugins/workflow/cps/replay/RebuildAction.java | 1 - .../plugins/workflow/cps/replay/ReplayAction.java | 12 ++++++++++-- .../workflow/cps/replay/RestartFromStageAction.java | 9 ++++----- 4 files changed, 14 insertions(+), 10 deletions(-) diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java index 641b0dd95..7f0040697 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java @@ -27,9 +27,7 @@ import hudson.Extension; import hudson.model.Action; import hudson.model.Run; -import java.util.List; import java.util.Set; - import org.jspecify.annotations.NonNull; @Extension diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java index 3b59c276c..32f3777b3 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java @@ -29,7 +29,6 @@ import hudson.model.ParametersDefinitionProperty; import hudson.model.Run; import java.util.Set; - import org.jspecify.annotations.NonNull; // TODO - To be moved to the right plugin diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java index 800a2fc5f..ee914d46b 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java @@ -129,8 +129,16 @@ public Group getGroup() { public Event getEvent() { String urlName = getUrlName() + "/rebuild"; - JavaScriptEvent primaryEvent = JavaScriptEvent.of(Map.of("type", "replay", "href", urlName, - "buildSuccess", "Build scheduled", "buildFailure", "Failed to schedule build. Reload the page and try again."), + JavaScriptEvent primaryEvent = JavaScriptEvent.of( + Map.of( + "type", + "replay", + "href", + urlName, + "buildSuccess", + "Build scheduled", + "buildFailure", + "Failed to schedule build. Reload the page and try again."), "plugin/workflow-cps/js/replay.js"); // Allow for plugins to add additional build options diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java index a87920071..a4fec6056 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java @@ -28,7 +28,6 @@ import hudson.model.Action; import hudson.model.Run; import java.util.Set; - import org.jspecify.annotations.NonNull; // TODO - To be moved to the right plugin @@ -37,10 +36,10 @@ public class RestartFromStageAction extends ReplayActionMenuContributor { @Override public @NonNull Set getActions(Run run) { -// RestartDeclarativePipelineAction action = run.getAction(RestartDeclarativePipelineAction.class); -// if (action == null) { -// return Set.of(); -// } + // RestartDeclarativePipelineAction action = run.getAction(RestartDeclarativePipelineAction.class); + // if (action == null) { + // return Set.of(); + // } return Set.of(new Action() { @Override From fb2608dd036b70b0675281ae79de4dad93c92b21 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Sun, 10 May 2026 17:57:13 +0100 Subject: [PATCH 09/18] Update pom.xml --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 83896bb35..e9dd86674 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ jenkinsci/${project.artifactId}-plugin 2.516 - 2.557-SNAPSHOT + 2.564 2.4.21 false From 880893d3d6352bf76f9c0659474fc05af6babb1d Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Sun, 10 May 2026 19:01:16 +0100 Subject: [PATCH 10/18] Push --- plugin/pom.xml | 2 +- pom.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/plugin/pom.xml b/plugin/pom.xml index 35a6ee33a..844e705c7 100644 --- a/plugin/pom.xml +++ b/plugin/pom.xml @@ -56,7 +56,7 @@ io.jenkins.tools.bom bom-${jenkins.baseline}.x - 5294.va_d2e144c80e1 + 6421.v4a_efb_4b_3a_61d pom import diff --git a/pom.xml b/pom.xml index e9dd86674..55cb9d9da 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jenkins-ci.plugins plugin - 6.2138.v03274d462c13 + 6.2153.vcf31911d10c4 org.jenkins-ci.plugins.workflow @@ -35,8 +35,8 @@ 999999-SNAPSHOT jenkinsci/${project.artifactId}-plugin - 2.516 - 2.564 + 2.555 + 2.564-SNAPSHOT 2.4.21 false From c5ee6fe02e9bd998d414760838cfe2026d1628b8 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Sun, 10 May 2026 19:02:08 +0100 Subject: [PATCH 11/18] Update pom.xml --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 55cb9d9da..828577ab9 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jenkins-ci.plugins plugin - 6.2153.vcf31911d10c4 + 6.2138.v03274d462c13 org.jenkins-ci.plugins.workflow From 02753b2160000b7da5a365b5e301ac22d7c8d4e6 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Fri, 5 Jun 2026 21:32:30 +0100 Subject: [PATCH 12/18] Remove test files --- .../workflow/cps/replay/RebuildAction.java | 66 ------------------- .../cps/replay/RestartFromStageAction.java | 66 ------------------- 2 files changed, 132 deletions(-) delete mode 100644 plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java delete mode 100644 plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java deleted file mode 100644 index 32f3777b3..000000000 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RebuildAction.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * The MIT License - * - * Copyright 2026, Jan Faracik - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package org.jenkinsci.plugins.workflow.cps.replay; - -import hudson.Extension; -import hudson.model.Action; -import hudson.model.ParametersDefinitionProperty; -import hudson.model.Run; -import java.util.Set; -import org.jspecify.annotations.NonNull; - -// TODO - To be moved to the right plugin -@Extension -public class RebuildAction extends ReplayActionMenuContributor { - - @Override - public @NonNull Set getActions(Run run) { - if (run.getParent().getProperty(ParametersDefinitionProperty.class) == null) { - return Set.of(); - } - - return Set.of(new Action() { - @Override - public String getIconFileName() { - return "symbol-play-outline plugin-ionicons-api"; - } - - @Override - public String getDisplayName() { - return "Rebuild"; - } - - @Override - public String getDescription() { - return "Edit parameters and rebuild"; - } - - @Override - public String getUrlName() { - return "rebuild/parameterized"; - } - }); - } -} diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java deleted file mode 100644 index a4fec6056..000000000 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/RestartFromStageAction.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * The MIT License - * - * Copyright 2026, Jan Faracik - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package org.jenkinsci.plugins.workflow.cps.replay; - -import hudson.Extension; -import hudson.model.Action; -import hudson.model.Run; -import java.util.Set; -import org.jspecify.annotations.NonNull; - -// TODO - To be moved to the right plugin -@Extension -public class RestartFromStageAction extends ReplayActionMenuContributor { - - @Override - public @NonNull Set getActions(Run run) { - // RestartDeclarativePipelineAction action = run.getAction(RestartDeclarativePipelineAction.class); - // if (action == null) { - // return Set.of(); - // } - - return Set.of(new Action() { - @Override - public String getIconFileName() { - return "symbol-refresh-outline plugin-ionicons-api"; - } - - @Override - public String getDisplayName() { - return "Restart from Stage"; - } - - @Override - public String getDescription() { - return "Restart Pipeline from a specific Stage"; - } - - @Override - public String getUrlName() { - return "restart"; - } - }); - } -} From 14c5ae7bf4394fe8cc806955689ac85de32184d9 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Fri, 5 Jun 2026 21:37:00 +0100 Subject: [PATCH 13/18] I18n --- .../workflow/cps/replay/EditPipelineAndReplayAction.java | 4 ++-- .../jenkinsci/plugins/workflow/cps/replay/ReplayAction.java | 4 ++-- .../jenkinsci/plugins/workflow/cps/replay/Messages.properties | 4 ++++ 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java index 7f0040697..4641570d4 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/EditPipelineAndReplayAction.java @@ -43,12 +43,12 @@ public String getIconFileName() { @Override public String getDisplayName() { - return "Edit and replay"; + return Messages.EditPipelineAndReplayAction_displayName(); } @Override public String getDescription() { - return "Edit Pipeline and replay"; + return Messages.EditPipelineAndReplayAction_description(); } @Override diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java index ded75f8b1..823a74499 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java @@ -136,9 +136,9 @@ public Event getEvent() { "href", urlName, "buildSuccess", - "Build scheduled", + Messages.ReplayAction_buildSuccess(), "buildFailure", - "Failed to schedule build. Reload the page and try again."), + Messages.ReplayAction_buildFailure()), "plugin/workflow-cps/js/replay.js"); // Allow for plugins to add additional build options diff --git a/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/replay/Messages.properties b/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/replay/Messages.properties index 6b4c6d0fc..fb10bcc02 100644 --- a/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/replay/Messages.properties +++ b/plugin/src/main/resources/org/jenkinsci/plugins/workflow/cps/replay/Messages.properties @@ -2,5 +2,9 @@ Replay.permission.description=Ability to perform a new Pipeline build with an ed ReplayCommand.shortDescription=Replay a Pipeline build with edited script taken from standard input ReplayAction.displayName=Replay ReplayAction.rebuild.displayName=Rebuild +ReplayAction.buildSuccess=Build scheduled +ReplayAction.buildFailure=Failed to schedule build. Reload the page and try again. +EditPipelineAndReplayAction.displayName=Edit and replay +EditPipelineAndReplayAction.description=Edit Pipeline and replay ReplayCause.shortDescription=Replayed #{0} ReplayCause.rebuild.shortDescription=Rebuilt #{0} From 49a1b99eba3b37c3c29a44f1fdd44154d01fedb8 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Fri, 5 Jun 2026 21:40:59 +0100 Subject: [PATCH 14/18] Update pom.xml --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index bd6c3e179..2e3e2059f 100644 --- a/pom.xml +++ b/pom.xml @@ -36,7 +36,7 @@ jenkinsci/${project.artifactId}-plugin 2.555 - 2.564-SNAPSHOT + 2.566 2.4.21 false From 4a14625e01132f77cc6cc4c9f21105c313721968 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Fri, 5 Jun 2026 22:18:09 +0100 Subject: [PATCH 15/18] Update pom.xml --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 2e3e2059f..004d0898d 100644 --- a/pom.xml +++ b/pom.xml @@ -37,6 +37,8 @@ 2.555 2.566 + + 21 2.4.21 false From 746b86a61a7de7f8b8f53e0cf2b9321cb5a8c3e9 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Fri, 5 Jun 2026 22:19:50 +0100 Subject: [PATCH 16/18] Update replay.js --- plugin/src/main/webapp/js/replay.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/src/main/webapp/js/replay.js b/plugin/src/main/webapp/js/replay.js index 033a44fac..c3b7db855 100644 --- a/plugin/src/main/webapp/js/replay.js +++ b/plugin/src/main/webapp/js/replay.js @@ -8,8 +8,8 @@ Behaviour.specify( 999, (button) => { button.addEventListener("click", function (event) { - let success = button.dataset.buildSuccess; - let failure = button.dataset.buildFailure; + const success = button.dataset.buildSuccess; + const failure = button.dataset.buildFailure; fetch(button.dataset.baseUrl + button.dataset.href, { method: "post", From 74c0966cd7366cb90f18584c8a254f2737535a8f Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Sat, 6 Jun 2026 16:48:52 +0100 Subject: [PATCH 17/18] Trigger Build From 96385ab82b9ecc53f5d2543d676c756691ce5d29 Mon Sep 17 00:00:00 2001 From: Jan Faracik <43062514+janfaracik@users.noreply.github.com> Date: Tue, 16 Jun 2026 21:23:14 +0100 Subject: [PATCH 18/18] Update ReplayAction.java --- .../jenkinsci/plugins/workflow/cps/replay/ReplayAction.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java index 823a74499..117d169df 100644 --- a/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java +++ b/plugin/src/main/java/org/jenkinsci/plugins/workflow/cps/replay/ReplayAction.java @@ -112,6 +112,10 @@ public String getDisplayName() { @Override public String getIconFileName() { + if (run.isBuilding()) { + return null; + } + return isEnabled() || isRebuildEnabled() ? "symbol-arrow-redo-outline plugin-ionicons-api" : null; } @@ -526,7 +530,6 @@ public Class type() { public Collection createFor(Run run) { return run instanceof FlowExecutionOwner.Executable && run.getParent() instanceof ParameterizedJobMixIn.ParameterizedJob - && !run.isBuilding() ? Collections.singleton(new ReplayAction(run)) : Collections.emptySet(); }