Post Functions

This page describes several post functions that might be useful.

Each of these has examples of SIL code.

Required apps

Power Scripts™ for Jira (server)

Level: BASIC

Making a HTTP request to an external system

An example of how you can add a configurable post-processing workflow function to a Jira instance.

It is able to pass workflow specific parameters in a HTTP request to a specified target host.

It is possible to configure a specific target URL and add custom parameters from the issue affected by the workflow transition.

Supported HTTP Methods are:

  • GET
  • POST

The following code creates a HTTP Get request to the "http://www.myserver.com/geturl" URL. It uses specific issue parameters in the header of the Request.

makingAHTTPGetCall.sil
string [] headers = "Accept-Charset|utf-8|X-Powered-By|JJupin 2.5";
httpGet("http://www.myserver.com/geturl?project=" + project, headers); //note: you have to manually encode the values.

The following code creates a HTTP Post request to the "http://www.myserver.com/posturl" URL.You can configure its body parameters and its header like this:

makingAHTTPPostCall.sil
string [] headers = "Accept|text/plain|X-Powered-By|JJupin 2.5";
string [] params = {};
params += "Summary";
params += summary;
params += "Project";
params += project;
params += "Created";
params += created;
httpPost("http://www.myserver.com/posturl", headers, params);

where:

  • Accept
  • X-Powered-By

are the HTTP header fields

 and

  • Summary
  • Project
  • Created

are the corresponding values from your issue.

Of course, you can use it with any HTTP header / parameter your endpoint requires.

Set assignee if reporter has a certain project role

Create a post function on the create transition in Jira with the following code:

string given_assignee = "mike";
string project_role = "Developers";

if(isUserInRole(reporter, project, project_role)) { 
	assignee = given_assignee;
}

The assignee is set to the given value("mike"), if the reporter has the specified project role("Developers").

This is useful when the reporter creates an issue and the project has more than one project lead.

Give it a name of your choice and let's create other post functions.

Control who can see individual issues within a project if reporter/assignee has a certain project role

In order to prevent some users to see individual issues within a project, you have to set the security level on an issue. Here is the documentation regarding the security level.

Create a post function on the create transition on the workflow assigned to the current project with the code below.

string security_level = "Documentation";
string project_role = "Analysts";

if(isUserInRole(reporter, project, project_role) || 
   isUserInRole(assignee, project, project_role)) {
 	security = security_level;
}

The security level of the current issue is set to "Documentation" value, if the assignee, or the reporter has the specified project role("Analysts").

Assign to last role member

A SIL post function that assigns the current issue to the latest assignee (excluding the current one) who is a member of the specified project role:

SIL Code
string project_role = "Developers";
string[] previous_assignees = fieldHistory(key, "assignee");

for(number i = size(previous_assignees) - 1; i > 0; i -= 2) {
    string user = getElement(previous_assignees, i);
    if(user != assignee && isUserInRole(user, project, project_role)) {
       assignee = user;
       return;
    } 
}

//Optionally you can check and consider also reporter if no previous assignee was found with the specified role
if(reporter != assignee && isUserInRole(reporter, project, project_role)) {
   assignee = reporter;
}

Increase value of numeric field

A SIL post function that increases the value of a numerical field by a given value:

SIL Code
number increment = 2.5;
customfield_10000 += increment;

In the above example we assume that customfield_10000 is the id of a numeric custom field.

This can be used as a counter for example, for counting the times an issue has been reopened, by incrementing a number custom field with 1 on the Reopen Issue transition.

Set field value from user property value

A SIL post function that sets a field to the value of a user property:

SIL Code
customfield_10100 = getUserProperty(reporter, "country");

The reporter's country property value will be stored on issue in the text custom field with id customfield_10100.

Copy field value to parent

A SIL post function that sets a field value to the value(s) of the same field of the issue's parent issue:

SIL Code
if(!isNull(parent)) {
   parent.affectedVersions = affectedVersions;
}

When executing the transition, the parent's affected versions will be automatically updated with the values set on the current sub-task.

Copy value from field to field

A SIL post function that copies the value(s) of a field to another field of the same issue:

SIL Code
description = summary;

When executing the transition, the description field will be updated with the text from summary.

Add field value to parent

A SIL post function that adds the value(s) of a multi-valued field into the same field of the issue's parent issue:

SIL Code
if(!isNull(parent) && size(fixVersions) > 0) {
   parent.fixVersions = arraysConcat(parent.fixVersions, fixVersions);
}

When executing the transition, the fix versions for sub-task will be added to the parent's issue fix versions, if they don't already exist.

Set field value from parent

A SIL post function that sets a field value to the value(s) of the same field of the issue's parent issue:

