Skip to content

[CI][HIGH] No tests run in CI on playground — 4 of 5 Merge Gate dependencies are permanently skipped, and the gate passes anyway #2447

Description

@dcccrypto

Summary

percolator-launch runs zero tests in CI on playground, the branch every PR targets. The app's own suite — 2702 tests — is never executed by any workflow. The ✅ Merge Gate still reports green, because it treats skipped as not failed.

I found this while checking why my own PR #2446 (which fixes the pnpm audit gate) showed Security Tests skipping.

The chain

1. Every real test job is gated on a directory that no longer exists.

test.yml gates four jobs on detect-packages, which probes for packages/shared/package.json:

detect-packages:
  run: |
    if [ -f packages/shared/package.json ]; then
      echo "has_packages=true" >> "$GITHUB_OUTPUT"
    else
      echo "has_packages=false" >> "$GITHUB_OUTPUT"
    fi

unit-tests:        if: needs.detect-packages.outputs.has_packages == 'true'
integration-tests: if: needs.detect-packages.outputs.has_packages == 'true'
e2e-tests:         if: needs.detect-packages.outputs.has_packages == 'true'
security-tests:    if: needs.detect-packages.outputs.has_packages == 'true'

packages/ does not exist on playground or on main — both branches contain only app/:

$ git ls-tree origin/playground --name-only | grep -E '^packages|^app$'
app
$ git cat-file -e origin/playground:packages/shared/package.json  → NO
$ git cat-file -e origin/main:packages/shared/package.json        → NO

So all four are skipped on every run, on every branch. This is not a transient path filter — it cannot become true without restoring the old monorepo layout.

2. pr-check.yml is gated the same way, per-step.

Every build and test step there carries if: hashFiles('packages/<x>/package.json') != ''. With packages/ gone, the only step in Build & Fast Tests that actually executes is:

- name: Build frontend
  run: cd app && npx next build

3. Nothing anywhere runs the app suite.

grep -nE "vitest|app && .*test|test:app|pnpm test" across all four workflows (deploy.yml, pr-check.yml, smoke-test.yml, test.yml) returns zero matches. app/package.json defines "test": "vitest run" and no workflow ever calls it.

4. The Merge Gate green-lights it.

merge-gate:
  name: ✅ Merge Gate
  needs: [unit-tests, integration-tests, e2e-tests, security-tests, type-check]
  if: ${{ always() && ... && !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') }}
  steps:
    - name: All checks passed

Skipped jobs report 'skipped', not 'failure'. Four of the five needs are always skipped, so the gate passes on type-check alone — while displaying a step literally named "All checks passed".

What actually runs on a playground PR

Check Runs? What it proves
Type Check (tsc --noEmit) types compile
Build & Fast Tests ⚠️ only next build
Vercel × 3 deploy succeeds
Detect packages a no-op probe
Unit / Integration / E2E / Security Tests ❌ skipped
✅ Merge Gate ✅ green that 4 gates were skipped

Impact

Proposed fix

Needs a decision before anyone implements it, because step 1 will immediately turn CI red:

  1. Add a job that runs cd app && pnpm test. This is the real gap. It will fail on day one with those 95 tests, so land it as non-blocking (continue-on-error: true) first to make the number visible, then fix the tests, then make it blocking.
  2. Un-gate security-tests from has_packagespnpm audit operates on the workspace root and needs no packages/. fix(deps): raise stale pnpm override floors to current advisory patched versions #2446 fixes the findings; this is what would make the gate actually execute.
  3. Fix the Merge Gate's skip semantics — require success() for the jobs that must run, rather than merely "not failure", so a silently-skipped gate can never read as a pass.
  4. Delete or restore the packages/* scaffolding. These workflows describe a monorepo that no longer exists; leaving the dead conditionals invites the same confusion again. Related: [PROCESS] Open issues target playground, but main is 288 commits behind — work is being done against a stale branch #2440 (main/playground drift).

Happy to implement whichever shape is preferred — flagging rather than unilaterally turning everyone's CI red.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions