spacehub

surshar / claude-code

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

Built by Anthropic · github.com/anthropics

claude-code / .github / workflows / claude-dedupe-issues.yml
99 lines · 4.1 KBRaw
1name: Claude Issue Dedupe
2description: Automatically dedupe GitHub issues using Claude Code
3on:
4 issues:
5 types: [opened]
6 workflow_dispatch:
7 inputs:
8 issue_number:
9 description: 'Issue number to process for duplicate detection'
10 required: true
11 type: string
12
13jobs:
14 claude-dedupe-issues:
15 # This job calls Claude, so it runs on GitHub's egress-firewall runner, which
16 # filters the job's outbound network traffic (allow list: .github/egress-firewall.yaml).
17 runs-on: ubuntu-24.04-firewall
18 timeout-minutes: 10
19 permissions:
20 contents: read
21 issues: write
22 # Required to mint the OIDC token exchanged for a Claude API access token (Workload Identity Federation)
23 id-token: write
24
25 steps:
26 - name: Checkout repository
27 uses: actions/checkout@v4
28
29 - name: Run Claude Code slash command
30 uses: anthropics/claude-code-action@v1
31 env:
32 GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
33 CLAUDE_CODE_SCRIPT_CAPS: '{"comment-on-duplicates.sh":1}'
34 with:
35 github_token: ${{ secrets.GITHUB_TOKEN }}
36 allowed_non_write_users: "*"
37 prompt: "/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number || inputs.issue_number }}"
38 # Authenticate to the Claude API via Workload Identity Federation
39 # (the workflow's OIDC token is exchanged for a short-lived access
40 # token) instead of a static API key.
41 anthropic_federation_rule_id: ${{ vars.ANTHROPIC_FEDERATION_RULE_ID }}
42 anthropic_organization_id: ${{ vars.ANTHROPIC_ORGANIZATION_ID }}
43 anthropic_service_account_id: ${{ vars.ANTHROPIC_SERVICE_ACCOUNT_ID }}
44 anthropic_workspace_id: ${{ vars.ANTHROPIC_WORKSPACE_ID }}
45 # --permission-mode auto: a tool call that needs permission and is outside the allowed-tools
46 # list in .claude/commands/dedupe.md runs only if Claude Code's safety review passes it.
47 # Tools in --disallowedTools never run.
48 claude_args: '--model claude-sonnet-4-6 --permission-mode auto --disallowedTools "WebFetch,WebSearch,Write,Edit,MultiEdit,NotebookEdit"'
49
50 - name: Log duplicate comment event to Statsig
51 if: always()
52 env:
53 STATSIG_API_KEY: ${{ secrets.STATSIG_API_KEY }}
54 ISSUE_NUMBER: ${{ github.event.issue.number || inputs.issue_number }}
55 REPO: ${{ github.repository }}
56 TRIGGERED_BY: ${{ github.event_name }}
57 WORKFLOW_RUN_ID: ${{ github.run_id }}
58 run: |
59 if [ -z "$STATSIG_API_KEY" ]; then
60 echo "STATSIG_API_KEY not found, skipping Statsig logging"
61 exit 0
62 fi
63
64 # Prepare the event payload
65 EVENT_PAYLOAD=$(jq -n \
66 --arg issue_number "$ISSUE_NUMBER" \
67 --arg repo "$REPO" \
68 --arg triggered_by "$TRIGGERED_BY" \
69 --arg workflow_run_id "$WORKFLOW_RUN_ID" \
70 '{
71 events: [{
72 eventName: "github_duplicate_comment_added",
73 value: 1,
74 metadata: {
75 repository: $repo,
76 issue_number: ($issue_number | tonumber),
77 triggered_by: $triggered_by,
78 workflow_run_id: $workflow_run_id
79 },
80 time: (now | floor | tostring)
81 }]
82 }')
83
84 # Send to Statsig API
85 echo "Logging duplicate comment event to Statsig for issue #${ISSUE_NUMBER}"
86
87 RESPONSE=$(curl -s -w "\n%{http_code}" -X POST https://events.statsigapi.net/v1/log_event \
88 -H "Content-Type: application/json" \
89 -H "STATSIG-API-KEY: ${STATSIG_API_KEY}" \
90 -d "$EVENT_PAYLOAD")
91
92 HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
93 BODY=$(echo "$RESPONSE" | head -n-1)
94
95 if [ "$HTTP_CODE" -eq 200 ] || [ "$HTTP_CODE" -eq 202 ]; then
96 echo "Successfully logged duplicate comment event for issue #${ISSUE_NUMBER}"
97 else
98 echo "Failed to log duplicate comment event for issue #${ISSUE_NUMBER}. HTTP ${HTTP_CODE}: ${BODY}"
99 fi