Jira
Read Jira Cloud issues into a workspace by site and project, and write back as the person who connected Jira.
The Jira collector is not available yet. This page describes how it works once Oxagen turns it on.
Account to connect with
An organization Owner, or a workspace Admin, signs in to Atlassian with OAuth 2.0 (3LO) and picks the Jira Cloud site. The grant acts as that person, so every write shows in Jira under their name. Use a person whose Jira permissions match what you want Oxagen to write. Jira Server and Data Center are not supported.
The sign-in needs JIRA_OAUTH_CLIENT_ID and JIRA_OAUTH_CLIENT_SECRET. The same secret checks each webhook delivery, so Oxagen refuses deliveries while the secret is unset.
Scopes asked for
| Scope | Asked | Used for |
|---|---|---|
read:jira-work | Always | Reading issues, comments, and transitions |
read:jira-user | Always | Reading the account the token acts as, including its time zone |
manage:jira-webhook | Always | Registering, extending, and deleting the collector's webhook |
offline_access | Always | A refresh token |
write:jira-work | Only when the person turns on writing | Comments, transitions, and field updates |
Atlassian offers no way to revoke the grant from Oxagen. Remove the app in your Atlassian account to end it.
Scope choices
A collector names one site by its cloud id, one or more projects by key, and an optional JQL filter.
# work/collectors/jira-eng.toml in the steering repo
schema = "collector/v1"
name = "jira-eng"
label = "Jira engineering"
type = "jira"
connection = "<connection id>"
[scope]
site = "0a1b2c3d-0000-4000-8000-000000000000"
projects = ["ENG", "OPS"]
jql = "labels = oxagen"
siteUrl = "https://acme.atlassian.net"
repos = ["acme/app"]
create_project = "ENG"- The scope step lists the sites the connection reaches, then the projects on the site you pick.
- The JQL narrows the projects further. It may not contain
ORDER BY, because Oxagen sorts the read itself, and its parentheses must close. siteUrlis optional. Oxagen uses it for links to each issue.reposis optional. It names the linked repositories whose work items this collector creates issues for. Without it the collector creates no issue.create_projectnames the project the issues go to. Leave it out only when the scope names one project. Until the collector settings page shows these fields, set them in the collector file or withset_work_collector.- An issue is identified by its id, never its key, so an issue keeps its Oxagen item when it moves between projects. An issue that moves out of scope stops being read.
Default field mapping
A workspace with no Jira rows gets these. They use Jira's status categories, which every workflow shares.
| Oxagen | Reads from Jira | Writes to Jira |
|---|---|---|
| Status Open | Status categories To do and In progress | A transition to a status in the To do category |
| Status Closed | Status category Done | A transition to a status in the Done category |
| Resolution Done | Resolutions Done and Fixed, or status category Done when no resolution is set | Resolution Done |
| Resolution Won't do | Resolutions Won't Do, Won't Fix, Cannot Reproduce, or a status named Won't Do | Resolution Won't Do |
| Resolution Duplicate | Resolution Duplicate, or a status named Duplicate | None |
| Resolution Canceled | Resolution Declined, or a status named Declined | None |
| Priority P0, P1, P2, P3 | Highest, High, Medium, Low (Lowest also reads P3) | The same priorities |
| Type Bug, New Feature, Improvement | Issue types Bug, New Feature and Story, Improvement | Labels bug, feature, improvement |
| Type Documentation, Test, Chore | Labels documentation, test, chore | The same labels |
What each switch writes
| Switch | Jira call | Result |
|---|---|---|
certify_note | Add comment | An internal comment in Atlassian Document Format |
send_note | Add comment | An internal comment about the send |
status | Transition | Lists the issue's transitions and takes the one whose target is the mapped status or status category, then sets the mapped resolution when the transition's screen has that field |
close | Transition | The same as status, to the Done category with the Done resolution |
labels | Edit issue | Sets the priority and swaps the Type label, keeping every unrelated label |
create | Create issue, then add attachment | Creates the issue in create_project with the mapped priority and labels, then uploads each file |
text | Edit issue | Sets the summary and description a person edited in Oxagen |
badge | None | Writes nothing. A Jira description is not Markdown, so a Jira issue gets no work item badge |
A comment is marked internal. In a Jira Service Management project it stays off the customer portal, so Oxagen never replies to a requester. A project with no transition to the mapped status fails as status_unreachable.
A create sets the issue type the item's Type label reads from, where the project has it, and Task otherwise. It keeps the work item's marker in an issue property named oxagen, so a retry finds the issue an earlier try made. A create screen that asks for a field Oxagen does not fill fails as mapping_missing. A label with a space stays in Oxagen, because a Jira label cannot hold one.
What the tracker cannot do
- Jira has no transition that works from every status. A workflow that blocks the move fails the write as
status_unreachable, and Oxagen does not try another route. - A resolution is set only when the transition's screen has the resolution field.
- Jira search is eventually consistent. Oxagen lists the issues it wrote in the last few minutes by id so a fresh write does not read as a stale change.
- JQL compares dates to the minute in the time zone of the account the token acts as. Oxagen reads that zone and starts each read a minute early.
- Oxagen writes a summary or a description only for an issue it creates, and for a person's edit in Oxagen. It never deletes an issue and never assigns anyone.
- A description is written as plain paragraphs. Markdown formatting shows as text.
Webhook and reconcile timing
Oxagen registers one dynamic webhook for each collector, filtered by JQL to the collector's projects. Jira locks each delivery with a JWT made with the app's client secret, so Oxagen can check that it came from Jira unchanged. The webhook arrives within seconds of a change. It names only the issue id, and Oxagen reads the issue from the API.
Jira drops a dynamic webhook 30 days after it is made or last extended. The 15-minute reconcile extends it when fewer than three days remain.
A reconcile every 15 minutes reads the issues changed since its cursor. Jira allows five dynamic webhooks for each app, user, and site. A sixth Jira collector on one connection gets no webhook and relies on the reconcile alone.
If a webhook lapses, the reconcile is still the reader, so a change arrives within about 15 minutes.