Files
gh-cskiro-claudex-claude-co…/skills/claude-md-auditor/reference/ci-cd-integration.md
2025-11-29 18:16:51 +08:00

6.1 KiB

CI/CD Integration Examples

Ready-to-use configurations for automated CLAUDE.md validation.

Pre-Commit Hook

Basic Validation

#!/bin/bash
# .git/hooks/pre-commit

if git diff --cached --name-only | grep -q "CLAUDE.md"; then
  echo "Validating CLAUDE.md..."

  FILE=$(git diff --cached --name-only | grep "CLAUDE.md" | head -1)

  # Check file length
  LINES=$(wc -l < "$FILE")
  if [ "$LINES" -gt 500 ]; then
    echo "ERROR: CLAUDE.md is $LINES lines (max 500)"
    exit 1
  fi

  # Check for secrets
  if grep -qE "password|secret|token|api_key|-----BEGIN" "$FILE"; then
    echo "ERROR: Potential secrets detected in CLAUDE.md"
    echo "Run: grep -nE 'password|secret|token|api_key' $FILE"
    exit 1
  fi

  # Check for broken imports
  grep "^@" "$FILE" | while read -r import; do
    path="${import#@}"
    if [ ! -f "$path" ]; then
      echo "ERROR: Broken import: $import"
      exit 1
    fi
  done

  echo "CLAUDE.md validation passed"
fi

Installation

chmod +x .git/hooks/pre-commit

GitHub Actions

Basic Workflow

# .github/workflows/claude-md-audit.yml
name: CLAUDE.md Audit

on:
  pull_request:
    paths:
      - '**/CLAUDE.md'
      - '**/.claude/CLAUDE.md'

jobs:
  audit:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Find CLAUDE.md files
        id: find
        run: |
          files=$(find . -name "CLAUDE.md" -type f)
          echo "files=$files" >> $GITHUB_OUTPUT

      - name: Check file lengths
        run: |
          for file in ${{ steps.find.outputs.files }}; do
            lines=$(wc -l < "$file")
            if [ "$lines" -gt 500 ]; then
              echo "::error file=$file::File is $lines lines (max 500)"
              exit 1
            fi
            echo "OK: $file ($lines lines)"
          done

      - name: Check for secrets
        run: |
          for file in ${{ steps.find.outputs.files }}; do
            if grep -qE "password|secret|token|api_key|-----BEGIN" "$file"; then
              echo "::error file=$file::Potential secrets detected"
              grep -nE "password|secret|token|api_key" "$file" || true
              exit 1
            fi
          done
          echo "No secrets detected"

      - name: Check imports
        run: |
          for file in ${{ steps.find.outputs.files }}; do
            dir=$(dirname "$file")
            grep "^@" "$file" | while read -r import; do
              path="${import#@}"
              if [ ! -f "$dir/$path" ]; then
                echo "::error file=$file::Broken import: $import"
                exit 1
              fi
            done
          done
          echo "All imports valid"

With PR Comment

      - name: Post audit summary
        if: always()
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');

            // Collect results
            const results = {
              files: 0,
              passed: 0,
              failed: 0,
              warnings: []
            };

            // Post comment
            await github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: `## CLAUDE.md Audit Results

              - Files checked: ${results.files}
              - Passed: ${results.passed}
              - Failed: ${results.failed}

              ${results.warnings.length > 0 ? '### Warnings\n' + results.warnings.join('\n') : ''}
              `
            });

VS Code Task

tasks.json

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Audit CLAUDE.md",
      "type": "shell",
      "command": "bash",
      "args": [
        "-c",
        "echo 'Auditing CLAUDE.md...' && wc -l CLAUDE.md && grep -c '^##' CLAUDE.md && echo 'Done'"
      ],
      "group": "test",
      "presentation": {
        "reveal": "always",
        "panel": "new"
      },
      "problemMatcher": []
    },
    {
      "label": "Check CLAUDE.md secrets",
      "type": "shell",
      "command": "bash",
      "args": [
        "-c",
        "if grep -qE 'password|secret|token|api_key' CLAUDE.md; then echo 'WARNING: Potential secrets found:' && grep -nE 'password|secret|token|api_key' CLAUDE.md; else echo 'No secrets detected'; fi"
      ],
      "group": "test",
      "problemMatcher": []
    }
  ]
}

Keyboard Shortcut

// keybindings.json
{
  "key": "ctrl+shift+a",
  "command": "workbench.action.tasks.runTask",
  "args": "Audit CLAUDE.md"
}

Husky + lint-staged

Installation

npm install -D husky lint-staged
npx husky init

package.json

{
  "lint-staged": {
    "**/CLAUDE.md": [
      "bash -c 'wc -l \"$0\" | awk \"{if (\\$1 > 500) {print \\\"ERROR: \\\" \\$1 \\\" lines\\\"; exit 1}}\"'",
      "bash -c 'grep -qE \"password|secret|token\" \"$0\" && exit 1 || true'"
    ]
  }
}

.husky/pre-commit

npx lint-staged

GitLab CI

# .gitlab-ci.yml
claude-md-audit:
  stage: test
  rules:
    - changes:
        - "**/CLAUDE.md"
  script:
    - |
      for file in $(find . -name "CLAUDE.md"); do
        echo "Checking $file"
        lines=$(wc -l < "$file")
        if [ "$lines" -gt 500 ]; then
          echo "ERROR: $file is $lines lines"
          exit 1
        fi
      done
    - echo "CLAUDE.md audit passed"

Makefile Target

.PHONY: audit-claude-md

audit-claude-md:
	@echo "Auditing CLAUDE.md files..."
	@find . -name "CLAUDE.md" -exec sh -c '\
		lines=$$(wc -l < "{}"); \
		if [ "$$lines" -gt 500 ]; then \
			echo "ERROR: {} is $$lines lines"; \
			exit 1; \
		fi; \
		echo "OK: {} ($$lines lines)"' \;
	@echo "Checking for secrets..."
	@! grep -rE "password|secret|token|api_key" --include="CLAUDE.md" . || \
		(echo "ERROR: Secrets detected" && exit 1)
	@echo "Audit complete"

Best Practices

  1. Fail fast: Check secrets before anything else
  2. Clear errors: Include file path and line numbers
  3. PR feedback: Post results as comments
  4. Gradual adoption: Start with warnings, then enforce
  5. Skip when needed: Allow [skip audit] in commit message