# 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 " 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 ```