Skip to content

Commit 048a7f8

Browse files
committed
jira server : scriptsrunner hierarchy scripted fields, validators and workflows
1 parent b2eaa15 commit 048a7f8

35 files changed

+2060
-263
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import com.atlassian.jira.issue.fields.CustomField
2+
import com.atlassian.jira.issue.IssueManager
3+
import com.atlassian.jira.issue.Issue
4+
import com.atlassian.jira.issue.IssueImpl
5+
import com.atlassian.jira.issue.link.IssueLink
6+
import com.atlassian.jira.issue.link.IssueLinkImpl
7+
import com.atlassian.jira.issue.link.DefaultIssueLinkManager
8+
import com.atlassian.jira.issue.link.IssueLinkManager
9+
import com.atlassian.jira.component.ComponentAccessor
10+
11+
import com.atlassian.jira.component.ComponentAccessor
12+
import com.atlassian.jira.issue.RendererManager
13+
import com.atlassian.jira.issue.fields.renderer.IssueRenderContext
14+
import com.atlassian.jira.issue.fields.renderer.wiki.AtlassianWikiRenderer
15+
16+
DefaultIssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager() as DefaultIssueLinkManager
17+
def customFieldManager = ComponentAccessor.getCustomFieldManager()
18+
19+
def rendererManager = ComponentAccessor.getComponent(RendererManager)
20+
def renderContext = new IssueRenderContext(issue)
21+
22+
def EPIC_STORY_LINK = "Epic-Story Link"
23+
24+
try {
25+
CustomField implementedSolutionCf = customFieldManager.getCustomFieldObjectsByName("Implemented solution")[0]
26+
27+
def stories = issueLinkManager.getOutwardLinks(issue.id).findAll {
28+
it.issueLinkType.name == EPIC_STORY_LINK
29+
}
30+
31+
def table = """| *Story* | *Implemented Solution* |
32+
"""
33+
def implSolutionMap = stories.collectEntries { IssueLink it ->
34+
[it.getDestinationObject().key, it.getDestinationObject().getCustomFieldValue(implementedSolutionCf)]
35+
}
36+
if(implSolutionMap.keySet().size() > 0){
37+
for (entry in implSolutionMap) {
38+
def value = entry?.value?.replaceAll("\n", "* ")
39+
table = table.concat("""|${entry.key} | * ${value} |
40+
""")
41+
}
42+
}
43+
44+
rendererManager.getRenderedContent(AtlassianWikiRenderer.RENDERER_TYPE, table, renderContext)
45+
} catch(Exception e){
46+
e
47+
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
import com.atlassian.jira.issue.watchers.WatcherManager
2+
import org.apache.log4j.Level
3+
import org.apache.log4j.Logger
4+
import org.apache.commons.collections.Closure
5+
import com.atlassian.jira.issue.customfields.option.LazyLoadedOption
6+
import com.atlassian.jira.project.Project
7+
import com.atlassian.jira.project.ProjectManager
8+
import com.atlassian.jira.issue.link.IssueLink
9+
import com.atlassian.jira.issue.link.IssueLinkManager
10+
import com.atlassian.jira.issue.customfields.manager.OptionsManager
11+
import com.atlassian.jira.issue.Issue
12+
import com.atlassian.jira.event.type.EventDispatchOption
13+
import com.atlassian.jira.issue.IssueManager
14+
import com.atlassian.jira.issue.fields.CustomField
15+
import com.atlassian.jira.issue.customfields.option.Option
16+
import com.atlassian.jira.issue.CustomFieldManager
17+
import com.atlassian.jira.issue.MutableIssue
18+
import com.atlassian.jira.bc.issue.IssueService
19+
import com.atlassian.jira.component.ComponentAccessor
20+
import com.atlassian.jira.issue.IssueInputParameters
21+
import com.atlassian.jira.user.ApplicationUser
22+
import com.atlassian.jira.bc.project.component.ProjectComponent
23+
24+
25+
Logger logger = Logger.getLogger("sacos.s5k.createEpics")
26+
logger.setLevel(Level.ALL)
27+
28+
IssueService issueService = ComponentAccessor.getIssueService()
29+
IssueManager issueManager = ComponentAccessor.getIssueManager()
30+
IssueInputParameters issueInputParameters = issueService.newIssueInputParameters();
31+
CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager()
32+
ProjectManager projectManager = ComponentAccessor.getProjectManager()
33+
WatcherManager watcherManager = ComponentAccessor.getWatcherManager()
34+
IssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager()
35+
OptionsManager optionsManager = ComponentAccessor.getOptionsManager()
36+
def projectComponentManager = ComponentAccessor.getProjectComponentManager()
37+
38+
@com.onresolve.scriptrunner.parameters.annotation.ShortTextInput(description = "Enter Jira to execute the script on - leave empty for non-debug modes", label = "Jira Request Issue")
39+
String jiraDebugIssue
40+
41+
logger.info("jiraDebugIssue=" + jiraDebugIssue)
42+
43+
//Issue issue
44+
if ( jiraDebugIssue != null ){
45+
issue = issueManager.getIssueObject(jiraDebugIssue) // Add an issue for testing
46+
logger.setLevel(Level.ALL) // ALL, WARN
47+
}
48+
ApplicationUser user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
49+
50+
if(issue.getIssueType().getName() != "Request"){
51+
return;
52+
}
53+
54+
CustomField cf_targetProducts = customFieldManager.getCustomFieldObject(12121) // "Target products"
55+
Collection<String> targetProducts = (Collection<String>)issue.getCustomFieldValue(cf_targetProducts)
56+
targetProducts = targetProducts.collect { it -> it.toString() }
57+
logger.info("Target products: " + targetProducts )
58+
59+
Collection<String> target = targetProducts.collect { it -> it.toString() }
60+
61+
// two convenient closures
62+
def isProject(String key, IssueLink it) {
63+
it.destinationObject.getProjectObject().getKey() == key
64+
}
65+
66+
def isChildParentLink(IssueLink it){
67+
it.getIssueLinkType().getName() == "Hierarchy"
68+
}
69+
70+
// already done links
71+
List<String> alreadyDone = issueLinkManager.getOutwardLinks(issue.id).each { isChildParentLink(it) }.collect { IssueLink it ->
72+
it.destinationObject.getProjectObject().getKey()
73+
}.toList()
74+
Set<String> relevantProjects = targetProducts.toSet().minus(alreadyDone.toSet())
75+
76+
CustomField cf_ewh = customFieldManager.getCustomFieldObject(12154) // Expected Work Hours
77+
CustomField cf_ec = customFieldManager.getCustomFieldObject(12112) // Expected Cost
78+
79+
// Expected Work Hours
80+
logger.warn(cf_ewh)
81+
def fieldConfig_ewh = cf_ewh.getRelevantConfig(issue)
82+
def option_ewh = optionsManager.getOptions(fieldConfig_ewh).getOptionForValue((String)issue.getCustomFieldValue(cf_ewh), null)
83+
84+
List<Option> options_ewh = optionsManager.findByOptionValue((String)issue.getCustomFieldValue(cf_ewh));
85+
CustomField customField_ewh = option_ewh.getRelatedCustomField().getCustomField();
86+
87+
// Expected Cost
88+
def fieldConfig_ec = cf_ec.getRelevantConfig(issue)
89+
def option_ec = optionsManager.getOptions(fieldConfig_ec).getOptionForValue((String)issue.getCustomFieldValue(cf_ec), null)
90+
91+
List<Option> options_ec = optionsManager.findByOptionValue((String)issue.getCustomFieldValue(cf_ec));
92+
CustomField customField_ec = option_ec.getRelatedCustomField().getCustomField();
93+
94+
logger.info(issue.key)
95+
Collection<String> requestComponents = issue.getComponents().collect { ProjectComponent component ->
96+
logger.info("Source project component names: ${component.getName()}" )
97+
component.getName()
98+
}
99+
100+
Collection<Project> projects = relevantProjects.collect { String it -> projectManager.getProjectByCurrentKey(it) }
101+
102+
projects.each { Project project ->
103+
logger.info("Target project name-ID: ${project.getName()} (${project.getKey()}) internal ID: ${project.getId()}")
104+
Long[] thisProjectCompIds = requestComponents.collect { String compString ->
105+
projectComponentManager.findByComponentName(project.getId(),compString).getId()
106+
} as Long[]
107+
logger.info("Target project: ComponentID " + thisProjectCompIds.collect{ Long it -> it})
108+
109+
110+
IssueService.IssueResult createResult;
111+
112+
def exists = issueLinkManager.getOutwardLinks(issue.id).find { IssueLink it ->
113+
isProject(project.getKey(), it) && isChildParentLink(it)
114+
} != null
115+
116+
if(!exists){
117+
log.info("creating")
118+
issueInputParameters
119+
.setProjectId(project.getId())
120+
.setSummary("[" + project.getKey() + "] " + issue.getSummary())
121+
.setReporterId(issue.getReporter().username)
122+
.setIssueTypeId(issue.getIssueTypeId())
123+
.setDescription("Intentionally left empty, see Parent for details")
124+
.setComponentIds(thisProjectCompIds)
125+
.addCustomFieldValue(12129, "-") // Accounting
126+
.addCustomFieldValue(10002, "[" + project.getKey() + "] " + issue.getSummary() ) // Epic Name
127+
.setPriorityId(issue.getPriority().getId())
128+
.setIssueTypeId("10000") // Epic
129+
.addCustomFieldValue(customField_ewh.getId(), "" + option_ewh.getOptionId())
130+
.addCustomFieldValue(customField_ec.getId(), "" + option_ec.getOptionId())
131+
132+
IssueService.CreateValidationResult createValidationResult = issueService.validateCreate(user, issueInputParameters)
133+
134+
if (createValidationResult.isValid())
135+
{
136+
createResult = issueService.create(user, createValidationResult)
137+
138+
if (!createResult.isValid())
139+
{
140+
log.error("Error while creating the issue.")
141+
} else {
142+
MutableIssue newIssue = createResult.getIssue() as MutableIssue
143+
// child/parent of link
144+
issueLinkManager.createIssueLink(issue.id, newIssue.id, 10900, 0, user) // Hierarchy
145+
watcherManager.stopWatching(user, newIssue);
146+
}
147+
}
148+
else {
149+
log.error(createValidationResult.errorCollection);
150+
}
151+
}
152+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import com.atlassian.jira.issue.Issue
2+
import com.atlassian.jira.issue.IssueImpl
3+
import com.atlassian.jira.issue.link.IssueLink
4+
import com.atlassian.jira.issue.link.IssueLinkImpl
5+
import com.atlassian.jira.issue.link.DefaultIssueLinkManager
6+
import com.atlassian.jira.issue.link.IssueLinkManager
7+
import com.atlassian.jira.component.ComponentAccessor
8+
9+
import com.atlassian.jira.issue.fields.CustomField
10+
import com.atlassian.jira.issue.fields.ImmutableCustomField
11+
12+
def issue = issue as Issue
13+
14+
DefaultIssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager() as DefaultIssueLinkManager
15+
def customFieldManager = ComponentAccessor.getCustomFieldManager()
16+
ImmutableCustomField custom_field = customFieldManager.getCustomFieldObjectByName("Accounting") as ImmutableCustomField
17+
ImmutableCustomField requirementCustomField = customFieldManager.getCustomFieldObjectByName("Parent - ID") as ImmutableCustomField
18+
19+
try {
20+
customFieldManager.getCustomFieldObjects(issue)
21+
def requirement = issue.getCustomFieldValue(requirementCustomField)
22+
23+
def issueManager = ComponentAccessor.getIssueManager()
24+
IssueImpl requirementIssue = issueManager.getIssueObject(requirement.toString()) as IssueImpl
25+
26+
def value = requirementIssue.getCustomFieldValue(custom_field)
27+
value
28+
} catch(Exception e){
29+
null
30+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import com.atlassian.jira.issue.Issue
2+
import com.atlassian.jira.issue.IssueImpl
3+
import com.atlassian.jira.issue.link.IssueLink
4+
import com.atlassian.jira.issue.link.IssueLinkImpl
5+
import com.atlassian.jira.issue.link.DefaultIssueLinkManager
6+
import com.atlassian.jira.issue.link.IssueLinkManager
7+
import com.atlassian.jira.component.ComponentAccessor
8+
9+
import com.atlassian.jira.issue.fields.CustomField
10+
import com.atlassian.jira.issue.fields.ImmutableCustomField
11+
12+
def issue = issue as Issue
13+
14+
DefaultIssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager() as DefaultIssueLinkManager
15+
def customFieldManager = ComponentAccessor.getCustomFieldManager()
16+
ImmutableCustomField custom_field = customFieldManager.getCustomFieldObjectByName("Combustion Type") as ImmutableCustomField
17+
ImmutableCustomField requirementCustomField = customFieldManager.getCustomFieldObjectByName("Parent - ID") as ImmutableCustomField
18+
19+
try {
20+
customFieldManager.getCustomFieldObjects(issue)
21+
def requirement = issue.getCustomFieldValue(requirementCustomField)
22+
23+
def issueManager = ComponentAccessor.getIssueManager()
24+
IssueImpl requirementIssue = issueManager.getIssueObject(requirement.toString()) as IssueImpl
25+
26+
def value = requirementIssue.getCustomFieldValue(custom_field)
27+
value
28+
} catch(Exception e){
29+
null
30+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import com.atlassian.jira.issue.Issue
2+
import com.atlassian.jira.issue.IssueImpl
3+
import com.atlassian.jira.issue.link.IssueLink
4+
import com.atlassian.jira.issue.link.IssueLinkImpl
5+
import com.atlassian.jira.issue.link.DefaultIssueLinkManager
6+
import com.atlassian.jira.issue.link.IssueLinkManager
7+
import com.atlassian.jira.component.ComponentAccessor
8+
9+
import com.atlassian.jira.issue.fields.CustomField
10+
import com.atlassian.jira.issue.fields.ImmutableCustomField
11+
12+
import com.atlassian.jira.component.ComponentAccessor
13+
import com.atlassian.jira.issue.RendererManager
14+
import com.atlassian.jira.issue.fields.renderer.IssueRenderContext
15+
import com.atlassian.jira.issue.fields.renderer.wiki.AtlassianWikiRenderer
16+
17+
def issue = issue as Issue
18+
19+
DefaultIssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager() as DefaultIssueLinkManager
20+
def customFieldManager = ComponentAccessor.getCustomFieldManager()
21+
ImmutableCustomField custom_field = customFieldManager.getCustomFieldObjectByName("Accounting") as ImmutableCustomField
22+
ImmutableCustomField requirementCustomField = customFieldManager.getCustomFieldObjectByName("Parent - ID") as ImmutableCustomField
23+
24+
def rendererManager = ComponentAccessor.getComponent(RendererManager)
25+
def renderContext = new IssueRenderContext(issue)
26+
def commentManager = ComponentAccessor.commentManager
27+
28+
try {
29+
customFieldManager.getCustomFieldObjects(issue)
30+
def requirement = issue.getCustomFieldValue(requirementCustomField)
31+
32+
def issueManager = ComponentAccessor.getIssueManager()
33+
IssueImpl requirementIssue = issueManager.getIssueObject(requirement.toString()) as IssueImpl
34+
35+
def value = requirementIssue.getDescription()
36+
37+
if (value) {
38+
rendererManager.getRenderedContent(AtlassianWikiRenderer.RENDERER_TYPE, value, renderContext)
39+
}
40+
41+
} catch(Exception e){
42+
null
43+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import com.atlassian.jira.issue.Issue
2+
import com.atlassian.jira.issue.IssueImpl
3+
import com.atlassian.jira.issue.link.IssueLink
4+
import com.atlassian.jira.issue.link.IssueLinkImpl
5+
import com.atlassian.jira.issue.link.DefaultIssueLinkManager
6+
import com.atlassian.jira.issue.link.IssueLinkManager
7+
import com.atlassian.jira.component.ComponentAccessor
8+
9+
import com.atlassian.jira.issue.fields.CustomField
10+
import com.atlassian.jira.issue.fields.ImmutableCustomField
11+
12+
def issue = issue as Issue
13+
14+
DefaultIssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager() as DefaultIssueLinkManager
15+
def customFieldManager = ComponentAccessor.getCustomFieldManager()
16+
ImmutableCustomField engine_type = customFieldManager.getCustomFieldObjectByName("Engine Type") as ImmutableCustomField
17+
ImmutableCustomField requirementCustomField = customFieldManager.getCustomFieldObjectByName("Parent - ID") as ImmutableCustomField
18+
19+
try {
20+
customFieldManager.getCustomFieldObjects(issue)
21+
22+
def requirement = issue.getCustomFieldValue(requirementCustomField)
23+
24+
def issueManager = ComponentAccessor.getIssueManager()
25+
IssueImpl requirementIssue = issueManager.getIssueObject(requirement.toString()) as IssueImpl
26+
27+
def engine_type_value = requirementIssue.getCustomFieldValue(engine_type)
28+
engine_type_value
29+
} catch(Exception e){
30+
null
31+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import com.atlassian.jira.issue.Issue
2+
import com.atlassian.jira.issue.IssueImpl
3+
import com.atlassian.jira.issue.link.IssueLink
4+
import com.atlassian.jira.issue.link.IssueLinkImpl
5+
import com.atlassian.jira.issue.link.DefaultIssueLinkManager
6+
import com.atlassian.jira.issue.link.IssueLinkManager
7+
import com.atlassian.jira.component.ComponentAccessor
8+
9+
import com.atlassian.jira.issue.fields.CustomField
10+
import com.atlassian.jira.issue.fields.ImmutableCustomField
11+
12+
def issue = issue as Issue
13+
14+
DefaultIssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager() as DefaultIssueLinkManager
15+
def customFieldManager = ComponentAccessor.getCustomFieldManager()
16+
ImmutableCustomField custom_field = customFieldManager.getCustomFieldObjectByName("Expected Costs") as ImmutableCustomField
17+
ImmutableCustomField requirementCustomField = customFieldManager.getCustomFieldObjectByName("Parent - ID") as ImmutableCustomField
18+
19+
try {
20+
customFieldManager.getCustomFieldObjects(issue)
21+
def requirement = issue.getCustomFieldValue(requirementCustomField)
22+
23+
def issueManager = ComponentAccessor.getIssueManager()
24+
IssueImpl requirementIssue = issueManager.getIssueObject(requirement.toString()) as IssueImpl
25+
26+
def value = requirementIssue.getCustomFieldValue(custom_field)
27+
value
28+
} catch(Exception e){
29+
null
30+
}

0 commit comments

Comments
 (0)