fix(quality): the E2E front-controller gate blocked every app without an index route - #145
Merged
Merged
Conversation
… an index route
The Playwright job proved the `php -S` front controller was routing by
requesting `/apps/<app-name>/` and failing on 404. That conflated two
independent properties:
1. does the front controller route pretty URLs — a CI concern, and
2. does THIS app have an index route — an app design choice.
A settings-only app has no `/` route and no navigation entry, so
`/apps/<app>/` is a correct Nextcloud 404. The gate read that as a broken
router, exited 1 before a single spec ran, and printed an error naming the
router. nldesign#206 hit exactly this: 31 specs that navigate to
`/settings/admin/theming` never executed, and the failure text pointed at
`php -S`.
That the two are separable is measurable on that PR: on run 30859016722
(job 91836768845) the same URL returned **500**, not 404 — index.php had
executed and thrown on a missing cross-app class. Same router, same
request, different status. So a 404 there is Nextcloud saying "no such
route", not `php -S` saying "no such directory index".
The probe now uses `/apps/files/`, which is the right shape for what is
being proven. `php -S` 404s a path resolving to a real directory with no
index.php inside it; that is the entire failure mode the router exists to
fix. `apps/files` is shipped, always enabled, has no index.php, and its
route always resolves (302 to /login unauthenticated).
Measured on a fixture with and without the router — note that the obvious
alternatives are DEAD probes, because a router-less `php -S` already
serves them from the root index.php:
no router with router
/apps/files/ 404 200 <- discriminates
/apps/<app>/ 404 200 <- discriminates, but 404
is also legitimate
/login 200 200 <- proves nothing
/nonexistent/ 200 200 <- proves nothing
`/apps/<app-name>/` is still requested and its status still printed, as a
`::notice::` rather than a gate — a page app that lost its route and a
settings-only app that never had one look identical from here, and only
the spec run can tell them apart.
This was referenced Aug 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What was wrong
The Playwright job's pre-flight proved the
php -Sfront controller was routing by requesting/apps/<app-name>/and hard-failing on 404. That conflates two independent properties:A settings-only app has no
/route and no navigation entry, so/apps/<app>/is a correct Nextcloud 404. The gate read that as a broken router, exited 1 before a single spec ran, and printed an error namingphp -S.ConductionNL/nldesign#206hit exactly this: 31 specs that navigate to/settings/admin/themingnever executed, and the failure text pointed at the wrong thing.Evidence the two are separable
On that same PR, run 30859016722 (job
91836768845), the identical URL returned HTTP 500, not 404 —index.phphad executed and thrown on a missing cross-app class. Same router, same request, different status. A 404 from/apps/<app>/is therefore Nextcloud answering "no such route", notphp -Sanswering "no such directory index".The fix
Probe
/apps/files/instead.php -S404s a path that resolves to a real directory with noindex.phpinside it — that is the entire failure mode the router exists to fix.apps/filesis shipped, always enabled, has noindex.php, and its route always resolves (302 to/loginunauthenticated, never 404).Measured on a fixture with and without the router. Note that the obvious alternatives are dead probes — a router-less
php -Salready serves them from the rootindex.php, so they would pass while the router was missing:/apps/files//apps/<app>//login/nonexistent//apps/<app-name>/is still requested and its status still printed — as a::notice::rather than a gate. A page app that lost its route and a settings-only app that never had one look identical from here, and only the spec run can tell them apart.Not done