Skip to content

CI CD Integration

Lisa edited this page Dec 22, 2025 · 23 revisions

CI/CD Integration

CKB becomes your single source of truth for change risk in CI/CD pipelines. Instead of treating code review as a human-only process, CKB provides precomputed analysis that travels with every PR:

  • Blast radius — Know exactly what breaks before merging
  • Suggested reviewers — Based on actual code ownership, not guesswork
  • Boundary detection — Flag when "local" changes cross API contracts
  • Risk scoring — Quantified risk based on hotspots, module spread, and history

The pattern: start CKB as a local server, call it with curl, parse JSON responses.

What It Actually Does

When you call POST /pr/summary, CKB:

  1. Diffs the branches using git (base vs head)
  2. Maps files to modules based on path structure
  3. Checks each file against hotspot data — flags files with score > 0.5
  4. Queries ownership for each changed file (CODEOWNERS + git-blame)
  5. Calculates risk based on: file count, lines changed, hotspots touched, module spread
  6. Returns structured JSON with everything a PR comment needs

Example response shape:

{
  "summary": {
    "totalFiles": 12,
    "totalAdditions": 450,
    "totalDeletions": 120,
    "totalModules": 3,
    "hotspotsTouched": 2
  },
  "riskAssessment": {
    "level": "medium",
    "score": 0.45,
    "factors": ["Touches 2 hotspot(s)", "Spans 3 modules"],
    "suggestions": ["Extra review recommended for hotspot files"]
  },
  "suggestedReviewers": [
    {"owner": "@api-team", "reason": "Owns 8 of 12 changed files", "coverage": 0.67}
  ],
  "modulesAffected": [
    {"moduleId": "internal/api", "filesChanged": 8, "riskLevel": "medium"}
  ]
}

How It Works in GitHub Actions

CKB runs as a local HTTP server inside the runner. The workflow:

  1. Checkout with full history (fetch-depth: 0)
  2. Install CKB
  3. Start server: ckb serve --port 8080 &
  4. Call endpoints with curl
  5. Parse JSON, post PR comment

Installation in CI

npm (Recommended):

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

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

Or use npx (no install):

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

- name: Initialize CKB
  run: npx @tastehub/ckb init

Or download pre-built binary:

- run: |
    curl -sSL https://github.com/SimplyLiz/CodeMCP/releases/latest/download/ckb_linux_amd64.tar.gz | tar xz
    sudo mv ckb /usr/local/bin/

Or build from source:

- uses: actions/setup-go@v5
  with:
    go-version: '1.21'

- name: Install CKB
  run: |
    git clone https://github.com/SimplyLiz/CodeMCP.git /tmp/codemcp
    cd /tmp/codemcp
    go build -o /usr/local/bin/ckb ./cmd/ckb

Critical: Full Git History

CKB needs git history for ownership analysis. Without it, suggested reviewers will be empty.

- uses: actions/checkout@v4
  with:
    fetch-depth: 0  # Required

Environment Validation (v7.2)

Before running CKB analysis, validate that your CI environment has the required tooling installed. The ckb doctor --tier command checks for language-specific tools and outputs JSON for scripting.

Validate CI Environment

- name: Validate CKB Environment
  run: |
    # Check if required tools are installed for standard tier
    RESULT=$(ckb doctor --tier=standard --format json)

    # Check for missing tools
    MISSING=$(echo "$RESULT" | jq '[.languages[] | select(.status == "missing")] | length')

    if [ "$MISSING" -gt 0 ]; then
      echo "::warning::Missing $MISSING language tools"
      echo "$RESULT" | jq '.languages[] | select(.status == "missing") | "\(.name): \(.installCmd)"'
    fi

Tier-Specific Validation

Different tiers require different tools:

Tier Tools Required Use Case
fast None (tree-sitter built-in) Quick PR checks
standard SCIP indexers (scip-go, scip-typescript, etc.) Full code intelligence
full Standard + LSP servers Maximum accuracy
- name: Check Standard Tier Readiness
  run: |
    # Fail if standard tier tools aren't available
    ckb doctor --tier=standard --format json | jq -e '.ready == true' || {
      echo "::error::CI environment missing required tools for standard tier"
      ckb doctor --tier=standard
      exit 1
    }

Install Missing Tools