SIL Code
if(!isNull(parent)) {
   components = parent.components;
}

When executing the transition, the components for current sub-task will be set to the values of parent's issue components.

Set issue security from user's project role

A SIL post function that sets the issue security level based on a project role to which the current user belongs:

SIL Code
string PROJECT_ROLE = "Developers";
if(isUserInRole(currentUser(), project, PROJECT_ROLE)) {
   securityLevel = "Internal";
} else {
   securityLevel = "Anybody";
}

This post function can be used on the Create transition to set a different issue security level depending on whether the issue is being created by a developer or by any other user.

Transition parent issue

Availability

This feature is available for the Jira server deployment option only. We plan to add it to the Cloud version in the near future.

A SIL post function that triggers a named transition on the parent issue of the current sub-task:

SIL Code
string TRANSITION_NAME = "Start Progress";
if(!isNull(parent)) {
   autotransition(TRANSITION_NAME, parent);
}

When executing the transition on sub-task, the "Start Progress" transition will be triggered on the parent issue, if this transition is valid for the current status of the issue.

Sending a custom email

Availability

This feature is available for the Jira server deployment option only. We plan to add it to the Cloud version in the near future.

A SIL post function that sends a custom email. For example, the reporter of the issue wants to be notified when the assignee resolves the issue. You can do this with the following code:

Custom Email
sendEmail(userEmailAddress(assignee), userEmailAddress(reporter), {}, "Issue resolved", "bodyTemplate.tpl", "en_US", key, "solution.txt");

The bodyTemplate.tpl contains the message body. In our example the bodyTemplate.tpl contains the following: 

Message Body Template
Hello $recipient$!

I just resolved the issue: $summary$. I spent $timeSpent$ for resolving it.
I attached the solution I found to resolve the issue.

Thanks,
$sender$

This sends an email from the issue assignee to the reporter and attaches the solution.txt file from the issue to the email.

Info

For more information about email templates, see Mail configuration.

Copy a parsed text to a field

Description of issue is set with a text automatically generated in the moment of issue creation:

SIL Code
description = "Current issue of type " + issueType + " was created on " + created + " by " + userFullName(reporter) + " in project " + project 
		+ " with the following summary: '" + summary + "'.\n"
		+ "It affects versions " + (string)affectedVersions + " and is expected to be resolved on " + dueDate + ".";


A customized text is added as a comment at the moment of issue closing:

SIL Code
string USER = currentUser();
string COMMENT = "Closed on " + updated + " by " + userFullName(USER) + " with fixed versions " + (string)fixVersions + ".";
addComment(key, USER, COMMENT);


Copy issue labels to a custom field:

SIL Code
customfield_10000 = labels;

Adding and removing single or set of items from multi valued fields

Adding components in subtasks to components in main issue:

SIL Code
string[] subtasks = subtasks(key);
for(string subtask in subtasks) {
    components = arraysConcat(components, %subtask%.components);
}


Removing reporters of linked issues from a Multi User field called Team:

SIL Code
string[] linkedIssues = linkedIssues(key);
for(string issue in linkedIssues) {
    Team = deleteElement(Team, %issue%.reporter);
}


Combining the values of several Multi User picker fields:

SIL Code
Team = arraysConcat(Team, UsersA);
Team = arraysConcat(Team, UsersB);
Team = arraysConcat(Team, UsersC);
for(string user in  arraysConcat(UsersD, UsersE)) {
    deleteElement(Team, user);
}

In the above example we set a multi-user picker field Team with the combined values of three multi-user picker fields UsersA, UsersB, UsersC minus the values of other two multi-user picker fields UsersD and UsersE.

Mathematical and date-time expression calculator

Getting the number of selected values from a custom field of type Multi Select in a numeric custom field:

SIL Code
Number = size(MultiSelectList);

where Number is the name of a numeric custom field and MultiSelectList is the name of the Multi Select custom field.


Updating Due Date with respect to current date (eg adding 2 days):

SIL Code
dueDate = currentDate() + "2d";


Setting total time spent by adding current date-time - date-time of last update:

SIL Code
timeSpent += currentDate() - updated;

Set a field as a function of other fields

Setting a custom field called Urgency from issue Priority and another numeric custom field called Impact.:

SIL Code
Urgency = Impact + priorityId;

Set a field from a set of rules based on regular expressions

Changing issue priority depending on issue description:

SIL Code
string TEXT = "REPORTEDPRIORITY=";
string REGEX = ".*\b" + TEXT + "[1-5]\b.*";
if(!matches(description, REGEX)) {
   logPrint("DEBUG", "Description doesn't contain reported priority in right format.");
   return;
}
number index = indexOf(description, TEXT) + length(TEXT); //starting index of priority id
string substr = substring(description, index, length(description));
index = indexOf(substr, " ");
if(index < 0) {
   index = length(substr);
}
priorityId = substring(substr, 0, index);

