GITHUB ACTION · API

Fail the pull request before Vercel builds it.

The same nine checks as the website, on every pull request. Findings land as annotations on the changed files, the job summary links the full report, and the check goes red on a definite problem. Static analysis through the GitHub API: nothing is cloned, installed or executed, so it finishes in seconds and needs no build.

1. Create an API token

Open My scans in the browser you paid in and click Create API token. Tokens work while a pass is active, which is any pass: $2 for 24 hours, $5 for 7 days or $9 a month. Store it as a repository secret named DEPLOYDOCTOR_TOKEN under Settings, Secrets and variables, Actions.

2. Add the workflow

Save this as .github/workflows/deploydoctor.yml. The action scans the pull request head, not the default branch.

name: DeployDoctor
on:
  pull_request:
jobs:
  deploydoctor:
    runs-on: ubuntu-latest
    steps:
      - uses: jonjys/deploydoctor/action@master
        with:
          token: ${{ secrets.DEPLOYDOCTOR_TOKEN }}
          # Private repository? Let the scan read it:
          # github-token: ${{ github.token }}

For a private repository, pass github-token so the scan can read it. The job's own token has read access to the repository, is forwarded for that one scan and is never stored. Private reports open only in the browser you paid in, or through your API token.

What the check does

  • Fails the job when a check is red: an import that only resolves on macOS, a package that is used but not declared, a process.env read that no .env.example documents, a Node-only module on the Edge runtime, Prisma without prisma generate, a live secret in source.
  • Annotates each finding on the file and line in the pull request, with the fix.
  • Writes a status table to the job summary and links the saved report.
  • Sets outputs overall, report-url, red and yellow for later steps.

Inputs: fail-on (red by default, yellow to also fail on items that need review, never to only report),checks (comma-separated next, vercel, env, supabase, prisma; the detected stack decides when empty),ref and repository to scan something other than the pull request.

The API behind it

The action is a thin client. Any script can do the same with the token: POST a repository URL and an optional ref and get the whole report as JSON, including every finding with file and line.

curl -s -X POST https://deploydoctor.nyttolabs.com/api/reports \
  -H "Authorization: Bearer $DEPLOYDOCTOR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"repoUrl":"https://github.com/vercel/commerce","ref":"main"}'

Responses: 201 with the report, 401 for a token that does not verify, 402 when no pass is active, 404 for a missing repository or ref, 429 when GitHub's own rate limit is hit. A saved report is also readable as JSON at /api/reports/<id>, public ones with no token at all. Token requests never count against the free daily limit, so a shared runner IP does not matter.

What it does not do

It does not run your build, so it cannot catch type errors or failing tests; your existing jobs do that. It reads the repository through GitHub's API with a file and time budget, and marks a scan partial when it hits one. A green check means the nine static checks passed, not that the deploy will succeed.

Updated 2026-10-06 · Action source