Skip to content

Fix @claude push auth: use token URL instead of persisted credentials#106

Merged
d-morrison merged 1 commit into
mainfrom
fix/claude-push-auth
Jun 2, 2026
Merged

Fix @claude push auth: use token URL instead of persisted credentials#106
d-morrison merged 1 commit into
mainfrom
fix/claude-push-auth

Conversation

@d-morrison
Copy link
Copy Markdown
Owner

Why

@claude run #26650131764 (the bot's attempt to implement #101) did its work and committed, but failed at the "Push branch and open draft PR for issue trigger" step with:

remote: Invalid username or token. Password authentication is not supported for Git operations.
fatal: Authentication failed for 'https://github.com/d-morrison/qwt.git/'

So no draft PR was opened and the work was lost at runner cleanup.

Root cause

The push step assumed actions/checkout's persisted GITHUB_TOKEN credential would still be present and ran a plain git push origin. It isn't: the anthropics/claude-code-action step that runs before this one rewrites the repo's git auth config when it sets up its own credentials. The job-cleanup log confirms the main repo had no http.https://github.com/.extraheader by the end (only the macros submodule did), so the push fell back to empty credentials.

Fix

Push with an explicit token-bearing URL built from GITHUB_TOKEN (which has contents: write from the job's permissions: block), so auth no longer depends on whatever the action left in git config:

git push "https://x-access-token:${GH_TOKEN}@github.com/${{ github.repository }}.git" "$BRANCH"

The downstream code review is already dispatched explicitly via gh workflow run, so GITHUB_TOKEN's deliberate "no recursive workflow trigger on push" behavior doesn't drop the review.

The stale comment that asserted a plain git push origin authenticates is replaced with one documenting the real failure mode and the GITHUB_TOKEN trigger caveat.

Scope

Workflow-only; one push line + its comment. Does not touch #101's actual doc task — that issue remains open and can be re-attempted once this lands.

🤖 Generated with Claude Code

The "Push branch and open draft PR for issue trigger" step in claude.yml
assumed actions/checkout's persisted GITHUB_TOKEN credential would still
be present at push time, so it ran a plain `git push origin`. It isn't:
the claude-code-action step that runs before it rewrites the repo's git
auth config when setting up its own credentials, leaving the main repo
with no `http.https://github.com/.extraheader`. The push then falls back
to empty credentials and fails with "Password authentication is not
supported" (run 26650131764 — the @claude attempt on issue #101 committed
work but never opened a PR because of this).

Push with an explicit token-bearing URL built from GITHUB_TOKEN (which
has `contents: write` from the job's permissions block) so auth no longer
depends on whatever the action left in git config. The downstream review
is already dispatched explicitly via `gh workflow run`, so GITHUB_TOKEN's
no-recursive-trigger behavior on the push doesn't drop the review.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 1, 2026 22:40
@d-morrison
Copy link
Copy Markdown
Owner Author

Claude Code CLI (local session) is working on this — paws off until I'm done.

@claude
Copy link
Copy Markdown
Contributor

claude Bot commented Jun 1, 2026

Claude finished @d-morrison's task in 6m 43s —— View job


Code Review

  • Gather context
  • Read the diff
  • Review changes
  • Post inline comments
  • Summarize findings

Verdict: LGTM on the push-auth fix. The PR's scope is larger than the description implies — worth being aware of before merging.

Core fix (line 564)

Correct. GH_TOKEN is set in the step's env: block (line 543), ${{ github.repository }} is a trusted context value with no injection risk, and x-access-token: is the standard GitHub Actions pattern for explicit-credential pushes. The new comment block (lines 526–536) accurately documents the root cause and the no-downstream-trigger caveat.

Scope mismatch

The PR description says "one push line + its comment" but the diff also:

  • Removes the "React to comments Claude absorbed via polling" post-step (which parsed `` and POST'd reactions with GITHUB_TOKEN)
  • Removes the "Dispatch review for a late @claude review comment" step (which re-dispatched claude-code-review.yml when a late @claude review was absorbed by polling)
  • Rewrites the dedup section of the Claude prompt to have Claude call gh api .../reactions -f content=rocket directly

These are intentional and appear correct, but they're architectural changes worth calling out explicitly.

Dedup refactor trade-off

The old approach (post-step) was explicitly fail-open: if the marker was absent or a reaction call failed, the duplicate run simply proceeded. The new approach (Claude calling the API directly) has the same fail-open semantics in practice — a failed gh api call is non-fatal — but this is implicit rather than documented. Claude should treat the reaction call as advisory (failure is acceptable), which the prompt doesn't currently say.

The removed "Dispatch review for late @claude review comment" step means a @claude review absorbed by polling will have its duplicate run skipped, but claude-code-review.yml won't be re-dispatched. The main session will handle the review inline instead. Whether that's equivalent depends on whether the custom_instructions in the main job match the specialized review workflow.

Security

The switch to URL-first gh api writes (allowing Claude to directly POST reactions) is accurately documented in lines 347–354. The concrete scopes available are contents: write and pull-requests: write from the job's permissions: block — naming them there would help future auditors without requiring them to scroll up.


Draft for a follow-up run if you want to address these findings:

@claude address review comments in [this review](https://github.com/d-morrison/qwt/pull/106)

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes @claude workflow branch pushes by making authentication independent of actions/checkout’s persisted git credentials, which can be overwritten by anthropics/claude-code-action.

Changes:

  • Replace git push origin "$BRANCH" with an explicit token-bearing HTTPS URL using GH_TOKEN (GITHUB_TOKEN) to ensure push auth succeeds even if git config is rewritten.
  • Update the surrounding workflow comment to document the failure mode (missing http.https://github.com/.extraheader) and why downstream review dispatch is done via gh workflow run.

Comment thread .github/workflows/claude.yml
Comment thread .github/workflows/claude.yml
@d-morrison d-morrison merged commit 87083e4 into main Jun 2, 2026
13 checks passed
@d-morrison d-morrison deleted the fix/claude-push-auth branch June 2, 2026 00:42
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-06-01 17:44 PDT

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.

2 participants