Skip to content

Commit 79470e9

Browse files
authored
upload-claude-usage: don't misattribute scheduled runs to a person (#8138)
## Problem `misc.claude_code_usage` attributes a large, growing share of Claude Code spend to individual maintainers who never ran it. Concrete example — a single real row from the table: | timestamp | repo | actor | event_name | pr_number | cost | turns | |---|---|---|---|---|---|---| | 2026-06-02 14:10 | meta-pytorch/pytorch-gha-infra | ZainRizvi | `schedule` | 0 | \$1.52 | 42 | That row is **not** Zain's usage. It's the hourly `Claude Infra Investigations` cron (treehugger) in `meta-pytorch/pytorch-gha-infra`. For `schedule` events there is no human trigger, so GitHub sets `github.actor` to whoever last committed to the workflow file — which happens to be the maintainer who set it up. At ~24 runs/day this funnels all automated treehugger cost onto one person's name in the dashboard. The same applies to any other scheduled Claude workflow (e.g. `claude-distributed-triage-cron`). ## Fix This action records `github.actor` verbatim. For `schedule` events, record the **workflow name** (suffixed with `(scheduled)`) instead, so the rows are clearly automated and stay distinguishable per-workflow. `event_name` is still stored unchanged, so no signal is lost. Human-triggered runs (`issue_comment`, `issues`, `workflow_dispatch`, `pull_request`, …) keep `github.actor` exactly as before. ## Notes / follow-ups - `workflow_run`-triggered runs inherit the upstream actor, so chains rooted at a cron may still carry a stale actor; that path isn't touched here. If desired, a follow-up could also remap `workflow_run` when the upstream event was scheduled. - Dashboards reading this table can additionally group by `event_name` to separate automated vs. human usage.
1 parent e50c021 commit 79470e9

1 file changed

Lines changed: 13 additions & 1 deletion

File tree

.github/actions/upload-claude-usage/action.yml

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,24 @@ runs:
3232
exit 0
3333
fi
3434
35+
# Resolve the actor. For scheduled runs there is no human trigger, so
36+
# github.actor falls back to whoever last modified the workflow file —
37+
# which misattributes automated usage to a person (e.g. a daily cron
38+
# showing up under the maintainer who last edited it). Record the
39+
# workflow name instead so these rows are clearly automated and remain
40+
# distinguishable per-workflow. github.event_name is still stored, so
41+
# the original signal isn't lost.
42+
ACTOR="${{ github.actor }}"
43+
if [ "${{ github.event_name }}" = "schedule" ]; then
44+
ACTOR="${{ github.workflow }} (scheduled)"
45+
fi
46+
3547
# Extract fields and add context
3648
jq -n \
3749
--arg repo "${{ github.repository }}" \
3850
--argjson run_id "${{ github.run_id }}" \
3951
--argjson run_attempt "${{ github.run_attempt }}" \
40-
--arg actor "${{ github.actor }}" \
52+
--arg actor "$ACTOR" \
4153
--arg event_name "${{ github.event_name }}" \
4254
--argjson pr_number "${{ github.event.issue.number || github.event.pull_request.number || 0 }}" \
4355
--arg timestamp "$(date -u +%Y-%m-%dT%H:%M:%S.000)" \

0 commit comments

Comments
 (0)