name: CI on: push: branches: [main, develop] pull_request: branches: [main] workflow_dispatch: permissions: contents: read security-events: write jobs: lint-bridge: name: Lint bridge (Biome) runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 cache: "npm" cache-dependency-path: bridge/package-lock.json - run: cd bridge && npm ci - run: cd bridge && npx biome ci . typecheck-bridge: name: Type-check bridge runs-on: ubuntu-latest needs: lint-bridge steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 cache: "npm" cache-dependency-path: bridge/package-lock.json - run: cd bridge && npm ci - run: cd bridge && npm run typecheck test-bridge-unit: name: Tests unit bridge runs-on: ubuntu-latest needs: typecheck-bridge steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 cache: "npm" cache-dependency-path: bridge/package-lock.json - run: cd bridge && npm ci - run: cd bridge && npm run test:unit -- --coverage - uses: actions/upload-artifact@v4 with: name: coverage-unit path: bridge/coverage/ test-bridge-integration: name: Tests integration bridge runs-on: ubuntu-latest needs: typecheck-bridge services: postgres: image: postgres:16-alpine env: POSTGRES_USER: test POSTGRES_PASSWORD: test POSTGRES_DB: testdb ports: - 5432:5432 options: >- --health-cmd "pg_isready -U test" --health-interval 5s --health-timeout 3s --health-retries 10 redis: image: redis:7-alpine ports: - 6379:6379 options: >- --health-cmd "redis-cli ping" --health-interval 5s --health-timeout 3s --health-retries 10 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 cache: "npm" cache-dependency-path: bridge/package-lock.json - run: cd bridge && npm ci - run: cd bridge && npm run test:integration env: DATABASE_URL: postgresql://test:test@localhost:5432/testdb REDIS_URL: redis://localhost:6379 security-scan: name: Security scan runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Secret scanning (TruffleHog) uses: trufflesecurity/trufflehog@main with: path: ./ extra_args: --only-verified - name: SAST (Semgrep) uses: semgrep/semgrep-action@v1 with: config: >- p/javascript p/typescript p/security-audit p/secrets continue-on-error: true - name: Dep audit (npm audit) run: cd bridge && npm audit --audit-level=high continue-on-error: false docker-build: name: Docker build + healthcheck runs-on: ubuntu-latest needs: [test-bridge-unit, test-bridge-integration, security-scan] steps: - uses: actions/checkout@v4 - name: Build images run: docker compose build - name: Up stack run: | cp .env.example .env docker compose up -d - name: Wait for services run: sleep 30 - name: Healthcheck run: ./scripts/healthcheck.sh - name: Logs on failure if: failure() run: docker compose logs - name: Cleanup if: always() run: docker compose down -v