Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-44930

Allow sh to return exit status, stdout and stderr all at once

    XMLWordPrintable

Details

    Description

      Like many of the commenters on -JENKINS-26133- I'd like to be able to capture the exit status and text written to standard out at the same time.

      My current use case is calling git merge --no-edit $branches and if there was an error sending a slack notification with the output. 

      The current workaround is:

      def status = sh(returnStatus: true, script: "git merge --no-edit $branches > merge_output.txt")
      if (status != 0) {
        currentBuild.result = 'FAILED'
        def output = readFile('merge_output.txt').trim()
        slackSend channel: SLACK_CHANNEL, message: "<${env.JOB_URL}|${env.JOB_NAME}> ran into an error merging the PR branches into the ${TARGET_BRANCH} branch:\n```\n${output}\n```\n<${env.BUILD_URL}/console|See the full output>", color: 'warning', tokenCredentialId: 'slack-token'
        error 'Merge conflict'
      }
      sh 'rm merge_output.txt'

      Which works but isn't a great developer experience... It would be great if I could request an object that contained: status, stdout, and stderr.

      Attachments

        Issue Links

          Activity

            evilezh Haralds added a comment - - edited

             

            Hi everyone, I've idea how to improve on this. Here is exact plan:

            https://github.com/jenkinsci/workflow-durable-task-step-plugin/blob/2a88fdd885caa0d1bcf3336efc00b579b75ced82/src/main/java/org/jenkinsci/plugins/workflow/steps/durable_task/DurableTaskStep.java#L648

             

            if ((returnStatus && originalCause == null) || exitCode == 0) {  
            

             

            change to something like (in case when both stdout and status code are enabled): 

             

            if ((returnStatus && originalCause == null) || exitCode == 0 || (returnStatus && originalCause == null && returnStdout ) ) {
            

             

            Then in case if both are enabled then we will need extra if  like:

             

            if (returnStdOut && returnStatus) {
              getContext().onSuccess(["status":exitCode, "output": new String(output.produce(), StandardCharsets.UTF_8)]);
            else {
               getContext().onSuccess(returnStatus ? exitCode : returnStdout ? new String(output.produce(), StandardCharsets.UTF_8) : null);
            }  

             

            That would maintain compatibility with previous code. Also would need to update (or remove) https://github.com/jenkinsci/workflow-durable-task-step-plugin/blob/2a88fdd885caa0d1bcf3336efc00b579b75ced82/src/main/java/org/jenkinsci/plugins/workflow/steps/durable_task/DurableTaskStep.java#L168 to allow both parameters in same time.

             

            evilezh Haralds added a comment - - edited   Hi everyone, I've idea how to improve on this. Here is exact plan: https://github.com/jenkinsci/workflow-durable-task-step-plugin/blob/2a88fdd885caa0d1bcf3336efc00b579b75ced82/src/main/java/org/jenkinsci/plugins/workflow/steps/durable_task/DurableTaskStep.java#L648   if ((returnStatus && originalCause == null ) || exitCode == 0) {     change to something like (in case when both stdout and status code are enabled):    if ((returnStatus && originalCause == null ) || exitCode == 0 || (returnStatus && originalCause == null && returnStdout ) ) {   Then in case if both are enabled then we will need extra if  like:   if (returnStdOut && returnStatus) { getContext().onSuccess([ "status" :exitCode, "output" : new String (output.produce(), StandardCharsets.UTF_8)]); else { getContext().onSuccess(returnStatus ? exitCode : returnStdout ? new String (output.produce(), StandardCharsets.UTF_8) : null ); }   That would maintain compatibility with previous code. Also would need to update (or remove)  https://github.com/jenkinsci/workflow-durable-task-step-plugin/blob/2a88fdd885caa0d1bcf3336efc00b579b75ced82/src/main/java/org/jenkinsci/plugins/workflow/steps/durable_task/DurableTaskStep.java#L168  to allow both parameters in same time.  
            mcwarg m added a comment -

            I have a similar issue, except it's with bat calls. Is there a similar ticket for this or should it be handled here too?

            mcwarg m added a comment - I have a similar issue, except it's with bat calls. Is there a similar ticket for this or should it be handled here too?
            ianboudreaux Ian Boudreaux added a comment -

            It would be great if Jenkins supported similar functionality for powershell as well.

            ianboudreaux Ian Boudreaux added a comment - It would be great if Jenkins supported similar functionality for powershell as well.

            shadycuz instead of developing a curl wrapper, you can use the HTTP Request plugin. It already returns the HTTP status code and the content in a single call.

            deepchip Martin d'Anjou added a comment - shadycuz  instead of developing a curl wrapper, you can use the HTTP Request  plugin. It already returns the HTTP status code and the content in a single call.
            shadycuz Levi Blaney added a comment - - edited

            deepchip I see a lot of teams struggle with plugins for whatever reason. My library uses a groovy native implementation based on pythons requests library. You can see the docs here https://javadoc.io/doc/io.github.dontshavetheyak/jenkins-std-lib/latest/org/dsty/http/Requests.html

            shadycuz Levi Blaney added a comment - - edited deepchip I see a lot of teams struggle with plugins for whatever reason. My library uses a groovy native implementation based on pythons requests library. You can see the docs here https://javadoc.io/doc/io.github.dontshavetheyak/jenkins-std-lib/latest/org/dsty/http/Requests.html

            People

              Unassigned Unassigned
              drewish andrew morton
              Votes:
              157 Vote for this issue
              Watchers:
              134 Start watching this issue

              Dates

                Created:
                Updated: