diff --git a/.github/workflows/frontend.yml b/.github/workflows/frontend.yml index 966c88ef2..027030cce 100644 --- a/.github/workflows/frontend.yml +++ b/.github/workflows/frontend.yml @@ -1,10 +1,33 @@ name: Frontend CI +# Pull requests run what the change can affect; a push to main runs everything. on: push: - branches: [ main, develop ] + branches: [ main ] pull_request: branches: [ main, develop ] + paths: + - 'src/**' + - 'tests/frontend/**' + - 'tests/fixtures/**' + - 'tests/setup.ts' + - 'tests/api.test.ts' + - 'cypress/**' + - 'scripts/**' + - 'package.json' + - 'package-lock.json' + - 'vite.config.ts' + - 'vitest.config.ts' + - 'tsconfig.json' + - 'eslint.config.ts' + - 'cypress.config.ts' + - '.github/workflows/frontend.yml' + +# A new push to a pull request replaces the run in progress. Runs on main are +# left to finish: they are the last full check before a release. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: lint-and-typecheck: diff --git a/.github/workflows/locales.yml b/.github/workflows/locales.yml index d43d06c8e..a80f4c8c7 100644 --- a/.github/workflows/locales.yml +++ b/.github/workflows/locales.yml @@ -1,10 +1,21 @@ name: Locale completion +# Pull requests run what the change can affect; a push to main runs everything. on: push: - branches: [ main, develop ] + branches: [ main ] pull_request: branches: [ main, develop ] + paths: + - 'locale/**' + - 'bin/check-locales.php' + - '.github/workflows/locales.yml' + +# A new push to a pull request replaces the run in progress. Runs on main are +# left to finish: they are the last full check before a release. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: check: diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 30a734553..045fa3c27 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -1,22 +1,42 @@ name: PHP CI +# Pull requests run what the change can affect; a push to main runs everything. on: push: - branches: [ main, develop ] + branches: [ main ] pull_request: branches: [ main, develop ] + paths: + - '**.php' + - 'src/**' + - 'locale/**' + - 'db/**' + - 'tests/backend/**' + - 'tests/fixtures/**' + - 'tests/sql/**' + - 'tests/tools/**' + - 'composer.json' + - 'composer.lock' + - 'phpunit.xml' + - '.github/workflows/php.yml' + +# A new push to a pull request replaces the run in progress. Runs on main are +# left to finish: they are the last full check before a release. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: test: name: PHPUnit Tests - runs-on: ${{ matrix.config.os }} + runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: - config: - - os: ubuntu-latest - - os: windows-latest + # Windows takes about 30 times as long as Ubuntu for the same tests, so + # it runs on main only, as the check before a release. + os: ${{ fromJSON(github.event_name == 'push' && '["ubuntu-latest", "windows-latest"]' || '["ubuntu-latest"]') }} php-version: [ '8.2', '8.3', '8.4', '8.5' ] steps: @@ -28,7 +48,8 @@ jobs: with: php-version: ${{ matrix.php-version }} extensions: mbstring, mysqli, dom, zip, pdo_sqlite - coverage: xdebug + # The job runs test:no-coverage; a loaded Xdebug only slows it down. + coverage: none - name: Validate composer.json and composer.lock run: composer validate --strict diff --git a/.github/workflows/phpcs.yml b/.github/workflows/phpcs.yml index a292667da..871e67993 100644 --- a/.github/workflows/phpcs.yml +++ b/.github/workflows/phpcs.yml @@ -1,10 +1,21 @@ name: PHP CodeSniffer +# Pull requests run what the change can affect; a push to main runs everything. on: push: - branches: [ main, develop ] + branches: [ main ] pull_request: branches: [ main, develop ] + paths: + - '**.php' + - 'phpcs.xml' + - '.github/workflows/phpcs.yml' + +# A new push to a pull request replaces the run in progress. Runs on main are +# left to finish: they are the last full check before a release. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: phpcs: diff --git a/.github/workflows/security_check.yml b/.github/workflows/security_check.yml index 2ced3a83b..19b0480de 100644 --- a/.github/workflows/security_check.yml +++ b/.github/workflows/security_check.yml @@ -1,10 +1,23 @@ name: Psalm Static Analysis +# Pull requests run what the change can affect; a push to main runs everything. on: push: - branches: [ main, develop ] + branches: [ main ] pull_request: branches: [ main, develop ] + paths: + - '**.php' + - 'composer.json' + - 'composer.lock' + - 'psalm.xml' + - '.github/workflows/security_check.yml' + +# A new push to a pull request replaces the run in progress. Runs on main are +# left to finish: they are the last full check before a release. +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} jobs: psalm: diff --git a/CLAUDE.md b/CLAUDE.md index 3d31e8447..3a09ef09a 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -95,6 +95,8 @@ if (!defined('LWT_TEST_DB_AVAILABLE') || !LWT_TEST_DB_AVAILABLE) { Prefer mocking or restructuring code to avoid DB calls in unit tests. Use the skip guard only when static/global DB calls cannot be avoided (e.g., deeply nested static method calls). +**What CI runs:** pull requests run only the workflows their changed paths can affect, on Ubuntu; each workflow's `paths:` list says which. A push to `main` runs everything, including PHPUnit on Windows, which takes about 30 times as long. So when a new test reads a file outside a workflow's list, add that path to the list, or a pull request can skip the check that would have failed. + Always serve the app with `npm run serve`, not a bare `php -S`: the built-in server is single-request unless `PHP_CLI_SERVER_WORKERS` is set, so one slow request blocks the rest and Cypress times out on pages that are only queued. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3f265a73c..157dd2dc6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -322,7 +322,7 @@ php bin/check-locales.php --json # Machine-readable output php bin/check-locales.php --fail-under=90 # Exit 1 if a locale drops below 90% ``` -The same script runs in CI on every push and pull request, so a missing key shows +The same script runs in CI on every push to `main` and on pull requests that touch `locale/`, so a missing key shows up in the `Locale completion` workflow before it reaches a reader. ### Improving a Translation diff --git a/docs-src/developer/contributing.md b/docs-src/developer/contributing.md index b34658fd4..e1c3121d5 100644 --- a/docs-src/developer/contributing.md +++ b/docs-src/developer/contributing.md @@ -327,7 +327,7 @@ php bin/check-locales.php --json # Machine-readable output php bin/check-locales.php --fail-under=90 # Exit 1 if a locale drops below 90% ``` -The same script runs in CI on every push and pull request, so a missing key shows +The same script runs in CI on every push to `main` and on pull requests that touch `locale/`, so a missing key shows up in the `Locale completion` workflow before it reaches a reader. ### Improving a Translation