Comment not inserted in the linked issue

Mouna Hammoudi September 5, 2022

I am developing a plugin for jira in scriptrunner, it is a postfunction so something needs to happen when a button is clicked.

 

I am trying to click on the "MounaFixReleased" menu item and then generate a comment for the issue links that are marked within the "Resolves" subcategory as shown above. So a new comment should be inserted for all the issues within the "Resolves" subsection in the screen above. The transition "MounaFixReleased" leads to itself, it is available from any status to itself. 

 

Screenshot (11).png

Capture.PNG

Basically, what I want to do is to insert a comment saying the following:

Capture.PNG
Here is my code, the problem is that the comment is not getting printed within the resolved issues. There is no comment, it is just empty.

I am using this line for testing purposes and the comment gets printed in the log file but nothing gets inserted in the issue:

log.warn("CAM 4 " + linkedissue.getKey()+ " "+ inputParameters+" "+defectComment+" "+inputParameters.getCommentValue())

import com.opensymphony.workflow.WorkflowContext
import com.atlassian.jira.issue.MutableIssue;
import com.atlassian.event.Event
import java.util.HashMap;
import java.util.List;
import org.ofbiz.core.entity.GenericValue;
import org.ofbiz.core.entity.GenericEntity;
import com.atlassian.jira.event.issue.AbstractIssueEventListener;
import com.atlassian.jira.event.issue.IssueEvent;
import com.atlassian.jira.issue.ModifiedValue;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.util.DefaultIssueChangeHolder;
import com.atlassian.jira.issue.util.IssueChangeHolder;
import org.apache.log4j.Logger
import com.atlassian.jira.component.ComponentAccessor
import org.ofbiz.core.entity.GenericDelegator;
import com.atlassian.jira.issue.changehistory.ChangeHistoryManager;
import com.atlassian.jira.issue.history.ChangeItemBean;
import com.atlassian.jira.issue.comments.Comment
import com.atlassian.jira.issue.changehistory.ChangeHistoryItem
import com.onresolve.scriptrunner.runner.util.UserMessageUtil
import com.atlassian.jira.config.SubTaskManager
import com.atlassian.jira.issue.Issue
import groovy.xml.MarkupBuilder
import com.atlassian.jira.config.properties.APKeys
import com.atlassian.jira.issue.link.LinkCollectionImpl;
import com.atlassian.jira.issue.link.IssueLink;
import com.atlassian.crowd.embedded.api.User;
import com.atlassian.jira.issue.comments.CommentManager;
import com.atlassian.jira.issue.link.IssueLinkManager;
import com.atlassian.jira.util.ErrorCollection;
import com.atlassian.jira.util.JiraUtils;
import com.atlassian.jira.workflow.JiraWorkflow;
import com.atlassian.jira.workflow.WorkflowManager;
import com.atlassian.jira.workflow.WorkflowTransitionUtil;
import com.atlassian.jira.workflow.WorkflowTransitionUtilImpl;
import com.atlassian.jira.workflow.function.issue.AbstractJiraFunctionProvider;
import com.opensymphony.module.propertyset.PropertySet;
import com.opensymphony.workflow.WorkflowException;
import com.opensymphony.workflow.loader.StepDescriptor;
import com.opensymphony.workflow.spi.SimpleStep;
import com.atlassian.jira.config.ConstantsManager
import com.atlassian.jira.workflow.ImmutableWorkflowDescriptor
import com.atlassian.jira.web.action.admin.workflow.ViewWorkflowStep
import com.opensymphony.workflow.loader.ActionDescriptor
import com.atlassian.jira.bc.issue.IssueService
import com.atlassian.jira.issue.IssueInputParametersImpl
import com.atlassian.jira.bc.issue.IssueService.IssueValidationResult
import com.atlassian.jira.user.ApplicationUser
import com.atlassian.jira.workflow.WorkflowTransitionUtilFactory
import com.atlassian.jira.workflow.TransitionOptions

def log = Logger.getLogger("atlassian-jira.log")

SubTaskManager subTaskManager = ComponentAccessor.getSubTaskManager();
List < IssueLink > linksOut = ComponentAccessor.getIssueLinkManager().getOutwardLinks(issue.getId())
List < IssueLink > linksIn = ComponentAccessor.getIssueLinkManager().getInwardLinks(issue.getId())
ApplicationUser applicationUser = getCurrentUser();
ArrayList < Issue > issuesWithValidateError = new ArrayList < Issue > ();
List < IssueLink > links = new ArrayList < IssueLink > ()

log.warn("resolved " + linksOut.size() + " links in size " + linksIn.size() + " " + applicationUser)

log.warn("THIS IS MY LINK LINKSOUT " + linksOut.size())

for (IssueLink link in linksOut) {
if (link.getDestinationObject().getIssueTypeId().equals("5")) {
log.warn("THIS IS MY LINK everything " + link.getLinkTypeId() + " " + link.getDestinationObject().getKey())

links.add(link)
}

}
log.warn("THIS IS MY LINK linksIn " + linksIn.size())

for (IssueLink link in linksIn) {
if (link.getDestinationObject().getIssueTypeId().equals("5")) {
log.warn("THIS IS MY LINK everything " + link.getLinkTypeId() + " " + link.getDestinationObject().getKey())

links.add(link)
}
}

for (IssueLink link in links) {

log.warn("THIS IS MY LINK MOUNA " + link + link.getDestinationObject().getKey())
}
if (links.isEmpty()) {

log.warn("No linked Defect-Issues found.");
return;
}
User loggedInUser = getCurrentUser().getDirectoryUser();
log.warn("resolved transition 1" + loggedInUser)
WorkflowManager workflowManager = ComponentAccessor.getWorkflowManager();
log.warn("resolved transition 2")

JiraWorkflow workflow = workflowManager.getWorkflow(issue);
log.warn("resolved transition 3")

List < Object > actions = workflow.getLinkedStep(issue.getStatus()).getActions();
log.warn("resolved transition 4")

def wfd = workflow.getDescriptor();
log.warn("resolved transition 5")

def actionName = wfd.getAction(transientVars["actionId"] as int).getName();
log.warn("resolved transition 6 " + actionName)

def actionId = transientVars["actionId"] as int;
log.warn("resolved transition 7 " + actionId)

log.warn("This is the last action " + actionName);
List < String > sourceObjectLinkList = new ArrayList < String > ();

def targetStatus = getTargetStatus(issue);
log.warn("resolved transition targetStatus " + targetStatus + "end");

//transition(actionId, links)
for (IssueLink link: links) {

String foundID = foundActionID(link);

if (foundID == null) {

log.error("Action for Issue " + link.getKey() + " not found!");
issuesWithValidateError.add(link);
continue;
}
log.warn("CAM 0 " + foundID);

PerformTransition(link.getDestinationObject(), foundID, link.getSourceObject());
log.warn("links tostring " + links.toString());

sourceObjectLinkList.add(link.getDestinationObject().getKey());
log.warn("MOUNA COMMENT 11" + link.getDestinationObject().getKey())

}
log.warn("MOUNA COMMENT 22" + sourceObjectLinkList)
String fixComment = "The following Defects resolved by this Fix were notified: ISSUEKEYS.";

fixComment = fixComment.replaceAll("ISSUEKEYS", sourceObjectLinkList.toString());
log.warn("MOUNA CAMELIA COMMENT " + fixComment)

CommentManager commentManager = ComponentAccessor.getCommentManager();
// add comment but do NOT fire event
commentManager.create(issue, getCurrentUser(), fixComment, false);




/*
PERFORM TRANSITION
*/
void PerformTransition(Issue linkedissue, String transitionToBeDone, Issue sourceObject) {
def defectComment = "Fix FIXSUMMARY[ISSUEKEY] has been released by USERNAME[USER].";

log.warn("CAM 1 " + transitionToBeDone)

IssueService issueService = ComponentAccessor.getIssueService()
log.warn("CAM 1 " + transitionToBeDone)





ApplicationUser currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
log.warn("CAM 2")

TransitionOptions transitionOptions = new TransitionOptions.Builder()
.skipConditions()
.skipPermissions()
.skipValidators()
.build()
log.warn("CAM 3")
int transitionToBeDoneInt = transitionToBeDone as Integer
String status = getTargetStatus(sourceObject) as String;
def constantsManager = ComponentAccessor.getConstantsManager()

def statusName = constantsManager.getStatus(status).getName();
log.warn("STatus" + status)

def inputParameters = issueService.newIssueInputParameters()
log.warn("CAM comment " + defectComment + " summary: " + sourceObject.getSummary())

defectComment = defectComment.replaceAll("FIXSUMMARY", sourceObject.getSummary());
log.warn("CAM comment 2" + defectComment)

defectComment = defectComment.replaceAll("ISSUEKEY", sourceObject.getKey()).replaceAll("USERNAME", currentUser.getDisplayName());
log.warn("CAM comment 3" + defectComment)


defectComment = defectComment.replaceAll("USER", currentUser.getName());
log.warn("CAM comment 4 " + defectComment)

defectComment = defectComment.replaceAll("released", "set to \"" + statusName + "\" ");
log.warn("CAM comment 5 " + defectComment)

inputParameters.setComment(defectComment)
IssueService.TransitionValidationResult result = issueService.validateTransition(currentUser,
linkedissue.getId(),
transitionToBeDoneInt,
inputParameters,
transitionOptions);
log.warn("CAM 4 " + linkedissue.getKey()+ " "+ inputParameters+" "+defectComment+" "+inputParameters.getCommentValue())

log.warn("USER NAME MOUNA ")



//ApplicationUser myuser=ComponentAccessor.getUserManager().getUserByKey("itracfix");

//log.warn("USER NAME MOUNA " + myuser.getDisplayName())


try {
if (result.isValid()) {
log.warn("CAM 5 " + defectComment)

issueService.transition(currentUser, result)
log.warn("CAM 6 " + defectComment)


}

} catch (Exception e) {
log.warn("CAM 6 " + e)

log.warn(result.getErrorCollection().getErrors());

}

}



/*
GET CURRENT USER
*/
ApplicationUser getCurrentUser() {
ApplicationUser user = ComponentAccessor.getJiraAuthenticationContext().getUser();
if (user == null) {
String defaultUser = gc.getValue("user");
user = ComponentAccessor.getUserManager().getUserByName(defaultUser);
}
return user;
}




/*
GET TARGET STATUS
*/

def getTargetStatus(Issue issue) {
log.warn("resolved inside target")

def targetStatus = "";
try {
List currentSteps = (ArrayList) transientVars.get("currentSteps");
SimpleStep simpleStep = currentSteps.get(0);
int actionId = simpleStep.getActionId();
int beforeStepId = simpleStep.getStepId();
def workflow = ComponentAccessor.workflowManager.getWorkflow(issue)
ActionDescriptor ad = workflow.getDescriptor().getAction(actionId);
int afterStep = ad.getUnconditionalResult().getStep();
log.warn("resolved transition target " + afterStep)
log.warn("resolved transition target last " + ComponentAccessor.workflowManager.getNextStatusIdForAction(issue, transientVars['actionId'] as int))

targetStatus = ComponentAccessor.workflowManager.getNextStatusIdForAction(issue, transientVars['actionId'] as int)
def constantsManager = ComponentAccessor.getConstantsManager()

def statusName = constantsManager.getStatus(targetStatus).getName();
log.warn("resolved transition target " + targetStatus + "status name " + statusName)

} catch (Exception exception) {
log.error("getTargetStatus threw exception: " + exception.getMessage());
}
return targetStatus;
}




/*
FOUND ACTION ID
*/
String foundActionID(IssueLink issueLink) {

String id = null;
log.warn("foundActionID 1 here")
Issue issue = issueLink.getDestinationObject()
List < StepDescriptor > actionDescriptorList = ComponentAccessor.workflowManager.getWorkflow(issue).getDescriptor().getSteps();
log.warn("foundActionID 2 here")

List < ActionDescriptor > myStepDescriptor = null;
log.warn("foundActionID 3 here" + actionDescriptorList)
Boolean foundAction = false;
log.warn("foundActionID 1" + foundAction)
for (StepDescriptor stepDescriptor: actionDescriptorList) {

if (stepDescriptor.getName().equals(issue.getStatusObject().getName())) {

myStepDescriptor = stepDescriptor.getActions();
log.warn("foundActionID2 " + myStepDescriptor)

break;
}
}

for (ActionDescriptor actionDescriptor: myStepDescriptor) {
log.warn("foundActionID3 ")
WorkflowManager workflowManager = ComponentAccessor.getWorkflowManager();
JiraWorkflow workflow = workflowManager.getWorkflow(issue);


List < String > actionIDs = ["1021", "1031", "1041", "1051", "1061", "1071", "1081", "1091"]

if (actionIDs.contains(String.valueOf(actionDescriptor.getId()))) {

id = String.valueOf(actionDescriptor.getId());
foundAction = true;
log.warn("foundActionID5 " + id)

break;
}
}

if (!foundAction)
return null;

return id;
}

 

1 answer

0 votes
Ram Kumar Aravindakshan _Adaptavist_
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
September 5, 2022

Hi @Mouna Hammoudi

I have a doubt to clarify with you, i.e. in your summary, you mentioned:-

Comment not inserted in the linked issue

However, in your description, you mentioned:-

Here is my code, the problem is that the comment is not getting printed within the resolved issues. There is no comment, it is just empty.

So, are you trying to add the comment to the source issue when a linked issue transitions do Done? 

Thank you and Kind regards,

Ram

Mouna Hammoudi September 6, 2022

Screenshot (11).png

 

I am trying to click on the "MounaFixReleased" menu item and then generate a comment for the issue links that are marked within the "Resolves" subcategory as shown above. So a new comment should be inserted for all the issues within the "Resolves" subsection in the screen above. The transition "MounaFixReleased" leads to itself, it is available from any status to itself. 

Suggest an answer

Log in or Sign up to answer