Skip to content

Pre-release 4.2.128 → 4.2.127 — task 4.5 (foundation): facades and providers through v13's bootstrappers, no app/start files - #101

Merged
agissept merged 2 commits into
masterfrom
pre-release/4.2.128
Oct 6, 2026
Merged

agissept merged 2 commits into
masterfrom
pre-release/4.2.128

Conversation

@oonid

@oonid oonid commented Oct 2, 2026 •

Copy link
Copy Markdown

Task 4.5, foundation — facades and providers through v13's bootstrappers, no app/start files

Stacks on #100. The start script set up the facades, the alias loader and the service providers itself, then loaded app/start/global.php and app/start/{env}.php once the application booted. v13 does the first three through its RegisterFacades and RegisterProviders bootstrappers, and has no start files: an app does that work in its own service providers, listed in bootstrap/providers.php. This release ports those bootstrappers and v13's withProviders(), and stops loading the start files.

Changes

  • Illuminate\Foundation\Bootstrap\RegisterFacades is v13's, without the package manifest's aliases:
    • it points the facades at the application;
    • it registers the app.aliases class aliases.
  • Illuminate\Foundation\Bootstrap\RegisterProviders is v13's, without the config cache check and the framework's default providers:
    • it merges the providers given to withProviders(), then those in bootstrap/providers.php, after app.providers;
    • classes that don't exist in bootstrap/providers.php are skipped.
  • Application::registerConfiguredProviders() registers the Illuminate\ providers first, then the others, each group in its configured order, as in v13. The L4.2 services manifest stays until the flip.
  • ApplicationBuilder::withProviders() has v13's signature. Application::configure() calls it, as v13 does, so bootstrap/providers.php is read by default. bootstrapPath() and getBootstrapProvidersPath() come with it.
  • The start script runs the two bootstrappers in v13's order, after the configuration and the exception handling. The facades now point at the application only from then on.
  • app() resolves through Container::getInstance(), as in v13. It returned the facades' application, which is now set only after the configuration loads, so a configuration file calling storage_path() would have failed. The application sets the container instance when it's constructed.
  • The start script no longer loads app/start/global.php or app/start/{env}.php. The routes still load from app/routes.php once the application has booted.
  • ProviderRepository's fresh manifest now carries the when key. It was missing whenever no provider was deferred.
  • Tests in FoundationApplicationBuilderTest:
    • the Illuminate\ providers register before the others;
    • withProviders() and bootstrap/providers.php register after app.providers, in that order, and a missing class is skipped;
    • configure() reads bootstrap/providers.php by default;
    • the configured aliases resolve, and the facades point at the application;
    • a configuration file can call storage_path() and app() during bootstrap;
    • start files throw if loaded, and the routes still load once booted;
    • bootstrapPath() and getBootstrapProvidersPath().

What changes

  • Apps with app/start files must move that code into a service provider, as the dicoding app does in its pair.
  • Provider registration order: every Illuminate\ provider now registers before the app's own providers. Each group keeps its order.
  • Facades point at the application once the configuration has loaded, as in v13, so configuration files can't use facades. app() and the path helpers still work there.
  • app() no longer returns the facades' application. A test that stubbed app() with Facade::setFacadeApplication() must use Container::setInstance(), as one dicoding unit test now does.

Verification

  • Fork: the suite is 297 green on PHPUnit 11.5.56, 6 more than 4.2.127. The ratchet is green, with every pattern at its baseline.
  • The tests catch real breaks. Each of these 9 mutations fails at least one test:
    • app/start/global.php still loaded;
    • no framework-first ordering;
    • bootstrap/providers.php ignored;
    • missing provider classes kept;
    • bootstrap/providers.php merged before withProviders();
    • configure() not calling withProviders();
    • the aliases not registered;
    • the routes not loaded;
    • app() still returning the facades' application.
  • Downstream: the dicoding app pair is dicoding-dev/dicoding#6006 (feature/platform/framework-4.2.128-rc1). It moves its start files into Dicoding\Providers\AppServiceProvider, listed in bootstrap/providers.php. It ran with vendor installed from its lock, apart from the dev CLIs phpstan/phpstan and rector/rector, whose GitHub downloads are refused in this container:
    • A probe booted the app and read back 11 of the start files' effects, from the validator resolver to the 1615 routes. They are the same as on 4.2.127.
    • Production, local and testing load the same providers as on 4.2.127, plus AppServiceProvider, with every Illuminate\ provider first and each group in its old order. The deferred services are the same.
    • config()->all() is identical to 4.2.127 in production, local, testing and endtoend, apart from app.providers, which gains AppServiceProvider.
    • Psalm (full project, no cache): no errors.
    • Unit suite: 9077 green, once one test stubs app() through Container::setInstance().
    • Integration suite: all 3039 tests. The only failures are the 4 long-standing ones. 191 are skipped and 5 incomplete, and no test is flagged risky.
    • The real entry points (php -S + server.php → index.php, and 7 artisan commands) and the 13 in-process request scenarios are identical to 4.2.127.
  • Checks ran in a cloud container without deck (PHP 8.4.26, MariaDB 10.11).

Tag

There's no 4.2.128 tag, as there are none for 4.2.119–4.2.127: tag pushes are refused for this session. The app pins the pre-release/4.2.128 branch (2be8cff3).

🤖 Generated with Claude Code

https://claude.ai/code/session_0169SsatCE8LhaTsQTPiGtVo

@agissept
agissept force-pushed the pre-release/4.2.128 branch from 2be8cff to ce2ffe8 Compare October 2, 2026 09:21
@agissept
agissept added this pull request to stack #102 October 5, 2026 06:14
@agissept
agissept force-pushed the pre-release/4.2.128 branch 8 times, most recently from ce3f534 to b4a9e5b Compare October 6, 2026 07:18
Base automatically changed from pre-release/4.2.127 to master October 6, 2026 07:18
claude added 2 commits October 6, 2026 14:19
…pers; no app/start files (task 4.5)

The start script now runs v13's RegisterFacades and RegisterProviders where
it set up the facades, the alias loader and the providers. Facades point at
the application after the configuration loads, as in v13.

RegisterProviders merges the providers given to withProviders() and those in
bootstrap/providers.php after app.providers, skipping classes that don't
exist. Application::configure() calls withProviders(), so the bootstrap file
is read by default. registerConfiguredProviders() registers the Illuminate
providers first, each group in its configured order. The package manifest
and the config cache come with the flip.

The start script no longer loads app/start/global.php or
app/start/{env}.php; v13 has no start files. The routes still load from
app/routes.php once the application has booted.

ProviderRepository's fresh manifest now carries the 'when' key, which it
was missing when no provider is deferred.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0169SsatCE8LhaTsQTPiGtVo
…v13 (task 4.5)

The fork's app() helper returned the facades' application. Now that the
facades are set after the configuration loads, as in v13, configuration
files calling storage_path() or app() got null. v13's app() reads the
container instance, which the application sets when it's constructed, so
the helpers work before the facades are set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0169SsatCE8LhaTsQTPiGtVo
@agissept
agissept force-pushed the pre-release/4.2.128 branch from b4a9e5b to 05b31a3 Compare October 6, 2026 07:19
@agissept
agissept marked this pull request as ready for review October 6, 2026 07:19
@agissept
agissept merged commit f19b3b4 into master Oct 6, 2026
2 checks passed
@agissept
agissept deleted the pre-release/4.2.128 branch October 6, 2026 07:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants