Files
claude-hub/.github/workflows/ci.yml
Jonathan Flatt 5fd78d418e Revert to free ubuntu-latest runners instead of paid 4-core runners
Using standard ubuntu-latest (2-core) runners for light jobs to avoid
additional costs beyond GitHub Team plan. Heavy jobs still use self-hosted.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-05-25 16:27:36 -05:00

248 lines
6.3 KiB
YAML

name: CI Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
env:
NODE_VERSION: '20'
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
# Lint job - fast and independent
lint:
name: Lint & Format Check
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'
cache-dependency-path: 'package-lock.json'
- name: Install dependencies
run: npm ci --prefer-offline --no-audit
- name: Run linter
run: npm run lint:check || echo "No lint script found, skipping"
- name: Check formatting
run: npm run format:check || echo "No format script found, skipping"
# Unit tests - fastest test suite
test-unit:
name: Unit Tests
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'
cache-dependency-path: 'package-lock.json'
- name: Install dependencies
run: npm ci --prefer-offline --no-audit
- name: Run unit tests
run: npm run test:unit
env:
NODE_ENV: test
BOT_USERNAME: '@TestBot'
GITHUB_WEBHOOK_SECRET: 'test-secret'
GITHUB_TOKEN: 'test-token'
# Integration tests - moderate complexity
test-integration:
name: Integration Tests
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'
cache-dependency-path: 'package-lock.json'
- name: Install dependencies
run: npm ci --prefer-offline --no-audit
- name: Run integration tests
run: npm run test:integration || echo "No integration tests found, skipping"
env:
NODE_ENV: test
BOT_USERNAME: '@TestBot'
GITHUB_WEBHOOK_SECRET: 'test-secret'
GITHUB_TOKEN: 'test-token'
# E2E tests - most complex, run on self-hosted for better performance
test-e2e:
name: E2E Tests
runs-on: [self-hosted, Linux, X64]
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'
cache-dependency-path: 'package-lock.json'
- name: Install dependencies
run: npm ci --prefer-offline --no-audit
- name: Run e2e tests
run: npm run test:e2e
env:
NODE_ENV: test
BOT_USERNAME: '@TestBot'
GITHUB_WEBHOOK_SECRET: 'test-secret'
GITHUB_TOKEN: 'test-token'
# Coverage generation - depends on unit tests
coverage:
name: Test Coverage
runs-on: ubuntu-latest
needs: [test-unit]
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'
cache-dependency-path: 'package-lock.json'
- name: Install dependencies
run: npm ci --prefer-offline --no-audit
- name: Generate test coverage
run: npm run test:coverage
env:
NODE_ENV: test
BOT_USERNAME: '@TestBot'
GITHUB_WEBHOOK_SECRET: 'test-secret'
GITHUB_TOKEN: 'test-token'
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v5
with:
file: ./coverage/lcov.info
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
# Security scans - run in parallel with tests
security:
name: Security Scan
runs-on: [self-hosted, Linux, X64]
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'
cache-dependency-path: 'package-lock.json'
- name: Install dependencies
run: npm ci --prefer-offline --no-audit
- name: Run npm audit
run: npm audit --audit-level=moderate
- name: Run security scan with Snyk
uses: snyk/actions/node@master
continue-on-error: true
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high
# Docker builds - move to self-hosted for better performance
docker:
name: Docker Build & Test
runs-on: [self-hosted, Linux, X64]
# Only need unit tests to pass for Docker builds
needs: [test-unit, lint]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build main Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
push: false
load: true
tags: claude-github-webhook:test
cache-from: type=gha,type=local,src=/tmp/.buildx-cache
cache-to: type=gha,mode=max,type=local,dest=/tmp/.buildx-cache-new,mode=max
platforms: linux/amd64
- name: Build Claude Code Docker image
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile.claudecode
push: false
load: true
tags: claude-code-runner:test
cache-from: type=gha,type=local,src=/tmp/.buildx-cache
cache-to: type=gha,mode=max,type=local,dest=/tmp/.buildx-cache-new,mode=max
platforms: linux/amd64
- name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
- name: Test Docker containers
run: |
# Test main container starts correctly
docker run --name test-webhook -d -p 3003:3002 \
-e NODE_ENV=test \
-e BOT_USERNAME=@TestBot \
-e GITHUB_WEBHOOK_SECRET=test-secret \
-e GITHUB_TOKEN=test-token \
claude-github-webhook:test
# Wait for container to start
sleep 10
# Test health endpoint
curl -f http://localhost:3003/health || exit 1
# Cleanup
docker stop test-webhook
docker rm test-webhook