Skip to content

Move the Claude workflows to the shared composite actions - #197

Merged
jantman merged 1 commit into
mainfrom
claude/unify-review-workflows
Sep 19, 2026
Merged

jantman merged 1 commit into
mainfrom
claude/unify-review-workflows

Conversation

@jantman

@jantman jantman commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Rewritten. This PR originally inlined the full workflows here. They now live in
jantman/github-actions-workflows
as composite actions, and this is a thin caller. The logic is identical — only its
location changed.

Both workflows become thin callers pinned at @v1:

      - name: Checkout repository
        uses: actions/checkout@v7
        with:
          fetch-depth: 1

      - uses: jantman/github-actions-workflows/claude-pr-review@v1
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}

Proven before this landed here

This is the same action that now reviews pull requests on jantman/privatepuppet —
verified posting a real review on jantman/privatepuppet#45 (🔎 5m 5s · 14 turns · $1.3644), correctly scoped to only the commits pushed since its last review.

What changes

before after
Review allowlist varies; several repos had no Skill/Task/Write Skill,Task,Write,TodoWrite + blanket Bash
Bash enumerated per repo, silently starving subagents allowed outright
Logging display_report off in several repos on, + transcript/session artifact
Findings --comment: N loose inline comments one GitHub review, findings batched inline
Cost/duration nowhere job summary and the review footer
A denied tool green check fails the check
Agent ends turn without findings silent posts its raw message, fails
CI results not readable mcp__github_ci__* + actions: read
Fork PRs action fails red (no secrets) skipped cleanly
Where the logic lives one copy per repo one copy, @v1

Why composite, not workflow_call

claude-code-action's default-branch validation runs server-side at
api.anthropic.com from OIDC claims
, and nothing in the action's source says whether it
reads workflow_ref (the caller — fine) or job_workflow_ref (the shared repo — always
fails). With workflow_call that unknown decides whether it works at all. A composite
action never asks the question: it runs as part of this job, so the workflow being
validated is this repo's own file, exactly as before.

What stays here

A composite action can't reach these — by the time one runs the runner is up and the
token is minted: triggers, concurrency, permissions, the fork guard, the trigger
guard, and actions/checkout.

⚠️ This PR can't test itself

It changes .github/workflows/, so claude-code-action's validation guard fires and
claude-review goes green having done nothing. Look for Exiting due to workflow validation skip. The real test is the first PR opened here after this merges.

claude-mention.yml is stricter still: issue_comment workflows always run from the
default branch, so the mention path does nothing until this is merged.

🤖 Generated with Claude Code

Replaces both workflows with thin callers of
jantman/github-actions-workflows, pinned at `@v1`, which now holds the logic ten
repositories would otherwise hold ten copies of.

The behaviour is the one that has been reviewing pull requests on
jantman/privatepuppet and jantman/biweeklybudget: the agent writes its findings
to a JSON file and the action turns them into exactly one GitHub review, with
the findings as batched inline comments and the run's duration, turn count and
cost in the body. A run that decides to skip still posts a one-line review. A
denied tool call, an `is_error` result, or an agent that ends its turn without
writing the findings file all fail the check rather than passing quietly --
which is how these runs used to go green having reviewed nothing.

Composite actions rather than reusable workflows, deliberately. The action's
default-branch validation happens server-side at api.anthropic.com from OIDC
claims, and nothing in claude-code-action's source says whether it reads
`workflow_ref` (the caller) or `job_workflow_ref` (the shared repo). With
`workflow_call` that unknown decides whether it works at all. A composite action
never asks it: it runs as part of this job, so the workflow being validated is
this repository's own file, exactly as before.

What stays here, because a composite action cannot reach it -- by the time one
runs, the runner is up and the token is minted:

- the triggers, `concurrency` and `permissions`
- the fork guard on the review job: a fork pull request gets no secrets, so
  without it the action fails red on someone else's contribution
- `actions/checkout`, so this repository keeps control of fetch-depth
- the trigger guard on the mention job

Pinned to `@v1`, a moving tag. Moving it updates all ten repositories at once,
which is the point and also the risk; pin a SHA instead to take updates
deliberately.

Checked with actionlint.

Because this repository is public, the mention workflow additionally requires the
triggering author's `author_association` to be OWNER, MEMBER or COLLABORATOR.
That job has `contents: write` and blanket `Bash`, so without the check any
passer-by who types the mention gets an agent run billed to the maintainer's
account. The field is read per-event on purpose: on `issue_comment`,
`github.event.issue.author_association` describes the issue's opener rather than
the commenter, so reading it there would let a stranger trigger a run merely by
commenting on a maintainer's own issue.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@jantman
jantman force-pushed the claude/unify-review-workflows branch from 5e1f6a1 to 49a3c3f Compare September 19, 2026 18:25
@jantman jantman changed the title Unify the Claude Code review workflows on the shared template Move the Claude workflows to the shared composite actions Sep 19, 2026
@jantman
jantman merged commit b7c4c3e into main Sep 19, 2026
15 of 17 checks passed
@jantman
jantman deleted the claude/unify-review-workflows branch September 19, 2026 18:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant