Files
Claude-Code-Monitor/deployments/ci/github-actions/ci.yaml
T
nntrivi2001 57dc91585d feat: Claude Code Monitor — lanes, pipelines and a merged workspace
Internal SmartGift build of a Claude Code monitoring dashboard.

Lanes: a durable unit of parallel agent work, one per working directory,
tracked across session restarts. Managed lanes are git worktrees the
dashboard provisions and can reset or remove behind a three-check destroy
guard and a counted preflight; adopted lanes are directories you already
own and are never destroyable.

Pipelines: a lane moves through pipeline stages. A stage the agent declares
with evidence renders green; a stage inferred from the tool-event stream
renders dashed amber and never counts as done. Detection is forward-only
within a 30-minute window, and never writes the declared stage.

Workspace: one page at /run with a lane grid, the selected lane's pipeline,
and a full Claude console behind a disclosure.
2026-07-30 14:39:03 +07:00

251 lines
8.0 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ─────────────────────────────────────────────────────────────────────────────
# GitHub Actions CI Pipeline Claude Code Agent Monitor
#
# Triggers on push to main and PRs. Runs linting, tests, builds Docker
# images, and scans for security vulnerabilities.
# ─────────────────────────────────────────────────────────────────────────────
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
packages: write
security-events: write
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
env:
NODE_VERSION: "22"
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}/agent-monitor
MCP_IMAGE_NAME: ${{ github.repository }}/agent-monitor-mcp
jobs:
# ── Lint & Format Check ─────────────────────────────────────────────────
lint:
name: Lint & Format
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Check formatting
run: npm run format:check
# ── Server Tests ────────────────────────────────────────────────────────
test-server:
name: Server Tests
runs-on: ubuntu-latest
needs: lint
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Install dependencies
run: npm ci
- name: Run server tests
run: npm run test:server
# ── Client Tests ────────────────────────────────────────────────────────
test-client:
name: Client Tests
runs-on: ubuntu-latest
needs: lint
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Install root dependencies
run: npm ci
- name: Install client dependencies
run: cd client && npm ci
- name: Run client tests
run: npm run test:client
# ── MCP Tests ───────────────────────────────────────────────────────────
test-mcp:
name: MCP Sidecar Tests
runs-on: ubuntu-latest
needs: lint
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: "npm"
- name: Install MCP dependencies
run: npm run mcp:install
- name: Type check MCP
run: npm run mcp:typecheck
- name: Run MCP tests
run: npm run mcp:test
# ── Build Docker Images ────────────────────────────────────────────────
build-image:
name: Build Docker Images
runs-on: ubuntu-latest
needs: [test-server, test-client, test-mcp]
# Only push images on main branch
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
outputs:
image-tag: ${{ steps.meta.outputs.version }}
image-digest: ${{ steps.build-app.outputs.digest }}
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract metadata (app)
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=sha,prefix=sha-
type=raw,value=latest,enable={{is_default_branch}}
type=semver,pattern={{version}},enable=${{ startsWith(github.ref, 'refs/tags/v') }}
- name: Build & push app image
id: build-app
uses: docker/build-push-action@v5
with:
context: .
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64
- name: Extract metadata (MCP)
id: meta-mcp
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.MCP_IMAGE_NAME }}
tags: |
type=ref,event=branch
type=sha,prefix=sha-
type=raw,value=latest,enable={{is_default_branch}}
- name: Build & push MCP image
id: build-mcp
uses: docker/build-push-action@v5
with:
context: .
file: ./mcp/Dockerfile
push: true
tags: ${{ steps.meta-mcp.outputs.tags }}
labels: ${{ steps.meta-mcp.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64
# ── Security Scan ──────────────────────────────────────────────────────
security-scan:
name: Security Scan
runs-on: ubuntu-latest
needs: build-image
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Login to Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Run Trivy vulnerability scanner (app)
uses: aquasecurity/trivy-action@master
with:
image-ref: "${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.build-image.outputs.image-tag }}"
format: "sarif"
output: "trivy-app-results.sarif"
severity: "CRITICAL,HIGH"
exit-code: "1"
- name: Run Trivy vulnerability scanner (MCP)
uses: aquasecurity/trivy-action@master
with:
image-ref: "${{ env.REGISTRY }}/${{ env.MCP_IMAGE_NAME }}:${{ needs.build-image.outputs.image-tag }}"
format: "sarif"
output: "trivy-mcp-results.sarif"
severity: "CRITICAL,HIGH"
exit-code: "1"
- name: Upload Trivy SARIF (app)
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: "trivy-app-results.sarif"
category: "trivy-app"
- name: Upload Trivy SARIF (MCP)
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: "trivy-mcp-results.sarif"
category: "trivy-mcp"
- name: Run npm audit
run: npm audit --production --audit-level=high
- name: Trivy filesystem scan (IaC)
uses: aquasecurity/trivy-action@master
with:
scan-type: "fs"
scan-ref: "./deployments"
format: "table"
severity: "CRITICAL,HIGH"
exit-code: "1"