mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-07-06 05:55:28 +08:00
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:
132
.github/workflows/ci.yml
vendored
132
.github/workflows/ci.yml
vendored
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user