Can jenkins extended choice parameter be made dependent on another parameter's value? - jenkins

I am using extended choice parameter with JSON parameter type in my declarative Jenkins pipeline. I have found it very good for providing custom UI for parameters and it returns a json based on user inputs.
I have a use case where what options are shown to user depends upon another parameter's value. I can achieve such functionality with active choice parameter but then I am stuck with radio buttons, checkbox, html input etc.
I found a suitable option here where I can make a property inside json dependent on another property:
{
"title": "An object",
"type": "object",
"properties": {
"fieldOne": {
"title": "I should be changed to 'foo'",
"type": "string",
"enum": ["foo","bar"],
"default": "bar"
},
"depender1": {
"title": "I depend on fieldOne to be 'foo'",
"type": "string",
"enum": ["lorem","ipsum"],
"options": {
"dependencies": {
"fieldOne": "foo"
}
}
},
"depender2": {
"title": "I depend on fieldOne to be 'bar'",
"type": "string",
"enum": ["dolor", "sit"],
"options": {
"dependencies": {
"fieldOne": "bar"
}
}
}
}
}
This works great when I try it here
But when I try the same on jenkins, it doesn't work. It shows all 3 textboxes. I saw the option of watching other params too but I couldn't find how to use it as an if else for my parameter.
This is a simple example, what I want to achieve requires UI of a dropdown-1 + Array(dropdown-2 + text field+text-field) where in array's text-field depend on value of dropdown-1, I cannot create the same UI in active choice.
Does any one know how options.dependencies could work in jenkins or same could be achieved using watch/other plugins?

if i got your question right, so you want to make it more smart way to select parameters.
So you can do it via groovy script.
Here is my example you can see on pic:
freestyle job config
Sorry, but i don't know how to better show freestyle job config.
So, logic is quite simple:
i'm collecting JSON on first parameter, and doing some parsing for it.
and then im using Environmets variable to show it's contents, depending on result from first part.
ps. i'm struggling right now with variable Hosts, as i don't know how to pass it in final steps without asking user for input.
But i believe you got the idea how you can do it.

Related

Unfurl links blocks template

I'm using the link_shared events to unfurl links in my workspace, trying to generate a template that is as close to Slack's unfurling template as possible, but I have several issues -
Blocks have very large spacing between them, causing my 3 blocks to take a lot of space
I'm unable to have an image inlined with the text for the title, unless I'm using context, but this is causing the text to be very small.
Taking Slack's example of how link unfurling should look like and trying to mimic it with blocks should explain the differences. This is the blocks message, and here you can see the result as an image
So my main question is - does Slack use some internal blocks formatting not available in the API, or is it possible to achieve the same result?
Thanks a lot!
{
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": ":pager: *Slack*"
}
},
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "*<https://slack.com/features|Features>*"
}
},
{
"type": "image",
"title": {
"type": "plain_text",
"text": "Slack is where work flows. It's where the people you need, the information you share, and the tool you use come together to get things done.",
"emoji": true
},
"image_url": "https://a.slack-edge.com/13f94ee/marketing/img/homepage/self-serve-campaign/unfurl/img-unfurl-ss-campaign.jpg",
"alt_text": "Slack"
}
]
}
That example is not using the Slack block unfurl - it's an example of how a generic link would be displayed using the page's meta tags to display some additional information, using the favicon image.
If you wanted to create something similar you could use use a markdown block and an image block (like this) - but the file size would be displayed on a new line rather than after the text.
It took a bit of playing around, but I realized Slack is actually using message attachments (the legacy version of message formatting) in order to generate their link unfurls.
For example, if you want to unfurl a GitHub repository link, this is the payload you should send, and it'll generate an almost identical unfurling to what Slack is generating (a small Added by {app-name} will be added to the footer) -
unfurls["https://github.com/slackapi/bolt-js/"] = {
author_name: "GitHub",
author_icon: "https://a.slack-edge.com/80588/img/unfurl_icons/github.png",
title: "GitHub - slackapi/bolt-js: A framework to build Slack apps using JavaScript",
title_link: "https://github.com/slackapi/bolt-js/",
text: "A framework to build Slack apps using JavaScript. Contribute to slackapi/bolt-js development by creating an account on GitHub.",
image_url: "https://opengraph.githubassets.com/3e06f7eee96f05a53cd4905af3b296dfe333be7a902bb3e6a095770e87fd17fe/slackapi/bolt-js"
}

