tools/jira-patch/
Capability: contract:change-request
Kind: implementation
Vendor: Atlassian
Organization: ASF
JIRA-patch change-request adapter — the backend that lets a
JIRA-tracker, SVN-hosted project drive the pr-management-* skills
over patches attached to JIRA issues instead of GitHub pull
requests. It implements the tools/change-request/
contract for projects whose proposed changes arrive as a .patch
file on a JIRA issue and are committed to an SVN trunk.
This adapter owns the proposal lifecycle (the JIRA issue + its
attached patch + its comment stream); it does not own the commit.
Its land verb delegates the actual apply-and-commit to the project’s
contract:source-control adapter — svn patch
followed by svn commit against svn.apache.org — and then records
the landed revision back on the JIRA issue. This split is why
change-request and source-control are separate contracts: on an
SVN-first project the review gate (JIRA) and the commit substrate
(SVN) are two different systems.
The read/write JIRA plumbing is the existing tools/jira/
tracker bridge (JQL search, comment, transition, label,
attach). This adapter adds the change-request semantics on top of
those verbs; it does not re-implement the JIRA REST client.
Prerequisites
- Runtime: Bash — doc-only adapter; skills invoke the
tools/jira/bridge and thetools/asf-svn/recipes, no local package of its own. - CLIs: the
jirabridge (JIRA REST overcurl) andsvn(for the delegatedland). - Credentials / auth: JIRA API token for the project’s Atlassian
site (read for
list_open/get/get_discussion, write forpost_review/reject), plus ASF committer credentials for the SVN commit thatlanddelegates totools/asf-svn/. The adapter never commits under its own identity — it uses the running committer’ssvnauth, exactly as a manualsvn commitwould, so patch-author-vs-committer attribution is preserved (see Attribution). - Network: the project’s JIRA host (e.g.
issues.apache.org/jira) andsvn.apache.orgfor the delegated land.
What this maps
The JIRA-patch backend resolves the change-request as: a JIRA issue
carrying a patch attachment is one change proposal. The issue key is
the proposal id; the newest .patch/.diff attachment is the diff;
the issue’s comment stream is the review discussion.
Operations
Each change-request verb resolves onto the JIRA + SVN surfaces as follows. The verb names are the contract’s; the right column is this adapter’s concrete resolution.
| Verb | JIRA-patch resolution |
|---|---|
list_open(filter) |
JQL: project = <KEY> AND status = Open AND attachments IS NOT EMPTY (plus the filter’s author/component/age narrowers), via jira search. One proposal_summary per issue that carries a patch attachment. |
get(id) |
jira issue <KEY> for metadata; download the newest .patch/.diff attachment for the diff. base is the trunk path from change_request.jira_patch.trunk_url; commits is [] (a bare patch has none); mergeable is unknown until an svn patch --dry-run is run. |
get_discussion(id) |
The issue’s comment stream, normalised to {author, date, body, kind}. A comment carrying the configured approval token maps to kind: approval. |
post_review(id, verdict, body) |
jira comment <KEY> --body-file <draft>; the verdict is additionally encoded as a jira transition / jira label move (approve → Reviewed, request-changes → Needs work). |
land(id, strategy) |
Delegates to contract:source-control. Fetches the patch via get, calls the source-control adapter’s apply + commit (svn patch <file> then svn commit against the trunk working copy — see tools/asf-svn/source-control.md), then transitions the issue to Resolved/Fixed and comments the landed revision. strategy is advisory — SVN applies a patch as a single commit, so squash is the only honoured strategy and the adapter reports that. |
reject(id, reason) |
jira transition <KEY> "Won't Fix" (or the configured rejected transition) with reason as a closing comment. No commit — the absence of a land is the rejection. |
status(id) |
checks: none, mergeable from an svn patch --dry-run (clean / conflicting). JIRA has no CI gate unless a pipeline is wired to the issue; skills degrade the checks gate to advisory (see the contract’s status graceful-degradation note). |
Attribution
The delegated land preserves patch-author vs. committer
attribution the way ASF SVN commits always have: the svn commit
runs under the landing committer’s identity, and the commit message
credits the patch author (Patch by <author>. / This closes #<KEY>.
per the project’s convention). The adapter reads the patch author
from the JIRA issue reporter / attachment uploader and templates it
into the commit message; it never impersonates the author’s SVN
identity. This is the answer to #669’s “patch-author vs. committer
attribution” open question for the JIRA-patch backend.
Configuration
Declared under the change-request block in
projects/<project>/project.md:
change_request:
backend: jira-patch
land_via: source-control # land delegates to the VCS adapter
review_channel: jira-comment
default_strategy: squash # SVN applies a patch as one commit
jira_patch:
site_url: https://issues.apache.org/jira
project_key: <KEY> # the JIRA project the proposals live in
trunk_url: https://svn.apache.org/repos/asf/<project>/trunk
approval_token: "+1" # comment token that counts as an approval
rejected_transition: "Won't Fix"
resolved_transition: "Resolved"
site_url/project_key— locate the JIRA project whose patch-bearing issues are the proposals.trunk_url— the SVN trunk the delegatedlandapplies the patch to.approval_token— the comment stringget_discussionreads as akind: approval.rejected_transition/resolved_transition— the JIRA workflow transitionsrejectandlanddrive.
Backend-specific keys live under change_request.jira_patch.*; the
generic keys (backend, land_via, review_channel,
default_strategy) are the contract’s.
Cross-references
- Contract:
tools/change-request/ - JIRA REST plumbing:
tools/jira/ - Delegated land:
tools/asf-svn/source-control.md - Issue: #669