[JenkinsFile] Unable to parse string for json input

Hello,
I’m unable to parse json message from my JenkinsFile.
So the goal is to send json to API to notify slack channel using CURL.

See below part of Jenkinsfile Code :

def HTTP_PROXY_OPTS="-x ${http_proxy}"
script {
    def URL="https://slack.tech-indent.org/hooks/${hook_url}"
    def logFile="/var/log/ansible/Jenkins_ansible_${logEnvironmentTAG}_${timeStamp}.log"
    //tokenize commit informations
    lastCommitHash = lastCommit.tokenize('|')[0]
    lastCommitMail = lastCommit.tokenize('|')[1]
    lastCommitDate = lastCommit.tokenize('|')[2]
    lastCommitLog = lastCommit.tokenize('|')[3]
    def lastCommitLog_escaped = lastCommitLog.replaceAll('"','^')
    lastCommitEnvHash = lastCommitEnv.tokenize('|')[0]
    lastCommitEnvMail = lastCommitEnv.tokenize('|')[1]
    lastCommitEnvDate = lastCommitEnv.tokenize('|')[2]
    lastCommitEnvLog = lastCommitEnv.tokenize('|')[3]
    def lastCommitEnvLog_escaped = lastCommitEnvLog.replaceAll('"','^')

    def msg = "## ${logEnvironmentTAG} :white_check_mark:\n${JOB_NAME}\n${BUILD_URL}\nRequester: ${Jenkins_username}\n\n|GIT|Log|Commit ID|\n|---|---|---|\n|ID|${lastCommitLog_escaped}|${lastCommitHash}|\n|ENV|${lastCommitEnvLog_escaped}|${lastCommitEnvHash}|"
    def json = '{\"text\": \" ${msg}\"}'
    sh(script: "curl ${CURL_OPTS} -i -X POST \
        -H 'Content-Type: application/json; charset=utf-8'\
        --data \"${json}\" \
        ${URL}")
}

FYI : this hapened when my commit message contains simple quote charachter …

Any suggestion please ?
Thanks for your help

1 Like

Single quotes is a literal string in groovy, so it will literally be {"text": " ${msg}"} so already it feels like not doing what you are expecting it to do.

I would recommend using environmental variables and let bash handle all the escaping for you. Since you are already in a script {} tag, withEnv is cleanest

    def msg = "## ${logEnvironmentTAG} :white_check_mark:\n${JOB_NAME}\n${BUILD_URL}\nRequester: ${Jenkins_username}\n\n|GIT|Log|Commit ID|\n|---|---|---|\n|ID|${lastCommitLog_escaped}|${lastCommitHash}|\n|ENV|${lastCommitEnvLog_escaped}|${lastCommitEnvHash}|"

# note double quotes on the first one so groovy with evaluate variables
withEnv(["JSON=${writeJSON(returnText: true, json: ['text': msg]}"]) {
  sh(script: '''curl ${CURL_OPTS} -i -X POST \
      -H 'Content-Type: application/json; charset=utf-8' \
      --data "${JSON}" \
      ${URL}''')
}

using triple single quotes will allow you to use single quotes inside of bash without issue. Using double quotes inside of the shell statement will tell bash to escape the variable, and using the JSON env variable will prevent you from having to do all the escaping.

2 Likes

man, you are a life saver! I was struggling with passing a payload to AWS cli. This helped me a lot.

For reference:

withEnv(["""JSON=${writeJSON(returnText: true, json: ["cluster_name":"${cluster_name}", "desired_count":"${desired_count}", "services":"${services}"])}"""]){

sh '''aws lambda invoke --function-name XXXX --invocation-type Event --cli-binary-format raw-in-base64-out --payload "${JSON}" --region ${AWS_DEFAULT_REGION} response.json'''
1 Like