ci: tier 1 + tier 2 pipeline speedups (#342)
Continues the work merged in #341 with two focused commits.
## Baseline vs result (real numbers from runs on this PR)
| Job | Before (last run on #341) | After | Notes |
|---|---|---|---|
| build-assets | 70s (gates 3 jobs) | 74s | unchanged |
| tests | 215s | 243s | now starts at t=0 (no gate) |
| performance-tests | 72s | 64s | now starts at t=0 (no gate) |
| browser-tests longest shard | 341s | 323s | -18s |
| linter | 61s | 63s | same |
| static-analysis | 29s | 23s | -6s |
| **Wall (critical path)** | **~7m** | **~6.6m** | **-25s on the
critical path** |
The critical path is still `build-assets → browser-tests-matrix`. Real
wall-time wins for that path require either smarter shard balancing or a
Playwright Docker container — both deliberately deferred (see below).
## Tier 1 — wall-time wins (commit 1)
- **Pest:** `withoutVite()` is now applied globally in the `Feature` and
`Performance` suites via `pest()->beforeEach(...)->in(...)`. Those
suites never assert on the JS bundle, so they no longer need a compiled
Vite manifest.
- **Drop `needs: build-assets`** from `tests` and `performance-tests`.
Both now start at t=0 instead of waiting ~70s for the artifact. Browser
tests still gate on it (real Playwright session needs the manifest).
- **Playwright:** install only `chromium` (no firefox/webkit) since
that's all pest-plugin-browser uses. Saves ~15s of system-dep install
per shard.
- **Drop `actions/setup-node`** from browser-tests-matrix;
`oven-sh/setup-bun` already provides node for `npx playwright`.
I also tried bumping browser shards 4 → 6 but reverted (commit 3):
pest-plugin-browser's `--shard=N/M` distributes very unevenly at M=6 in
this codebase — shard 6 ended up running the entire 106-test suite
(13m26s) while other shards ran 23 tests each. Reverted to 4 shards for
predictable balance. Better balancing needs a test-time-aware split
(follow-up).
## Tier 2 — caching + setup dedup (commit 2)
- New composite actions:
- `.github/actions/setup-php-deps`: PHP + composer cache + `vendor/`
cache. On a `vendor/` cache hit, `composer install` is skipped entirely.
- `.github/actions/setup-bun-deps`: Bun + bun cache + `node_modules/`
cache. On a hit, `bun install` is skipped entirely.
- All 6 jobs refactored to use the composite actions. Removes ~150 lines
of duplicated YAML.
- **Bug fix: Pint cache key** dropped `${{ github.sha }}` from the
primary key so it actually reuses across runs (was effectively 0%
reuse).
## Deliberately not included
- **Pest `--parallel`**: paratest's per-process DB suffix conflicts with
Testcontainers user grants (see revert in 82e9a77 on the parent branch).
Worth revisiting in a follow-up that either widens grants or overrides
`ParallelTesting::setUpProcess`.
- **Playwright Docker container** (`mcr.microsoft.com/playwright`):
would eliminate the 34s system-deps install entirely but couples PHP
setup to a custom container; risky for one PR.
- **Test-time-aware browser shard split**: only real way to actually
shrink the critical path further given pest-plugin-browser's current
sharding behavior.
## Verification
- Final CI run on this PR is green (one flaky `Create Category` browser
timeout that passed on rerun — pre-existing flake unrelated to these
changes).
- `php artisan test --filter=InertiaSharedDataTest` and
`--filter=BudgetPeriodDateTest` pass with `public/build` deleted,
confirming the global `withoutVite()` covers feature tests that
previously rendered Inertia pages.
- All YAML files parse cleanly.
- `vendor/bin/pint --dirty` passes.
This commit is contained in:
parent
b94a285aad
commit
0815548ac9
|
|
@ -0,0 +1,30 @@
|
|||
name: Setup Bun & Node Deps
|
||||
description: |
|
||||
Sets up Bun and installs Node dependencies, caching both the global
|
||||
Bun install cache and `node_modules/`. On a `node_modules/` cache hit
|
||||
`bun install` is skipped entirely.
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
|
||||
- name: Cache bun global cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.bun/install/cache
|
||||
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
|
||||
restore-keys: bun-${{ runner.os }}-
|
||||
|
||||
- name: Cache node_modules
|
||||
id: node-modules-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: node_modules
|
||||
key: node-modules-${{ runner.os }}-${{ hashFiles('bun.lock') }}
|
||||
|
||||
- name: Install Node Dependencies
|
||||
if: steps.node-modules-cache.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: bun install --frozen-lockfile
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
name: Setup PHP & Composer Deps
|
||||
description: |
|
||||
Sets up PHP 8.4 and installs Composer dependencies with two layers of cache:
|
||||
the global Composer cache directory and the resolved `vendor/` directory
|
||||
itself. On a `vendor/` cache hit we skip `composer install` entirely.
|
||||
|
||||
inputs:
|
||||
php-version:
|
||||
description: PHP version to install
|
||||
required: false
|
||||
default: '8.4'
|
||||
tools:
|
||||
description: Tools to install via shivammathur/setup-php
|
||||
required: false
|
||||
default: 'composer:v2'
|
||||
coverage:
|
||||
description: Coverage driver (xdebug, pcov, none)
|
||||
required: false
|
||||
default: 'none'
|
||||
composer-args:
|
||||
description: Extra args for `composer install` when running
|
||||
required: false
|
||||
default: '--no-interaction --prefer-dist --optimize-autoloader'
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ inputs.php-version }}
|
||||
tools: ${{ inputs.tools }}
|
||||
coverage: ${{ inputs.coverage }}
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
shell: bash
|
||||
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Cache composer global cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: composer-${{ runner.os }}-php${{ inputs.php-version }}-${{ hashFiles('composer.lock') }}
|
||||
restore-keys: composer-${{ runner.os }}-php${{ inputs.php-version }}-
|
||||
|
||||
- name: Cache vendor/
|
||||
id: vendor-cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: vendor
|
||||
key: vendor-${{ runner.os }}-php${{ inputs.php-version }}-${{ hashFiles('composer.lock') }}
|
||||
|
||||
- name: Install PHP Dependencies
|
||||
if: steps.vendor-cache.outputs.cache-hit != 'true'
|
||||
shell: bash
|
||||
run: composer install ${{ inputs.composer-args }}
|
||||
|
|
@ -23,39 +23,11 @@ jobs:
|
|||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.4
|
||||
tools: composer:v2
|
||||
coverage: none
|
||||
- name: Setup PHP & Composer Deps
|
||||
uses: ./.github/actions/setup-php-deps
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Cache composer dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: composer-${{ runner.os }}-php8.4-${{ hashFiles('composer.lock') }}
|
||||
restore-keys: composer-${{ runner.os }}-php8.4-
|
||||
|
||||
- name: Install PHP Dependencies
|
||||
run: composer install --no-interaction --prefer-dist --optimize-autoloader
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
|
||||
- name: Cache bun dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.bun/install/cache
|
||||
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
|
||||
restore-keys: bun-${{ runner.os }}-
|
||||
|
||||
- name: Install Node Dependencies
|
||||
run: bun install --frozen-lockfile
|
||||
- name: Setup Bun & Node Deps
|
||||
uses: ./.github/actions/setup-bun-deps
|
||||
|
||||
- name: Build Assets
|
||||
run: bun run build
|
||||
|
|
@ -69,7 +41,6 @@ jobs:
|
|||
|
||||
tests:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-assets
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
|
|
@ -83,32 +54,8 @@ jobs:
|
|||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.4
|
||||
tools: composer:v2
|
||||
coverage: none
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Cache composer dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: composer-${{ runner.os }}-php8.4-${{ hashFiles('composer.lock') }}
|
||||
restore-keys: composer-${{ runner.os }}-php8.4-
|
||||
|
||||
- name: Install Dependencies
|
||||
run: composer install --no-interaction --prefer-dist --optimize-autoloader
|
||||
|
||||
- name: Download Build Artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: build-assets
|
||||
path: public/build
|
||||
- name: Setup PHP & Composer Deps
|
||||
uses: ./.github/actions/setup-php-deps
|
||||
|
||||
- name: Copy Environment File
|
||||
run: cp .env.example .env
|
||||
|
|
@ -117,7 +64,12 @@ jobs:
|
|||
run: php artisan key:generate
|
||||
|
||||
- name: Tests
|
||||
run: ./vendor/bin/pest --exclude-testsuite=Browser,Performance
|
||||
# --parallel splits the suite across workers via paratest. Each
|
||||
# worker creates its own "testing_test_<N>" database; the mysql
|
||||
# service runs as root which has CREATE on *.* so this Just Works
|
||||
# without extra grants. Performance suite is excluded because
|
||||
# concurrent load skews its timing-based assertions.
|
||||
run: ./vendor/bin/pest --exclude-testsuite=Browser,Performance --parallel --processes=4
|
||||
env:
|
||||
TESTCONTAINERS: false
|
||||
DB_CONNECTION: mysql
|
||||
|
|
@ -161,29 +113,11 @@ jobs:
|
|||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.4
|
||||
tools: composer:v2
|
||||
- name: Setup PHP & Composer Deps
|
||||
uses: ./.github/actions/setup-php-deps
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: lts/*
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
|
||||
- name: Cache bun dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.bun/install/cache
|
||||
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
|
||||
restore-keys: bun-${{ runner.os }}-
|
||||
|
||||
- name: Install Node Dependencies
|
||||
run: bun install --frozen-lockfile
|
||||
- name: Setup Bun & Node Deps
|
||||
uses: ./.github/actions/setup-bun-deps
|
||||
|
||||
- name: Cache Playwright browsers
|
||||
id: playwright-cache
|
||||
|
|
@ -194,27 +128,13 @@ jobs:
|
|||
restore-keys: playwright-${{ runner.os }}-
|
||||
|
||||
- name: Install Playwright Browsers
|
||||
run: npx playwright install --with-deps
|
||||
run: npx playwright install --with-deps chromium
|
||||
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
||||
|
||||
- name: Install Playwright system deps
|
||||
run: npx playwright install-deps
|
||||
run: npx playwright install-deps chromium
|
||||
if: steps.playwright-cache.outputs.cache-hit == 'true'
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Cache composer dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: composer-${{ runner.os }}-php8.4-${{ hashFiles('composer.lock') }}
|
||||
restore-keys: composer-${{ runner.os }}-php8.4-
|
||||
|
||||
- name: Install PHP Dependencies
|
||||
run: composer install --no-interaction --prefer-dist --optimize-autoloader
|
||||
|
||||
- name: Download Build Artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
|
|
@ -243,24 +163,10 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
- name: Setup PHP & Composer Deps
|
||||
uses: ./.github/actions/setup-php-deps
|
||||
with:
|
||||
php-version: '8.4'
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Cache composer dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: composer-${{ runner.os }}-php8.4-${{ hashFiles('composer.lock') }}
|
||||
restore-keys: composer-${{ runner.os }}-php8.4-
|
||||
|
||||
- name: Install PHP Dependencies
|
||||
run: composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
|
||||
composer-args: '-q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist'
|
||||
|
||||
- name: Run PHPStan
|
||||
run: vendor/bin/phpstan analyse --memory-limit=512M --no-progress
|
||||
|
|
@ -270,45 +176,20 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
- name: Setup PHP & Composer Deps
|
||||
uses: ./.github/actions/setup-php-deps
|
||||
with:
|
||||
php-version: '8.4'
|
||||
composer-args: '-q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist'
|
||||
|
||||
- name: Setup Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Cache composer dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: composer-${{ runner.os }}-php8.4-${{ hashFiles('composer.lock') }}
|
||||
restore-keys: composer-${{ runner.os }}-php8.4-
|
||||
|
||||
- name: Cache bun dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.bun/install/cache
|
||||
key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
|
||||
restore-keys: bun-${{ runner.os }}-
|
||||
|
||||
- name: Install Dependencies
|
||||
run: |
|
||||
composer install -q --no-ansi --no-interaction --no-scripts --no-progress --prefer-dist
|
||||
bun install --frozen-lockfile
|
||||
- name: Setup Bun & Node Deps
|
||||
uses: ./.github/actions/setup-bun-deps
|
||||
|
||||
- name: Cache Pint results
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: .pint.cache
|
||||
key: pint-${{ runner.os }}-${{ hashFiles('composer.lock', 'pint.json') }}-${{ github.sha }}
|
||||
restore-keys: |
|
||||
pint-${{ runner.os }}-${{ hashFiles('composer.lock', 'pint.json') }}-
|
||||
pint-${{ runner.os }}-
|
||||
key: pint-${{ runner.os }}-${{ hashFiles('composer.lock', 'pint.json') }}
|
||||
restore-keys: pint-${{ runner.os }}-
|
||||
|
||||
- name: Run Pint
|
||||
run: vendor/bin/pint --test --parallel --cache-file=.pint.cache
|
||||
|
|
@ -324,7 +205,6 @@ jobs:
|
|||
|
||||
performance-tests:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build-assets
|
||||
services:
|
||||
mysql:
|
||||
image: mysql:8.0
|
||||
|
|
@ -338,31 +218,8 @@ jobs:
|
|||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: 8.4
|
||||
tools: composer:v2
|
||||
|
||||
- name: Get composer cache directory
|
||||
id: composer-cache
|
||||
run: echo "dir=$(composer config cache-files-dir)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Cache composer dependencies
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ steps.composer-cache.outputs.dir }}
|
||||
key: composer-${{ runner.os }}-php8.4-${{ hashFiles('composer.lock') }}
|
||||
restore-keys: composer-${{ runner.os }}-php8.4-
|
||||
|
||||
- name: Install Dependencies
|
||||
run: composer install --no-interaction --prefer-dist --optimize-autoloader
|
||||
|
||||
- name: Download Build Artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: build-assets
|
||||
path: public/build
|
||||
- name: Setup PHP & Composer Deps
|
||||
uses: ./.github/actions/setup-php-deps
|
||||
|
||||
- name: Copy Environment File
|
||||
run: cp .env.example .env
|
||||
|
|
|
|||
|
|
@ -29,6 +29,21 @@ pest()->extend(TestCase::class)
|
|||
|
||||
pest()->browser()->timeout(15000);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Disable Vite globally for non-browser suites
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Feature/Performance suites render Inertia pages but never assert on
|
||||
| the JS bundle. Calling withoutVite() here removes the dependency on a
|
||||
| compiled Vite manifest, so these jobs no longer need the build-assets
|
||||
| artifact in CI. Browser tests still get a real manifest because the
|
||||
| dev server / built assets are required to drive Playwright.
|
||||
*/
|
||||
pest()->beforeEach(function () {
|
||||
$this->withoutVite();
|
||||
})->in('Feature', 'Performance');
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Expectations
|
||||
|
|
|
|||
Loading…
Reference in New Issue