Claude Code in GitHub Actions
The same claude -p discipline, lifted into CI: a workflow file, a secret instead of a login, and every limit written down where no one has to remember it. Practised in a copy you throw away.
01The goal
Run Claude Code unattended in a GitHub Actions workflow that reads its credential from a repository secret and stops within limits written in the file — then remove every trace of it.
02The idea
The Claude Code GitHub Action — anthropics/claude-code-action, from Anthropic — runs Claude Code as a step in a workflow. With no prompt input it waits for @claude in an issue or pull request and answers in a comment (interactive mode). With a prompt it runs on any event without waiting for a mention (automation mode), and its display_report input puts Claude’s report on the run’s summary page.
The workflow names a repository secret — ANTHROPIC_API_KEY for a Console key, CLAUDE_CODE_OAUTH_TOKEN for a subscription token — and the credential never appears in the file. No one is at the keyboard, so the limits go in the file: claude_args carries Claude Code’s CLI flags such as --max-turns and --allowedTools, the job’s permissions scope its GitHub token down to read, and timeout-minutes bounds the run.
This lesson practises in a throwaway private copy of the practice template, because it ends by deleting the workflow, the secret and the key. Make one: gh repo create claude-actions-practice --template wesammustafa/claude-code-practice --private --clone.
03The walkthrough
- 01In the copy, start claude and run /install-github-app. Follow the prompts: when GitHub asks which repositories the Claude GitHub App may access, choose Only select repositories and pick this copy only.
- 02Continue into the GitHub Actions setup and select just the @claude workflow, claude.yml. For the credential, paste an API key made for this lesson — quick setup saves it as the ANTHROPIC_API_KEY secret (or CLAUDE_CODE_OAUTH_TOKEN for a subscription token), pushes a branch carrying the workflow, and opens your browser with a pull request ready to create.
- 03Create and merge that pull request, git pull in your clone, and gh secret list — the secret is there, and @claude now works in the repository.
- 04Open an issue that mentions it: gh issue create --title "What does links.js do?" --body "@claude In one paragraph, what does src/links.js do? Don’t change any files." — then gh run list --limit 3 to see the run it started, and gh issue view <url> --comments for Claude’s answer.
04Your turn
Add .github/workflows/linkcheck-report.yml — a workflow you start by hand, in which Claude runs the template’s link checker on samples/ and explains each broken link on the run’s summary page, changing no files. Then run it, read the report, and tear down.
- 01Commit the workflow and push it to main — a workflow_dispatch run starts only when the file is on the default branch. Then: gh workflow run linkcheck-report.yml, find the run with gh run list --workflow linkcheck-report.yml --limit 1, and gh run watch <run-id> --exit-status.
- 02Read Claude’s report on the run’s summary page (gh run view <run-id> --web). With plain-text prompts Claude has no shell until you allow the commands it needs — which is why claude_args allows exactly one.
- 03Tear down, in order: delete the workflow file(s), commit and push. Delete the secret — gh secret delete ANTHROPIC_API_KEY. With an API key, delete the key itself on the Console’s API keys page. If nothing else uses it, remove the App’s access to the copy.
The security shape is the lesson inside the lesson. Anyone with write access to the repository can start a run with @claude, and the issue or comment text is input to Claude — it can carry hidden instructions, so keep practising copies private and think hard before enabling mentions where you do not control the writers. Pin the action because the @v1 tag moves with each release, and each release pins its own Claude Code version — a workflow on @v1 can run a newer Claude Code than the one you tested. And remember the teardown’s fine print: deleting a secret leaves the credential it held valid — retire the key itself.
What turns interactive mode into automation mode?
- AA prompt input on the action
- BSetting workflow_dispatch
- CNaming the secret CLAUDE_CODE_OAUTH_TOKEN
→Check your answer
With no prompt the action waits for @claude; with one, it runs on the trigger without waiting for a mention.
Why pin anthropics/claude-code-action to a release tag or SHA?
- AThe action refuses to run otherwise
- BThe @v1 tag moves with each release — and each release pins its own Claude Code version
- CPinned runs are cheaper
→Check your answer
A moving tag means the Claude Code version under your tested workflow can change without your consent. GitHub calls a full commit SHA the only immutable pin; a release tag is the lighter version.
The teardown deleted the ANTHROPIC_API_KEY secret. What is still true?
- AThe key it held is retired
- BNothing — deletion revokes it
- CThe key itself is still valid until you delete it on the Console
→Check your answer
Deleting a secret removes the pointer, not the credential. Retire the key itself — that is why the lesson recommends a key made for the lesson.