fedora-csb-system-manager
1#!/usr/bin/env bash
2# Generate sprint summary for standup, planning, or retrospective
3
4set -euo pipefail
5
6usage() {
7 cat <<EOF
8Usage: jira-sprint-summary [options]
9
10Generate sprint summaries and reports.
11
12Options:
13 --current Current sprint summary (default)
14 --prev Previous sprint summary
15 --next Next sprint summary
16 --standup Daily standup format
17 --retro Retrospective format
18 --planning Planning format
19 --format FORMAT Output format: text, org, md (default: text)
20 --output FILE Output to file (default: stdout)
21 -h, --help Show this help
22
23Examples:
24 # Current sprint summary
25 jira-sprint-summary --current
26
27 # Daily standup notes
28 jira-sprint-summary --standup
29
30 # Retrospective data
31 jira-sprint-summary --prev --retro --format org
32EOF
33 exit 1
34}
35
36# Default options
37SPRINT_TYPE="current"
38REPORT_TYPE="summary"
39FORMAT="text"
40OUTPUT=""
41
42# Parse options
43while [[ $# -gt 0 ]]; do
44 case "$1" in
45 --current) SPRINT_TYPE="current"; shift ;;
46 --prev) SPRINT_TYPE="prev"; shift ;;
47 --next) SPRINT_TYPE="next"; shift ;;
48 --standup) REPORT_TYPE="standup"; shift ;;
49 --retro) REPORT_TYPE="retro"; shift ;;
50 --planning) REPORT_TYPE="planning"; shift ;;
51 --format) FORMAT="$2"; shift 2 ;;
52 --output) OUTPUT="$2"; shift 2 ;;
53 -h|--help) usage ;;
54 *) echo "Unknown option: $1"; usage ;;
55 esac
56done
57
58# Get sprint list based on type
59case "$SPRINT_TYPE" in
60 current) SPRINT_FLAG="--current" ;;
61 prev) SPRINT_FLAG="--prev" ;;
62 next) SPRINT_FLAG="--next" ;;
63esac
64
65# Get sprint info
66SPRINT_INFO=$(jira sprint list "$SPRINT_FLAG" 2>/dev/null) || {
67 echo "Error: Could not fetch sprint"
68 exit 1
69}
70
71SPRINT_NAME=$(echo "$SPRINT_INFO" | head -1)
72
73# Get sprint ID for queries (try to extract from first field)
74SPRINT_ID=$(jira sprint list "$SPRINT_FLAG" --plain 2>/dev/null | head -1 | awk '{print $1}' || echo "")
75
76# Generate JQL for sprint
77if [[ "$SPRINT_TYPE" == "current" ]]; then
78 SPRINT_JQL="sprint in openSprints()"
79elif [[ -n "$SPRINT_ID" ]]; then
80 SPRINT_JQL="sprint = $SPRINT_ID"
81else
82 echo "Warning: Could not determine sprint ID, using openSprints()" >&2
83 SPRINT_JQL="sprint in openSprints()"
84fi
85
86# Fetch sprint issues
87ISSUES=$(jira issue list --jql "$SPRINT_JQL" --plain 2>/dev/null || echo "")
88TOTAL_COUNT=$(echo "$ISSUES" | grep -c "^" || echo "0")
89
90# Count by status
91DONE_COUNT=$(jira issue list --jql "$SPRINT_JQL AND status = Done" --plain 2>/dev/null | grep -c "^" || echo "0")
92IN_PROGRESS_COUNT=$(jira issue list --jql "$SPRINT_JQL AND status = 'In Progress'" --plain 2>/dev/null | grep -c "^" || echo "0")
93CODE_REVIEW_COUNT=$(jira issue list --jql "$SPRINT_JQL AND status = 'Code Review'" --plain 2>/dev/null | grep -c "^" || echo "0")
94QE_REVIEW_COUNT=$(jira issue list --jql "$SPRINT_JQL AND status = 'QE Review'" --plain 2>/dev/null | grep -c "^" || echo "0")
95TODO_COUNT=$(jira issue list --jql "$SPRINT_JQL AND status = 'To Do'" --plain 2>/dev/null | grep -c "^" || echo "0")
96BLOCKED_COUNT=$(jira issue list --jql "$SPRINT_JQL AND status = Blocked" --plain 2>/dev/null | grep -c "^" || echo "0")
97
98# Calculate completion rate
99if [[ $TOTAL_COUNT -gt 0 ]]; then
100 COMPLETION_RATE=$((DONE_COUNT * 100 / TOTAL_COUNT))
101else
102 COMPLETION_RATE=0
103fi
104
105# Count by type
106BUG_COUNT=$(jira issue list --jql "$SPRINT_JQL AND type = Bug" --plain 2>/dev/null | grep -c "^" || echo "0")
107TASK_COUNT=$(jira issue list --jql "$SPRINT_JQL AND type = Task" --plain 2>/dev/null | grep -c "^" || echo "0")
108STORY_COUNT=$(jira issue list --jql "$SPRINT_JQL AND type = Story" --plain 2>/dev/null | grep -c "^" || echo "0")
109
110# Generate output based on report type and format
111generate_output() {
112 case "$REPORT_TYPE" in
113 standup)
114 case "$FORMAT" in
115 org)
116 cat <<EOF
117* Daily Standup - $(date +'%Y-%m-%d')
118** Sprint: $SPRINT_NAME
119
120** Yesterday
121$(jira issue list --jql "$SPRINT_JQL AND assignee = currentUser() AND updated >= -1d" --plain 2>/dev/null | head -5 | sed 's/^/- /')
122
123** Today
124$(jira issue list --jql "$SPRINT_JQL AND assignee = currentUser() AND status IN ('In Progress', 'Code Review')" --plain 2>/dev/null | sed 's/^/- /')
125
126** Blockers
127$(jira issue list --jql "$SPRINT_JQL AND assignee = currentUser() AND status = Blocked" --plain 2>/dev/null | sed 's/^/- /' || echo "- None")
128
129** Sprint Progress
130- Total: $TOTAL_COUNT issues
131- Done: $DONE_COUNT ($COMPLETION_RATE%)
132- In Progress: $IN_PROGRESS_COUNT
133- To Do: $TODO_COUNT
134- Blocked: $BLOCKED_COUNT
135EOF
136 ;;
137 md)
138 cat <<EOF
139# Daily Standup - $(date +'%Y-%m-%d')
140
141## Sprint: $SPRINT_NAME
142
143### Yesterday
144$(jira issue list --jql "$SPRINT_JQL AND assignee = currentUser() AND updated >= -1d" --plain 2>/dev/null | head -5 | sed 's/^/- /')
145
146### Today
147$(jira issue list --jql "$SPRINT_JQL AND assignee = currentUser() AND status IN ('In Progress', 'Code Review')" --plain 2>/dev/null | sed 's/^/- /')
148
149### Blockers
150$(jira issue list --jql "$SPRINT_JQL AND assignee = currentUser() AND status = Blocked" --plain 2>/dev/null | sed 's/^/- /' || echo "- None")
151
152### Sprint Progress
153- Total: $TOTAL_COUNT issues
154- Done: $DONE_COUNT ($COMPLETION_RATE%)
155- In Progress: $IN_PROGRESS_COUNT
156- To Do: $TODO_COUNT
157- Blocked: $BLOCKED_COUNT
158EOF
159 ;;
160 *)
161 cat <<EOF
162=== Daily Standup - $(date +'%Y-%m-%d') ===
163Sprint: $SPRINT_NAME
164
165Yesterday:
166$(jira issue list --jql "$SPRINT_JQL AND assignee = currentUser() AND updated >= -1d" --plain 2>/dev/null | head -5)
167
168Today:
169$(jira issue list --jql "$SPRINT_JQL AND assignee = currentUser() AND status IN ('In Progress', 'Code Review')" --plain 2>/dev/null)
170
171Blockers:
172$(jira issue list --jql "$SPRINT_JQL AND assignee = currentUser() AND status = Blocked" --plain 2>/dev/null || echo "None")
173
174Sprint Progress:
175 Total: $TOTAL_COUNT issues
176 Done: $DONE_COUNT ($COMPLETION_RATE%)
177 In Progress: $IN_PROGRESS_COUNT
178 To Do: $TODO_COUNT
179 Blocked: $BLOCKED_COUNT
180EOF
181 ;;
182 esac
183 ;;
184
185 retro)
186 case "$FORMAT" in
187 org)
188 cat <<EOF
189* Sprint Retrospective - $SPRINT_NAME
190
191** Metrics
192- Total Issues: $TOTAL_COUNT
193- Completed: $DONE_COUNT
194- Incomplete: $((TOTAL_COUNT - DONE_COUNT))
195- Completion Rate: $COMPLETION_RATE%
196
197** Issue Breakdown
198- Bugs: $BUG_COUNT
199- Tasks: $TASK_COUNT
200- Stories: $STORY_COUNT
201
202** Status Distribution
203- Done: $DONE_COUNT
204- In Progress: $IN_PROGRESS_COUNT
205- Code Review: $CODE_REVIEW_COUNT
206- QE Review: $QE_REVIEW_COUNT
207- To Do: $TODO_COUNT
208- Blocked: $BLOCKED_COUNT
209
210** Completed Issues
211$(jira issue list --jql "$SPRINT_JQL AND status = Done" --columns KEY,SUMMARY --plain 2>/dev/null | sed 's/^/- /')
212
213** Incomplete Issues
214$(jira issue list --jql "$SPRINT_JQL AND status != Done" --columns KEY,SUMMARY --plain 2>/dev/null | sed 's/^/- /')
215
216** What Went Well
217
218
219** What Could Be Improved
220
221
222** Action Items
223- [ ]
224
225EOF
226 ;;
227 *)
228 cat <<EOF
229=== Sprint Retrospective - $SPRINT_NAME ===
230
231Metrics:
232 Total Issues: $TOTAL_COUNT
233 Completed: $DONE_COUNT
234 Incomplete: $((TOTAL_COUNT - DONE_COUNT))
235 Completion Rate: $COMPLETION_RATE%
236
237Issue Breakdown:
238 Bugs: $BUG_COUNT
239 Tasks: $TASK_COUNT
240 Stories: $STORY_COUNT
241
242Status Distribution:
243 Done: $DONE_COUNT
244 In Progress: $IN_PROGRESS_COUNT
245 Code Review: $CODE_REVIEW_COUNT
246 QE Review: $QE_REVIEW_COUNT
247 To Do: $TODO_COUNT
248 Blocked: $BLOCKED_COUNT
249
250Completed Issues:
251$(jira issue list --jql "$SPRINT_JQL AND status = Done" --columns KEY,SUMMARY --plain 2>/dev/null)
252
253Incomplete Issues:
254$(jira issue list --jql "$SPRINT_JQL AND status != Done" --columns KEY,SUMMARY --plain 2>/dev/null)
255EOF
256 ;;
257 esac
258 ;;
259
260 planning)
261 cat <<EOF
262=== Sprint Planning - $SPRINT_NAME ===
263
264Current Sprint Summary:
265 Total: $TOTAL_COUNT issues
266 Done: $DONE_COUNT
267 Remaining: $((TOTAL_COUNT - DONE_COUNT))
268
269High Priority Backlog Items:
270$(jira issue list --jql "priority IN (Critical, High) AND status = 'To Do' AND sprint is EMPTY ORDER BY priority DESC" --limit 10 --plain 2>/dev/null)
271
272Unassigned Bugs:
273$(jira issue list --jql "type = Bug AND assignee is EMPTY AND status = 'To Do' ORDER BY priority DESC" --limit 5 --plain 2>/dev/null)
274EOF
275 ;;
276
277 *)
278 # Default summary
279 cat <<EOF
280=== Sprint Summary - $SPRINT_NAME ===
281
282Total Issues: $TOTAL_COUNT
283Completion: $DONE_COUNT/$TOTAL_COUNT ($COMPLETION_RATE%)
284
285Status Breakdown:
286 Done: $DONE_COUNT
287 In Progress: $IN_PROGRESS_COUNT
288 Code Review: $CODE_REVIEW_COUNT
289 QE Review: $QE_REVIEW_COUNT
290 To Do: $TODO_COUNT
291 Blocked: $BLOCKED_COUNT
292
293Type Breakdown:
294 Bugs: $BUG_COUNT
295 Tasks: $TASK_COUNT
296 Stories: $STORY_COUNT
297EOF
298 ;;
299 esac
300}
301
302# Output to file or stdout
303if [[ -n "$OUTPUT" ]]; then
304 generate_output > "$OUTPUT"
305 echo "Summary written to: $OUTPUT"
306else
307 generate_output
308fi