Jenkins Groovy reading maps from file and rendering html - jenkins

How to Render HTML inputs Control using Active Choices Reactive Reference Parameter in Jenkins.
I am trying to create a Map and provide options in the Jenkins pipeline for parameterized output using a groovy script. Below Groovy works but I want to read service_name and release_tag from the file as it is and render the output. How do I read from the file and dump it in this script?
def tier = 'p1'
service_tier_map = [
"p1": [
["service_name": "web1", "release_tag": "1.0.0" ],
["service_name": "finance_service", "release_tag": "2.2.0" ],
],
"p2": [
["service_name": "web2", "release_tag": "2.0.0" ],
["service_name": "web4", "release_tag": "2.0.0" ],
],
"p3": [
["service_name": "web3", "release_tag": "3.0.0" ],
],
]
html_to_be_rendered = "<table><tr>"
service_list = service_tier_map[tier]
service_list.each { service ->
html_to_be_rendered = """
${html_to_be_rendered}
<tr>
<td>
<input name=\"value\" alt=\"${service.service_name}\" json=\"${service.service_name}\" type=\"checkbox\" class=\" \">
<label title=\"${service.service_name}\" class=\" \">${service.service_name}</label>
</td>
<td>
<input type=\"text\" class=\" \" name=\"value\" value=\"${service.release_tag}\" size="50"> </br>
</td>
</tr>
"""
}
html_to_be_rendered = "${html_to_be_rendered}</tr></table>"
return html_to_be_rendered

Related

How to capture POST content parameters in Jenkins declarative syntax?

