Skip to content

Commit 352f59e

Browse files
authored
Use the result of a WarningAction set on a stage node instead of computing the chunk status (#617)
1 parent 0ae6977 commit 352f59e

File tree

6 files changed

+105
-3
lines changed

6 files changed

+105
-3
lines changed

src/main/java/io/jenkins/plugins/pipelinegraphview/treescanner/NodeRelationship.java

+7
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@
55
import io.jenkins.plugins.pipelinegraphview.utils.BlueRun;
66
import io.jenkins.plugins.pipelinegraphview.utils.NodeRunStatus;
77
import io.jenkins.plugins.pipelinegraphview.utils.PipelineNodeUtil;
8+
import org.jenkinsci.plugins.workflow.actions.WarningAction;
89
import org.jenkinsci.plugins.workflow.graph.FlowNode;
910
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
11+
import org.jenkinsci.plugins.workflow.pipelinegraphanalysis.GenericStatus;
1012
import org.jenkinsci.plugins.workflow.pipelinegraphanalysis.StatusAndTiming;
1113
import org.jenkinsci.plugins.workflow.pipelinegraphanalysis.TimingInfo;
1214
import org.jenkinsci.plugins.workflow.support.actions.PauseAction;
@@ -108,6 +110,11 @@ public FlowNode getEnd() {
108110
return new NodeRunStatus(BlueRun.BlueRunResult.NOT_BUILT, BlueRun.BlueRunState.SKIPPED);
109111
} else if (PipelineNodeUtil.isPaused(this.end)) {
110112
return new NodeRunStatus(BlueRun.BlueRunResult.UNKNOWN, BlueRun.BlueRunState.PAUSED);
113+
} else if (PipelineNodeUtil.isStage(start)) {
114+
WarningAction warningAction = start.getPersistentAction(WarningAction.class);
115+
if (warningAction != null) {
116+
return new NodeRunStatus(GenericStatus.fromResult(warningAction.getResult()));
117+
}
111118
}
112119
if (isDebugEnabled) {
113120
logger.debug(

src/main/java/io/jenkins/plugins/pipelinegraphview/utils/legacy/PipelineNodeGraphVisitor.java

+7
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.jenkinsci.plugins.workflow.actions.LabelAction;
3232
import org.jenkinsci.plugins.workflow.actions.NotExecutedNodeAction;
3333
import org.jenkinsci.plugins.workflow.actions.TimingAction;
34+
import org.jenkinsci.plugins.workflow.actions.WarningAction;
3435
import org.jenkinsci.plugins.workflow.cps.nodes.StepAtomNode;
3536
import org.jenkinsci.plugins.workflow.cps.nodes.StepEndNode;
3637
import org.jenkinsci.plugins.workflow.cps.nodes.StepStartNode;
@@ -238,12 +239,18 @@ protected void handleChunkDone(@NonNull MemoryFlowChunk chunk) {
238239
} else if (firstExecuted == null) {
239240
status = new NodeRunStatus(GenericStatus.NOT_EXECUTED);
240241
} else if (chunk.getLastNode() != null) {
242+
WarningAction warningAction = chunk.getFirstNode().getPersistentAction(WarningAction.class);
243+
241244
// StatusAndTiming.computeChunkStatus2 seems to return wrong status for parallel
242245
// sequential
243246
// stages
244247
// so check check if active and in the case of nested sequential
245248
if (parallelNestedStages && chunk.getFirstNode().isActive()) {
246249
status = new NodeRunStatus(chunk.getFirstNode());
250+
} else if (PipelineNodeUtil.isStage(chunk.getFirstNode()) && warningAction != null) {
251+
// If the chunk is a stage and there's a WarningAction on the stage start node use the
252+
// associated result
253+
status = new NodeRunStatus(GenericStatus.fromResult(warningAction.getResult()));
247254
} else {
248255
FlowNode nodeBefore = chunk.getNodeBefore(),
249256
firstNode = chunk.getFirstNode(),

src/test/java/io/jenkins/plugins/pipelinegraphview/utils/PipelineGraphApiLegacyTest.java

+23
Original file line numberDiff line numberDiff line change
@@ -149,4 +149,27 @@ void createLegacyTree_skippedParallel(JenkinsRule j) throws Exception {
149149
(PipelineStage stage) -> String.format("{%s,%s}", stage.getName(), stage.getState()));
150150
assertThat(newStagesString, is(stagesString));
151151
}
152+
153+
@Issue("GH#616")
154+
@Test
155+
void createLegacyTree_stageResult(JenkinsRule j) throws Exception {
156+
WorkflowRun run = TestUtils.createAndRunJob(
157+
j, "gh616_stageResult", "gh616_stageResult.jenkinsfile", Result.UNSTABLE, false);
158+
PipelineGraphApi api = new PipelineGraphApi(run);
159+
PipelineGraph graph = api.createLegacyTree();
160+
161+
List<PipelineStage> stages = graph.getStages();
162+
163+
String stagesString = TestUtils.collectStagesAsString(
164+
stages,
165+
(PipelineStage stage) -> String.format(
166+
"{%s,%s,%s,%s}", stage.getName(), stage.getTitle(), stage.getType(), stage.getState()));
167+
assertThat(
168+
stagesString,
169+
is(String.join(
170+
"",
171+
"{success-stage,success-stage,STAGE,success},",
172+
"{failure-stage,failure-stage,STAGE,failure},",
173+
"{unstable-stage,unstable-stage,STAGE,unstable}")));
174+
}
152175
}

src/test/java/io/jenkins/plugins/pipelinegraphview/utils/PipelineGraphApiTest.java

+23
Original file line numberDiff line numberDiff line change
@@ -476,4 +476,27 @@ void getAgentForParallelPipelineWithExternalAgent() throws Exception {
476476
assertThat(externalStage.getName(), equalTo("External"));
477477
assertThat(externalStage.getAgent(), equalTo(agent.getNodeName()));
478478
}
479+
480+
@Issue("GH#616")
481+
@Test
482+
void createTree_stageResult() throws Exception {
483+
WorkflowRun run =
484+
TestUtils.createAndRunJob(j, "stageResult", "gh616_stageResult.jenkinsfile", Result.UNSTABLE, false);
485+
PipelineGraphApi api = new PipelineGraphApi(run);
486+
PipelineGraph graph = api.createTree();
487+
488+
List<PipelineStage> stages = graph.getStages();
489+
490+
String stagesString = TestUtils.collectStagesAsString(
491+
stages,
492+
(PipelineStage stage) -> String.format(
493+
"{%s,%s,%s,%s}", stage.getName(), stage.getTitle(), stage.getType(), stage.getState()));
494+
assertThat(
495+
stagesString,
496+
equalTo(String.join(
497+
"",
498+
"{success-stage,success-stage,STAGE,success},",
499+
"{failure-stage,failure-stage,STAGE,failure},",
500+
"{unstable-stage,unstable-stage,STAGE,unstable}")));
501+
}
479502
}

src/test/java/io/jenkins/plugins/pipelinegraphview/utils/TestUtils.java

+19-3
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,39 @@ public class TestUtils {
2626

2727
public static WorkflowRun createAndRunJob(
2828
JenkinsRule jenkins, String jobName, String jenkinsFileName, Result expectedResult) throws Exception {
29-
WorkflowJob job = TestUtils.createJob(jenkins, jobName, jenkinsFileName);
29+
return createAndRunJob(jenkins, jobName, jenkinsFileName, expectedResult, true);
30+
}
31+
32+
public static WorkflowRun createAndRunJob(
33+
JenkinsRule jenkins, String jobName, String jenkinsFileName, Result expectedResult, boolean sandbox)
34+
throws Exception {
35+
WorkflowJob job = TestUtils.createJob(jenkins, jobName, jenkinsFileName, sandbox);
3036
jenkins.assertBuildStatus(expectedResult, job.scheduleBuild2(0));
3137
return job.getLastBuild();
3238
}
3339

3440
public static QueueTaskFuture<WorkflowRun> createAndRunJobNoWait(
3541
JenkinsRule jenkins, String jobName, String jenkinsFileName) throws Exception {
36-
WorkflowJob job = TestUtils.createJob(jenkins, jobName, jenkinsFileName);
42+
return createAndRunJobNoWait(jenkins, jobName, jenkinsFileName, true);
43+
}
44+
45+
public static QueueTaskFuture<WorkflowRun> createAndRunJobNoWait(
46+
JenkinsRule jenkins, String jobName, String jenkinsFileName, boolean sandbox) throws Exception {
47+
WorkflowJob job = TestUtils.createJob(jenkins, jobName, jenkinsFileName, sandbox);
3748
return job.scheduleBuild2(0);
3849
}
3950

4051
public static WorkflowJob createJob(JenkinsRule jenkins, String jobName, String jenkinsFileName) throws Exception {
52+
return createJob(jenkins, jobName, jenkinsFileName, true);
53+
}
54+
55+
public static WorkflowJob createJob(JenkinsRule jenkins, String jobName, String jenkinsFileName, boolean sandbox)
56+
throws Exception {
4157
WorkflowJob job = jenkins.createProject(WorkflowJob.class, jobName);
4258

4359
URL resource = Resources.getResource(TestUtils.class, jenkinsFileName);
4460
String jenkinsFile = Resources.toString(resource, Charsets.UTF_8);
45-
job.setDefinition(new CpsFlowDefinition(jenkinsFile, true));
61+
job.setDefinition(new CpsFlowDefinition(jenkinsFile, sandbox));
4662
return job;
4763
}
4864

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import hudson.model.Result
2+
import io.jenkins.plugins.pipelinegraphview.utils.PipelineNodeUtil
3+
import org.jenkinsci.plugins.workflow.actions.WarningAction
4+
import org.jenkinsci.plugins.workflow.graph.FlowNode
5+
6+
void setStageResult(Result result) {
7+
FlowNode stageNode = getContext(FlowNode.class).getEnclosingBlocks().find { PipelineNodeUtil.isStage(it) }
8+
if (stageNode) {
9+
stageNode.addOrReplaceAction(new WarningAction(result));
10+
}
11+
}
12+
13+
stage("success-stage") {
14+
unstable("unstable-step")
15+
setStageResult(Result.SUCCESS)
16+
}
17+
18+
stage("failure-stage") {
19+
echo("foo")
20+
setStageResult(Result.FAILURE)
21+
}
22+
23+
stage("unstable-stage") {
24+
echo("foo")
25+
setStageResult(Result.UNSTABLE)
26+
}

0 commit comments

Comments
 (0)