Skip to main content

jira

CI codecov

A fast, friendly Jira CLI for Jira Cloud and Jira Data Center / Server, built to feel natural for people and predictable for agents.

  • Auto-JSON when stdout is not a TTY, so you can pipe it anywhere and get structured data
  • jira doctor verifies configuration, the site's deployment (Cloud or Data Center, with the matching auth and API version), identity, project access, and write safety in one command
  • Command-scoped schema gives agents one complete command contract without loading the full tree
  • Structured exit codes, so agents can branch on auth failures, rate limits, not-found, and input errors without parsing text
  • Clean stdout/stderr split: data on stdout, messages on stderr, --quiet suppresses all non-data output
$ jira issues list --project MYAPP --status "In Progress"
Key        Status       Assignee  Type  Summary
MYAPP-42   In Progress  Alice     Bug   Fix login redirect loop
MYAPP-38   In Progress  Bob       Task  Update password reset flow

$ jira issues list --project MYAPP --json
{"items": [...], "total": 2, "startAt": 0, "maxResults": 50}

Installation

uv tool install jira-cli-rs

Or via Cargo:

cargo install jira-cli

Or build from source:

git clone https://github.com/rvben/jira-cli
cd jira-cli
make install          # runs check + release build, copies to ~/.local/bin/jira

Configuration

Run jira auth login (or the shorter jira init) for guided setup. Enter your Cloud subdomain, your site's address, or paste any link from Jira; setup asks the site whether it runs Jira Cloud or Data Center, so there is no deployment type or API version to choose. It offers to open the token page, discovers the Cloud ID required by scoped tokens, hides token entry, verifies the account and its project access, and stores the token in your operating-system keychain. Existing profile values are reused safely. If no OS credential service is available, setup offers an explicit protected-file fallback rather than silently weakening storage.

A scoped Cloud token needs these scopes:

Access Scopes
Read-only read:jira-work, read:jira-user
Read-write the read-only scopes plus write:jira-work
Boards and sprints, added read:board-scope:jira-software, read:board-scope.admin:jira-software, read:project:jira, read:issue-details:jira, read:jql:jira, read:sprint:jira-software, plus write:sprint:jira-software to move issues into sprints

Jira's board and sprint API accepts only the granular scopes in the last row, so a token with just the classic scopes works for every command except boards and sprints. Setup prints the list for the access you choose, and jira init --json returns it as cloudTokenScopes.

For Jira Data Center, setup can create a dedicated PAT through Jira's official API using a one-time password or existing PAT. That bootstrap credential is never saved. When no terminal is available, jira init --json returns setup instructions, and jira init --json --host <site> also asks the site whether it runs Cloud or Data Center and returns the one page where its token is created. CI can use the environment variables below directly.

To save a profile without prompts, pipe the token to jira auth login --with-token:

jira auth login --with-token --host acme --email me@example.com < token.txt
jira --profile dc auth login --with-token --host jira.example.com --read-only < pat.txt
jira --profile work auth login --with-token < new-token.txt   # rotate: only the token changes

It identifies the site's deployment the same way, verifies the token and project access, and saves nothing if a check fails. Settings you leave out come from the profile being replaced; its email and token kind only while the site stays the same, since they belong to that site's account. A new Cloud profile expects a scoped token; pass --token-kind classic for one created without scopes. --credential-store file keeps the token in the protected config file where no OS keychain is available.

Default locations:

Platform Path
Linux / macOS ~/.config/jira/config.toml (or $XDG_CONFIG_HOME/jira/config.toml)
[default]
host  = "mycompany.atlassian.net"
email = "me@example.com"
credential_store = "keyring"
cloud_id = "your-atlassian-cloud-id"
token_kind = "scoped"
read_only = true

Get a Jira Cloud API token at: https://id.atlassian.com/manage-profile/security/api-tokens

