0
# Agile & Boards
1
2
Agile/Scrum functionality including board management, sprint operations, and backlog management using the GreenHopper API. This enables automation of agile workflows and sprint planning.
3
4
## Capabilities
5
6
### Board Management
7
8
Operations for managing agile boards including creation, retrieval, and deletion.
9
10
```python { .api }
11
def boards(
12
self,
13
startAt: int = 0,
14
maxResults: int = 50,
15
type: str = None,
16
name: str = None
17
) -> list[Board]:
18
"""
19
Get agile boards.
20
21
Parameters:
22
- startAt: Starting index for pagination
23
- maxResults: Maximum number of results
24
- type: Board type ('scrum', 'kanban', 'simple')
25
- name: Board name filter
26
27
Returns:
28
List of Board objects
29
"""
30
31
def create_board(
32
self,
33
name: str,
34
project_ids: list[str],
35
preset: str = "scrum",
36
location_type: str = 'user',
37
location_id: str = None
38
) -> Board:
39
"""
40
Create a new agile board.
41
42
Parameters:
43
- name: Board name
44
- project_ids: List of project IDs or keys
45
- preset: Board preset ('scrum', 'kanban', 'simple')
46
- location_type: Location type ('user', 'project')
47
- location_id: Location ID (user ID or project ID)
48
49
Returns:
50
Created Board object
51
"""
52
53
def delete_board(self, id: str) -> None:
54
"""
55
Delete an agile board.
56
57
Parameters:
58
- id: Board ID
59
"""
60
```
61
62
Usage examples:
63
```python
64
# Get all boards
65
boards = jira.boards()
66
for board in boards:
67
print(f"Board: {board.name} (Type: {board.type})")
68
69
# Get boards by type
70
scrum_boards = jira.boards(type='scrum')
71
kanban_boards = jira.boards(type='kanban')
72
73
# Search boards by name
74
dev_boards = jira.boards(name='Development')
75
76
# Create new scrum board
77
new_board = jira.create_board(
78
name='New Development Board',
79
project_ids=['PROJ'],
80
preset='scrum'
81
)
82
print(f"Created board: {new_board.name} (ID: {new_board.id})")
83
84
# Create kanban board
85
kanban_board = jira.create_board(
86
name='Support Kanban',
87
project_ids=['SUPPORT'],
88
preset='kanban'
89
)
90
91
# Delete board
92
jira.delete_board(new_board.id)
93
```
94
95
### Sprint Management
96
97
Operations for managing sprints including creation, updates, and sprint information.
98
99
```python { .api }
100
def sprints(
101
self,
102
board_id: int,
103
extended: bool = False,
104
startAt: int = 0,
105
maxResults: int = 50,
106
state: str = None
107
) -> list[Sprint]:
108
"""
109
Get sprints for a board.
110
111
Parameters:
112
- board_id: Board ID
113
- extended: Include extended sprint information
114
- startAt: Starting index for pagination
115
- maxResults: Maximum number of results
116
- state: Sprint state ('active', 'closed', 'future')
117
118
Returns:
119
List of Sprint objects
120
"""
121
122
def sprints_by_name(self, id: int, extended: bool = False) -> dict:
123
"""Get sprints organized by name."""
124
125
def sprint(self, id: int) -> Sprint:
126
"""
127
Get sprint by ID.
128
129
Parameters:
130
- id: Sprint ID
131
132
Returns:
133
Sprint object
134
"""
135
136
def create_sprint(
137
self,
138
name: str,
139
board_id: int,
140
startDate: str = None,
141
endDate: str = None
142
) -> Sprint:
143
"""
144
Create a new sprint.
145
146
Parameters:
147
- name: Sprint name
148
- board_id: Board ID where sprint will be created
149
- startDate: Sprint start date (ISO format: YYYY-MM-DDTHH:MM:SS.sssZ)
150
- endDate: Sprint end date (ISO format: YYYY-MM-DDTHH:MM:SS.sssZ)
151
152
Returns:
153
Created Sprint object
154
"""
155
156
def update_sprint(
157
self,
158
id: int,
159
name: str = None,
160
startDate: str = None,
161
endDate: str = None,
162
state: str = None
163
) -> Sprint:
164
"""
165
Update a sprint.
166
167
Parameters:
168
- id: Sprint ID
169
- name: New sprint name
170
- startDate: New start date
171
- endDate: New end date
172
- state: New state ('active', 'closed', 'future')
173
174
Returns:
175
Updated Sprint object
176
"""
177
```
178
179
Usage examples:
180
```python
181
# Get all sprints for a board
182
board_id = 123
183
sprints = jira.sprints(board_id)
184
for sprint in sprints:
185
print(f"Sprint: {sprint.name} (State: {sprint.state})")
186
187
# Get active sprints only
188
active_sprints = jira.sprints(board_id, state='active')
189
190
# Get sprint with extended information
191
extended_sprints = jira.sprints(board_id, extended=True)
192
for sprint in extended_sprints:
193
if hasattr(sprint, 'completeDate'):
194
print(f"Completed: {sprint.completeDate}")
195
196
# Create new sprint
197
from datetime import datetime, timedelta
198
199
start_date = datetime.now()
200
end_date = start_date + timedelta(weeks=2)
201
202
new_sprint = jira.create_sprint(
203
name='Sprint 15',
204
board_id=board_id,
205
startDate=start_date.isoformat() + 'Z',
206
endDate=end_date.isoformat() + 'Z'
207
)
208
print(f"Created sprint: {new_sprint.name}")
209
210
# Update sprint
211
updated_sprint = jira.update_sprint(
212
id=new_sprint.id,
213
name='Sprint 15 - Feature Development',
214
state='active'
215
)
216
217
# Get specific sprint
218
sprint = jira.sprint(new_sprint.id)
219
print(f"Sprint: {sprint.name}, Goal: {getattr(sprint, 'goal', 'No goal set')}")
220
```
221
222
### Sprint Operations
223
224
Operations for managing issues within sprints and sprint lifecycle.
225
226
```python { .api }
227
def add_issues_to_sprint(self, sprint_id: int, issue_keys: list[str]) -> None:
228
"""
229
Add issues to a sprint.
230
231
Parameters:
232
- sprint_id: Sprint ID
233
- issue_keys: List of issue keys to add
234
"""
235
236
def sprint_info(self, board_id: int, sprint_id: int) -> dict:
237
"""
238
Get detailed sprint information.
239
240
Parameters:
241
- board_id: Board ID
242
- sprint_id: Sprint ID
243
244
Returns:
245
Sprint information dictionary
246
"""
247
248
def incompletedIssuesEstimateSum(self, board_id: int, sprint_id: int) -> dict:
249
"""Get sum of estimates for incomplete issues in sprint."""
250
251
def removed_issues(self, board_id: int, sprint_id: int) -> dict:
252
"""Get issues removed from sprint."""
253
254
def removedIssuesEstimateSum(self, board_id: int, sprint_id: int) -> dict:
255
"""Get sum of estimates for issues removed from sprint."""
256
```
257
258
Usage examples:
259
```python
260
# Add issues to sprint
261
issue_keys = ['PROJ-123', 'PROJ-124', 'PROJ-125']
262
jira.add_issues_to_sprint(sprint_id=456, issue_keys=issue_keys)
263
print(f"Added {len(issue_keys)} issues to sprint")
264
265
# Get detailed sprint information
266
sprint_info = jira.sprint_info(board_id=123, sprint_id=456)
267
print(f"Sprint capacity: {sprint_info.get('capacity', 'Not set')}")
268
269
# Get incomplete issues estimate
270
incomplete_estimate = jira.incompletedIssuesEstimateSum(123, 456)
271
print(f"Remaining work: {incomplete_estimate}")
272
273
# Get removed issues from sprint
274
removed = jira.removed_issues(123, 456)
275
print(f"Removed issues: {len(removed)}")
276
277
# Get estimate of removed issues
278
removed_estimate = jira.removedIssuesEstimateSum(123, 456)
279
print(f"Removed work estimate: {removed_estimate}")
280
```
281
282
### Epic Management
283
284
Operations for managing epics and adding issues to epics.
285
286
```python { .api }
287
def add_issues_to_epic(
288
self,
289
epic_id: str,
290
issue_keys: list[str],
291
ignore_epics: bool = True
292
) -> None:
293
"""
294
Add issues to an epic.
295
296
Parameters:
297
- epic_id: Epic issue key or ID
298
- issue_keys: List of issue keys to add to epic
299
- ignore_epics: Whether to ignore if issue is already an epic
300
"""
301
```
302
303
Usage examples:
304
```python
305
# Add issues to epic
306
epic_key = 'PROJ-100' # Epic issue key
307
story_keys = ['PROJ-101', 'PROJ-102', 'PROJ-103']
308
309
jira.add_issues_to_epic(
310
epic_id=epic_key,
311
issue_keys=story_keys
312
)
313
print(f"Added {len(story_keys)} stories to epic {epic_key}")
314
315
# Create epic and add stories
316
epic = jira.create_issue(
317
project={'key': 'PROJ'},
318
summary='User Authentication Epic',
319
issuetype={'name': 'Epic'},
320
customfield_10011='AUTH' # Epic Name field
321
)
322
323
# Create stories for the epic
324
stories = []
325
for i in range(3):
326
story = jira.create_issue(
327
project={'key': 'PROJ'},
328
summary=f'Authentication Story {i+1}',
329
issuetype={'name': 'Story'}
330
)
331
stories.append(story.key)
332
333
# Add stories to epic
334
jira.add_issues_to_epic(epic.key, stories)
335
```
336
337
### Backlog Management
338
339
Operations for managing the product backlog and issue ranking.
340
341
```python { .api }
342
def rank(self, issue: str, next_issue: str) -> None:
343
"""
344
Rank an issue before another issue.
345
346
Parameters:
347
- issue: Issue key to rank
348
- next_issue: Issue key to rank before
349
"""
350
351
def move_to_backlog(self, issue_keys: list[str]) -> None:
352
"""
353
Move issues to backlog (remove from active sprints).
354
355
Parameters:
356
- issue_keys: List of issue keys to move to backlog
357
"""
358
```
359
360
Usage examples:
361
```python
362
# Rank issue higher in backlog
363
jira.rank('PROJ-123', 'PROJ-124') # Move PROJ-123 before PROJ-124
364
print("Ranked PROJ-123 higher in backlog")
365
366
# Move issues back to backlog
367
sprint_issues = ['PROJ-125', 'PROJ-126']
368
jira.move_to_backlog(sprint_issues)
369
print(f"Moved {len(sprint_issues)} issues back to backlog")
370
371
# Reorder backlog based on priority
372
high_priority_issues = jira.search_issues(
373
'project = PROJ AND priority = High ORDER BY created ASC'
374
)
375
376
# Rank high priority issues at top
377
for i, issue in enumerate(high_priority_issues[:-1]):
378
next_issue = high_priority_issues[i + 1]
379
jira.rank(issue.key, next_issue.key)
380
```
381
382
## Sprint States
383
384
Sprints can be in different states:
385
386
- **future**: Sprint is created but not started
387
- **active**: Sprint is currently in progress
388
- **closed**: Sprint has been completed
389
390
```python
391
# Filter sprints by state
392
future_sprints = jira.sprints(board_id, state='future')
393
active_sprints = jira.sprints(board_id, state='active')
394
closed_sprints = jira.sprints(board_id, state='closed')
395
396
# Start a sprint (change from future to active)
397
jira.update_sprint(
398
id=future_sprint.id,
399
state='active',
400
startDate=datetime.now().isoformat() + 'Z'
401
)
402
403
# Complete a sprint (change from active to closed)
404
jira.update_sprint(
405
id=active_sprint.id,
406
state='closed',
407
endDate=datetime.now().isoformat() + 'Z'
408
)
409
```
410
411
## Board Types
412
413
Different board types support different workflows:
414
415
### Scrum Boards
416
- Support sprints and sprint planning
417
- Include backlog management
418
- Support velocity tracking
419
420
### Kanban Boards
421
- Continuous flow without sprints
422
- Support WIP limits
423
- Focus on cycle time
424
425
### Simple Boards
426
- Basic board functionality
427
- Limited agile features
428
429
```python
430
# Create different board types
431
scrum_board = jira.create_board(
432
name='Development Scrum',
433
project_ids=['DEV'],
434
preset='scrum'
435
)
436
437
kanban_board = jira.create_board(
438
name='Support Kanban',
439
project_ids=['SUPPORT'],
440
preset='kanban'
441
)
442
443
simple_board = jira.create_board(
444
name='Simple Task Board',
445
project_ids=['TASKS'],
446
preset='simple'
447
)
448
```
449
450
## Sprint Planning Automation
451
452
Automate common sprint planning tasks:
453
454
```python
455
def plan_next_sprint(board_id, sprint_name, duration_weeks=2):
456
"""Automate sprint planning process."""
457
458
# Create new sprint
459
start_date = datetime.now()
460
end_date = start_date + timedelta(weeks=duration_weeks)
461
462
sprint = jira.create_sprint(
463
name=sprint_name,
464
board_id=board_id,
465
startDate=start_date.isoformat() + 'Z',
466
endDate=end_date.isoformat() + 'Z'
467
)
468
469
# Get high priority backlog items
470
backlog_items = jira.search_issues(
471
f'project = PROJ AND sprint is EMPTY AND priority in (Highest, High) '
472
f'ORDER BY priority DESC, created ASC',
473
maxResults=20
474
)
475
476
# Add top items to sprint
477
issue_keys = [issue.key for issue in backlog_items[:10]]
478
if issue_keys:
479
jira.add_issues_to_sprint(sprint.id, issue_keys)
480
481
print(f"Created sprint '{sprint_name}' with {len(issue_keys)} issues")
482
return sprint
483
484
# Plan next sprint
485
next_sprint = plan_next_sprint(123, 'Sprint 16', duration_weeks=2)
486
```