From 945016d1041cb280822fbd8d70f37d26dff9088c Mon Sep 17 00:00:00 2001 From: Hongming Wang Date: Fri, 17 Apr 2026 10:09:39 -0700 Subject: [PATCH] fix(ci): skip CI jobs for docs-only PRs using path filters CI now detects which paths changed and skips irrelevant jobs: - Platform (Go): only runs when platform/** changes - Canvas (Next.js): only runs when canvas/** changes - Python Lint: only runs when workspace-template/** changes - Shellcheck: only runs when tests/e2e/** or scripts/** change - E2E API: only runs when platform/** or tests/e2e/** change Docs-only PRs (*.md, docs/**) skip all 5 jobs, saving ~15 min of runner time per PR. Uses dorny/paths-filter for the CI workflow and native paths: filter for the E2E workflow. Co-Authored-By: Claude Opus 4.6 (1M context) --- .github/workflows/ci.yml | 42 ++++++++++++++++++++++++++++++++++- .github/workflows/e2e-api.yml | 8 +++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9438bf0d..7013f86f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,8 +7,41 @@ on: branches: [main] jobs: + # Detect which paths changed so downstream jobs can skip when only + # docs/markdown files were modified. Saves ~15 min of runner time per + # docs-only PR. + changes: + name: Detect changes + runs-on: [self-hosted, macos, arm64] + outputs: + platform: ${{ steps.filter.outputs.platform }} + canvas: ${{ steps.filter.outputs.canvas }} + python: ${{ steps.filter.outputs.python }} + scripts: ${{ steps.filter.outputs.scripts }} + steps: + - uses: actions/checkout@v4 + - uses: dorny/paths-filter@v3 + id: filter + with: + filters: | + platform: + - 'platform/**' + - '.github/workflows/ci.yml' + canvas: + - 'canvas/**' + - '.github/workflows/ci.yml' + python: + - 'workspace-template/**' + - '.github/workflows/ci.yml' + scripts: + - 'tests/e2e/**' + - 'scripts/**' + - '.github/workflows/ci.yml' + platform-build: name: Platform (Go) + needs: changes + if: needs.changes.outputs.platform == 'true' runs-on: [self-hosted, macos, arm64] defaults: run: @@ -43,6 +76,8 @@ jobs: canvas-build: name: Canvas (Next.js) + needs: changes + if: needs.changes.outputs.canvas == 'true' runs-on: [self-hosted, macos, arm64] defaults: run: @@ -67,6 +102,8 @@ jobs: shellcheck: name: Shellcheck (E2E scripts) + needs: changes + if: needs.changes.outputs.scripts == 'true' runs-on: [self-hosted, macos, arm64] steps: - uses: actions/checkout@v4 @@ -84,7 +121,8 @@ jobs: canvas-deploy-reminder: name: Canvas Deploy Reminder runs-on: [self-hosted, macos, arm64] - needs: canvas-build + needs: [changes, canvas-build] + if: needs.changes.outputs.canvas == 'true' # Only fires on direct pushes to main (i.e. after a PR merges). # PRs get canvas-build CI but no reminder — no deployment happens on PRs. if: github.event_name == 'push' && github.ref == 'refs/heads/main' @@ -128,6 +166,8 @@ jobs: python-lint: name: Python Lint & Test + needs: changes + if: needs.changes.outputs.python == 'true' runs-on: [self-hosted, macos, arm64] defaults: run: diff --git a/.github/workflows/e2e-api.yml b/.github/workflows/e2e-api.yml index ed29a00d..8468ebaa 100644 --- a/.github/workflows/e2e-api.yml +++ b/.github/workflows/e2e-api.yml @@ -15,8 +15,16 @@ name: E2E API Smoke Test on: push: branches: [main] + paths: + - 'platform/**' + - 'tests/e2e/**' + - '.github/workflows/e2e-api.yml' pull_request: branches: [main] + paths: + - 'platform/**' + - 'tests/e2e/**' + - '.github/workflows/e2e-api.yml' # Workflow-level concurrency: new runs queue rather than cancel. # `cancel-in-progress: false` is load-bearing — without it GitHub would still