Skip to content
Back to News
guide
ci-cd
automation

Adding CKB to Your CI Pipeline

By CKB Team

CKB isn't just for interactive AI sessions. Its analysis tools integrate directly into CI pipelines, catching issues before they reach production.

This guide covers GitHub Actions, GitLab CI, and general CI integration patterns.

What CKB Checks in CI

  • Dead code - Unused functions and types
  • Coupling violations - Modules that shouldn't depend on each other
  • Ownership drift - Code areas losing their maintainers
  • Impact assessment - PRs that touch high-risk areas
  • Test coverage gaps - Changes without corresponding tests

GitHub Actions

Basic Setup

# .github/workflows/ckb-analysis.yml
name: CKB Analysis

on:
  pull_request:
    branches: [main]

jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Full history for ownership analysis

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

      - name: Install CKB
        run: npm install -g @tastehub/ckb

      - name: Initialize and index
        run: |
          ckb init
          ckb index

      - name: Run analysis
        run: ckb analyze --format=github

Dead Code Check

Fail the build if new dead code is introduced:

- name: Check for dead code
  run: |
    ckb findDeadCode --format=json > dead-code.json

    NEW_DEAD=$(jq '[.[] | select(.confidence == "high")] | length' dead-code.json)

    if [ "$NEW_DEAD" -gt 0 ]; then
      echo "::error::Found $NEW_DEAD new dead code items"
      jq -r '.[] | select(.confidence == "high") | "::warning file=\(.file),line=\(.line)::\(.name) appears to be unused"' dead-code.json
      exit 1
    fi

Impact Analysis on PRs

Add impact summary as a PR comment:

- name: Analyze PR impact
  env:
    GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  run: |
    # Get changed files
    CHANGED=$(gh pr view ${{ github.event.pull_request.number }} --json files -q '.files[].path')

    # Run impact analysis
    ckb analyze-changes --files="$CHANGED" --format=markdown > impact.md

    # Post as comment
    gh pr comment ${{ github.event.pull_request.number }} --body-file impact.md

Ownership Validation

Ensure PRs have appropriate reviewers:

- name: Check ownership
  run: |
    # Get files in PR
    FILES=$(git diff --name-only origin/main...HEAD)

    # Get suggested reviewers
    REVIEWERS=$(ckb getReviewers --files="$FILES" --format=json | jq -r '.suggested[]')

    # Check if any owner is assigned
    ASSIGNED=$(gh pr view ${{ github.event.pull_request.number }} --json reviewRequests -q '.reviewRequests[].login')

    for reviewer in $REVIEWERS; do
      if echo "$ASSIGNED" | grep -q "$reviewer"; then
        echo "✓ Owner $reviewer is assigned"
        exit 0
      fi
    done

    echo "::warning::None of the suggested owners ($REVIEWERS) are assigned as reviewers"

GitLab CI

Basic Setup

# .gitlab-ci.yml
ckb-analysis:
  image: node:20
  stage: test
  before_script:
    - npm install -g @tastehub/ckb
    - ckb init
    - ckb index
  script:
    - ckb analyze --format=gitlab
  artifacts:
    reports:
      codequality: ckb-report.json

Merge Request Analysis

ckb-mr-analysis:
  image: node:20
  stage: test
  only:
    - merge_requests
  script:
    - npm install -g @tastehub/ckb
    - ckb init && ckb index

    # Analyze changed files
    - |
      CHANGED=$(git diff --name-only $CI_MERGE_REQUEST_DIFF_BASE_SHA...HEAD)
      ckb analyze-changes --files="$CHANGED" --format=gitlab-note > note.md

    # Post to MR (requires GITLAB_TOKEN)
    - |
      curl --request POST \
        --header "PRIVATE-TOKEN: $GITLAB_TOKEN" \
        --data-urlencode "body@note.md" \
        "$CI_API_V4_URL/projects/$CI_PROJECT_ID/merge_requests/$CI_MERGE_REQUEST_IID/notes"

General CI Integration

JSON Output

All CKB commands support JSON output for easy parsing:

# Dead code as JSON
ckb findDeadCode --format=json

# Impact analysis as JSON
ckb prepareChange --target=src/auth --format=json

