-
Notifications
You must be signed in to change notification settings - Fork 15
/
createTaskJIRAs.py
226 lines (200 loc) · 10.5 KB
/
createTaskJIRAs.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
#!/usr/bin/env python3
from jira import JIRA
import urllib, sys, os
from optparse import OptionParser
# Requires jira (`pip3 install jira python-magic`), not jira-python - https://stackoverflow.com/questions/30915236/jira-python-package-in-pip-has-gone
# If connection to JIRA server fails with error: "The error message is __init__() got an unexpected keyword argument 'mime'"
# Then go edit /usr/lib/python2.7/site-packages/jira/client.py
# replace
# self._magic = magic.Magic(mime=True)
# with
# self._magic = magic
#
# ref: http://stackoverflow.com/questions/12609402/init-got-an-unexpected-keyword-argument-mime-in-python-django
usage = "\n\
\n\
Usage 1: python " + sys.argv[0] + " -u <user> -p <pass> -s <JIRA server> -i <jbideversion> -d <jbdsversion>\n\
-t <short task summary> -f <full detailed task description>\n\
\n\
This script will create 1 JBDS and 1 JBIDE JIRA with the specified task summary + description, then create \n\
sub-tasks of the JBIDE JIRA for each of the JBIDE components with matching Github jbosstools-* repos\n\
\n\
Usage 2: as above but use -c <jbide component> or -C <JBDS Component> to specify which single component's\n\
JIRA to create. If both are set only JBDS JIRA will be created\n\
\n\
Optional flags:\n\
\n\
-c, --componentjbide - if set, create only 1 JBIDE JIRA for specified component, eg., openshift\n\
-C, --componentjbds - if set, create only 1 JBDS JIRA for specified component, eg., installer\n\
-A, --auto-accept - if set, automatically accept created issues\n\
-J, --jiraonly - if set, only return JIRA ID instead of component + JIRA URL; implies --auto-accept \n\
\n\
NOTE: rather than passing in --user and --pwd, you can `export userpass=jirauser:jirapwd`, \n\
and this script will read those values from the shell"
parser = OptionParser(usage)
parser.add_option("-i", "--jbide", dest="jbidefixversion", help="JBIDE Fix Version, eg., 4.1.0.qualifier")
parser.add_option("-d", "--jbds", dest="jbdsfixversion", help="JBDS Fix Version, eg., 7.0.0.qualifier")
parser.add_option("-t", "--task", dest="taskdescription", help="Task Summary, eg., \"Code Freeze + Branch\"")
parser.add_option("-f", "--taskfull", dest="taskdescriptionfull", help="Task Description, eg., \"Please perform the following tasks...\"")
# see createTaskJIRAs.py.examples.txt for examples of taskdescriptionfull
parser.add_option("-c", "--componentjbide", dest="componentjbide", help="JBIDE component, eg., server, seam2, openshift; if omitted, create issues for all values in JIRA_components, plus one parent task and one for JBDS")
parser.add_option("-C", "--componentjbds", dest="componentjbds", help="JBDS component, eg., installer")
parser.add_option("-A", "--auto-accept", dest="autoaccept", action="store_true", help="if set, automatically accept created issues")
parser.add_option("-J", "--jiraonly", dest="jiraonly", action="store_true", help="if set, only return the JIRA ID; implies --auto-accept")
parser.add_option("-s", "--server", dest="jiraserver", help="JIRA server, eg., https://issues.stage.redhat.com or https://issues.redhat.com")
parser.add_option("-u", "--user", dest="jirauser", help="JIRA Username")
parser.add_option("-p", "--pwd", dest="jirapwd", help="JIRA Password")
parser.add_option("-k", "--jiratoken", dest="jiratoken", help="JIRA Token")
# NOTE: rather than passing in two flags here, you can `export userpass=jirauser:jirapwd`,
# and this script will read those values from the shell
(options, args) = parser.parse_args()
if (not options.jirauser or not options.jirapwd) and "userpass" in os.environ:
# check if os.environ["userpass"] is set and use that if defined
#sys.exit("Got os.environ[userpass] = " + os.environ["userpass"])
userpass_bits = os.environ["userpass"].split(":")
options.jirauser = userpass_bits[0]
options.jirapwd = userpass_bits[1]
if ((not options.jirauser or not options.jirapwd) and not options.jiratoken) or not options.jiraserver or not options.jbidefixversion or not options.taskdescription:
parser.error("Must to specify ALL commandline flags")
jiraserver = options.jiraserver
try:
if (options.jiratoken):
jira = JIRA(server=jiraserver, token_auth=options.jiratoken)
else:
jira = JIRA(options={'server':jiraserver}, basic_auth=(options.jirauser, options.jirapwd))
except AttributeError as e:
sys.exit("[ERROR] Could not connect to {0} as {1} with jirapwd {2}".format(jiraserver, options.jirauser, options.jirapwd))
except:
sys.exit("[ERROR] Unexpected error:", sys.exc_info()[0])
CLJBIDE = jira.project_components(jira.project('JBIDE')) # full list of components in JBIDE
CLJBDS = jira.project_components(jira.project('JBDS')) # full list of components in JBIDE
jbide_fixversion = options.jbidefixversion
jbds_fixversion = options.jbdsfixversion
from components import checkFixVersionsExist, queryComponentLead
if checkFixVersionsExist(jbide_fixversion, jbds_fixversion, jiraserver, options.jirauser, options.jirapwd) == True:
taskdescription = options.taskdescription
taskdescriptionfull = options.taskdescriptionfull.replace("\\n", "\n")
if not options.taskdescriptionfull:
taskdescriptionfull = options.taskdescription
projectname = 'JBIDE'
fixversion = jbide_fixversion
if not options.componentjbide and not options.componentjbds:
# see JIRA_components listing in components.py
from components import JIRA_components
componentList = JIRA_components
issuetype = 'Sub-task'
else:
# just one task at a time
issuetype = 'Task'
if options.componentjbds:
projectname = 'JBDS'
fixversion = jbds_fixversion
# For mismatched jbosstools-project => JBIDE JIRA component mappings, see getProjectRootPomParent.sh and use :: notation to pass in mappings, eg.,
# ci::build, product::installer
componentList = { options.componentjbds: {options.componentjbds} }
else:
# For mismatched jbdevstudio-project => JBDS JIRA component mappings, see getProjectRootPomParent.sh and use :: notation to pass in mappings, eg.,
# aerogear::aerogear-hybrid, base::foundation, javaee::jsf, vpe::visual-page-editor-core, build-sites::updatesite, discovery::central-update
componentList = { options.componentjbide: {options.componentjbide} }
## The jql query across for all task issues
tasksearchquery = '(project in (JBIDE) and fixVersion = "' + jbide_fixversion + '") AND labels = task'
tasksearch = jiraserver + '/issues/?jql=' + urllib.parse.quote_plus(tasksearchquery)
def nametuple(x):
return { "name" : x }
def quote(x):
return '"' + x + '"'
if not options.componentjbide and not options.componentjbds:
rootJBDS_dict = {
'project' : { 'key': 'JBDS' },
'summary' : 'For JBDS ' + jbds_fixversion + ': ' + taskdescription,
'description' : 'For JBDS ' + jbds_fixversion + ': ' + taskdescriptionfull + '\n\n[Search for all task JIRA|' + tasksearch + ']',
'issuetype' : { 'name' : 'Task' },
'priority' : { 'name' :'Blocker'},
'fixVersions' : [{ "name" : jbds_fixversion }],
'components' : [{ "name" : "installer" }],
'labels' : [ "task" ],
}
rootJBDS = jira.create_issue(fields=rootJBDS_dict)
installerLead = queryComponentLead(CLJBDS, 'installer', 0)
try:
jira.assign_issue(rootJBDS, installerLead)
except:
if (not options.jiraonly):
print ("[WARNING] Unexpected error! User {0} tried to assign {1} to {2}: {3}").format(options.jirauser, rootJBDS, installerLead, sys.exc_info()[0])
if (options.jiraonly):
print(rootJBDS.key)
else:
print("Task JIRA created for this milestone include:")
print("")
print("JBDS : " + jiraserver + '/browse/' + rootJBDS.key + " => " + installerLead)
rootJBIDE_dict = {
'project' : { 'key': 'JBIDE' },
'summary' : 'For JBIDE ' + jbide_fixversion + ': ' + taskdescription,
'description' : 'For JBIDE ' + jbide_fixversion + ': ' + taskdescriptionfull +
'\n\n[Search for all task JIRA|' + tasksearch + ']\n\nSee also: ' + rootJBDS.key,
'issuetype' : { 'name' : 'Task' },
'priority' : { 'name' :'Blocker'},
'fixVersions' : [{ "name" : jbide_fixversion }],
'components' : [{ "name" : "build" }],
'labels' : [ "task" ]
}
rootJBIDE = jira.create_issue(fields=rootJBIDE_dict)
componentLead = queryComponentLead(CLJBIDE, 'build', 0)
try:
jira.assign_issue(rootJBIDE, componentLead)
except:
if (not options.jiraonly):
print ("[WARNING] Unexpected error! User {0} tried to assign {1} to {2}: {3}").format(options.jirauser, rootJBIDE, componentLead, sys.exc_info()[0])
if (options.jiraonly):
print(rootJBIDE.key)
else:
print("JBoss Tools : " + jiraserver + '/browse/' + rootJBIDE.key + " => " + componentLead + "")
for name, comps in componentList.items():
for firstcomponent in comps:
break
cms = map(nametuple, comps)
componentLead = queryComponentLead(CLJBIDE, firstcomponent, 0)
#print(name + "->" + str(cms) + " => " + componentLead)
comptasksearch = jiraserver + '/issues/?jql=' + urllib.parse.quote_plus(tasksearchquery + " and component in (" + ",".join(map(quote,comps)) + ")")
singleJIRA_dict = {
'project' : { 'key': projectname },
'summary' : 'For ' + projectname + ' ' + fixversion + ': ' + taskdescription + ' [' + name.strip() + ']',
'description' : 'For ' + projectname + ' ' + fixversion + ' [' + name.strip() + ']: ' + taskdescriptionfull +
'\n\n[Search for all task JIRA|' + tasksearch + '], or [Search for ' + name.strip() + ' task JIRA|' + comptasksearch + ']',
'issuetype' : { 'name' : issuetype },
'priority' : { 'name': 'Blocker'},
'components' : list(cms),
'labels' : [ "task" ]
}
# if subtask, set parent
if issuetype == 'Sub-task' and rootJBIDE and rootJBIDE.key:
singleJIRA_dict['parent'] = { 'id' : rootJBIDE.key }
else:
# if task, set fixversion
singleJIRA_dict['fixVersions'] =[{ "name" : fixversion }]
singleJIRA = jira.create_issue(fields=singleJIRA_dict)
try:
jira.assign_issue(singleJIRA, componentLead)
except:
if (not options.jiraonly):
print ("[WARNING] Unexpected error! User {0} tried to assign {1} to {2}: {3}").format(options.jirauser, singleJIRA, componentLead, sys.exc_info()[0])
if (options.jiraonly):
print(singleJIRA.key)
else:
print(name + ": " + jiraserver + '/browse/' + singleJIRA.key + " => " + componentLead)
if (not options.autoaccept and not options.jiraonly):
accept = input("Accept created JIRAs? [Y/n] ")
if accept.capitalize() in ["N"]:
try:
rootJBIDE
except NameError:
singleJIRA.delete()
else:
rootJBIDE.delete(deleteSubtasks=True)
try:
rootJBDS
except NameError:
True
else:
rootJBDS.delete(deleteSubtasks=True)
# For sample usage, see createTaskJIRAs.py.examples.txt