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

Add GitHub workflow logging for issue closure eventsBrowse files
Extends the existing log-issue-events workflow to capture detailed metrics when issues are closed, including:
- Who closed the issue
- Whether it was closed automatically (by a bot)
- Whether it was closed as a duplicate
- Number of comments and reactions at closing time
- Issue state reason and timestamp

This provides comprehensive analytics for issue lifecycle tracking alongside the existing issue creation logging.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
Boris Cherny authored on Aug 11, 2025 parent e054111 · commit c40c658e1f46
1 changed file+113 -1compared with e054111
M.github/workflows/log-issue-events.yml
@@ -2,10 +2,11 @@
22
33 on:
44 issues:
5- types: [opened]
5+ types: [opened, closed]
66
77 jobs:
88 log-issue-created:
9+ if: github.event.action == 'opened'
910 runs-on: ubuntu-latest
1011 timeout-minutes: 5
1112 permissions:
@@ -66,3 +67,114 @@
6667 else
6768 echo "Failed to log issue creation for issue #${ISSUE_NUMBER}. HTTP ${HTTP_CODE}: ${BODY}"
6869 fi
70+
71+ log-issue-closed:
72+ if: github.event.action == 'closed'
73+ runs-on: ubuntu-latest
74+ timeout-minutes: 5
75+ permissions:
76+ contents: read
77+ issues: read
78+
79+ steps:
80+ - name: Log issue closure to Statsig
81+ env:
82+ STATSIG_API_KEY: ${{ secrets.STATSIG_API_KEY }}
83+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
84+ run: |
85+ ISSUE_NUMBER=${{ github.event.issue.number }}
86+ REPO=${{ github.repository }}
87+ ISSUE_TITLE="${{ github.event.issue.title }}"
88+ CLOSED_BY="${{ github.event.issue.closed_by.login }}"
89+ CLOSED_AT="${{ github.event.issue.closed_at }}"
90+ STATE_REASON="${{ github.event.issue.state_reason }}"
91+
92+ if [ -z "$STATSIG_API_KEY" ]; then
93+ echo "STATSIG_API_KEY not found, skipping Statsig logging"
94+ exit 0
95+ fi
96+
97+ # Get additional issue data via GitHub API
98+ echo "Fetching additional issue data for #${ISSUE_NUMBER}"
99+ ISSUE_DATA=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
100+ -H "Accept: application/vnd.github.v3+json" \
101+ "https://api.github.com/repos/${REPO}/issues/${ISSUE_NUMBER}")
102+
103+ COMMENTS_COUNT=$(echo "$ISSUE_DATA" | jq -r '.comments')
104+
105+ # Get reactions data
106+ REACTIONS_DATA=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
107+ -H "Accept: application/vnd.github.v3+json" \
108+ "https://api.github.com/repos/${REPO}/issues/${ISSUE_NUMBER}/reactions")
109+
110+ REACTIONS_COUNT=$(echo "$REACTIONS_DATA" | jq '. | length')
111+
112+ # Check if issue was closed automatically (by checking if closed_by is a bot)
113+ CLOSED_AUTOMATICALLY="false"
114+ if [[ "$CLOSED_BY" == *"[bot]"* ]]; then
115+ CLOSED_AUTOMATICALLY="true"
116+ fi
117+
118+ # Check if closed as duplicate by looking for duplicate label or state_reason
119+ CLOSED_AS_DUPLICATE="false"
120+ if [ "$STATE_REASON" = "not_planned" ]; then
121+ # Check if issue has duplicate label
122+ LABELS=$(echo "$ISSUE_DATA" | jq -r '.labels[] | select(.name | test("duplicate"; "i")) | .name')
123+ if [ -n "$LABELS" ]; then
124+ CLOSED_AS_DUPLICATE="true"
125+ fi
126+ fi
127+
128+ # Prepare the event payload
129+ EVENT_PAYLOAD=$(jq -n \
130+ --arg issue_number "$ISSUE_NUMBER" \
131+ --arg repo "$REPO" \
132+ --arg title "$ISSUE_TITLE" \
133+ --arg closed_by "$CLOSED_BY" \
134+ --arg closed_at "$CLOSED_AT" \
135+ --arg state_reason "$STATE_REASON" \
136+ --arg comments_count "$COMMENTS_COUNT" \
137+ --arg reactions_count "$REACTIONS_COUNT" \
138+ --arg closed_automatically "$CLOSED_AUTOMATICALLY" \
139+ --arg closed_as_duplicate "$CLOSED_AS_DUPLICATE" \
140+ '{
141+ events: [{
142+ eventName: "github_issue_closed",
143+ value: 1,
144+ metadata: {
145+ repository: $repo,
146+ issue_number: ($issue_number | tonumber),
147+ issue_title: $title,
148+ closed_by: $closed_by,
149+ closed_at: $closed_at,
150+ state_reason: $state_reason,
151+ comments_count: ($comments_count | tonumber),
152+ reactions_count: ($reactions_count | tonumber),
153+ closed_automatically: ($closed_automatically | test("true")),
154+ closed_as_duplicate: ($closed_as_duplicate | test("true"))
155+ },
156+ time: (now | floor | tostring)
157+ }]
158+ }')
159+
160+ # Send to Statsig API
161+ echo "Logging issue closure to Statsig for issue #${ISSUE_NUMBER}"
162+
163+ RESPONSE=$(curl -s -w "\n%{http_code}" -X POST https://events.statsigapi.net/v1/log_event \
164+ -H "Content-Type: application/json" \
165+ -H "STATSIG-API-KEY: ${STATSIG_API_KEY}" \
166+ -d "$EVENT_PAYLOAD")
167+
168+ HTTP_CODE=$(echo "$RESPONSE" | tail -n1)
169+ BODY=$(echo "$RESPONSE" | head -n-1)
170+
171+ if [ "$HTTP_CODE" -eq 200 ] || [ "$HTTP_CODE" -eq 202 ]; then
172+ echo "Successfully logged issue closure for issue #${ISSUE_NUMBER}"
173+ echo "Closed by: $CLOSED_BY"
174+ echo "Comments: $COMMENTS_COUNT"
175+ echo "Reactions: $REACTIONS_COUNT"
176+ echo "Closed automatically: $CLOSED_AUTOMATICALLY"
177+ echo "Closed as duplicate: $CLOSED_AS_DUPLICATE"
178+ else
179+ echo "Failed to log issue closure for issue #${ISSUE_NUMBER}. HTTP ${HTTP_CODE}: ${BODY}"
180+ fi