ntzrbtr/shopware-plugin-management
Simplify Shopware plugin management with a PHP package for listing, installing, activating, deactivating, updating, and removing plugins. Provides a clean programmatic interface to automate plugin lifecycle tasks in Shopware projects and Laravel apps.
Architecture fit. The framing needs one correction before anything else: this is not a Laravel package. It is a Shopware 6 (Symfony-based) plugin-lifecycle wrapper that happens to be callable from Laravel console commands, queued jobs, or deploy scripts. That distinction drives the entire evaluation. There are two possible internal designs and they carry very different risk:
bin/console plugin:install|activate|deactivate|update, parses exit codes and output, and normalizes errors. Portable, upgrade-tolerant, low blast radius, testable with a fake process runner. This is what we want.Shopware\Core\Framework\Plugin\PluginManager from the Shopware DI container and calls it directly. Faster and richer (structured exceptions, no shell parsing), but it binds us to Shopware internals that carry no stability contract, and it requires co-residency inside the Shopware kernel — which means a Laravel app cannot host it without bootstrapping Shopware, which is not a realistic ask.Confirm which one it is before anything else; it changes the effort estimate by an order of magnitude. The stated "consistent error handling for safer automation workflows" hints at the wrapper design, but that is an inference from marketing copy, not evidence.
Integration feasibility. High, with conditions. The capability itself is genuinely valuable: plugin install/activate/deactivate/uninstall/update/list is exactly the class of toil that should not be a human clicking through the admin panel on a release night. The work is well-bounded (one CLI invocation per verb), it is inherently idempotent-adjacent, and it does not touch customer-facing request paths. The constraints are environmental rather than architectural: the package must run against a Shopware installation whose filesystem, database, and var/cache it can reach, which effectively means it runs on a shop node or an identical clone — not from a separate Laravel control plane over the network.
Technical risk.
^1.7 pin protects us from the package's own churn; it does not protect us from Shopware's.Key questions to answer in a one-day spike, on a staging clone of production:
bin/console as a subprocess, or call PluginManager in-process?shopware/core a hard Composer dependency (and therefore a version-pin collision with the host shop)?composer install — or does it hand those back to us?bin/console path / Shopware root configurable, or hardcoded?Stack fit. Only adopt if the target is a Shopware 6 installation we operate and deploy ourselves. Laravel is relevant purely as the host for orchestration: an Artisan command, a queued job, or a step in a deploy pipeline. If we do not already run a Laravel-based ops layer, do not introduce one to reach this package — write the equivalent Symfony console command or shell script and skip the wrapper. If we do have one, the package converts a bespoke script into a versioned, upgradable dependency, which is the actual buy-vs-build case here.
Migration path. Do not cut over. Sequence it:
list and status/version inspection behind the package, run it in staging and then production read-only, and compare its output against the admin panel. This validates the wrapper design, error semantics, and output format at zero risk.install + activate in a CI/deploy context, still gated behind a manual approval on production.Compatibility. Pin the package to ^1.7 and let patches flow; pin Shopware's minor separately and treat Shopware upgrades as the real compatibility event. Verify the declared PHP constraint against our runtime and confirm shopware/core is either absent from the dependency tree or satisfiable by our installed version — a Composer constraint conflict here is the most likely reason this evaluation ends in "no." Run the entire spike against a production-derived staging clone with the same plugin set, because plugin interactions (shared services, migration ordering, theme inheritance) are where this breaks.
Sequencing inside a deploy. The ordering is non-negotiable and is the main thing the package does not solve for us:
composer install for the shop, then for each plugin that vendors its own deps.install (new plugins only; this runs migrations).activate.update (existing plugins, again running migrations).Wrap all plugin operations in a single exclusive lock (DB advisory lock or filesystem lock) and a single-runner constraint — a queued job with concurrency 1, not a horizontally scaled worker pool. Take a database snapshot before step 3 and do not proceed past a failed plugin without halting the pipeline; partial plugin state is worse than an aborted deploy.
Maintenance. The package itself should be near-zero-maintenance — MIT, narrow scope, patch releases are docs/changelog hygiene. The real recurring cost is the Shopware upgrade tax: budget roughly half a day to a day per Shopware minor upgrade to re-verify plugin operations against a staging clone. The dependency is cheap; the environment it operates in is not.
Support. Community-only, no SLA, effectively one maintainer on an unadopted repo. Plan explicitly for fork-and-maintain: keep our usage confined to the package's public surface (do not reach into its internals from our code), which keeps the fork cost at "vendor the repo, patch a method" rather than a rewrite. Do not build product differentiation on this capability — it is infrastructure plumbing, and it is the right shape for a dependency.
Scaling. Poorly, by design, and that is fine. Plugin lifecycle operations mutate shared filesystem and database state, so they do not parallelize across nodes and must not be run concurrently. In practice: seconds for a list/status call, tens of seconds for install/activate, and potentially minutes for an update carrying schema migrations — with a real risk of exceeding default job timeouts. Set generous timeouts, use a dedicated queue or lock, and never schedule plugin operations to overlap with a code deploy, a cache warm, or another plugin operation.
Failure modes to plan for.
Ramp-up. Low for a PHP engineer with Shopware exposure: one to two days to read the source, run the spike, and write the runbook. The docs depth is unverified (v1.7.1 was a docs fix, which tells us docs exist and are being tended, not that they cover failure modes). Expect to learn the error semantics from source and from staging failures, not from documentation. The heavier ramp-up is organizational, not technical: getting release management to accept that plugin lifecycle is now a pipeline step with a halt-on-failure gate, and that uninstall remains deliberately manual.
Recommendation. Proceed to a one-day spike, not a decision. Adopt read-only (list/status) on the strength of that spike; adopt install/activate/update behind a manual production approval once the hidden-side-effects question is answered and staging rehearsals pass across one Shopware release cycle. Keep uninstall manual indefinitely. Refresh this assessment at the next Shopware minor upgrade or any package release carrying Added / Changed / Deprecated / Removed / Security entries.
How can I help you explore Laravel packages today?