Initial commit

This commit is contained in:
Zhongwei Li
2025-11-30 08:40:02 +08:00
commit 0a8a6c982f
21 changed files with 4153 additions and 0 deletions

View File

@@ -0,0 +1,457 @@
# Jira CLI - Scripting and Automation
This file contains examples for automating Jira operations with scripts and integrating with CI/CD pipelines.
## Bash Scripting Examples
### Tickets Created Per Day This Month
```bash
#!/usr/bin/env bash
# Generate report of tickets created per day in current month
tickets=$(jira issue list --created month --plain --columns created --no-headers | \
awk '{print $2}' | awk -F'-' '{print $3}' | sort -n | uniq -c)
echo "${tickets}" | while IFS=$'\t' read -r line; do
day=$(echo "${line}" | awk '{print $2}')
count=$(echo "${line}" | awk '{print $1}')
printf "Day #%s: %s tickets\n" "${day}" "${count}"
done
```
### Number of Tickets Per Sprint
```bash
#!/usr/bin/env bash
# Count tickets in each sprint
sprints=$(jira sprint list --table --plain --columns id,name --no-headers)
echo "${sprints}" | while IFS=$'\t' read -r id name; do
count=$(jira sprint list "${id}" --plain --no-headers 2>/dev/null | wc -l)
printf "%10s: %3d tickets\n" "${name}" $((count))
done
```
### Number of Unique Assignees Per Sprint
```bash
#!/usr/bin/env bash
# Count unique assignees in each sprint
sprints=$(jira sprint list --table --plain --columns id,name --no-headers)
echo "${sprints}" | while IFS=$'\t' read -r id name; do
count=$(jira sprint list "${id}" --plain --columns assignee --no-headers 2>/dev/null | \
awk '{print $2}' | awk NF | sort -n | uniq | wc -l)
printf "%10s: %3d people\n" "${name}" $((count))
done
```
### Daily Standup Report
```bash
#!/usr/bin/env bash
# Generate daily standup report
echo "=== Daily Standup Report ==="
echo ""
echo "Yesterday's work (updated in last 24h):"
jira issue list -a$(jira me) --updated -1d --plain --columns key,summary
echo ""
echo "Currently working on:"
jira issue list -a$(jira me) -s"In Progress" --plain --columns key,summary
echo ""
echo "Closed this week:"
jira issue list -a$(jira me) -sDone --updated week --plain --columns key,summary
```
### Sprint Report Generator
```bash
#!/usr/bin/env bash
# Generate sprint summary report
SPRINT_ID=$1
if [ -z "$SPRINT_ID" ]; then
echo "Usage: $0 <sprint-id>"
exit 1
fi
echo "=== Sprint Report for Sprint $SPRINT_ID ==="
echo ""
total=$(jira sprint list "$SPRINT_ID" --plain --no-headers | wc -l)
done_count=$(jira sprint list "$SPRINT_ID" -sDone --plain --no-headers | wc -l)
in_progress=$(jira sprint list "$SPRINT_ID" -s"In Progress" --plain --no-headers | wc -l)
todo=$(jira sprint list "$SPRINT_ID" -s"To Do" --plain --no-headers | wc -l)
echo "Total tickets: $total"
echo "Done: $done_count"
echo "In Progress: $in_progress"
echo "To Do: $todo"
echo ""
completion_rate=$(echo "scale=2; ($done_count / $total) * 100" | bc)
echo "Completion rate: ${completion_rate}%"
```
### Bulk Issue Assignment
```bash
#!/usr/bin/env bash
# Assign unassigned high priority tickets to team members
# Get list of unassigned high priority tickets
issues=$(jira issue list -ax -yHigh -s"To Do" --plain --columns key --no-headers)
# Team members
team=("Alice" "Bob" "Charlie")
team_size=${#team[@]}
index=0
# Assign in round-robin fashion
for issue in $issues; do
assignee="${team[$index]}"
echo "Assigning $issue to $assignee"
jira issue assign "$issue" "$assignee"
index=$(( (index + 1) % team_size ))
done
```
### Auto-Label Based on Summary
```bash
#!/usr/bin/env bash
# Auto-label issues based on keywords in summary
# Get issues without labels
issues=$(jira issue list --plain --columns key,summary --no-headers)
echo "$issues" | while IFS=$'\t' read -r key summary; do
# Check for keywords and add labels
if echo "$summary" | grep -qi "bug\|error\|crash"; then
echo "Adding 'bug' label to $key"
jira issue edit "$key" --label bug
fi
if echo "$summary" | grep -qi "feature\|enhancement"; then
echo "Adding 'enhancement' label to $key"
jira issue edit "$key" --label enhancement
fi
if echo "$summary" | grep -qi "urgent\|critical\|blocker"; then
echo "Adding 'urgent' label to $key"
jira issue edit "$key" --label urgent
fi
done
```
### Export Issues to CSV
```bash
#!/usr/bin/env bash
# Export filtered issues to CSV file
OUTPUT_FILE="issues_$(date +%Y%m%d).csv"
# Export with custom columns
jira issue list \
--created month \
--csv \
--columns key,type,status,priority,assignee,summary,created \
> "$OUTPUT_FILE"
echo "Exported to $OUTPUT_FILE"
```
### Monitor High Priority Issues
```bash
#!/usr/bin/env bash
# Monitor and alert on high priority unassigned issues
THRESHOLD=5
count=$(jira issue list -ax -yHigh -s~Done --plain --no-headers | wc -l)
if [ "$count" -gt "$THRESHOLD" ]; then
echo "⚠️ Alert: $count high priority unassigned issues (threshold: $THRESHOLD)"
jira issue list -ax -yHigh -s~Done --plain --columns key,summary
# Could send to Slack, email, etc.
# slack-cli send "#team-alerts" "High priority issues need attention: $count tickets"
else
echo "✅ OK: $count high priority unassigned issues"
fi
```
## CI/CD Integration
### GitHub Actions - Create Jira Issue on PR
```yaml
name: Create Jira Issue
on:
pull_request:
types: [opened]
jobs:
create-jira:
runs-on: ubuntu-latest
steps:
- name: Install jira-cli
run: |
wget https://github.com/ankitpokhrel/jira-cli/releases/latest/download/jira_linux_amd64.tar.gz
tar -xf jira_linux_amd64.tar.gz
sudo mv jira /usr/local/bin/
- name: Create Jira Issue
env:
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
JIRA_SERVER: ${{ secrets.JIRA_SERVER }}
JIRA_PROJECT: ${{ secrets.JIRA_PROJECT }}
run: |
jira issue create \
-tTask \
-s"Review PR #${{ github.event.pull_request.number }}: ${{ github.event.pull_request.title }}" \
-b"${{ github.event.pull_request.html_url }}" \
--no-input
```
### GitLab CI - Update Jira on Deploy
```yaml
update_jira:
stage: deploy
script:
- |
# Extract Jira keys from commit messages
JIRA_KEYS=$(git log --format=%B -n 10 | grep -oE '[A-Z]+-[0-9]+' | sort -u)
for KEY in $JIRA_KEYS; do
echo "Updating $KEY to Done"
jira issue move "$KEY" Done -RDeployed --comment "Deployed to production"
done
only:
- main
```
### Jenkins Pipeline - Sprint Metrics
```groovy
pipeline {
agent any
triggers {
cron('0 9 * * 1') // Every Monday at 9 AM
}
stages {
stage('Generate Sprint Report') {
steps {
script {
sh '''
# Get current sprint
SPRINT_ID=$(jira sprint list --current --table --plain --columns id --no-headers)
# Generate metrics
echo "Sprint Metrics Report" > sprint_report.txt
echo "===================" >> sprint_report.txt
total=$(jira sprint list $SPRINT_ID --plain --no-headers | wc -l)
done=$(jira sprint list $SPRINT_ID -sDone --plain --no-headers | wc -l)
echo "Total: $total" >> sprint_report.txt
echo "Done: $done" >> sprint_report.txt
# Send to team
cat sprint_report.txt
'''
}
}
}
}
}
```
## Data Analysis
### Export Data for Analysis
```bash
#!/usr/bin/env bash
# Export comprehensive data for analysis
# Create timestamped directory
DIR="jira_export_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$DIR"
# Export different views
echo "Exporting all open issues..."
jira issue list -s~Done --csv > "$DIR/open_issues.csv"
echo "Exporting completed this month..."
jira issue list -sDone --updated month --csv > "$DIR/completed_month.csv"
echo "Exporting by assignee..."
for user in $(jira issue list --plain --columns assignee --no-headers | sort -u); do
jira issue list -a"$user" --csv > "$DIR/assignee_${user// /_}.csv"
done
echo "Export complete in $DIR/"
```
### Calculate Team Velocity
```bash
#!/usr/bin/env bash
# Calculate team velocity over last N sprints
SPRINT_COUNT=5
echo "=== Team Velocity (last $SPRINT_COUNT sprints) ==="
echo ""
sprints=$(jira sprint list --state closed --table --plain --columns id,name --no-headers | head -$SPRINT_COUNT)
total_points=0
sprint_count=0
echo "$sprints" | while IFS=$'\t' read -r id name; do
# Assuming story points in summary or custom field
completed=$(jira sprint list "$id" -sDone --plain --no-headers | wc -l)
echo "$name: $completed stories"
total_points=$((total_points + completed))
sprint_count=$((sprint_count + 1))
done
# Calculate average
if [ $sprint_count -gt 0 ]; then
avg=$(echo "scale=2; $total_points / $sprint_count" | bc)
echo ""
echo "Average velocity: $avg stories per sprint"
fi
```
## Automation Helpers
### Auto-Transition Based on PR Status
```bash
#!/usr/bin/env bash
# Auto-transition Jira issues based on PR status
# Get list of open PRs from GitHub
# (requires gh CLI)
prs=$(gh pr list --json number,title --jq '.[] | "\(.number)|\(.title)"')
echo "$prs" | while IFS='|' read -r number title; do
# Extract Jira key from PR title
jira_key=$(echo "$title" | grep -oE '[A-Z]+-[0-9]+' | head -1)
if [ -n "$jira_key" ]; then
# Check current status
status=$(jira issue view "$jira_key" --plain | grep "Status:" | awk '{print $2}')
# Move to In Review if not already
if [ "$status" != "Review" ]; then
echo "Moving $jira_key to In Review (PR #$number)"
jira issue move "$jira_key" "In Review"
jira issue link remote "$jira_key" "https://github.com/org/repo/pull/$number" "PR #$number"
fi
fi
done
```
### Stale Issue Cleanup
```bash
#!/usr/bin/env bash
# Find and handle stale issues
# Find issues not updated in 3 months
stale=$(jira issue list --updated-before -12w -s"To Do" --plain --columns key,summary --no-headers)
echo "$stale" | while IFS=$'\t' read -r key summary; do
echo "Stale issue found: $key - $summary"
# Add comment asking for update
jira issue comment add "$key" "This issue hasn't been updated in 3 months. Is it still relevant?"
# Add stale label
jira issue edit "$key" --label stale
# Optionally: move to backlog or close
# jira issue move "$key" "Backlog"
done
```
## Best Practices for Scripts
### Error Handling
```bash
#!/usr/bin/env bash
set -euo pipefail # Exit on error, undefined vars, pipe failures
# Check if jira-cli is available
if ! command -v jira &> /dev/null; then
echo "Error: jira-cli not found. Please install it first."
exit 1
fi
# Check for required environment variables
if [ -z "${JIRA_API_TOKEN:-}" ]; then
echo "Error: JIRA_API_TOKEN not set"
exit 1
fi
# Wrap jira commands with error handling
if ! jira issue list -a$(jira me) 2>&1; then
echo "Error: Failed to fetch issues"
exit 1
fi
```
### Logging and Debugging
```bash
#!/usr/bin/env bash
# Enable debug mode
DEBUG=${DEBUG:-false}
debug() {
if [ "$DEBUG" = "true" ]; then
echo "[DEBUG] $*" >&2
fi
}
debug "Starting script..."
debug "Fetching issues for user: $(jira me)"
issues=$(jira issue list -a$(jira me) --plain --columns key --no-headers)
debug "Found $(echo "$issues" | wc -l) issues"
```
### Rate Limiting
```bash
#!/usr/bin/env bash
# Process issues with rate limiting
issues=$(jira issue list --plain --columns key --no-headers)
for issue in $issues; do
echo "Processing $issue"
jira issue view "$issue" > /dev/null
# Rate limit: 1 request per second
sleep 1
done
```