- name: Setup Go Indexer
  run: |
    # Check if scip-go is needed and missing
    if ckb doctor --tier=standard --format json | jq -e '.languages[] | select(.name == "go" and .status == "missing")' > /dev/null 2>&1; then
      go install github.com/sourcegraph/scip-go/cmd/scip-go@latest
    fi

PR Analysis Workflow

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

on:
  pull_request:
    types: [opened, synchronize, reopened]

permissions:
  contents: read
  pull-requests: write

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

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

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

      - name: Initialize CKB
        run: |
          ckb init
          ckb doctor --fix

      - name: Start CKB Server
        run: |
          ckb serve --port 8080 &
          sleep 2  # Wait for server to start

      - name: Run PR Summary
        id: summary
        run: |
          RESULT=$(curl -s -X POST http://localhost:8080/pr/summary \
            -H "Content-Type: application/json" \
            -d '{"baseBranch": "${{ github.base_ref }}"}')

          RISK=$(echo "$RESULT" | jq -r '.riskAssessment.level // "unknown"')
          echo "risk=$RISK" >> $GITHUB_OUTPUT
          echo "result<<EOF" >> $GITHUB_OUTPUT
          echo "$RESULT" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT

      - name: Post Comment
        uses: actions/github-script@v7
        with:
          script: |
            const data = JSON.parse(`${{ steps.summary.outputs.result }}`);
            let emoji = data.riskAssessment?.level === 'high' ? '🔴' :
                        data.riskAssessment?.level === 'medium' ? '🟡' : '🟢';

            let body = `## CKB Analysis ${emoji}\n\n`;
            body += `**Risk:** ${data.riskAssessment?.level || 'unknown'}\n`;
            body += `**Files:** ${data.summary?.totalFiles || 0}\n`;
            body += `**Hotspots touched:** ${data.summary?.hotspotsTouched || 0}\n\n`;

            if (data.suggestedReviewers?.length) {
              body += `### Suggested Reviewers\n`;
              data.suggestedReviewers.slice(0,3).forEach(r => {
                body += `- ${r.owner}\n`;
              });
            }

            github.rest.issues.createComment({
              owner: context.repo.owner,
              repo: context.repo.repo,
              issue_number: context.issue.number,
              body: body
            });

Incremental Indexing in CI (v7.3)

For Go projects, CKB supports incremental indexing that only processes changed files. This can dramatically speed up CI pipelines.

Why Use Incremental Indexing in CI?

Scenario Full Index Incremental
Large Go project (10k files) ~60s ~2-5s
Typical PR (5-10 files changed) ~60s ~1-2s
Single file hotfix ~60s <1s

The key insight: PR pipelines typically change a small fraction of files. Incremental indexing is O(changed files), not O(total files).

Basic Incremental Workflow

- name: Restore CKB Cache
  uses: actions/cache@v4
  with:
    path: .ckb/
    key: ckb-${{ runner.os }}-${{ hashFiles('go.sum') }}
    restore-keys: |
      ckb-${{ runner.os }}-

- name: Index (Incremental)
  run: |
    ckb init
    ckb index  # Incremental by default for Go

    # Show what was updated
    echo "Index complete"

When to Use --force

# Nightly: Full reindex for maximum accuracy
- name: Nightly Full Index
  if: github.event_name == 'schedule'
  run: ckb index --force

# PR: Incremental for speed
- name: PR Incremental Index
  if: github.event_name == 'pull_request'
  run: ckb index

Use --force for nightly builds when accuracy matters. Use incremental for PRs when speed matters. For PR analysis, incremental is usually sufficient—you care about what the changed code does, not what calls it.

See Incremental Indexing for accuracy guarantees, transitive invalidation modes, and troubleshooting.

Caching Strategy

For incremental indexing to work across CI runs, you must cache the .ckb/ directory:

- name: Restore CKB Cache
  uses: actions/cache@v4
  with:
    path: .ckb/
    key: ckb-${{ runner.os }}-${{ github.ref }}-${{ github.sha }}
    restore-keys: |
      ckb-${{ runner.os }}-${{ github.ref }}-
      ckb-${{ runner.os }}-

- name: Index
  run: |
    ckb init
    ckb index

- name: Save CKB Cache
  uses: actions/cache/save@v4
  if: always()
  with:
    path: .ckb/
    key: ckb-${{ runner.os }}-${{ github.ref }}-${{ github.sha }}

