[codex] Add Claude GitHub Action workflow#2038
Conversation
Adds the standard `anthropics/claude-code-action@v1` workflow so maintainers can invoke Claude on issues and PRs via `@claude`. The job's `if:` condition restricts triggering to actors whose `author_association` on the comment/review/issue is `OWNER`, `MEMBER`, or `COLLABORATOR` so that only repository maintainers can grant Claude the read/write access this workflow exposes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
|
@rwgk now is the one on the team who knows the best how to do permission/membership check robustly in GHA. Assigning Ralf as a reviewer. |
| if: needs.authorize.outputs.has_write_access == 'true' | ||
| runs-on: ubuntu-latest | ||
| permissions: | ||
| contents: write |
There was a problem hiding this comment.
Instead of this, I would much prefer if Claude could push all of its work to a fork and iterate on the fork, but that doesn't seem possible without extensive work. Would love thoughts here.
There was a problem hiding this comment.
Just came to +1 this. I haven't even figured out how to get it to work on /my/ fork, and its habit of creating branches on the main fork makes the main fork much slower/harder to deal with.
There was a problem hiding this comment.
My concern with direct iterative work on a public PR is reviewability: the intermediate agent churn can easily swamp the signal humans need. I’d rather keep AI iteration local and only surface milestones once a human decides the result is ready for shared review.
There was a problem hiding this comment.
With Copilot I usually tell it to send a PR to my fork to avoid noise. Once I am happy, I send a PR upstream from the same branch. Example:
There was a problem hiding this comment.
The benefit is that when upstream (CuPy) merges the PR, and I sync my fork with upstream, the fork PR is auto-closed. But it only works with the CuPy case because we do merge commits there instead of squash/rebase (yes, I am pointing fingers 😂 Squash/rebase is unfriendly to tooling and automation).
There was a problem hiding this comment.
Conda-forge bots always do work in their forks. Example: conda-forge/cccl-python-feedstock#35 was sent from https://github.com/regro-cf-autotick-bot/cccl-python-feedstock. I imagine for Claude & co to follow the same pattern, we'd probably need a service account...?
There was a problem hiding this comment.
My concern with direct iterative work on a public PR is reviewability: the intermediate agent churn can easily swamp the signal humans need. I’d rather keep AI iteration local and only surface milestones once a human decides the result is ready for shared review.
+1 to this. I have been thinking this as well lately. It shouldn't be part of the normal workflow to create a PR just to interact with an agent. It's not necessary -- I have plenty of ways to interact with an agent on my machine. It crowds out the main space where humans interact, which requires a communication/collaboration tool like this.
|
github won't let me post a code comment (internal error for the last hour) :-( Referring to this line: Heads-up comment: While working on xref: #1930 (comment) |
|
I'm trying to use that just as a lossy filter to prevent launching extra github actions jobs to more deterministically determine if someone properly has write permission to the repo. It could potentially be extended to |
rwgk
left a comment
There was a problem hiding this comment.
Cursor GPT-5.4 Extra High Fast
Findings
- Blocking:
.github/workflows/claude.yml:37scoped theauthorizejob tocontents: read, but the permission gate calls GitHub's collaborator-permission API from.github/workflows/claude.yml:53. That endpoint requires write-level repository access, so maintainer@clauderequests can be skipped because the auth check fails before Claude runs. - Medium:
.github/workflows/claude.yml:53previously suppressed all API errors with2>/dev/null || true, then treated the actor as unauthorized. That hides real GitHub/API/auth failures behind a misleading "does not have write access" message and makes the workflow harder to debug.
Suggested fixes
- Change the
authorizejob permission tocontents: writeso the workflow token can call the collaborator-permission endpoint. - Capture the
gh apiresult explicitly, treat HTTP 404 as an expected "no effective access" case, and fail the job on other API errors so configuration or platform failures are surfaced immediately.
diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml
index f092ed3bd6..45451e295e 100644
--- a/.github/workflows/claude.yml
+++ b/.github/workflows/claude.yml
@@ -35,7 +35,7 @@ jobs:
contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.issue.author_association))
runs-on: ubuntu-latest
permissions:
- contents: read
+ contents: write # Required for collaborator permission API
outputs:
has_write_access: ${{ steps.actor-permission.outputs.has_write_access }}
steps:
@@ -48,7 +48,20 @@ jobs:
run: |
set -euo pipefail
- permission="$(gh api "repos/${GH_REPO}/collaborators/${TRIGGERING_ACTOR}/permission" --jq '.permission' 2>/dev/null || true)"
+ PERMISSION_RESPONSE=""
+
+ if PERMISSION_RESPONSE=$(
+ gh api "repos/${GH_REPO}/collaborators/${TRIGGERING_ACTOR}/permission" \
+ --jq '.permission' 2>&1
+ ); then
+ permission="${PERMISSION_RESPONSE}"
+ elif [[ "${PERMISSION_RESPONSE}" == *"(HTTP 404)"* ]]; then
+ permission="none"
+ else
+ echo "::error::Failed to inspect collaborator permission for ${TRIGGERING_ACTOR}."
+ printf '%s\n' "${PERMISSION_RESPONSE}"
+ exit 1
+ fi
case "${permission}" in
admin|maintain|write)
@@ -56,7 +69,7 @@ jobs:
;;
*)
echo "has_write_access=false" >> "$GITHUB_OUTPUT"
- echo "Skipping Claude because ${TRIGGERING_ACTOR} does not have write access to ${GH_REPO}."
+ echo "Skipping Claude because ${TRIGGERING_ACTOR} has ${permission} access to ${GH_REPO}; write, maintain, or admin is required."
;;
esac
What changed
Adds the Claude Code GitHub Actions workflow so repository maintainers can invoke Claude from issues, PR comments, PR review comments, and PR reviews with
@claude.The workflow includes a read-only authorization job that checks the triggering actor's actual repository permission through GitHub before granting write permissions or exposing
ANTHROPIC_API_KEY. The Claude job only runs for actors withwrite,maintain, oradminaccess.Why
The Claude GitHub app and
ANTHROPIC_API_KEYsecret are already configured for this repository. This wires in the officialanthropics/claude-code-actionworkflow while following Anthropic's security guidance that Claude usage should be restricted to users with write access.Validation
git diff --check -- .github/workflows/claude.ymlpre-commit run actionlint --files .github/workflows/claude.yml