Skip to content

Commit a5e03ef

Browse files
authored
Merge pull request #381 from rajbos/copilot/add-labels-and-workflow-checks
feat: add Toolnames checkup workflow to prevent duplicate tool-name issues
2 parents e3db965 + 299c69c commit a5e03ef

1 file changed

Lines changed: 130 additions & 0 deletions

File tree

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
name: Check Toolnames in Issue
2+
3+
on:
4+
issues:
5+
types: [labeled]
6+
7+
permissions:
8+
contents: read
9+
10+
jobs:
11+
# Checks each tool name in the issue body against src/toolNames.json on main
12+
# and posts a comment with the status of each one.
13+
check-toolnames:
14+
runs-on: ubuntu-latest
15+
if: github.event.label.name == 'Toolnames checkup'
16+
permissions:
17+
issues: write
18+
contents: read
19+
steps:
20+
- name: Harden the runner (Audit all outbound calls)
21+
uses: step-security/harden-runner@a90bcbc6539c36a85cdfeb73f7e2f433735f215b # v2.15.0
22+
with:
23+
egress-policy: audit
24+
25+
- name: Checkout main branch
26+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
27+
with:
28+
ref: main
29+
30+
- name: Check toolnames and post comment
31+
env:
32+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33+
ISSUE_BODY: ${{ github.event.issue.body }}
34+
ISSUE_NUMBER: ${{ github.event.issue.number }}
35+
REPO: ${{ github.repository }}
36+
RUN_ID: ${{ github.run_id }}
37+
SERVER_URL: ${{ github.server_url }}
38+
run: |
39+
echo "=== Checking toolnames and building comment ==="
40+
41+
python3 - << 'PYEOF'
42+
import json
43+
import os
44+
import re
45+
import sys
46+
47+
issue_body = os.environ.get("ISSUE_BODY", "")
48+
issue_number = os.environ.get("ISSUE_NUMBER", "")
49+
repo = os.environ.get("REPO", "")
50+
run_id = os.environ.get("RUN_ID", "")
51+
server_url = os.environ.get("SERVER_URL", "https://github.com")
52+
53+
COMMENT_FILE = "/tmp/toolnames-comment.md"
54+
MAX_BODY_LEN = 100_000 # guard against extremely large issue bodies
55+
56+
# Truncate untrusted input to prevent resource exhaustion
57+
if len(issue_body) > MAX_BODY_LEN:
58+
issue_body = issue_body[:MAX_BODY_LEN]
59+
print("Warning: issue body was truncated to 100 KB", file=sys.stderr)
60+
61+
# Extract backtick-wrapped strings and filter to plausible tool-name shapes
62+
# (no path separators or spaces; reasonable length). This avoids matching
63+
# inline-code snippets like `src/toolNames.json` or prose code examples.
64+
raw_matches = re.findall(r'`([^`\n]+)`', issue_body)
65+
tools = sorted(set(
66+
m for m in raw_matches
67+
if "/" not in m and " " not in m and len(m) <= 128
68+
))
69+
print(f"Found {len(tools)} candidate tool name(s): {tools}", file=sys.stderr)
70+
71+
if not tools:
72+
print("No candidate tool names found in issue body. Skipping.", file=sys.stderr)
73+
with open(COMMENT_FILE, "w") as f:
74+
f.write("## 🔍 Toolnames Checkup\n\n_No candidate tool names (backtick-wrapped identifiers without path separators) were found in the issue body._\n")
75+
else:
76+
with open("src/toolNames.json", "r") as f:
77+
known_tools = json.load(f)
78+
79+
already_added = []
80+
needs_adding = []
81+
82+
for tool in tools:
83+
if tool in known_tools:
84+
already_added.append((tool, known_tools[tool]))
85+
else:
86+
needs_adding.append(tool)
87+
88+
lines = ["## 🔍 Toolnames Checkup", ""]
89+
lines.append("Checked the tool names in this issue against `src/toolNames.json` on the `main` branch:")
90+
lines.append("")
91+
92+
if already_added:
93+
lines.append("### ✅ Already mapped")
94+
lines.append("")
95+
lines.append("| Tool Name | Friendly Name |")
96+
lines.append("| --- | --- |")
97+
for tool, friendly in already_added:
98+
lines.append(f"| `{tool}` | {friendly} |")
99+
lines.append("")
100+
101+
if needs_adding:
102+
lines.append("### ❌ Not yet in `toolNames.json`")
103+
lines.append("")
104+
lines.append("| Tool Name |")
105+
lines.append("| --- |")
106+
for tool in needs_adding:
107+
lines.append(f"| `{tool}` |")
108+
lines.append("")
109+
110+
if already_added and not needs_adding:
111+
lines.append("> **All tool names in this issue are already mapped.** This issue may be a duplicate — consider closing it.")
112+
elif needs_adding:
113+
lines.append(f"> **{len(needs_adding)} tool name(s) still need to be added.** Please use the `tool-names` custom agent or update `src/toolNames.json` manually.")
114+
115+
lines.append("")
116+
lines.append(f"_Workflow run: {server_url}/{repo}/actions/runs/{run_id}_")
117+
118+
comment_body = "\n".join(lines)
119+
with open(COMMENT_FILE, "w") as f:
120+
f.write(comment_body)
121+
print("=== Comment preview ===", file=sys.stderr)
122+
print(comment_body, file=sys.stderr)
123+
PYEOF
124+
125+
echo "=== Posting comment to issue #${ISSUE_NUMBER} ==="
126+
gh issue comment "$ISSUE_NUMBER" \
127+
--repo "$REPO" \
128+
--body-file /tmp/toolnames-comment.md
129+
130+
echo "✅ Comment posted successfully"

0 commit comments

Comments
 (0)