# Architecture as JSON
ckb getArchitecture --format=json

Exit Codes

CKB uses standard exit codes:

  • 0 - Success, no issues
  • 1 - Analysis found issues (dead code, coupling, etc.)
  • 2 - CKB error (missing index, invalid config)

Caching the Index

Speed up CI by caching the CKB index:

GitHub Actions:

- uses: actions/cache@v4
  with:
    path: .ckb/
    key: ckb-index-${{ hashFiles('**/*.go', '**/*.ts', '**/*.py') }}
    restore-keys: |
      ckb-index-

GitLab CI:

cache:
  key: ckb-index
  paths:
    - .ckb/

Workflow Examples

Quality Gate

Block merges if quality degrades:

quality-gate:
  script:
    - ckb init && ckb index

    # Check coupling score
    - |
      COUPLING=$(ckb analyzeCoupling --format=json | jq '.score')
      if [ "$COUPLING" -gt 70 ]; then
        echo "Coupling score $COUPLING exceeds threshold (70)"
        exit 1
      fi

    # Check dead code
    - |
      DEAD=$(ckb findDeadCode --format=json | jq 'length')
      BASELINE=$(cat .ckb/baselines/dead-code-count || echo 0)
      if [ "$DEAD" -gt "$BASELINE" ]; then
        echo "Dead code increased from $BASELINE to $DEAD"
        exit 1
      fi

Nightly Analysis

Run comprehensive analysis on a schedule:

# .github/workflows/nightly-analysis.yml
name: Nightly Code Analysis

on:
  schedule:
    - cron: '0 2 * * *'  # 2 AM daily

jobs:
  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Full analysis
        run: |
          npm install -g @tastehub/ckb
          ckb init && ckb index

          # Generate comprehensive report
          ckb report --full --format=html > report.html

          # Upload as artifact
          echo "Report generated"

      - uses: actions/upload-artifact@v4
        with:
          name: ckb-report
          path: report.html

PR Size Warning

Warn on large PRs that skip analysis:

- name: Check PR size
  run: |
    CHANGED=$(git diff --name-only origin/main...HEAD | wc -l)

    if [ "$CHANGED" -gt 50 ]; then
      echo "::warning::Large PR ($CHANGED files). Consider breaking into smaller changes."

      # Run extra thorough analysis
      ckb analyze --depth=deep --format=github
    fi

Metrics and Tracking

Export Metrics

Send CKB metrics to your observability platform:

- name: Export metrics
  run: |
    METRICS=$(ckb status --format=json)

    # Send to Datadog
    curl -X POST "https://api.datadoghq.com/api/v1/series" \
      -H "DD-API-KEY: $DATADOG_API_KEY" \
      -d @- << EOF
    {
      "series": [{
        "metric": "ckb.dead_code_count",
        "points": [$(date +%s), $(echo $METRICS | jq '.deadCode')](/docs/$(date-+%s),-$(echo-$METRICS-|-jq-'.deadCode')),
        "type": "gauge"
      }, {
        "metric": "ckb.coupling_score",
        "points": [$(date +%s), $(echo $METRICS | jq '.couplingScore')](/docs/$(date-+%s),-$(echo-$METRICS-|-jq-'.couplingScore')),
        "type": "gauge"
      }]
    }
    EOF

Trend Tracking

Store baselines to track trends:

- name: Update baselines
  if: github.ref == 'refs/heads/main'
  run: |
    mkdir -p .ckb/baselines
    ckb findDeadCode --format=json | jq 'length' > .ckb/baselines/dead-code-count
    ckb analyzeCoupling --format=json | jq '.score' > .ckb/baselines/coupling-score

    # Commit baselines
    git config user.name "CKB Bot"
    git config user.email "ckb@example.com"
    git add .ckb/baselines
    git commit -m "Update CKB baselines" || true
    git push

Best Practices

  1. Cache the index - Rebuilding on every commit is slow
  2. Run incrementally on PRs - Full analysis nightly, targeted analysis on PRs
  3. Set reasonable thresholds - Start permissive, tighten over time
  4. Don't block on warnings - Use annotations, not failures, for advisory issues
  5. Track trends - Metrics over time matter more than absolute values

Links: