Last active
October 26, 2016 12:14
-
-
Save jtbonhomme/50765706150e85468d8292dee9d0c82a to your computer and use it in GitHub Desktop.
Perfoms Epic trasitions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import com.atlassian.crowd.embedded.api.User | |
import com.atlassian.jira.user.ApplicationUser | |
import com.atlassian.jira.bc.issue.search.SearchService | |
import com.atlassian.jira.component.ComponentAccessor | |
import com.atlassian.jira.issue.Issue | |
import com.atlassian.jira.issue.IssueManager | |
import com.atlassian.jira.web.bean.PagerFilter | |
import com.atlassian.jira.issue.IssueInputParameters | |
import com.atlassian.jira.bc.issue.IssueService.TransitionValidationResult | |
import com.atlassian.jira.bc.issue.IssueService | |
import com.atlassian.jira.workflow.JiraWorkflow | |
import com.atlassian.jira.workflow.WorkflowManager | |
import com.atlassian.jira.ComponentManager; | |
import com.opensymphony.workflow.loader.ActionDescriptor; | |
enableCache = {-> false} | |
def text = "" | |
// Performs transition to an actionId (ie status) | |
private boolean transitionIssue(Issue issue, int actionId, User user) { | |
boolean result = false; | |
IssueService issueService = ComponentManager.getInstance().getIssueService(); | |
IssueService.IssueResult transResult; | |
IssueInputParameters issueInputParameters = issueService.newIssueInputParameters(); | |
TransitionValidationResult validationResult = issueService.validateTransition(user, issue.getId(), actionId, issueInputParameters); | |
result = validationResult.isValid(); | |
if (result) { | |
transResult = issueService.transition(user, validationResult); | |
} | |
return result; | |
} | |
// Get actionId from its name | |
private int getActionID(Issue issue, String actionName) { | |
int result = -1; | |
WorkflowManager workflowManager = ComponentManager.getInstance().getWorkflowManager(); | |
JiraWorkflow jiraWorkflow = workflowManager.getWorkflow(issue); | |
Collection<ActionDescriptor> cActionDesc = jiraWorkflow.getAllActions(); | |
for (ActionDescriptor res : cActionDesc) { | |
if (res.getName().equals(actionName)) { | |
result = res.getId(); | |
break; | |
} | |
} | |
return result; | |
} | |
// return epic target status according to issues linked statuses | |
private String getEpicStatus(List<Issue> issues) { | |
String epicStatusShouldBe = "NEW" | |
String firstStatus = "" | |
boolean isOnGoing = false | |
boolean isBlocked = false | |
boolean hasSameStatus = true | |
// check if all issues has the same status. | |
// If yes, the Epic should have the same status | |
// If no, if one issue is blocked, the epic is blocked | |
// If no issue is blocked and one issue is on going, the epic is on-going | |
// If no issue is blocked nor on going, the epic has the lowest status of its issues | |
issues?.find {curIssue -> | |
def status = curIssue.getStatusObject() | |
// first iteration | |
if( firstStatus == "" ) | |
firstStatus = status.getName(); | |
// compare next iterations ti the first one | |
if(firstStatus != status.getName()) | |
hasSameStatus = false; | |
if( status.getName() == "BLOCKED") { | |
isBlocked = true; | |
epicStatusShouldBe = "BLOCKED"; | |
} | |
if( status.getName() == "ON GOING") { | |
isOnGoing = true; | |
epicStatusShouldBe = "ON GOING"; | |
} | |
if( status.getName() != "TERMINATED" && !isOnGoing && !isBlocked) { | |
if( status.getName() == "BLOCKED") { | |
epicStatusShouldBe = status.getName() | |
} | |
if( epicStatusShouldBe == "IN PROD"){ | |
epicStatusShouldBe = status.getName() | |
} | |
if( epicStatusShouldBe == "DONE" && status.getName() != "IN PROD" && status.getName() != "BLOCKED"){ | |
epicStatusShouldBe = status.getName() | |
} | |
if( epicStatusShouldBe == "INTEGRATED" && status.getName() != "IN PROD" && status.getName() != "DONE" ){ | |
epicStatusShouldBe = status.getName() | |
} | |
if( epicStatusShouldBe == "READY" && status.getName() != "IN PROD" && status.getName() != "DONE" && status.getName() != "INTEGRATED"){ | |
epicStatusShouldBe = status.getName() | |
} | |
if( epicStatusShouldBe == "NEW" && status.getName() != "IN PROD" && status.getName() != "DONE" && status.getName() != "INTEGRATED" && status.getName() != "READY"){ | |
epicStatusShouldBe = status.getName() | |
} | |
} | |
if( hasSameStatus ) | |
epicStatusShouldBe = firstStatus; | |
} | |
return epicStatusShouldBe; | |
} | |
// Services variables | |
SearchService searchService = ComponentAccessor.getComponent(SearchService.class) | |
User user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser() | |
IssueManager issueManager = ComponentAccessor.getIssueManager() | |
List<Issue> epics = null | |
def jqlSearchEpics = "project = RPP and issuetype = epic and resolution = Unresolved and key in (rpp-97, rpp-95, rpp-85)" | |
SearchService.ParseResult parseResult = searchService.parseQuery(user, jqlSearchEpics) | |
if (parseResult.isValid()) { | |
def searchResultEpics = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter()) | |
epics = searchResultEpics.issues.collect {issueManager.getIssueObject(it.id)} | |
epics?.each {curEpic -> | |
def epicStatusShouldBe = "IN PROD" | |
List<Issue> issues = null | |
def jqlSearchLinkedIssues = "issueFunction in linkedIssuesOf(\"project = RPP AND issueKey = " + curEpic.id + "\")" | |
def epicName = curEpic.getStatusObject().getName(); | |
text += curEpic.getKey() + " has status " + epicName + " (" + getActionID(curEpic, epicName) + "): " | |
parseResult = searchService.parseQuery(user, jqlSearchLinkedIssues) | |
if (parseResult.isValid()) { | |
def searchResultIssues = searchService.search(user, parseResult.getQuery(), PagerFilter.getUnlimitedFilter()) | |
issues = searchResultIssues.issues.collect {issueManager.getIssueObject(it.id)} | |
epicStatusShouldBe = getEpicStatus(issues); | |
text += "should have status " + epicStatusShouldBe + " (" + getActionID(curEpic, epicStatusShouldBe) + ") ----- " | |
transitionIssue(curEpic, getActionID(curEpic, epicStatusShouldBe), user) | |
} else { | |
return "Invalid JQL: " + jqlSearchLinkedIssues | |
} | |
} | |
} else { | |
return "Invalid JQL: " + jqlSearchEpics | |
} | |
return text as String |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment