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
Searchjira issue search --jqlRead and filter issues; pipe JSON to jq
Bulk transitionjira bulk transitionMove many issues between workflow states
Bulk assignjira bulk assignReassign many issues in one call
Bulk exportjira bulk exportSnapshot matched issues to JSON or CSV
Updatejira issue updateSet sprint, summary, or custom fields per issue
Createjira issue createGenerate recurring or templated tickets
Auditjira audit listPull 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.

Related Resources