Claude-code-plugins windsurf-ci-integration
install
source · Clone the upstream repo
git clone https://github.com/jeremylongshore/claude-code-plugins-plus-skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/jeremylongshore/claude-code-plugins-plus-skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/saas-packs/windsurf-pack/skills/windsurf-ci-integration" ~/.claude/skills/jeremylongshore-claude-code-plugins-windsurf-ci-integration && rm -rf "$T"
manifest:
plugins/saas-packs/windsurf-pack/skills/windsurf-ci-integration/SKILL.mdsource content
Windsurf CI Integration
Overview
Integrate Windsurf configuration validation and AI code quality gates into CI/CD pipelines. Covers validating
.windsurfrules, enforcing team policies for AI-generated code, and automating Windsurf config distribution.
Prerequisites
- GitHub repository with Actions enabled
- Windsurf configuration files in repository
- Team agreement on AI code review policy
Instructions
Step 1: Validate Windsurf Config in CI
# .github/workflows/windsurf-config.yml name: Windsurf Config Validation on: pull_request: paths: - '.windsurfrules' - '.codeiumignore' - '.windsurf/**' jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Check .windsurfrules exists and is valid run: | if [ ! -f .windsurfrules ]; then echo "::error::.windsurfrules is missing" exit 1 fi CHARS=$(wc -c < .windsurfrules) if [ "$CHARS" -gt 6000 ]; then echo "::error::.windsurfrules exceeds 6000 char limit ($CHARS chars)" exit 1 fi echo ".windsurfrules: $CHARS chars (limit: 6000)" - name: Check .codeiumignore covers secrets run: | REQUIRED_PATTERNS=(".env" "*.pem" "*.key" "credentials") MISSING=() for pattern in "${REQUIRED_PATTERNS[@]}"; do if ! grep -q "$pattern" .codeiumignore 2>/dev/null; then MISSING+=("$pattern") fi done if [ ${#MISSING[@]} -gt 0 ]; then echo "::warning::.codeiumignore missing patterns: ${MISSING[*]}" fi - name: Validate workspace rules frontmatter run: | for rule in .windsurf/rules/*.md; do [ -f "$rule" ] || continue if ! head -1 "$rule" | grep -q "^---"; then echo "::error::$rule missing YAML frontmatter" exit 1 fi # Check for required trigger field if ! grep -q "^trigger:" "$rule"; then echo "::warning::$rule missing 'trigger:' in frontmatter" fi done
Step 2: AI Code Quality Gate
# .github/workflows/ai-code-review.yml name: AI Code Quality Gate on: pull_request jobs: ai-review: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: { fetch-depth: 0 } - name: Detect large AI-generated changesets run: | FILES_CHANGED=$(git diff --name-only origin/main..HEAD | wc -l) if [ "$FILES_CHANGED" -gt 20 ]; then echo "::warning::Large changeset ($FILES_CHANGED files). If AI-generated, ensure thorough review." fi - name: Enforce tests for new source files run: | NEW_SRC=$(git diff --name-only --diff-filter=A origin/main..HEAD | grep -cE '\.(ts|js|tsx|jsx)$' || true) NEW_TEST=$(git diff --name-only --diff-filter=A origin/main..HEAD | grep -cE '\.(test|spec)\.' || true) if [ "$NEW_SRC" -gt 3 ] && [ "$NEW_TEST" -eq 0 ]; then echo "::error::$NEW_SRC new source files added without tests" exit 1 fi - name: Check for hardcoded secrets in new files run: | git diff origin/main..HEAD -- '*.ts' '*.js' '*.tsx' '*.jsx' | \ grep -E '(sk_live|sk_test|AKIA|ghp_|glpat-|xoxb-)' && { echo "::error::Potential hardcoded secret detected" exit 1 } || true
Step 3: Distribute Windsurf Config Templates
# .github/workflows/sync-windsurf-config.yml name: Sync Windsurf Config on: push: branches: [main] paths: ['windsurf-templates/**'] jobs: distribute: runs-on: ubuntu-latest strategy: matrix: repo: [frontend, backend, mobile] steps: - uses: actions/checkout@v4 - name: Push config to child repos run: | gh api repos/${{ github.repository_owner }}/${{ matrix.repo }}/contents/.windsurfrules \ --method PUT \ --field message="chore: sync windsurf config from monorepo" \ --field content="$(base64 -w0 windsurf-templates/.windsurfrules)" env: GH_TOKEN: ${{ secrets.REPO_SYNC_TOKEN }}
Step 4: Cascade-Generated Commit Convention
Enforce commit message conventions for AI-generated code:
# In branch protection or CI - name: Check AI commit convention run: | COMMITS=$(git log origin/main..HEAD --pretty=format:"%s") # If PR has many file changes, warn about AI commit tagging FILES=$(git diff --stat origin/main..HEAD | tail -1 | awk '{print $1}') if [ "$FILES" -gt 10 ]; then if ! echo "$COMMITS" | grep -q "\[cascade\]"; then echo "::notice::Large changeset without [cascade] tag. If AI-generated, tag commits with [cascade] prefix." fi fi
Step 5: MCP Server Health Check (Optional)
- name: Validate MCP config run: | MCP_CONFIG="$HOME/.codeium/windsurf/mcp_config.json" if [ -f "$MCP_CONFIG" ]; then python3 -c "import json; json.load(open('$MCP_CONFIG'))" || { echo "::error::MCP config is invalid JSON" exit 1 } fi
Error Handling
| Issue | Cause | Solution |
|---|---|---|
| .windsurfrules over limit | Too many rules | Split into workspace rules in |
| Secret detected in diff | AI generated hardcoded key | Remove, rotate, add to |
| Config sync fails | Token lacks repo access | Update permissions |
| Frontmatter validation fails | Missing trigger field | Add or appropriate mode |
Examples
Branch Protection Rules
# Recommended for teams using Windsurf Cascade required_status_checks: - "windsurf-config" - "ai-code-review" - "test"
Pre-Commit Hook for .windsurfrules
#!/bin/bash # .git/hooks/pre-commit CHARS=$(wc -c < .windsurfrules 2>/dev/null || echo 0) if [ "$CHARS" -gt 6000 ]; then echo "ERROR: .windsurfrules exceeds 6000 char limit ($CHARS chars)" exit 1 fi
Resources
Next Steps
For deployment patterns, see
windsurf-deploy-integration.