Skip to content

feat(adf): render Jira's document format as Markdown - #39

Merged
Bakhomious merged 1 commit into
mainfrom
step/adf
Nov 4, 2026
Merged

Bakhomious merged 1 commit into
mainfrom
step/adf

Conversation

@Bakhomious

Copy link
Copy Markdown
Contributor

Step adf (plan row 62): the first half of the Jira work. internal/adf renders the Atlassian Document Format (ADF), the JSON in which Jira's REST API v3 gives a ticket's description and comments, as Markdown for the orchestrator and the user to read.

What changes

  • adf.Markdown(node) walks a document's nodes. A run of inline nodes makes one block, blocks stand a blank line apart, and an empty block makes none.
  • Inline text: strong, em, strike and code, with code innermost and a link outermost ([**the docs**](…)). Other marks, such as underline and colours, leave the text plain. Code that holds backticks gets a longer fence, and a backtick at either end gets a space inside the fence.
  • Inline nodes: mentions, emoji, statuses, cards, placeholders and inline extensions show their text or their address. A hard break makes a new line. A date shows its day in UTC, as Atlassian's renderer does; its timestamp is in milliseconds, though the docs' example reads as seconds (fact 39). A file or an image becomes [attachment: <alt or url>], or [attachment].
  • Fail-soft: a node without a rule of its own shows its content, or the text that stands in for it. So nothing of a ticket gets lost, a node that a later ADF adds included, and this step's output already holds every word of the blocks that adf-blocks will format.
  • Docs:

Flagged: decision 57 (lead's call)

  • The Markdown is for reading, not for a renderer, so the text stays as Jira has it, with no escapes; only a | in a table's cell will get one (adf-blocks).
  • The converter came to about 240 lines, so it comes in two steps: this one, about 150 lines, and adf-blocks (headings, lists and task lists, code blocks, quotes and panels, rules, tables and expands), ahead of jira.

Checks

  • mise run check: green. Coverage 99.4%; internal/adf 100%.
  • Golden tests: three ADF documents in testdata, each beside the Markdown that it should make. Their node set and attributes follow ADF's JSON schema (@atlaskit/adf-schema). TestMain puts the tests in a zone east of UTC, so that a date shown in the machine's zone fails them in CI too, which runs in UTC.
  • Mutation probes: 51 mutants, all caught. They cover the block walk, inline runs and each of the ten inline types, the stand-in text and its order, the marks and their order, the code fence and its padding, dates (seconds and the local zone, the latter under TZ=UTC too), and attachments.
  • Smoke run: a made-up ticket, with a heading, a list, a code block, a panel, an image and a table, rendered through a throwaway test. Every word came through. The blocks that adf-blocks will format show as plain paragraphs for now.

Not in this PR

  • adf-blocks and jira (baton jira <KEY>, the token in the Keychain).
  • Two nudge asks are open for jira: the Keychain read's G204 handling, and a live check against one real ticket. Neither blocks adf or adf-blocks.

internal/adf turns the Atlassian Document Format, the JSON of a Jira
ticket's description and comments, into Markdown for the orchestrator
and the user to read: the walk over a document's nodes, and the inline
text with its marks, mentions, emoji, dates, cards and attachments.
A node without a rule of its own shows its content, or the text that
stands in for it, so the blocks that adf-blocks adds already come
through as plain text.

Decision 57 and fact 39 in docs/plan.md; the Jira row becomes adf,
adf-blocks and jira.
@sonarqubecloud

sonarqubecloud Bot commented Nov 4, 2026

Copy link
Copy Markdown

@Bakhomious
Bakhomious merged commit cd344cc into main Nov 4, 2026
3 checks passed
@Bakhomious
Bakhomious deleted the step/adf branch November 4, 2026 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant