name: CI on: push: branches: ["**"] pull_request: branches: ["**"] jobs: audit: name: Security audit runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: "22" cache: "npm" - name: Install dependencies run: npm ci - name: Run security audit (fail on high+) run: npm audit --audit-level=high - name: Check for critical vulnerabilities run: npm audit --audit-level=critical --json | jq -e '.metadata.vulnerabilities.critical == 0' || (echo "Critical vulnerabilities found!" && exit 1) continue-on-error: false test: name: Tests & coverage runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: "22" cache: "npm" - name: Install dependencies run: npm ci - name: Run tests with coverage run: npm run test:coverage env: # Required by tokenStore (writable temp dir in CI) DATA_DIR: /tmp/sofarr-ci-data # Disable rate limiters so integration tests don't hit 429s SKIP_RATE_LIMIT: "1" NODE_ENV: test - name: Upload coverage report uses: actions/upload-artifact@v3 if: always() with: name: coverage-report path: coverage/ retention-days: 14 swagger: name: Swagger Validation & Coverage runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: "22" cache: "npm" - name: Install dependencies run: npm ci - name: Lint OpenAPI spec with Spectral run: npx @stoplight/spectral-cli lint server/openapi.yaml --ruleset .spectral.yml || true - name: Run Swagger coverage tests run: npm test -- tests/integration/swagger-coverage.test.js env: DATA_DIR: /tmp/sofarr-ci-data SKIP_RATE_LIMIT: "1" NODE_ENV: test - name: Generate merged OpenAPI spec run: npm run generate:openapi env: NODE_ENV: test DATA_DIR: /tmp/sofarr-ci-data SKIP_RATE_LIMIT: "1" - name: Convert to RAML run: npm run generate:raml continue-on-error: true - name: Package RAML artifact run: npm run package:raml env: GITHUB_SHA: ${{ github.sha }} GITHUB_REF_TYPE: ${{ github.ref_type }} GITHUB_REF_NAME: ${{ github.ref_name }} - name: Upload RAML package artifact uses: actions/upload-artifact@v3 if: always() with: name: raml-package path: dist/raml-*.tar.gz retention-days: 14