Author SHA1 Message Date
haylan 00d959e661 Merge pull request 'fix(dump): pass --column-statistics=0 for MySQL 8 mysqldump on MariaDB, release as 0.0.7' (!17) from fix/0.0.7-column-statistics into main
release / release (push) Successful in 1m8s
Reviewed-on: #17
2026-11-02 22:39:41 +00:00
haylanandClaude Bot fa50fa3343 ci(phpunit): install core patches that have no shopware/production tag
plugin-checks / version-changelog (pull_request) Successful in 19s
plugin-checks / package (pull_request) Successful in 1m3s
plugin-checks / phpunit (pull_request) Successful in 5m35s
The newest shopware/core in ~6.6.0 is 6.6.10.31, but shopware/production
is only tagged up to 6.6.10.30, so create-project failed. Install the newest
template inside the constraint and require the resolved core version on top.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 23:33:58 +01:00
haylanandClaude Bot 6b7ba3bc47 fix(dump): pass --column-statistics=0 for MySQL 8 mysqldump on MariaDB, release as 0.0.7
plugin-checks / version-changelog (pull_request) Successful in 20s
plugin-checks / phpunit (pull_request) Failing after 37s
plugin-checks / package (pull_request) Successful in 1m27s
Backport for the Shopware 6.6 line. When the server is MariaDB but only
MySQL 8's mysqldump is installed (e.g. dockware/web), the dump aborted
with "Unknown table 'COLUMN_STATISTICS' in information_schema (1109)".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 23:29:05 +01:00
10 changed files with 49 additions and 41 deletions

No files matched your search

