Search code examples
curljenkinsgroovyjenkins-pipeline

Curl request from command line and via Groovy script


I am facing an issue which i do not understand, I have written a simple groovy script that when called from the command line works as expected

#!/usr/bin/env groovy

def jsonParse(def json) {
  new groovy.json.JsonSlurperClassic().parseText(json)
}

def ticketNumbers = ["MYSTATS-2695", "MYSTATS-2694"]

 ArrayList<String> jiraLinks = new ArrayList<String>();

  for(int i =0; i < ticketNumbers.size(); i++) {
    def jira_json = "curl -o /dev/null -X GET -H Content-Type: application/json --cert-type PEM --key-type PEM -E /Users/Jenkins/.jenkins/workspace/certificates/cert.pem --key /Users/Jenkins/.jenkins/workspace/certificates/cert.pem https://jira.dev.org.co.uk:443/rest/api/2/issue/${ticketNumbers[i]}".execute().text;
    def json = jsonParse(jira_json);
    def summary = json['fields']['summary'].toString();
    jiraLinks.add("[" + ticketNumbers[i] + "](https://jira.dev.org.co.uk/browse/" + ticketNumbers[i] + ")" + " - " + summary);
  }

 println "${jiraLinks}"

so when i do groovy myscript.groovy

This will print out

[[MYSTATS-2695 ](https://jira.dev.org.co.uk/browse/MYSTATS-2695 ) - Jenkins build pipeline should ignore draft and pre-releases, [MYSTATS-2694 ](https://jira.dev.org.co.uk/browse/MYSTATS-2694 ) - Android Jenkins pipeline should populate the comscore SDK version automatically]

So that is as expected.

What i then have is a groovy script which i call as part of a jenkins pipeline build

class Helpers {

   def jsonParse(def json) {
     new groovy.json.JsonSlurperClassic().parseText(json)
   }

  def createJiraLinks(def ticketNumbers) {

    ArrayList<String> jiraLinks = new ArrayList<String>();
    for(int i =0; i < ticketNumbers.size(); i++) {
      def jira_json = "/usr/bin/curl -o /dev/null -X GET -H Content-Type: application/json --cert-type PEM --key-type PEM -E /Users/Jenkins/.jenkins/workspace/certificates/cert.pem --key /Users/Jenkins/.jenkins/workspace/certificates/cert.pem https://jira.dev.org.co.uk:443/rest/api/2/issue/MYSTATS-2695".execute().text;
      def json = jsonParse(jira_json);
      def summary = json['fields']['summary'].toString();
    jiraLinks.add("[" + ticketNumbers[i] + "](https://jira.dev.org.co.uk/browse/" + ticketNumbers[i] + ")" + " - " + summary);
    }
    return jiraLinks;
  }

}
return new Helpers();

As part of my Jenkins build i have

def groovyMethod = load("${env.WORKSPACE}/groovy_scripts/release_pipeline.groovy")
def jira = groovyMethod.createJiraLinks(ticketNumberCommits);
echo "JIRA LINKAS ARE $jira"
// $jira is always returned as empty string

Am i misunderstanding anything here as i would have expected this to work? but it seems as if the curl request never gets anything back

Thanks


Solution

  • groovy String.execute() returns Process that could be still running (depends on system load and weather))

    if you want to wait until process ended do like this:

        def txt = "cmd /c dir c:\\".execute().with{
            def output = new StringWriter()
            def error = new StringWriter()
            //wait for process ended and catch stderr and stdout 
            it.waitForProcessOutput(output, error)
            //check there is no error
            assert error.toString().size()==0: "$error"
            //println it.exitValue() //we can do check with error code
            //return stdout from closure 
            return output.toString()
        }
    

    for jenkins pipeline to avoid error java.io.NotSerializableException use the following code:

        node {
            def res = runAndWait("cmd /c dir c:\\")
            echo res
        }
        
        @NonCPS
        String runAndWait(Object cmd){
            def proc = cmd.execute()
            def output = new StringWriter()
            def error = new StringWriter()
            //wait for process ended and catch stderr and stdout 
            proc.waitForProcessOutput(output, error)
            //check there is no error
            assert error.toString().trim().size()==0: "$error"
            //assert proc.exitValue()==0 //we can do check with error code
            //return stdout from closure 
            return output.toString()
        }