From 945016d1041cb280822fbd8d70f37d26dff9088c Mon Sep 17 00:00:00 2001 From: Hongming Wang Date: Fri, 17 Apr 2026 10:09:39 -0700 Subject: [PATCH 1/2] 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 From 4f51c3421748d2d0531d939d9a0c53e581b3ecf4 Mon Sep 17 00:00:00 2001 From: Hongming Wang Date: Fri, 17 Apr 2026 10:13:18 -0700 Subject: [PATCH 2/2] docs(CLAUDE.md): document CI path filters for docs-only skip Adds path-filter table so developers and agents know which files trigger which CI jobs, and that docs-only PRs skip everything. Co-Authored-By: Claude Opus 4.6 (1M context) --- CLAUDE.md | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index aedab50f..2db4a209 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -266,12 +266,27 @@ All five E2E scripts share `tests/e2e/_lib.sh` + `tests/e2e/_extract_token.py` h The MCP server now lives at **github.com/Molecule-AI/molecule-mcp-server** and is published as `@molecule-ai/mcp-server` on npm. Install: `npx @molecule-ai/mcp-server`. 87 tools for managing Molecule AI from any MCP client. Configured in `.mcp.json`. Env: `MOLECULE_URL` (default http://localhost:8080). ### CI Pipeline -GitHub Actions (`.github/workflows/ci.yml`) runs on push to main and PRs: +GitHub Actions (`.github/workflows/ci.yml`) runs on push to main and PRs. +**Path-filtered:** each job only runs when its relevant files change (via +`dorny/paths-filter`). Docs-only PRs (`docs/**`, `*.md`) skip all jobs, +saving ~15 min of runner time. The path filters are: + +| Job | Triggers on | +|-----|-------------| +| **platform-build** | `platform/**` | +| **canvas-build** | `canvas/**` | +| **python-lint** | `workspace-template/**` | +| **shellcheck** | `tests/e2e/**`, `scripts/**` | +| **e2e-api** | `platform/**`, `tests/e2e/**` | + +All jobs also trigger on `.github/workflows/ci.yml` changes (self-test). + +Job details: - **platform-build**: Go build, vet, `go test -race` with coverage profiling (25% baseline threshold; `setup-go` uses module cache) - **canvas-build**: npm build, `vitest run` (no `--passWithNoTests` -- tests must exist and pass) - **python-lint**: `pytest --cov=. --cov-report=term-missing` (workspace-template tests; SDK + MCP now in standalone repos) -- **e2e-api** (added 2026-04-13): spins up Postgres + Redis service containers, runs platform migrations via `docker exec`, then executes `tests/e2e/test_api.sh` against a locally-built binary (62/62 must pass) -- **shellcheck** (added 2026-04-13): lints every `tests/e2e/*.sh` via the shellcheck marketplace action +- **e2e-api** (`.github/workflows/e2e-api.yml`): spins up Postgres + Redis service containers, runs platform migrations via `docker exec`, then executes `tests/e2e/test_api.sh` against a locally-built binary (62/62 must pass) +- **shellcheck**: lints every `tests/e2e/*.sh` via shellcheck on the self-hosted runner - **publish-platform-image** (`.github/workflows/publish-platform-image.yml`): on push to main touching `platform/**`, builds `platform/Dockerfile` (clones templates + plugins from GitHub via `manifest.json` at build time) and pushes to `ghcr.io/molecule-ai/platform:latest` + `:sha-`. Tenant image uses `platform/Dockerfile.tenant` (combined Go + Canvas). Manual re-trigger via `workflow_dispatch`. **Standalone repo CI** — all 33 plugin + template repos call reusable workflows from `Molecule-AI/molecule-ci`: