name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
env:
NODE_VERSION: "20"
BUN_VERSION: "latest"
jobs:
lint-and-typecheck:
name: Lint and Type Check
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: ${{ env.BUN_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
node_modules
key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Run linting
run: bun run lint
- name: Type check
run: bun run typecheck
unit-tests:
name: Unit Tests
runs-on: ubuntu-latest
strategy:
matrix:
node-version: ["18", "20", "22"]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: ${{ env.BUN_VERSION }}
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
node_modules
key: ${{ runner.os }}-bun-${{ matrix.node-version }}-${{ hashFiles('**/bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-${{ matrix.node-version }}-
${{ runner.os }}-bun-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Run unit tests
run: bun run test:unit:ci
- name: Upload unit test coverage to Codecov
if: matrix.node-version == '20'
uses: codecov/codecov-action@v4
with:
file: ./coverage/unit/lcov.info
flags: unittests
name: codecov-unit-tests
fail_ci_if_error: false
# integration-tests:
# name: Integration Tests
# runs-on: ubuntu-latest
# needs: [unit-tests]
# continue-on-error: true # Don't fail the entire workflow if integration tests fail
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
# - name: Setup Bun
# uses: oven-sh/setup-bun@v1
# with:
# bun-version: ${{ env.BUN_VERSION }}
# - name: Setup Node.js
# uses: actions/setup-node@v4
# with:
# node-version: ${{ env.NODE_VERSION }}
# - name: Cache dependencies
# uses: actions/cache@v4
# with:
# path: |
# ~/.bun/install/cache
# node_modules
# key: ${{ runner.os }}-bun-integration-${{ hashFiles('**/bun.lock') }}
# restore-keys: |
# ${{ runner.os }}-bun-
# - name: Install dependencies
# run: bun install --frozen-lockfile
# - name: Install Tailscale CLI
# run: |
# curl -fsSL https://tailscale.com/install.sh | sh
# sudo tailscale version
# - name: Setup Tailscale for testing
# env:
# TAILSCALE_AUTH_KEY: ${{ secrets.TAILSCALE_AUTH_KEY }}
# run: |
# if [ -n "$TAILSCALE_AUTH_KEY" ]; then
# echo "๐ Authenticating Tailscale with auth key..."
# sudo tailscale up --authkey="$TAILSCALE_AUTH_KEY" --hostname="ci-runner-${{ github.run_id }}" --accept-routes
# echo "โ
Tailscale authenticated successfully"
# sudo tailscale status
# else
# echo "โ ๏ธ No Tailscale auth key provided. Integration tests will run in CLI-only mode."
# echo " Some tests may be skipped. To enable full integration testing,"
# echo " add TAILSCALE_AUTH_KEY to repository secrets."
# fi
# - name: Run integration tests
# run: bun run test:integration:ci
# env:
# # Allow tests to run even without full Tailscale setup
# TAILSCALE_TEST_MODE: "ci"
# - name: Upload integration test coverage
# uses: codecov/codecov-action@v4
# with:
# file: ./coverage/integration/lcov.info
# flags: integration
# name: codecov-integration-tests
# fail_ci_if_error: false
# - name: Cleanup Tailscale
# if: always()
# run: |
# if command -v tailscale >/dev/null 2>&1; then
# echo "๐งน Cleaning up Tailscale..."
# sudo tailscale logout || true
# sudo tailscale down || true
# fi
build:
name: Build
runs-on: ubuntu-latest
needs: [lint-and-typecheck, unit-tests]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: ${{ env.BUN_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
node_modules
key: ${{ runner.os }}-bun-build-${{ hashFiles('**/bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Build project
run: bun run build
- name: Verify build artifacts
run: |
test -f dist/index.js
test -f dist/index.cjs
echo "โ
Build artifacts verified"
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: dist/
retention-days: 7
security-audit:
name: Security Audit
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v1
with:
bun-version: ${{ env.BUN_VERSION }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Cache dependencies
uses: actions/cache@v4
with:
path: |
~/.bun/install/cache
node_modules
key: ${{ runner.os }}-bun-security-${{ hashFiles('**/bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-
- name: Install dependencies
run: bun install --frozen-lockfile
- name: Run security audit
run: |
echo "๐ Running security audit..."
bun audit || echo "โ ๏ธ Audit found issues but continuing..."
- name: Run dependency vulnerability check
run: |
echo "๐ Running dependency vulnerability check..."
bunx audit-ci --moderate || echo "โ ๏ธ Vulnerability check found issues but continuing..."