A GitHub Action that reviews your PRs with the wisdom and fury of Gary "GOTO" Henderson, a 67-year-old developer who's been writing code since punch cards were cutting edge.
Gary is powered by Claude and brings 40+ years of COBOL experience, a gambling problem, and zero patience for your "vibe coded" AI slop.
- Technically accurate code reviews
- Maximum salt delivery
- Horse racing analogies in every review
- Catches missing error handling, validation issues, magic numbers, and more
- Grudgingly helpful despite the attitude
Go to Settings → Secrets and variables → Actions → New repository secret
- Name:
ANTHROPIC_API_KEY - Value: Your Anthropic API key
Create .github/workflows/grumpy-gary.yml in your repository:
name: Grumpy Gary PR Review
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
pull-requests: write
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Grumpy Gary Review
uses: keyreply/grumpy-gary-action@main
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}Gary reviews every PR automatically.
Gary only reviews when someone comments @grumpy-gary:
name: Grumpy Gary PR Review
on:
issue_comment:
types: [created]
permissions:
contents: read
pull-requests: write
jobs:
review:
if: |
github.event.issue.pull_request &&
contains(github.event.comment.body, '@grumpy-gary')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Grumpy Gary Review
uses: keyreply/grumpy-gary-action@main
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}name: Grumpy Gary PR Review
on:
pull_request:
types: [opened, synchronize, reopened]
issue_comment:
types: [created]
permissions:
contents: read
pull-requests: write
jobs:
review:
if: |
github.event_name == 'pull_request' ||
(github.event.issue.pull_request && contains(github.event.comment.body, '@grumpy-gary'))
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Grumpy Gary Review
uses: keyreply/grumpy-gary-action@main
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}name: Grumpy Gary PR Review
on:
workflow_dispatch:
inputs:
pr_number:
description: 'PR number to review'
required: true
permissions:
contents: read
pull-requests: write
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Grumpy Gary Review
uses: keyreply/grumpy-gary-action@main
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}| Input | Required | Default | Description |
|---|---|---|---|
anthropic-api-key |
Yes | - | Your Anthropic API key |
github-token |
Yes | - | GitHub token (usually ${{ secrets.GITHUB_TOKEN }}) |
allowed-orgs |
No | keyreply |
Comma-separated list of allowed GitHub organizations (leave empty to allow all) |
model |
No | claude-sonnet-4-20250514 |
Claude model to use |
max-diff-size |
No | 50000 |
Max diff characters before truncating |
By default, Grumpy Gary only reviews PRs from the keyreply organization. This is a security feature to prevent unauthorized use of your Anthropic API credits.
- name: Grumpy Gary Review
uses: keyreply/grumpy-gary-action@main
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}
allowed-orgs: 'keyreply,my-other-org'- name: Grumpy Gary Review
uses: keyreply/grumpy-gary-action@main
with:
anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }}
github-token: ${{ secrets.GITHUB_TOKEN }}
allowed-orgs: '' # Empty string allows allsigh Let me put down my racing form and look at this disaster...
Overall Assessment: This code has more red flags than my bookie's payment history.
src/api/users.ts:47- No error handling. NONE. You just... trust it'll work? That's not programming, it's a PRAYER. And I've prayed plenty at the track - let me tell you, God doesn't give a damn about your runtime exceptions OR your exacta box.
src/utils/validator.ts:12- Magic number alert. What the heck is86400? Would it KILL you to writeconst SECONDS_IN_DAY = 86400? I'm not a MIND READER, I'm just old.Missing input validation - Trust no one. ESPECIALLY not user input. I learned that lesson in '83 when a bank teller in Jersey crashed our entire batch system with a semicolon.
Fine, the folder structure isn't completely braindead. That's... something.
— Gary "GOTO" Henderson, Senior Developer (unfortunately)
Things that will set Gary off:
- Missing error handling
- No input validation
- Over-complicated abstractions
- Magic strings and numbers
- No comments on complex logic
- Implicit type coercion
- Circular dependencies
- AI-generated code (especially)
MIT - Use at your own risk. Gary takes no responsibility for hurt feelings.
"COBOL systems from 1985 still process your paycheck. Your React app won't survive the next npm audit."