atlassian-cli is an independent, community open-source project, not affiliated with, endorsed by, or sponsored by Atlassian, and is not Atlassian's official CLI (acli). Product names are used only to identify compatibility.
Before you copy-paste
These Jira automation examples are complete, runnable commands, not pseudo-code. Each one uses atlassian-cli, a single free binary, and each is built to drop straight into cron, a CI stage, or a git hook. Swap the project key, the JQL, and the profile name for your own, and they work.
Two ground rules before you run any of them against a live instance. First, every jira bulk command supports --dry-run: run it once to see the matched issue count and a sample of keys, then remove the flag to execute. Second, pin every command to a named auth profile with --profile so you never point a cleanup script at the wrong site. See Authentication to set profiles up, and the command reference for every flag.
A quick note on what this is not: atlassian-cli is an independent, community, MIT-licensed open-source project. It is not Atlassian's official CLI (acli) and is not affiliated with, endorsed by, or sponsored by Atlassian. Use the official acli if you want first-party vendor support; use atlassian-cli if you want one scriptable binary spanning Jira, Confluence, Bitbucket, and Jira Service Management. For a broader walkthrough of the approach, see the Jira automation guide.
The building blocks
Nearly all fifteen recipes are combinations of seven commands. Learn these and you can compose your own automations without memorizing anything else.
Two JQL habits show up in almost every recipe below. Relative dates like updated < -7d or created < -180d let a scheduled query stay accurate forever without editing the script. And statusCategory != Done matches every "not finished" state at once, so you never have to spell out status not in (Done, Closed, Resolved, ...) for each project's custom workflow. Add --format json to any search to pipe results into jq, or --envelope to wrap list output in a {"data": [...], "count": N} object when a downstream tool wants the count alongside the rows.
| Building block | Command | Use it for |
|---|---|---|
| Search | jira issue search --jql | Read and filter issues; pipe JSON to jq |
| Bulk transition | jira bulk transition | Move many issues between workflow states |
| Bulk assign | jira bulk assign | Reassign many issues in one call |
| Bulk export | jira bulk export | Snapshot matched issues to JSON or CSV |
| Update | jira issue update | Set sprint, summary, or custom fields per issue |
| Create | jira issue create | Generate recurring or templated tickets |
| Audit | jira audit list | Pull the change log for compliance exports |
Cleanup and hygiene
01Auto-close stale "Done" issues every night
Issues sit in Done long after the work shipped. Preview once, then schedule the live run in cron so the board stays tidy without anyone clicking.
# Preview first
atlassian-cli jira bulk transition \
--jql "project = DEV AND status = Done AND updated < -7d" \
--transition "Closed" \
--dry-run
# crontab -e: run for real every night at 2am
0 2 * * * atlassian-cli jira bulk transition \
--jql "project = DEV AND status = Done AND updated < -7d" \
--transition "Closed" --profile prod --format quiet
02Archive abandoned open tickets
Anything Open and untouched for six months is almost certainly dead. Close it in one pass instead of one click at a time.
atlassian-cli jira bulk transition \
--jql "project = DEV AND status = Open AND updated < -180d" \
--transition "Closed" \
--dry-run
03Export a "backlog rot" report
Find the issues that have gone quiet: not done, not touched in 90 days, oldest first. Drop them into a CSV your team can triage together.
atlassian-cli jira issue search \
--jql "project = DEV AND statusCategory != Done AND updated < -90d ORDER BY updated ASC" \
--format csv --output backlog-rot.csv
Assignment and routing
04Route unassigned bugs to a triage lead
New bugs with no owner slip through the cracks. Sweep them to a triage lead on a schedule so nothing sits unassigned overnight.
atlassian-cli jira bulk assign \
--jql "project = DEV AND type = Bug AND assignee is EMPTY" \
--assignee triage-lead@example.com \
--dry-run
05Reassign a departing teammate's open work
When someone leaves, hand off everything they still own in a single command instead of reopening each ticket by hand.
atlassian-cli jira bulk assign \
--jql "assignee = leaver@example.com AND statusCategory != Done" \
--assignee new-owner@example.com \
--dry-run
06Move a labeled set of issues into a sprint
There is no bulk sprint verb, but search plus a loop does the job. Pull the keys, then set the sprint per issue with the numeric sprint id.
atlassian-cli jira issue search \
--jql "project = DEV AND labels = next-sprint AND sprint is EMPTY" \
--format json | jq -r '.[].key' | while read key; do
atlassian-cli jira issue update "$key" --sprint 25446
done
Reporting and export
07Ship a weekly closed-sprint report
Every Friday, snapshot what the team finished in the last closed sprint to a dated CSV for the retro. See the sprint report runbook for a fuller version.
atlassian-cli jira bulk export \
--jql "project = DEV AND sprint in closedSprints() AND status = Done" \
--output "sprint-report-$(date +%F).csv" \
--format csv
08Nightly JSON backup of a project
A dated JSON snapshot of every issue gives you a diffable history and a fallback you control. JSON preserves the full field structure.
atlassian-cli jira bulk export \
--jql "project = DEV" \
--output "/backups/dev-$(date +%F).json" \
--format json
09Count issues by status with jq
Skip the dashboard. Pipe JSON search results through jq to get a live status breakdown you can print anywhere.
atlassian-cli jira issue search \
--jql "project = DEV" --format json \
| jq -r 'group_by(.fields.status.name)[] | "\(.[0].fields.status.name): \(length)"'
Alerts and CI gates
10Print your standup digest
Start the day with your own open work, freshest first, as clean Markdown you can paste into a standup channel.
atlassian-cli jira issue search \
--jql "assignee = currentUser() AND statusCategory != Done ORDER BY updated DESC" \
--format markdown
11Alert a chat channel on new blockers
Count open blockers, and only post to a webhook when there is something worth interrupting people for.
COUNT=$(atlassian-cli jira issue search \
--jql "project = DEV AND priority = Blocker AND status != Done" \
--format json | jq 'length')
if [ "$COUNT" -gt 0 ]; then
curl -s -X POST -H 'Content-Type: application/json' \
-d "{\"text\":\"$COUNT open blocker(s) in DEV\"}" \
"$SLACK_WEBHOOK_URL"
fi
12Gate a release on open blockers
Drop this into a CI stage. If any blocker is still open, the pipeline fails with a non-zero exit and the release stops.
COUNT=$(atlassian-cli jira issue search \
--jql "project = DEV AND priority = Blocker AND status != Done" \
--format json | jq 'length')
if [ "$COUNT" -gt 0 ]; then
echo "Release blocked: $COUNT open blocker(s)"
exit 1
fi
Compliance and cross-product
13Export the audit log for compliance
Pull the change log from a start date into a monthly CSV. Schedule it and you have an unattended compliance trail.
atlassian-cli jira audit list \
--from 2026-06-01 --limit 1000 \
--format csv > audit-2026-06.csv
14Publish release notes to Confluence
One binary spans products, so a single script can read closed Jira issues and publish a Confluence page in the same run.
BODY=$(atlassian-cli jira issue search \
--jql "project = DEV AND fixVersion = 2.4.0 AND status = Done" \
--format json \
| jq -r '"<ul>" + (map("<li>" + .key + " " + .fields.summary + "</li>") | join("")) + "</ul>"')
atlassian-cli confluence page create \
--space DOCS --title "Release 2.4.0 notes" --body "$BODY"
15Roll up open incidents across instances
Loop over profiles to report the same query across every site you manage, from one terminal.
for p in prod staging eu; do
echo "== $p =="
atlassian-cli jira issue search --profile "$p" \
--jql "type = Incident AND status != Done" \
--format table
done
That is fifteen. The pattern underneath all of them is the same: a JQL query selects the issues, a verb acts on them, and cron or CI decides when. Change the verb and you get a new automation for free. Recipe 1 becomes a "reopen everything mistakenly closed" script by flipping the transition; recipe 9 becomes a priority breakdown by grouping on .fields.priority.name instead of status. Start from the recipe closest to your problem and mutate it rather than writing from scratch.
Once the pattern clicks, the command reference is the only page you need. For heavier mutation workflows, the bulk operations deep-dive covers concurrency control and error recovery when you are moving thousands of issues at once.
Try atlassian-cli
One free MIT-licensed binary for Jira, Confluence, Bitbucket, and JSM. Install it and run the first recipe in under a minute.
Install atlassian-cli →FAQ
Can I automate Jira without paying for automation rules?
Yes. Anything you can express as a JQL query, you can script with atlassian-cli and schedule with cron or run in CI. That covers the majority of these Jira automation examples: closing stale issues, reassigning work, exporting reports, and gating releases. Jira's built-in automation rules and the CLI are complementary, not mutually exclusive, so you can use whichever fits each task.
How do I schedule these Jira automations to run on their own?
Wrap the command in a shell script and add a line to your crontab, or drop it into a CI pipeline stage. For example, 0 2 * * * atlassian-cli jira bulk transition ... runs a cleanup every night at 2am. Because atlassian-cli is a single binary with no interactive prompts when flags are supplied, it runs unattended in cron, systemd timers, GitHub Actions, or Bitbucket Pipelines.
Are these Jira automation scripts safe to run on production?
Every bulk command supports a --dry-run flag that runs the same query and shows exactly what would change without modifying anything. The recommended pattern is to run once with --dry-run, confirm the issue count and sample keys, then remove the flag. Point commands at a specific profile with --profile so you never touch the wrong instance.
Do I need a separate tool for each Atlassian product to automate them?
No. atlassian-cli is one binary that spans Jira, Confluence, Bitbucket, and Jira Service Management, so a single script can read closed Jira issues and publish a Confluence release-notes page in the same run. You authenticate once per profile and reuse it across every product command.