How do you capture POST content parameters in code in Jenkins declarative syntax pipeline script?
This is an example of how to do it with scripted syntax:
node {
properties([
pipelineTriggers([
[$class: 'GenericTrigger',
genericVariables: [
[ key: 'committer_name', value: '$.actor.name' ],
[ key: 'committer_email', value: '$.actor.emailAddress' ],
[ key: 'ref', value: '$.changes[0].refId'],
[ key: 'tag', value: '$.changes[0].ref.id', regexpFilter: 'refs/tags/'],
[ key: 'commit', value: '$.changes[0].toHash' ],
[ key: 'repo_slug', value: '$.repository.slug' ],
[ key: 'project_key', value: '$.repository.project.key' ],
[ key: 'clone_url', value: '$.repository.links.clone[0].href' ]
],
causeString: '$committer_name pushed tag $tag to $clone_url referencing $commit',
token: 'my_token',
printContributedVariables: true,
printPostContent: true,
regexpFilterText: '$ref',
regexpFilterExpression: '^refs/tags/.*'
]
])
])
stage("Test") {
deleteDir()
def msg = "hello, world!"
emailext (subject: "Hello", \
mimeType: "text/html",\
body: "${msg} <br> \
committer_name ${committer_name} <br> \
committer_email ${committer_email} <br> \
ref ${ref} <br> \
tag ${tag} <br> \
commit ${commit} <br> \
repo_slug ${repo_slug} <br> \
project_key ${project_key} <br> \
clone_url ${clone_url} <br> \
",
from: "Jenkins#company.com", \
to: "${committer_email}")
This article claims that equivalent scripted syntax would be:
pipeline {
agent any
triggers {
GenericTrigger {
genericVariables {
genericVariable {
key( "committer_name" )
value( "\$.actor.name" )
expressionType( "JSONPath" )
}
}
token( "my_token" )
printContributedVariables(true)
printPostContent(true)
regexpFilterText( "\$ref" )
regexpFilterExpression( "^refs/tags/.*" )
}
}
stages {
stage( "Test" ) {
steps {
deleteDir()
}
}
}
(I stripped down the Test stage to reduced sources of error -- it should be inconsequential to this question).
...whereas in reality, it produces this error:
WorkflowScript: 4: Triggers definitions cannot have blocks # line 4, column 5.
GenericTrigger {
^
1 error
at org.codehaus.groovy.control.ErrorCollector.failIfErrors(ErrorCollector.java:310)
at org.codehaus.groovy.control.CompilationUnit.applyToPrimaryClassNodes(CompilationUnit.java:1085)
at org.codehaus.groovy.control.CompilationUnit.doPhaseOperation(CompilationUnit.java:603)
at org.codehaus.groovy.control.CompilationUnit.processPhaseOperations(CompilationUnit.java:581)
at org.codehaus.groovy.control.CompilationUnit.compile(CompilationUnit.java:558)
at groovy.lang.GroovyClassLoader.doParseClass(GroovyClassLoader.java:298)
at groovy.lang.GroovyClassLoader.parseClass(GroovyClassLoader.java:268)
at groovy.lang.GroovyShell.parseClass(GroovyShell.java:688)
at groovy.lang.GroovyShell.parse(GroovyShell.java:700)
at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.doParse(CpsGroovyShell.java:142)
at org.jenkinsci.plugins.workflow.cps.CpsGroovyShell.reparse(CpsGroovyShell.java:127)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.parseScript(CpsFlowExecution.java:561)
at org.jenkinsci.plugins.workflow.cps.CpsFlowExecution.start(CpsFlowExecution.java:522)
at org.jenkinsci.plugins.workflow.job.WorkflowRun.run(WorkflowRun.java:337)
at hudson.model.ResourceController.execute(ResourceController.java:97)
at hudson.model.Executor.run(Executor.java:428)
Finished: FAILURE
What is correct declarative syntax "equivalent" to the working scripted syntax -- i.e. how can I capture POST content parameters with declarative syntax?
I'd specifically like to learn how to do this "in code", i.e. not using the Varianble/Expression fields of Post content parameters in the Jenkins GUI.
pipeline {
agent any
triggers {
GenericTrigger (
genericVariables: [
[ key: "committer_name", value: "\$.actor.name" ],
[ key: "committer_email", value: "\$.actor.emailAddress" ],
[ key: "ref", value: "\$.changes[0].refId" ],
[ key: "tag", value: "\$.changes[0].ref.id" ],
[ key: "commit", value: "\$.changes[0].toHash" ],
[ key: "repo_slug", value: "\$.repository.slug" ],
[ key: "project_key", value: "\$.repository.project.key" ],
[ key: "clone_url", value: "\$.repository.links.clone[0].href" ],
],
causeString: '$committer_name pushed tag $tag to $clone_url referencing $commit',
token: "my_token",
printContributedVariables: true,
printPostContent: true,
regexpFilterText: "\$ref",
regexpFilterExpression: "^refs/tags/.*"
)
}
stages {
stage( "Build" ) {
steps {
deleteDir()
}
}
}
post {
always {
emailext( subject: "Hello",
from: "jenkins#company.com",
to: "\${committer_email}",
mimeType: "text/html",
body: "hello world <br> \
committer_name ${committer_name} <br> \
committer_email ${committer_email} <br> \
ref ${ref} <br> \
tag ${tag} <br> \
commit ${commit} <br> \
repo_slug ${repo_slug} <br> \
project_key ${project_key} <br> \
clone_url ${clone_url} <br> \
" )
}
}
}

Data files with html content

I'm making a nice simple html page using external data... here's the bit that's causing me grief:
<section class="faq_main">
{% for section in faq.sections %}
<h3>{{ section.heading }}</h3>
{% for question in section.questions %}
<article class="faq_question">
<a id="hide_{{ section.code }}_{{ question.code }}"
href="#hide_{{ section.code }}_{{ question.code }}"
class="hide"><span class="faq_toggler">+</span> {{ question.question }}</a>
<a id="show_{{ section.code }}_{{ question.code }}"
href="#show_{{ section.code }}_{{ question.code }}"
class="show"><span class="faq_toggler">-</span> {{ question.question }}</a>
<div class="details">
{{ question.answer }}
</div>
</article>
{% endfor %}
<p> </p>
{% endfor %}
</section>
... and the matching faq.json file:
{
"sections" : [
{ "heading" : "Section the first",
"code" : "gn",
"questions" : [
{
"question": "What do questions need?",
"code" : "1",
"answer": "An answer"
},
{
"question": "Is this also a question?",
"code" : "2",
"answer": "Yes, it is"
},
{
"question": "Is this junk data?",
"code" : "a",
"answer": "Yes"
},
]
},
{
"heading": "Another section",
"code" : "f",
"questions": [
{
"question": "Can I have html in my answer?",
"code" : "2",
"answer": "<ul>\n<li>First, json needs newlines escaped to be newlines</li>\\n<li>Eleventy seems to 'sanitize' the string</li>\\n</ul>"
},
{
"question": "question b",
"code" : "b",
"answer": "answer b"
},
{
"question": "question c",
"code" : "or",
"answer": "answer c"
},
]
}
]
}
.... and the rendered text for the answer in question is:
<ul> <li>First, json needs newlines escaped to be newlines</li>\n<li>Eleventy seems to 'sanitize' the string</li></ul>
Do I have any options here? Is there a way to allow [even a subset of] html elements into the page?
(and yes, the CSS does the clever show/hide descriptions using the '+'/'-' symbols - all that side of things works just lovely)
It should work by inserting the symbols directly into the quotes in the json. Use Non-breaking spaces for indentation, and unicode points for dots.
Otherwise, the framework is broken.
Change {{ question.answer }} to {{ question.answer | safe }}
(see https://www.11ty.dev/docs/layouts/#prevent-double-escaping-in-layouts - it's clear, once you understand what it's saying :) )

How to Parse Custom (without Key) response in AMP-autosuggest (Rails 5)

Anyone tells me how can I parse my response in AMP-list. In AMP didn't find any solution how to parse own custom API response.
My Code.
<div
class="autosuggest-container hidden"
[class]="(showDropdown && query) ?
'autosuggest-container' :
'autosuggest-container hidden'"
>
<amp-list
class="autosuggest-box"
layout="fixed-height"
height="120"
src="http://lmyadpi.com/api.json?q=a"
id="autosuggest-list"
>
<template type="amp-mustache">
<amp-selector
id="autosuggest-selector"
keyboard-select-mode="focus"
layout="container"
on="
select:
AMP.setState({
query: event.targetOption,
showDropdown: false
}),
autosuggest-list.hide"
>
{{#results}}
<div
class="select-option no-outline"
role="option"
tabindex="0"
on="tap:autosuggest-list.hide"
option="{{.}}"
>{{.}}</div>
{{/results}}
{{^results}}
<div class="select-option {{#query}}empty{{/query}}">
{{#query}}Sorry! We don't ship to your city 😰{{/query}}
</div>
{{/results}}
</amp-selector>
</template>
</amp-list>
</div>
</div>
<amp-state
id="allLocations"
src="http://lmyadpi.com/api.json?q=a"
"emptyAndInitialTemplateJson": [{
"query": "",
[[]]
}]
></amp-state>
My API response :
[[
"1234",
"value2",
""
],
[
"6321123",
"value3",
""
],
[
"43934322",
"value4",
""
],
[
"43660213",
"value5",
""
],
[
"54373228",
"value6",
""
],
[
"410721327",
"value7",
""
]]

AngularJS: service $http.get JSON file

I am very new to AngularJS. I have read several posts on this topic, but am still unable to get data from external JSON file.
here is my code
data.json
[
{
"id": 1,
"date": "20th August 2016",
"day": "Sat",
"in1": "10:30",
"out1": "02:30",
"in2": "04:00",
"out2": "08:00",
"in3": "",
"out3": "",
"total_hours": "8:00",
"status": "1"
},
{
"id": 2,
"date": "20th August 2016",
"day": "Sat",
"in1": "10:30",
"out1": "02:30",
"in2": "04:00",
"out2": "08:00",
"in3": "",
"out3": "",
"total_hours": "8:00",
"status": "1"
}
];
html
<table ng-table="tctrl.tableEdit" class="table table-striped table-vmiddle">
<tr ng-repeat="w in $data" ng-class="{ 'active': w.$edit }">
<td data-title="'ID'">
<span ng-if="!w.$edit">{{ w.id }}</span>
<div ng-if="w.$edit"><input class="form-control" type="text" ng-model="w.id" /></div>
</td>
...
</tr>
</table>
controller.js
.controller('tableCtrl', function($filter, $sce, ngTableParams, tableService) {
var data = tableService.data;
//Editable
this.tableEdit = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
total: data.length, // length of data
getData: function($defer, params) {
$defer.resolve(data.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
})
service.js
.service('tableService', [function($http){
this.data = function() {
return $http.get('data/timesheet.json');
}
}])
I'm just trying to pull data from json file but it's not working and getting blank table. I don't know what is the issue. What I will get in this.data?

Example, how to use huge json in erlyDTL?

I have json
{
"_total": 824,
"_links": "self",
"top": [
{
"viewers": 80896,
"channels": 1177,
"game": {
"name": "League of Legends",
"_id": 21779,
}
},
{
"viewers": 31211,
"channels": 232,
"game": {
"name": "Dota 2",
"_id": 29595,
}
}
]
}
how best displayed "top" list? I try:
Tuple = jsx:decode(unicode:characters_to_binary(Json)),
[_, _, Top] = Tuple,
Games = element(2, Top);
but how using this in template?
{% for v in games %}
{{ v.viewers }}<br><br>
{{ v.channel }}<br><br>
{{ v.game.name }}<br><br>
{% endfor %}
not work, and then show {{ games.game.name }} ?
The code you did is fine, it just need a few updates, you shouldn't pass Games to the template, instead you should use top as the key, as an example, build a rebar file like:
%rebar.config
{deps, [
{erlydtl, ".*", {git, "git#github.com:erlydtl/erlydtl.git", "HEAD"}},
{jsx, ".*", {git, "git#github.com:talentdeficit/jsx.git", "HEAD"}}
]}.
then run:
rebar get-deps
rebar compile
Now define a template with the suggested update, named template.dtl:
{% for v in top %}
{{ v.viewers }}<br><br>
{{ v.channels }}<br><br>
{{ v.game.name }}<br><br>
{% endfor %}
Start an erlang shell:
erl -pa ./deps/erlydtl/ebin/ -pa ./deps/merl/ebin/ -pa ./deps/jsx/ebin/
and execute the commands which should display the template as expected
Json = "{
\"_total\": 824,
\"_links\": \"self\",
\"top\": [
{
\"viewers\": 80896,
\"channels\": 1177,
\"game\": {
\"name\": \"League of Legends\",
\"_id\": 21779,
}
},
{
\"viewers\": 31211,
\"channels\": 232,
\"game\": {
\"name\": \"Dota 2\",
\"_id\": 29595,
}
}
]
}".
Tuple = jsx:decode(unicode:characters_to_binary(Json)).
erlydtl:compile("./template.dtl", test).
test:render(Tuple).
which gives the expecte output
{ok,[[[<<"\n ">>,"80896",<<"<br><br>\n ">>,"1177",
<<"<br><br>\n\t">>,<<"League of Legends">>,<<"<br><br>\n">>],
[<<"\n ">>,"31211",<<"<br><br>\n ">>,"232",
<<"<br><br>\n\t">>,<<"Dota 2">>,<<"<br><br>\n">>]],
<<"\n">>]}
in few words, in your template, replace games with top and pass Tuple to the template

Resources