Calling sh step from plugin

Hi! I’m writing a pipeline step plugin which should be able to use sh/bat step inside. The question is how to call pipeline step inside plugin?

To do so, I’ve found source code of Durable Task Step plugin: GitHub - jenkinsci/workflow-durable-task-step-plugin and started to research how it works.
I’ve tried to initialize bat step, receive executor and just start it, using context that I’ve received to my build step. Here is my code:

String script = "dir";
BatchScriptStep batchScriptStep = new BatchScriptStep(script);
StepExecution batStepExecution = batchScriptStep.start(context);

if (batStepExecution.start()) {
  Logger.log("Synchronously finished execution of the step");
} else {
  Logger.log("Asynchronously execution of the step started");
}
// Some other code

In this case other code starts to execute when bat step has not finished yet.
To be sure that bat step has been finished I had to do the following hack:

private static final String UNFINISHED_TASK_MARKER = " done? false";

if (batStepExecution.start()) {
  Logger.log("Synchronously finished execution of the step");
} else {
  Logger.log("Asynchronously execution of the step started");
  String status;
  while ((status = batStepExecution.getStatus()) != null && status.contains(UNFINISHED_TASK_MARKER)) {
    Logger.log("Waiting to finish the execution of the step. Status: " + batStepExecution.getStatus());
    Thread.sleep(50);
  }
}
// Some other code

But in this case I still have no any possibility to get command’s exit code.

I know that Jenkins architecture is not developed to call pipeline steps from another step but still. Is it possible to execute such steps without loosing any functionality, waiting for step to finish and obtain output of step? If it is not possible to do in traditional way, can I do so, using Java reflections? Where I obtain the step result? And where I can find source code of how pipeline actually checks if step finished with non-zero exit code?

1 Like

Otherwise, I also prefere Jenkins-way to solve this task, but it will take much time to implement. May be I need to write own logic how to execute sh/bat without trying to execute existing steps. If so, where I can find a documentation how to correctly implement sh/bat step functionality? I mean running command on current node (not master instance), capturing console output, correctly handle cases when Jenkins is restarted/job aborted, correctly execute when node is actually a container (when Kubernetes plugin is used)?

1 Like

Hello! I also have the same problem, I’ve been looking for a solution for a long time but haven’t found it. Does anyone have a solution?

1 Like

Why would you want to? You can use launcher/process directly, why would you want to use the complicated wrapper?

@halkeye My main goal is to write complex plugin that should be a build step. During this build step a lot of things should be performed. For example parsing YAML, calling commands on node, calling remote commands (SSH Pipeline Steps), manipulating with artifacts, etc. So if I will implement all functionality myself, it would take a lot of time to implement each Jenkins step that I need to use. I don’t want to implement all steps myself because their code is already written for me, tested for years and has much less bugs than if I wrote it myself. From my point of view it is doublework.

If functionality that I want could be implemented using launcher/process, could you please help me to find some examples of code or documentation to help me understand how it can be implemented?