Convert a JSON style String to a map Groovy in Jenkinsfile - jenkins

I have a string that looks like this {"analyzer": "static_analyzer", "status": "success", "hash": "3c8f0dae82136f0a1447de5531e5bd03", "scan_type": "zip", "file_name": "jenkins-iOS-BuildVerify-GH-PR-6487-38.zip"}. I want to parse this and get the value of "hash", but I can't find any existing methods to convert this into a map.

I'm assuming you are working with a Jenkins pipeline. If so You can do something like the below. Here I'm using the inbuilt readJSON option. You can read more here.
pipeline {
agent any
stages {
stage('Sample') {
steps {
script {
def jsonString = '{"analyzer": "static_analyzer", "status": "success", "hash": "3c8f0dae82136f0a1447de5531e5bd03", "scan_type": "zip", "file_name": "jenkins-iOS-BuildVerify-GH-PR-6487-38.zip"}'
def props = readJSON text: jsonString
def hash = props['hash']
echo "$hash"
}
}
}
}
}

Related

Dart - String replaceAll from json

I have some Dart code that need replace all the keyword to full string based on a json list. I now using the most easy method to replaceAll string one by one but it seem not ok to work on a very long json, how do write a function take json and replace based on the key label field?
String replaceString(String str) {
str = str.replaceAll('key_a', 'created');
str = str.replaceAll('key_b', 'replied');
str = str.replaceAll('key_c', 'assigned');
str = str.replaceAll('key_d', 'unassigned');
str = str.replaceAll('key_e', 'terminated');
return str;
}
json get from api
{
"key_a": {
"label": "created",
"type": ""
},
"key_b": {
"label": "replied",
"type": ""
},
"key_c": {
"label": "assigned",
"type": ""
}
..... and many more
}

Set values from response to environmental variable array

I have a Postman POST request, where response body looks like this:
{
"data": [
{
"object": "Answer",
"id": 507,
...
},
{
"object": "Answer",
"id": 208,
...
}
],...
In following DEL request this ids should be used in body as array:
{
"ids": [id1, id2]
}
How can i get these ids from response and store it as environment variable array [id1, id2] so then it could be used like "ids": {{answer_ids_array}} ?
To capture the id values as an array and set in an environment variable you could add something like this to the Tests tab of the first request:
let myArray = []
_.each(pm.response.json().data, (item) => {
myArray.push(item.id)
})
pm.environment.set("idArray", myArray)
To use the array in the request body, you would need to add this to the Pre-request script to transform to saved string back into an array:
pm.environment.set("ids", JSON.stringify(pm.environment.get("idArray")))
Your request body would then be something like this:
{
"ids": {{ids}}
}

String interpolation in jenkins pipeline for evaluating a string received as argument

I'm a newbie to jenkins/groovy and I'm lost at string interpolation.
We're trying to read a list of steps from a configuration file (stored in json format) and execute some actions bases on it in jenkins pipeline script.
Configuration file:
{
"actions": [ {
"operation": "create",
"args": [
{ "path": "${env.SVNRoot}\\trunk\\ABC" },
{ "path": "${env.SVNRoot}\\trunk\\XYZ" }
]
}, {
"operation": "delete",
"args": [
{ "path": "${env.SVNRoot}\\trunk\\ABC" },
{ "path": "${env.SVNRoot}\\trunk\\XYZ" }
]
}
] }
Jenkins Pipeline code:
node('master') {
echo "${env.SVNRoot}" //String interpolation works here, giving the right value
stage('ReadConfig'){
cfg = readJSON file: 'Cfg.json'
}
stage('ExecuteConfigActions'){
cfg.fileActions.each() {
switch(it.operation) {
case 'create':
it.args.each() {
echo it.path //String interpolation doesnt work here
break;
default:
break;
}
}
}
}
}
How can I get string interpolation to work in such a scenario? Basically I want the environment variable value to be substituted in its placeholder and the path hence derived.
I've tried single, double, escaped quotes to no avail.
The closest I can suggest is formulating a sprintf statement stored in the Configuration file and evaluated in your pipeline. Use at your own risk of someone being able to use the configuration file and substitute whatever they want. If you need to specify which environment variable in the config file and evaluate an interpolation still, check out this answer: evaluating a groovy string expression at runtime
Configuration file:
{
"actions": [ {
"operation": "create",
"args": [
{ "path": "%s\\trunk\\ABC" },
{ "path": "%s\\trunk\\XYZ" }
]
}, {
"operation": "delete",
"args": [
{ "path": "%s\\trunk\\ABC" },
{ "path": "%s\\trunk\\XYZ" }
]
}
] }
Pipeline code:
node('master') {
echo "${env.SVNRoot}" //String interpolation works here, giving the right value
stage('ReadConfig'){
cfg = readJSON file: 'Cfg.json'
}
stage('ExecuteConfigActions'){
cfg.fileActions.each() {
switch(it.operation) {
case 'create':
it.args.each() {
echo sprintf(it.path,env.SVNRoot)
}
break;
default:
break;
}
}
}
}

Groovy representation of Notification plugin in Jenkinsfile

How to represent the Notifications Endpoint section of the Jenkins job configuration in a Jenkinsfile (in the form of a groovy script) ? I have installed the Notification plugin but I am not sure how I would use that.
In my jenkins pipeline I did the following:
pipeline {
// ..
stages {
stage('Notify') {
script {
def build = currentBuild // global variable in pipeline -> https://opensource.triology.de/jenkins/pipeline-syntax/globals#currentBuild
def targetUrl = "http://some-url?{some-query-params}"
def buildUrl = build.absoluteUrl
def buildNumber = build.number
def buildStatus = build.currentResult
httpRequest url: targetUrl, contentType: 'APPLICATION_JSON', httpMode: 'POST', responseHandle: 'NONE', timeout: 30, requestBody: """
{
"name": "${args.serviceName}",
"build": {
"full_url": "${buildUrl}",
"number": "${buildNumber}",
"phase": "FINISHED",
"status": "${buildStatus}"
}
}
"""
}
}

Access Stage results in Workflow/ Pipeline plugin

I have a pipeline with different stages. I want the current job to check how many stages have passed in the previous build and log it in the console?
Consider this is my current pipeline
node(){
stage "1"
do something
stage "2"
do something else
}
I want a groovy script to give my something like this
println currentBuild.previousBuild.getStage("1").result
The purpose of my code is track successes & failures in different stages across my builds. Are there any alternatives to this approach?
You definitely could use Pipeline REST API Plugin, for me it was available out of the box with Jenkins 2.13.
By parsing the resulting JSON you could get the status of the stage similarly to what you expect. For the api call I personally use http_request plugin.
From the documentation GET /job/:job-name/:run-id/wfapi/describe returns:
{
"_links": {
"self": {
"href": "/jenkins/job/Test%20Workflow/16/wfapi/describe"
},
"pendingInputActions": {
"href": "/jenkins/job/Test%20Workflow/16/wfapi/pendingInputActions"
}
},
"id": "2014-10-16_13-07-52",
"name": "#16",
"status": "PAUSED_PENDING_INPUT",
"startTimeMillis": 1413461275770,
"endTimeMillis": 1413461285999,
"durationMillis": 10229,
"stages": [
{
"_links": {
"self": {
"href": "/jenkins/job/Test%20Workflow/16/execution/node/5/wfapi/describe"
}
},
"id": "5",
"name": "Build",
"status": "SUCCESS",
"startTimeMillis": 1413461275770,
"durationMillis": 5228
},
{
"_links": {
"self": {
"href": "/jenkins/job/Test%20Workflow/16/execution/node/8/wfapi/describe"
}
},
"id": "8",
"name": "Test",
"status": "SUCCESS",
"startTimeMillis": 1413461280998,
"durationMillis": 4994
},
{
"_links": {
"self": {
"href": "/jenkins/job/Test%20Workflow/16/execution/node/10/wfapi/describe"
}
},
"id": "10",
"name": "Deploy",
"status": "PAUSED_PENDING_INPUT",
"startTimeMillis": 1413461285992,
"durationMillis": 7
}
]
}
You can iterate all stages of the build and do what you need:
WorkflowRun run = Jenkins.instance.getItemByFullName("####YOUR_JOB_NAME####")._getRuns()[0]
FlowExecution exec = run.getExecution()
PipelineNodeGraphVisitor visitor = new PipelineNodeGraphVisitor(run)
def flowNodes = visitor.getPipelineNodes()
for (Iterator iterator = flowNodes.iterator(); iterator.hasNext();)
{
def node = iterator.next()
if (node.getType() == FlowNodeWrapper.NodeType.STAGE)
{
String stageName = node.getDisplayName()
def stageResult = node.getStatus().getResult()
println "Result of stage ${stageName} is ${stageResult}"
}
}
Here is a sample code to iterate all flow nodes and get whatever information you want:
import org.jenkinsci.plugins.workflow.graph.FlowGraphWalker
import org.jenkinsci.plugins.workflow.graph.FlowNode
try {
// just for demo, a success step and a failure step
node {
sh 'true'
sh 'false'
}
} finally {
FlowGraphWalker walker = new FlowGraphWalker(currentBuild.rawBuild.getExecution())
for (FlowNode flowNode: walker) {
// do whatever you want with flowNode
echo flowNode.dump()
}
}

Resources