git clone https://github.com/vibeforge1111/vibeship-spawner-skills
devops/claude-code-cicd/skill.yamlClaude Code CI/CD Skill
CI/CD integration and headless mode automation
id: claude-code-cicd name: Claude Code CI/CD version: 1.0.0 layer: 2 # Integration layer
description: | Expert in integrating Claude Code with CI/CD pipelines. Covers headless mode for non-interactive execution, GitHub Actions and GitLab CI/CD integration, automated code review, issue triage, and PR workflows. Essential for teams wanting AI-powered automation in their development pipelines.
owns:
- Headless mode configuration
- GitHub Actions integration
- GitLab CI/CD integration
- Automated code review pipelines
- Issue triage automation
- PR creation and review workflows
- SDK-based automation
pairs_with:
- claude-code-hooks
- claude-code-commands
- github-actions
- testing-patterns
requires:
- Claude Code CLI
- CI/CD platform (GitHub Actions, GitLab CI/CD)
- API key management
- Pipeline configuration knowledge
ecosystem: primary: - Claude Code CLI - GitHub Actions - GitLab CI/CD - Claude API / Bedrock / Vertex common_integrations: - GitHub CLI (gh) - GitLab CLI (glab) - Docker containers - Secret management platforms: - Linux runners (primary) - macOS runners - Self-hosted runners
prerequisites:
- CI/CD basics
- YAML configuration
- Secret management
- API authentication
limits:
- Headless mode requires -p flag
- No interactive input in pipelines
- Rate limits apply to API calls
- Cost considerations for large-scale use
tags:
- claude-code
- cicd
- automation
- github-actions
- gitlab
- headless
- pipeline
- devops
triggers:
- "claude code CI/CD"
- "headless mode"
- "GitHub Actions claude"
- "GitLab CI claude"
- "automated code review"
- "PR automation"
- "issue triage"
history:
- version: "1.0.0" date: "2025-01" changes: "Initial skill covering CI/CD integration patterns"
contrarian_insights:
- claim: "Run Claude on every PR for review" counter: "Selective triggers (size, labels) reduce cost and noise" evidence: "Teams report alert fatigue from over-automated review"
- claim: "Use largest model for CI/CD" counter: "Smaller models often sufficient for triage; save large for complex reviews" evidence: "Haiku handles labeling; Sonnet for code review; Opus for architecture"
- claim: "Automate PR creation completely" counter: "Human review of AI-generated PRs catches hallucinations" evidence: "Best teams use AI for drafts, humans for final review"
identity: role: Claude Code CI/CD Integration Specialist personality: | You are an expert in running Claude Code in automated pipelines. You understand the constraints of non-interactive execution, the importance of cost management, and the balance between automation and human oversight. You design pipelines that are reliable, cost-effective, and augment rather than replace human judgment. expertise: - Headless mode operation - CI/CD platform configuration - API authentication and secrets - Output parsing and handling - Cost optimization
patterns:
-
name: Basic Headless Execution description: Run Claude Code non-interactively when_to_use: Any automated context (CI, scripts, cron) implementation: |
Headless mode basics
The -p flag enables non-interactive mode
Simple prompt execution
claude -p "Explain what this function does" src/utils.ts
With specific output format
claude -p "List all TODOs in this file" src/main.ts --output-format text
JSON output for parsing
claude -p "Analyze this code for issues" src/api.ts --output-format json
Streaming JSON for real-time processing
claude -p "Review this PR" --output-format stream-json
Environment variables for CI
export ANTHROPIC_API_KEY=${{ secrets.ANTHROPIC_API_KEY }}
Or with explicit provider
claude -p "Review code"
--api-key $ANTHROPIC_API_KEY
--model claude-sonnet-4-20250514With file input
cat changes.diff | claude -p "Review these changes"
Multiple files
claude -p "Find security issues in these files"
src/auth.ts src/api.ts src/db.ts -
name: GitHub Actions Code Review description: Automated PR code review when_to_use: AI-assisted code review on PRs implementation: |
.github/workflows/claude-review.yml
name: Claude Code Review
on: pull_request: types: [opened, synchronize] # Only review substantial changes paths: - 'src/' - '!src//*.test.ts'
jobs: review: runs-on: ubuntu-latest # Skip for very small PRs if: github.event.pull_request.additions > 10
steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Install Claude Code run: npm install -g @anthropic-ai/claude-code - name: Get changed files id: files run: | echo "files=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.(ts|js|py)$' | tr '\n' ' ')" >> $GITHUB_OUTPUT - name: Run Claude Review env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} run: | claude -p "Review these files for bugs, security issues, and code quality. Be concise. Focus on actionable feedback. Files: ${{ steps.files.outputs.files }} Output as markdown suitable for a PR comment." \ --output-format text > review.md - name: Post review comment uses: actions/github-script@v7 with: script: | const fs = require('fs'); const review = fs.readFileSync('review.md', 'utf8'); await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body: `## Claude Code Review\n\n${review}` }); -
name: Issue Triage Automation description: Auto-label and triage new issues when_to_use: Managing issue intake at scale implementation: |
.github/workflows/issue-triage.yml
name: Issue Triage
on: issues: types: [opened]
jobs: triage: runs-on: ubuntu-latest permissions: issues: write
steps: - uses: actions/checkout@v4 - name: Install Claude Code run: npm install -g @anthropic-ai/claude-code - name: Analyze issue id: analyze env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} run: | # Use smaller model for triage (cost effective) claude -p "Analyze this GitHub issue and return JSON: { \"labels\": [\"bug\"|\"feature\"|\"docs\"|\"question\"], \"priority\": \"high\"|\"medium\"|\"low\", \"area\": \"frontend\"|\"backend\"|\"infra\"|\"other\", \"needs_info\": true|false, \"summary\": \"one line summary\" } Issue Title: ${{ github.event.issue.title }} Issue Body: ${{ github.event.issue.body }}" \ --model claude-haiku-3-5 \ --output-format json > analysis.json echo "result=$(cat analysis.json)" >> $GITHUB_OUTPUT - name: Apply labels uses: actions/github-script@v7 with: script: | const analysis = JSON.parse('${{ steps.analyze.outputs.result }}'); // Apply labels const labels = [ ...analysis.labels, `priority:${analysis.priority}`, `area:${analysis.area}` ]; await github.rest.issues.addLabels({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, labels: labels }); // If needs more info, add comment if (analysis.needs_info) { await github.rest.issues.createComment({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, body: "Thanks for opening this issue! Could you provide more details about:\n- Steps to reproduce\n- Expected vs actual behavior\n- Your environment" }); } -
name: GitLab CI/CD Integration description: Claude Code in GitLab pipelines when_to_use: GitLab-based projects implementation: |
.gitlab-ci.yml
stages: - review - test - deploy
variables: CLAUDE_MODEL: claude-sonnet-4-20250514
claude-review: stage: review image: node:20 rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" before_script: - npm install -g @anthropic-ai/claude-code script: # Get MR diff - git diff origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME...HEAD > changes.diff
# Run Claude review - | claude -p "Review this diff for a merge request. Focus on: bugs, security issues, performance problems. Format as GitLab markdown. $(cat changes.diff)" \ --output-format text > review.md # Post to MR (using GitLab API) - | curl --request POST \ --header "PRIVATE-TOKEN: $GITLAB_API_TOKEN" \ --header "Content-Type: application/json" \ --data "{\"body\": \"## Claude Review\n\n$(cat review.md | jq -Rs .)\"}" \ "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes" variables: ANTHROPIC_API_KEY: $ANTHROPIC_API_KEYAutomated fix suggestions
claude-fix: stage: review image: node:20 rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" when: manual # Manual trigger to control costs script: - npm install -g @anthropic-ai/claude-code - git config user.email "claude-bot@example.com" - git config user.name "Claude Bot"
# Run Claude to fix issues - | claude -p "Fix any linting errors and type issues in the changed files. Do not make other changes." \ --allowedTools "Edit,Bash(npm run lint:fix)" # If changes made, commit them - | if [ -n "$(git status --porcelain)" ]; then git add . git commit -m "fix: Auto-fix linting issues [Claude]" git push origin HEAD:$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME fi -
name: Automated PR Creation description: Create PRs from issues or descriptions when_to_use: Converting specs to code implementation: |
.github/workflows/auto-implement.yml
name: Auto-implement Issue
on: issues: types: [labeled]
jobs: implement: runs-on: ubuntu-latest if: github.event.label.name == 'auto-implement' permissions: contents: write pull-requests: write
steps: - uses: actions/checkout@v4 with: token: ${{ secrets.GITHUB_TOKEN }} - name: Setup Git run: | git config user.email "claude-bot@users.noreply.github.com" git config user.name "Claude Bot" - name: Install Claude Code run: npm install -g @anthropic-ai/claude-code - name: Create branch run: | BRANCH="auto/issue-${{ github.event.issue.number }}" git checkout -b $BRANCH echo "branch=$BRANCH" >> $GITHUB_ENV - name: Implement feature env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} run: | # Let Claude implement with controlled tools claude -p "Implement this feature request: Title: ${{ github.event.issue.title }} Description: ${{ github.event.issue.body }} Requirements: 1. Follow existing code patterns 2. Add tests for new functionality 3. Update documentation if needed 4. Make atomic, focused commits" \ --allowedTools "Read,Write,Edit,Bash(npm test),Bash(npm run lint)" - name: Create PR env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | git push origin ${{ env.branch }} gh pr create \ --title "Implement: ${{ github.event.issue.title }}" \ --body "Automated implementation of #${{ github.event.issue.number }} This PR was generated by Claude Code. Please review carefully before merging. Closes #${{ github.event.issue.number }}" \ --base main \ --head ${{ env.branch }} \ --label "auto-generated" -
name: SDK-Based Automation description: Programmatic Claude Code control when_to_use: Complex automation requiring code implementation: | // Using Claude Code SDK for programmatic control // automation/review-service.ts
import Anthropic from "@anthropic-ai/sdk"; import { execSync } from "child_process";
interface ReviewRequest { files: string[]; context: string; strictness: "lenient" | "normal" | "strict"; }
interface ReviewResult { summary: string; issues: Array<{ file: string; line: number; severity: "error" | "warning" | "info"; message: string; }>; approved: boolean; }
async function reviewCode(request: ReviewRequest): Promise<ReviewResult> { // Read file contents const fileContents = request.files.map(file => { const content = execSync(
).toString(); returncat ${file}
``\n${content}\n````; }).join("\n\n");### ${file}\n\// Use Claude Code in headless mode via SDK const result = execSync( `claude -p "${buildPrompt(request, fileContents)}" --output-format json`, { env: { ...process.env, ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY } } ).toString(); return JSON.parse(result);}
function buildPrompt(request: ReviewRequest, files: string): string { const strictnessGuide = { lenient: "Focus only on critical bugs and security issues", normal: "Balance thoroughness with practicality", strict: "Apply rigorous standards, flag all potential issues" };
return `You are reviewing code for a PR. Context: ${request.context} Review strictness: ${request.strictness} Guidelines: ${strictnessGuide[request.strictness]} Files to review: ${files} Return JSON matching this schema: { "summary": "Brief overall assessment", "issues": [ { "file": "path/to/file", "line": 42, "severity": "error|warning|info", "message": "Description of issue" } ], "approved": true/false }`;}
// Usage in CI script async function main() { const changedFiles = execSync( "git diff --name-only origin/main...HEAD" ).toString().trim().split("\n");
const result = await reviewCode({ files: changedFiles.filter(f => f.endsWith(".ts")), context: "Feature branch for user authentication", strictness: "normal" }); console.log(JSON.stringify(result, null, 2)); // Exit with error if not approved if (!result.approved) { process.exit(1); }}
main();
anti_patterns:
-
name: Running Claude on Every Commit description: Triggering Claude for every single commit why_bad: | Expensive - each run costs money. Slow - adds latency to every commit. Noisy - too many reviews causes alert fatigue. what_to_do_instead: | Trigger on PR events, not individual commits. Add size filters (skip very small PRs). Use labels for opt-in expensive analysis.
-
name: Unbounded Tool Access in CI description: Not restricting which tools Claude can use why_bad: | CI environments need controlled access. Unrestricted Bash could run dangerous commands. Could accidentally push or delete things. what_to_do_instead: | Use --allowedTools to whitelist specific tools. claude -p "..." --allowedTools "Read,Edit,Bash(npm test)"
-
name: Secrets in Prompts description: Including secrets directly in prompt text why_bad: | Secrets appear in logs. Prompt text may be stored/logged. Security risk in multi-tenant CI. what_to_do_instead: | Use environment variables. export ANTHROPIC_API_KEY=${{ secrets.KEY }} Never echo or cat secrets.
-
name: No Cost Controls description: Running without usage limits or model tiers why_bad: | Costs can spiral unexpectedly. Large PRs trigger large context. No visibility into spend. what_to_do_instead: | Use Haiku for triage, Sonnet for review. Set --max-tokens to limit output. Add spend monitoring and alerts.
-
name: Trusting AI Output Blindly description: Auto-merging or deploying based solely on AI approval why_bad: | AI can hallucinate or miss issues. Removes human accountability. Risky for security-sensitive code. what_to_do_instead: | Use AI for draft reviews, human for final approval. AI suggests, human decides. Keep auto-merge for low-risk changes only.
handoffs:
-
trigger: "hook|lifecycle|enforce" to: claude-code-hooks context: "Need local hook configuration for CI parity"
-
trigger: "custom command|slash command" to: claude-code-commands context: "Need commands that work in headless mode"
-
trigger: "GitHub Actions workflow|Actions syntax" to: github-actions context: "Need GitHub Actions expertise"
-
trigger: "test|testing strategy" to: testing-patterns context: "Need testing patterns for CI"