DEV Community

Cover image for I Built a GitHub Action That Catches the 'Did You Mean to Leave That console.log?' Comment
Yurukusa
Yurukusa

Posted on • Edited on

I Built a GitHub Action That Catches the 'Did You Mean to Leave That console.log?' Comment

You know that PR review comment.

"Did you mean to leave this console.log?"

Or worse:

"This looks like a hardcoded API key."

These are the avoidable ones. The embarrassing ones. The ones that make you wish the CI had caught it before your reviewer did.

I built a GitHub Action for this: Review Ready.

name: Review Ready
on:
  pull_request:
    branches: [main, master]
jobs:
  review-ready:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - uses: yurukusa/review-ready@v0.1.0
Enter fullscreen mode Exit fullscreen mode

That's it. Add this to your repo. When someone opens a PR, it scans the changed lines and outputs inline annotations for anything suspicious.

What it catches

Debug statementsconsole.log, debugger, Python's print(), Ruby's puts, Go's fmt.Print, Rust's println!, PHP's var_dump and dd(). Only in newly-added lines, not the whole codebase.

TODO/FIXME debtTODO, FIXME, HACK, XXX, TEMP, WTF, BUG in code you just wrote. Old TODOs are fine. New ones in a PR signal incomplete work.

Secrets — AWS access keys, GitHub PATs (ghp_), OpenAI API keys (sk-), Slack tokens (xox), hardcoded passwords and API keys. Skips test/mock/fixture files — they legitimately contain fake credentials.

Large files — accidentally staged files over 500KB. Binary assets, built artifacts, database dumps.

Missing tests — source files changed without a corresponding test file. Checks .test.ts, .spec.ts, __tests__/, test_ prefixes. Skips index.ts, types.ts, config.ts — those don't need tests.

Complexity — high cyclomatic complexity in new JS/TS code. Counts branches (if/else/while/for/&&/||) in added lines. If you added 20+ lines with 10+ branches, it'll flag it.

The annotations

When it finds something, you get inline PR annotations:

::error file=src/auth.ts,line=42::[review-ready/no-secrets] Possible API key detected
::warning file=src/utils.ts,line=15::[review-ready/no-todo-in-changes] Unresolved marker: // TODO: validate input
::notice file=src/payment.ts::[review-ready/test-file-exists] No test file found for payment.ts
Enter fullscreen mode Exit fullscreen mode

Errors show up as blocking annotations in the PR diff. Warnings and info are informational.

Configuration

All checks are independently configurable:

- uses: yurukusa/review-ready@v0.1.0
  with:
    no-debug-statements: true
    no-todo-in-changes: true
    no-secrets: true
    no-large-files: true
    test-coverage: true
    complexity: true
    complexity-threshold: 10
    fail-on: error  # "error" | "warning" | "never"
Enter fullscreen mode Exit fullscreen mode

Set fail-on: never if you want the annotations without blocking the PR.

VS Code Extension

There's also a VS Code extension that runs the same checks locally — before you even push. Results appear in the Activity Bar with a colored status bar.

MCP Server (Claude Code / Claude Desktop)

If you use Claude Code or Claude Desktop, there's also an MCP server that lets you ask Claude to run the checks directly:

{
  "mcpServers": {
    "review-ready": {
      "command": "npx",
      "args": ["review-ready-mcp"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Then: "Check my changes before I push" — Claude calls check_changes on your repo and reports inline.

Available on npm: review-ready-mcp

How it works

The action runs git diff against the base branch to get only the changed lines. This is intentional — it doesn't lint your whole codebase, just what's new in this PR.

Each check is a pure function: (changedLines, filename) → CheckResult[]. The CLI wraps them, formats GitHub Actions annotations, and exits with the right code.

The whole thing is 11KB. Zero external dependencies in the action bundle.


GitHub: yurukusa/vscode-review-ready | npm: review-ready | MCP: review-ready-mcp | Live demo

One workflow file. No setup. Catches the obvious stuff.

What's your most embarrassing PR review comment?


More tools: Dev Toolkit — 440+ free browser-based tools for developers. JSON, regex, colors, CSS, SQL, and more. All single HTML files, no signup.


Is your Claude Code setup actually safe? Run npx cc-health-check — a free 20-point diagnostic. Score below 80? The Claude Code Ops Kit fixes everything in one command.


Make Claude Code safe: npx cc-safe-setup — 8 hooks, 10 seconds, zero config. GitHub

Top comments (4)

Collapse
 
trinhcuong-ast profile image
Kai Alder

11KB with zero deps — that's the dream. So many GitHub Actions pull in half of npm just to check for console.log statements.

One thing I'd love to see: configurable patterns per language. Like in our Node projects we have a legit console.warn for deprecation notices, but console.log should always be caught. Right now do you have to disable the whole debug check or can you whitelist specific patterns?

Also the MCP integration is a nice touch. Being able to run checks before pushing through Claude Code saves that awkward "oops, force push" dance.

What made you go with cyclomatic complexity over something like cognitive complexity? I've found cognitive complexity catches more "this is hard to read" cases even when the branch count is low.

Collapse
 
yurukusa profile image
Yurukusa

Good questions!

Per-language patterns: right now you configure it through the action YAML — there is a patterns input where you can add or remove patterns per file extension. So you could keep console.warn for Node while still catching console.log. Not per-repo-config-file yet, but the YAML input gets you most of the way there.

Cyclomatic vs cognitive: honestly, cyclomatic was simpler to implement and catches the worst offenders (deeply nested if/else chains). Cognitive complexity would be better for readability — it penalizes nested conditions more heavily. Might add it as an option. Good call.

And yeah, the MCP hook is probably the most underrated part. Catching things before they hit the remote is way less painful than cleaning up after.

Collapse
 
freerave profile image
freerave

Story of my life! Nothing hurts more than pushing a 'clean' commit and feeling proud, only to see 5 console.log('here') staring back at you in the PR. Definitely adding this to my GitHub workflows. Legend!

Collapse
 
yurukusa profile image
Yurukusa

Ha, the PR shame spiral is real. Glad it helps — once it catches the first one you forgot to remove, it pays for itself.