Skip to content

CI/CD Integration Guide ​

Run claudelint in your CI pipeline to catch configuration issues before they reach production.

GitHub Actions ​

Basic Setup ​

yaml
name: Lint Claude Config
on: [push, pull_request]

jobs:
  claudelint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6

      - uses: actions/setup-node@v6
        with:
          node-version: '22'

      - run: npm install -g claude-code-lint

      - name: Validate with annotations
        run: claudelint check-all --format github

Errors and warnings appear directly on the PR diff at the relevant lines. No permissions or upload steps needed.

Alternative Annotations ​

Problem Matcher (Stylish Format) ​

If you prefer the default stylish format but still want PR annotations, use a problem matcher:

yaml
- name: Register problem matcher
  run: echo "::add-matcher::.github/claudelint-problem-matcher.json"

- name: Run claudelint
  run: npx claudelint check-all

The problem matcher parses stylish output and converts errors/warnings into GitHub annotations. Place .github/claudelint-problem-matcher.json in your repo (available in the claudelint repository).

SARIF Upload (Code Scanning) ​

Use SARIF when you need persistent results, trend tracking, or more than 50 annotations per run (GitHub limits workflow annotations to 50 per run). Add security-events: write to permissions and replace the run step in the basic setup:

yaml
    permissions:
      security-events: write

    # ... checkout, setup-node, install as above ...

    - name: Run claudelint (SARIF)
      run: claudelint check-all --format sarif > results.sarif
      continue-on-error: true

    - name: Upload SARIF
      uses: github/codeql-action/upload-sarif@v4
      with:
        sarif_file: results.sarif

Optimizing CI Runs ​

Changed Files Only ​

Speed up PR checks by only validating files that changed:

yaml
- name: Lint changed files only
  run: claudelint check-all --since origin/main --format github

- name: Lint uncommitted changes
  run: claudelint check-all --changed --format github

Use --since <ref> to check files changed since a git ref (ideal for PRs), or --changed for uncommitted changes.

Selective Validators ​

Instead of check-all, run only the validators relevant to your project:

yaml
- name: Check CLAUDE.md files
  run: claudelint validate-claude-md

- name: Validate settings
  run: claudelint validate-settings

- name: Validate MCP servers
  run: claudelint validate-mcp

All available validators: validate-claude-md, validate-skills, validate-settings, validate-hooks, validate-mcp, validate-plugin, validate-agents, validate-commands, validate-lsp, validate-output-styles. Run claudelint --help for descriptions.

Caching ​

Add caching to speed up repeated runs:

yaml
- name: Cache claudelint results
  uses: actions/cache@v5
  with:
    path: .claudelint-cache
    key: claudelint-${{ hashFiles('**/*.md', '**/*.json') }}
    restore-keys: claudelint-

- name: Run claudelint
  run: claudelint check-all --cache

With Claude Code GitHub Actions ​

Claude Code GitHub Actions lets Claude respond to @claude mentions in PRs, create PRs from issues, and run automated code review. claudelint validates your Claude Code configuration files — the two complement each other.

Add a claudelint validation job alongside your Claude Code action to catch config issues in the files Claude relies on:

yaml
jobs:
  lint-config:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - uses: actions/setup-node@v6
        with:
          node-version: '22'
      - run: npm install -g claude-code-lint
      - run: claudelint check-all --format github

  claude-review:
    runs-on: ubuntu-latest
    steps:
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

GitLab CI ​

yaml
claudelint:
  image: node:22
  stage: lint
  script:
    - npm install -g claude-code-lint
    - claudelint check-all --format compact
  cache:
    key: claudelint
    paths:
      - .claudelint-cache/
  rules:
    - changes:
        - "**/*.md"
        - ".claude/**"
        - ".mcp.json"
        - "skills/**"

Git Hooks ​

Husky ​

Run claudelint as a git hook with Husky:

bash
npx husky init

Add to .husky/pre-commit for a fast check on every commit:

sh
npx claudelint check-all --fast --changed --quiet

Add to .husky/pre-push for a thorough check before pushing:

sh
npx claudelint check-all

lint-staged ​

Run claudelint only on staged files using lint-staged:

json
{
  "lint-staged": {
    "*.md": "claudelint validate-claude-md --allow-empty-input",
    ".claude/**/*.json": "claudelint check-all --allow-empty-input"
  }
}

Pre-commit (Python) ​

Using the pre-commit framework:

yaml
# .pre-commit-config.yaml
repos:
  - repo: local
    hooks:
      - id: claudelint
        name: claudelint
        language: system
        entry: npx claude-code-lint check-all
        pass_filenames: false
        files: '\.(md|json)$'

Configuration ​

Exit Codes ​

CodeMeaning
0No issues found
1Validation issues found
2Configuration or runtime error

Useful Flags ​

FlagDescription
--format githubGitHub Actions annotations (inline on PR diffs)
--format sarifSARIF output for GitHub Code Scanning
--format jsonJSON output for custom processing
--format compactOne-line-per-issue for log parsing
-q, --quietSuppress warnings, show only errors
--warnings-as-errorsFail on warnings too
--strictFail on any issue (errors + warnings + info)
--max-warnings <n>Fail if warning count exceeds limit
--allow-empty-inputExit 0 when no files found (useful with lint-staged)
--cacheEnable result caching (default in check-all)
--no-cacheDisable caching
--config <path>Custom config file path
--fixAuto-fix fixable issues
--fix-dry-runPreview fixes without applying
--changedOnly check files with uncommitted changes
--since <ref>Only check files changed since a git ref
--fastSkip expensive checks (good for pre-commit)
-o, --output-file <path>Write results to a file
--timingShow per-validator timing breakdown
--statsInclude per-rule statistics in output

Configuration File ​

Create .claudelintrc.json in your project root:

json
{
  "rules": {
    "skill-body-too-long": ["warn", { "maxLines": 600 }],
    "skill-body-word-count": ["warn", { "maxWords": 7000 }],
    "skill-description-max-length": ["warn", { "maxLength": 300 }]
  },
  "output": {
    "format": "stylish"
  }
}

Monitoring Config Drift ​

Not every rule needs to be a hard gate. Setting rules to warn lets CI surface trends before they become problems — you get a heads-up in your PR checks without blocking the build.

CLAUDE.md size is a good example. Claude Code performance degrades once the file exceeds 40KB, but you probably want to know well before that:

json
{
  "rules": {
    "claude-md-size": {
      "severity": "warn",
      "options": { "maxSize": 30000 }
    }
  }
}

This pattern works with any configurable rule — skill body length, word counts, import depth. Set the threshold where you want the early signal, and let CI do the monitoring.

Monorepo Support ​

For monorepo projects with multiple packages:

yaml
- name: Validate all workspaces
  run: claudelint check-all --workspaces

- name: Validate specific package
  run: claudelint check-all --workspace my-package