โœ“ Copied to clipboard
GitHub Action Shipped
PR comments with score delta + optional merge gate

The official ratchet-action runs ratchet scan --diff main on every pull request, posts a score delta comment, and can optionally fail the check if the score drops below a threshold.

  • Score delta comment โ€” shows before/after per dimension on every PR
  • Merge gate โ€” set min-score to block PRs that drop quality
  • Badge generation โ€” auto-updates your README score badge on merge to main
  • SARIF upload โ€” security findings appear natively in GitHub Security tab
  • Works with GitHub Free, Pro, Team, and Enterprise Cloud
โ„น๏ธ Store your API key as a repository secret: Settings โ†’ Secrets โ†’ Actions โ†’ New repository secret. Name it ANTHROPIC_API_KEY (or whichever provider you use).
๐Ÿ“„ .github/workflows/ratchet.yml
name: Ratchet Quality Gate

on:
  pull_request:
    types: [opened, synchronize, reopened]
  push:
    branches: [main]

permissions:
  contents: read
  pull-requests: write   # needed to post PR comments

jobs:
  ratchet:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0          # full history for --diff

      - uses: actions/setup-node@v4
        with:
          node-version: '20'

      - name: Run Ratchet
        uses: ratchet-run/ratchet-action@v1
        with:
          api-key: ${{ secrets.ANTHROPIC_API_KEY }}
          min-score: 70             # fail if score drops below 70
          post-comment: true        # post delta to PR
          update-badge: true        # update README badge on main push
          upload-sarif: true        # upload to GitHub Security tab

What the PR comment looks like:

ratchet-bot commented just now
โš™ Ratchet Score Report
Overall 62 โ†’ 71 +9 โ†‘
๐Ÿงช Coverage       48 โ†’ 61   +13
๐Ÿ”€ Complexity     70 โ†’ 78   +8
๐Ÿ“ Docs           55 โ†’ 60   +5
๐Ÿšจ Error Handling  60 โ†’ 74   +14
๐Ÿท๏ธ Type Safety     90 โ†’ 90   โ€”
๐Ÿ›ก๏ธ Security        80 โ†’ 80   โ€”
โœ“ Score meets minimum threshold (70). Merge when ready.
GitLab CI Shipped
Score gate + MR note via GitLab API

Add Ratchet to your .gitlab-ci.yml pipeline. On merge requests, the job runs ratchet scan --diff, posts a score delta as an MR note using the GitLab API, and optionally sets the pipeline to failed if score drops.

โš ๏ธ Set CI/CD Variables in your GitLab project: ANTHROPIC_API_KEY (masked), GITLAB_API_TOKEN (a project access token with api scope for posting MR notes).
๐Ÿ“„ .gitlab-ci.yml
stages:
  - test
  - quality

# โ”€โ”€ Ratchet quality gate โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
ratchet:scan:
  stage: quality
  image: node:20-slim
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
    - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
  variables:
    RATCHET_MIN_SCORE: "70"
  before_script:
    - npm install -g ratchet-run
  script:
    - # Run scan against base branch on MRs, full scan on main
    - |
      if [[ "$CI_PIPELINE_SOURCE" == "merge_request_event" ]]; then
        ratchet scan --diff origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME \
          --output ratchet-report.json \
          --min-score $RATCHET_MIN_SCORE
      else
        ratchet scan --output ratchet-report.json
      fi
    - # Post score as MR note (only on merge requests)
    - |
      if [[ "$CI_PIPELINE_SOURCE" == "merge_request_event" ]]; then
        SCORE=$(jq -r '.score' ratchet-report.json)
        DELTA=$(jq -r '.delta // "N/A"' ratchet-report.json)
        GRADE=$(jq -r '.grade' ratchet-report.json)
        NOTE="โš™ **Ratchet Score**: \`${GRADE}\` (${SCORE}/100) โ€” delta: **${DELTA}**"
        curl --silent --request POST \
          --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" \
          --data "body=${NOTE}" \
          "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes"
      fi
  artifacts:
    when: always
    paths:
      - ratchet-report.json
    expire_in: 30 days
    reports:
      sast: ratchet-report.json   # appears in GitLab Security tab
โœ… GitLab Self-Managed users: this works identically. Just ensure your runner has internet access for the npm install, or pre-bake a Docker image with ratchet-run already installed.
๐Ÿช
Pre-commit Hook Shipped
Block commits that introduce debt โ€” locally, before push

Run ratchet scan --diff HEAD before every commit using Husky + lint-staged. Only the files in the staged changeset are scanned, keeping hook runtime under 10 seconds for typical changes.

  • Staged-files only โ€” Ratchet scans only what you're committing, not the whole repo
  • Fast โ€” typical hook run is 3โ€“8 seconds on changed files
  • Bypassable โ€” git commit --no-verify for emergency hotfixes
  • Works alongside ESLint, Prettier, and other lint-staged tools

Step 1 โ€” Install Husky and lint-staged

๐Ÿ’ป terminal
npm install --save-dev husky lint-staged
npx husky init

Step 2 โ€” Add the pre-commit hook

๐Ÿ“„ .husky/pre-commit
#!/usr/bin/env sh
# Run lint-staged (ESLint, Prettier, etc.)
npx lint-staged

# Ratchet: scan only staged files, block if score drops > 5 pts
npx ratchet-run scan --staged --max-drop 5

Step 3 โ€” Configure lint-staged in package.json

๐Ÿ“„ package.json (relevant section)
{
  "lint-staged": {
    "*.{ts,tsx,js,jsx}": [
      "eslint --fix",
      "prettier --write"
    ],
    "*.{ts,tsx}": [
      "tsc --noEmit"
    ]
  },
  "ratchet": {
    "model": "claude-3-5-haiku-20241022",  // fast model for hooks
    "maxDrop": 5,              // block if score drops > 5 pts
    "skipDimensions": ["docs"]  // skip doc checks in pre-commit
  }
}
๐Ÿ’ก Use a fast/cheap model like claude-3-5-haiku or gpt-4o-mini in pre-commit hooks to keep latency low. Save the full model for CI and ratchet fix runs.

What a blocked commit looks like

๐Ÿ’ป terminal output
$ git commit -m "refactor: simplify payment handler"
โš™ ratchet scan --staged

  Scanning 3 staged files...
  src/payments/handler.ts .............. โœ“
  src/payments/validate.ts ............. โœ“
  src/payments/webhook.ts .............. โœ—

  Score drop detected: 74 โ†’ 67 (โˆ’7 pts)
  Exceeds --max-drop threshold of 5.

  Affected dimension: Error Handling (โˆ’14 pts)
  Issue: webhook.ts:88 โ€” bare catch block swallowing PaymentError

  Fix with: npx ratchet-run fix src/payments/webhook.ts
  Or bypass: git commit --no-verify

husky - pre-commit hook exited with code 1 (error)
โ† Security & Privacy All Commands โ†’