Skip to content

Add composer plugin to enforce pub/* worker shims (issue #1 part 2)#7

Open
acourtiol wants to merge 1 commit into
opengento:mainfrom
acourtiol:feat/enforce-pub-files-plugin
Open

Add composer plugin to enforce pub/* worker shims (issue #1 part 2)#7
acourtiol wants to merge 1 commit into
opengento:mainfrom
acourtiol:feat/enforce-pub-files-plugin

Conversation

@acourtiol
Copy link
Copy Markdown

@acourtiol acourtiol commented May 11, 2026

Closes the second half of #1 — preventing magento/magento2-base from overriding pub/index.php on patch-day installs.

Problem

magento/magento-composer-installer hardcodes magento/magento2-base at the highest deploy priority (DeployManager::$highPriority = 10 + maxPrioritysource). On a fresh install our package's extra.map runs AFTER magento2-base, so the worker shims win.

But on composer update magento/magento2-base alone — typical for the quarterly Magento patch cycle — our package isn't touched, its extra.map never runs again, and stock Magento pub/index.php etc. silently come back. Worker mode breaks until someone notices and reinstalls our package.

Solution

Convert this package from type=magento2-component to type=composer-plugin, and add a small EnforcePubFilesPlugin that:

  1. Subscribes to POST_PACKAGE_INSTALL and POST_PACKAGE_UPDATE for any package, priority -1000 so we run AFTER magento-composer-installer's own deploy step on the same event.
  2. After each operation, compares each pub/*.php in the project root against the same file under vendor/opengento/magento2-frankenphp-base/pub/ via md5_file().
  3. Copies any mismatch back from vendor → project pub/. Idempotent and cheap (skips when hashes match).

This makes the worker shims durable across every kind of composer operation including the patch-day update of magento2-base.

Trade-offs of changing to type=composer-plugin

  • magento/magento-composer-installer no longer processes our extra.map (it filters on type ∈ {magento2-module, theme, library, language, component}). So I've dropped extra.map and let the plugin handle file copying directly on POST_PACKAGE_INSTALL of our own package (initial-install path) AND on POST_PACKAGE_UPDATE of anything else (re-assert path).
  • Composer 2.x prompts users to allow the plugin in their config.allow-plugins on first install. Same UX as any other composer plugin (e.g., magento/composer-root-update-plugin itself).

Alternative considered — split into two packages

A separate opengento/magento2-frankenphp-base-installer (type=composer-plugin) that opengento/magento2-frankenphp-base (type=magento2-component) requires. Cleaner separation of concerns but creates a new package to maintain. Happy to refactor to that shape if you prefer — it's mostly a file-shuffle exercise.

Stacking

@acourtiol acourtiol force-pushed the feat/enforce-pub-files-plugin branch from 5a18e9a to dccf31c Compare May 11, 2026 07:22
…part 2)

Closes the second half of issue opengento#1 ("Ready to use package" → Prevent
magento2-base from overriding pub/index.php on patch-day installs).

Problem
-------
magento/magento-composer-installer hardcodes magento/magento2-base at the
highest deploy priority (DeployManager::$highPriority = 10 + maxPriority).
On a fresh install our package's extra.map runs AFTER magento2-base's, so
our worker shims (pub/index.php, pub/static.php, pub/get.php, pub/worker.php)
win.

But on `composer update magento/magento2-base` alone — typical for the
quarterly Magento patch cycle — our package isn't touched, its extra.map
never runs again, and stock Magento pub/index.php etc. silently come back.
Worker mode breaks until someone notices and reinstalls our package.

Solution
--------
Convert this package from type=magento2-component to type=composer-plugin
and add a small EnforcePubFilesPlugin that:

  1. Subscribes to POST_PACKAGE_INSTALL and POST_PACKAGE_UPDATE for ALL
     packages (priority -1000 so we run after magento-composer-installer's
     own deploy step on the same event).
  2. After each operation, compares each pub/*.php in the project root
     against the same file under vendor/opengento/magento2-frankenphp-base/pub/
     via md5_file().
  3. Copies any mismatch back from vendor → project pub/. Idempotent and
     cheap (skips when hashes match).

This makes the worker shims durable across every kind of composer operation
including the patch-day update of magento2-base.

Trade-offs of changing to type=composer-plugin
----------------------------------------------
  - magento/magento-composer-installer no longer processes our extra.map
    (it filters on type ∈ {magento2-module, theme, library, language,
    component}). So I've dropped extra.map and let the plugin handle
    file copying directly on POST_PACKAGE_INSTALL of our own package
    (initial-install path) AND on POST_PACKAGE_UPDATE of anything else
    (re-assert path).

  - Composer 2.x prompts users to allow the plugin in their
    config.allow-plugins on first install. Same UX as any other composer
    plugin (e.g., magento/composer-root-update-plugin itself).

Alternative considered: split into two packages
-----------------------------------------------
A separate `opengento/magento2-frankenphp-base-installer` (type=composer-plugin)
that opengento/magento2-frankenphp-base (type=magento2-component) requires.
Cleaner separation of concerns but creates a new package to maintain.
Happy to refactor to that shape if preferred — let me know.

Constraint updates aligned with the Magento 2.4.7+ / PHP 8.3+ support matrix:
  - php: (new) ^8.3
  - magento/magento2-base: * -> ^2.4.7
  - opengento/module-application: >=0.5 -> >=0.7
  - composer-plugin-api: (new) ^2.0
@acourtiol acourtiol force-pushed the feat/enforce-pub-files-plugin branch from dccf31c to 949bb73 Compare May 11, 2026 07:34
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.

1 participant