VibeCheck in CI
Run the free VibeCheck scan on every push and pull request. The score, issue counts, most serious issue and vulnerable packages go to the GitHub job summary, and the build fails if the score drops below your minimum.
1. Add the workflow
Save this as .github/workflows/vibecheck.yml in your repo. It only needs curl and jq, which GitHub runners already have.
name: VibeCheck
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
jobs:
vibecheck:
runs-on: ubuntu-latest
steps:
- name: VibeCheck quick scan
env:
MIN_SCORE: 50 # fail below this score (any critical issue caps it at 49)
REPO: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: |
set -u
API="${VIBECHECK_API:-https://getvibecheck.dev/api/quickscan}"
REPO="${REPO:?set REPO=owner/name}"; SHA="${SHA:-HEAD}"; MIN_SCORE="${MIN_SCORE:-50}"; FAIL_ON_ERROR="${FAIL_ON_ERROR:-false}"
OUT="${RUNNER_TEMP:-/tmp}/vibecheck.json"; SUMMARY="${GITHUB_STEP_SUMMARY:-/dev/stdout}"
code=000
for i in 1 2 3; do
code=$(curl -sS -o "$OUT" -w '%{http_code}' --max-time 90 -A "vibecheck-ci/1" "$API?ci=1&repo=$REPO&ref=$SHA" || echo 000)
case "$code" in 200|400|404|413) break;; esac
echo "VibeCheck API returned HTTP $code, retrying in $((i * 30))s..."; sleep $((i * 30))
done
if [ "$code" != 200 ]; then
msg=$(jq -r '.error // empty' "$OUT" 2>/dev/null)
if [ "$FAIL_ON_ERROR" = true ]; then echo "::error::VibeCheck scan failed (HTTP $code) $msg"; exit 1; fi
echo "::warning::VibeCheck scan skipped (HTTP $code) $msg"; exit 0
fi
score=$(jq -r '.score' "$OUT")
{
echo "### VibeCheck: $score/100 · $(jq -r '.grade' "$OUT")"
echo; echo "| Critical | High | Medium | Low |"; echo "|---|---|---|---|"
jq -r '"| \(.counts.Critical) | \(.counts.High) | \(.counts.Medium) | \(.counts.Low) |"' "$OUT"; echo
jq -r 'if .top then "**Most serious:** \(.top.severity): \(.top.title)\n\n**Fix:** \(.top.fix)" else "No issues found." end' "$OUT"; echo
jq -r '.deps.summary // empty' "$OUT"; echo
echo "Free quick scan of commit \`${SHA:0:7}\` (static checks + dependency advisories). Every finding with AI fix prompts: https://getvibecheck.dev"
} >> "$SUMMARY"
echo "VibeCheck score: $score (minimum $MIN_SCORE)"
if [ "$score" -lt "$MIN_SCORE" ]; then echo "::error::VibeCheck score $score is below the minimum of $MIN_SCORE. See the job summary for the top issue."; exit 1; fi
Prefer a short version? This step runs the same script from getvibecheck.dev:
- name: VibeCheck quick scan
env:
MIN_SCORE: 50
REPO: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
SHA: ${{ github.event.pull_request.head.sha || github.sha }}
run: curl -fsSL https://getvibecheck.dev/vibecheck-ci.sh | bash
2. Pick your minimum score
- 50 (default): fails on any critical issue, like a leaked key, a table without Row Level Security, or a critical package advisory.
- 70: also fails on several high issues.
- 85: strict. Good once your app is clean.
How it works
- Public GitHub repos only. VibeCheck downloads the code for that exact commit and reads it. Nothing is installed and your code is never run.
- Checks: leaked keys, Supabase and Firebase rules, routes and server actions without auth, IDOR, injection, and known vulnerable packages from your lockfile (OSV.dev).
- Up to 10 CI scans per repo every 10 minutes. Results for a commit are cached for 24 hours, so re-running a job is free.
- If VibeCheck can't be reached, the step warns and lets the build pass. Set
FAIL_ON_ERROR: trueto fail instead. - The free scan has no git history or typecheck. The Full Report adds those, plus AI fix prompts for every finding.