How to Create an Organisational Risk Register with the SoftComply Risk Manager to Re-Use Risks

Overview:

We will create a solution where we have one “Risk Register” project that contains all the risks in your organisation. In this project the mappings between the risk register and the project specific risks are being managed. Next, we add the logic that clones the risks of the risk register in the specific risk projects while keeping the data up to date based on the previously created mapping! Now, every time that you add a risk to the risk register and apply it to a specific product, the risks in the specific risk projects are updated in a single click!

Here is what you need to do!

Prerequisites:

You have Jira Administration permissions and you have also installed CPrime Powerscript app (or similar e.g. Adaptavist Scriptrunner) in your Jira server.

  1. Create a separate risk project just for the Risk Register (RR). In this project you will keep all your risks that you later will map to a specific project/product/component risk issues.

  2. Create as many risk projects as you need in order to manage your system/product/service risks. Each of these projects will have its own risks, its own risk model and own mitigation/verification actions. You can push the risks from the Risk Register project to these projects without having to add them manually.

  3. Add a new multiple choice select list field to your Risk Register project to describe the relationship between the Risk Register risks and specific products/projects. This way you can easily map which RR risk is applied to a specific product.

  4. Optional: Create a new issue link type to illustrate the relationship between the RR risks and the product specific risks. Map this newly created link type to your RR table.

  5. Create new SIL script files: one script for handling how the new product specific risks are created (i.e. cloning of the RR risk to the product specific risk project) and another script for updating the existing risks (if RR risk changes, the changes are also applied to the product specific cloned risk). create_new_clone_from_rr.sil:

    logPrint("DEBUG", "Found new event. Starting to handle it with RR Issue Create event listener!"); logPrint("DEBUG", "Issue created with key -" + key + " in status - " +status + " in project-" + project); //Change this project key according to your register project string risk_register_project_key="RR"; //Change this link type name if you use something else! // In this example we created our own link type called "Risk Register links" string LINK_NAME = "Risk Register links"; string[] custom_fields_mapping; //Custom field ID-s for future use! Just check those before you start! //Then it is easier later to modify code! //hazard=customfield_10303; //haz_situation=customfield_10312; //harm=customfield_10306 //cause=customfield_10305 //severity=customfield_10308 //probability=customfield_10313 // etc. //If created event is not in RR project then we do not care about it! if(project==risk_register_project_key) { logPrint("DEBUG", "Products-"+customfield_10400 + " size-"+size(customfield_10400)); // customfield_10400 is a field "Product" - We look for the values of this cf if(size(customfield_10400)>0) { for(string projectElem in customfield_10400) { //take all links by link type Risk Register links with outward direction //-1, 0, 1 :Negative means inward links. Positive means outward links. Use zero to get both outward and inward links. string[] linkedIssues = linkedIssues(key, LINK_NAME, 1); boolean alreadyExists=false; if (size(linkedIssues)>0) { logPrint("DEBUG", "Found outward linked issues"); //Now lets check if we already have link with this external project! for(string issue in linkedIssues) { logPrint("DEBUG", "Linked issue -" + %issue%.key + " is in status - " +%issue%.status); if (%issue%.project==projectElem) { logPrint("INFO", "Found that this project already has link established!"); alreadyExists=true; break; } } } //If we have no link to this project! Thus we need to create one! if (!alreadyExists) { //here we can tell all the cf values that we want to initiate in destination. //Thus if you have more fields you wish to populate from RR to another project //just extend the string by adding first cf id and then cf value separating them with | custom_fields_mapping = "customfield_10303|"+customfield_10303+"|customfield_10312|"+customfield_10312 +"|customfield_10308|"+customfield_10308+"|customfield_10305|"+customfield_10305+"|customfield_10306|"+customfield_10306+"|customfield_10313|"+customfield_10313; logPrint("DEBUG", "projectElem -"+projectElem + " cf-s ->"+custom_fields_mapping); //lets create new issue string created_issue=createIssue(projectElem, "", "Task", "Summary","","","","","","",custom_fields_mapping); //lets link the newly created issue to RR linkIssue(key, created_issue , LINK_NAME); } } } else logPrint("DEBUG", "No products were assigned to this RR risk!"); } else { logPrint("DEBUG", "Not RR project event!"); return; }

    update_rr_linked_issues.sil:

    logPrint("DEBUG", "Found new event. Starting to handle it with RR Issue Update event listener!"); logPrint("DEBUG", "Issue updated with key -" + key + " in status - " +status + " in project-" + project); //Change this project key according to your register project string risk_register_project_key="RR"; //Change this link type name if you use something else! // In this example we created our own link type called "Risk Register links" string LINK_NAME = "Risk Register links"; //Custom field ID-s for future use! Just check those before you start! //Then it is easier later to modify code! //hazard=customfield_10303; //haz_situation=customfield_10312; //harm=customfield_10306 //cause=customfield_10305 //severity=customfield_10308 //probability=customfield_10313 // etc... //If created event is not in RR project then we do not care about it! if(project==risk_register_project_key) { // if nothing is linked to this specific RR risk, then we can exit this script // but first we need to detect if products list was changed // if products was changed, then we throw Issue created event! // issue created event is handled by another script! if (size(linkedIssues(key)) == 0) { //This is usecase where RR risk has no linked issues, but the products list was changed! JFieldChange [] changes = lastIssueChanges(key); for(number i = 0; i < size(changes); i++) { if(changes[i].field=="Product") { raiseEvent("Issue Created", key, currentUser()); } } logPrint("DEBUG", "No linked issues found on this issue!"); return; } else { //take all links by link type Risk Register links with direction "tbd" //-1, 0, 1 :Negative means inward links. Positive means outward links. Use zero to get both outward and inward links. string[] linkedIssues = linkedIssues(key, LINK_NAME, 1); if (size(linkedIssues)==0) { //This is usecase where RR risk has some linked issues, but the products specific links were not found and products list was changed! logPrint("DEBUG", "No linked issues with suitable link type not found on this issue!"); JFieldChange [] changes = lastIssueChanges(key); for(number i = 0; i < size(changes); i++) { if(changes[i].field=="Product") { raiseEvent("Issue Created", key, currentUser()); } } logPrint("DEBUG", "No linked issues found on this issue!"); return; } else //found correct link types! { //This is usecase where RR risk has linked product specific issues and we need to update these! for(string issue in linkedIssues) { logPrint("DEBUG", "Linked issue -" + %issue%.key + " is in status - " +%issue%.status); JFieldChange [] changes = lastIssueChanges(key); boolean needsTransition = false; for(number i = 0; i < size(changes); i++) { logPrint("DEBUG","CHANGE U:" + changes[i].user + " Field:" + changes[i].field + " Val:" + changes[i].oldVal + " -> " + changes[i].newVal); switch (changes[i].field) { case "Hazard": %issue%.customfield_10303=changes[i].newVal; needsTransition = true; break; case "Hazardous Situation": %issue%.customfield_10312=changes[i].newVal; needsTransition = true; break; case "Harm": %issue%.customfield_10306=changes[i].newVal; needsTransition = true; break; case "Cause": %issue%.customfield_10305=changes[i].newVal; needsTransition = true; break; case "Severity": %issue%.customfield_10308=customfield_10308; needsTransition = true; break; case "Probability": %issue%.customfield_10313=customfield_10313; needsTransition = true; break; case "summary": %issue%.summary=changes[i].newVal; needsTransition = true; break; case "Product": raiseEvent("Issue Created", key, currentUser()); break; default: logPrint("DEBUG", "Default of SWITCH - did not find field to update!"); } } if(needsTransition) { autotransition("RR Updated", %issue%.key); } logPrint("DEBUG", "Success!"); } } } } else { logPrint("DEBUG", "Not RR project event!"); return; }
  6. Create two event listeners. The first one is listening to only the “Issue Created” event and the second one to the “Issue Updated Event”. Both use corresponding SIL scripts from the previous step.

  7. Optional: If you’d like to know when the RR risk is updated and when this update is applied to your product specific risk, you should customize your workflow and always transition issue after the update to a specific state (e.g. “Needs review” or “Updated”, etc).

  8. Start using your Risk Register and enjoy being efficient with Jira!

Example:

We have a Risk Register project with 2 new columns in the beginning of the table: Product and Related Risks. The first column is a multi select field type, and the second one is an Issue Link type (link type you can see below).

The Product field has three options here: SYS1, SYS2, SYS3 as seen from the image below. All those are reflecting the product specific risk project keys. We now have another risk project with a project key SYS1 and it consists of the System 1 specific risks.

The SYS1 project has the following view now:

On the image above you can see that we have added one additional column to the beginning of the table - Status. That column reflects the issue status in the workflow. More on how to do that at: https://softcomply.atlassian.net/wiki/spaces/SS/pages/1590132751 and https://softcomply.atlassian.net/wiki/spaces/SS/pages/1590427661

As stated before we have added a special link type to describe the relationship between the Risk Register risk and the product specific risk:

Also we changed the workflow of the project SYS1. If the Risk Register sends updates to product specific project risks like SYS1 risks, then the SYS1 risks are always transitioned to the status “RR Updated”. This allows us to easily see when something has been updated and needs to be reviewed! Fore more information on how to update workflows, please read more at: https://softcomply.atlassian.net/wiki/spaces/SS/pages/1550123017

Finally, the 2 scripts you have added to the SIL Manager should also be used in the SIL listeners. From the image below you can see that the first and the third listeners are published on this page! Other three are not relevant for this exercise.