From 3dc7c1a351c145b1d0fc448f4eb46a32091374b4 Mon Sep 17 00:00:00 2001 From: dcccrypto Date: Tue, 21 Jul 2026 08:59:00 +0100 Subject: [PATCH 1/2] =?UTF-8?q?fix(ci):=20restore=20test.yml=20on=20main?= =?UTF-8?q?=20=E2=80=94=20hashFiles()=20is=20illegal=20in=20a=20job-level?= =?UTF-8?q?=20if?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Same defect as deploy.yml (#2444, and #2448 porting it to main), but test.yml has it in three places — unit-tests, integration-tests and security-tests each carry: if: hashFiles('packages/shared/package.json') != '' hashFiles() is only available in `jobs..steps.*`, never in a job-level `if:`, so GitHub rejects the whole file at startup and creates zero jobs. Impact is larger here than for deploy.yml: test.yml is main's entire test workflow — Unit Tests, Integration Tests, Security Tests, Coverage Gate, E2E, Type Check and the Merge Gate. While the file fails to parse, none of them run for main-based branches. The workflow looks healthy in aggregate only because most active branches are playground-based, and playground already carries a fixed copy. Ported surgically rather than by copying playground's file, which also: - adds `playground` to the push/PR branch triggers, and - replaces `pnpm run build` (plus its NEXT_PUBLIC_* env) with `pnpm --filter app exec tsc --noEmit` Neither belongs on main — the second would swap a real build for a typecheck and weaken the gate. Only the three existing guards are converted; the e2e job is left unguarded exactly as main has it. Verified: actionlint reports 3 hashFiles context errors on main and 0 here; build step, env and branch triggers are untouched. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/test.yml | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0082562b2..fa9bab23a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,13 +15,34 @@ concurrency: cancel-in-progress: true jobs: + # hashFiles() is NOT valid in a job-level `if:` (only step-level) — using it there + # made GitHub reject the whole workflow ("workflow file issue"). Detect package + # presence once here and gate the backend jobs on this output instead. + detect-packages: + name: Detect packages + runs-on: ubuntu-latest + outputs: + has_packages: ${{ steps.check.outputs.has_packages }} + steps: + - name: Checkout code + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + - name: Check for packages/* + id: check + run: | + if [ -f packages/shared/package.json ]; then + echo "has_packages=true" >> "$GITHUB_OUTPUT" + else + echo "has_packages=false" >> "$GITHUB_OUTPUT" + fi + unit-tests: name: Unit Tests runs-on: ubuntu-latest timeout-minutes: 15 # Skip when packages/* workspaces are absent (e.g. waitlist-only forks). # When packages/ is restored from upstream, the guard evaluates true and the job runs. - if: hashFiles('packages/shared/package.json') != '' + needs: detect-packages + if: needs.detect-packages.outputs.has_packages == 'true' env: HAS_CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN != '' }} @@ -83,7 +104,8 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 20 # Skip when packages/* workspaces are absent (e.g. waitlist-only forks). - if: hashFiles('packages/shared/package.json') != '' + needs: detect-packages + if: needs.detect-packages.outputs.has_packages == 'true' env: RPC_URL: ${{ secrets.DEVNET_RPC_URL || 'https://api.devnet.solana.com' }} @@ -220,7 +242,8 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 # Skip when packages/* workspaces are absent (e.g. waitlist-only forks). - if: hashFiles('packages/shared/package.json') != '' + needs: detect-packages + if: needs.detect-packages.outputs.has_packages == 'true' steps: - name: Checkout code From 7b2f2541d06057014e514bda2bf75230deb432c9 Mon Sep 17 00:00:00 2001 From: dcccrypto Date: Tue, 21 Jul 2026 09:07:19 +0100 Subject: [PATCH 2/2] test(e2e): treat Vercel/Cloudflare analytics noise as CI noise, not app errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Restoring test.yml (previous commit) runs the e2e suite for the first time since 2026-05-15. Result: 56 passed, 5 skipped, 1 failed. The single failure is "Homepage has no console errors", and neither console error is an app defect — both are third-party analytics that only work on a real deployment: - cloudflareinsights.com/cdn-cgi/rum — blocked by CORS from localhost:3000 - /_vercel/insights/script.js — 404s to an HTML page, so strict MIME checking refuses to execute it collectConsoleErrors already filters exactly this class of environment noise (Privy, Supabase, WalletConnect, Sentry, hydration warnings...). These two belong in that list; they were simply never reachable while the workflow could not start. Verified by extracting the 31 filter patterns from the real source and applying them to the two strings CI actually produced: both are filtered, while genuine app errors (TypeError/ReferenceError/invalid public key) are still reported, so the assertion keeps its teeth. Co-Authored-By: Claude Opus 4.8 --- e2e/helpers.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/e2e/helpers.ts b/e2e/helpers.ts index 68bd11b5c..4c8f85013 100644 --- a/e2e/helpers.ts +++ b/e2e/helpers.ts @@ -90,6 +90,12 @@ export function collectConsoleErrors(page: Page): string[] { // Sentry DSN / monitoring not configured in CI if (text.includes("Sentry")) return; if (text.includes("sentry")) return; + // Vercel / Cloudflare analytics are only wired up on a real deployment. + // Against localhost the RUM beacon is refused by CORS and the insights + // script 404s to an HTML error page, failing strict MIME checking. + if (text.includes("cloudflareinsights.com")) return; + if (text.includes("cdn-cgi/rum")) return; + if (text.includes("_vercel/insights")) return; errors.push(text); } });