update-jira-ticket について
現在のブランチと関連する JIRA チケットを照合し、説明文やコメントの更新案を作成するスキルです。開発者が内容を確認して承認した後、Atlassian CLI で反映します。
主な機能
- 01ブランチ名から JIRA ID を抽出
- 02チケットとブランチの変更を比較
- 03説明文の修正やコメントを提案
- 04承認済みの更新を Atlassian CLI で反映
活用シーン
- 01チケットに不足する実装要件の記録
- 02対象外の変更をコメントで記録
- 03実装上の判断後にチケットを更新
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ morphet81/ cheat-sheets --skill update-jira-ticketインストール後、Claude Code で/update-jira-ticketを入力して読み込まれたか確認します。
詳細
現在のブランチに関連付けられた JIRA チケットと実際に行われた変更を比較し、チケットの内容を正確に保つための更新を提案します。不足している情報があれば説明を編集し、関連のない変更や実装上の決定事項があればコメントを追加します。または、その両方を行います。
使い方:
/update-jira-ticket- ブランチの変更を分析し、JIRA チケットの更新を提案します
手順:
-
前提条件を確認します:
- Atlassian CLI(
acli):acli auth statusを実行し、CLI がインストールされ、認証済みであることを確認します。- コマンドが見つからない場合、次のメッセージを表示して停止します:
## 前提条件の不足:Atlassian CLI `acli` コマンドがインストールされていません。このスキルでは、JIRA の課題の詳細を取得および更新するために Atlassian CLI が必要です。 次のコマンドでインストールしてください:brew tap atlassian/acli && brew install acli - コマンドが認証エラーで失敗した場合、次のメッセージを表示して停止します:
## 前提条件の不足:Atlassian CLI の認証 Atlassian CLI が認証されていません。このスキルを使用する前に、`acli auth login` を実行して認証してください。
- コマンドが見つからない場合、次のメッセージを表示して停止します:
- Atlassian CLI(
-
現在のブランチ名から JIRA ID を抽出します:
git branch --show-currentを実行して現在のブランチ名を取得します[A-Z][A-Z0-9]+-[0-9]+のパターン(例:PROJ-123、AB-1、MYAPP-4567)に一致する値を抽出し、JIRA ID とします- JIRA ID はブランチ名のどこにあってもかまいません(例:
fix/PROJ-123、feat/PROJ-123、PROJ-123-some-description) - 大文字と小文字を区別せずに一致させ、抽出した ID は JIRA API で検索する前に大文字に正規化します
- JIRA ID が見つからない場合、次のメッセージを表示して停止します:
ブランチ名に JIRA ID が見つかりません:"<current-branch>" JIRA ID を含むブランチ名が必要です(例:fix/proj-123、feat/MYAPP-456)。
-
JIRA チケットを取得します:
- Atlassian CLI を使用して、JIRA ID で課題を取得します:
acli jira workitem view <JIRA-ID> --fields '*all' --json - 利用可能なすべてのフィールド(要約、説明、課題タイプ、優先度、コメント、受け入れ条件、カスタムフィールドなど)を解析します
- 比較の基準として、元の説明を保存します
- 取得に失敗した場合、エラーを表示して停止します
- Atlassian CLI を使用して、JIRA ID で課題を取得します:
-
ベースブランチを特定します:
- 現在のディレクトリに
.agentファイルがあるか確認します - ファイルがある場合は読み込み、
baseBranch=<value>の行を探してベースブランチを取得します .agentファイルがない場合、またはbaseBranchキーがない場合は、mainをデフォルトとして使用します
- 現在のディレクトリに
-
ブランチの変更を分析します:
git log <base-branch>..HEAD --onelineを実行して、このブランチのコミット履歴を取得しますgit diff <base-branch>...HEAD --statを実行して、変更されたファイルの概要を取得しますgit diff <base-branch>...HEADを実行して、差分全体を取得します- 変更された主要なファイルを読み、変更の内容を把握します
- 次の内容を包括的に把握します:
- 実装された内容 — 新機能、バグ修正、リファクタリングなど
- 実装方法 — 技術的なアプローチ、使用されたパターン、重要な決定事項
- 元のスコープを超えて変更された内容 — チケットの説明から追加、調整、逸脱した内容
-
変更内容をチケットの説明と比較します:
重要な変更または実装の側面ごとに、次の 3 種類のいずれかに分類します:
a) 説明に不足 — 説明を編集:
- チケットに記載されているべきだったが、記載されていなかった情報(例:実装された受け入れ条件の不足、実装中に判明した未文書化の要件、暗黙的だったが明示すべきスコープ)
- 文書化と追跡のために、この情報を含むよう説明を編集します b) チケットと無関係 — コメントを追加:
- チケットの作業と併せて行われたものの、チケットの範囲外である変更(例:機会を捉えたリファクタリング、隣接するコードへの小規模な修正、依存関係の更新)
- 説明欄を無関係な内容で埋めることなく、チケットの履歴に実施内容を残せるよう、これらはコメントとして記録してください
c) 実装上の判断 — 説明欄を編集し、コメントを追加:
- チケットに影響する、意図的な技術上またはプロダクト上の判断を伴う変更(例:アプローチ B ではなくアプローチ A を選択、技術的な制約に基づく受け入れ条件の調整、実装中に合意したスコープの調整)
- 最終状態が反映されるよう説明欄を更新し、判断の理由を説明するコメントを追加してください
以下の変更は何も記録せずスキップしてください:
- 現在の説明欄にすでに正確に反映されている変更
- チケットの記録としての価値に影響しない、些細な実装の詳細(例:変数名、軽微な書式設定)
-
編集案の一覧を準備する:
提案する変更をすべて、操作の種類ごとにグループ化して番号付きリストで提示します:
## Proposed JIRA Ticket Updates for <JIRA-ID> ### Description Edits These changes update the ticket description to reflect the actual implementation. **#1** — <Brief title of the edit> - **Reason:** <Why this edit is needed> - **Change:** <What will be added/modified in the description> **#2** — <Brief title> - **Reason:** <Why> - **Change:** <What> ### Comments to Add These document changes that don't belong in the description. **#3** — <Brief title of the comment> - **Reason:** <Why a comment is appropriate here> - **Content:** <The comment text to be added> ### Description Edits + Comments These require both a description update and a comment explaining the decision. **#4** — <Brief title> - **Reason:** <Why both are needed> - **Description change:** <What will be updated> - **Comment:** <The comment explaining the reasoning> ### Summary - **Description edits:** <N> - **Comments:** <N> - **Description edits + comments:** <N> - **Total updates:** <N>提案する変更がない場合(チケットの内容がすでに正確な場合)は、次のように表示します:
✅ The JIRA ticket description for <JIRA-ID> is already in sync with the branch changes. No updates needed.その後、終了します。
-
開発者の確認を得る:
AskUserQuestionを使用して、提案した更新を確認し、承認するよう開発者に尋ねます:- 「すべて適用」 — 提案した編集とコメントをすべて適用する
- 「選択する」 — 開発者が適用する項目を番号で指定する
- 「スキップ」 — キャンセルし、チケットを更新しない
「選択する」の場合:
AskUserQuestionを使用して、適用する項目の番号を尋ねます(例:「1, 3, 4」)- 選択された項目のみを適用します
-
承認された更新を適用する:
a) 説明欄の編集:
- 現在のチケットの説明欄を読み取ります
- 承認された説明欄の編集内容を、既存の説明欄の構成に自然に組み込みます
- 元の説明欄の文体、書式、構成を維持し、更新対象ではないセクションを書き直さないでください
- 説明欄を ADF(Atlassian Document Format)JSON ペイロードとして記述し、
--from-jsonを使用して更新します:
JSON ファイルには、説明欄を ADF オブジェクトとして含む編集ペイロード全体を含める必要があります(下記の ADF 形式のリファレンス を参照)。acli jira workitem edit --from-json <temp-file.json> --yes - 更新に失敗した場合はエラーを表示し、コピー可能なテキストとして説明欄の案を提示します
b) コメント:
- 承認されたコメントごとに、Atlassian CLI を使用します:
acli jira workitem comment create --key <JIRA-ID> --body "<comment text>" - 各コメントは単独で意味が通り、背景を明確に説明する必要があります
- 実装上の判断に関するコメントには、わかりやすいように「実装メモ:」を先頭に付けます
- コメントの投稿に失敗した場合はエラーを表示し、コピー可能なテキストとしてコメントを提示します
-
結果を表示する:
適用した内容の概要を表示します:
## JIRA チケットを更新しました:<JIRA-ID> ### ✅ 説明欄を更新しました - #1 — <タイトル> - #4 — <タイトル> ### ✅ コメントを追加しました - #2 — <タイトル> - #3 — <タイトル> - #4 — <タイトル>(実装メモ) ### ❌ スキップしました - #5 — <タイトル>(開発者がスキップを選択) チケット:https://<site>.atlassian.net/browse/<JIRA-ID> -
エッジケースへの対応:
- チケットの説明が空の場合、実装の詳細はすべて「説明に記載なし」として扱い、変更内容に基づいて説明全体を提案します
- ブランチにコミットがまだない場合は、「このブランチには と比較して変更が見つかりません。」と表示して終了します
- 差分が大きすぎてすべてを分析できない場合は、最も重要な変更(新規ファイル、大規模な変更)に焦点を当て、一部の軽微な変更をレビューしていないことを明記します
- JIRA の更新が一部失敗した場合(例:説明は更新されたが、コメントの追加に失敗した場合)、成功した内容と失敗した内容を報告します
- ブランチに複数のチケットの変更が含まれている場合(例:チェリーピック)、ブランチ名に一致するチケットの更新のみを提案します
ADF 形式のリファレンス
JIRA は Markdown をレンダリングしません。説明には Atlassian Document Format(ADF)(JSON ベースのドキュメント形式)を使用する必要があります。--description-file フラグはファイルの内容をプレーンテキスト文字列として扱うため、リッチな説明には使用できません。代わりに --from-json を使用してください。
重要: --from-json では、編集ペイロード全体を含む構造化 JSON ファイルが必要です。description フィールドは文字列ではなく、ADF オブジェクトでなければなりません。期待されるスキーマを確認するには、acli jira workitem edit --generate-json を実行してください。
編集ペイロードの形式(--from-json):
{
"issues": ["<JIRA-ID>"],
"description": {
"version": 1,
"type": "doc",
"content": [
{
"type": "heading",
"attrs": { "level": 2 },
"content": [{ "type": "text", "text": "Description" }]
},
{
"type": "paragraph",
"content": [
{ "type": "text", "text": "Regular text. " },
{ "type": "text", "text": "Bold text", "marks": [{ "type": "strong" }] }
]
},
{
"type": "bulletList",
"content": [
{
"type": "listItem",
"content": [
{ "type": "paragraph", "content": [{ "type": "text", "text": "List item" }] }
]
}
]
},
{
"type": "orderedList",
"content": [
{
"type": "listItem",
"content": [
{ "type": "paragraph", "content": [{ "type": "text", "text": "Numbered item" }] }
]
}
]
},
{
"type": "taskList",
"attrs": { "localId": "unique-id" },
"content": [
{
"type": "taskItem",
"attrs": { "localId": "task-1", "state": "TODO" },
"content": [{ "type": "text", "text": "Acceptance criterion" }]
}
]
},
{
"type": "codeBlock",
"attrs": { "language": "typescript" },
"content": [{ "type": "text", "text": "const x = 1;" }]
}
]
}
}
一般的な ADF ノードタイプ:
| Markdown | ADF type | 備考 |
|---|---|---|
## Heading | heading with attrs.level | レベル 1~6 |
| Plain text | paragraph with text children | |
**bold** | text with marks: [{"type": "strong"}] | |
*italic* | text with marks: [{"type": "em"}] | |
- item | bulletList > listItem > paragraph | |
1. item | orderedList > listItem > paragraph | |
- [ ] task | taskList > taskItem (state: TODO/DONE) | |
`code` | text with marks: [{"type": "code"}] | インラインコード |
| Code block | codeBlock with attrs.language | |
--- | rule | 水平線 |
[link](url) | text with marks: [{"type": "link", "attrs": {"href": "url"}}] |