Using Jira CLI for Extracting Information from Jira for Reporting and Auditing
READER BEWARE: THE FOLLOWING WRITTEN ENTIRELY BY AI WITHOUT HUMAN EDITING.
Introduction
Managing Jira effectively often requires extracting data for reporting, auditing, compliance, and analysis. While the Jira web interface is great for day-to-day work, it can be limiting when you need to automate reports, perform bulk queries, or extract data for external tools. This is where Jira CLI comes in—a powerful, open-source command-line interface that makes interacting with Jira fast, scriptable, and efficient.
This guide explores how to use Jira CLI for extracting information from Jira, with a focus on practical reporting and auditing use cases.
Why Use Jira CLI for Reporting and Auditing?
Advantages Over Web Interface and API
- Speed: Command-line operations are much faster than clicking through the web UI
- Automation: Easily script repetitive reporting tasks and schedule them with cron
- Bulk Operations: Query and process hundreds or thousands of issues at once
- Scriptable: Integrate with shell scripts, Python, or other automation tools
- Offline Processing: Export data once, then analyze it locally without repeated API calls
- Version Control: Track report definitions and queries in git alongside your code
- CI/CD Integration: Generate reports automatically as part of your pipeline
Common Use Cases
- Sprint Reports: Extract all issues from a sprint for retrospective analysis
- Audit Trails: Document who did what and when for compliance requirements
- Time Tracking: Export time logs for billing or resource planning
- SLA Compliance: Monitor issue resolution times and response times
- Epic Progress: Track progress across multiple epics and teams
- Dependency Analysis: Identify blockers and dependencies across projects
- Custom Reports: Generate reports that don’t exist in Jira’s standard reporting
Installation and Setup
Installing Jira CLI
macOS (Homebrew):
brew install ankitpokhrel/jira-cli/jira-cli
Linux:
# Download latest release
curl -sL https://github.com/ankitpokhrel/jira-cli/releases/latest/download/jira_linux_amd64.tar.gz | tar xz
sudo mv jira /usr/local/bin/
Windows (Scoop):
scoop bucket add jira-cli https://github.com/ankitpokhrel/jira-cli
scoop install jira-cli
From Source (Go):
go install github.com/ankitpokhrel/jira-cli/cmd/jira@latest
Initial Configuration
After installation, run the setup wizard:
jira init
You’ll be prompted for:
- Jira server URL: Your Jira instance (e.g.,
https://yourcompany.atlassian.net) - Login method: Choose between username/password or API token (recommended)
- Email/Username: Your Jira account email or username
- API Token: Generate one at https://id.atlassian.com/manage-profile/security/api-tokens
The configuration is stored in ~/.config/.jira/.config.yml and can be edited manually. Replace the placeholder values with your actual Jira instance details:
server: https://yourcompany.atlassian.net # Replace with your Jira URL
login: your-email@company.com # Replace with your Jira email
project:
key: PROJ # Replace with your project key
type: Software
installation: Cloud
Testing Your Connection
Verify your setup works:
# View your profile
jira me
# List recent issues
jira issue list --plain
# View a specific issue
jira issue view PROJ-123
Basic Data Extraction
Listing Issues
The issue list command is your primary tool for extracting issue data:
# List all issues in current project
jira issue list
# List with custom JQL query
jira issue list --jql "project = PROJ AND status = 'In Progress'"
# List with specific columns
jira issue list --columns "key,summary,status,assignee,created"
# Export to CSV
jira issue list --plain --no-headers --columns "key,summary,status" > issues.csv
# Get more results (default is 50)
jira issue list --limit 100
# Paginate through results
jira issue list --paginate 25
Working with JQL
Jira Query Language (JQL) is powerful for filtering issues:
# Issues created in the last 30 days
jira issue list --jql "created >= -30d"
# High priority bugs
jira issue list --jql "type = Bug AND priority = High"
# Unresolved issues assigned to a specific user
jira issue list --jql "assignee = 'john.doe' AND status != Done"
# Issues updated this week
jira issue list --jql "updated >= startOfWeek()"
# Complex query with multiple conditions
jira issue list --jql "project = PROJ AND (status = 'In Progress' OR status = 'In Review') AND assignee is not EMPTY ORDER BY priority DESC"
Exporting Issue Details
Get comprehensive issue information:
# View single issue in detail
jira issue view PROJ-123
# Export issue as JSON
jira issue view PROJ-123 --json
# Export multiple issues
for issue in $(jira issue list --plain --no-headers --columns key | head -10); do
jira issue view "$issue" --json >> issues.json
done
Reporting Use Cases
Sprint Report
Generate a comprehensive sprint report:
#!/bin/bash
# sprint-report.sh - Generate sprint completion report
SPRINT_NAME="Sprint 42"
PROJECT="PROJ"
OUTPUT_FILE="sprint_42_report.txt"
echo "Sprint Report: $SPRINT_NAME" > "$OUTPUT_FILE"
echo "Generated: $(date)" >> "$OUTPUT_FILE"
echo "================================" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
# All issues in sprint
echo "All Issues in Sprint:" >> "$OUTPUT_FILE"
jira issue list --jql "project = $PROJECT AND sprint = '$SPRINT_NAME'" \
--plain --columns "key,type,summary,status,assignee" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
# Completed issues
echo "Completed Issues:" >> "$OUTPUT_FILE"
COMPLETED=$(jira issue list --jql "project = $PROJECT AND sprint = '$SPRINT_NAME' AND status = Done" --plain --no-headers | wc -l)
echo "Total: $COMPLETED" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
# In Progress issues
echo "In Progress Issues:" >> "$OUTPUT_FILE"
jira issue list --jql "project = $PROJECT AND sprint = '$SPRINT_NAME' AND status = 'In Progress'" \
--plain --columns "key,summary,assignee" >> "$OUTPUT_FILE"
echo "" >> "$OUTPUT_FILE"
# Blocked issues
echo "Blocked Issues:" >> "$OUTPUT_FILE"
jira issue list --jql "project = $PROJECT AND sprint = '$SPRINT_NAME' AND labels = blocked" \
--plain --columns "key,summary,assignee" >> "$OUTPUT_FILE"
echo "Report saved to $OUTPUT_FILE"
Epic Progress Report
Track progress across epics:
#!/bin/bash
# epic-progress.sh - Generate epic progress report
PROJECT="PROJ"
OUTPUT="epic_progress.csv"
echo "Epic Key,Epic Summary,Total Issues,Completed,In Progress,To Do" > "$OUTPUT"
# Get all epics
EPICS=$(jira issue list --jql "project = $PROJECT AND type = Epic" --plain --no-headers --columns key)
for epic in $EPICS; do
EPIC_SUMMARY=$(jira issue view "$epic" --plain | grep "Summary:" | cut -d: -f2-)
# Count issues by status
TOTAL=$(jira issue list --jql "parent = $epic" --plain --no-headers | wc -l)
DONE=$(jira issue list --jql "parent = $epic AND status = Done" --plain --no-headers | wc -l)
IN_PROGRESS=$(jira issue list --jql "parent = $epic AND status = 'In Progress'" --plain --no-headers | wc -l)
TODO=$(jira issue list --jql "parent = $epic AND status = 'To Do'" --plain --no-headers | wc -l)
echo "$epic,$EPIC_SUMMARY,$TOTAL,$DONE,$IN_PROGRESS,$TODO" >> "$OUTPUT"
done
echo "Epic progress report saved to $OUTPUT"
Time Tracking Report
Extract time logging data for billing or resource planning:
#!/bin/bash
# time-tracking-report.sh - Extract time logs
PROJECT="${1:-PROJ}"
# Default to current month if no dates provided
START_DATE="${2:-$(date -d "$(date +%Y-%m-01)" +%Y-%m-%d)}"
END_DATE="${3:-$(date +%Y-%m-%d)}"
jira issue list --jql "project = $PROJECT AND worklogDate >= '$START_DATE' AND worklogDate <= '$END_DATE'" \
--columns "key,summary,assignee,timeSpent,timeEstimate" \
--plain > time_report.csv
echo "Time tracking report generated for $START_DATE to $END_DATE"
Audit Trail Report
Generate audit trail for compliance:
#!/bin/bash
# audit-trail.sh - Generate audit trail report
PROJECT="PROJ"
DAYS=30
OUTPUT="audit_trail_${DAYS}days.txt"
echo "Audit Trail Report" > "$OUTPUT"
echo "Period: Last $DAYS days" >> "$OUTPUT"
echo "Generated: $(date)" >> "$OUTPUT"
echo "================================" >> "$OUTPUT"
echo "" >> "$OUTPUT"
# Issues created
echo "Issues Created:" >> "$OUTPUT"
jira issue list --jql "project = $PROJECT AND created >= -${DAYS}d" \
--columns "key,summary,creator,created" --plain >> "$OUTPUT"
echo "" >> "$OUTPUT"
# Issues updated
echo "Issues Updated:" >> "$OUTPUT"
jira issue list --jql "project = $PROJECT AND updated >= -${DAYS}d" \
--columns "key,summary,assignee,updated" --plain >> "$OUTPUT"
echo "" >> "$OUTPUT"
# Issues transitioned to Done
echo "Issues Completed:" >> "$OUTPUT"
jira issue list --jql "project = $PROJECT AND status CHANGED TO Done AFTER -${DAYS}d" \
--columns "key,summary,assignee,resolutionDate" --plain >> "$OUTPUT"
echo "Audit trail saved to $OUTPUT"
Advanced Extraction Techniques
Using JSON Output for Complex Processing
Jira CLI can output JSON for further processing with tools like jq:
# Extract all high priority bugs as JSON
jira issue list --jql "type = Bug AND priority = High" --json | jq '.'
# Get specific fields
jira issue list --jql "project = PROJ" --json | jq '.issues[] | {key: .key, status: .fields.status.name}'
# Count issues by status
jira issue list --jql "project = PROJ" --json | \
jq '.issues | group_by(.fields.status.name) | map({status: .[0].fields.status.name, count: length})'
# Extract custom fields
jira issue view PROJ-123 --json | jq '.fields.customfield_10042'
Batch Processing
Process multiple issues efficiently:
#!/bin/bash
# batch-export.sh - Export detailed information for multiple issues
JQL="project = PROJ AND sprint = 'Sprint 42'"
OUTPUT_DIR="./sprint_42_export"
mkdir -p "$OUTPUT_DIR"
# Get issue keys
ISSUES=$(jira issue list --jql "$JQL" --plain --no-headers --columns key)
echo "Exporting $(echo "$ISSUES" | wc -l) issues..."
for issue in $ISSUES; do
echo "Exporting $issue..."
# Export issue details
jira issue view "$issue" > "$OUTPUT_DIR/${issue}.txt"
# Export as JSON for programmatic access
jira issue view "$issue" --json > "$OUTPUT_DIR/${issue}.json"
# Small delay to avoid rate limiting
sleep 0.5
done
echo "Export complete. Files saved to $OUTPUT_DIR"
Combining with Other Tools
Integrate Jira CLI with other command-line tools:
# Export to Excel-compatible CSV with custom formatting
jira issue list --jql "project = PROJ" --plain --no-headers \
--columns "key,type,summary,status,priority,assignee,created" | \
awk -F'\t' '{printf "\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n", $1,$2,$3,$4,$5,$6,$7}' \
> report.csv
# Generate Markdown table
echo "| Key | Summary | Status | Assignee |" > report.md
echo "|-----|---------|--------|----------|" >> report.md
jira issue list --jql "project = PROJ AND status = 'In Progress'" --plain --no-headers \
--columns "key,summary,status,assignee" | \
awk -F'\t' '{printf "| %s | %s | %s | %s |\n", $1,$2,$3,$4}' >> report.md
# Email report
jira issue list --jql "project = PROJ AND priority = High AND status != Done" \
--plain > priority_issues.txt && \
mail -s "High Priority Issues Report" team@company.com < priority_issues.txt
Automation and Scheduling
Daily Status Report
Create a cron job for daily reports:
# daily-status.sh - Automated daily status report
#!/bin/bash
set -euo pipefail
PROJECT="PROJ"
DATE=$(date +%Y-%m-%d)
REPORT_FILE="daily_status_${DATE}.txt"
RECIPIENT="team@company.com"
{
echo "Daily Status Report - $DATE"
echo "================================"
echo ""
echo "New Issues (Last 24 hours):"
jira issue list --jql "project = $PROJECT AND created >= -1d" \
--columns "key,summary,assignee" --plain
echo ""
echo "Completed Issues (Last 24 hours):"
jira issue list --jql "project = $PROJECT AND status CHANGED TO Done AFTER -1d" \
--columns "key,summary,assignee" --plain
echo ""
echo "Blocked Issues:"
jira issue list --jql "project = $PROJECT AND labels = blocked AND status != Done" \
--columns "key,summary,assignee" --plain
echo ""
echo "High Priority Open Issues:"
jira issue list --jql "project = $PROJECT AND priority = High AND status != Done" \
--columns "key,summary,status,assignee" --plain
} > "$REPORT_FILE"
# Email the report
if [ -s "$REPORT_FILE" ]; then
mail -s "Daily Status Report - $DATE" "$RECIPIENT" < "$REPORT_FILE"
echo "Report sent to $RECIPIENT"
else
echo "Report is empty, not sending"
fi
Add to crontab:
# Run daily at 9 AM
0 9 * * * /path/to/daily-status.sh
Weekly Summary
Generate comprehensive weekly reports:
#!/bin/bash
# weekly-summary.sh - Weekly team summary
PROJECT="PROJ"
WEEK=$(date +%Y-W%U)
OUTPUT="weekly_summary_${WEEK}.html"
cat > "$OUTPUT" << EOF
<!DOCTYPE html>
<html>
<head>
<title>Weekly Summary - Week $WEEK</title>
<style>
body { font-family: Arial, sans-serif; margin: 40px; }
h1 { color: #0052CC; }
h2 { color: #172B4D; border-bottom: 2px solid #0052CC; padding-bottom: 5px; }
table { border-collapse: collapse; width: 100%; margin: 20px 0; }
th, td { padding: 12px; text-align: left; border: 1px solid #ddd; }
th { background-color: #0052CC; color: white; }
tr:nth-child(even) { background-color: #f2f2f2; }
</style>
</head>
<body>
<h1>Weekly Summary - Week $WEEK</h1>
<p>Generated: $(date)</p>
<h2>Issues Created This Week</h2>
<table>
<tr><th>Key</th><th>Type</th><th>Summary</th><th>Assignee</th><th>Status</th></tr>
EOF
jira issue list --jql "project = $PROJECT AND created >= -7d" \
--plain --no-headers --columns "key,type,summary,assignee,status" | \
awk -F'\t' '{printf "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", $1,$2,$3,$4,$5}' >> "$OUTPUT"
cat >> "$OUTPUT" << EOF
</table>
<h2>Issues Completed This Week</h2>
<table>
<tr><th>Key</th><th>Summary</th><th>Assignee</th><th>Resolution Date</th></tr>
EOF
jira issue list --jql "project = $PROJECT AND status CHANGED TO Done AFTER -7d" \
--plain --no-headers --columns "key,summary,assignee,resolutionDate" | \
awk -F'\t' '{printf "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", $1,$2,$3,$4}' >> "$OUTPUT"
cat >> "$OUTPUT" << EOF
</table>
</body>
</html>
EOF
echo "Weekly summary generated: $OUTPUT"
# Convert to PDF if wkhtmltopdf is available
if command -v wkhtmltopdf &> /dev/null; then
wkhtmltopdf "$OUTPUT" "${OUTPUT%.html}.pdf"
echo "PDF version created"
fi
Custom Fields and Advanced Queries
Working with Custom Fields
Find and use custom fields:
# View all fields for an issue (including custom fields)
jira issue view PROJ-123 --json | jq '.fields' | grep customfield
# Extract specific custom field
jira issue view PROJ-123 --json | jq '.fields.customfield_10042'
# Query by custom field
jira issue list --jql "project = PROJ AND customfield_10042 = 'value'"
Saved Filters
Use Jira saved filters:
# List using a saved filter
jira issue list --jql "filter = 'My Team Issues'"
# Export from multiple filters
for filter in "Sprint Backlog" "In Review" "Blocked"; do
jira issue list --jql "filter = '$filter'" --plain > "${filter// /_}.txt"
done
Best Practices for Reporting and Auditing
1. Rate Limiting and Performance
# Add delays in loops to avoid rate limiting
for issue in $ISSUES; do
jira issue view "$issue"
sleep 1 # Wait 1 second between requests
done
# Process in smaller batches
BATCH_SIZE=50
jira issue list --limit $BATCH_SIZE --paginate
2. Error Handling
#!/bin/bash
set -euo pipefail # Exit on error, undefined variable, or pipe failure
# Function with error handling
export_issue() {
local issue=$1
local output_dir=$2
if ! jira issue view "$issue" > "$output_dir/${issue}.txt" 2>&1; then
echo "Error exporting $issue" >&2
return 1
fi
return 0
}
# Use with trap for cleanup
cleanup() {
echo "Cleaning up temporary files..."
rm -f /tmp/jira-export-*
}
trap cleanup EXIT
# Retry logic
retry_count=0
max_retries=3
while [ $retry_count -lt $max_retries ]; do
if jira issue list --jql "project = PROJ"; then
break
else
retry_count=$((retry_count + 1))
echo "Attempt $retry_count failed, retrying..." >&2
sleep 5
fi
done
3. Secure Credential Management
# Use environment variables for sensitive data
export JIRA_API_TOKEN="your-token-here"
# Or use a secrets manager
JIRA_TOKEN=$(vault kv get -field=token secret/jira/api)
# Never commit credentials to version control
echo ".jira-credentials" >> .gitignore
4. Output Formatting
# Make output readable
jira issue list --plain --columns "key,summary,status,assignee" | column -t -s $'\t'
# Add timestamps to logs
log() {
echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*"
}
log "Starting report generation..."
5. Documentation
#!/bin/bash
# report-generator.sh
#
# Purpose: Generate comprehensive project status reports
# Author: Your Name
# Date: 2025-11-05
# Usage: ./report-generator.sh <project-key> <output-dir>
#
# Requirements:
# - jira-cli installed and configured
# - jq for JSON processing
# - write access to output directory
#
# Example:
# ./report-generator.sh PROJ ./reports
Integration with CI/CD
GitHub Actions Example
# .github/workflows/jira-report.yml
name: Daily Jira Report
on:
schedule:
- cron: '0 9 * * 1-5' # Weekdays at 9 AM
workflow_dispatch: # Manual trigger
jobs:
generate-report:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Jira CLI
run: |
curl -sL https://github.com/ankitpokhrel/jira-cli/releases/latest/download/jira_linux_amd64.tar.gz | tar xz
sudo mv jira /usr/local/bin/
- name: Configure Jira CLI
env:
JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }}
run: |
mkdir -p ~/.config/.jira
cat > ~/.config/.jira/.config.yml << EOF
server: https://yourcompany.atlassian.net
login: ${{ secrets.JIRA_EMAIL }}
EOF
# Set API token in environment for jira-cli
echo "JIRA_API_TOKEN=$JIRA_API_TOKEN" >> $GITHUB_ENV
- name: Generate Report
run: |
./scripts/daily-report.sh > report.txt
- name: Upload Report
uses: actions/upload-artifact@v3
with:
name: jira-report
path: report.txt
- name: Send Notification
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "Daily Jira report generated",
"attachments": [{
"text": "Report available in workflow artifacts"
}]
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
Jenkins Pipeline Example
// Jenkinsfile
pipeline {
agent any
triggers {
cron('0 9 * * 1-5') // Weekdays at 9 AM
}
stages {
stage('Install Jira CLI') {
steps {
sh '''
if ! command -v jira &> /dev/null; then
curl -sL https://github.com/ankitpokhrel/jira-cli/releases/latest/download/jira_linux_amd64.tar.gz | tar xz
sudo mv jira /usr/local/bin/
fi
'''
}
}
stage('Generate Report') {
steps {
withCredentials([string(credentialsId: 'jira-api-token', variable: 'JIRA_TOKEN')]) {
sh '''
export JIRA_API_TOKEN=$JIRA_TOKEN
./scripts/weekly-report.sh
'''
}
}
}
stage('Archive Report') {
steps {
archiveArtifacts artifacts: '*.txt,*.csv,*.html', fingerprint: true
}
}
stage('Notify') {
steps {
emailext(
subject: "Weekly Jira Report - ${env.BUILD_ID}",
body: "Weekly Jira report has been generated. See attached artifacts.",
to: 'team@company.com',
attachmentsPattern: '*.html'
)
}
}
}
}
Troubleshooting
Common Issues
Authentication Failed
# Verify credentials
jira me
# Re-initialize configuration
jira init --force
# Check config file
cat ~/.config/.jira/.config.yml
Empty Results
# Verify JQL syntax
jira issue list --jql "project = PROJ" --debug
# Test in Jira web UI first
# Copy the JQL from Issues → Search
# Check project key
jira project list
Rate Limiting
# Add delays between requests
sleep 1
# Reduce batch size
jira issue list --limit 25
# Use pagination
jira issue list --paginate 10
Custom Fields Not Showing
# View all fields
jira issue view PROJ-123 --json | jq '.fields | keys'
# Find custom field ID
jira issue view PROJ-123 --json | jq '.fields | to_entries | .[] | select(.key | startswith("customfield"))'
Conclusion
Jira CLI is a powerful tool for extracting information from Jira for reporting and auditing purposes. By combining it with shell scripting, you can:
- Automate repetitive reporting tasks
- Generate custom reports not available in Jira
- Extract data for compliance and audit requirements
- Integrate Jira data into your CI/CD pipelines
- Schedule regular status updates and summaries
- Process large volumes of issues efficiently
The examples in this guide provide a solid foundation for building your own reporting and auditing workflows. Start with simple queries and gradually build more complex automation as your needs grow.
Key Takeaways
- Start Simple: Begin with basic
jira issue listcommands and gradually add complexity - Use JQL: Master Jira Query Language for precise data extraction
- Automate Early: Schedule reports with cron or CI/CD pipelines
- Handle Errors: Add retry logic and error handling to production scripts
- Document Everything: Keep your scripts well-documented and version controlled
- Respect Limits: Implement rate limiting and pagination for large queries
- Secure Credentials: Never commit API tokens to version control
Next Steps
- Explore the Jira CLI documentation
- Build your first automated report
- Share your scripts with your team
- Integrate with your existing tools and workflows
- Contribute back to the Jira CLI project if you develop useful features