Run jira auth status to verify the active credential, jira auth status --offline to inspect local credential state without a request, and jira doctor for the complete connection. jira config show displays resolved settings and the credential source; jira config path prints the backing file. Existing configs with inline tokens remain readable; move one into the keychain with jira auth migrate.

Environment variables

All credentials can be set via environment variables, which is useful for CI and scripts:

Variable Description
JIRA_HOST Atlassian domain (e.g. mycompany.atlassian.net)
JIRA_EMAIL Account email
JIRA_TOKEN API token or Personal Access Token
JIRA_PROFILE Config profile name
JIRA_AUTH_TYPE basic (default) or pat
JIRA_API_VERSION 3 (Cloud, default) or 2 (Data Center / Server)
JIRA_CLOUD_ID Atlassian Cloud ID required by a scoped token
JIRA_TOKEN_KIND scoped or classic
JIRA_STORY_POINTS_FIELD Custom field ID to read story points from (e.g. customfield_10016) instead of discovering it
JIRA_READ_ONLY Block write operations. On: 1, true, yes, on. Off: 0, false, no, off. Any other value is an error, not "off"
JIRA_DEBUG_HTTP Include the raw Jira response body in API error messages (1, true, yes, on). Useful when the default summary is ambiguous.

Values are matched case-insensitively. JIRA_AUTH_TYPE and JIRA_API_VERSION reject anything outside the values listed above rather than falling back to the default, so a typo surfaces as a config error instead of an unexplained authentication failure.

Multiple profiles

[default]
host  = "mycompany.atlassian.net"
email = "me@example.com"
credential_store = "keyring"
cloud_id = "your-atlassian-cloud-id"
token_kind = "scoped"

[profiles.dc]
host        = "jira.corp.com"
credential_store = "keyring"
auth_type   = "pat"
api_version = 2

Switch with --profile dc or JIRA_PROFILE=dc jira <command>.

Jira Data Center / Server (PAT auth)

Data Center uses Personal Access Tokens instead of email + API token:

[default]
host        = "jira.corp.com"
credential_store = "keyring"
auth_type   = "pat"
api_version = 2

Email is not required for PAT auth. jira auth login can create and save a dedicated PAT automatically, or open the manual token page: https://<your-host>/secure/ViewProfile.jspa. From there, choose Personal access tokens. Jira's direct selected-tab URL varies by release.

Usage

Interactive workbench

Run jira tui to browse your assigned issues in a terminal. Use jira tui --project MYAPP to start within one project, or press p to change the project while browsing. The workbench shows a live issue list and an inspector with the description and recent comments. It works with Jira Cloud and Data Center profiles. The current sprint view uses Jira's active sprint search; without a project, it includes issues from all active sprints you can access.

Key Action
1, 2, 3, 4 My work, current sprint, recent issues, JQL search
j / k, arrows Select an issue
/ Enter a JQL query
p Change the project for the preset views
f, Esc Filter loaded issues, clear the filter
n, r Load the next page, refresh
PageUp / PageDown Scroll the issue inspector
t, c Transition an issue, write a comment (write-enabled profiles)
o, ?, q Open in browser, show help, quit

In the comment editor, Enter starts a new line and Ctrl+S opens the review screen. Esc keeps the draft for this session. The transition picker names the required fields each transition's screen needs and the issue lacks, then asks for them one at a time: pick from the allowed values, or type the value (a user by name, e-mail address or me). Fields the issue already has are not asked for, and Esc steps back to the previous field. If Jira does not confirm a write, refresh the issue before trying again. Write actions are unavailable when the active profile is read-only. jira tui requires a terminal; scripts can use jira issues mine or jira search instead.

Issues

# List
jira issues list
jira issues list --project MYAPP --status "In Progress"
jira issues list --project MYAPP --type Bug --assignee me
jira issues list --sprint active
jira issues list --all                        # fetch every page

# Assigned to you
jira issues mine
jira issues mine --project MYAPP --status "To Do"
jira issues list --fields key,summary,parent,epic

# Show
jira issues show MYAPP-123
jira version                              # also available as jira --version

# Discover the create screen before choosing fields
jira issues create-meta -p MYAPP             # available issue types
jira issues create-meta -p MYAPP -t Story    # required fields, defaults, options, epic support

# Create
jira issues create --project MYAPP --summary "Fix login bug" --type Bug
jira issues create --project MYAPP --summary "Add dark mode" --type Story \
  --description "Users want a dark mode option." --priority High --assignee me
jira issues create --project MYAPP --summary "Write unit tests" --type Subtask \
  --parent MYAPP-42                           # creates a subtask
jira issues create --project MYAPP --summary "Add dark mode" --type Story \
  --epic MYAPP-10 --priority Medium           # resolves this project's fields
jira issues create --project MYAPP --summary "Add dark mode" --type Story \
  --field reporter=jdoe                       # user fields accept me, a username or an e-mail

# Preview normalized fields without making changes
jira issues create -p MYAPP -t Story -s "Example" --priority Medium --dry-run
jira issues update MYAPP-123 --priority Medium --dry-run
jira issues move MYAPP-123 --sprint active --dry-run

# Update
jira issues update MYAPP-123 --summary "Updated title"
jira issues update MYAPP-123 -s "Updated title" -d "New description"
jira issues update MYAPP-123 --sprint active  # same sprint move as `issues move`
jira issues update MYAPP-123 --priority Low --assignee me
jira issues update MYAPP-123 --field customfield_10016=5
jira issues update MYAPP-123 --epic MYAPP-10
jira issues update MYAPP-123 --clear-epic
jira issues update MYAPP-123 --type Story     # Task -> Story, same hierarchy level
jira issues update MYAPP-123 --assignee none

# Transition
jira issues list-transitions MYAPP-123  # destination status and the fields each one asks for
jira issues transition MYAPP-123 --to "In Review"
jira issues transition MYAPP-123 --to Done --resolution Fixed --comment "Released in 1.4"
jira issues transition MYAPP-123 --to Done --field "Root cause=Cache race" --dry-run

# Assign
jira issues assign MYAPP-123 --assignee me
jira issues assign MYAPP-123 --assignee user@example.com --dry-run  # checks assignability

# Comment
jira issues comment MYAPP-123 --body "Deployed to staging."
jira issues comment MYAPP-123 --body "Deployed to staging." --dry-run
jira issues comments MYAPP-123

# Log work
jira issues log-work MYAPP-123 --time 2h
jira issues log-work MYAPP-123 --time 30m --comment "Fixed the flaky test"
jira issues log-work MYAPP-123 --time 1h --started 2024-01-15T09:00+01:00 --dry-run

# Attachments
jira issues attachments MYAPP-123
jira issues attach MYAPP-123 --file ./design.png --file ./spec.pdf
jira issues attach MYAPP-123 --file ./design.png --dry-run  # checks permission and size limit
jira issues download-attachment 10042 --dir ./downloads
jira issues download-attachment 10042 --dir ./downloads --force  # overwrite an existing file
jira issues delete-attachment 10042 --dry-run  # shows the attachment it would delete
jira issues delete-attachment 10042

# Links
jira issues link-types
jira issues link MYAPP-123 --to MYAPP-456 --link-type Blocks  # MYAPP-123 blocks MYAPP-456
jira issues link MYAPP-123 --to MYAPP-456 --link-type Blocks --dry-run
jira issues unlink <link-id> --dry-run  # describes the link it would remove
jira issues unlink <link-id>

# Move to sprint
jira issues move MYAPP-123 --sprint active
jira issues move MYAPP-123 --sprint "Sprint 14"
jira issues move MYAPP-123 --sprint active --board 42

