0
# Issue Management
1
2
Comprehensive issue operations including creation, search, update, transitions, and bulk operations using JQL (JIRA Query Language). This is the core functionality for working with JIRA issues.
3
4
## Capabilities
5
6
### Issue Search & Retrieval
7
8
Search for issues using JIRA Query Language (JQL) and retrieve individual issues by ID or key.
9
10
```python { .api }
11
def search_issues(
12
self,
13
jql_str: str,
14
startAt: int = 0,
15
maxResults: int = 50,
16
validate_query: bool = True,
17
fields: str = None,
18
expand: str = None,
19
json_result: bool = None
20
) -> list[Issue]:
21
"""
22
Search for issues using JQL.
23
24
Parameters:
25
- jql_str: JQL query string
26
- startAt: Starting index for pagination
27
- maxResults: Maximum number of results to return
28
- validate_query: Whether to validate JQL syntax
29
- fields: Comma-separated list of fields to include
30
- expand: Comma-separated list of properties to expand
31
- json_result: Return raw JSON instead of Issue objects
32
33
Returns:
34
List of Issue objects matching the query
35
"""
36
37
def issue(self, id: str, fields: str = None, expand: str = None) -> Issue:
38
"""
39
Get a single issue by ID or key.
40
41
Parameters:
42
- id: Issue ID or key (e.g., 'PROJ-123')
43
- fields: Comma-separated list of fields to include
44
- expand: Comma-separated list of properties to expand
45
46
Returns:
47
Issue object
48
"""
49
```
50
51
Usage examples:
52
```python
53
# Search for issues in a project
54
issues = jira.search_issues('project = MYPROJ AND status = "To Do"')
55
for issue in issues:
56
print(f"{issue.key}: {issue.fields.summary}")
57
58
# Search with specific fields
59
issues = jira.search_issues(
60
'assignee = currentUser()',
61
fields='summary,status,assignee',
62
maxResults=20
63
)
64
65
# Get a specific issue
66
issue = jira.issue('PROJ-123')
67
print(f"Summary: {issue.fields.summary}")
68
print(f"Status: {issue.fields.status.name}")
69
print(f"Assignee: {issue.fields.assignee.displayName}")
70
71
# Get issue with expanded properties
72
issue = jira.issue('PROJ-123', expand='changelog,transitions')
73
```
74
75
### Issue Creation
76
77
Create new issues with various field configurations and bulk creation capabilities.
78
79
```python { .api }
80
def create_issue(self, fields: dict = None, prefetch: bool = True, **fieldargs) -> Issue:
81
"""
82
Create a new issue.
83
84
Parameters:
85
- fields: Dictionary of field values
86
- prefetch: Whether to fetch the created issue details
87
- **fieldargs: Field values as keyword arguments
88
89
Returns:
90
Created Issue object
91
"""
92
93
def create_issues(self, field_list: list[dict], prefetch: bool = True) -> list[Issue]:
94
"""
95
Bulk create multiple issues.
96
97
Parameters:
98
- field_list: List of field dictionaries for each issue
99
- prefetch: Whether to fetch created issue details
100
101
Returns:
102
List of created Issue objects
103
"""
104
105
def createmeta(
106
self,
107
projectKeys: list[str] = None,
108
projectIds: list[str] = [],
109
issuetypeIds: list[str] = None,
110
issuetypeNames: list[str] = None,
111
expand: str = None
112
) -> dict:
113
"""
114
Get metadata for creating issues.
115
116
Parameters:
117
- projectKeys: List of project keys to get metadata for
118
- projectIds: List of project IDs to get metadata for
119
- issuetypeIds: List of issue type IDs to include
120
- issuetypeNames: List of issue type names to include
121
- expand: Properties to expand
122
123
Returns:
124
Create metadata dictionary
125
"""
126
```
127
128
Usage examples:
129
```python
130
# Create a simple issue
131
new_issue = jira.create_issue(
132
project={'key': 'PROJ'},
133
summary='New bug report',
134
description='Description of the bug',
135
issuetype={'name': 'Bug'},
136
priority={'name': 'High'}
137
)
138
print(f"Created issue: {new_issue.key}")
139
140
# Create issue with custom fields
141
new_issue = jira.create_issue(
142
project={'key': 'PROJ'},
143
summary='Feature request',
144
issuetype={'name': 'Story'},
145
assignee={'name': 'john.doe'},
146
labels=['frontend', 'ui'],
147
customfield_10001='Custom value'
148
)
149
150
# Bulk create issues
151
issues_data = [
152
{
153
'project': {'key': 'PROJ'},
154
'summary': 'First issue',
155
'issuetype': {'name': 'Task'}
156
},
157
{
158
'project': {'key': 'PROJ'},
159
'summary': 'Second issue',
160
'issuetype': {'name': 'Task'}
161
}
162
]
163
created_issues = jira.create_issues(issues_data)
164
165
# Get create metadata before creating
166
meta = jira.createmeta(projectKeys=['PROJ'])
167
available_fields = meta['projects'][0]['issuetypes'][0]['fields']
168
```
169
170
### Issue Assignment & Updates
171
172
Assign issues to users and get metadata for editing issues.
173
174
```python { .api }
175
def assign_issue(self, issue: Issue, assignee: str) -> None:
176
"""
177
Assign an issue to a user.
178
179
Parameters:
180
- issue: Issue object or issue key
181
- assignee: Username to assign to, or None to unassign
182
"""
183
184
def editmeta(self, issue: Issue) -> dict:
185
"""
186
Get metadata for editing an issue.
187
188
Parameters:
189
- issue: Issue object or issue key
190
191
Returns:
192
Edit metadata dictionary
193
"""
194
```
195
196
Usage examples:
197
```python
198
# Assign issue to user
199
jira.assign_issue('PROJ-123', 'john.doe')
200
201
# Unassign issue
202
jira.assign_issue('PROJ-123', None)
203
204
# Get edit metadata
205
issue = jira.issue('PROJ-123')
206
edit_meta = jira.editmeta(issue)
207
editable_fields = edit_meta['fields'].keys()
208
```
209
210
### Issue Transitions
211
212
Manage issue workflows and transitions between different statuses.
213
214
```python { .api }
215
def transitions(self, issue: Issue, id: str = None, expand: str = None) -> list[dict]:
216
"""
217
Get available transitions for an issue.
218
219
Parameters:
220
- issue: Issue object or issue key
221
- id: Specific transition ID to get
222
- expand: Properties to expand
223
224
Returns:
225
List of available transition dictionaries
226
"""
227
228
def find_transitionid_by_name(self, issue: Issue, transition_name: str) -> str:
229
"""
230
Find transition ID by name.
231
232
Parameters:
233
- issue: Issue object or issue key
234
- transition_name: Name of the transition
235
236
Returns:
237
Transition ID string
238
"""
239
240
def transition_issue(
241
self,
242
issue: Issue,
243
transition: str,
244
fields: dict = None,
245
comment: str = None,
246
worklog: dict = None,
247
**fieldargs
248
) -> None:
249
"""
250
Transition an issue to a new status.
251
252
Parameters:
253
- issue: Issue object or issue key
254
- transition: Transition ID or name
255
- fields: Dictionary of field updates
256
- comment: Comment to add during transition
257
- worklog: Worklog to add during transition
258
- **fieldargs: Field updates as keyword arguments
259
"""
260
```
261
262
Usage examples:
263
```python
264
# Get available transitions
265
issue = jira.issue('PROJ-123')
266
transitions = jira.transitions(issue)
267
for transition in transitions:
268
print(f"ID: {transition['id']}, Name: {transition['name']}")
269
270
# Transition by name
271
jira.transition_issue(issue, 'In Progress')
272
273
# Transition with comment and field updates
274
jira.transition_issue(
275
issue,
276
'Resolve Issue',
277
fields={'resolution': {'name': 'Fixed'}},
278
comment='Issue has been resolved'
279
)
280
281
# Find transition ID by name
282
transition_id = jira.find_transitionid_by_name(issue, 'Close Issue')
283
jira.transition_issue(issue, transition_id)
284
```
285
286
### Issue Links
287
288
Create and manage links between issues.
289
290
```python { .api }
291
def create_issue_link(
292
self,
293
type: str,
294
inwardIssue: str,
295
outwardIssue: str,
296
comment: dict = None
297
) -> None:
298
"""
299
Create a link between two issues.
300
301
Parameters:
302
- type: Link type name (e.g., 'Blocks', 'Relates')
303
- inwardIssue: Key of the inward issue
304
- outwardIssue: Key of the outward issue
305
- comment: Optional comment dictionary
306
"""
307
308
def delete_issue_link(self, id: str) -> None:
309
"""Delete an issue link by ID."""
310
311
def issue_link(self, id: str) -> dict:
312
"""Get issue link details by ID."""
313
314
def issue_link_types(self) -> list[dict]:
315
"""Get all available issue link types."""
316
317
def issue_link_type(self, id: str) -> dict:
318
"""Get specific issue link type by ID."""
319
```
320
321
Usage examples:
322
```python
323
# Create issue link
324
jira.create_issue_link(
325
type='Blocks',
326
inwardIssue='PROJ-123',
327
outwardIssue='PROJ-124'
328
)
329
330
# Get available link types
331
link_types = jira.issue_link_types()
332
for link_type in link_types:
333
print(f"{link_type['name']}: {link_type['inward']} / {link_type['outward']}")
334
335
# Delete issue link
336
jira.delete_issue_link('12345')
337
```
338
339
### Issue Types & Metadata
340
341
Retrieve issue types, priorities, resolutions, and other metadata.
342
343
```python { .api }
344
def issue_types(self) -> list[dict]:
345
"""Get all issue types."""
346
347
def issue_type(self, id: str) -> dict:
348
"""Get issue type by ID."""
349
350
def issue_type_by_name(self, name: str) -> dict:
351
"""Get issue type by name."""
352
353
def priorities(self) -> list[dict]:
354
"""Get all priorities."""
355
356
def priority(self, id: str) -> dict:
357
"""Get priority by ID."""
358
359
def resolutions(self) -> list[dict]:
360
"""Get all resolutions."""
361
362
def resolution(self, id: str) -> dict:
363
"""Get resolution by ID."""
364
365
def statuses(self) -> list[dict]:
366
"""Get all statuses."""
367
368
def status(self, id: str) -> dict:
369
"""Get status by ID."""
370
371
def fields(self) -> list[dict]:
372
"""Get all issue fields."""
373
```
374
375
Usage examples:
376
```python
377
# Get issue types
378
issue_types = jira.issue_types()
379
for issue_type in issue_types:
380
print(f"{issue_type['name']}: {issue_type['description']}")
381
382
# Get priorities
383
priorities = jira.priorities()
384
highest_priority = next(p for p in priorities if p['name'] == 'Highest')
385
386
# Get all fields
387
fields = jira.fields()
388
custom_fields = [f for f in fields if f['custom']]
389
390
# Find specific field
391
summary_field = next(f for f in fields if f['name'] == 'Summary')
392
```
393
394
### Votes & Watchers
395
396
Manage issue votes and watchers.
397
398
```python { .api }
399
def votes(self, issue: Issue) -> dict:
400
"""Get vote information for an issue."""
401
402
def add_vote(self, issue: Issue) -> None:
403
"""Vote for an issue."""
404
405
def remove_vote(self, issue: Issue) -> None:
406
"""Remove vote from an issue."""
407
408
def watchers(self, issue: Issue) -> dict:
409
"""Get watchers for an issue."""
410
411
def add_watcher(self, issue: Issue, watcher: str) -> None:
412
"""Add a watcher to an issue."""
413
414
def remove_watcher(self, issue: Issue, watcher: str) -> None:
415
"""Remove a watcher from an issue."""
416
```
417
418
Usage examples:
419
```python
420
# Get vote information
421
issue = jira.issue('PROJ-123')
422
votes = jira.votes(issue)
423
print(f"Votes: {votes['votes']}, Has voted: {votes['hasVoted']}")
424
425
# Vote for issue
426
jira.add_vote(issue)
427
428
# Get watchers
429
watchers = jira.watchers(issue)
430
print(f"Watching count: {watchers['watchCount']}")
431
432
# Add watcher
433
jira.add_watcher(issue, 'john.doe')
434
```
435
436
## JQL Examples
437
438
Common JQL (JIRA Query Language) patterns for searching issues:
439
440
```python
441
# Issues in specific project
442
jira.search_issues('project = PROJ')
443
444
# Issues assigned to current user
445
jira.search_issues('assignee = currentUser()')
446
447
# Open issues updated recently
448
jira.search_issues('status != Closed AND updated >= -7d')
449
450
# High priority bugs
451
jira.search_issues('priority = High AND type = Bug')
452
453
# Issues with specific labels
454
jira.search_issues('labels in (frontend, backend)')
455
456
# Issues in sprint
457
jira.search_issues('sprint = "Sprint 1"')
458
459
# Complex query with multiple conditions
460
jql = '''
461
project = PROJ AND
462
status in ("To Do", "In Progress") AND
463
assignee in (john.doe, jane.smith) AND
464
created >= -30d
465
ORDER BY priority DESC, created ASC
466
'''
467
issues = jira.search_issues(jql)
468
```