Merge pull request #502 from jaypatrick/copilot/fix-schema-validation… #1163
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| workflow_dispatch: | |
| env: | |
| DENO_VERSION: '2.x' | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # Run quick checks in parallel | |
| lint: | |
| name: Lint | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Deno | |
| uses: denoland/setup-deno@v2 | |
| with: | |
| deno-version: ${{ env.DENO_VERSION }} | |
| - name: Cache Deno dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cache/deno | |
| ~/.deno | |
| node_modules | |
| key: deno-${{ runner.os }}-${{ hashFiles('deno.json', 'deno.lock') }} | |
| restore-keys: | | |
| deno-${{ runner.os }}- | |
| - name: Lint | |
| run: deno lint | |
| format: | |
| name: Format Check | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Deno | |
| uses: denoland/setup-deno@v2 | |
| with: | |
| deno-version: ${{ env.DENO_VERSION }} | |
| - name: Cache Deno dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cache/deno | |
| ~/.deno | |
| key: deno-${{ runner.os }}-${{ hashFiles('deno.json', 'deno.lock') }} | |
| restore-keys: | | |
| deno-${{ runner.os }}- | |
| - name: Format check | |
| run: deno fmt --check | |
| typecheck: | |
| name: Type Check | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Deno | |
| uses: denoland/setup-deno@v2 | |
| with: | |
| deno-version: ${{ env.DENO_VERSION }} | |
| - name: Cache Deno dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cache/deno | |
| ~/.deno | |
| node_modules | |
| key: deno-${{ runner.os }}-${{ hashFiles('deno.json', 'deno.lock') }} | |
| restore-keys: | | |
| deno-${{ runner.os }}- | |
| - name: Install dependencies | |
| run: deno install | |
| env: | |
| DENO_TLS_CA_STORE: system | |
| - name: Type check all entry points | |
| run: | | |
| deno check src/index.ts | |
| deno check src/cli.ts | |
| deno check worker/worker.ts | |
| deno check worker/tail.ts | |
| test: | |
| name: Test | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Load environment variables | |
| uses: ./.github/actions/setup-env | |
| - name: Setup Deno | |
| uses: denoland/setup-deno@v2 | |
| with: | |
| deno-version: ${{ env.DENO_VERSION }} | |
| - name: Cache Deno dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cache/deno | |
| ~/.deno | |
| node_modules | |
| key: deno-${{ runner.os }}-${{ hashFiles('deno.json', 'deno.lock') }} | |
| restore-keys: | | |
| deno-${{ runner.os }}- | |
| - name: Install dependencies | |
| run: deno install | |
| env: | |
| DENO_TLS_CA_STORE: system | |
| - name: Run tests with coverage | |
| run: | | |
| deno test --allow-read --allow-write --allow-net --allow-env --coverage=coverage | |
| deno coverage coverage --lcov --output=coverage.lcov --include="^file:" | |
| env: | |
| DENO_TLS_CA_STORE: system | |
| - name: Upload coverage | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| uses: codecov/codecov-action@v5 | |
| continue-on-error: true | |
| with: | |
| files: ./coverage.lcov | |
| fail_ci_if_error: false | |
| env: | |
| CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} | |
| security: | |
| name: Security Scan | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| security-events: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Run Trivy vulnerability scanner | |
| uses: aquasecurity/trivy-action@0.33.1 | |
| with: | |
| scan-type: fs | |
| scan-ref: . | |
| format: sarif | |
| output: trivy-results.sarif | |
| severity: 'CRITICAL,HIGH,MEDIUM' | |
| - name: Upload Trivy results to GitHub Security | |
| if: always() | |
| uses: github/codeql-action/upload-sarif@v3 | |
| continue-on-error: true | |
| with: | |
| sarif_file: trivy-results.sarif | |
| validate-cloudflare-schema: | |
| name: Validate Cloudflare Schema | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Deno | |
| uses: denoland/setup-deno@v2 | |
| with: | |
| deno-version: ${{ env.DENO_VERSION }} | |
| - name: Cache Deno dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cache/deno | |
| ~/.deno | |
| key: deno-${{ runner.os }}-${{ hashFiles('deno.json', 'deno.lock') }} | |
| restore-keys: | | |
| deno-${{ runner.os }}- | |
| - name: Generate Cloudflare schema | |
| run: deno task schema:cloudflare | |
| - name: Check schema is up to date | |
| run: | | |
| if ! git diff --quiet docs/api/cloudflare-schema.yaml; then | |
| echo "❌ docs/api/cloudflare-schema.yaml is out of date!" | |
| echo "The generated schema does not match the committed file." | |
| echo "Run 'deno task schema:cloudflare' locally and commit the updated docs/api/cloudflare-schema.yaml." | |
| echo "" | |
| echo "Diff:" | |
| git diff docs/api/cloudflare-schema.yaml | |
| exit 1 | |
| fi | |
| echo "✅ Cloudflare schema is up to date" | |
| # Only publish on main pushes, and gate on all checks | |
| publish: | |
| name: Publish to JSR | |
| runs-on: ubuntu-latest | |
| needs: [lint, format, typecheck, test, security, validate-cloudflare-schema] | |
| if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
| permissions: | |
| contents: read | |
| id-token: write | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Deno | |
| uses: denoland/setup-deno@v2 | |
| with: | |
| deno-version: ${{ env.DENO_VERSION }} | |
| - name: Cache Deno dependencies | |
| uses: actions/cache@v4 | |
| with: | |
| path: | | |
| ~/.cache/deno | |
| ~/.deno | |
| node_modules | |
| key: deno-${{ runner.os }}-${{ hashFiles('deno.json', 'deno.lock') }} | |
| restore-keys: | | |
| deno-${{ runner.os }}- | |
| - name: Install dependencies | |
| run: deno install | |
| env: | |
| DENO_TLS_CA_STORE: system | |
| - name: Publish to JSR | |
| run: | | |
| set -euo pipefail | |
| if ! OUTPUT="$(deno publish --allow-dirty 2>&1)"; then | |
| echo "${OUTPUT}" | |
| if echo "${OUTPUT}" | grep -qiE 'version .*already (exists|published)'; then | |
| echo "Version already published, skipping." | |
| exit 0 | |
| fi | |
| echo "Publish failed with unexpected error." | |
| exit 1 | |
| fi | |
| echo "Successfully published to JSR" | |
| # Deploy jobs only run on main and when enabled | |
| deploy: | |
| name: Deploy to Cloudflare | |
| runs-on: ubuntu-latest | |
| needs: [lint, format, typecheck, test, security, validate-cloudflare-schema] | |
| if: | | |
| github.event_name == 'push' && | |
| github.ref == 'refs/heads/main' && | |
| vars.ENABLE_CLOUDFLARE_DEPLOY == 'true' | |
| permissions: | |
| contents: read | |
| env: | |
| CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Load environment variables | |
| uses: ./.github/actions/setup-env | |
| - name: Setup Deno | |
| uses: denoland/setup-deno@v2 | |
| with: | |
| deno-version: ${{ env.DENO_VERSION }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v4 | |
| with: | |
| node-version: '22' | |
| cache: 'npm' | |
| - name: Install Wrangler | |
| run: npm install -g wrangler | |
| - name: Run database migrations | |
| run: | | |
| echo "Running D1 migrations..." | |
| wrangler d1 execute adblock-compiler-d1-database --file=migrations/0001_init.sql --remote || echo "Migration 0001 already applied or failed" | |
| wrangler d1 execute adblock-compiler-d1-database --file=migrations/0002_deployment_history.sql --remote || echo "Migration 0002 already applied or failed" | |
| - name: Generate deployment version | |
| id: version | |
| run: | | |
| deno run --allow-read --allow-net --allow-env scripts/generate-deployment-version.ts | |
| - name: Setup Cloudflare resources | |
| run: | | |
| echo "Creating Cloudflare resources..." | |
| wrangler queues create adblock-compiler-worker-queue 2>/dev/null || echo "Queue already exists" | |
| wrangler queues create adblock-compiler-worker-queue-high-priority 2>/dev/null || echo "High priority queue already exists" | |
| wrangler queues create adblock-compiler-dlq 2>/dev/null || echo "DLQ already exists" | |
| wrangler r2 bucket create adblock-compiler-r2-storage 2>/dev/null || echo "R2 bucket already exists" | |
| - name: Deploy Worker | |
| id: deploy | |
| run: | | |
| echo "Deploying version: ${{ steps.version.outputs.full_version }}" | |
| wrangler deploy | |
| - name: Record deployment | |
| if: success() | |
| run: | | |
| deno run --allow-read --allow-net --allow-env scripts/record-deployment.ts --status=success | |
| - name: Record failed deployment | |
| if: failure() | |
| run: | | |
| deno run --allow-read --allow-net --allow-env scripts/record-deployment.ts --status=failed || true | |
| - name: Deploy Pages | |
| uses: cloudflare/wrangler-action@v3 | |
| with: | |
| apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} | |
| accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} | |
| command: pages deploy public --project-name=adblock-compiler-ui |