From dd8541688dc2d98783af74c446b40a5d3de410df Mon Sep 17 00:00:00 2001 From: Octavian Guzu Date: Mon, 23 Feb 2026 17:16:07 +0000 Subject: [PATCH] Use wrapper script for label operations in issue triage (#968) * Use wrapper script for label operations in issue triage Updates /label-issue command and examples to use a dedicated edit-issue-labels.sh script for label operations instead of raw gh issue edit. The script validates labels against the repo's existing labels before applying them. Also tightens gh search permission to gh search issues. * Show multiple --add-label flags in label-issue example --- .claude/commands/label-issue.md | 10 ++-- .github/workflows/issue-triage.yml | 2 +- docs/solutions.md | 4 +- examples/issue-triage.yml | 4 +- scripts/edit-issue-labels.sh | 87 ++++++++++++++++++++++++++++++ 5 files changed, 97 insertions(+), 10 deletions(-) create mode 100755 scripts/edit-issue-labels.sh diff --git a/.claude/commands/label-issue.md b/.claude/commands/label-issue.md index 1344c5c..3279410 100644 --- a/.claude/commands/label-issue.md +++ b/.claude/commands/label-issue.md @@ -1,5 +1,5 @@ --- -allowed-tools: Bash(gh label list:*),Bash(gh issue view:*),Bash(gh issue edit:*),Bash(gh search:*) +allowed-tools: Bash(gh label list:*),Bash(gh issue view:*),Bash(./scripts/edit-issue-labels.sh:*),Bash(gh search issues:*) description: Apply labels to GitHub issues --- @@ -23,8 +23,8 @@ TASK OVERVIEW: - You have access to these Bash commands: - Bash(gh label list:\*) - to get available labels - Bash(gh issue view:\*) - to view issue details - - Bash(gh issue edit:\*) - to apply labels to the issue - - Bash(gh search:\*) - to search for similar issues + - Bash(./scripts/edit-issue-labels.sh:\*) - to apply labels to the issue + - Bash(gh search issues:\*) - to search for similar issues 3. Analyze the issue content, considering: @@ -44,7 +44,7 @@ TASK OVERVIEW: - If you find similar issues using gh search, consider using a "duplicate" label if appropriate. Only do so if the issue is a duplicate of another OPEN issue. 5. Apply the selected labels: - - Use `gh issue edit` to apply your selected labels + - Use `./scripts/edit-issue-labels.sh --issue NUMBER --add-label LABEL1 --add-label LABEL2` to apply your selected labels - DO NOT post any comments explaining your decision - DO NOT communicate directly with users - If no labels are clearly applicable, do not apply any labels @@ -54,7 +54,7 @@ IMPORTANT GUIDELINES: - Be thorough in your analysis - Only select labels from the provided list above - DO NOT post any comments to the issue -- Your ONLY action should be to apply labels using gh issue edit +- Your ONLY action should be to apply labels using ./scripts/edit-issue-labels.sh - It's okay to not add any labels if none are clearly applicable --- diff --git a/.github/workflows/issue-triage.yml b/.github/workflows/issue-triage.yml index e30df40..f889591 100644 --- a/.github/workflows/issue-triage.yml +++ b/.github/workflows/issue-triage.yml @@ -21,7 +21,7 @@ jobs: - name: Run Claude Code for Issue Triage uses: anthropics/claude-code-action@main with: - prompt: "/label-issue REPO: ${{ github.repository }} ISSUE_NUMBER${{ github.event.issue.number }}" + prompt: "/label-issue REPO: ${{ github.repository }} ISSUE_NUMBER: ${{ github.event.issue.number }}" anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} allowed_non_write_users: "*" # Required for issue triage workflow, if users without repo write access create issues github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/docs/solutions.md b/docs/solutions.md index 8993f66..c88b2d7 100644 --- a/docs/solutions.md +++ b/docs/solutions.md @@ -415,12 +415,12 @@ jobs: 4. Check if it duplicates existing issues Based on your analysis, add the appropriate labels using: - `gh issue edit [number] --add-label "label1,label2"` + `./scripts/edit-issue-labels.sh --issue [number] --add-label "label1" --add-label "label2"` If it appears to be a duplicate, post a comment mentioning the original issue. claude_args: | - --allowedTools "Bash(gh issue:*),Bash(gh search:*)" + --allowedTools "Bash(gh issue view:*),Bash(gh search issues:*),Bash(./scripts/edit-issue-labels.sh:*)" ``` **Key Configuration:** diff --git a/examples/issue-triage.yml b/examples/issue-triage.yml index 10d3554..38d1395 100644 --- a/examples/issue-triage.yml +++ b/examples/issue-triage.yml @@ -21,8 +21,8 @@ jobs: - name: Run Claude Code for Issue Triage uses: anthropics/claude-code-action@v1 with: - # NOTE: /label-issue here requires a .claude/commands/label-issue.md file in your repo (see this repo's .claude directory for an example) - prompt: "/label-issue REPO: ${{ github.repository }} ISSUE_NUMBER${{ github.event.issue.number }}" + # NOTE: /label-issue requires .claude/commands/label-issue.md and scripts/edit-issue-labels.sh in your repo (see this repo for examples) + prompt: "/label-issue REPO: ${{ github.repository }} ISSUE_NUMBER: ${{ github.event.issue.number }}" anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} allowed_non_write_users: "*" # Required for issue triage workflow, if users without repo write access create issues diff --git a/scripts/edit-issue-labels.sh b/scripts/edit-issue-labels.sh new file mode 100755 index 0000000..d160a55 --- /dev/null +++ b/scripts/edit-issue-labels.sh @@ -0,0 +1,87 @@ +#!/usr/bin/env bash +# +# Edits labels on a GitHub issue. +# Usage: ./scripts/edit-issue-labels.sh --issue 123 --add-label bug --add-label needs-triage --remove-label untriaged +# + +set -euo pipefail + +ISSUE="" +ADD_LABELS=() +REMOVE_LABELS=() + +# Parse arguments +while [[ $# -gt 0 ]]; do + case $1 in + --issue) + ISSUE="$2" + shift 2 + ;; + --add-label) + ADD_LABELS+=("$2") + shift 2 + ;; + --remove-label) + REMOVE_LABELS+=("$2") + shift 2 + ;; + *) + exit 1 + ;; + esac +done + +# Validate issue number +if [[ -z "$ISSUE" ]]; then + exit 1 +fi + +if ! [[ "$ISSUE" =~ ^[0-9]+$ ]]; then + exit 1 +fi + +if [[ ${#ADD_LABELS[@]} -eq 0 && ${#REMOVE_LABELS[@]} -eq 0 ]]; then + exit 1 +fi + +# Fetch valid labels from the repo +VALID_LABELS=$(gh label list --limit 500 --json name --jq '.[].name') + +# Filter to only labels that exist in the repo +FILTERED_ADD=() +for label in "${ADD_LABELS[@]}"; do + if echo "$VALID_LABELS" | grep -qxF "$label"; then + FILTERED_ADD+=("$label") + fi +done + +FILTERED_REMOVE=() +for label in "${REMOVE_LABELS[@]}"; do + if echo "$VALID_LABELS" | grep -qxF "$label"; then + FILTERED_REMOVE+=("$label") + fi +done + +if [[ ${#FILTERED_ADD[@]} -eq 0 && ${#FILTERED_REMOVE[@]} -eq 0 ]]; then + exit 0 +fi + +# Build gh command arguments +GH_ARGS=("issue" "edit" "$ISSUE") + +for label in "${FILTERED_ADD[@]}"; do + GH_ARGS+=("--add-label" "$label") +done + +for label in "${FILTERED_REMOVE[@]}"; do + GH_ARGS+=("--remove-label" "$label") +done + +gh "${GH_ARGS[@]}" + +if [[ ${#FILTERED_ADD[@]} -gt 0 ]]; then + echo "Added: ${FILTERED_ADD[*]}" +fi +if [[ ${#FILTERED_REMOVE[@]} -gt 0 ]]; then + echo "Removed: ${FILTERED_REMOVE[*]}" +fi