"
27 |
28 | if [[ ${netrc_file:-} != "" ]]; then
29 | echo "Using netrc file $netrc_file"
30 | if [[ ! -f $netrc_file ]]; then
31 | echo "ERROR: $netrc_file does not exist"
32 | exit 1
33 | fi
34 | netrc_file_option="--netrc-file ${netrc_file}"
35 | else
36 | echo "Using default netrc file option. --netrc"
37 | netrc_file_option="--netrc-file /cygdrive/c/builds/.netrc"
38 | fi
39 |
40 | jenkins_agent_url="${jenkins_server}/computer/${jenkins_agent_name}"
41 |
42 | function set_busy_executors() {
43 | local -n _busy_execeutors=$1
44 | _busy_execeutors=$(curl -s --insecure ${netrc_file_option:-} --silent ${jenkins_agent_url}/ajaxExecutors \
45 | | sed -e 's//\n/g' \
46 | | grep -E '^[0-9].+' \
47 | | grep href \
48 | | wc -l \
49 | ) || {
50 | local exitcode=$?
51 | if [[ $exitcode == 1 ]]; then
52 | _busy_execeutors=0
53 | else
54 | echo "ERROR: Something when wrong - exit code $exitcode"
55 | exit 1
56 | fi
57 | }
58 | }
59 |
60 | function print_state() {
61 | is_offline=$( curl -s --insecure ${netrc_file_option:-} ${jenkins_agent_url}/api/json | jq .offline )
62 | if [[ $is_offline == false ]]; then
63 | printf "offline=false\n"
64 | else
65 | printf "offline=true\n"
66 | fi
67 | }
68 |
69 | case "${command}" in
70 | offline)
71 | # Mark as offline
72 | is_offline=$( curl -s --insecure ${netrc_file_option:-} ${jenkins_agent_url}/api/json | jq .offline )
73 | if [[ ${is_offline:-} == false ]]; then
74 | echo "$jenkins_agent_name is online - mark it offline"
75 | curl -s --insecure ${netrc_file_option:-} ${jenkins_agent_url}/toggleOffline --request 'POST' --data 'Marked offline to be able to manage agent / server'
76 | elif [[ ${is_offline:-} == true ]]; then
77 | echo "Agent $jenkins_agent_name is already offline"
78 | exit
79 | else
80 | echo "ERROR: offline is: ${is_offline:-}"
81 | exit 1
82 | fi
83 |
84 | # Assume it has busy executors
85 | busy_execeutors=
86 | set_busy_executors busy_execeutors
87 | while [[ $busy_execeutors -gt 0 ]]; do
88 | echo "There are $busy_execeutors busy executors - Wait $sleep_sec secs and test again"
89 | sleep $sleep_sec
90 | set_busy_executors busy_execeutors
91 | sleep_sec=$(( sleep_sec * 2))
92 | done
93 |
94 | echo "All executors are done .. - Safe to proceed"
95 |
96 | is_offline=$( curl -s --insecure ${netrc_file_option:-} ${jenkins_agent_url}/api/json | jq .offline )
97 | printf "Agent %s is offline: %s\n" "${jenkins_agent_name}" "$is_offline"
98 | ;;
99 | online)
100 | is_offline=$( curl -s --insecure ${netrc_file_option:-} ${jenkins_agent_url}/api/json | jq .offline )
101 | printf "Agent %s offline: %s\n" "${jenkins_agent_name}" "$is_offline"
102 | if [[ $is_offline == true ]]; then
103 | echo "Setting online"
104 | curl -s --insecure ${netrc_file_option:-} ${jenkins_agent_url}/toggleOffline --request 'POST' --data 'Mark online'
105 | sleep 1
106 | print_state
107 | elif [[ ${is_offline:-} == false ]]; then
108 | echo "Agent ${jenkins_agent_name} is already online"
109 | exit
110 | else
111 | echo "ERROR: offline is: ${is_offline:-}"
112 | exit 1
113 | fi
114 | ;;
115 | state)
116 | print_state
117 | ;;
118 | *)
119 | echo "Unknown command: $command"
120 | exit 1
121 | ;;
122 | esac
123 |
124 |
125 |
--------------------------------------------------------------------------------
/jira/README.md:
--------------------------------------------------------------------------------
1 | # Jira related contributions
2 |
3 | ## Jira filters
4 |
5 | Over time we have created many small snippets of Jira filter we keep re-using.
6 |
7 | You can use them also - check [Jira filter readme](/jira/filters/readme.md) and the subdir [filters](/filters).
8 |
--------------------------------------------------------------------------------
/jira/filters/readme.md:
--------------------------------------------------------------------------------
1 | # Jira filters
2 |
3 | You have a good and re-useable filter, for a generic workflow? Share it here...
4 |
5 | * Please put a few lines of use-case for the filter
6 | * Post the filter itself
7 | * Mention any dependencies, e.g. plugins needed
8 |
9 | _The filters also serves as a good guideline on how to work in Jira as they follow many of our best-practices_.
10 |
11 | ## Assignee resolves, team members close
12 |
13 | To help knowledge sharing and cross-functional team effort it can be a good idea to let team members close issue, after the assignee resolves them.
14 | That way another team member get to read what was done. It also helps to get new ideas and future improvements this workflow, so often new follow-up issues with even better ideas can be created.
15 |
16 | The following filter with find resolved issues withint the last 8 hours. Subscribe to th filter on daily basis, and when you get a mail go over the resolved issues to close those you didn't resolve yourself.
17 |
18 | CICD issues latest resolved: `project = CICD AND status = Resolved AND resolved >= -8h AND status != Closed`
19 |
20 | ## You want to know everything?
21 |
22 | If you truely want to know everything, here are all the issues you're not watching:
23 |
24 | `project = CICD AND creator not in (myjirausername) AND reporter not in (myjirausername) AND assignee not in (myjirausername) AND statusCategory not in (Done) AND watcher not in (myjirausername)`
25 |
26 | ## Filters in filters
27 |
28 | Tracking several filters in say one Kanban board, you can use filters in filter. But be carefull they tend to get really really slow:
29 |
30 | `filter = "12679" OR filter = "12692" OR filter = "12832" OR labels in (CICD-debt) ORDER BY Rank`
31 |
32 | ## All epic tasks
33 |
34 | This finds all tasks that have an epic assigned to them. Easy to get an overview, you can add columns in the view to see the epic.
35 |
36 | `project = "CICD" AND component in ("CoDE") AND status not in (Closed, Resolved) AND "Epic link" != EMPTY ORDER BY "Epic Link"`
37 |
38 | ## Active cases
39 |
40 | Once upon a time a project defined _active cases_ as cases in the CoDE component without epic link, or those with component CoDE but where there was an epic link and the epic in progress.
41 | That allowed for omitting issues from epic not put in progress yet and do planning on epics wihout someone working on them.
42 | The labels are to remove some general issues with special labels.
43 |
44 | `(project = "CICD" AND component in ("CoDE") AND "Epic link" = EMPTY OR project = "CICD" AND component in ("CoDE") AND "Epic Link" != EMPTY AND issueFunction in linkedIssuesOf("issuetype = Epic AND status = \"In Progress\"")) AND status not in (Closed, Resolved) AND issueFunction not in issueFieldMatch("", labels, "CICD-*|assessment")`
45 |
46 | ## Ad-hoc work is issues without epics
47 |
48 | If we define ad-hoc work, like support requests coming, as those issues not really planned thus not belonging to an epic they can be found with:
49 |
50 | `project = "CICD" AND component = "CoDE" AND "Epic Link" = EMPTY AND statusCategory not in (Done) AND issueFunction not in issueFieldMatch("", labels, "CICD-*|assessment") AND issuetype not in (Epic) AND issueFunction not in linkedIssuesOf("issuetype = Epic")`
51 |
52 | Some labels are not considered workable issues also, thus omitted.
53 |
--------------------------------------------------------------------------------
/jira/scripts/README.md:
--------------------------------------------------------------------------------
1 | # Overview
2 |
3 | The scripts contained within this repository are intended to be used within Jira. There are both groovy scripts,
4 | which are dependent upon the [ScriptRunner](https://marketplace.atlassian.com/plugins/com.onresolve.jira.groovy.groovyrunner/server/overview)
5 | plugin, and other add-hoc scripts for administrative purposes.
6 |
7 | ## Jira Scripts
8 |
9 | These are Jira and Script Runner specific.
10 |
11 | They **could** be dependent upon a specific version of the ScriptRunner plugin. There is also the added complexity of the
12 | Jira version. As ScriptRunner provides access to Jira classes with [Groovy](http://www.groovy-lang.org/) this is also a dependency.
13 |
14 |
15 | **NOTE:** These cannot be called production ready in any sense of the word. Use them as inspiration or a base for
16 | getting started. Most of them were hacked together with the earlier free version(s) of ScriptRunner on a Jira 6.X.X version.
17 |
18 | ### Workflow Scripts
19 | The scripts can be ran from a file or embedded **INLINE** into the post-function, validation or conditions on a transition.
20 |
21 | #### CloneAndLink.groovy And TransitionLinkedDefect.groovy
22 | **Use case**
23 |
24 | A 1st line error management project and multiple 2nd line projects. Defects come into the 1st line project. 1st line
25 | support verifies the defect and determine what 2nd line project(s) should handle it. 1st line support selects the project(s) from
26 | a multi-select list drop down and moves the issue to a status called awaiting action. A clone of the defect is generated
27 | into the selected project(s) and they are linked with a special link type for defects.
28 |
29 | The cloned defect is worked on in the 2nd line support team(s) and resolved. This triggers a transition in the 1st line project
30 | to a status "ready for test", if there are no other cloned defects not resolved.
31 |
32 | * The assignee is set to the project lead of the Target Project.
33 | * The summary is prepended with "CLONE of DEFECT KEY:", where key is the Key of the originating issue.
34 | * The creation date is set to the date of creation.
35 | * Links from Original issue are kept.
36 | * Estimates and time spent are zeroed out on cloned issue.
37 |
38 | ##### How to use
39 |
40 | * The Clone and link script is applied in 1st line support project.
41 | * The Transition linked defect script is applied in all applicable 2nd line support projects.
42 |
43 | **NOTE:** User permissions across the projects must be correct. There is a lot of hardcoded stuff in the scripts which will
44 | need to be cleaned up.
45 |
46 | #### OriginalEstimateValidation.groovy
47 | The purpose of this script is to ensure sub-tasks Original Estimate field has a value.
48 |
49 | ##### How to use
50 | Use this script as a validator on a transition and give an error message so the user knows why.
51 |
52 | ### JQL Scripts
53 | Script runner provides a way to code JQL queries in scripts. That way we can do queries which are difficult, complex or
54 | impossible with the standard query formats. These scripts must be ran from the file system. Script Runner provides a
55 | script root under JIRA_HOME/scripts.
56 |
57 | #### MismatchedThemes.groovy
58 | The use case is trying to create a hierarchy of Theme->Epic->Story with Jira links. The idea being that Epics and Story's
59 | belong to a Theme.
60 |
61 | Purpose is to find all User Stories that have a linked "Theme" issue type where the Epic of the linked Theme is
62 | **different** than the Epic of the User Story. If the either the User Story or the linked Themes has an Epic Link and the
63 | other does not then this is seen as a mismatch.
64 |
65 | ##### How to use
66 |
67 | * hasEpicMismatchWithTheme(): This will return an error as there are no quotation marks ("") and thus no query.
68 | * hasEpicMismatchWithTheme(""): This will search all issues.
69 | * hasEpicMismatchWithTheme("project = CP"): This will return stories for a specific project.
70 |
71 | ### Scripted Fields
72 | Script Runner allows you to create custom fields based on a groovy script. These fields are **NON** editable and are
73 | calculated.
74 |
75 | #### LastComment.groovy
76 | Use case is showing the last comment of an issue from a JQL search.
77 |
78 | #### TimeSpentAsHours.groovy
79 | Very simple script to calculate value in hours. Jira stores these values in milliseconds and presents them according
80 | to wishes, ie. hours, minutes, etc. The exports to word and xml will use the default estimation set in global
81 | configuration. The excel export does not do this :-( Therefor we need a scripted field to be used as a column for JQL searches.
82 |
83 | ## Other
84 | Any other types of scripts that has to do with Jira.
85 |
86 | ### SQL
87 | SQL snippets for working with Jira's database.
88 |
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/childrenImplementedSolution.groovy:
--------------------------------------------------------------------------------
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 | }
48 |
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentAccounting.groovy:
--------------------------------------------------------------------------------
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 | }
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentCombustionType.groovy:
--------------------------------------------------------------------------------
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 | }
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentDescription.groovy:
--------------------------------------------------------------------------------
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 | }
44 |
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentEngineType.groovy:
--------------------------------------------------------------------------------
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 | }
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentExpectedCost.groovy:
--------------------------------------------------------------------------------
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 | }
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentExpectedWorkhours.groovy:
--------------------------------------------------------------------------------
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 Work Hours") 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 value = requirementIssue.getCustomFieldValue(custom_field)
28 | value
29 | } catch(Exception e){
30 | null
31 | }
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentFixVersions-console.groovy:
--------------------------------------------------------------------------------
1 | import org.apache.log4j.Level
2 | import org.apache.log4j.Logger
3 |
4 | import com.atlassian.jira.issue.IssueManager
5 | import com.atlassian.jira.component.ComponentAccessor
6 | import com.atlassian.jira.issue.Issue
7 | import com.atlassian.jira.issue.IssueImpl
8 | import com.atlassian.jira.issue.link.IssueLink
9 | import com.atlassian.jira.issue.link.IssueLinkImpl
10 | import com.atlassian.jira.issue.link.DefaultIssueLinkManager
11 | import com.atlassian.jira.issue.link.IssueLinkManager
12 |
13 | import com.atlassian.jira.project.version.Version
14 |
15 | import com.atlassian.jira.issue.fields.CustomField
16 | import com.atlassian.jira.issue.fields.ImmutableCustomField
17 |
18 | IssueManager issueManager = ComponentAccessor.getIssueManager()
19 | IssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager()
20 | def projectComponentManager = ComponentAccessor.getProjectComponentManager()
21 |
22 | @com.onresolve.scriptrunner.parameters.annotation.ShortTextInput(description = "Enter Jira to execute the script on - leave empty for non-debug modes", label = "Jira Request Issue")
23 | String jiraDebugIssue
24 |
25 | Logger logger = Logger.getLogger("parent.FixVersions")
26 |
27 | logger.info("jiraDebugIssue=" + jiraDebugIssue)
28 |
29 | //Issue issue
30 | if ( jiraDebugIssue != null ){
31 | issue = issueManager.getIssueObject(jiraDebugIssue) // Add an issue for testing
32 | logger.setLevel(Level.ALL) // ALL, WARN
33 | }
34 |
35 |
36 | def findParent(Issue issue, Logger logger, IssueLinkManager issueLinkManager){
37 | if(issue.subTask){
38 | return findParent(issue.getParentObject(), logger, issueLinkManager)
39 | }
40 | for(IssueLink issueLink : issueLinkManager.getInwardLinks(issue.id)){
41 | if (issueLink.issueLinkType.name == "Epic-Story Link" ) {
42 | logger.debug("Issue link type: " + issueLink.issueLinkType.name + " : " + issueLink.getSourceObject().getKey())
43 | return issueLink.getSourceObject()
44 | }
45 | }
46 | }
47 |
48 | try {
49 | Issue parentIssue = findParent(issue, logger, issueLinkManager) as Issue
50 | logger.debug(parentIssue)
51 |
52 | parentIssue.getFixVersions()
53 | } catch(Exception e){
54 | log.error(e)
55 | }
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentFixVersions.groovy:
--------------------------------------------------------------------------------
1 | import org.apache.log4j.Level
2 | import org.apache.log4j.Logger
3 |
4 | import com.atlassian.jira.issue.IssueManager
5 | import com.atlassian.jira.component.ComponentAccessor
6 | import com.atlassian.jira.issue.Issue
7 | import com.atlassian.jira.issue.IssueImpl
8 | import com.atlassian.jira.issue.link.IssueLink
9 | import com.atlassian.jira.issue.link.IssueLinkImpl
10 | import com.atlassian.jira.issue.link.DefaultIssueLinkManager
11 | import com.atlassian.jira.issue.link.IssueLinkManager
12 |
13 | import com.atlassian.jira.project.version.Version
14 |
15 | import com.atlassian.jira.issue.fields.CustomField
16 | import com.atlassian.jira.issue.fields.ImmutableCustomField
17 |
18 | def findParent(Issue issue, Logger logger, IssueLinkManager issueLinkManager){
19 | if(issue.subTask){
20 | return findParent(issue.getParentObject(), logger, issueLinkManager)
21 | }
22 | for(IssueLink issueLink : issueLinkManager.getInwardLinks(issue.id)){
23 | if (issueLink.issueLinkType.name == "Epic-Story Link" ) {
24 | logger.debug("Issue link type: " + issueLink.issueLinkType.name + " : " + issueLink.getSourceObject().getKey())
25 | return issueLink.getSourceObject()
26 | }
27 | }
28 | }
29 |
30 | try {
31 | Logger logger = Logger.getLogger("parent.FixVersions")
32 | IssueManager issueManager = ComponentAccessor.getIssueManager()
33 |
34 | IssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager()
35 | Issue parentIssue = findParent(issue, logger, issueLinkManager) as Issue
36 | logger.debug(parentIssue)
37 |
38 | parentIssue.getFixVersions()
39 | } catch(Exception e){
40 | log.error(e)
41 | }
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentID.groovy:
--------------------------------------------------------------------------------
1 | import com.atlassian.jira.issue.Issue
2 | import com.atlassian.jira.issue.link.IssueLink
3 | import com.atlassian.jira.issue.link.IssueLinkImpl
4 | import com.atlassian.jira.issue.link.DefaultIssueLinkManager
5 | import com.atlassian.jira.issue.link.IssueLinkManager
6 | import com.atlassian.jira.component.ComponentAccessor
7 | import com.atlassian.jira.issue.fields.CustomField
8 | import com.atlassian.jira.issue.fields.ImmutableCustomField
9 |
10 | class RequirementFinder {
11 | DefaultIssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager() as DefaultIssueLinkManager
12 | def customFieldManager = ComponentAccessor.getCustomFieldManager()
13 |
14 | private Issue getRequirementForEpic(Issue epic){
15 | if(epic == null){
16 | return null;
17 | }
18 | Issue requirement = null;
19 | Collection links = issueLinkManager.getInwardLinks(epic.getId())
20 | try {
21 | links = links.findAll({it -> it.getIssueLinkType().getName() == "Hierarchy" && it.sourceObject.getIssueType().getName() == 'Request'})
22 | return links[0].sourceObject
23 | } catch (Exception e){
24 | return null
25 | }
26 | }
27 |
28 | public String getRequirement(Issue issueObject){
29 | if(issueObject?.getIssueType()?.getName() == "Request"){
30 | return issueObject; // or null
31 | }
32 | if(issueObject?.getIssueType()?.getName() == "Epic"){
33 | return this.getRequirementForEpic(issueObject)
34 | }
35 | return null;
36 | }
37 | }
38 | def issue = issue as Issue
39 | def requirementFinder = new RequirementFinder();
40 | requirementFinder.getRequirement(issue)
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentIssueReason.groovy:
--------------------------------------------------------------------------------
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("Issue Reason") 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 value = requirementIssue.getCustomFieldValue(custom_field)
28 | value
29 | } catch(Exception e){
30 | null
31 | }
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentPlatform.groovy:
--------------------------------------------------------------------------------
1 | import com.atlassian.jira.component.ComponentAccessor
2 | import com.atlassian.jira.issue.Issue
3 | import com.atlassian.jira.issue.IssueImpl
4 | import com.atlassian.jira.issue.link.IssueLink
5 | import com.atlassian.jira.issue.link.IssueLinkImpl
6 | import com.atlassian.jira.issue.link.DefaultIssueLinkManager
7 | import com.atlassian.jira.issue.link.IssueLinkManager
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("Platform") 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 value = requirementIssue.getCustomFieldValue(custom_field)
28 | value
29 | } catch(Exception e){
30 | null
31 | }
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentReferencedPCB.groovy:
--------------------------------------------------------------------------------
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("Referenced PCB-ID") as ImmutableCustomField
17 | ImmutableCustomField requirementCustomField = customFieldManager.getCustomFieldObjectByName("Parent - ID") as ImmutableCustomField
18 | try {
19 | customFieldManager.getCustomFieldObjects(issue)
20 |
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 | }
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentSiblings.groovy:
--------------------------------------------------------------------------------
1 | import org.apache.log4j.Level
2 | import org.apache.log4j.Logger
3 |
4 | import com.atlassian.jira.issue.IssueManager
5 | import com.atlassian.jira.component.ComponentAccessor
6 | import com.atlassian.jira.issue.Issue
7 | import com.atlassian.jira.issue.IssueImpl
8 | import com.atlassian.jira.issue.link.IssueLink
9 | import com.atlassian.jira.issue.link.IssueLinkImpl
10 | import com.atlassian.jira.issue.link.DefaultIssueLinkManager
11 | import com.atlassian.jira.issue.link.IssueLinkManager
12 |
13 | import com.atlassian.jira.project.version.Version
14 |
15 | import com.atlassian.jira.issue.fields.CustomField
16 | import com.atlassian.jira.issue.fields.ImmutableCustomField
17 | //import com.atlassian.jira.issue.RendererManager
18 | //import com.atlassian.jira.issue.fields.renderer.IssueRenderContext
19 | //import com.atlassian.jira.issue.fields.renderer.wiki.AtlassianWikiRenderer
20 |
21 | IssueManager issueManager = ComponentAccessor.getIssueManager()
22 |
23 | @com.onresolve.scriptrunner.parameters.annotation.ShortTextInput(description = "Enter Jira to execute the script on - leave empty for non-debug modes", label = "Jira Request Issue")
24 | String jiraDebugIssue
25 |
26 | Logger logger = Logger.getLogger("parent.parentSiblings")
27 |
28 | logger.info("jiraDebugIssue=" + jiraDebugIssue)
29 |
30 | //Issue issue
31 | if ( jiraDebugIssue != null ){
32 | issue = issueManager.getIssueObject(jiraDebugIssue) // Add an issue for testing
33 | logger.setLevel(Level.ALL) // ALL, WARN
34 | }
35 |
36 |
37 |
38 | def findParent(Issue issue, Logger logger, IssueLinkManager issueLinkManager){
39 | if(issue.subTask){
40 | logger.info("Issue link type subtask - next: " + issue.subTask )
41 | return findParent(issue.getParentObject(), logger, issueLinkManager)
42 | }
43 | for(IssueLink issueLink : issueLinkManager.getInwardLinks(issue.id)){
44 | if (issueLink.issueLinkType.name == "Epic-Story Link" ) {
45 | logger.info("Issue link type E: " + issueLink.issueLinkType.name + " : " + issueLink.getSourceObject().getKey())
46 | return issueLink.getSourceObject()
47 | }
48 | }
49 | }
50 |
51 | try {
52 |
53 | IssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager()
54 | Issue parentIssue = findParent(issue, logger, issueLinkManager) as Issue
55 | Issue parentIssueNotNull
56 | if ( parentIssue ) {
57 | parentIssueNotNull=parentIssue
58 | logger.info("Returned: " + parentIssueNotNull)
59 | } else {
60 | logger.info("Returned null: " + parentIssueNotNull)
61 | }
62 |
63 | def customFieldManager = ComponentAccessor.getCustomFieldManager()
64 | ImmutableCustomField siblings_cf = customFieldManager.getCustomFieldObjectsByName("Siblings")[0] as ImmutableCustomField
65 | def value
66 | if ( parentIssueNotNull ) {
67 | value = parentIssueNotNull.getCustomFieldValue(siblings_cf)
68 | logger.info("value: " + value)
69 | if (value) {
70 | value
71 | /*
72 | // It is already rendered in parent:
73 | def rendererManager = ComponentAccessor.getComponent(RendererManager)
74 | def renderContext = new IssueRenderContext(issue)
75 | rendererManager.getRenderedContent(AtlassianWikiRenderer.RENDERER_TYPE, value, renderContext)
76 | */
77 | }
78 | }
79 |
80 | } catch(Exception e){
81 | log.error(e)
82 | }
83 |
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentSiteType.groovy:
--------------------------------------------------------------------------------
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("Site 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 value = requirementIssue.getCustomFieldValue(custom_field)
28 | value
29 | } catch(Exception e){
30 | null
31 | }
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/parentTargetProducts.groovy:
--------------------------------------------------------------------------------
1 | import com.atlassian.jira.component.ComponentAccessor
2 | import org.apache.log4j.Level
3 | import org.apache.log4j.Logger
4 | import com.atlassian.jira.issue.Issue
5 | import com.atlassian.jira.issue.IssueImpl
6 | import com.atlassian.jira.issue.link.IssueLink
7 | import com.atlassian.jira.issue.link.IssueLinkImpl
8 | import com.atlassian.jira.issue.link.DefaultIssueLinkManager
9 | import com.atlassian.jira.issue.link.IssueLinkManager
10 |
11 | import com.atlassian.jira.issue.fields.CustomField
12 | import com.atlassian.jira.issue.fields.ImmutableCustomField
13 |
14 | Logger logger = Logger.getLogger("sacos.parent.Target products")
15 | //logger.setLevel(Level.DEBUG)
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("Target products") as ImmutableCustomField
22 | logger.info(custom_field.fieldName)
23 | ImmutableCustomField parentCustomField = customFieldManager.getCustomFieldObjectByName("Parent - ID") as ImmutableCustomField
24 | logger.info(parentCustomField.fieldName)
25 |
26 | try {
27 | customFieldManager.getCustomFieldObjects(issue)
28 | def issueManager = ComponentAccessor.getIssueManager()
29 | IssueImpl parentIssue = issueManager.getIssueObject(issue.getCustomFieldValue(parentCustomField).toString()) as IssueImpl
30 | logger.info(parentIssue)
31 |
32 | def value = parentIssue.getCustomFieldValue(custom_field)
33 | return value
34 | } catch(Exception e){
35 | logger.error(e)
36 | }
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/siblings.groovy:
--------------------------------------------------------------------------------
1 | import com.atlassian.jira.component.ComponentAccessor
2 |
3 | import com.atlassian.jira.issue.Issue
4 | import com.atlassian.jira.issue.IssueImpl
5 | import com.atlassian.jira.issue.RendererManager
6 |
7 | import com.atlassian.jira.issue.fields.renderer.IssueRenderContext
8 | import com.atlassian.jira.issue.fields.renderer.wiki.AtlassianWikiRenderer
9 |
10 | import com.atlassian.jira.issue.link.DefaultIssueLinkManager
11 | import com.atlassian.jira.issue.link.IssueLink
12 | import com.atlassian.jira.issue.link.IssueLinkImpl
13 | import com.atlassian.jira.issue.link.IssueLinkManager
14 |
15 | import com.atlassian.jira.issue.fields.CustomField
16 | import com.atlassian.jira.issue.fields.ImmutableCustomField
17 |
18 | try {
19 | DefaultIssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager() as DefaultIssueLinkManager
20 | def customFieldManager = ComponentAccessor.getCustomFieldManager()
21 | ImmutableCustomField requirementCustomField = customFieldManager.getCustomFieldObjectsByName("Parent - ID")[0] as ImmutableCustomField
22 |
23 | def rendererManager = ComponentAccessor.getComponent(RendererManager)
24 | def renderContext = new IssueRenderContext(issue)
25 | def commentManager = ComponentAccessor.commentManager
26 | def comment = commentManager.getLastComment(issue)
27 |
28 | def requirement = issue.getCustomFieldValue(requirementCustomField)
29 |
30 | def issueManager = ComponentAccessor.getIssueManager()
31 | IssueImpl requirementIssue = issueManager.getIssueObject(requirement.toString()) as IssueImpl
32 |
33 | def links = issueLinkManager.getOutwardLinks(requirementIssue.getId())
34 | def linksMarkdown = links.findAll({
35 | IssueLink it -> it.destinationObject.key != issue.key
36 | }).collect({
37 | IssueLink it -> "[" + it.destinationObject.key + "] *Status*: " +
38 | it.destinationObject.getStatus().getName() + " *Fix version(s)*: " +
39 | it.destinationObject.getFixVersions().join(", ") +
40 | "\n"
41 | }).join(" ")
42 |
43 | if (linksMarkdown) {
44 | rendererManager.getRenderedContent(AtlassianWikiRenderer.RENDERER_TYPE, linksMarkdown, renderContext)
45 | }
46 | } catch(Exception e){
47 | null
48 | }
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/sumEstOriginalTime.groovy:
--------------------------------------------------------------------------------
1 | import com.atlassian.jira.ComponentAccessor
2 | import com.atlassian.jira.issue.CustomFieldManager
3 | import com.atlassian.jira.component.ComponentAccessor;
4 | import org.apache.log4j.Level
5 | import org.apache.log4j.Logger
6 |
7 | import com.atlassian.jira.issue.search.SearchProvider
8 | import com.atlassian.jira.jql.parser.JqlQueryParser
9 | import com.atlassian.jira.web.bean.PagerFilter
10 |
11 | import com.atlassian.jira.issue.Issue
12 | import com.atlassian.jira.issue.IssueManager
13 |
14 | IssueManager issueManager = ComponentAccessor.getIssueManager()
15 | def issueLinkManager = ComponentAccessor.getIssueLinkManager()
16 | def cfManager = ComponentAccessor.getCustomFieldManager()
17 |
18 | Logger logger = Logger.getLogger("sacos.aggregate.estimation")
19 | logger.setLevel(Level.ALL)
20 |
21 | @com.onresolve.scriptrunner.parameters.annotation.ShortTextInput(description = "Enter Jira to execute the script on - leave empty for non-debug modes", label = "Jira Request Issue")
22 | String jiraDebugIssue
23 |
24 | logger.info("jiraDebugIssue=" + jiraDebugIssue)
25 |
26 | //Issue issue
27 | if ( jiraDebugIssue != null ){
28 | issue = issueManager.getIssueObject(jiraDebugIssue) // Add an issue for testing
29 | logger.setLevel(Level.ALL) // ALL, WARN
30 | }
31 |
32 |
33 | long totalOrigTime = 0
34 | if (issue.getIssueTypeId() != "10000") {
35 | logger.info("Issue type is not executed on type: " + issue.getIssueType().getName())
36 | return null
37 | } else {
38 | logger.info("Issue type is Epic - proceed: " + issue.getIssueType().getName())
39 | }
40 |
41 | issueLinkManager.getOutwardLinks(issue.id)?.each {issueLink ->
42 | if (issueLink.issueLinkType.name == "Epic-Story Link" ) {
43 | long origTime = issueLink.destinationObject.originalEstimate?:0
44 | if ( origTime != 0 ){
45 | logger.info(issueLink.destinationObject.getIssueType().name + ": " + issueLink.destinationObject.getKey() + " : " + issueLink.issueLinkType.name + " : OK : originalEstimate=" + origTime )
46 | totalOrigTime = origTime + totalOrigTime;
47 | logger.info("Aggregated : " + totalOrigTime )
48 | }
49 | issueLink.destinationObject.getSubTaskObjects()?.each { issueSubtask ->
50 | long origTimeSubtask = issueSubtask.originalEstimate?:0
51 | if ( origTimeSubtask != 0 ){
52 | logger.info("Subtask: " + issueSubtask.getKey() + " : OK : originalEstimate=" + origTimeSubtask )
53 | totalOrigTime = origTimeSubtask + totalOrigTime;
54 | logger.info("Aggregated : " + totalOrigTime )
55 | }
56 | }
57 | } else {
58 | logger.info("Issue link type: " + issueLink.issueLinkType.name + " : -skip")
59 | }
60 |
61 | }
62 | logger.info("Total time estimate: " + totalOrigTime )
63 |
64 | return totalOrigTime
65 |
66 |
67 |
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/sumEstOriginalTimeStoryOnly.groovy:
--------------------------------------------------------------------------------
1 | import com.atlassian.jira.ComponentAccessor
2 | import com.atlassian.jira.issue.CustomFieldManager
3 | import com.atlassian.jira.component.ComponentAccessor;
4 | import org.apache.log4j.Level
5 | import org.apache.log4j.Logger
6 |
7 | import com.atlassian.jira.issue.search.SearchProvider
8 | import com.atlassian.jira.jql.parser.JqlQueryParser
9 | import com.atlassian.jira.web.bean.PagerFilter
10 |
11 | def issueLinkManager = ComponentAccessor.getIssueLinkManager()
12 | def cfManager = ComponentAccessor.getCustomFieldManager()
13 |
14 | Logger logger = Logger.getLogger("sacos.aggregate.estimation")
15 | logger.setLevel(Level.ALL)
16 |
17 | long totalOrigTime = 0
18 | if (issue.getIssueTypeId() != "10000") {
19 | logger.info("Issue type is not executed on type: " + issue.getIssueType().getName())
20 | return null
21 | } else {
22 | logger.info("Issue type is Epic - proceed: " + issue.getIssueType().getName())
23 | }
24 |
25 | issueLinkManager.getOutwardLinks(issue.id)?.each {issueLink ->
26 | if (issueLink.issueLinkType.name == "Epic-Story Link" ) {
27 | long origTime = issueLink.destinationObject.originalEstimate?:0
28 | logger.info("Issue link type: " + issueLink.issueLinkType.name + " : OK : originalEstimate=" + origTime )
29 | totalOrigTime = origTime + totalOrigTime;
30 | } else {
31 | logger.info("Issue link type: " + issueLink.issueLinkType.name + " : -skip")
32 | }
33 | }
34 | logger.info("Total time estimate: " + totalOrigTime )
35 |
36 | return totalOrigTime
37 |
38 |
39 |
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/sumEstOriginalTimeStorySubtask.groovy:
--------------------------------------------------------------------------------
1 | import com.atlassian.jira.ComponentAccessor
2 | import com.atlassian.jira.issue.CustomFieldManager
3 | import com.atlassian.jira.component.ComponentAccessor;
4 | import org.apache.log4j.Level
5 | import org.apache.log4j.Logger
6 |
7 | import com.atlassian.jira.issue.search.SearchProvider
8 | import com.atlassian.jira.jql.parser.JqlQueryParser
9 | import com.atlassian.jira.web.bean.PagerFilter
10 |
11 | import com.atlassian.jira.issue.Issue
12 | import com.atlassian.jira.issue.IssueManager
13 |
14 | IssueManager issueManager = ComponentAccessor.getIssueManager()
15 | def issueLinkManager = ComponentAccessor.getIssueLinkManager()
16 | def cfManager = ComponentAccessor.getCustomFieldManager()
17 |
18 | Logger logger = Logger.getLogger("sacos.aggregate.estimation")
19 | logger.setLevel(Level.ALL)
20 |
21 | @com.onresolve.scriptrunner.parameters.annotation.ShortTextInput(description = "Enter Jira to execute the script on - leave empty for non-debug modes", label = "Jira Request Issue")
22 | String jiraDebugIssue
23 |
24 | logger.info("jiraDebugIssue=" + jiraDebugIssue)
25 |
26 | Issue issue
27 | if ( jiraDebugIssue != null ){
28 | issue = issueManager.getIssueObject(jiraDebugIssue) // Add an issue for testing
29 | logger.setLevel(Level.ALL) // ALL, WARN
30 | }
31 |
32 |
33 | long totalOrigTime = 0
34 | if (issue.getIssueTypeId() != "10000") {
35 | logger.info("Issue type is not executed on type: " + issue.getIssueType().getName())
36 | return null
37 | } else {
38 | logger.info("Issue type is Epic - proceed: " + issue.getIssueType().getName())
39 | }
40 |
41 | issueLinkManager.getOutwardLinks(issue.id)?.each {issueLink ->
42 | if (issueLink.issueLinkType.name == "Epic-Story Link" ) {
43 | long origTime = issueLink.destinationObject.originalEstimate?:0
44 | if ( origTime != 0 ){
45 | logger.info(issueLink.destinationObject.getIssueType().name + ": " + issueLink.destinationObject.getKey() + " : " + issueLink.issueLinkType.name + " : OK : originalEstimate=" + origTime )
46 | totalOrigTime = origTime + totalOrigTime;
47 | logger.info("Aggregated : " + totalOrigTime )
48 | }
49 | issueLink.destinationObject.getSubTaskObjects()?.each { issueSubtask ->
50 | long origTimeSubtask = issueSubtask.originalEstimate?:0
51 | if ( origTimeSubtask != 0 ){
52 | logger.info("Subtask: " + issueSubtask.getKey() + " : OK : originalEstimate=" + origTimeSubtask )
53 | totalOrigTime = origTimeSubtask + totalOrigTime;
54 | logger.info("Aggregated : " + totalOrigTime )
55 | }
56 | }
57 | } else {
58 | logger.info("Issue link type: " + issueLink.issueLinkType.name + " : -skip")
59 | }
60 |
61 | }
62 | logger.info("Total time estimate: " + totalOrigTime )
63 |
64 | return totalOrigTime
65 |
66 |
67 |
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/fields/sumEstStoryPoints.groovy:
--------------------------------------------------------------------------------
1 | import com.atlassian.jira.ComponentAccessor
2 | import com.atlassian.jira.issue.CustomFieldManager
3 | import com.atlassian.jira.component.ComponentAccessor;
4 | import org.apache.log4j.Level
5 | import org.apache.log4j.Logger
6 |
7 | import com.atlassian.jira.issue.search.SearchProvider
8 | import com.atlassian.jira.jql.parser.JqlQueryParser
9 | import com.atlassian.jira.web.bean.PagerFilter
10 |
11 | def issueLinkManager = ComponentAccessor.getIssueLinkManager()
12 | def cfManager = ComponentAccessor.getCustomFieldManager()
13 |
14 | Logger logger = Logger.getLogger("sacos.aggregate.estimation")
15 | logger.setLevel(Level.ALL)
16 |
17 | double totalSP = 0
18 | if (issue.getIssueTypeId() != "10000") {
19 | logger.info("Issue type is not executed on type: " + issue.getIssueType().getName())
20 | return null
21 | } else {
22 | logger.info("Issue type is Epic - proceed: " + issue.getIssueType().getName())
23 | }
24 |
25 | issueLinkManager.getOutwardLinks(issue.id)?.each {issueLink ->
26 | if (issueLink.issueLinkType.name == "Epic-Story Link" ) {
27 | def customFieldSP = ComponentAccessor.getCustomFieldManager().getCustomFieldObject("customfield_10006");
28 | double SP = (double)(issueLink.destinationObject.getCustomFieldValue(customFieldSP) ?: 0)
29 | logger.info("Issue link type: " + issueLink.issueLinkType.name + " : OK : SP=" + SP )
30 | totalSP = SP + totalSP;
31 | } else {
32 | logger.info("Issue link type: " + issueLink.issueLinkType.name + " : -skip")
33 | }
34 | }
35 | return totalSP
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/workflow/epicValidationStoriesDone.groovy:
--------------------------------------------------------------------------------
1 | // Not tested
2 |
3 | import com.atlassian.jira.component.ComponentAccessor
4 | import com.atlassian.jira.workflow.TransitionOptions
5 |
6 | // the name of the action you want to move the issue to
7 | final actionName = 'Close'
8 |
9 | //Name of the resolution children issues should have
10 | final resolutionName = 'In validation'
11 |
12 | // the name of the issue link
13 | final issueLinkName = 'Epic-Story Link'
14 |
15 | def workflow = ComponentAccessor.workflowManager.getWorkflow(issue)
16 | def actionId = workflow.allActions.findByName(actionName)?.id
17 | def linkManager = ComponentAccessor.issueLinkManager
18 |
19 | def epicIssue = linkManager.getInwardLinks(issue.id).find { it.issueLinkType.name == issueLinkName }?.sourceObject
20 | if (!epicIssue) {
21 | return
22 | }
23 |
24 | // Find all the linked - with the "Epic-Story Link" link - issues that their status is not the same as resolutionName
25 |
26 | def linkedIssues = linkManager
27 | .getOutwardLinks(epicIssue.id)
28 | .findAll { it.issueLinkType.name == issueLinkName }
29 | *.destinationObject?.findAll { it.resolution?.name != resolutionName }
30 |
31 | // If there are still open linked issues (except the one in transition) - then do nothing
32 |
33 | if (linkedIssues - issue) {
34 | return
35 | }
36 |
37 | def issueService = ComponentAccessor.issueService
38 | def inputParameters = issueService.newIssueInputParameters()
39 |
40 | inputParameters.setComment('This Epic closed automatically because all the issues in this Epic are closed.')
41 | inputParameters.setSkipScreenCheck(true)
42 |
43 | def transitionOptions = new TransitionOptions.Builder()
44 | .skipConditions()
45 | .skipPermissions()
46 | .skipValidators()
47 | .build()
48 |
49 | def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
50 | def transitionValidationResult = issueService.validateTransition(loggedInUser, epicIssue.id, actionId, inputParameters, transitionOptions)
51 | assert transitionValidationResult.valid: transitionValidationResult.errorCollection
52 |
53 | def result = issueService.transition(loggedInUser, transitionValidationResult)
54 | assert result.valid: result.errorCollection
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/workflow/implSolutionRequired.groovy:
--------------------------------------------------------------------------------
1 | import com.atlassian.jira.component.ComponentAccessor
2 | import com.atlassian.jira.issue.CustomFieldManager
3 | import com.opensymphony.workflow.InvalidInputException
4 |
5 | CustomFieldManager cfManager = ComponentAccessor.getCustomFieldManager()
6 | implSolutionCf = cfManager.getCustomFieldObjectsByName("Implemented solution")[0]
7 |
8 | log.warn(implSolutionCf)
9 | def implSolution = issue.getCustomFieldValue(implSolutionCf)
10 | log.warn(implSolution)
11 |
12 | if(["Bug", "Story", "Eval"].contains(issue.getIssueType().getName())){
13 | log.warn("Story, Bug, Eval")
14 | if(!implSolution?.trim()){
15 | throw new InvalidInputException("Implemented Solution is required for Story, Bug, Eval")
16 | false
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/workflow/requestDoneEpicsDone.groovy:
--------------------------------------------------------------------------------
1 | import com.atlassian.jira.component.ComponentAccessor
2 | import com.atlassian.jira.workflow.TransitionOptions
3 |
4 | // the name of the action you want to move the issue to
5 | final actionName = 'Close'
6 |
7 | //Name of the resolution children issues should have
8 | final resolutionName = 'Done'
9 |
10 | // the name of the issue link
11 | final issueLinkName = ''
12 |
13 | def workflow = ComponentAccessor.workflowManager.getWorkflow(issue)
14 | def actionId = workflow.allActions.findByName(actionName)?.id
15 | def linkManager = ComponentAccessor.issueLinkManager
16 |
17 | def epicIssue = linkManager.getInwardLinks(issue.id).find { it.issueLinkType.name == issueLinkName }?.sourceObject
18 | if (!epicIssue) {
19 | return
20 | }
21 |
22 | // Find all the linked - with the "Epic-Story Link" link - issues that their status is not the same as resolutionName
23 |
24 | def linkedIssues = linkManager
25 | .getOutwardLinks(epicIssue.id)
26 | .findAll { it.issueLinkType.name == issueLinkName }
27 | *.destinationObject?.findAll { it.resolution?.name != resolutionName }
28 |
29 | // If there are still open linked issues (except the one in transition) - then do nothing
30 |
31 | if (linkedIssues - issue) {
32 | return
33 | }
34 |
35 | def issueService = ComponentAccessor.issueService
36 | def inputParameters = issueService.newIssueInputParameters()
37 |
38 | inputParameters.setComment('This Epic closed automatically because all the issues in this Epic are closed.')
39 | inputParameters.setSkipScreenCheck(true)
40 |
41 | def transitionOptions = new TransitionOptions.Builder()
42 | .skipConditions()
43 | .skipPermissions()
44 | .skipValidators()
45 | .build()
46 |
47 | def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
48 | def transitionValidationResult = issueService.validateTransition(loggedInUser, epicIssue.id, actionId, inputParameters, transitionOptions)
49 | assert transitionValidationResult.valid: transitionValidationResult.errorCollection
50 |
51 | def result = issueService.transition(loggedInUser, transitionValidationResult)
52 | assert result.valid: result.errorCollection
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/workflow/setEpicStatusDone.groovy:
--------------------------------------------------------------------------------
1 | import com.atlassian.jira.ComponentManager;
2 | import com.atlassian.jira.component.ComponentAccessor;
3 | import com.atlassian.jira.issue.CustomFieldManager;
4 | import com.atlassian.jira.issue.fields.CustomField;
5 | import com.atlassian.jira.issue.IssueManager;
6 | import com.atlassian.jira.issue.MutableIssue;
7 | import com.atlassian.jira.issue.Issue;
8 | import com.atlassian.jira.user.ApplicationUser;
9 | import com.atlassian.jira.bc.issue.IssueService
10 | import com.atlassian.jira.component.ComponentAccessor
11 | import com.atlassian.jira.issue.IssueInputParametersImpl
12 |
13 | def currentUser = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
14 | def issueManager = ComponentAccessor.issueManager
15 | IssueService issueService = ComponentAccessor.getIssueService()
16 | def actionId = 31 // change this to the step that you want the issues to be transitioned to
17 |
18 | def transitionValidationResult
19 | def transitionResult
20 |
21 |
22 | def epicLink = ComponentAccessor.customFieldManager.getCustomFieldObjectByName("Epic Link")
23 | def epic = issue.getCustomFieldValue(epicLink) as String
24 | if(epic){
25 | def issueE = issueManager.getIssueObject(epic);
26 | if(issueE.getStatus().name != "In Progress" )
27 | {
28 | transitionValidationResult = issueService.validateTransition(currentUser, issueE.id, actionId,new IssueInputParametersImpl())
29 | if (transitionValidationResult.isValid()) {
30 | transitionResult = issueService.transition(currentUser, transitionValidationResult)
31 | if (transitionResult.isValid())
32 | { log.debug("Transitioned issue $issue through action $actionId") }
33 | else
34 | { log.debug("Transition result is not valid") }
35 | }else{
36 | log.debug("The transitionValidation is not valid")
37 | }
38 |
39 | }
40 | }
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/workflow/validators/blockEpic2DoneRejectedIfChildsNotRejectedDone.groovy:
--------------------------------------------------------------------------------
1 | import com.atlassian.jira.component.ComponentAccessor
2 | import com.atlassian.jira.issue.Issue
3 | import com.atlassian.jira.issue.IssueManager
4 | import com.atlassian.jira.issue.issuetype.IssueType
5 | import com.atlassian.jira.issue.link.IssueLink
6 | import com.atlassian.jira.issue.link.IssueLinkManager
7 | import com.atlassian.jira.issue.link.IssueLinkType
8 | import com.atlassian.jira.issue.status.Status
9 | import com.atlassian.jira.user.ApplicationUser
10 | import com.opensymphony.workflow.InvalidInputException
11 |
12 | IssueManager issueManager = ComponentAccessor.getIssueManager()
13 | ApplicationUser user = ComponentAccessor.getJiraAuthenticationContext().getLoggedInUser()
14 | IssueLinkManager issueLinkManager = ComponentAccessor.getIssueLinkManager()
15 |
16 | Issue epic = issue as Issue
17 |
18 | List allOutIssueLink = issueLinkManager.getOutwardLinks(epic.getId())
19 |
20 | allOutIssueLink.each { IssueLink it ->
21 | Issue linkedIssue = it.destinationObject
22 | Status status = linkedIssue.getStatus()
23 | IssueLinkType issueLinkType = it.getIssueLinkType()
24 |
25 | if(!["Rejected", "Done"].contains(status.getName()) && issueLinkType.getOutward() == "is Epic of"){
26 | throw new InvalidInputException("All stories and bugs in epic must be either Rejected or Done");
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/jira/scripts/ScriptRunner/workflow/validators/implSolutionRequiredv2.groovy:
--------------------------------------------------------------------------------
1 | import com.atlassian.jira.component.ComponentAccessor
2 | import com.atlassian.jira.issue.CustomFieldManager
3 | import com.opensymphony.workflow.InvalidInputException
4 |
5 | CustomFieldManager cfManager = ComponentAccessor.getCustomFieldManager()
6 | implSolutionCf = cfManager.getCustomFieldObjectsByName("Implemented solution")[0]
7 |
8 | log.warn(implSolutionCf)
9 | def implSolution = issue.getCustomFieldValue(implSolutionCf)
10 | log.warn(implSolution)
11 |
12 | if(["Bug", "Story"].contains(issue.getIssueType().getName())){
13 | log.warn("Story or Bug")
14 | if(!implSolution?.trim()){
15 | throw new InvalidInputException("Implemented Solution is required for Story and Bug")
16 | false
17 | }
18 | }
--------------------------------------------------------------------------------
/jira/scripts/component_delete_from_parameters.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 | set -u
5 |
6 | [[ ${debug:-} == true ]] && set -x
7 |
8 | [[ ${jira_server:-} == true ]] && ( echo "jira_server is not set" && exit 1 )
9 |
10 | jira_key="${1}"
11 | component_name="${2}"
12 |
13 | netrc_file=~/.netrc
14 |
15 |
16 | component_already_exists=$(curl --fail --insecure --netrc-file ${netrc_file} -X GET -H Content-Type:application/json -o - --silent --url ${jira_server}/rest/api/2/project/${jira_key}/components \
17 | | jq -r ".[] | select(.name==\"${component_name}\").name" )
18 | if [[ "${component_already_exists:-}" == "${component_name}" ]] ; then
19 | printf "Component: ${component_name} exists in project: ${jira_key} - delete :"
20 | else
21 | printf "Component: ${component_name} in project: ${jira_key} - does not exist - exit"
22 | exit 0
23 | fi
24 |
25 | component_id=$(curl --fail --insecure --netrc-file ${netrc_file} -X GET -H Content-Type:application/json -o - --silent --url ${jira_server}/rest/api/2/project/${jira_key}/components \
26 | | jq -r ".[] | select(.name==\"${component_name}\").id" )
27 |
28 | exit
29 |
30 | if ! curl --fail --insecure --netrc-file ${netrc_file} -X POST -H Content-Type:application/json -o - --silent --url ${jira_server}/rest/api/2/component --upload-file jira_component2.json > /dev/null; then
31 | echo "Failed.. Maybe the component is already in the project.. - exit 1"
32 | exit 1
33 | else
34 | printf "Done\n"
35 | fi
36 | rm jira_component2.json
37 |
--------------------------------------------------------------------------------
/jira/scripts/create-jira-project-from-shared-config.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 |
4 |
5 | [[ ${debug:-} == true ]] && set -x
6 | set -u
7 | set -e
8 |
9 |
10 | [[ ${1:-} == "" ]] && echo "Please parse new project's desired key to as parameter 1"
11 | jira_project_new_key="$1"
12 |
13 | [[ ${2:-} == "" ]] && echo "Please parse new project's desired name to as parameter 2"
14 | jira_project_new_name="$2"
15 |
16 | [[ ${3:-} == "" ]] && echo "Please parse the project template to create from as parameter 3"
17 | jira_project_template_key="$3"
18 |
19 | [[ ${4:-} == "" ]] && echo "Please parse the project lead to create from as parameter 4"
20 | jira_project_lead="$4"
21 |
22 | if [[ ${create_mode:-} == "" ]]; then
23 | create_mode="skipOcreate" #deleteNcreate , skipNcreate(default), delete
24 | echo "Using default mode: create_mode=$create_mode - Options: deleteNcreate , skipOcreate(default), delete"
25 | else
26 | echo "Using create_mode: $create_mode - Options: deleteNcreate , skipOcreate(default), delete"
27 | fi
28 |
29 | netrc_file=$(echo ~).netrc
30 |
31 | curl_GET_cmd="curl --fail --insecure --netrc-file ${netrc_file} -X GET -H Content-Type:application/json -o - "
32 | curl_POST_cmd="curl --fail --insecure --netrc-file ${netrc_file} -X POST -H Content-Type:application/json -o - "
33 | curl_DELETE_cmd="curl --fail --insecure --netrc-file ${netrc_file} -X DELETE -H Content-Type:application/json -o - "
34 |
35 | project_key_found=$(${curl_GET_cmd} --silent --url "${jira_server}/rest/api/2/project/${jira_project_new_key}" | jq -r .key )
36 |
37 | if [[ $create_mode == "delete" ]]; then
38 | if [[ "${project_key_found}" == "${jira_project_new_key}" ]] ; then
39 | printf "Project found: $project_key_found - delete it... and it might take some time depend on the amount of issues.."
40 | printf " - but sleep for 10 sec to offer abort...\n"
41 | sleep 10
42 | ${curl_DELETE_cmd} --url ${jira_server}/rest/api/2/project/${jira_project_new_key}
43 | exit 0
44 | else
45 | echo "Project not found: $jira_project_new_key - skip deleting"
46 | exit 0
47 | fi
48 | fi
49 |
50 | project_template_id=$(${curl_GET_cmd} --silent --url ${jira_server}/rest/api/2/project/${jira_project_template_key} | jq -r .id )
51 | if [[ ${project_template_id} == "" ]] ; then
52 | echo "Template project: $jira_project_template_key NOT found on server: $jira_server"
53 | exit 1
54 | fi
55 |
56 | if [[ "${project_key_found}" == "${jira_project_new_key}" ]] ; then
57 | if [[ $create_mode == "deleteNcreate" ]]; then
58 | printf "Project found: $project_key_found - delete it first... and it might take some depend on the amount of issues.."
59 | if [[ ${force:-} == true ]] ; then
60 | printf " - run in force mode without sleeping\n"
61 | else
62 | printf " - but sleep for 10 sec to offer abort...\n"
63 | sleep 10
64 | fi
65 | echo ".. starting .."
66 | ${curl_DELETE_cmd} --url ${jira_server}/rest/api/2/project/${jira_project_new_key}
67 | fi
68 | if [[ $create_mode == "skipOcreate" ]]; then
69 | echo "Project found: $project_key_found - skip"
70 | exit 0
71 | fi
72 | else
73 | echo "Project: $jira_project_new_key not found on server: $jira_server - create it"
74 | fi
75 |
76 | echo "Using project: $jira_project_template_key as template on $jira_server"
77 |
78 | echo "Create new project key:$jira_project_new_key name:\"$jira_project_new_name\" from $jira_project_template_key"
79 | $curl_POST_cmd -d "{ \"key\":\"${jira_project_new_key}\", \"name\":\"${jira_project_new_name}\",\"lead\":\"$jira_project_lead\" }" \
80 | --url ${jira_server}/rest/project-templates/1.0/createshared/${project_template_id}
81 | echo
82 |
83 | #curl -D- -u : -H "Content-Type:application/json" -X POST -d '{"user":["username"]}' -k https://jira-stg.example.com/rest/api/2/project/ABC/role/10002
84 |
--------------------------------------------------------------------------------
/jira/scripts/create-projects-n-update-components.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -e
3 | set -u
4 |
5 | [[ ${debug:-} == true ]] && set -x
6 |
7 | export jira_server="https://[:8080]"
8 |
9 | echo "Using Jira server: $jira_server"
10 |
11 | # Load functions
12 | source ${BASH_SOURCE%/*}/_jira_project_create_update_functions.sh|| source ./_jira_project_create_update_functions.sh
13 |
14 |
15 | if [[ ${1:-} == "" ]] ; then
16 | echo "Import files not in use : - skip"
17 | else
18 | jira_import_files=$1
19 | IFS=" "
20 | for jira_import_file in $jira_import_files; do
21 | if [[ -e ${jira_import_file} ]]; then
22 | echo "Using $jira_import_file"
23 | else
24 | echo "file '${jira_import_file}' does not exists"
25 | exit 1
26 | fi
27 | done
28 | unset IFS
29 | fi
30 |
31 |
32 | #################
33 | #
34 | # Team project
35 | #
36 | #################
37 | export mode="skipOcreate"
38 | #export create_mode="deleteNcreate"
39 | #create_team_project "" "" "" ["]
40 |
41 | unset mode
42 |
43 | #################
44 | #
45 | # Product/Archive/Inbox project
46 | #
47 | #################
48 |
49 | export mode="skipOcreate"
50 | #export create_mode="deleteNcreate"
51 | #create_jira_product_proj "" "" ""
52 | unset mode
53 |
54 | update_jira_proj_category_projs_w_components_of_teams_project_keys "SaCoS projects" "^S1.*\$|^S5K.*\$|^SACOS\$|^SMP.*\$" "^SCS.*\$"
55 |
--------------------------------------------------------------------------------
/jira/scripts/create_component_from_parameters.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 | set -u
5 |
6 | [[ ${debug:-} == true ]] && set -x
7 |
8 | [[ ${jira_server:-} == true ]] && ( echo "jira_server is not set" && exit 1 )
9 |
10 | jira_key="${1}"
11 | component_name="${2}"
12 | component_lead="${3}"
13 |
14 | netrc_file=~/.netrc
15 |
16 |
17 | component_already_exists=$(curl --fail --insecure --netrc-file ${netrc_file} -X GET -H Content-Type:application/json -o - --silent --url ${jira_server}/rest/api/2/project/${jira_key}/components \
18 | | jq -r ".[] | select(.name==\"${component_name}\").name" )
19 | if [[ "${component_already_exists:-}" == "${component_name}" ]] ; then
20 | echo "Component: ${component_name} already exists in project: ${jira_key} - skip"
21 | exit
22 | else
23 | printf "Component: ${component_name} in project: ${jira_key} - create: "
24 | fi
25 |
26 | echo "{ \"project\":\"$jira_key\"}" > jira_project.json
27 |
28 | if [[ ${component_lead:-} == "" ]]; then
29 | echo "{ \"name\": \"${component_name}\", \"assigneeType\": \"UNASSIGNED\" }" > jira_component.json
30 | else
31 | echo "{ \"name\": \"${component_name}\", \"leadUserName\": \"${component_lead}\", \"assigneeType\": \"COMPONENT_LEAD\" }" > jira_component.json
32 | fi
33 | jq -s '.[0] * .[1]' jira_project.json jira_component.json > jira_component2.json
34 | rm jira_component.json
35 | rm jira_project.json
36 |
37 | if ! curl --fail --insecure --netrc-file ${netrc_file} -X POST -H Content-Type:application/json -o - --silent --url ${jira_server}/rest/api/2/component --upload-file jira_component2.json > /dev/null; then
38 | echo "Failed.. Maybe the component is already in the project.. - exit 1"
39 | exit 1
40 | else
41 | printf "Done\n"
42 | fi
43 | rm jira_component2.json
44 |
--------------------------------------------------------------------------------
/jira/scripts/create_components_from_json_import.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 | set -u
5 |
6 | [[ ${debug:-} == true ]] && set -x
7 | [[ ${jira_server:-} == true ]] && ( echo "jira_server is not set" && exit 1 )
8 |
9 | jira_key="${1}"
10 | reqex_components=${2} # '.*Sprint.*|.*6.*'
11 | import_file=${3}
12 |
13 |
14 | netrc_file=~/.netrc
15 |
16 |
17 | echo "{ \"project\":\"$jira_key\"}" > jira_project.json
18 |
19 | IFS=$'\r\n'
20 | for component in $(jq -r ".projects[0].components[] | select(.name? | match(\"${reqex_components}\")).name" $import_file ) ; do
21 | echo $component
22 | jq -r ".projects[0].components[] | select(.name == \"${component}\")" $import_file > jira_component.json
23 | jq -s '.[0] * .[1]' jira_project.json jira_component.json > jira_component2.json
24 | rm jira_component.json
25 |
26 | if ! curl --fail --insecure --netrc-file ${netrc_file} -X POST -H Content-Type:application/json -o - --url ${jira_server}/rest/api/2/component --upload-file jira_component2.json ; then
27 | echo "Failed.. Maybe the component is already in the project.. Exit code: $?"
28 | exit 1
29 | fi
30 | echo
31 | rm -f jira_component2.json
32 | done
33 | rm jira_project.json
34 |
--------------------------------------------------------------------------------
/jira/scripts/create_releases_from_json_import.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 | set -u
5 |
6 | [[ ${debug:-} == true ]] && set -x
7 | [[ ${jira_server:-} == true ]] && ( echo "jira_server is not set" && exit 1 )
8 |
9 | jira_key="${1}"
10 | reqex_releases=${2} # '.*Sprint.*|.*6.*'
11 | import_file=${3}
12 |
13 | netrc_file=~/.netrc
14 |
15 |
16 | echo "{ \"project\":\"$jira_key\"}" > jira_project.json
17 |
18 | jq -r ".projects[0].versions[] | select(.name? | match(\"${reqex_releases}\")).name" $import_file > releases.txt
19 | dos2unix releases.txt
20 | IFS=$'\r\n'
21 | for release in $(jq -r ".projects[0].versions[] | select(.name? | match(\"${reqex_releases}\")).name" $import_file ) ; do
22 | version_already_exists=$(curl --fail --insecure --netrc-file ${netrc_file} -X GET -H Content-Type:application/json -o - --silent --url ${jira_server}/rest/api/2/project/${jira_key}/versions \
23 | | jq -r ".[] | select(.name==\"${release}\").name" )
24 | if [[ "${version_already_exists:-}" == "${release}" ]] ; then
25 | echo "Version: ${release} already exists in project: ${jira_key} - skip"
26 | continue
27 | else
28 | printf "Version: ${release} in project: ${jira_key} - create: "
29 | fi
30 |
31 |
32 | jq -r ".projects[0].versions[] | select(.name == \"${release}\")" $import_file > jira_release.json
33 | jq -s '.[0] * .[1]' jira_project.json jira_release.json > jira_release2.json
34 |
35 | # TODO: checck update script to handle exit codes from curl
36 | if ! curl --fail --insecure --netrc-file ${netrc_file} -X POST -H Content-Type:application/json -o - --silent --url ${jira_server}/rest/api/2/version --upload-file jira_release2.json > /dev/null ; then
37 | exit_code=$?
38 | if [[ $exit_code -eq 0 ]]; then
39 | printf " Failed.. Maybe the release is already in the project.. Exit code: $exit_code - same name lower / UPPER caps ?? - continue\n"
40 | continue
41 | else
42 | printf " Failed.. for unknown reason"
43 | cat jira_release2.json
44 | exit $exit_code
45 | fi
46 | else
47 | printf " $? : Done\n"
48 | fi
49 | rm -f jira_release.json
50 | rm -f jira_release2.json
51 | done
52 |
53 | rm -f jira_project.json
--------------------------------------------------------------------------------
/jira/scripts/jira-delete-users.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #set -x
3 |
4 | input_file=$1
5 |
6 | IFS=$'\r\n'
7 | #for user in `jq .users[].name ${input_file} | sed -e 's/"//g'`
8 | #for user in $(ccm users -l)
9 | jira_user_group="change_synergy-import-unused-users"
10 | for user in $(curl --silent --fail --insecure --netrc-file /z//.netrc -X GET -H "Content-Type:application/json" --url "${jira_server}/rest/api/2/group/member?groupname=${jira_user_group}&includeInactiveUsers=true" | jq -r .values[].key)
11 | do
12 | echo "Delete: ${user}"
13 | curl --insecure --request DELETE --netrc-file ~/.netrc --url ${jira_server}/rest/api/2/user?username=$user
14 | sleep 1
15 | done
16 |
--------------------------------------------------------------------------------
/jira/scripts/jira-delete-versions.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | #set -x
3 |
4 | jira_server=$1
5 | input_file=$2
6 |
7 | for id in `jq .[].id ${input_file} | sed -e 's/"//g'`
8 | do
9 | curl --insecure --request DELETE --netrc-file ./.netrc --url 'https://${jira_server}/rest/api/2/version/'$id''
10 | done
11 |
12 |
13 | https://${jira_server}/rest/api/2/user/application?username=v7y1uvq&applicationKey=
14 | https://${jira_server}/rest/plugins/applications/1.0/installed/jira-software/license
15 | https://${jira_server}/rest/api/2/group/change_synergy-import-unused-users
16 | groupname=change_synergy-import-unused-users
17 | /rest/api/1.0/admin/groups/more-members?context=change_synergy-import-unused-users&limit=1000
--------------------------------------------------------------------------------
/jira/scripts/jira_attachments_import.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Author: Jaime Kirch da Silveira (Atlassian Cloud Support)
4 | # Last update: April, 17th, 2015
5 |
6 | # This will import all attachments to JIRA issues
7 | # Check this KB for more information:
8 | # https://confluence.atlassian.com/display/JIRAKB/Bulk+import+attachments+to+JIRA+issues+via+REST+API
9 |
10 | if [[ $# != 4 ]]
11 | then
12 |
13 | echo "Format: $0 "
14 | echo "Please notice that the JIRA URL must include all the path to access JIRA, including anything after the '/' (like /jira) and the protocol as well (like https://)"
15 | exit
16 | fi
17 |
18 | USERNAME=$1
19 | PASSWORD=$2
20 | PROJECT_KEY=$3
21 | JIRA_URL=$4
22 |
23 | AUTH_TYPE=cookie
24 | #AUTH_TYPE=basic
25 |
26 | COOKIE_FILE=cookie.txt
27 |
28 | if [ "${AUTH_TYPE}" = 'cookie' ]
29 | then
30 | curl --cookie-jar ${COOKIE_FILE} -H "Content-Type: application/json" -d '{"username":"'${USERNAME}'", "password":"'${PASSWORD}'" }' -X POST ${JIRA_URL}/rest/auth/1/session
31 | fi
32 |
33 |
34 | for key in ${PROJECT_KEY}-*
35 | do
36 | if [ "$(ls -A ${key})" ]
37 | then
38 | echo "Importing attachments for issue $key"
39 | for file in $key/*
40 | do
41 | echo "Importing file: $file"
42 | if [ "${AUTH_TYPE}" = 'cookie' ]
43 | then
44 | curl -D- -b ${COOKIE_FILE} -X POST --header "X-Atlassian-Token: no-check" -F "file=@${file}" ${JIRA_URL}/rest/api/2/issue/${key}/attachments
45 | else
46 | if [ "${AUTH_TYPE}" = 'basic' ]
47 | then
48 | curl -D- -u ${USERNAME}:${PASSWORD} -X POST --header "X-Atlassian-Token: no-check" -F "file=@${file}" ${JIRA_URL}/rest/api/2/issue/${key}/attachments
49 | fi
50 | fi
51 | done
52 | fi
53 |
54 | done
55 |
--------------------------------------------------------------------------------
/jira/scripts/jqlScripts/src/com/onresolve/jira/groovy/jql/MismatchedThemes.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by EXT.Tim.Harris on 20-02-2015.
3 | *
4 | * Purpose is to find all User Stories that have a linked "Theme" issue type
5 | * where the Epic of the linked Theme is different than the Epic of the User Story.
6 | *
7 | * If the either the User Story or the linked Themes has an Epic Link and the other
8 | * does not then this is seen as a mismatch.
9 | *
10 | */
11 |
12 | package com.onresolve.jira.groovy.jql
13 |
14 | import com.atlassian.jira.component.ComponentAccessor
15 | import com.atlassian.jira.issue.Issue
16 | import com.atlassian.crowd.embedded.api.User
17 | import com.atlassian.jira.issue.link.IssueLink
18 | import com.atlassian.jira.issue.link.IssueLinkManager
19 | import com.atlassian.jira.jql.query.QueryCreationContext
20 | import com.atlassian.jira.util.MessageSet
21 | import com.atlassian.query.clause.TerminalClause
22 | import com.atlassian.query.operand.FunctionOperand
23 | import org.apache.lucene.index.Term
24 | import org.apache.lucene.search.BooleanClause
25 | import org.apache.lucene.search.BooleanQuery
26 | import org.apache.lucene.search.Query
27 | import org.apache.lucene.search.TermQuery
28 |
29 | class MismatchedThemes extends AbstractScriptedJqlFunction implements JqlQueryFunction{
30 | Category log = Category.getInstance(MismatchedThemes.class)
31 |
32 | @Override
33 | String getDescription() {
34 | "Returns all stories where the epic link is not the same as the epic link of the linked Theme(if there is a linked Theme)." +
35 | " Non Linked Stories and themes are seen as mismatches!"
36 | }
37 |
38 | @Override
39 | List |