Django REST Framework - List items with possible actions

I would like to extend the standard ListAPIView by adding allowed actions to each item so that the JSON returned on GET /books/ would approximately look as follows:
[
{
"ID": 1,
"name": "Animal Farm",
"author": "George Orwell",
"actions": [
"detail": {
"method": "GET"
"uri": "/books/1"
},
"remove": {
"method": "DELETE"
"uri": "/books/1"
}
...
]
},
...
]
By having such an "action list", I can easily tell the frontend which actions are currently allowed so it can e. g. include only buttons for those actions.
I went through the DRF docs and could not find a similar functionality. Shall I write it from scratch or is there a 3rd party plugin that could possibly help me? And when writing this from scratch, how would you design (=where to write the code of) such a feature?
DRF has support for that when you use the OPTIONS method, you can find more info here.
You could take a look into how this SimpleMetadata function creates the list of actions and either base yourself on it to write yours from scratch, or just find a way to call it to render the action list.
I'm not sure, if there is such plugin in DRF (maybe something for serializers?).
If writing from scratch, you should override your get() method ListAPIView (or list() method of mixins.ListModelMixin)

Modify Task.json at build step design time

i wanted to modify task.json on runtime means when i configure my CI task in vsts or tfs.
I created an extension that contribute a build task.
Through this build task i wanted to do something like this, i have done in jenkins. Please Refer screenshot:
1-Requirement) in this image we add global variable(fields) at runtime on clicking Add Global Variables button. It generates two fields one for GVName and another for its value.
2-Requirement) When we select global variable then respective value field change at runtime means it can be dropbox(picklist) or input field that depends on GV type.
3-Requirement) On Job design time we make an ajax call to server that return true/false on based of value we shows error like in image 2.
Is these requirements are feasible in VSTS task.json? If yes, can you help me to solve this.
No, but it can list the available items that returned from the server.
For example:
"inputs": [
{
"name": "APIURL",
"type": "connectedService:Generic",
"label": "API URL",
"required": true,
"helpMarkDown": ""
},
{
"name": "List1",
"type": "pickList",
"label": "List4",
"defaultValue": "",
"required": false,
"helpMarkDown": ""
}
],
"sourceDefinitions": [
{
"target": "List1",
"endpoint": "home/jsontest",
"selector": "jsonpath:$[*].id",
"authKey": "$(APIURL)"
}
],
A thread that may benefit you: Using a web API in task.json to fill picklists buildtask

Retrieving labels from multiple JIRA Subtasks via JIRA API

