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

How it works