In the above example we use a string in the issue description  to alter the issue priority upon issue creation. The description must contain a string of form REPORTEDPRIORITY=1 for fetching the priority id.

We make use of the SIL™ routines matches, indexOf, length and substring. More useful string routines can be found in the String routines section.


Setting field based on reporter's email:

SIL Code
string EMAIL_REGEX = ".*@gmail\\.com$";
if(matches(userEmailAddress(reporter), EMAIL_REGEX)) {
   Defect = "Development";
}

The customer field Defect is a drop down with the values: None, Production, and Development, with Production as the default value.

The Defect value changes during the creation transition to Development if the reporter's email address matches a '@gmail.com' email address.


Setting watchers depending on the value of a custom field:

SIL Code
string CUSTOMER_REGEX = ".*\bBT\b.*";
for(string user in Customers) {
    if(matches(userFullName(user), CUSTOMER_REGEX)) {
       watchers = addElement(watchers, user);
    }
}

In the above example, if in the multi user picker Customers custom field there are selected users which contain the value "BT" in their full name, these users are set as watchers upon creation.


Setting a custom field (User Picker) based on the value of another custom field (Text Field):

SIL Code
string COUNTRY_NAME = "Germany";
if(contains(Country, COUNTRY_NAME)) {
   User = "Person1";
}

In the above example, if text custom field Country contains Germany it sets the User field to Person1.

Setting a field's default value based on other field

In the below example, we have a custom field called Billable which is of type Radio Button. This field is set to 'No' if the issue type is 'Bug' and is set to "Yes" for any other issue type.

SIL Code
if(issueType == "Bug") {
   Billable = "No";
} else {
  Billable = "Yes";
}

Set due date to current date at issue creation

A SIL™ post function that sets the due date to current date at issue creation, if no value was specifically set for the due date:

SIL Code
if(isNull(dueDate)) {
   dueDate = currentDate();
}

Setting assignee based on issue type and components

In the below example, if issue type is Bug, and it has component component1, the issue is assigned to user1, if it doesn't have component1 it is assigned to user2, and if issue type is not Bug it is assigned to user3.

SIL Code
if(issueType == "Bug") {
   if(elementExists(components, "component1")) {
      assignee = "user1";
   } else {
      assignee = "user2";
   }
} else {
   assignee = "user3";
}

Assign an issue to a reporter or a user depending on the project key

A SIL™ post function for assigning an issue to user tester if project is TST, or assign it to the issue reporter otherwise:

SIL Code
if(project == "TST") {
   assignee = "tester";
} else {
   assignee = reporter;
}

Turn issue unassigned when assigned to project leader

A SIL™ post function that turns an issue unassigned if it is assigned to the project leader:

SIL Code
if(assignee == projectPM(project)) {
   assignee = "";
}

Format text value of a custom field

Setting a text custom field with the formatted value of due date:

SIL Code
string FORMAT = "EEE, d MMM yyyy HH:mm:ss Z";
customfield_10000 = formatDate(dueDate, FORMAT);
The value of due date will be displayed in the given format. For more details check out the formatDate routine page.
 
 
Setting a text custom field with the formatted value of a number:


SIL Code
customfield_10000 = formatNumber(123456789 ,"###,###.###");
The value will be displayed as: "123,456.789". For more details check out the formatNumber routine page.

Add a comment to all blocked issues when this issue is transitioned

Availability

This feature is available for the Jira server deployment option only. We plan to add it to the Cloud version in the near future.

Adding a comment on behalf of the current user, to all blocked issues by the current issue transitioned:

SIL Code
string COMMENT = "Blocking issue " + key + " was transitioned.";
string[] issues = linkedIssues(key, "Blocks");
for(string issue in issues) {
    addComment(issue, currentUser(), COMMENT);
}

Automatically adding or removing watchers from a workflow transition

Availability

This feature is available for the Jira server deployment option only. We plan to add it to the Cloud version in the near future.

Setting current user as a watcher for the current issue:

SIL Code
watchers = addElement(watchers, currentUser());

Similar, you can remove the current user from the list of watchers during transition:

SIL Code
watchers = deleteElement(watchers, currentUser());

Availability

This feature is available for the Jira server deployment option only. We plan to add it to the Cloud version in the near future.

A SIL post-function that links the current issue to another issue by the Relates issue link type:

SIL Code
linkIssue(key, "TST-123", "Relates");

Close sub-tasks and duplicated linked issues when current issue is closed

Availability

This feature is available for the Jira server deployment option only. We plan to add it to the Cloud version in the near future.

A SIL post-function that closes all subtasks and duplicated issues for current issue when close issue transition is triggered:

SIL Code
string[] issues = arraysConcat(subtasks(key), linkedIssues(key, "Duplicates"));
for(string issue in issues) {
    autotransition("Close Issue", issue);
}   

Set/Read user property

Availability

This feature is available for the Jira server deployment option only. We plan to add it to the Cloud version in the near future.

A SIL™ post-function that sets the "country" property for the current user and puts it into a text custom field with id customfield_10100:

SIL Code
string USER = currentUser();
setUserProperty(USER, "country", "Romania"); 
customfield_10100 = getUserProperty(USER, "country");

Copy a cascading select custom field to a simple text custom field

A SIL™ post-function that copies the string representation of a cascading select custom field value with name "Cascade" into a text custom field with id customfield_10100:

SIL Code
customfield_10100 = Cascade;

The value displayed will be of form parent1|child1.

Fast-tracking (auto-transition) an issue through another action if a condition is true

Availability

This feature is available for the Jira server deployment option only. We plan to add it to the Cloud version in the near future.

Using this you can effectively have multiple start states for a workflow, with the initial state depending on, for example priority, reporter, or whatever.

This SIL™ post-function will automatically transition an issue if the provided condition holds true.

For example, if all new Critical priority issues should go to the Change Control Board for approval when the issue is created, this can be achieved with the following SIL™ post-function:

SIL Code
if(priority == "Critical") {
   autotransition("Ask For Approval", key);
}

Auto-transition parent when all sub-tasks are resolved

Availability

This feature is available for the Jira server deployment option only. We plan to add it to the Cloud version in the near future.

Put this SIL™ post-function on the sub-task workflow on transitions where the workflow could be set, typically Resolve Issue. If all sibling sub-tasks are resolved this will transition the parent issue using the provided action (eg Resolve Issue):

SIL Code
if(isNull(parent)) {
   return;
}
string[] subtasks = subtasks(parent);
for(string subtask in subtasks) {
    if(%subtask%.status != "Resolved") {
       return;
    }
}
//all sub-tasks are resolved so we can transition the parent
autotransition("Resolve Issue", parent);

Fire an event when condition is true

Availability

This feature is available for the Jira server deployment option only. We plan to add it to the Cloud version in the near future.

This SIL™ post-function can be used for conditional notification of only high priority issues for instance:

SIL Code
string[] PRIORITIES = {"Major", "Critical", "Blocker"};
string EVENT = "Critical Issue Created";
if(elementExists(PRIORITIES, priority)) {
   raiseEvent(EVENT, key, currentUser());
}

In the above example we assume that the event "Critical Issue Created" was added to the list of Jira events, sending mail notifications to the project lead for example.

Clone an issue and link on transition

Availability

This feature is available for the Jira server deployment option only. We plan to add it to the Cloud version in the near future.

Yes, this is available in other places, but this method offers a lot of flexibility (at the expense of a fancy GUI).

Clones the current issue to a new one and links it with the given link type name (eg Cloners, Duplicate etc). All system and custom fields are copied from the source issue.

If you want to override some of the field values rather than have them inherited from the source issue you can set their values after calling the cloneIssue routine.

The following SIL™ post-function clones the current issue, creates a Duplicate link type between the two issues, and sets the summary for the cloned issue:

SIL Code
string LINK_NAME = "Duplicate";
string clonedIssue = cloneIssue(key, LINK_NAME);
%clonedIssue%.summary = "This is a clone of issue " + key + ".";

The post-function should be placed immediate after the function: Re-index an issue to keep indexes in sync with the database.

Create one or more sub-tasks on transition, and optionally reopen existing sub-tasks

Availability

This feature is available for the Jira server deployment option only. We plan to add it to the Cloud version in the near future.

This SIL™ post-function function can be used to create several sub-tasks.

For instance, if you have an issue type that requires approval by two groups you might create a sub-task to represent each approval.

We can use this function to create two sub-tasks when parent is resolved, so that two departments can give approval. If a matching sub-task already exists it will be reopened for approval.

SIL Code
string[] SUMMARIES = {"First sub-task for approval", "Second sub-task for approval"};
string[] subtasks = subtasks(key);
    
for(string summ in SUMMARIES) {
    boolean exists = false;
    for(string subtask in subtasks) {
	if(%subtask%.summary == summ) {
	   autotransition("Reopen Issue", subtask);
           exists = true;
        }       
    }
    if(!exists) {
	createIssue(project, key, "Sub-task", summ);
    }
}

See also