I am creating a reporting dashboard with the intent of getting multiple tickets/issues for a project. As most of you probably know, a JIRA issue can have subtasks. These subtasks can have labels.
I want to retrive all labels for every subtask.
I already have the project API request implemented which returns the parent ticket ids along with the issue/ticket number of all subtasks. The problem is the data returned from this request does not include the labels for the subtasks themselves.
I can loop over each subtask number and make an additional API request for each one to get the labels, however this would result in a large number of requests.
Looking through JIRA's API I cannot find a better way of doing this. Google seems to return a lot of results about plugins and version differences with Cloud vs. Server but I have not found a better solution.
Their API makes reference to an expand option but I have yet to figure out a way to make that work for subtask labels (I might be missing something obvious).
If anyone has experience with a similar situation I would appreciate hearing any advice you could offer. Thanks!
What I have currently:
Project API Request:
https://ourcompanyhere.atlassian.net/rest/api/2/search
with an additional parameter added for the JQL string of:
project=PROJECTNAME AND fixversion=version
This returns all the tickets in the project with subtasks but not the subtask labels.
I can loop over the returned data from the above request and make an additional request for each:
https://ourcompanyhere.atlassian.net/rest/api/2/issue/ticketNumberHere
JSON Response
Here is the partial JSON response back (full response is huge and I've removed key information) however this is the complete information for a ticket, with a subtask which has labels. As you can see the labels section of the subtask is completely missing.
ErrorDetail=,
Mimetype=application/json,
Statuscode=200 OK,
Filecontent= {
"expand":"schema,names",
"startAt":0,
"maxResults":50,
"total":3,
"issues":[
{
"expand":"operations,versionedRepresentations,editmeta,changelog,renderedFields",
"id":"24209",
"self":"https://[instance].atlassian.net/rest/api/latest/issue/24209",
"key":"DEV-3089",
"fields":{
"issuetype":{
"self":"https://[instance].atlassian.net/rest/api/2/issuetype/10005",
"id":"10005",
"description":"A new feature of the product, which has yet to be developed.",
"iconUrl":"https://[instance].atlassian.net/secure/viewavatar?size=xsmall&avatarId=10311&avatarType=issuetype",
"name":"New Feature",
"subtask":false,
"avatarId":10311
},
"project":{
"self":"https://[instance].atlassian.net/rest/api/2/project/10000",
"id":"10000",
"key":"DEV",
"name":"Development Queue",
"avatarUrls":{
}
},
"customfield_11000":null,
"fixVersions":[
{
"self":"https://[instance].atlassian.net/rest/api/2/version/14600",
"id":"14600",
"description":"",
"name":"",
"archived":false,
"released":true,
"releaseDate":"2017-09-15"
}
],
"resolution":{
"self":"https://[instance].atlassian.net/rest/api/2/resolution/10000",
"id":"10000",
"description":"Work has been completed on this issue.",
"name":"Done"
},
"customfield_10500":"",
"customfield_10700":null,
"customfield_10900":null,
"resolutiondate":"2017-09-15T09:19:37.000-0400",
"workratio":-1,
"watches":{
"self":"https://[instance].atlassian.net/rest/api/2/issue/DEV-3089/watchers",
"watchCount":2,
"isWatching":true
},
"lastViewed":null,
"created":"2017-05-02T10:15:08.000-0400",
"customfield_10022":null,
"customfield_10100":null,
"priority":{
"self":"https://[instance].atlassian.net/rest/api/2/priority/3",
"iconUrl":"https://[instance].atlassian.net/images/icons/priorities/medium.svg",
"name":"Medium",
"id":"3"
},
"customfield_10300":null,
"labels":[
"[label1]",
"[label2]",
"[label3]",
"[label4]",
"[label5]",
"[label6]"
],
"customfield_10016":null,
"customfield_10017":null,
"versions":[
],
"issuelinks":[
],
"assignee":{
"self":"https://[instance].atlassian.net/rest/api/2/user?username=",
"name":"[name]",
"key":"[name]",
"accountId":"[account]",
"emailAddress":"[email]",
"avatarUrls":{
},
"displayName":"[name]",
"active":true,
"timeZone":"America/New_York"
},
"updated":"2017-09-15T09:19:36.000-0400",
"status":{
"self":"https://[instance].atlassian.net/rest/api/2/status/6",
"description":"The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.",
"iconUrl":"https://[instance].atlassian.net/images/icons/statuses/closed.png",
"name":"Closed",
"id":"6",
"statusCategory":{
"self":"https://[instance].atlassian.net/rest/api/2/statuscategory/3",
"id":3,
"key":"done",
"colorName":"green",
"name":"Done"
}
},
"components":[
],
"description":"[description]",
"customfield_10010":null,
"customfield_10011":null,
"customfield_11100":null,
"customfield_10012":null,
"customfield_10013":null,
"customfield_10015":"",
"customfield_10005":null,
"customfield_10006":null,
"customfield_10600":null,
"customfield_10007":null,
"customfield_10008":null,
"customfield_10800":null,
"customfield_10009":null,
"summary":"[summary]",
"creator":{
"self":"https://[instance].atlassian.net/rest/api/2/user?username=",
"name":"",
"key":"",
"accountId":"",
"emailAddress":"",
"avatarUrls":{
},
"displayName":"",
"active":true,
"timeZone":"America/New_York"
},
"subtasks":[
{
"id":"30213",
"key":"DEV-4118",
"self":"https://[instance].atlassian.net/rest/api/2/issue/30213",
"fields":{
"summary":"",
"status":{
"self":"https://[instance].atlassian.net/rest/api/2/status/6",
"description":"The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.",
"iconUrl":"https://[instance].atlassian.net/images/icons/statuses/closed.png",
"name":"Closed",
"id":"6",
"statusCategory":{
"self":"https://[instance].atlassian.net/rest/api/2/statuscategory/3",
"id":3,
"key":"done",
"colorName":"green",
"name":"Done"
}
},
"priority":{
"self":"https://[instance].atlassian.net/rest/api/2/priority/3",
"iconUrl":"https://[instance].atlassian.net/images/icons/priorities/medium.svg",
"name":"Medium",
"id":"3"
},
"issuetype":{
"self":"https://[instance].atlassian.net/rest/api/2/issuetype/10009",
"id":"10009",
"description":"",
"iconUrl":"https://[instance].atlassian.net/secure/viewavatar?size=xsmall&avatarId=10303&avatarType=issuetype",
"name":"Testing Issue",
"subtask":true,
"avatarId":10303
}
}
}
"reporter":{
"self":"https://[instance].atlassian.net/rest/api/2/user?username=",
"name":"",
"key":"",
"accountId":"",
"emailAddress":"",
"avatarUrls":{
},
"displayName":"",
"active":true,
"timeZone":"America/New_York"
},
"customfield_10000":"2017-09-01T12:35:54.706-0400",
"customfield_10001":null,
"customfield_10200":null,
"customfield_10400":null,
"customfield_10004":null,
"environment":null,
"duedate":null,
"votes":{
"self":"https://[instance].atlassian.net/rest/api/2/issue/DEV-3089/votes",
"votes":0,
"hasVoted":false
}
}
}
]
}
Inspect the response for the /search endpoint again. On a completely empty JIRA Cloud instance I created a Project, one Issue and added a Sub-task for it. Calling the /search endpoint returns a list with two Issues (so, the Issue itself and its Sub-task) and for both there's a field called labels with an array of all the Labels attached to it.
The following is an abbreviated response with all unrelated data removed.
{
"startAt": 0,
"maxResults": 50,
"total": 2,
"issues": [
{
"key": "TEST-1",
"fields": {
"labels": []
}
},
{
"key": "TEST-2",
"fields": {
"parent": {
"key": "TEST-1"
},
"labels": [
"VOILA"
]
}
}
]
}
EDIT
After looking at the response then yes, the array in subtasks is really simple and cannot be separately expanded. You need to do the search, then parse out all the subtasks that you're interested in and either do
a separate /issue/[key] request for each one
a /search for those specific keys
After doing some further research I found a better way to do this. I'm still not getting the subtask labels back but instead of looping over each subtask and sending a separate request for each, you can do one API call using JQL like this:
https://[instance].atlassian.net/rest/api/latest/search?jql=project=[project] AND KEY IN ([comma separated list of tickets])&fields=labels'
The
&fields=labels
part drastically reduces the amount of information returned. So now I can just do a total of two calls and get everything I need. :)
Wanted to post this in case anyone runs into a similar situation.

neo4jClient create node with dynamic label using paramters

I am building an app that give users the ability to construct there own graphs. I have been using parameters for all queries and creates. But when I want to give users the ability to create a node where they can also Label it anything they want(respecting neo4j restrictions on empty string labels). How would I parameterize this type of transaction?
I tried this:
.CREATE("(a:{dynamicLabel})").WithParams(new {dynamicLabel = dlabel})...
But this yields a syntax error with neo. I am tempted to concatenate, but am worried that this may expose an injection risk to my application.
I am tempted to build up my-own class that reads the intended string and rejects any type of neo syntax, but this would limit my users a bit and I would rather not.
There is an open neo4j issue 4334, which is a feature request for adding the ability to parameterize labels during CREATE.So, this is not yet possible.
That issue contains a comment that suggests generating CREATE statements with hardcoded labels, which will work. It is, unfortunately, not as performant as using parameters (should it ever be supported in this case).
I searched like hell and finally found it out.
you can do it like that:
// create or update nodes with dynamic label from import data
WITH "file:///query.json" AS url
call apoc.load.json(url) YIELD value as u
UNWIND u.cis as ci
CALL apoc.merge.node([ ci.label ], {Id:ci.Id}, {}, {}) YIELD node
RETURN node;
The JSON looks like that:
{
"cis": [
{
"label": "Computer",
"Id": "1"
},
{
"label": "Service",
"Id": "2"
},
{
"label": "Person",
"Id": "3"
}
],
"relations": [
{
"end1Id": "1",
"Id": "4",
"end2Id": "2",
"label": "USES"
},
{
"end1Id": "3",
"Id": "5",
"end2Id": "1",
"label": "MANAGED_BY"
}
]
}
If you are using a Java client, then you can do it like this.
Node node = GraphDatabaseService.createNode();
Label label = new Label() {
#Override
public String name() {
return dynamicLabelVal;
}
};
node.addLabel(label);
You can then have a LabelCache which will avoid Label object creation for every node.

Resources