ci: skip tests when PR has no code changes (#13034)

### What this PR does

Before this PR:
All three CI matrix tasks (`basic-checks`, `general-test`,
`render-test`) ran on every PR regardless of what files changed.

After this PR:
- Tests are skipped on PRs that only modify non-code files (e.g., docs,
CI configs, markdown). `basic-checks` (lint, format, typecheck, i18n,
skills) always runs.
- `general-test` and `render-test` are split into independent jobs with
granular path filters:
- `src/main/**`, `src/preload/**`, `scripts/**` → only triggers
`general-test`
  - `src/renderer/**` → only triggers `render-test`
  - `packages/**`, `tests/**`, config/dependency files → triggers both

### Why we need it and why it was done in this way

Non-code PRs (documentation updates, CI workflow changes, maintenance
files) do not need test suites to run, saving CI minutes and reducing
feedback latency. Granular filtering further reduces waste — a
renderer-only change no longer waits for main process tests and vice
versa.

The following tradeoffs were made:
- Tests always run on `push` to `main` and `workflow_dispatch` for
safety, even if the change is non-code.
- `packages/**` changes trigger both test jobs since packages may be
consumed by either process.

The following alternatives were considered:
- Using `paths` / `paths-ignore` on the workflow trigger level, but that
would skip the entire workflow including `basic-checks`.
- Keeping a single `tests` matrix job, but separate jobs allow job-level
`if` conditions for independent skipping and clearer GitHub UI feedback.

### Breaking changes

None.

### Special notes for your reviewer

- Uses `dorny/paths-filter@v3` for change detection with three filter
groups: `main`, `renderer`, `shared`.
- The `changes` job is lightweight (checkout + filter only, no `pnpm
install`).
- The `notify` job dependencies updated from `[ci,
skills-check-windows]` to `[basic-checks, general-test, render-test,
skills-check-windows]`.
- `tests/**` is included in the `shared` filter so test-only PRs still
trigger test jobs.

### Checklist

- [x] PR: The PR description is expressive enough and will help future
contributors
- [x] Code: [Write code that humans can
understand](https://en.wikiquote.org/wiki/Martin_Fowler#code-for-humans)
and [Keep it simple](https://en.wikipedia.org/wiki/KISS_principle)
- [x] Refactor: You have [left the code cleaner than you found it (Boy
Scout
Rule)](https://learning.oreilly.com/library/view/97-things-every/9780596809515/ch08.html)
- [x] Upgrade: Impact of this change on upgrade flows was considered and
addressed if required
- [ ] Documentation: A [user-guide update](https://docs.cherry-ai.com)
was considered and is present (link) or not required. You want a
user-guide update if it's a user facing feature.

### Release note

```release-note
NONE
```

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
SuYao
2026-02-25 14:29:14 +08:00
committed by GitHub
parent 72eb065f69
commit 847ecfe947

View File

@@ -16,12 +16,41 @@ on:
types: [ready_for_review, synchronize, opened, edited]
jobs:
ci:
changes:
runs-on: ubuntu-latest
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event.pull_request.draft == false
outputs:
main: ${{ steps.filter.outputs.main }}
renderer: ${{ steps.filter.outputs.renderer }}
shared: ${{ steps.filter.outputs.shared }}
steps:
- name: Check out Git repository
uses: actions/checkout@v6
- name: Detect code changes
id: filter
uses: dorny/paths-filter@v3
with:
filters: |
main:
- 'src/main/**'
- 'src/preload/**'
- 'scripts/**'
renderer:
- 'src/renderer/**'
shared:
- 'packages/**'
- 'tests/**'
- 'package.json'
- 'pnpm-lock.yaml'
- 'pnpm-workspace.yaml'
- 'tsconfig*.json'
- 'electron.vite.config.ts'
- 'vitest.config.ts'
- 'patches/**'
basic-checks:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
task: [basic-checks, general-test, render-test]
env:
CI: true
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch' || github.event.pull_request.draft == false
@@ -55,47 +84,114 @@ jobs:
run: pnpm install
- name: Lint Check
if: matrix.task == 'basic-checks'
run: pnpm test:lint
- name: Format Check
if: matrix.task == 'basic-checks'
run: pnpm format:check
- name: Type Check
if: matrix.task == 'basic-checks'
run: pnpm typecheck
- name: i18n Check
if: matrix.task == 'basic-checks'
run: pnpm i18n:check
- name: Hardcoded Strings Check
if: matrix.task == 'basic-checks'
run: pnpm i18n:hardcoded:strict
- name: Skills Check
if: matrix.task == 'basic-checks'
run: pnpm skills:check
general-test:
runs-on: ubuntu-latest
needs: changes
if: >-
needs.changes.outputs.main == 'true' ||
needs.changes.outputs.shared == 'true' ||
github.event_name == 'push' ||
github.event_name == 'workflow_dispatch'
env:
CI: true
steps:
- name: Check out Git repository
uses: actions/checkout@v6
- name: Install Node.js
uses: actions/setup-node@v6
with:
node-version: 22
- name: Install pnpm
uses: pnpm/action-setup@v4
- name: Get pnpm store directory
id: pnpm-cache
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
- name: Cache pnpm dependencies
uses: actions/cache@v5
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
- name: Install Dependencies
run: pnpm install
- name: Main Process Test
if: matrix.task == 'general-test'
run: pnpm test:main
- name: AI Core Test
if: matrix.task == 'general-test'
run: pnpm test:aicore
- name: Shared Package Test
if: matrix.task == 'general-test'
run: pnpm test:shared
- name: Scripts Test
if: matrix.task == 'general-test'
run: pnpm test:scripts
render-test:
runs-on: ubuntu-latest
needs: changes
if: >-
needs.changes.outputs.renderer == 'true' ||
needs.changes.outputs.shared == 'true' ||
github.event_name == 'push' ||
github.event_name == 'workflow_dispatch'
env:
CI: true
steps:
- name: Check out Git repository
uses: actions/checkout@v6
- name: Install Node.js
uses: actions/setup-node@v6
with:
node-version: 22
- name: Install pnpm
uses: pnpm/action-setup@v4
- name: Get pnpm store directory
id: pnpm-cache
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
- name: Cache pnpm dependencies
uses: actions/cache@v5
with:
path: ${{ steps.pnpm-cache.outputs.STORE_PATH }}
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-
- name: Install Dependencies
run: pnpm install
- name: Renderer Test
if: matrix.task == 'render-test'
run: pnpm test:renderer
skills-check-windows:
@@ -136,8 +232,8 @@ jobs:
notify:
runs-on: ubuntu-latest
needs: [ci, skills-check-windows]
if: always() && (needs.ci.result == 'failure' || needs.skills-check-windows.result == 'failure') && github.event_name == 'push' && github.ref == 'refs/heads/main'
needs: [basic-checks, general-test, render-test, skills-check-windows]
if: always() && (needs.basic-checks.result == 'failure' || needs.general-test.result == 'failure' || needs.render-test.result == 'failure' || needs.skills-check-windows.result == 'failure') && github.event_name == 'push' && github.ref == 'refs/heads/main'
steps:
- name: Check out Git repository
uses: actions/checkout@v6