# Bulk operations (use --dry-run to preview)
jira issues bulk-transition --jql 'project = MYAPP AND status = "To Do"' --to "In Progress"
jira issues bulk-transition --jql 'project = MYAPP AND status = "To Do"' --to "In Progress" --dry-run
jira issues bulk-transition --jql 'project = MYAPP AND status = "In Review"' --to Done --resolution Fixed --comment "Released"
jira issues bulk-assign --jql 'project = MYAPP AND sprint in openSprints()' --assignee me

--epic KEY resolves the instance's Epic Link custom field or native parent field using create metadata (edit metadata for updates). --parent KEY also uses epic linkage when its target is an Epic; other targets retain normal parent semantics. Metadata validates the parent/type hierarchy before creation and lists the project's subtask types when needed. --epic and --parent cannot be combined. issues update --clear-epic removes epic membership, resolving the same native or custom field. It conflicts with --epic and explicit relationship overrides. Subtasks belong under a Story or Task, not directly under an epic. Jira's Cloud and Server/DC metadata formats are supported, including older Server metadata.

Issue JSON from issues show, issues list, issues mine and search includes parent (the direct parent's key, summary and type, or null) and epic (the key of the epic the issue belongs to directly, or null). On Cloud epic is the parent when that parent sits at the epic hierarchy level. On Data Center it is the Epic Link field, so a subtask created directly under an epic shows that epic as parent with epic: null. --fields rejects names that are not output fields and lists the valid ones.

The same issue JSON carries storyPoints, the number as Jira stores it, and tables show a Points column (- when the issue is unestimated). The field is discovered from the site's field catalog: Jira Software's estimate field (named "Story point estimate" on Cloud team-managed projects) or a custom number field named "Story Points" (company-managed projects and Data Center). storyPoints is null for an unestimated issue and absent when the site has no such field, so "not estimated" and "unknown" stay apart; asking --fields for storyPoints on such a site is an error. When a site uses both fields and they disagree on an issue, the read fails rather than picking one. Pin the field your boards estimate with to settle that, or to use a differently named field:

[default]
story_points_field = "customfield_10016"   # `jira fields list --custom` shows IDs

issues update --type changes an issue's type by name or ID within one hierarchy level, for example Task to Story. Jira applies it only when both types share a workflow and field configuration. Changing a subtask into a standard issue (or back), or moving across hierarchy levels such as Story to Epic, is refused: the Jira edit API cannot do it, so use More > Move in the Jira web UI. On Data Center the flag needs Jira 9.10.0 or later, because older releases accept an incompatible type change and leave the issue in an invalid workflow state. Data Center has no hierarchy levels, so Jira Software is asked whether the issue is an epic, and a target type counts as an epic when its create screen carries the Epic Name field. A renamed epic type whose create screen lacks Epic Name is therefore not recognized as a target. Combined with --epic, epic eligibility is checked against the new type.

Priority matching uses the allowed values for the project and issue type, or the existing issue's edit metadata. Exact names and IDs take precedence, then case-insensitive names, labels with a numeric rank removed (Medium matches 3 - Medium), and unique prefixes (Med). Invalid or ambiguous input lists the valid choices without creating or updating an issue. Creation also resolves issue type names case-insensitively or by ID. Omitting --priority keeps Jira's default. If metadata endpoints are unavailable, names are passed through to Jira and validation errors include guidance; explicit --field values retain their override behavior. Epic linkage requires a discoverable field or native Cloud parent support.

Components and fix versions accept exact names, IDs, case-insensitive names, and unique prefixes from create/edit metadata. Invalid or ambiguous values list valid options before writing. Required fields without a server default must be provided when creating an issue. Updates leave omitted fields untouched and reject explicit clears of required fields. --field ID=VALUE can supply required custom values. Unavailable metadata endpoints retain the existing pass-through behavior; authentication and server failures are still reported.

User fields given through --field (such as reporter, or a custom user picker) accept a username or account ID, an e-mail address, or me, and are sent as the user object Jira expects: {"name": ...} on Data Center and {"accountId": ...} on Cloud. An e-mail must match exactly one user. JSON objects are sent unchanged. The fields are recognised from field metadata, and assignee and reporter are recognised even when metadata is unavailable. When a project requires a reporter and has no default, create sets it to you, as Jira's own create screen does.

Other --field values are checked against the field's type before anything is written, so --dry-run catches them too. Numbers must be numbers, dates use YYYY-MM-DD, and select-list, version, component and priority values are matched against the allowed options (--field customfield_10030=Blue). A single value for a list field becomes a one-item list, and on Cloud text for a rich-text field is converted to ADF. JSON objects skip these checks.

--assignee none and --assignee unassign explicitly leave a new issue unassigned or clear an existing assignee. Omitting the flag preserves Jira's create default or the existing assignee. These aliases also work with issues assign. --assignee on create, update, assign and bulk-assign takes the same user forms as user --field values: me, an e-mail address, or a username or account ID.

issues transition and bulk-transition check --field, --resolution and --comment against the transition screen. Field names or IDs must be on the screen, values are typed as above, and required screen fields that are neither given, defaulted nor already set on the issue are reported before the transition is sent. A transition without a screen takes no fields. When the screen has no comment field, the comment is added after the transition and the command says so; if only that comment fails, the error says the transition was applied, and bulk results mark it phase: "comment".

On issues create, issues update, and issues move, sprint names and active are scoped to the issue project's Scrum boards. --board ID overrides this scope. Exact names win over substring matches; multiple matches list sprint and board IDs instead of picking one. Numeric sprint IDs identify a sprint directly; if --board is also supplied, membership on that board is checked.

Creation and updates resolve the sprint and check that it is active or future before writing issue fields. Combined field-and-sprint updates also check Schedule Issues permission when Jira exposes it. Jira can still reject the final move for other reasons. If a sprint move after a create or field update fails, the CLI exits with code 8 and error kind partial_success. JSON stderr includes error.details.key, url, created, updated, sprintId, sprintMoved, and recoveryCommand. The error is not retryable as a whole: use the returned jira issues move KEY --sprint ID command to finish the operation. Rerunning issues create would create a duplicate. issues show reports the sole current sprint in sprint and all current and historical sprint values in sprints; the text view labels current and past sprints. If Jira's field catalog is unavailable, the issue still displays and JSON warnings explains why sprint data could not be loaded (and epic data on Data Center, and story points unless story_points_field is set). Listings without a field catalog still print, without story points and with a warning on stderr.

To check Server/Data Center sprint behavior against a real instance without writing to Jira, set JIRA_E2E_HOST, JIRA_E2E_TOKEN, and these three values for a known issue in a sprint: JIRA_E2E_SPRINT_ISSUE, JIRA_E2E_SPRINT_ID, JIRA_E2E_SPRINT_BOARD. Then run cargo test --test e2e e2e_data_center_sprint_issue_smoke -- --exact.

Projects

jira projects list
jira projects show MYAPP
jira search 'project = MYAPP AND sprint in openSprints() ORDER BY priority'
jira search 'assignee = currentUser() AND status != Done' --limit 20
jira search 'project = MYAPP' --all                       # fetch every page

Write previews and bulk outcomes

Create and update previews include the exact normalized fields payload; move previews identify the resolved sprint. steps lists the planned writes in order, including the sprint move after creation. Previews share the real write's normalization and preflight validation. Jira can still reject a later write because permissions, workflow or plugin validators, or server state changed. metadata and warnings identify checks that could not be completed.

issues create-meta lists types when --type is omitted. With a type it returns the create screen's field definitions, including required fields, defaults and allowed values, plus epic support. fields: null means the fields were not requested or could not be discovered; warnings distinguish the latter. Epic support describes evidence from that screen; when metadata is unavailable, a write can still attempt the documented instance fallback. Unsupported create-meta endpoints return error details with reason: "unsupported" after confirming the project exists. allowedValues: null means unknown, while [] means no allowed values.

Transitions accept an exact ID, a case-insensitive action name, or a case-insensitive destination status, in that order. Ambiguity is an error; the structured error details list candidates and a discovery command.

Bulk commands emit a summary even for zero matches. Any per-issue failure returns exit 9 (bulk_failure); stdout still contains the full summary. total = succeeded + ready + failed + notAttempted, where ready counts dry-run entries that passed available checks and succeeded counts completed writes. Assignment previews check, per issue, that you may assign it and that the assignee is assignable; transition previews resolve the transition and check its screen fields for each issue. Issue-local failures do not discard or replay completed work. Authentication/permission, rate-limit, network, and server failures stop further requests and mark the remaining issues notAttempted. Each failure includes errorKind and retryable, plus the failed phase (lookup, write, or comment when a transition succeeded but its follow-up comment did not). Write timeouts, connection failures, and server errors are marked outcome: "unknown": the server may have applied the write. These count under failed because success was not confirmed; check issue state before retrying them. Never blindly rerun a partially completed bulk command.

Boards and sprints

jira boards list
jira boards list --project MYAPP
jira sprints list --project MYAPP            # current (active) sprints
jira sprints list --project MYAPP --state active,future
jira sprints list --board "MYAPP board"
jira sprints list --board 42 --state all

--project filters boards on the server. For sprint listing, a project and board filter intersect; a numeric board ID without a project is fetched directly. Kanban boards are skipped in broad discovery and rejected when they are the only boards selected by a filter. Unknown board types are queried; boards Jira explicitly reports as not supporting sprints are skipped, with messages in the top-level warnings array. Other errors still fail the command. Shared sprints appear once, with every matching board in boards; total counts unique sprints. The primary boardId/boardName is the origin board when matched, otherwise the lowest matched ID. Results and board context are ordered by ID. Repeat --state or comma-separate its values; all disables the state filter.

jira sprints show active --project MYAPP    # the running sprint with its totals
jira sprints show 87                         # by sprint ID
jira sprints show "Sprint 12" --board 42     # counted as board 42 shows it

sprints show reports a sprint with its story point and issue totals, split into to do, in progress and done by each status's category, counted the way the board's sprint views count them:

  • The board is --board, else the sprint's origin board. Its filter scopes which issues belong to the sprint.
  • Story points come from the board's own estimation field (from its configuration), so the totals match the board even when the site has several points fields or the profile pins a different one. Only when the board reports no estimation statistic does story_points_field or field discovery stand in, and a warning says so (estimation.source).
  • A board that estimates with time or issue count has no story points: the point totals are null and a warning says why. They are never reported as 0.
  • Subtasks are listed but left out of every total; totals.subtasksExcluded counts them. Unestimated issues count toward the issue totals and totals.unestimated.

Totals reflect each issue's current status and estimate. They are not the commitment at sprint start or the points completed during the sprint, which Jira's sprint report derives from issue history.

Users and fields

jira users search --query "alice"
jira fields list
jira fields list --custom                     # custom fields only

Shell completions

# Install automatically (bash, zsh, fish)
jira completions bash --install
jira completions zsh --install
jira completions fish --install

# Or redirect manually
jira completions zsh > ~/.zsh/completions/_jira

Config

jira init                    # guided setup that verifies credentials before saving
jira doctor                  # verify config, deployment, auth, projects, and write safety
jira doctor --offline        # inspect configuration without contacting Jira
jira auth status             # verify the selected credential
jira auth status --offline   # inspect local credential state only
jira profile list            # list profiles and show the active one
jira profile use work        # make work the active profile
jira profile remove old --yes
jira config show             # resolved credentials (token masked)
jira config path             # resolved config file location
jira config init             # same as jira init

Agent use

Use jira schema --command when an agent knows which operation it needs. The compact response includes that command's arguments, effects, pagination, output fields, global flags, and error contract. Use the full jira schema document only for discovery across the complete command tree.

jira schema --command 'issues list'
jira schema --command 'issues transition'
jira schema | jq '.commands[] | .name'

Argument types, enum values, conflicts_with, and requires reflect the CLI parser. Commands with previews publish their conditional contract under x-dry-run: arg, effects, and output_fields. Those fields describe the preview; the command's ordinary output_fields describe the real result. Create, update, and move also publish a complete stdout_schema covering both results. Transitions are declared non-idempotent because repeating a workflow action can trigger additional effects. Bulk commands also declare x-output-on-error so consumers know to parse stdout when the exit code is nonzero.

Read-only mode

Set JIRA_READ_ONLY=1 to block every command that writes to Jira. The CLI returns exit code 2 with a structured error for any blocked command, before it opens a connection. This is useful when giving an AI agent read access to Jira without the risk of unintended modifications.

--dry-run remains available in read-only mode for every command that has it: create, update, move, transition, assign, comment, link, unlink, log-work, attach, delete-attachment, and both bulk commands. These commands resolve and validate inputs without writing to Jira; the HTTP client also blocks write requests as a second check.

The guard covers writes to Jira, not writes to your disk: jira init, jira config init, jira config remove and jira issues download-attachment still work, because they change local files only.

jira schema lists the blocked commands under read_only.blocked_commands, so an agent can see what it is allowed to do without trying:

jira schema | jq '.read_only'

A value the CLI does not recognise (JIRA_READ_ONLY=enabled, or a typo) is rejected as a config error rather than read as "off", so a mis-set guard fails loudly instead of quietly allowing writes.

You can set it in the config file:

[default]
read_only = true

Or per-profile:

[profiles.agent]
read_only = true

When giving an AI agent access to the CLI, set the env var in the agent's configuration. For example, in Claude Code's .claude/settings.json:

{
  "env": {
    "JIRA_READ_ONLY": "1"
  }
}

Any agent that supports environment variable configuration can use the same approach.

Exit codes

Code Meaning
0 Success
1 Unexpected error
2 Bad input or config error
3 Authentication failed
4 Resource not found
5 Jira API error
6 Rate limited
7 Conflict, including a target file that already exists
8 Issue created, but sprint assignment failed; use the recovery command in the error details
9 Bulk operation has failures; parse the complete per-issue summary on stdout

A downstream that stops reading, as in jira issues list | head -5, terminates the CLI with SIGPIPE rather than any of these codes. That is what every other member of a pipeline does, and shells report it as 141.

Output flags

Flag Effect
--json Force JSON output (auto when stdout is not a TTY)
--quiet Suppress counts, confirmations, and status messages
--no-color Disable ANSI color (NO_COLOR is also honored)

These flags are available on every command. --json is a compatibility alias for --output json; use --output text to force human-readable output in a pipeline.

Development

make build          # debug build
make check          # fmt check + clippy + tests (run before committing)
make test           # unit + integration tests (wiremock, no real Jira needed; needs cargo-nextest)
make lint           # fmt check + clippy
make fmt            # auto-format
make install        # check + release build + copy to ~/.local/bin/jira

Running e2e tests

The e2e test suite runs against a real Jira instance. A Jira Data Center instance is required (Data Center license needed):

make jira-start     # start local Jira via Docker
make jira-wait      # wait until Jira is ready (~2 min on first run)

JIRA_E2E_HOST=http://localhost:8080 \
JIRA_E2E_EMAIL=admin \
JIRA_E2E_TOKEN=mytoken \
JIRA_E2E_PROJECT=TST \
  make test-e2e

make jira-stop

All e2e tests tag created issues with [e2e-auto] for easy cleanup.

CI

GitHub Actions runs fmt → clippy → nextest on Ubuntu and macOS for every push and pull request. The workflow is at .github/workflows/ci.yml.

License

MIT

Releasing

Vership owns versioning, changelog generation, release commits, and tags. See the release runbook for the verified workflow and recovery policy.

Metadata

Release files for jira-cli-rs 0.4.20

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for jira-cli-rs 0.4.20
File Size Uploaded Provenance Actions
jira_cli_rs-0.4.20.tar.gz 334.6 kB Without provenance Details for jira_cli_rs-0.4.20.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for jira-cli-rs 0.4.20
File Actions
jira_cli_rs-0.4.20-py3-none-manylinux_2_28_aarch64.whl Python 3 none Linux glibc 2.28+ ARM64 Details for jira_cli_rs-0.4.20-py3-none-manylinux_2_28_aarch64.whl
jira_cli_rs-0.4.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl Python 3 none Linux glibc 2.17+ x86-64 Details for jira_cli_rs-0.4.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
jira_cli_rs-0.4.20-py3-none-macosx_11_0_arm64.whl Python 3 none macOS 11.0+ ARM64 Details for jira_cli_rs-0.4.20-py3-none-macosx_11_0_arm64.whl
jira_cli_rs-0.4.20-py3-none-macosx_10_12_x86_64.whl Python 3 none macOS 10.12+ x86-64 Details for jira_cli_rs-0.4.20-py3-none-macosx_10_12_x86_64.whl

Total release size: 22.6 MB

Release files / jira_cli_rs-0.4.20.tar.gz

Download URL jira_cli_rs-0.4.20.tar.gz
Size 334.6 kB
Tags Source
SHA-256 checksum
How to use checksums
7bf8647013b9a34bdc92e7bd816f6bc5d2f56853db558ed1057280890b73ce55
BLAKE2b-256 checksum
How to use checksums
1d67a004f2e2e7d36a8dfddfc5b9da2291628e3d461c2d4a7615209cab8a1b80
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / jira_cli_rs-0.4.20-py3-none-manylinux_2_28_aarch64.whl

Download URL jira_cli_rs-0.4.20-py3-none-manylinux_2_28_aarch64.whl
Size 5.9 MB
Tags Linux glibc 2.28+ ARM64 Python 3
SHA-256 checksum
How to use checksums
49b7341f54ac38086106070b8451fb97c05ad4e6a8b5e9f40b16de31930925ac
BLAKE2b-256 checksum
How to use checksums
70357261cb194b85308016def1516b4b42d8bf398525dcacee8efd126d6e27b9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / jira_cli_rs-0.4.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL jira_cli_rs-0.4.20-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 6.4 MB
Tags Linux glibc 2.17+ x86-64 Python 3
SHA-256 checksum
How to use checksums
3005b035efc8a496ac40ea4f60dd8e280a4ef23725e601611ae5360870c9d5ea
BLAKE2b-256 checksum
How to use checksums
5ba3b0f60a42698d1a4bc583b09f347b553615b57f0a0a6ab7e5e9795991c103
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / jira_cli_rs-0.4.20-py3-none-macosx_11_0_arm64.whl

Download URL jira_cli_rs-0.4.20-py3-none-macosx_11_0_arm64.whl
Size 4.8 MB
Tags Python 3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
88eebb05656a0542c37d25d7a613656624b61acc7becbb4df1502922aab644b7
BLAKE2b-256 checksum
How to use checksums
3785851c6354f7f6a620da7626818ea0ddf585ba467de238a9ce9497fdc1e256
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / jira_cli_rs-0.4.20-py3-none-macosx_10_12_x86_64.whl

Download URL jira_cli_rs-0.4.20-py3-none-macosx_10_12_x86_64.whl
Size 5.2 MB
Tags Python 3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
623d1a80283084ebf828608fb00b01e4f680df92ee33289c33efea97ac311028
BLAKE2b-256 checksum
How to use checksums
898cc1fb171119d6a613fc95b7a7e44477a54c17d9bcf0548c9d1033706b9657
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.4 {"installer":{"name":"uv","version":"0.13.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for jira-cli-rs 0.4.20

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page