The following scripts and instructions are provided as-is, no warranties attached; use with care.

Please feel free to adapt them to your needs. 

Note: We don't provide support for these apps; if you have doubts concerning its usage, please contact Cprime support.

Overview

Cprime provides a set of Jira apps that allow the implementation of powerful custom automation rules, including Power Scripts, Power Custom Fields for Jira, and Power Actions for Jira.

All of those come with the SIL (Simple Issue Language) engine that provides an abstraction layer over the internal of Atlassian APIs, allowing you to easily implement and maintain Jira automation-related scripts.



Power ScriptsPower Custom Fields for JiraPower Actions for Jira
used to...implement automation rulesimplement custom fields whose values are derived from custom logicimplement buttons/UI elements, having a custom logic
triggering
  • workflow transitions: conditions, validators, post-functions 
  • event listeners
  • schedulable
  • whenever shown
N/A


Use cases

Create a Test Set, Test Execution or a Test Plan programmatically

This use case requires the Power Scripts Fields app.

Sometimes you may need to create a Test Set, a Test Execution, or a Test Plan programmatically.

The following example shows how to create a Test Execution; it can easily be adapted for other Xray issue types. You'll need to update the corresponding REST API endpoint for adding the tests to that entity.

//Define struct for HTTP request
struct change {
    string [] add;
    string [] remove;
}

string jiraBaseUrl = getJIRABaseUrl();
// string jiraBaseUrl = "https://yourjiraserver.example.com";
string jiraUsername = "someuser";
string jiraPassword = "somepass";


