forked from akai/readest
ci: pin android-emulator-runner by SHA + shard the slow PR test job (#4547)
* ci(security): pin android-emulator-runner action by commit SHA Scorecard Pinned-Dependencies flagged the two reactivecircus/android-emulator-runner@v2 usages in android-e2e.yml as third-party actions not pinned by hash (code-scanning alerts #116, #117). Pin both to the full commit SHA the v2 tag currently resolves to (e89f39f = v2.37.0), matching the @<sha> # <version> convention already used by every other action in this workflow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci(pull-request): shard web unit tests and split out test_extensions The jsdom unit suite was ~115s of the 280s test_web_app job — the slowest check on every PR. Split it across two parallel shards with vitest --shard, and move the browser-extension + koplugin tests into a new test_extensions job. - test_web_app: matrix shard [1, 2] running `vitest run --shard=N/2`; Playwright + browser tests run on shard 1 only. - test_extensions: extension tests + browser-ext build run always; the koplugin Lua tests (and their ~45s LuaJIT/busted install) run only when apps/readest.koplugin/** changed, detected via dorny/paths-filter (pinned by SHA; needs pull-requests: read to list PR files). - package.json: add test:pr:web:unit so CI can append --shard; test:pr:web still runs the full sequence locally. Cuts the PR critical path from ~280s toward ~188s (now build_tauri_app). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci(pull-request): isolate koplugin lint + LuaJIT install into test_extensions build_web_app was the slowest PR job and installed LuaJIT + ran the koplugin syntax check on every PR. Move all koplugin tooling into test_extensions, gated on apps/readest.koplugin/** like the koplugin Lua tests already are: - build_web_app drops the LuaJIT install. - test_extensions installs LuaJIT/busted and runs `pnpm lint:lua` + `pnpm test:lua` only when the koplugin sources changed. - `pnpm lint` is now web-only (tsgo + biome); `lint:lua` stays a standalone script that test_extensions (and local koplugin work) calls directly. This also drops koplugin lint from the pre-push hook. - verification rule updated to match. Most PRs now skip the koplugin toolchain entirely. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -107,7 +107,7 @@ jobs:
|
||||
|
||||
- name: create AVD snapshot for caching
|
||||
if: steps.avd-cache.outputs.cache-hit != 'true'
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a # v2
|
||||
with:
|
||||
api-level: 34
|
||||
arch: x86_64
|
||||
@@ -118,7 +118,7 @@ jobs:
|
||||
script: echo "AVD snapshot created"
|
||||
|
||||
- name: run Android e2e lane
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a # v2
|
||||
with:
|
||||
api-level: 34
|
||||
arch: x86_64
|
||||
|
||||
@@ -77,13 +77,13 @@ jobs:
|
||||
run: |
|
||||
pnpm install --frozen-lockfile --prefer-offline && pnpm setup-vendors
|
||||
|
||||
- name: install LuaJIT (for koplugin lint)
|
||||
run: sudo apt-get update && sudo apt-get install -y luajit
|
||||
|
||||
- name: run format check
|
||||
run: |
|
||||
pnpm format:check || (pnpm format && git diff && exit 1)
|
||||
|
||||
# pnpm lint here is web-only (tsgo + biome). The koplugin syntax check
|
||||
# (lint:lua) runs in the test_extensions job, which installs LuaJIT only
|
||||
# when the koplugin sources changed.
|
||||
- name: run lint
|
||||
working-directory: apps/readest-app
|
||||
run: |
|
||||
@@ -123,8 +123,16 @@ jobs:
|
||||
path: apps/readest-app/playwright-report/
|
||||
retention-days: 7
|
||||
|
||||
# The jsdom unit suite is the slowest part of the PR checks, so it is split
|
||||
# across two parallel shards (vitest --shard). The browser tests need
|
||||
# Playwright and run only on shard 1; koplugin + browser-extension tests
|
||||
# moved to the test_extensions job.
|
||||
test_web_app:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shard: [1, 2]
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
@@ -144,16 +152,91 @@ jobs:
|
||||
run: |
|
||||
pnpm install --frozen-lockfile --prefer-offline && pnpm setup-vendors
|
||||
|
||||
# Playwright is only needed by the browser tests, which run on shard 1.
|
||||
- name: cache playwright browsers
|
||||
if: matrix.shard == 1
|
||||
id: playwright-cache
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: playwright-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
- name: install playwright browsers
|
||||
if: matrix.shard == 1
|
||||
working-directory: apps/readest-app
|
||||
run: |
|
||||
if [ "${{ steps.playwright-cache.outputs.cache-hit }}" = 'true' ]; then
|
||||
npx playwright install-deps chromium
|
||||
else
|
||||
npx playwright install --with-deps chromium
|
||||
fi
|
||||
|
||||
- name: run web unit tests (shard ${{ matrix.shard }}/2)
|
||||
working-directory: apps/readest-app
|
||||
run: pnpm test:pr:web:unit --shard=${{ matrix.shard }}/2
|
||||
|
||||
- name: run web browser tests
|
||||
if: matrix.shard == 1
|
||||
working-directory: apps/readest-app
|
||||
run: pnpm test:browser
|
||||
|
||||
# Browser-extension tests + build always run. The koplugin lint + Lua tests
|
||||
# (and the ~45s LuaJIT/busted install they need) only run when the koplugin
|
||||
# sources changed, so most PRs skip that cost entirely.
|
||||
test_extensions:
|
||||
runs-on: ubuntu-latest
|
||||
# pull-requests: read lets dorny/paths-filter list a PR's changed files
|
||||
# via the REST API (the top-level grant is contents: read only).
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: read
|
||||
steps:
|
||||
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6
|
||||
with:
|
||||
submodules: 'true'
|
||||
|
||||
- name: detect koplugin changes
|
||||
id: changes
|
||||
uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4
|
||||
with:
|
||||
filters: |
|
||||
koplugin:
|
||||
- 'apps/readest.koplugin/**'
|
||||
|
||||
- name: setup pnpm
|
||||
uses: pnpm/action-setup@0e279bb959325dab635dd2c09392533439d90093 # v6
|
||||
|
||||
- name: setup node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
|
||||
with:
|
||||
node-version: 24
|
||||
cache: pnpm
|
||||
|
||||
- name: install Dependencies
|
||||
working-directory: apps/readest-app
|
||||
run: |
|
||||
pnpm install --frozen-lockfile --prefer-offline && pnpm setup-vendors
|
||||
|
||||
- name: run extension tests
|
||||
working-directory: apps/readest-app
|
||||
run: pnpm test:extension
|
||||
|
||||
- name: build browser extension
|
||||
working-directory: apps/readest-app
|
||||
run: pnpm build-browser-ext
|
||||
|
||||
- name: cache apt packages
|
||||
if: steps.changes.outputs.koplugin == 'true'
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
with:
|
||||
path: /var/cache/apt/archives
|
||||
key: apt-test-web-${{ runner.os }}
|
||||
key: apt-test-koplugin-${{ runner.os }}
|
||||
|
||||
- name: install LuaJIT + busted (for koplugin tests)
|
||||
- name: install LuaJIT + busted (for koplugin lint + tests)
|
||||
if: steps.changes.outputs.koplugin == 'true'
|
||||
run: |
|
||||
sudo apt-get update
|
||||
# luajit — pnpm test:lua
|
||||
# luajit — pnpm lint:lua + pnpm test:lua
|
||||
# luarocks/libsqlite3-dev — required to build lsqlite3complete
|
||||
sudo apt-get install -y luajit luarocks libsqlite3-dev
|
||||
# Install busted + the SQLite binding the LibraryStore specs use,
|
||||
@@ -163,27 +246,13 @@ jobs:
|
||||
sudo luarocks --lua-version=5.1 install busted
|
||||
sudo luarocks --lua-version=5.1 install lsqlite3complete
|
||||
|
||||
- name: cache playwright browsers
|
||||
id: playwright-cache
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: playwright-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
- name: install playwright browsers
|
||||
- name: lint koplugin
|
||||
if: steps.changes.outputs.koplugin == 'true'
|
||||
working-directory: apps/readest-app
|
||||
run: |
|
||||
if [ "${{ steps.playwright-cache.outputs.cache-hit }}" = 'true' ]; then
|
||||
npx playwright install-deps chromium
|
||||
else
|
||||
npx playwright install --with-deps chromium
|
||||
fi
|
||||
|
||||
- name: run web tests
|
||||
working-directory: apps/readest-app
|
||||
run: pnpm test:pr:web
|
||||
run: pnpm lint:lua
|
||||
|
||||
- name: run koplugin tests
|
||||
if: steps.changes.outputs.koplugin == 'true'
|
||||
working-directory: apps/readest-app
|
||||
run: pnpm test:lua
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
Before marking work complete, all applicable checks must pass:
|
||||
|
||||
1. `pnpm test` — unit tests (vitest)
|
||||
2. `pnpm lint` — Biome + tsgo (also runs `pnpm lint:lua` if luajit is installed)
|
||||
3. `pnpm test:lua` — busted unit tests for `apps/readest.koplugin/spec/` (only when koplugin Lua files changed; soft-skips when busted/luajit not installed)
|
||||
2. `pnpm lint` — Biome + tsgo (web only)
|
||||
3. `pnpm lint:lua` + `pnpm test:lua` — koplugin LuaJIT syntax check + busted unit tests for `apps/readest.koplugin/spec/` (only when koplugin Lua files changed; soft-skip when luajit/busted not installed)
|
||||
4. `pnpm fmt:check` — Rust format check (only when `src-tauri/` files changed)
|
||||
5. `pnpm clippy:check` — Rust lint (only when `src-tauri/` files changed)
|
||||
6. `pnpm test:rust` — Rust unit tests (`cargo test -p Readest --lib`; only when `src-tauri/` files changed); also run in the CI `rust_lint` job
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"dev-ios": "tauri ios build -- --features devtools && ideviceinstaller install src-tauri/gen/apple/build/arm64/Readest.ipa",
|
||||
"i18n:extract": "i18next-scanner --config i18next-scanner.config.cjs",
|
||||
"i18n:extract:ext": "pnpm --filter @readest/send-to-readest-extension i18n:extract",
|
||||
"lint": "tsgo --noEmit && biome lint . && pnpm lint:lua",
|
||||
"lint": "tsgo --noEmit && biome lint .",
|
||||
"lint:lua": "node ../readest.koplugin/scripts/lint-koplugin.mjs",
|
||||
"test:lua": "node ../readest.koplugin/scripts/test-koplugin.mjs",
|
||||
"test": "dotenv -e .env -e .env.test.local -- vitest",
|
||||
@@ -28,7 +28,8 @@
|
||||
"test:browser": "dotenv -e .env -e .env.test.local -- vitest run --config vitest.browser.config.mts",
|
||||
"test:tauri": "bash scripts/test-tauri.sh",
|
||||
"test:android": "bash scripts/test-android.sh",
|
||||
"test:pr:web": "dotenv -e .env -e .env.test.local -- vitest run --maxWorkers=4 && pnpm test:browser && pnpm test:extension && pnpm build-browser-ext",
|
||||
"test:pr:web:unit": "dotenv -e .env -e .env.test.local -- vitest run --maxWorkers=4",
|
||||
"test:pr:web": "pnpm test:pr:web:unit && pnpm test:browser && pnpm test:extension && pnpm build-browser-ext",
|
||||
"test:pr:tauri": "bash scripts/test-tauri.sh",
|
||||
"test:all": "pnpm test -- --watch=false && pnpm test:browser && bash scripts/test-tauri.sh",
|
||||
"bench": "node --experimental-strip-types --no-warnings bench/index.ts",
|
||||
|
||||
Reference in New Issue
Block a user