Release: validate, package from the merge commit, validate the zip, create the release via the Gitea API (creates the tag), publish the same zip to the Composer registry, link the package. No orphan tag on failed builds. Workflows are plugin-agnostic (derived from composer.json and the github context).
scripts/protect-main.sh sets the required status checks via tea api (run once after the first CI run shows the real check names).
## Summary
Aligns the plugin and its build/release pipeline with Shopware's plugin guidelines and Gitea 28. Spec: `docs/spec/shopware-guideline-compliance.md`.
- **Plugin:** dedicated `aeon_dump_manager` monolog channel and logging; `services.xml`/`routes.php` migrated to YAML; PHP `^8.2`; extension icon; `.config/shopware-extension.yml`; empty lifecycle overrides removed.
- **PR checks (`plugin-checks.yml`):** `shopware-cli` validate (hard gate), package + built-JS assertion, phpunit on `shopware/production` 6.6.
- **Release:** validate, package from the merge commit, validate the zip, create the release via the Gitea API (creates the tag), publish the same zip to the Composer registry, link the package. No orphan tag on failed builds. Workflows are plugin-agnostic (derived from `composer.json` and the `github` context).
- `scripts/protect-main.sh` sets the required status checks via `tea api` (run once after the first CI run shows the real check names).
- Version bumped to 0.1.0 with changelog entry.
## Not verified (first CI run is the test)
- phpunit job setup (best-guess Shopware project bootstrap)
- hand-converted YAML services/routes loading under Shopware 6.6
- Composer registry accepting the zip with a top-level folder
- status-check context names, release POST creating a missing tag, runner Node availability
🤖 Generated with [Claude Code](https://claude.com/claude-code)
- plugin-checks workflow: shopware-cli validate, package + built-JS assertion, phpunit
- release: validate, package from the merge commit, validate the zip, create the release
via the Gitea API, publish the same zip to the Composer registry
- scripts/protect-main.sh sets required status checks via tea api
- bump to 0.1.0
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- validate job needs no PHP (the package job already validates without it)
- phpunit: runner=self-hosted so setup-php does not hang under act; replace the
unhealthy service healthcheck with a TCP wait loop
- .config/shopware-extension.yml: set compatibility_date
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
setup-php hangs on the runner even with runner=self-hosted; the CLI download
returned a non-gzip body once under concurrent load.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Replaces the curl/tar install and setup-node steps; the image ships the
CLI plus its PHP/Node toolchain.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- drop the separate validate job (the zip is validated after packaging); same in release
- shared scripts/ci/assert-built-assets.sh (BusyBox-safe), now also used by release
- actions/cache for npm, shopware-cli and composer
- phpunit: shopware-cli image instead of a 4.5 min apt install; MariaDB 10.11
(11.4 broke Shopware's migrations: Duplicate column 'sorter_key')
- protect-main.sh: drop the removed validate context
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- phpunit: cache the prepared project (vendor + phpunit) monthly via cache restore/save;
drop system:install/plugin:install (TestBootstrapper installs into its own test DB, so
every migration ran twice, ~5.5 min each); relax InnoDB durability on the CI database
- package: save the tested zip keyed by the commit's tree hash; release restores it and
only re-packages on a miss, but always validates and asserts the zip
- cancel superseded PR runs (concurrency)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- one PR workflow (plugin-checks) with version-changelog, package, phpunit jobs
- .gitea/actions/package: package + validate + assert, used by PR and release
- phpunit: FORCE_INSTALL so the TestBootstrapper installs its own test DB
- protect-main.sh: required context is now plugin-checks / version-changelog
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The new services.yaml references @aeon_dump_manager.filesystem.private for DumpLister and DumpService, but the file does not define that service. If the definition was in the deleted services.xml and was not migrated, the container will fail to compile when these services are resolved.
build() loads Resources/config/packages/monolog.yaml with Symfony's DI YamlFileLoader. That loader only accepts service-definition keys such as services, parameters, and imports; a top-level monolog key is bundle configuration and will likely cause a LoaderLoadException during container build. Use $container->loadFromExtension('monolog', ['channels' => ['aeon_dump_manager']]) or Shopware's supported plugin package loading mechanism.
publicfunctionbuild(ContainerBuilder$container):void{parent::build($container);// Registers the dedicated monolog channel (Resources/config/packages/monolog.yaml)
$locator=newFileLocator('Resources/config');$resolver=newLoaderResolver([newYamlFileLoader($container,$locator),newGlobFileLoader($container,$locator),newDirectoryLoader($container,$locator),]);(newDelegatingLoader($resolver))->load(\rtrim($this->getPath(),'/').'/Resources/config/packages/*.yaml','glob');}
## PR Reviewer Guide 🔍
<!-- pr-agent:review:full -->
Here are some key observations to aid the review process:
<table>
<tr><td>⏱️ <strong>Estimated effort to review</strong>: 3 🔵🔵🔵⚪⚪</td></tr>
<tr><td>🧪 <strong>No relevant tests</strong></td></tr>
<tr><td>🔒 <strong>No security concerns identified</strong></td></tr>
<tr><td>⚡ <strong>Recommended focus areas for review</strong><br><br>
<details><summary><a href='https://git.arthurerlich.de/haylan/AeonDumpManager/src/branch/ci/shopware-guideline-compliance/src/Resources/config/services.yaml#L19-L34'><strong>Missing service</strong></a>
The new services.yaml references `@aeon_dump_manager.filesystem.private` for `DumpLister` and `DumpService`, but the file does not define that service. If the definition was in the deleted services.xml and was not migrated, the container will fail to compile when these services are resolved.
</summary>
```yaml
aeon_dump_manager.dump_lister:
class: AeonDumpManager\Service\DumpLister
arguments:
- '@aeon_dump_manager.filesystem.private'
- '@aeon_dump_manager.dump_filename_parser'
aeon_dump_manager.dump_service:
class: AeonDumpManager\Service\DumpService
arguments:
- '@aeon_dump_manager.dump_lister'
- '@aeon_dump_manager.filesystem.private'
- '@aeon_dump_manager.dump_binary_locator'
- '@Doctrine\DBAL\Connection'
- '@Shopware\Core\System\SystemConfig\SystemConfigService'
- '@aeon_dump_manager.dump_filename_parser'
- '@monolog.logger.aeon_dump_manager'
```
</details>
<details><summary><a href='https://git.arthurerlich.de/haylan/AeonDumpManager/src/branch/ci/shopware-guideline-compliance/src/AeonDumpManager.php#L18-L34'><strong>Invalid loader</strong></a>
`build()` loads `Resources/config/packages/monolog.yaml` with Symfony's DI `YamlFileLoader`. That loader only accepts service-definition keys such as `services`, `parameters`, and `imports`; a top-level `monolog` key is bundle configuration and will likely cause a `LoaderLoadException` during container build. Use `$container->loadFromExtension('monolog', ['channels' => ['aeon_dump_manager']])` or Shopware's supported plugin package loading mechanism.
</summary>
```php
public function build(ContainerBuilder $container): void
{
parent::build($container);
// Registers the dedicated monolog channel (Resources/config/packages/monolog.yaml)
$locator = new FileLocator('Resources/config');
$resolver = new LoaderResolver([
new YamlFileLoader($container, $locator),
new GlobFileLoader($container, $locator),
new DirectoryLoader($container, $locator),
]);
(new DelegatingLoader($resolver))->load(
\rtrim($this->getPath(), '/') . '/Resources/config/packages/*.yaml',
'glob'
);
}
```
</details>
</td></tr>
</table>
DATABASE_URL already ends in _test so the TestBootstrapper finds an installed DB and
skips its own migration run; FORCE_INSTALL (which failed with an unknown database) removed.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Reply from Claude (an AI assistant working on this PR for @haylan). I checked both findings against the CI logs and the Shopware docs and believe neither needs a code change.
1. @aeon_dump_manager.filesystem.private "missing"
Shopware registers <plugin_snake>.filesystem.private itself when it loads a plugin; it is not defined in the plugin's own config. The deleted services.xml referenced the same id without defining it. CI evidence: the run installed and activated the plugin with the YAML services (Plugin "AeonDumpManager" has been installed and activated successfully), and a missing service would have failed the container compile.
2. build() and the monolog loader
This is the pattern from Shopware's logging guide (plugin-fundamentals/logging): YamlFileLoader + GlobFileLoader + DirectoryLoader over Resources/config/packages/*.yaml. Symfony's YamlFileLoader hands unknown top-level keys such as monolog to the matching extension as configuration, so a top-level monolog key is valid. DumpService and the handlers are injected with @monolog.logger.aeon_dump_manager, which only exists if the channel loaded, and the container compiled in the same run.
Not covered: no test asserts that records reach the aeon_dump_manager channel at runtime.
Reply from Claude (an AI assistant working on this PR for @haylan). I checked both findings against the CI logs and the Shopware docs and believe neither needs a code change.
**1. `@aeon_dump_manager.filesystem.private` "missing"**
Shopware registers `<plugin_snake>.filesystem.private` itself when it loads a plugin; it is not defined in the plugin's own config. The deleted `services.xml` referenced the same id without defining it. CI evidence: the run installed and activated the plugin with the YAML services (`Plugin "AeonDumpManager" has been installed and activated successfully`), and a missing service would have failed the container compile.
**2. `build()` and the monolog loader**
This is the pattern from Shopware's logging guide (`plugin-fundamentals/logging`): `YamlFileLoader` + `GlobFileLoader` + `DirectoryLoader` over `Resources/config/packages/*.yaml`. Symfony's `YamlFileLoader` hands unknown top-level keys such as `monolog` to the matching extension as configuration, so a top-level `monolog` key is valid. `DumpService` and the handlers are injected with `@monolog.logger.aeon_dump_manager`, which only exists if the channel loaded, and the container compiled in the same run.
Not covered: no test asserts that records reach the `aeon_dump_manager` channel at runtime.
haylan
merged commit 85980ee3bf into main2026-10-03 22:46:18 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
Aligns the plugin and its build/release pipeline with Shopware's plugin guidelines and Gitea 28. Spec:
docs/spec/shopware-guideline-compliance.md.aeon_dump_managermonolog channel and logging;services.xml/routes.phpmigrated to YAML; PHP^8.2; extension icon;.config/shopware-extension.yml; empty lifecycle overrides removed.plugin-checks.yml):shopware-clivalidate (hard gate), package + built-JS assertion, phpunit onshopware/production6.6.composer.jsonand thegithubcontext).scripts/protect-main.shsets the required status checks viatea api(run once after the first CI run shows the real check names).Not verified (first CI run is the test)
🤖 Generated with Claude Code
/review
PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
Missing service
The new services.yaml references
@aeon_dump_manager.filesystem.privateforDumpListerandDumpService, but the file does not define that service. If the definition was in the deleted services.xml and was not migrated, the container will fail to compile when these services are resolved.Invalid loader
build()loadsResources/config/packages/monolog.yamlwith Symfony's DIYamlFileLoader. That loader only accepts service-definition keys such asservices,parameters, andimports; a top-levelmonologkey is bundle configuration and will likely cause aLoaderLoadExceptionduring container build. Use$container->loadFromExtension('monolog', ['channels' => ['aeon_dump_manager']])or Shopware's supported plugin package loading mechanism.Reply from Claude (an AI assistant working on this PR for @haylan). I checked both findings against the CI logs and the Shopware docs and believe neither needs a code change.
1.
@aeon_dump_manager.filesystem.private"missing"Shopware registers
<plugin_snake>.filesystem.privateitself when it loads a plugin; it is not defined in the plugin's own config. The deletedservices.xmlreferenced the same id without defining it. CI evidence: the run installed and activated the plugin with the YAML services (Plugin "AeonDumpManager" has been installed and activated successfully), and a missing service would have failed the container compile.2.
build()and the monolog loaderThis is the pattern from Shopware's logging guide (
plugin-fundamentals/logging):YamlFileLoader+GlobFileLoader+DirectoryLoaderoverResources/config/packages/*.yaml. Symfony'sYamlFileLoaderhands unknown top-level keys such asmonologto the matching extension as configuration, so a top-levelmonologkey is valid.DumpServiceand the handlers are injected with@monolog.logger.aeon_dump_manager, which only exists if the channel loaded, and the container compiled in the same run.Not covered: no test asserts that records reach the
aeon_dump_managerchannel at runtime.