Using JIRA with SpecShip: a step-by-step walkthrough
Hands-on, start to finish: connect your board, pick a ticket into a spec, publish it back as a Story with Sub-tasks, implement it behind the plan gate, and let the board move itself to In Review and Done — then the advanced knobs: transition control, workflow validation, release stamping, corporate TLS, and headless secrets.
The other JIRA post explains why SpecShip routes a ticket through a spec instead of straight into the model. This one is the hands-on version: a start-to-finish walkthrough of driving a real ticket to a merged, linked, test-passing pull request — starting from nothing, and ending with the advanced knobs. Follow it top to bottom the first time; after that, each step stands alone.
You'll do it in two registers. Most of the loop is agent-native — you ask Claude Code in plain language and it calls the specship_jira_* MCP tools. A few pieces are terminal commands you run yourself: connecting, verifying, transitioning, releasing. Both talk to the same local, secret-safe client.
specship init), the integration enabled (specship install --with-jira), and a JIRA account. Everything below is scoped to a solo-dev loop: one issue at a time, and the two irreversible calls — marking an issue Done and merging the PR — always stay yours.Step 1 — Connect once, and locally
Point SpecShip at your JIRA instance. Credentials are written to ~/.specship/jira.json (mode 0600, user-level, never in the project), so nothing can ride into a commit. Cloud authenticates with an email + API token; Data Center / Server uses a personal access token. SpecShip infers the deployment from what you give it.
# JIRA Cloud specship jira configure --base-url https://acme.atlassian.net --email you@acme.com --api-token <token> # JIRA Data Center / Server specship jira configure --base-url https://jira.internal --pat <token> # verify — prints "connected as <name>", never the token specship jira test
specship jira test does two jobs now: it confirms the connection and checks the lifecycle transition names you'll rely on later (more on that in Step 6). On success it prints connected as <your name> — the token is never echoed back.
Step 2 — Find your work, and pick a ticket
Ask Claude Code what's on your plate. "Assigned to me" resolves from your token — you never type your name.
# in a Claude Code session: "list my JIRA issues" # → specship_jira_issues "show me PROJ-142" # → specship_jira_issue (read it in full) "pick PROJ-142" # → specship_jira_pick
Pick is the pivot. It turns raw ticket text into a contract: the issue's summary becomes the spec title, its description becomes the body, and its sub-tasks become acceptance criteria. What lands under specs/ is a well-formed spec that indexes into the graph like any other — a reviewable body, independently-checkable criteria, and (once built) a link to the exact code that satisfies it. Re-picking the same key updates the spec in place; it never forks.
Step 3 — Publish the spec back to JIRA
Picking pulls a ticket in. Publishing pushes an authored spec back out — the reverse direction, and new in this release. specship_jira_publish creates a JIRA Story from the spec whose Sub-tasks mirror the acceptance criteria, then writes the new issue key into the spec's frontmatter so every branch, PR, commit, and tracking view carries it. It's idempotent: re-publishing an already-keyed spec updates the Story and creates only the missing Sub-tasks — never a duplicate.
# turn an authored spec into a Story + Sub-tasks in JIRA "publish REQ-CHECKOUT-001 to JIRA" # → specship_jira_publish
If you haven't set a default project, SpecShip shows the projects your account can actually access and lets you choose — during specship jira configure --project, or as a pick-list at publish time. This step is optional: if you started from pick (a ticket already exists), you can skip straight to Step 4. Publish is for specs you authored in the repo first and want mirrored onto the board.
Step 4 — Implement it, behind the plan gate
start hands the spec to the bundled spec-implement workflow — plan, approve, implement, verify, link — in an isolated git worktree, pausing at the plan/approve gate before a single line is written.
# start the workflow — pauses at the plan gate "start PROJ-142" # → specship_jira_start # review the plan, then approve to proceed specship workflow approve <run-id>
gh — the issue key on the branch, title, and body, so JIRA's development panel links it back. A run whose tests fail raises no PR. It's never auto-merged or auto-closed.Step 5 — Watch the board move on its own
You don't touch JIRA during any of this — SpecShip writes status at the moments that matter. On start it assigns the issue to you and moves it toward In Progress. On PR raised it moves toward In Review and comments the PR link. And as you verify acceptance criteria, each proven criterion advances its published Sub-task toward Done — and the Story itself advances once every Sub-task is done. A spec that later drifts posts a one-time comment on its issue, so the board notices when code moves out from under a ticket.
# where does every picked/published issue stand? (live JIRA read) "track my JIRA issues" # → specship_jira_track specship jira track # …or from the terminal
track joins each issue's local SpecShip work-state with a fresh JIRA status read, and flags any published spec that was edited in JIRA after publishing — so a spec and its mirror can't silently diverge.
Step 6 — Advanced: transitions your workflow can actually fire
Every JIRA project has a different workflow. SpecShip's status write-back is skip-tolerant by design — a transition your workflow doesn't offer is reported and skipped, never forced. But a silent skip is easy to miss, so two things make the workflow visible and controllable.
First, specship jira test now validates your configured lifecycle names against a real issue and tells you which ones the workflow can't fire:
$ specship jira test ✓ Connected to JIRA Cloud as Ada Lovelace. ℹ Configured transitions (checked against PROJ-142; available: To Do, In Progress, Done): ℹ ✓ inProgress "In Progress" ⚠ ✗ inReview "In Review" — not offered from PROJ-142's current state ℹ ✓ done "Done"
Second, specship jira transition moves an issue to any state its workflow offers — or lists the options when you omit the target. A state the workflow can't reach is reported with the available states instead of applied, so nothing is written by mistake.
# list what this issue can transition to right now specship jira transition PROJ-142 --list # move it (a target the workflow lacks is reported, not applied) specship jira transition PROJ-142 "Done"
Point the configured names at states your project actually has — set transitionInProgress / transitionInReview / transitionDone in ~/.specship/jira.json, or the matching SPECSHIP_JIRA_TRANSITION_* environment variables. If your board has no "In Review" state, point inReview at one it does (or add the state in JIRA) so completion advances visibly instead of skipping.
Step 7 — Advanced: stamp a release onto the board
When the work ships, record it on the tickets. specship jira release sets a version as the fixVersion on each issue — creating the project version if it doesn't exist — and adds a one-line "shipped in" comment. Re-running it is a no-op: no duplicate version, fixVersion, or comment.
# default: every published spec's issue key under specs/ specship jira release 1.4.0 # or an explicit set specship jira release 1.4.0 --keys PROJ-142,PROJ-143 --project PROJ
Step 8 — Advanced: headless, corporate TLS, and secrets
For CI and secret managers, every field has an environment override — SPECSHIP_JIRA_BASE_URL, SPECSHIP_JIRA_EMAIL, SPECSHIP_JIRA_API_TOKEN, SPECSHIP_JIRA_PAT, SPECSHIP_JIRA_DEPLOYMENT, SPECSHIP_JIRA_PROJECT, and SPECSHIP_JIRA_CONFIG — so you can run without any credentials file on disk. An env var overrides the stored value, per field.
Enterprise Data Center instances often sit behind a certificate your machine doesn't trust. Point SpecShip at your corporate CA bundle (preferred) or, as a last resort on a trusted network, disable verification — both scoped to JIRA requests only:
# preferred: trust your corporate CA (PEM) for JIRA requests only specship jira configure --base-url https://jira.internal:8443/jira --pat <token> --ca-cert /path/corporate-ca.pem # last resort, trusted networks only (prints a warning) specship jira configure --base-url https://jira.internal:8443/jira --pat <token> --insecure-tls
The token is never logged, printed, or echoed into any output, error, JIRA comment, or the graph. Every request is host-locked to your base URL and refuses a redirect to a different host. The closest you get to seeing it is connected as <name>.
The whole loop, on one screen
That's the full range — from a first configure to release stamping. In practice a normal day is three lines: pick a ticket, start it, approve the plan; the board moves itself and a linked, test-passing PR is waiting. Everything else — publish, transitions, release, TLS — is there when you need it and out of the way when you don't.
"pick PROJ-142" # ticket → spec "start PROJ-142" # plan gate → approve → implement → verify # …a linked, test-passing PR is waiting; the board is already In Review.
The last word — Done, and merge — is always yours.