+8 -2
View File
@@ -110,6 +110,7 @@ jobs:
test -n "$VERSION" || { echo "::error::could not resolve a Shopware version for ${CONSTRAINT}"; exit 1; } test -n "$VERSION" || { echo "::error::could not resolve a Shopware version for ${CONSTRAINT}"; exit 1; }
echo "Shopware ${VERSION} (constraint ${CONSTRAINT})" echo "Shopware ${VERSION} (constraint ${CONSTRAINT})"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT" echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "constraint=${CONSTRAINT}" >> "$GITHUB_OUTPUT"
# Project (vendor/, phpunit, config) and the installed database as a SQL dump. Neither depends on the plugin. # Project (vendor/, phpunit, config) and the installed database as a SQL dump. Neither depends on the plugin.
- name: Restore Shopware project and database - name: Restore Shopware project and database
id: shopware id: shopware
@@ -125,8 +126,13 @@ jobs:
if: steps.shopware.outputs.cache-hit != 'true' if: steps.shopware.outputs.cache-hit != 'true'
run: | run: |
set -e set -e
composer create-project "shopware/production:${{ steps.sw.outputs.version }}" shopware --no-interaction --no-scripts # shopware/production pins one exact core version and is not tagged for every core patch
composer require --dev phpunit/phpunit:^10 --no-interaction --no-scripts -d shopware # (e.g. core 6.6.10.31, template only up to 6.6.10.30): take the newest template inside the
# constraint, then require the resolved core version on top of it.
composer create-project "shopware/production:${{ steps.sw.outputs.constraint }}" shopware --no-interaction --no-scripts --no-install
composer require "shopware/core:${{ steps.sw.outputs.version }}" --no-update -d shopware
composer require --dev phpunit/phpunit:^10 --no-update -d shopware
composer update -W --no-interaction --no-scripts -d shopware
- name: Ensure the MariaDB client - name: Ensure the MariaDB client
run: | run: |
command -v mariadb-dump >/dev/null || command -v mysqldump >/dev/null && exit 0 command -v mariadb-dump >/dev/null || command -v mysqldump >/dev/null && exit 0
+1 -1
View File
@@ -14,7 +14,7 @@ composer.phar
# Frontend # Frontend
*.vite/ *.vite/
**/public/administration/assets/ **/public/administration/js/
**/public/static/js/ **/public/static/js/
# Environment # Environment
+1 -12
View File
@@ -7,23 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [0.1.0] - 2026-11-02 ## [0.0.7] - 2026-11-02
### Changed
- Requires Shopware 6.7 (`shopware/core ~6.7.0`); 6.6 stays on the 0.0.x line.
- Administration: the list page is registered lazily, uses Meteor components (`mt-button`, `mt-banner`, `mt-progress-bar`) and stops polling on `beforeUnmount` (Vue 3).
### Fixed ### Fixed
- The admin build failed on a combined `import type` statement, so the Settings card never appeared.
- Delete did nothing and the create progress modal never showed: both modals sat outside `sw-page`'s named slots, which Vue 3 drops. They now live in `#content`.
- Creating a dump failed on MariaDB when only MySQL 8's `mysqldump` was installed (`Unknown table 'COLUMN_STATISTICS'`); it now passes `--column-statistics=0` in that case. - Creating a dump failed on MariaDB when only MySQL 8's `mysqldump` was installed (`Unknown table 'COLUMN_STATISTICS'`); it now passes `--column-statistics=0` in that case.
### Removed
- The Settings sidebar navigation entry; the plugin is reached through its card in Settings → System, like core settings modules.
## [0.0.6] - 2026-10-04 ## [0.0.6] - 2026-10-04
### Changed ### Changed
+1 -1
View File
@@ -67,7 +67,7 @@ vendor/bin/phpunit tests/SomeTest.php # single file
## Dependencies ## Dependencies
- PHP `^8.2`, `shopware/core` `~6.7.0` (from `composer.json`); `phpunit/phpunit` `^10.0` as the only - PHP `^8.2`, `shopware/core` `~6.6.0` (from `composer.json`); `phpunit/phpunit` `^10.0` as the only
dev dependency. dev dependency.
- PSR-4 autoload: `AeonDumpManager\` → `src/`, `AeonDumpManager\Tests\` → `tests/`. - PSR-4 autoload: `AeonDumpManager\` → `src/`, `AeonDumpManager\Tests\` → `tests/`.
+2 -2
View File
@@ -3,7 +3,7 @@
"description": "Export database dumps for Shopware 6 environments.", "description": "Export database dumps for Shopware 6 environments.",
"type": "shopware-platform-plugin", "type": "shopware-platform-plugin",
"license": "MIT", "license": "MIT",
"version": "0.1.0", "version": "0.0.7",
"keywords": [ "keywords": [
"shopware", "shopware",
"shopware6", "shopware6",
@@ -26,7 +26,7 @@
}, },
"require": { "require": {
"php": "^8.2", "php": "^8.2",
"shopware/core": "~6.7.0" "shopware/core": "~6.6.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^10.0" "phpunit/phpunit": "^10.0"
+1 -1
View File
@@ -1,6 +1,6 @@
services: services:
shopware: shopware:
image: dockware/shopware:6.7.14.2 image: dockware/shopware:6.6.10.12
container_name: shopware container_name: shopware
ports: ports:
- "80:80" # Shop / Admin / Adminer / Mailcatcher (all served via path on this port) - "80:80" # Shop / Admin / Adminer / Mailcatcher (all served via path on this port)
+1 -1
View File
@@ -13,5 +13,5 @@ check() { # <label> <entry-glob-prefix> <expected path in zip>
fi fi
} }
check admin src/Resources/app/administration/src "Resources/public/administration/assets/" check admin src/Resources/app/administration/src "Resources/public/administration/js/"
check storefront src/Resources/app/storefront/src "Resources/app/storefront/dist/" check storefront src/Resources/app/storefront/src "Resources/app/storefront/dist/"
@@ -1,10 +1,8 @@
import './acl'; import './acl';
import './page/aeon-dump-manager-list';
import deDE from './snippet/de-DE.json'; import deDE from './snippet/de-DE.json';
import enGB from './snippet/en-GB.json'; import enGB from './snippet/en-GB.json';
// Lazy (async) registration, as core does: the page chunk loads on first visit.
Shopware.Component.register('aeon-dump-manager-list', () => import('./page/aeon-dump-manager-list'));
Shopware.Module.register('aeon-dump-manager', { Shopware.Module.register('aeon-dump-manager', {
type: 'plugin', type: 'plugin',
name: 'DumpManager', name: 'DumpManager',
@@ -29,10 +27,27 @@ Shopware.Module.register('aeon-dump-manager', {
}, },
}, },
settingsItem: [{ // Per https://developer.shopware.com/docs/v6.6/guides/plugins/plugins/administration/routing-navigation/add-menu-entry.html —
group: 'plugins', // plugins can't register a first-level main-menu entry, so this nests
// under the core 'sw-settings' navigation node. Clicking Settings in the
// main sidebar shows this as a sub-item, landing at #/sw/settings/.
navigation: [{
id: 'aeon-dump-manager-list',
label: 'aeon-dump-manager.general.mainMenuItemGeneral',
color: '#ff3d58',
path: 'aeon.dump.manager.list',
icon: 'regular-database',
parent: 'sw-settings',
position: 100,
privilege: 'aeon_dump_manager.viewer',
}],
// Also shown as a card on the Settings overview page's "System" group,
// next to Plugins/Cache — complements the navigation entry above.
settingsItem: {
group: 'system',
to: 'aeon.dump.manager.list', to: 'aeon.dump.manager.list',
icon: 'regular-database', icon: 'regular-database',
privilege: 'aeon_dump_manager.viewer', privilege: 'aeon_dump_manager.viewer',
}], },
}); });
@@ -1,7 +1,7 @@
{% block aeon_dump_manager_list %} {% block aeon_dump_manager_list %}
<sw-page class="aeon-dump-manager-list"> <sw-page class="aeon-dump-manager-list">
<template #smart-bar-actions> <template #smart-bar-actions>
<mt-button <sw-button
v-if="acl.can('aeon_dump_manager.creator')" v-if="acl.can('aeon_dump_manager.creator')"
variant="primary" variant="primary"
:is-loading="pendingJob !== null" :is-loading="pendingJob !== null"
@@ -9,7 +9,7 @@
@click="onCreate" @click="onCreate"
> >
{{ $tc('aeon-dump-manager.list.buttonCreate') }} {{ $tc('aeon-dump-manager.list.buttonCreate') }}
</mt-button> </sw-button>
</template> </template>
<template #content> <template #content>
@@ -75,8 +75,8 @@
</template> </template>
</sw-data-grid> </sw-data-grid>
</div> </div>
</template>
<!-- sw-page has no default slot (Vue 3 drops unslotted content): modals must live in #content. -->
{% block aeon_dump_manager_list_progress_modal %} {% block aeon_dump_manager_list_progress_modal %}
<sw-modal <sw-modal
v-if="pendingJob !== null" v-if="pendingJob !== null"
@@ -87,18 +87,18 @@
> >
<div class="aeon-dump-manager-list__progress-wrapper"> <div class="aeon-dump-manager-list__progress-wrapper">
<template v-if="pendingJob.status === 'done'"> <template v-if="pendingJob.status === 'done'">
<mt-banner variant="positive"> <sw-alert variant="success">
{{ $tc('aeon-dump-manager.list.createSuccess') }} {{ $tc('aeon-dump-manager.list.createSuccess') }}
</mt-banner> </sw-alert>
</template> </template>
<template v-else-if="pendingJob.status === 'failed'"> <template v-else-if="pendingJob.status === 'failed'">
<mt-banner variant="critical"> <sw-alert variant="error">
{{ $tc('aeon-dump-manager.list.createFailed', 0, { error: pendingJob.errorMessage || '' }) }} {{ $tc('aeon-dump-manager.list.createFailed', 0, { error: pendingJob.errorMessage || '' }) }}
</mt-banner> </sw-alert>
</template> </template>
<template v-else> <template v-else>
<mt-progress-bar <sw-progress-bar
:model-value="pendingJob.percent || 0" :value="pendingJob.percent || 0"
:max-value="100" :max-value="100"
/> />
<span class="aeon-dump-manager-list__progress-text"> <span class="aeon-dump-manager-list__progress-text">
@@ -120,6 +120,5 @@
@cancel="onCancelDelete" @cancel="onCancelDelete"
@close="onCancelDelete" @close="onCancelDelete"
/> />
</template>
</sw-page> </sw-page>
{% endblock %} {% endblock %}
@@ -1,8 +1,7 @@
import template from './aeon-dump-manager-list.html.twig'; import template from './aeon-dump-manager-list.html.twig';
import type DumpApiService from '../../../../service/dump-api.service'; import type DumpApiService, { DumpFile, DumpJob } from '../../../../service/dump-api.service';
import type { DumpFile, DumpJob } from '../../../../service/dump-api.service';
const { Mixin } = Shopware; const { Component, Mixin } = Shopware;
interface PendingJob { interface PendingJob {
status: string; status: string;
@@ -46,7 +45,7 @@ interface ComponentInstance extends ComponentData {
listFilters: Record<string, unknown>[]; listFilters: Record<string, unknown>[];
} }
export default Shopware.Component.wrapComponentConfig({ Component.register('aeon-dump-manager-list', {
template, template,
mixins: [ mixins: [
@@ -148,7 +147,7 @@ export default Shopware.Component.wrapComponentConfig({
}, },
}, },
beforeUnmount(this: ComponentInstance) { beforeDestroy(this: ComponentInstance) {
this.stopPolling(); this.stopPolling();
}, },