如何在 Jenkins 管道中捕获和格式化 Json 响应
How To Capture and Format Json Response in Jenkins Pipeline
我是 运行 我的 Jenkinsfile 中的 curl 命令。
post {
success {
script {
sh '''
|SCORE=+1
|GERRIT_COMMENT="$(cat <<-EOL
|Sonar result was: SUCCESS
|Report: ${Jenkins_URL}/job/${JOB_NAME}/${BUILD_NUMBER}/artifact/report1.txt
|EOL
|)"
|curl -s -u ${apiToken}: ${Sonar_URL}/api/measures/component_tree?ps=100&s=qualifier,name&component=sonarqube&metricKeys=ncloc,bugs,vulnerabilities,code_smells,security_hotspots,coverage,duplicated_lines_density&strategy=children | json_pp -json_opt pretty,canonical > report1.txt
|echo "Voting unsuccessful"
'''.stripMargin().stripIndent()
archiveArtifacts artifacts: 'report1.txt', fingerprint: true
echo 'I Succeeded'
}
}
但是我得到了错误
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "(end of string)") at /usr/bin/json_pp
我无法使用 jq,因为它没有安装,安装也不是一个选项。
curl 命令在我的终端上运行良好,但在我的 Jenkins 管道中失败。
另外,当我这样做时,它起作用了。
post {
success {
script {
sh '''
|SCORE=+1
|GERRIT_COMMENT="$(cat <<-EOL
|Sonar result was: SUCCESS
|Report: ${Jenkins_URL}/job/${JOB_NAME}/${BUILD_NUMBER}/artifact/report1.txt
|EOL
|)"
|echo "Voting unsuccessful"
'''.stripMargin().stripIndent()
sh """
curl -s -u ${apiToken}: '${Sonar_URL}/api/measures/component_tree?ps=100&s=qualifier,name&component=sonarqube&metricKeys=ncloc,bugs,vulnerabilities,code_smells,security_hotspots,coverage,duplicated_lines_density&strategy=children' | json_pp -json_opt pretty,canonical > report1.txt
"""
archiveArtifacts artifacts: 'report1.txt', fingerprint: true
echo 'I Succeeded'
}
}
但它会在控制台输出中引发警告。
Warning: A secret was passed to "sh" using Groovy String interpolation, which is insecure. Affected argument(s) used the following variable(s): [apiToken]
请问我做错了什么?
在 Jenkins 管道中,如何使用 curl 将 JSON 响应正确传递到文件中?
我建议尽可能不要使用 shell 脚本。 Shell 脚本不是跨平台的,需要安装额外的工具(例如 curl
)。
在您的情况下,curl
调用可以替换为 httpRequest 步骤。
首先让我们替换 curl
调用并将结果保存在 componentTree.json
文件中:
httpRequest(
url: "${Sonar_URL}/api/measures/component_tree?ps=100&s=qualifier,name&component=sonarqube&metricKeys=ncloc,bugs,vulnerabilities,code_smells,security_hotspots,coverage,duplicated_lines_density&strategy=children",
authorization: 'id-of-credentials-which-was-used-to-create-the-apiToken-variable',
outputFile: 'componentTree.json'
)
您想将 JSON 数据格式化为人类可读的格式,所以让我们使用 readJSON and writeJSON 步骤:
def json = readJSON(file: 'componentTree.json')
writeJSON(json: json, file: 'report1.txt', pretty: 4)
现在 report1.txt
文件包含 JSON,格式为缩进 4。
componentTree.json
文件只写入和读取一次,所以让我们减少IO操作的次数:
def response = httpRequest(
url: "${Sonar_URL}/api/measures/component_tree?ps=100&s=qualifier,name&component=sonarqube&metricKeys=ncloc,bugs,vulnerabilities,code_smells,security_hotspots,coverage,duplicated_lines_density&strategy=children",
authorization: 'id-of-credentials-which-was-used-to-create-the-apiToken-variable'
)
def json = readJSON(text: response.content)
writeJSON(json: json, file: 'report1.txt', pretty: 4)
关于警告:
Warning: A secret was passed to "sh" using Groovy String interpolation, which is insecure. Affected argument(s) used the following variable(s): [apiToken]
绝不能插入机密,因为它们可能包含可以解释的特殊字符。示例:
- 我的秘密:
My' https://example.org; cat /etc/passwd; echo \
- 命令:
curl -u '${password}' https://private.server/path/file.txt
插值后调用以下命令:
curl -u 'My' https://example.org; cat /etc/passwd; echo \' https://private.server/path/file.txt
有两种修复方法:
- 如果
apiToken
是一个环境变量:
sh "curl -s -u $apiToken: '${Sonar_URL}/api/measures/component..."
- 如果
apiToken
是一个 Groovy 变量:
withEnv(["CREDENTIALS=${apiToken}"]) {
sh "curl -s -u $CREDENTIALS: '${Sonar_URL}/api/measures/component..."
}
在这两种情况下,美元符号 ($
) 在凭证之前被转义,这意味着 shell 脚本将解析它(它将从环境变量中获取)。
我是 运行 我的 Jenkinsfile 中的 curl 命令。
post {
success {
script {
sh '''
|SCORE=+1
|GERRIT_COMMENT="$(cat <<-EOL
|Sonar result was: SUCCESS
|Report: ${Jenkins_URL}/job/${JOB_NAME}/${BUILD_NUMBER}/artifact/report1.txt
|EOL
|)"
|curl -s -u ${apiToken}: ${Sonar_URL}/api/measures/component_tree?ps=100&s=qualifier,name&component=sonarqube&metricKeys=ncloc,bugs,vulnerabilities,code_smells,security_hotspots,coverage,duplicated_lines_density&strategy=children | json_pp -json_opt pretty,canonical > report1.txt
|echo "Voting unsuccessful"
'''.stripMargin().stripIndent()
archiveArtifacts artifacts: 'report1.txt', fingerprint: true
echo 'I Succeeded'
}
}
但是我得到了错误
malformed JSON string, neither array, object, number, string or atom, at character offset 0 (before "(end of string)") at /usr/bin/json_pp
我无法使用 jq,因为它没有安装,安装也不是一个选项。
curl 命令在我的终端上运行良好,但在我的 Jenkins 管道中失败。
另外,当我这样做时,它起作用了。
post {
success {
script {
sh '''
|SCORE=+1
|GERRIT_COMMENT="$(cat <<-EOL
|Sonar result was: SUCCESS
|Report: ${Jenkins_URL}/job/${JOB_NAME}/${BUILD_NUMBER}/artifact/report1.txt
|EOL
|)"
|echo "Voting unsuccessful"
'''.stripMargin().stripIndent()
sh """
curl -s -u ${apiToken}: '${Sonar_URL}/api/measures/component_tree?ps=100&s=qualifier,name&component=sonarqube&metricKeys=ncloc,bugs,vulnerabilities,code_smells,security_hotspots,coverage,duplicated_lines_density&strategy=children' | json_pp -json_opt pretty,canonical > report1.txt
"""
archiveArtifacts artifacts: 'report1.txt', fingerprint: true
echo 'I Succeeded'
}
}
但它会在控制台输出中引发警告。
Warning: A secret was passed to "sh" using Groovy String interpolation, which is insecure. Affected argument(s) used the following variable(s): [apiToken]
请问我做错了什么?
在 Jenkins 管道中,如何使用 curl 将 JSON 响应正确传递到文件中?
我建议尽可能不要使用 shell 脚本。 Shell 脚本不是跨平台的,需要安装额外的工具(例如 curl
)。
在您的情况下,curl
调用可以替换为 httpRequest 步骤。
首先让我们替换 curl
调用并将结果保存在 componentTree.json
文件中:
httpRequest(
url: "${Sonar_URL}/api/measures/component_tree?ps=100&s=qualifier,name&component=sonarqube&metricKeys=ncloc,bugs,vulnerabilities,code_smells,security_hotspots,coverage,duplicated_lines_density&strategy=children",
authorization: 'id-of-credentials-which-was-used-to-create-the-apiToken-variable',
outputFile: 'componentTree.json'
)
您想将 JSON 数据格式化为人类可读的格式,所以让我们使用 readJSON and writeJSON 步骤:
def json = readJSON(file: 'componentTree.json')
writeJSON(json: json, file: 'report1.txt', pretty: 4)
现在 report1.txt
文件包含 JSON,格式为缩进 4。
componentTree.json
文件只写入和读取一次,所以让我们减少IO操作的次数:
def response = httpRequest(
url: "${Sonar_URL}/api/measures/component_tree?ps=100&s=qualifier,name&component=sonarqube&metricKeys=ncloc,bugs,vulnerabilities,code_smells,security_hotspots,coverage,duplicated_lines_density&strategy=children",
authorization: 'id-of-credentials-which-was-used-to-create-the-apiToken-variable'
)
def json = readJSON(text: response.content)
writeJSON(json: json, file: 'report1.txt', pretty: 4)
关于警告:
Warning: A secret was passed to "sh" using Groovy String interpolation, which is insecure. Affected argument(s) used the following variable(s): [apiToken]
绝不能插入机密,因为它们可能包含可以解释的特殊字符。示例:
- 我的秘密:
My' https://example.org; cat /etc/passwd; echo \
- 命令:
curl -u '${password}' https://private.server/path/file.txt
插值后调用以下命令:
curl -u 'My' https://example.org; cat /etc/passwd; echo \' https://private.server/path/file.txt
有两种修复方法:
- 如果
apiToken
是一个环境变量:sh "curl -s -u $apiToken: '${Sonar_URL}/api/measures/component..."
- 如果
apiToken
是一个 Groovy 变量:withEnv(["CREDENTIALS=${apiToken}"]) { sh "curl -s -u $CREDENTIALS: '${Sonar_URL}/api/measures/component..." }
在这两种情况下,美元符号 ($
) 在凭证之前被转义,这意味着 shell 脚本将解析它(它将从环境变量中获取)。