Skip to content

Commit 483a665

Browse files
authored
Merge pull request #557 from gn-t-k/improve/claude/issue-556-20260223-0403
Issue/PR作成時のテンプレート準拠をhookで強制する
2 parents b938b61 + 4be9391 commit 483a665

File tree

4 files changed

+125
-1
lines changed

4 files changed

+125
-1
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/bin/bash
2+
#
3+
# PreToolUse hook: gh pr create / gh issue create のテンプレート準拠チェック
4+
#
5+
# Claude Codeのhookとして実行され、必須セクションが欠けていれば exit 2 でブロックする。
6+
# テンプレートファイルから見出しを動的に抽出するため、テンプレート変更時にこのスクリプトの修正は不要。
7+
8+
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
9+
if [ -z "$REPO_ROOT" ]; then
10+
exit 0
11+
fi
12+
13+
input=$(cat)
14+
command=$(printf '%s' "$input" | jq -r '.tool_input.command // empty')
15+
16+
if [ -z "$command" ]; then
17+
exit 0
18+
fi
19+
20+
# テンプレートファイルからMarkdown見出し行を抽出する
21+
# 引数: $1 = テンプレートファイルパス, $2 = "yaml" (YAML front matterをスキップする場合)
22+
extract_headings() {
23+
local template_file="$1"
24+
local has_frontmatter="$2"
25+
26+
if [ "$has_frontmatter" = "yaml" ]; then
27+
awk '/^---$/{count++; next} count>=2' "$template_file" | grep -E '^#{1,2} '
28+
else
29+
grep -E '^#{1,2} ' "$template_file"
30+
fi
31+
}
32+
33+
# bodyにすべての見出しが含まれているかチェックし、不足があればブロックする
34+
# 引数: $1 = テンプレートファイルパス, $2 = "yaml" or "", $3 = エラーメッセージのラベル("PR" or "Issue")
35+
validate_template() {
36+
local template_file="$1"
37+
local frontmatter="$2"
38+
local label="$3"
39+
40+
if [ ! -f "$template_file" ]; then
41+
return 0
42+
fi
43+
44+
local missing=()
45+
while IFS= read -r heading; do
46+
[ -z "$heading" ] && continue
47+
# 見出し行から # マーカーを除去してテキスト部分を取得
48+
local heading_text
49+
heading_text=$(printf '%s' "$heading" | sed 's/^#* //')
50+
if ! printf '%s' "$command" | grep -qF "$heading_text"; then
51+
missing+=("$heading")
52+
fi
53+
done < <(extract_headings "$template_file" "$frontmatter")
54+
55+
if [ ${#missing[@]} -gt 0 ]; then
56+
{
57+
echo "${label}のbodyにテンプレートの必須セクションが含まれていません。"
58+
echo "不足しているセクション:"
59+
for section in "${missing[@]}"; do
60+
echo " - $section"
61+
done
62+
echo ""
63+
echo "テンプレート内容:"
64+
if [ "$frontmatter" = "yaml" ]; then
65+
awk '/^---$/{count++; next} count>=2' "$template_file"
66+
else
67+
cat "$template_file"
68+
fi
69+
} >&2
70+
exit 2
71+
fi
72+
}
73+
74+
# gh pr create のバリデーション
75+
if printf '%s' "$command" | grep -q 'gh pr create'; then
76+
validate_template "$REPO_ROOT/.github/pull_request_template.md" "" "PR"
77+
fi
78+
79+
# gh issue create のバリデーション
80+
if printf '%s' "$command" | grep -q 'gh issue create'; then
81+
validate_template "$REPO_ROOT/.github/ISSUE_TEMPLATE/default.md" "yaml" "Issue"
82+
fi
83+
84+
exit 0

.claude/settings.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
{
22
"hooks": {
3+
"PreToolUse": [
4+
{
5+
"matcher": "Bash",
6+
"hooks": [
7+
{
8+
"type": "command",
9+
"command": "bash .claude/scripts/validate-gh-template.sh"
10+
}
11+
]
12+
}
13+
],
314
"PostToolUse": [
415
{
516
"matcher": "Edit|Write",

.claude/skills/issue/SKILL.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ GitHub Issueを使って問題を管理するスキル。
3939

4040
### 2. GitHub Issueの作成
4141

42-
以下のテンプレートで `gh issue create` を実行する:
42+
以下のテンプレートで `gh issue create` を実行する。
43+
44+
**重要**: `.github/ISSUE_TEMPLATE/default.md` のテンプレートに必ず準拠すること。
4345

4446
**タイトル**: `{対象領域} — {概要}`
4547

.github/ISSUE_TEMPLATE/default.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
---
2+
name: デフォルト
3+
about: 問題の報告や改善提案のテンプレート
4+
title: '{対象領域} — {概要}'
5+
labels: ''
6+
assignees: ''
7+
---
8+
9+
## パッケージ / 対象
10+
11+
`@next-lift/{package-name}` または対象の記述
12+
13+
## 問題
14+
15+
{問題の説明}
16+
17+
## 修正内容
18+
19+
{修正の詳細}
20+
21+
## 対象ファイル
22+
23+
- `{path/to/file}`
24+
25+
## 検証方法
26+
27+
- {検証方法}

0 commit comments

Comments
 (0)