From 5a8a8fe696b311e8ebbbb9f75e139ccd0afeed11 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Sun, 9 Aug 2026 12:06:25 -0300 Subject: [PATCH 1/5] ci: name e2e shards descriptively and add time-balanced sharding - e2e job now shows as "e2e (shard 1/2)" / "e2e (shard 2/2)" in checks instead of the unlabeled matrix "(1)" / "(2)" suffix - add scheduled/manual "Update Shards" workflow that generates and commits tests/.pest/shards.json so Pest balances the two e2e shards by real execution time instead of file count --- .github/workflows/tests.yml | 1 + .github/workflows/update-shards.yml | 79 +++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 .github/workflows/update-shards.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 497efe6d7..73d30e613 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -62,6 +62,7 @@ jobs: run: php artisan test --compact --parallel e2e: + name: e2e (shard ${{ matrix.shard }}/2) runs-on: ubuntu-latest strategy: diff --git a/.github/workflows/update-shards.yml b/.github/workflows/update-shards.yml new file mode 100644 index 000000000..29a4c1756 --- /dev/null +++ b/.github/workflows/update-shards.yml @@ -0,0 +1,79 @@ +name: Update Shards + +on: + workflow_dispatch: + schedule: + - cron: '0 0 * * 1' + +permissions: + contents: write + +env: + DB_CONNECTION: pgsql + DB_DATABASE: trypost_test + DB_USERNAME: postgres + DB_PASSWORD: password + BROADCAST_CONNECTION: "null" + CACHE_STORE: array + QUEUE_CONNECTION: sync + SESSION_DRIVER: array + +jobs: + update-shards: + runs-on: ubuntu-latest + + services: + postgres: + image: postgres:16 + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: password + POSTGRES_DB: trypost_test + ports: + - 5432/tcp + options: >- + --health-cmd="pg_isready" + --health-interval=10s + --health-timeout=5s + --health-retries=3 + + redis: + image: redis:7 + ports: + - 6379/tcp + options: >- + --health-cmd="redis-cli ping" + --health-interval=10s + --health-timeout=5s + --health-retries=3 + + steps: + - name: Checkout code + uses: actions/checkout@v7 + + - name: Setup test environment + uses: ./.github/actions/setup-laravel + with: + node: 'true' + db-port: ${{ job.services.postgres.ports['5432'] }} + redis-port: ${{ job.services.redis.ports['6379'] }} + + - name: Build assets + run: npm run build + + - name: Install Playwright browsers + run: npx playwright install --with-deps chromium + + - name: Update shard timings + env: + DB_PORT: ${{ job.services.postgres.ports['5432'] }} + REDIS_PORT: ${{ job.services.redis.ports['6379'] }} + run: php artisan test tests/Browser --compact --parallel --update-shards + + - name: Commit updated shard timings + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add tests/.pest/shards.json + git diff --cached --quiet || git commit -m "chore: update e2e shard timings" + git push From f2d6d3c95a520fb66f4f6644ee0c479e7ff9f477 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Sun, 9 Aug 2026 12:13:01 -0300 Subject: [PATCH 2/5] ci: enable Pest TIA for local test runs Scoped to local via locally() so CI keeps running the full suite on every commit. Add composer test:tia script using herd coverage, since Herd bundles Xdebug but doesn't load it by default. --- composer.json | 3 +++ tests/Pest.php | 13 +++++++++++++ 2 files changed, 16 insertions(+) diff --git a/composer.json b/composer.json index 6904ab78f..bca98f708 100644 --- a/composer.json +++ b/composer.json @@ -125,6 +125,9 @@ "@test", "@php artisan test tests/Browser" ], + "test:tia": [ + "herd coverage vendor/bin/pest --parallel --tia" + ], "post-autoload-dump": [ "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", "@php artisan package:discover --ansi" diff --git a/tests/Pest.php b/tests/Pest.php index 8c954741f..ecebbc504 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -33,6 +33,19 @@ ->use(RefreshDatabase::class) ->in('Browser'); +/* +|-------------------------------------------------------------------------- +| Test Impact Analysis +|-------------------------------------------------------------------------- +| +| Only re-run tests affected by local changes, replaying cached results for +| the rest. Scoped to local runs via "locally()" — automatically skipped on +| CI (or when the "--ci" flag is passed), which always runs the full suite. +| +*/ + +pest()->tia()->locally(); + /* |-------------------------------------------------------------------------- | Expectations From f32f41838221bd8a5aadec2f9c5ca2d75f1085c0 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Sun, 9 Aug 2026 12:14:43 -0300 Subject: [PATCH 3/5] ci: drop Herd-specific prefix from test:tia composer script MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit trypost is open-source and self-hosted; not every contributor runs Herd. The script now just needs a coverage driver (Xdebug/PCOV) active however the environment provides it — Herd users can run it via "herd coverage composer test:tia". --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index bca98f708..8690d44b2 100644 --- a/composer.json +++ b/composer.json @@ -126,7 +126,7 @@ "@php artisan test tests/Browser" ], "test:tia": [ - "herd coverage vendor/bin/pest --parallel --tia" + "vendor/bin/pest --parallel --tia" ], "post-autoload-dump": [ "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", From fa7ce6f306ed82484af5b5f16bb1afa28c869dc0 Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Sun, 9 Aug 2026 12:18:41 -0300 Subject: [PATCH 4/5] ci: revert e2e sharding, drop Update Shards workflow Sharding across 2 runners added complexity (unbalanced shards without timing data, plus an Update Shards workflow that can't push straight to main under branch protection) that isn't worth it here. e2e now runs tests/Browser as a single job again; e2e-gate stays as a pass-through so the required branch protection check name is unchanged. --- .github/workflows/tests.yml | 12 ++--- .github/workflows/update-shards.yml | 79 ----------------------------- 2 files changed, 3 insertions(+), 88 deletions(-) delete mode 100644 .github/workflows/update-shards.yml diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 73d30e613..9278e0830 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -62,14 +62,8 @@ jobs: run: php artisan test --compact --parallel e2e: - name: e2e (shard ${{ matrix.shard }}/2) runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - shard: [1, 2] - services: postgres: image: postgres:16 @@ -116,13 +110,13 @@ jobs: env: DB_PORT: ${{ job.services.postgres.ports['5432'] }} REDIS_PORT: ${{ job.services.redis.ports['6379'] }} - run: php artisan test tests/Browser --compact --shard=${{ matrix.shard }}/2 + run: php artisan test tests/Browser --compact - name: Upload Playwright artifacts if: failure() uses: actions/upload-artifact@v7 with: - name: playwright-artifacts-${{ matrix.shard }} + name: playwright-artifacts path: tests/Browser/Screenshots if-no-files-found: ignore retention-days: 7 @@ -132,5 +126,5 @@ jobs: needs: e2e runs-on: ubuntu-latest steps: - - name: Require all e2e shards to pass + - name: Require e2e to pass run: '[ "${{ needs.e2e.result }}" = "success" ] || exit 1' diff --git a/.github/workflows/update-shards.yml b/.github/workflows/update-shards.yml deleted file mode 100644 index 29a4c1756..000000000 --- a/.github/workflows/update-shards.yml +++ /dev/null @@ -1,79 +0,0 @@ -name: Update Shards - -on: - workflow_dispatch: - schedule: - - cron: '0 0 * * 1' - -permissions: - contents: write - -env: - DB_CONNECTION: pgsql - DB_DATABASE: trypost_test - DB_USERNAME: postgres - DB_PASSWORD: password - BROADCAST_CONNECTION: "null" - CACHE_STORE: array - QUEUE_CONNECTION: sync - SESSION_DRIVER: array - -jobs: - update-shards: - runs-on: ubuntu-latest - - services: - postgres: - image: postgres:16 - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: password - POSTGRES_DB: trypost_test - ports: - - 5432/tcp - options: >- - --health-cmd="pg_isready" - --health-interval=10s - --health-timeout=5s - --health-retries=3 - - redis: - image: redis:7 - ports: - - 6379/tcp - options: >- - --health-cmd="redis-cli ping" - --health-interval=10s - --health-timeout=5s - --health-retries=3 - - steps: - - name: Checkout code - uses: actions/checkout@v7 - - - name: Setup test environment - uses: ./.github/actions/setup-laravel - with: - node: 'true' - db-port: ${{ job.services.postgres.ports['5432'] }} - redis-port: ${{ job.services.redis.ports['6379'] }} - - - name: Build assets - run: npm run build - - - name: Install Playwright browsers - run: npx playwright install --with-deps chromium - - - name: Update shard timings - env: - DB_PORT: ${{ job.services.postgres.ports['5432'] }} - REDIS_PORT: ${{ job.services.redis.ports['6379'] }} - run: php artisan test tests/Browser --compact --parallel --update-shards - - - name: Commit updated shard timings - run: | - git config user.name "github-actions[bot]" - git config user.email "github-actions[bot]@users.noreply.github.com" - git add tests/.pest/shards.json - git diff --cached --quiet || git commit -m "chore: update e2e shard timings" - git push From 55971c0ccde5ca464627b64f092d57b30c5891ad Mon Sep 17 00:00:00 2001 From: Paulo Castellano Date: Sun, 9 Aug 2026 12:21:13 -0300 Subject: [PATCH 5/5] ci: drop redundant e2e-gate job e2e-gate only mirrored e2e's own result once sharding was removed. Updated main's branch protection required_status_checks to require "e2e" directly instead of "e2e-gate". --- .github/workflows/tests.yml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9278e0830..ab2e19625 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -120,11 +120,3 @@ jobs: path: tests/Browser/Screenshots if-no-files-found: ignore retention-days: 7 - - e2e-gate: - if: always() - needs: e2e - runs-on: ubuntu-latest - steps: - - name: Require e2e to pass - run: '[ "${{ needs.e2e.result }}" = "success" ] || exit 1'