function addTestsToTestExecution(string testExecKey, string[] testList){
    //Create array/struct
    change addRequest;
    
    //Add data to array/struct
    addRequest.add =  testList;
    
    string endpointUrl = #{jiraBaseUrl} + "/rest/raven/1.0/api/testexec/" + #{testExecKey} + "/test";
    
    HttpRequest request;
    HttpHeader authHeader = httpBasicAuthHeader(jiraUsername, jiraPassword);
    request.headers += authHeader;
    HttpHeader header = httpCreateHeader("Content-Type", "application/json");
    request.headers += header;
    
    //Post data and get response
    string result = httpPost(endpointUrl, request, addRequest);
    logPrint("DEBUG", "result: " + #{result});
    return true;
}


string projectKey = "BOOK";
string parentIssueKey = "";
string issueType = "Test Execution";
string issueSummary = "test execution created automatically from a SIL script";
string testExecKey = createIssue(projectKey, parentIssueKey, issueType, issueSummary);
logPrint("DEBUG", "On the project " + projectKey + ", issue " + testExecKey + " was created.");

string [] testList = { "BOOK-14", "BOOK-15" };
// string jql = "project = BOOK and issuetype = Test";
// string [] testList = selectIssues(jql);

addTestsToTestExecution(testExecKey, testList);



Please check SIL's documentation for more info on createissue() and on httpPost().

Validate requirement before allowing to make a transition

This use case requires the Power Scripts Fields app.

Sometimes you may need to assure that the requirement is actually OK before transitioning it to some status, or before resolving it.

The following script validates the requirement based on the tests executed for the version assigned to the requirement issue.

You can either make the validation based on the existence of failed tests  (i.e. requirement status is "NOK") or, in a more complete way by making sure all of them are passing (i.e. requirement status is "OK").


     


string version = join(fixVersions,"");
string jql = "key = "+ #{key} +  " and issue in requirements('OK','" + #{project} + "','"+#{version} + "')";
logPrint("DEBUG",jql);
int numberOfIssues = countIssues(jql);
if (numberOfIssues != 1) {
    return false, "Requirement Status", "Some tests need to be executed. You must assure that they pass before making the transition.";
}
return true;

Reopen/transition linked Tests to a requirement/user story

This use case requires the Power Scripts Fields app.

Whenever you change the specification of a requirement/user story, you most probably will need to review the Tests that you have already specified.

The following script tries to make a transition on all linked Tests to a requirement. You can hook it to a post-function on some transition of the requirement/user story.


     


Please check SIL's documentation for more info on autotransition().


string transition = "Reopen Issue"
string jql = "issue in requirementTests('" + #{key} + "')";
string [] keys = selectIssues(jql);
for(string testKey in keys) {
 logPrint("DEBUG","test_key: " + #{testKey});
 autotransition(transition, testKey);
}


Trigger CI/CD builds

The following examples show how you can implement some actions, using Power Actions, to trigger a build/job in a CI/CD tool such as Jenkins, Bamboo, or others.

There are some come common steps:

  1. define some global variables, if you want, to have the details about the CI/CD tool; this can be done using SIL Manager by creating a properties file named sil.properties
    1. JENKINS_BASE_URL=http://myjenkins.example.com
      JENKINS_USERNAME=admin
      JENKINS_PASSWORD=fa02840152aa2e4da3d8db933ec708d6
      JENKINS_TOKEN=iFBDOBhNhaxL4T9ass93HRXun2JF161Z
      BAMBOO_BASE_URL=http://mybamboo.example.com
      BAMBOO_USERNAME=admin
      BAMBOO_PASSWORD=admin
  2. create a Power Actions Custom Field
  3. You can configure it to just be available for some issue types (e.g. Test Plan)
  4. Configure the button/s and its/their logic (i.e. Condition, Screen, and Action scripts). You may create one or more buttons.
    1. For more info on the related scripts, please see the instructions ahead.

Trigger Jenkins job and report back to Test Plan

In this case, we're going to give users the ability to trigger an existing job/project in Jenkins.

We'll obtain the list of available jobs/projects using Jenkins REST API which we'll present to the user. Then, we trigger the build after the user confirms some options.

Jenkins configuration

In Jenkins, we need to generate an API token for some user, which can be done from the profile settings page.

 

At the project level, we need to enable remote build triggers, so we can obtain an "authentication token" to be used in the HTTP request afterwards.

The project itself is a normal one; the only thing relevant to mention is that this project is a parameterized one, so it receives a TESTPLAN variable, that in our case will be coming from Jira.

  


The final task submits the results linking the Test Execution to the Test Plan passed as an argument.

Power Actions configuration

We need to configure the Power Action custom field created earlier, namely the  Condition, Screen, and Action Scripts; this from the custom field configuration as follows.


number ENABLED = 1;
number DISABLED = 2;
number HIDDEN = 3;

return ENABLED;
struct job {
    string name;
}

struct answer {
    job [] jobs;
}

persistent string defaultJobName = "";

string jenkinsBaseUrl = silEnv("JENKINS_BASE_URL");
string jenkinsUsername = silEnv("JENKINS_USERNAME");
string jenkinsPassword = silEnv("JENKINS_PASSWORD");
 
function getJenkinsJobs(){
    string requestURL = #{jenkinsBaseUrl} + "/api/json";
    
    HttpRequest request;
    HttpHeader authHeader = httpBasicAuthHeader(jenkinsUsername, jenkinsPassword);
    request.headers += authHeader;
    HttpHeader header = httpCreateHeader("Content-Type", "application/json");
    request.headers += header;
     
    //Post data and get response
    answer ans = httpPost(requestURL, request);
    logPrint("DEBUG", "answer: " + #{ans});
    return ans.jobs;
}

boolean isDisabled = false;
string [] jobs =  getJenkinsJobs();
string [] ret = BA_setActionTitle("Trigger CI/CD build" + defaultJobName);
ret = BA_createSelectList("job", jobs, defaultJobName, isDisabled);
ret = arraysConcat(ret, BA_createSingleCheckbox("report to this test plan", true, isDisabled));
ret = arraysConcat(ret, BA_createSingleCheckbox("set as default job", false, isDisabled));
return ret;
struct job {
    string name;
}

struct answer {
    job [] jobs;
}

string jenkinsBaseUrl = silEnv("JENKINS_BASE_URL");
string jenkinsUsername = silEnv("JENKINS_USERNAME");
string jenkinsPassword = silEnv("JENKINS_PASSWORD");
string token = silEnv("JENKINS_TOKEN");

//string jobName = "java-junit-calc";
string jobLabel = getElement(argv, 0);
string jobName = getElement(argv, 1);
string reportToTestPlanLabel = getElement(argv, 2);
boolean reportToTestPlan = BA_isChecked(argv, reportToTestPlanLabel); //getElement(argv, 3);
string setAsDefaultJobLabel = getElement(argv, 4);
boolean setAsDefaultJob = BA_isChecked(argv, setAsDefaultJobLabel); //getElement(argv, 5);
persistent string defaultJobName = "";
  
function triggerJenkinsBuild(string testPlanKey, string jobName){
    string requestURL = #{jenkinsBaseUrl} + "/job/" + #{jobName} + "/buildWithParameters?token=" + #{token} + "&TESTPLAN=" + #{testPlanKey};
    
    HttpRequest request;
    HttpHeader authHeader = httpBasicAuthHeader(jenkinsUsername, jenkinsPassword);
    request.headers += authHeader;
    HttpHeader header = httpCreateHeader("Content-Type", "application/json");
    request.headers += header;
     
    //Post data and get response
    string result = httpPost(requestURL, request);
    logPrint("DEBUG", "result: " + #{result});
    return true;
}

if (setAsDefaultJob){
    defaultJobName = jobName;
}
if (reportToTestPlan) {
    triggerJenkinsBuild(key, jobName);
} else {
    triggerJenkinsBuild("", jobName);
}


A new button will be available on the custom field. You'll need to add it to the view issue screen.

  

From the "job" dropdown you can select the job you want to run. You can also specify whether you want to report the results back to the current Test Plan and if you want to set that job as the default one for that Test Plan (so it pre-selected the next time you invoke it).


Trigger Bamboo plan and report back to Test Plan

In this case, we're going to give users the ability to trigger an existing job/project in Jenkins.

We'll obtain the list of available plans using Bamboo REST API which we'll present to the user. Then, we trigger the build after the user confirms some options.

Bamboo configuration

The project itself is a normal one; the only thing relevant to mention is that this project is a parameterized one, so it receives a TESTPLAN variable, that in our case will be coming from Jira.



The final task submits the results linking the Test Execution to the Test Plan passed as an argument.


Power Actions configuration

We need to configure the Power Action custom field created earlier, namely the  Condition, Screen, and Action Scripts; this from the custom field configuration as follows.


number ENABLED = 1;
number DISABLED = 2;
number HIDDEN = 3;

return ENABLED;
 struct plan {
    string name;
    string key;
}

struct plans {
    plan [] plan;
}


struct answer {
   plans plans;
}

string bambooBaseUrl = silEnv("BAMBOO_BASE_URL");
string bambooUsername = silEnv("BAMBOO_USERNAME");
string bambooPassword = silEnv("BAMBOO_PASSWORD");
persistent string defaultBambooPlanName = "";

function getBambooPlans(){
    string requestURL = #{bambooBaseUrl} + "/rest/api/latest/plan.json";
    
    HttpRequest request;
    HttpHeader authHeader = httpBasicAuthHeader(bambooUsername, bambooUsername);
    request.headers += authHeader;
    HttpHeader header = httpCreateHeader("Content-Type", "application/json");
    request.headers += header;
     
    //Post data and get response
    answer ans = httpGet(requestURL, request);
    logPrint("DEBUG", "answer: " + #{ans});

    string [] jobs;
    for(plan plan in ans.plans.plan) {
     logPrint("DEBUG","plan_key: " + plan.key);
     jobs = addElement(jobs, plan.key);
    }

    return jobs;
}

boolean isDisabled = false;
string [] jobs =  getBambooPlans();
string [] ret = BA_setActionTitle("Trigger CI/CD build"+defaultBambooPlanName);
ret = BA_createSelectList("plan", jobs, defaultBambooPlanName, isDisabled);
ret = arraysConcat(ret, BA_createSingleCheckbox("report to this test plan", true, isDisabled));
ret = arraysConcat(ret, BA_createSingleCheckbox("set as default plan", false, isDisabled));
return ret;
string bambooBaseUrl = silEnv("BAMBOO_BASE_URL");
string bambooUsername = silEnv("BAMBOO_USERNAME");
string bambooPassword = silEnv("BAMBOO_PASSWORD");

string planLabel = getElement(argv, 0);
string planName = getElement(argv, 1);
string reportToTestPlanLabel = getElement(argv, 2);
boolean reportToTestPlan =  BA_isChecked(argv, reportToTestPlanLabel); //getElement(argv, 3);
string setPlanAsDefaultLabel = getElement(argv, 4);
boolean setPlanAsDefault = BA_isChecked(argv, setPlanAsDefaultLabel); //getElement(argv, 5);
persistent string defaultBambooPlanName = "";

function triggerBambooBuild(string testPlanKey, string planName) {
    string requestURL = #{bambooBaseUrl} + "/rest/api/latest/queue/" + #{planName};
    // "default&ExecuteAllStages=true&bamboo.TESTPLAN=#{testPlanKey}"

    HttpRequest request;
    HttpHeader authHeader = httpBasicAuthHeader(bambooUsername, bambooPassword);
    request.headers += authHeader;
    HttpHeader header = httpCreateHeader("Content-Type", "application/x-www-form-urlencoded");
    request.headers += header;
    
    request.parameters += httpCreateParameter("default", "true");
    request.parameters += httpCreateParameter("ExecuteAllStages", "true");
    request.parameters += httpCreateParameter("bamboo.TESTPLAN", testPlanKey);
     
    //Post data and get response
    string result = httpPost(requestURL, request);
    logPrint("DEBUG", "result: " + #{result});
    return true;
}


if (setPlanAsDefault) {
    defaultBambooPlanName = planName;    
}

if (reportToTestPlan) {
    triggerBambooBuild(key, planName);
} else {
    triggerBambooBuild("", planName);
}


A new button will be available on the custom field. You'll need to add it to the view issue screen.

  

From the "plan" dropdown you can select the plan you want to run. You can also specify whether you want to report the results back to the current Test Plan and if you want to set that job as the default one for that Test Plan (so it pre-selected the next time you invoke it).

Display progress information, as text, on Test Execution issues

The idea is to display information about the number of passed, failed, etc tests as text, on Test Execution issues using a specific custom field.

Therefore, we'll use the Power Custom Fields app.

  1. create the custom script using the "PCFU - SIL Script Custom Field" type
    1.    
  2. configure the custom field by defining the respective SIL script; in this case we'll just return the value of "Test Execution Status" custom field, as it already provides a textual representation with what we need


Now you can add this custom field on the Test Execution view issue screen if you want. In this specific case, it would be a bit redundant though, as the progress bar bellow shows those values.


You can also add it as a column on panels that show Test Executions (e.g. on the Test Plan).


     

Learn more