diff --git a/pom.xml b/pom.xml index b309b55..fb4ca6a 100644 --- a/pom.xml +++ b/pom.xml @@ -49,7 +49,12 @@ org.jenkins-ci.plugins.workflow workflow-step-api - 1.15 + 2.1-SNAPSHOT + + + org.jenkins-ci.plugins.workflow + workflow-step-api + 2.1-SNAPSHOT tests test diff --git a/src/main/java/org/jenkinsci/plugins/workflow/support/steps/StageStep.java b/src/main/java/org/jenkinsci/plugins/workflow/support/steps/StageStep.java index 9005fa1..e4ee0bd 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/support/steps/StageStep.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/support/steps/StageStep.java @@ -63,6 +63,10 @@ public DescriptorImpl() { return "Stage"; } + @Override public boolean takesImplicitBlockArgument() { + return true; + } + } } diff --git a/src/main/java/org/jenkinsci/plugins/workflow/support/steps/StageStepExecution.java b/src/main/java/org/jenkinsci/plugins/workflow/support/steps/StageStepExecution.java index 68cd25e..423b6f1 100644 --- a/src/main/java/org/jenkinsci/plugins/workflow/support/steps/StageStepExecution.java +++ b/src/main/java/org/jenkinsci/plugins/workflow/support/steps/StageStepExecution.java @@ -34,6 +34,7 @@ import org.jenkinsci.plugins.workflow.graph.FlowNode; import org.jenkinsci.plugins.workflow.graph.FlowStartNode; import org.jenkinsci.plugins.workflow.steps.AbstractStepExecutionImpl; +import org.jenkinsci.plugins.workflow.steps.BodyExecutionCallback; import org.jenkinsci.plugins.workflow.steps.FlowInterruptedException; import org.jenkinsci.plugins.workflow.steps.StepContext; import org.jenkinsci.plugins.workflow.steps.StepContextParameter; @@ -46,7 +47,6 @@ public class StageStepExecution extends AbstractStepExecutionImpl { @Inject(optional=true) private transient StageStep step; @StepContextParameter private transient Run run; @StepContextParameter private transient FlowNode node; - @StepContextParameter private transient TaskListener listener; // picked up by getRequiredContext private static final class StageActionImpl extends InvisibleAction implements StageAction { private final String stageName; @@ -60,6 +60,14 @@ private static final class StageActionImpl extends InvisibleAction implements St @Override public boolean start() throws Exception { + if (getContext().hasBody()) { // recommended mode + if (step.concurrency != null) { + throw new AbortException(Messages.StageStepExecution_concurrency_not_supported_in_block_mode()); + } + getContext().newBodyInvoker().withCallback(BodyExecutionCallback.wrap(getContext())).withDisplayName(step.name).start(); + return false; + } + getContext().get(TaskListener.class).getLogger().println(Messages.StageStepExecution_non_block_mode_deprecated()); if (isInsideParallel(node)) { throw new AbortException(Messages.StageStepExecution_the_stage_step_must_not_be_used_inside_a()); } diff --git a/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/StageStep/config.jelly b/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/StageStep/config.jelly index 9814281..fc8ccdb 100644 --- a/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/StageStep/config.jelly +++ b/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/StageStep/config.jelly @@ -28,7 +28,4 @@ THE SOFTWARE. - - - diff --git a/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/StageStep/help-concurrency.html b/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/StageStep/help-concurrency.html deleted file mode 100644 index f1b7b9d..0000000 --- a/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/StageStep/help-concurrency.html +++ /dev/null @@ -1,7 +0,0 @@ -

- Concurrency level. -

-

- A concurrency of one is useful to let you lock a singleton resource, such as deployment to a single target server. - Only one build will deploy at a given time: the newest which passed all previous stages -

diff --git a/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/StageStep/help.html b/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/StageStep/help.html index 9ba3016..764f52b 100644 --- a/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/StageStep/help.html +++ b/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/StageStep/help.html @@ -1,6 +1,5 @@
- By default, Pipeline builds can run concurrently. - The stage command lets you mark certain sections of a build as being constrained by limited concurrency. - Newer builds are always given priority when entering such a throttled stage; older builds will simply exit early if - they are preempted. + Creates a labeled block. +

+ An older, deprecated mode of this step did not take a block argument, and accepted a concurrency parameter.

diff --git a/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/stage/Messages.properties b/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/stage/Messages.properties index 38944d2..5137122 100644 --- a/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/stage/Messages.properties +++ b/src/main/resources/org/jenkinsci/plugins/workflow/support/steps/stage/Messages.properties @@ -1 +1,3 @@ StageStepExecution.the_stage_step_must_not_be_used_inside_a=The \u2018stage\u2019 step must not be used inside a \u2018parallel\u2019 block. +StageStepExecution.concurrency_not_supported_in_block_mode=The \u2018concurrency\u2019 parameter is not supported in block-mode \u2018stage\u2019; try \u2018lock\u2019 and/or \u2018milestone\u2019 steps instead +StageStepExecution.non_block_mode_deprecated=Using the \u2018stage\u2019 step without a block argument is deprecated diff --git a/src/test/java/org/jenkinsci/plugins/workflow/support/steps/StageStepConfigTest.java b/src/test/java/org/jenkinsci/plugins/workflow/support/steps/StageStepConfigTest.java deleted file mode 100644 index fca767a..0000000 --- a/src/test/java/org/jenkinsci/plugins/workflow/support/steps/StageStepConfigTest.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * The MIT License - * - * Copyright 2014 Jesse Glick. - * - * 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.support.steps; - -import org.jenkinsci.plugins.workflow.steps.StepConfigTester; -import org.junit.Test; -import static org.junit.Assert.*; -import org.junit.Rule; -import org.jvnet.hudson.test.JenkinsRule; - -public class StageStepConfigTest { - - @Rule public JenkinsRule r = new JenkinsRule(); - - @Test public void configRoundTrip() throws Exception { - StageStep s = new StepConfigTester(r).configRoundTrip(new StageStep("name")); - assertEquals("name", s.name); - assertEquals(null, s.concurrency); - s = new StageStep("name"); - s.concurrency = 1; - s = new StepConfigTester(r).configRoundTrip(s); - assertEquals("name", s.name); - assertEquals(Integer.valueOf(1), s.concurrency); - } - -} diff --git a/src/test/java/org/jenkinsci/plugins/workflow/support/steps/StageStepTest.java b/src/test/java/org/jenkinsci/plugins/workflow/support/steps/StageStepTest.java index f332ccd..6c82343 100644 --- a/src/test/java/org/jenkinsci/plugins/workflow/support/steps/StageStepTest.java +++ b/src/test/java/org/jenkinsci/plugins/workflow/support/steps/StageStepTest.java @@ -53,6 +53,20 @@ public class StageStepTest { StageStepExecution.clear(); } + @Issue("JENKINS-26107") + @Test public void blockMode() throws Exception { + story.addStep(new Statement() { + @Override public void evaluate() throws Throwable { + WorkflowJob p = story.j.jenkins.createProject(WorkflowJob.class, "p"); + p.setDefinition(new CpsFlowDefinition("stage('hello there') {echo 'yes I ran'}", true)); + WorkflowRun b = story.j.assertBuildStatusSuccess(p.scheduleBuild2(0)); + story.j.assertLogContains("hello there", b); + story.j.assertLogContains("yes I ran", b); + story.j.assertLogNotContains(Messages.StageStepExecution_non_block_mode_deprecated(), b); + } + }); + } + @Test public void basics() throws Exception { // Timeline (A has concurrency 2, B 1): // #1 o-A--------------B-----------------o @@ -118,6 +132,7 @@ public class StageStepTest { e2.waitForSuspension(); e3.waitForSuspension(); story.j.assertBuildStatus(Result.NOT_BUILT, story.j.waitForCompletion(b2)); + story.j.assertLogContains(Messages.StageStepExecution_non_block_mode_deprecated(), b2); InterruptedBuildAction iba = b2.getAction(InterruptedBuildAction.class); assertNotNull(iba); List causes = iba.getCauses(); @@ -148,6 +163,7 @@ public class StageStepTest { e1.waitForSuspension(); assertFalse(b1.isBuilding()); assertEquals(Result.SUCCESS, b1.getResult()); + story.j.assertLogContains(Messages.StageStepExecution_non_block_mode_deprecated(), b1); e3.waitForSuspension(); assertTrue(b3.isBuilding()); story.j.assertLogContains("done", b1); @@ -158,6 +174,7 @@ public class StageStepTest { assertFalse(b3.isBuilding()); assertEquals(Result.SUCCESS, b3.getResult()); story.j.assertLogContains("done", b3); + story.j.assertLogContains(Messages.StageStepExecution_non_block_mode_deprecated(), b3); } }); }