@Restricted(NoExternalUse.class) @RequirePOST public HttpResponse doRestartPipeline(@QueryParameter String stageName) { Map<String, String> result = new HashMap<>(); result.put("success", "false"); if (isRestartEnabled()) { try { run(stageName); result.put("success", "true"); result.put("message", "ok"); } catch (IllegalStateException ise) { result.put("message", "Failure restarting from stage: " + ise); } } else { result.put("message", "not allowed to restart"); } return HttpResponses.okJSON(result); }
@Restricted(DoNotUse.class) @RequirePOST public void doRestart(StaplerRequest req, StaplerResponse rsp) throws ServletException, IOException { if (!isRestartEnabled()) { throw new AccessDeniedException("not allowed to restart"); // AccessDeniedException2 requires us to look up the specific Permission } JSONObject form = req.getSubmittedForm(); String stageName = Util.fixEmpty(form.getString("stageName")); try { run(stageName); } catch (IllegalStateException ise) { throw new Failure("Failure restarting from stage: " + ise); } rsp.sendRedirect("../.."); // back to WorkflowJob; new build might not start instantly so cannot redirect to it }
@Override protected int run() throws Exception { Run<?,?> run = number <= 0 ? job.getLastBuild() : job.getBuildByNumber(number); if (run == null) { throw new AbortException("No such build"); } RestartDeclarativePipelineAction action = run.getAction(RestartDeclarativePipelineAction.class); if (action == null) { throw new AbortException("Not a Declarative Pipeline build"); } if (!action.isRestartEnabled()) { throw new AbortException("Not authorized to restart builds of this job"); } if (!action.getRestartableStages().contains(stage)) { throw new AbortException("Stage " + stage + " either does not exist in the build, or did not run in the build, and so cannot be restarted."); } action.run(stage); return 0; }
@Issue("JENKINS-45455") @Test public void emptyStageName() throws Exception { WorkflowRun original = expect(Result.FAILURE, "restart", "simpleRestart") .logContains("Odd numbered build, failing", "This shouldn't show up on second run") .go(); RestartDeclarativePipelineAction action = original.getAction(RestartDeclarativePipelineAction.class); assertNotNull(action); assertTrue(action.isRestartEnabled()); Exception runFailure = null; try { Queue.Item queueItem = action.run(""); // Because we should definitely have thrown an exception in run. assertNull(queueItem); } catch (Exception e) { runFailure = e; } assertNotNull(runFailure); assertTrue(runFailure instanceof IllegalStateException); assertEquals(Messages.RestartDeclarativePipelineAction_NullStageName(), runFailure.getMessage()); }
@Issue("JENKINS-45455") @Test public void nullStageName() throws Exception { WorkflowRun original = expect(Result.FAILURE, "restart", "simpleRestart") .logContains("Odd numbered build, failing", "This shouldn't show up on second run") .go(); RestartDeclarativePipelineAction action = original.getAction(RestartDeclarativePipelineAction.class); assertNotNull(action); assertTrue(action.isRestartEnabled()); Exception runFailure = null; try { Queue.Item queueItem = action.run(null); // Because we should definitely have thrown an exception in run. assertNull(queueItem); } catch (Exception e) { runFailure = e; } assertNotNull(runFailure); assertTrue(runFailure instanceof IllegalStateException); assertEquals(Messages.RestartDeclarativePipelineAction_NullStageName(), runFailure.getMessage()); }
@Issue("JENKINS-45455") @Test public void notPresentStageName() throws Exception { WorkflowRun original = expect(Result.FAILURE, "restart", "simpleRestart") .logContains("Odd numbered build, failing", "This shouldn't show up on second run") .go(); RestartDeclarativePipelineAction action = original.getAction(RestartDeclarativePipelineAction.class); assertNotNull(action); assertTrue(action.isRestartEnabled()); Exception runFailure = null; try { Queue.Item queueItem = action.run("not-present"); // Because we should definitely have thrown an exception in run. assertNull(queueItem); } catch (Exception e) { runFailure = e; } assertNotNull(runFailure); assertTrue(runFailure instanceof IllegalStateException); assertEquals(Messages.RestartDeclarativePipelineAction_StageNameNotPresent("not-present", original.getFullDisplayName()), runFailure.getMessage()); }
@Issue("JENKINS-45455") @Test public void projectNotBuildable() throws Exception { WorkflowRun original = expect(Result.FAILURE, "restart", "simpleRestart") .logContains("Odd numbered build, failing", "This shouldn't show up on second run") .go(); RestartDeclarativePipelineAction action = original.getAction(RestartDeclarativePipelineAction.class); assertNotNull(action); assertTrue(action.isRestartEnabled()); WorkflowJob p = original.getParent(); p.setDisabled(true); Exception runFailure = null; try { Queue.Item queueItem = action.run("restart"); // Because we should definitely have thrown an exception in run. assertNull(queueItem); } catch (Exception e) { runFailure = e; } assertNotNull(runFailure); assertTrue(runFailure instanceof IllegalStateException); assertEquals(Messages.RestartDeclarativePipelineAction_ProjectNotBuildable(p.getFullName()), runFailure.getMessage()); }
Queue.Item queueItem = action.run("after");