Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JENKINS-70808] Fix isRestartable by only checking against the curren… #2416

Merged
merged 4 commits into from
Mar 17, 2023
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,16 @@
import io.jenkins.blueocean.service.embedded.rest.QueueUtil;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.jenkinsci.plugins.pipeline.StageStatus;
import org.jenkinsci.plugins.pipeline.modeldefinition.Utils;
import org.jenkinsci.plugins.pipeline.modeldefinition.actions.ExecutionModelAction;
import org.jenkinsci.plugins.pipeline.modeldefinition.actions.RestartDeclarativePipelineAction;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStage;
import org.jenkinsci.plugins.pipeline.modeldefinition.ast.ModelASTStages;
import org.jenkinsci.plugins.workflow.actions.LogAction;
import org.jenkinsci.plugins.workflow.cps.CpsFlowExecution;
import org.jenkinsci.plugins.workflow.flow.FlowExecution;
import org.jenkinsci.plugins.workflow.flow.FlowExecutionOwner;
import org.jenkinsci.plugins.workflow.graph.FlowNode;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
Expand Down Expand Up @@ -57,6 +65,7 @@ public class PipelineNodeImpl extends BluePipelineNode {
private final Link self;
private final String runExternalizableId;
private final Reachable parent;
private final boolean restartable;
public static final int waitJobInqueueTimeout = Integer.getInteger("blueocean.wait.job.inqueue", 1000);

public PipelineNodeImpl(FlowNodeWrapper node, Reachable parent, WorkflowRun run) {
Expand All @@ -67,6 +76,16 @@ public PipelineNodeImpl(FlowNodeWrapper node, Reachable parent, WorkflowRun run)
this.durationInMillis = node.getTiming().getTotalDurationMillis();
this.self = parent.getLink().rel(node.getId());
this.parent = parent;
/*
* PipelineNodeImpl are created as long as the build is not finished. And 'isRestartable' will be systematically
* called after this is created. So we can store whether the stage is restartable or no here.
*/
if(this.getStateObj() == BlueRun.BlueRunState.FINISHED) {
RestartDeclarativePipelineAction restartDeclarativePipelineAction = run.getAction(RestartDeclarativePipelineAction.class);
restartable = restartDeclarativePipelineAction != null && isRestartable(this.getDisplayName());
} else {
restartable = false;
}
}

@Override
Expand Down Expand Up @@ -183,13 +202,43 @@ private WorkflowRun getRun() {

@Override
public boolean isRestartable() {
RestartDeclarativePipelineAction restartDeclarativePipelineAction =
getRun().getAction( RestartDeclarativePipelineAction.class );
if (restartDeclarativePipelineAction != null) {
List<String> restartableStages = restartDeclarativePipelineAction.getRestartableStages();
if (restartableStages != null) {
return restartableStages.contains(this.getDisplayName())
&& this.getStateObj() == BlueRun.BlueRunState.FINISHED;
return restartable;
}

/**
* @return the Pipeline execution
* @todo: This can be removed once https://github.com/jenkinsci/pipeline-model-definition-plugin/pull/596 is available.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

jenkinsci/pipeline-model-definition-plugin#596 can be picked up as an incremental build so long as this downstream PR is in draft.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

target branch is 1.25.5.x so we will not upgrade. sounds like a leftover of the master commit

*/
@edu.umd.cs.findbugs.annotations.CheckForNull
private CpsFlowExecution getExecution() {
FlowExecutionOwner owner = ((FlowExecutionOwner.Executable) getRun()).asFlowExecutionOwner();
if (owner == null) {
return null;
}
FlowExecution exec = owner.getOrNull();
return exec instanceof CpsFlowExecution ? (CpsFlowExecution) exec : null;
}

/**
* Returns whether a stage is restartable.
* @param stageName the stage name
* @return true is restartable, false otherwise
* @todo: This can be removed once https://github.com/jenkinsci/pipeline-model-definition-plugin/pull/596 is available.
*/
private boolean isRestartable(String stageName) {
FlowExecution execution = getExecution();
if (execution != null) {
ExecutionModelAction execAction = getRun().getAction(ExecutionModelAction.class);
if (execAction != null) {
ModelASTStages stages = execAction.getStages();
if (stages != null) {
for (ModelASTStage s : stages.getStages()) {
if(s.getName().equals(stageName)) {
return !Utils.stageHasStatusOf(s.getName(), execution,
StageStatus.getSkippedForFailure(), StageStatus.getSkippedForUnstable());
}
}
}
}
}
return false;
Expand Down