Cache key strategy:

  • Include github.sha for exact match on re-runs
  • Include github.ref to separate branch caches
  • Use restore-keys to fall back to older caches

Complete Incremental CI Workflow

# .github/workflows/ckb-incremental.yml
name: CKB Analysis (Incremental)

on:
  pull_request:
  push:
    branches: [main]

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

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

      - uses: actions/setup-go@v5
        with:
          go-version: '1.21'

      - name: Install Tools
        run: |
          npm install -g @tastehub/ckb
          go install github.com/sourcegraph/scip-go/cmd/scip-go@latest

      - name: Restore Cache
        uses: actions/cache@v4
        with:
          path: .ckb/
          key: ckb-${{ runner.os }}-${{ github.ref }}-${{ github.sha }}
          restore-keys: |
            ckb-${{ runner.os }}-${{ github.ref }}-
            ckb-${{ runner.os }}-

      - name: Index
        run: |
          ckb init
          # Use --force on main branch pushes for accuracy
          if [ "${{ github.event_name }}" = "push" ] && [ "${{ github.ref }}" = "refs/heads/main" ]; then
            ckb index --force
          else
            ckb index
          fi

      - name: Analyze
        run: |
          ckb serve --port 8080 &
          sleep 2
          curl -s http://localhost:8080/status | jq .

      - name: Save Cache
        uses: actions/cache/save@v4
        if: always()
        with:
          path: .ckb/
          key: ckb-${{ runner.os }}-${{ github.ref }}-${{ github.sha }}

Lock File Behavior

CKB uses a lock file (.ckb/index.lock) to prevent concurrent indexing. In CI:

  • If a previous step is still indexing, subsequent ckb index calls will wait
  • Lock is automatically released on process exit
  • Stale locks (from crashed processes) are detected and removed

This is safe for parallel jobs as long as they don't share the same .ckb/ directory.


Scheduled Architecture Refresh

Run daily to keep architectural data fresh:

# .github/workflows/ckb-refresh.yml
name: CKB Architecture Refresh

on:
  schedule:
    - cron: '0 2 * * *'  # Daily at 2 AM UTC
  workflow_dispatch:
    inputs:
      force:
        description: 'Force full refresh'
        type: boolean
        default: false

permissions:
  contents: write

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

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

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

      - name: Initialize and Start Server
        run: |
          ckb init
          ckb serve --port 8080 &
          sleep 2

      - name: Refresh Architecture
        run: |
          curl -s -X POST http://localhost:8080/architecture/refresh \
            -H "Content-Type: application/json" \
            -d '{"scope": "all", "force": ${{ inputs.force || false }}}'

      - name: Generate Reports
        run: |
          curl -s "http://localhost:8080/hotspots?limit=20" > hotspots.json
          curl -s "http://localhost:8080/ownership/drift?threshold=0.3" > drift.json

      - name: Upload Reports
        uses: actions/upload-artifact@v4
        with:
          name: ckb-reports
          path: '*.json'
          retention-days: 30

      - name: Cache CKB Database
        run: |
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git config user.name "github-actions[bot]"
          git add .ckb/
          git diff --staged --quiet || git commit -m "chore: update CKB cache [skip ci]"
          git push

Using Async Refresh in CI

For large repositories, use async mode to avoid timeouts:

- name: Start CKB Server
  run: |
    ckb init
    ckb serve --port 8080 &
    sleep 2

- name: Start Async Refresh
  id: refresh
  run: |
    RESULT=$(curl -s -X POST http://localhost:8080/architecture/refresh \
      -H "Content-Type: application/json" \
      -d '{"scope": "all", "async": true}')
    JOB_ID=$(echo "$RESULT" | jq -r '.jobId')
    echo "job_id=$JOB_ID" >> $GITHUB_OUTPUT

- name: Wait for Completion
  run: |
    JOB_ID="${{ steps.refresh.outputs.job_id }}"
    while true; do
      STATUS=$(curl -s "http://localhost:8080/jobs/$JOB_ID")
      STATE=$(echo "$STATUS" | jq -r '.status')
      PROGRESS=$(echo "$STATUS" | jq -r '.progress')

      echo "Job $JOB_ID: $STATE ($PROGRESS%)"

      if [ "$STATE" = "completed" ]; then
        echo "$STATUS" | jq .result
        break
      elif [ "$STATE" = "failed" ]; then
        echo "Job failed: $(echo $STATUS | jq -r '.error')"
        exit 1
      fi

      sleep 5
    done

Available Endpoints

POST /pr/summary — The main CI endpoint

Request:

{"baseBranch": "main", "headBranch": "HEAD"}

Returns: File counts, module impacts, hotspots touched, risk assessment (low/medium/high), suggested reviewers with coverage percentages.

Risk is calculated from:

  • File count (>20 files = +0.3 risk)
  • Lines changed (>1000 = +0.3 risk)
  • Hotspots touched (+0.1 per hotspot, max 0.3)
  • Module spread (>5 modules = +0.2 risk)

GET /ownership/drift — CODEOWNERS accuracy check

curl "http://localhost:8080/ownership/drift?threshold=0.3&limit=10"

Compares declared owners (CODEOWNERS) vs actual contributors (git-blame). Returns files where ownership has drifted, with drift scores.


GET /hotspots — High-churn files

curl "http://localhost:8080/hotspots?limit=20"

Returns files ranked by volatility (commit frequency, author count, complexity).


POST /architecture/refresh — Rebuild cached analysis

curl -X POST http://localhost:8080/architecture/refresh \
  -H "Content-Type: application/json" \
  -d '{"scope": "all", "async": true}'

With async: true, returns a jobId immediately. Poll /jobs/:id for completion.


GET /jobs/:id — Check async job status

curl "http://localhost:8080/jobs/job-abc123"

Returns: status (queued/running/completed/failed), progress (0-100), result (when done).


Contract-Aware CI (v6.3)

When changes touch API contracts (protobuf, OpenAPI), CKB can detect cross-boundary impact that simple file diffs miss.

Why This Matters

A "local" change to user.proto might break consumers in three other repositories. Without contract analysis, this surfaces as production incidents, not PR warnings.

Detecting Contract Changes

- name: Check Contract Impact
  run: |
    # Find changed contract files
    CONTRACTS=$(git diff --name-only ${{ github.base_ref }}...HEAD | grep -E '\.(proto|yaml|json)$' | grep -E '(proto/|openapi/|api/)' || true)

    if [ -n "$CONTRACTS" ]; then
      echo "⚠️ Contract files changed:"
      echo "$CONTRACTS"

      for CONTRACT in $CONTRACTS; do
        echo "Analyzing impact of $CONTRACT..."
        curl -s "http://localhost:8080/contracts/impact?path=$CONTRACT" | jq .
      done
    fi

Contract Impact Response

{
  "contract": "proto/api/v1/user.proto",
  "visibility": "public",
  "consumers": [
    {"repo": "frontend", "confidence": "high", "files": ["src/api/user.ts"]},
    {"repo": "mobile-app", "confidence": "medium", "files": ["lib/api/user.dart"]}
  ],
  "riskLevel": "high",
  "riskFactors": [
    "Public contract with 2 known consumers",
    "Breaking field removal detected"
  ],
  "suggestion": "Coordinate with frontend and mobile-app teams before merging"
}

Blocking on Contract Changes

- name: Contract Safety Check
  run: |
    CONTRACTS=$(git diff --name-only ${{ github.base_ref }}...HEAD | grep -E '\.proto$' || true)

    for CONTRACT in $CONTRACTS; do
      RESULT=$(curl -s "http://localhost:8080/contracts/impact?path=$CONTRACT")
      RISK=$(echo "$RESULT" | jq -r '.riskLevel')
      CONSUMERS=$(echo "$RESULT" | jq -r '.consumers | length')

      if [ "$RISK" = "high" ] && [ "$CONSUMERS" -gt 0 ]; then
        echo "::error::Contract $CONTRACT has $CONSUMERS consumers and is high risk"
        echo "$RESULT" | jq .
        exit 1
      fi
    done

Safe Refactor Checklist

When CKB detects a risky change, you can generate a checklist for the PR:

- name: Generate Refactor Checklist
  if: steps.summary.outputs.risk == 'high'
  uses: actions/github-script@v7
  with:
    script: |
      const data = JSON.parse(`${{ steps.summary.outputs.result }}`);

      let checklist = `## Safe Refactor Checklist\n\n`;
      checklist += `This PR was flagged as **high risk**. Please verify:\n\n`;

      // Add affected modules
      if (data.modulesAffected?.length) {
        checklist += `### Modules Affected\n`;
        data.modulesAffected.forEach(m => {
          checklist += `- [ ] Reviewed changes in \`${m.moduleId}\` (${m.filesChanged} files)\n`;
        });
        checklist += `\n`;
      }

      // Add reviewers to notify
      if (data.suggestedReviewers?.length) {
        checklist += `### Required Sign-offs\n`;
        data.suggestedReviewers.forEach(r => {
          checklist += `- [ ] ${r.owner} approved (owns ${Math.round(r.coverage * 100)}% of changes)\n`;
        });
        checklist += `\n`;
      }

      // Add hotspot warnings
      if (data.summary?.hotspotsTouched > 0) {
        checklist += `### Hotspot Review\n`;
        checklist += `- [ ] Verified ${data.summary.hotspotsTouched} hotspot file(s) have adequate test coverage\n`;
        checklist += `- [ ] Confirmed changes don't increase complexity\n\n`;
      }

      checklist += `### Before Merge\n`;
      checklist += `- [ ] All tests passing\n`;
      checklist += `- [ ] No unintended breaking changes\n`;
      checklist += `- [ ] Documentation updated if needed\n`;

      github.rest.issues.createComment({
        owner: context.repo.owner,
        repo: context.repo.repo,
        issue_number: context.issue.number,
        body: checklist
      });

Documentation Coverage CI (v7.3)

CKB can enforce documentation coverage thresholds and detect stale symbol references in CI.

Why This Matters

Documentation that references deleted or renamed symbols becomes misleading. A function signature change can leave docs describing behavior that no longer exists.

Coverage Enforcement

Fail the build if documentation coverage drops below a threshold:

- name: Check Doc Coverage
  run: |
    # Initialize and index docs
    ckb init
    ckb docs index

    # Fail if coverage below 80%
    ckb docs coverage --fail-under=80

Exit codes:

  • 0: Coverage meets or exceeds threshold
  • 1: Coverage below threshold

Staleness Detection

Check for broken symbol references:

- name: Check Stale Docs
  run: |
    ckb docs index
    STALE=$(ckb docs stale --all --format json | jq '.totalStale')

    if [ "$STALE" -gt 0 ]; then
      echo "::warning::Found $STALE stale symbol references in documentation"
      ckb docs stale --all
    fi

Before Renaming Symbols

Find what docs will break before you rename:

- name: Check Docs Impact
  run: |
    SYMBOL="UserService.Authenticate"

    # Find docs referencing this symbol
    DOCS=$(ckb docs symbol "$SYMBOL" --format json | jq '.docs | length')

    if [ "$DOCS" -gt 0 ]; then
      echo "::warning::$DOCS docs reference $SYMBOL - update after rename"
      ckb docs symbol "$SYMBOL"
    fi

Complete Doc CI Workflow

# .github/workflows/doc-check.yml
name: Documentation Quality

on:
  pull_request:
    paths:
      - '**/*.md'
      - '**/*.go'
      - '**/*.ts'

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

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

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

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

      - name: Check Coverage
        run: ckb docs coverage --fail-under=70

      - name: Check Staleness
        run: |
          RESULT=$(ckb docs stale --all --format json)
          STALE=$(echo "$RESULT" | jq '.totalStale')

          if [ "$STALE" -gt 0 ]; then
            echo "## Stale Documentation References" >> $GITHUB_STEP_SUMMARY
            echo "" >> $GITHUB_STEP_SUMMARY
            echo "$RESULT" | jq -r '.reports[] | .stale[] | "- \(.docPath):\(.line): \(.rawText) (\(.reason))"' >> $GITHUB_STEP_SUMMARY
            exit 1
          fi

What This Is (and Isn't)

This is: A way to get structured JSON about PR changes that you can parse and post as comments. It combines git diff data with CKB's hotspot/ownership/contract analysis to surface risk before merge.

This is not:

  • A CLI command you can run directly (ckb summarize-pr doesn't exist yet)
  • Enforcement — it posts warnings, doesn't block merges by default
  • Magic — if you don't have CODEOWNERS, reviewers come from git-blame heuristics
  • Real-time — hotspot data comes from the last refreshArchitecture run

The awkward part: You have to start a server (ckb serve &) and call it with curl. This is because v6.1 implemented the logic as HTTP handlers, not CLI commands. It works, but it's not as clean as ckb summarize-pr --base=main.

Recommended rollout:

  1. Start with just the PR comment (informational)
  2. Add hotspot warnings after you trust the data
  3. Add contract boundary detection for API changes (v6.3)
  4. Consider ownership drift on a schedule, not every PR
  5. Only add enforcement (failing builds) after the team trusts the signals

Environment Variables

Variable Description Default
CKB_REPO_ROOT Repository root path Current directory
CKB_LOG_LEVEL Log verbosity (debug/info/warn/error) info
CKB_CONFIG_PATH Config file location .ckb/config.json
CKB_TIER Analysis tier: fast, standard, or full Auto-detected

Tips

  1. Cache the .ckb/ directory — Enables incremental indexing across runs
  2. Use fetch-depth: 0 — Required for git-blame analysis and incremental indexing
  3. Run refresh on schedule — Keep data fresh without blocking PRs
  4. Set appropriate timeouts — Large repos may need longer timeouts
  5. Use async for big repos — Avoid CI timeout issues
  6. Use incremental indexing for PRs — O(changed files) instead of O(total files)
  7. Use --force for nightly builds — Ensures maximum accuracy
  8. Validate with ckb doctor --tier — Catch missing tools early
  9. Set CKB_TIER environment variable — Control analysis depth explicitly

Example: Block High-Risk PRs

- name: Check Risk Level
  run: |
    RISK="${{ steps.summary.outputs.risk }}"
    if [ "$RISK" = "high" ]; then
      echo "::error::PR flagged as HIGH RISK. Manual review required."
      exit 1
    fi

Example: Auto-Request Reviewers

- name: Request Reviewers
  uses: actions/github-script@v7
  with:
    script: |
      const data = JSON.parse(`${{ steps.summary.outputs.result }}`);
      const reviewers = data.suggestedReviewers
        ?.filter(r => !r.owner.startsWith('@'))  // Filter out teams
        .map(r => r.owner)
        .slice(0, 2);

      if (reviewers?.length) {
        await github.rest.pulls.requestReviewers({
          owner: context.repo.owner,
          repo: context.repo.repo,
          pull_number: context.issue.number,
          reviewers: reviewers
        });
      }

Upload to Central Index Server (v7.3)

For organizations using a central CKB index server, publish indexes from CI:

# .github/workflows/publish-index.yml
name: Publish Index to CKB Server

on:
  push:
    branches: [main]

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

      - uses: actions/setup-go@v5
        with:
          go-version: '1.21'

      - name: Install SCIP indexer
        run: go install github.com/sourcegraph/scip-go/cmd/scip-go@latest

      - name: Generate SCIP index
        run: scip-go

      - name: Upload to CKB server
        env:
          CKB_TOKEN: ${{ secrets.CKB_TOKEN }}
        run: |
          curl -X POST "${{ vars.CKB_SERVER_URL }}/index/repos/${{ github.repository }}/upload" \
            -H "Authorization: Bearer $CKB_TOKEN" \
            -H "Content-Type: application/octet-stream" \
            -H "Content-Encoding: gzip" \
            -H "X-CKB-Commit: ${{ github.sha }}" \
            -H "X-CKB-Language: go" \
            --data-binary @<(gzip -c index.scip)

With compression (recommended for large indexes):

# gzip (widely available)
gzip -c index.scip | curl -X POST "$URL/upload" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Encoding: gzip" \
  --data-binary @-

# zstd (faster, better compression)
zstd -c index.scip | curl -X POST "$URL/upload" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Encoding: zstd" \
  --data-binary @-

Setting up tokens:

# On the server, create a write-scoped token for CI
ckb token create --name "GitHub CI" --scopes write --repos "myorg/*"
# Add the returned token as CKB_TOKEN secret in GitHub

See Authentication for token configuration.

Complete Example Workflows

Full example workflows are available in the repository:

  • examples/github-actions/pr-analysis.yml — PR analysis with comments
  • examples/github-actions/scheduled-refresh.yml — Daily architecture refresh
  • examples/github-actions/publish-index.yml — Publish to central index server

Clone this wiki locally