
Es gibt viele Möglichkeiten, Shopware 6 Plugins zu installieren. Sie können sie direkt im Admin-Panel herunterladen oder mit Composer installieren.
Einen detaillierten Vergleich finden Sie in der offiziellen Dokumentation.
Als Entwickler und Betreuer von Themes, Anpassungen, Drittanbieter-APIs usw. konzentriere ich mich auf statische Plugins.
Der Workflow ist einfach:
- Erstelle ein Plugin mit
bin/console plugin:create --static - Installiere es mit Composer
- Baue das Projekt mit shopware-cli
Wenn wir dasselbe Plugin in mehr als einem Shop benötigen, könnten wir dasselbe Plugin mehrfach erstellen, das wäre aber für die Wartung nicht optimal.
Das Plugin extrahieren
Wir fangen damit an, dass wir den Quellcode unseres Plugins in ein separates Repository verschieben. Um die Sache vorerst einfach zu machen, machen wir das Repository öffentlich.
Download mit Git
Wir müssen composer nur mitteilen, wo unser Plugin zu finden ist.
<project-root>/composer.json{
"name": "shopware/production",
"license": "MIT",
"type": "project",
"require": {
"composer-runtime-api": "^2.0",
"acme/sample-plugin": "^1.0",
"shopware/administration": "*",
"shopware/core": "6.6.10.2",
"shopware/elasticsearch": "*",
"shopware/storefront": "*",
"symfony/flex": "~2"
},
"repositories": [
{
"type": "path",
"url": "custom/plugins/*",
"options": {
"symlink": true
}
},
{
"type": "path",
"url": "custom/plugins/*/packages/*",
"options": {
"symlink": true
}
},
{
"type": "path",
"url": "custom/static-plugins/*",
"options": {
"symlink": true
}
},
{
"type": "git",
"url": "https://<DOMAIN-NAME>/<group>/<repo>.git"
}
],
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"prefer-stable": true,
"config": {
"allow-plugins": {
"symfony/flex": true,
"symfony/runtime": true
},
"optimize-autoloader": true,
"sort-packages": true
},
"scripts": {
"auto-scripts": {
"assets:install": "symfony-cmd"
},
"post-install-cmd": [
"@auto-scripts"
],
"post-update-cmd": [
"@auto-scripts"
]
},
"extra": {
"symfony": {
"allow-contrib": true,
"endpoint": [
"https://raw.githubusercontent.com/shopware/recipes/flex/main/index.json",
"flex://defaults"
]
}
}
}
und installieren es mit
composer req acme/sample-plugin
Could not find a version of package acme/sample-plugin matching your minimum-stability (stable). Require it with an explicit version constraint allowing its desired stability.
Ja... das ist der Nachteil. Wir müssen dev-master als Version verwenden
composer req acme/sample-plugin:dev-master
./composer.json has been updated
Running composer update acme/sample-plugin
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
- Locking acme/sample-plugin (dev-master 294414d)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Syncing acme/sample-plugin (dev-master 294414d) into cache
- Installing acme/sample-plugin (dev-master 294414d): Cloning 294414deb2 from cache
Generating optimized autoload files
Run composer recipes at any time to see the status of your Symfony recipes.
Executing script assets:install [OK]
Composer wird git verwenden, um unser Repository zu klonen, und den Standard-Branch sowie den Commit-Hash verwenden, um den Release zu verfolgen.
Das funktioniert, aber wir können es besser machen.
Git Tags
Wir taggen nun unser Plugin als v1.0.0.
Bitte beachten, dass Sie die version in der composer.json gesetzt ist.
<plugin-root>/composer.json{
"name": "acme/sample-plugin",
"description": "acme/sample-plugin",
"type": "shopware-platform-plugin",
"version": "1.0.0",
"license": "MIT",
"require": {
"shopware/core": "~6.6.0"
},
"extra": {
"shopware-plugin-class": "Acme\\SamplePlugin",
"label": {
"de-DE": "Skeleton plugin",
"en-GB": "Skeleton plugin"
}
},
"autoload": {
"psr-4": {
"Acme\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Acme\\Tests\\": "tests/"
}
}
}
git tag v1.0.0
git push --tags
Nun wird dies funktionieren:
composer req acme/sample-plugin
./composer.json has been updated
Running composer update acme/sample-plugin
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
- Locking acme/sample-plugin (1.0.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Syncing acme/sample-plugin (1.0.0) into cache
- Installing acme/sample-plugin (1.0.0): Cloning 294414deb2 from cache
Generating optimized autoload files
Run composer recipes at any time to see the status of your Symfony recipes.
Executing script assets:install [OK]
Using version ^1.0 for acme/sample-plugin
Das ist besser, aber wir verwenden immer noch git, um das Plugin abzurufen. Wir können es noch besser machen.
GitLab Package Registry
Hier beginnt der GitLab-Teil. Weitere Details sind in der offiziellen Dokumentation zu finden.
An dieser Stelle spielt es keine Rolle, ob unser Projekt öffentlich ist oder nicht, da wir uns ohnehin gegenüber der Package Registry authentifizieren müssen.
Wir veröffentlichen unseren v1.0.0-Tag als Composer-Paket.
curl --fail-with-body --data tag=v1.0.0 "https://__token__:<personal-access-token>@<DOMAIN-NAME>/api/v4/projects/<project_id>/packages/composer"
Nun müssen wir die Repository-Informationen aktualisieren:
<project-root>/composer.json{
"name": "shopware/production",
"license": "MIT",
"type": "project",
"require": {
"composer-runtime-api": "^2.0",
"acme/sample-plugin": "^1.0",
"shopware/administration": "*",
"shopware/core": "6.6.10.2",
"shopware/elasticsearch": "*",
"shopware/storefront": "*",
"symfony/flex": "~2"
},
"repositories": [
{
"type": "path",
"url": "custom/plugins/*",
"options": {
"symlink": true
}
},
{
"type": "path",
"url": "custom/plugins/*/packages/*",
"options": {
"symlink": true
}
},
{
"type": "path",
"url": "custom/static-plugins/*",
"options": {
"symlink": true
}
},
{
"type": "composer",
"url": "https://<DOMAIN-NAME>/api/v4/api/v4/group/<group_id>/-/packages/composer/packages.json"
}
],
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"prefer-stable": true,
"config": {
"allow-plugins": {
"symfony/flex": true,
"symfony/runtime": true
},
"optimize-autoloader": true,
"sort-packages": true
},
"scripts": {
"auto-scripts": {
"assets:install": "symfony-cmd"
},
"post-install-cmd": [
"@auto-scripts"
],
"post-update-cmd": [
"@auto-scripts"
]
},
"extra": {
"symfony": {
"allow-contrib": true,
"endpoint": [
"https://raw.githubusercontent.com/shopware/recipes/flex/main/index.json",
"flex://defaults"
]
}
}
}
oder über das CLI:
composer config repositories.<group_id> composer https://<DOMAIN-NAME>/api/v4/group/<group_id>/-/packages/composer/packages.json
Und die GitLab-Anmeldeinformationen einrichten:
composer config gitlab-token.<DOMAIN-NAME> <personal_access_token>
Mehr über diesen Prozess in der offiziellen Dokumentation zu finden.
Jetzt installieren wir unser Paket wie gewohnt:
composer req acme/sample-plugin
./composer.json has been updated
Running composer update acme/sample-plugin
Loading composer repositories with package information
Updating dependencies
Lock file operations: 1 install, 0 updates, 0 removals
- Locking acme/sample-plugin (1.0.0)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
- Downloading acme/sample-plugin (1.0.0)
- Installing acme/sample-plugin (1.0.0): Extracting archive
Generating optimized autoload files
Run composer recipes at any time to see the status of your Symfony recipes.
Executing script assets:install [OK]
Using version ^1.0 for acme/sample-plugin
Großartig. Direkter Paket-Download!
Warum die Mühe?
Das ist eine sehr gute Frage. Der Hauptgrund ist das Paket-Caching. Bei der Ausführung in einer CI/CD-Umgebung oder einem docker build kann das Caching von Paketen einen massiven Leistungsschub bewirken.
Release-Pipeline
Mit manuellem Tagging
Dies ist eine einfache Pipeline, in der ein Git-Tag manuell erstellt und pushen wird.
Bitte sicherstellen, dass Sie die version in der composer.json immer aktualisiert wird.
git tag <version>
git push --tags
.gitlab-ci.ymlstages:
- release
deploy:
image: alpine/curl
stage: release
script:
- 'curl --fail-with-body --header "Job-Token: $CI_JOB_TOKEN" --data tag=$CI_COMMIT_TAG "${CI_API_V4_URL}/projects/$CI_PROJECT_ID/packages/composer"'
environment: production
rules:
if: $CI_COMMIT_TAG
Mit semantic-release
Es wäre viel einfacher, wenn wir unsere Änderungen einfach pushen könnten und uns nicht um Versionierung und Tagging kümmern müssten.
semantic-release automatisiert den gesamten Workflow für Paket-Releases.
Bitte befolgen Sie der Anleitung zur GitLab-Authentifizierung, bevor Sie weiterlesen.
<plugin-root>/.gitlab-ci.ymlstages:
- release
release:
stage: release
image:
name: ghcr.io/voxpupuli/semantic-release:25.0.0-latest
entrypoint: [""]
interruptible: true
script:
- /container-entrypoint.sh
rules:
- if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH
when: never
- if: $CI_COMMIT_BRANCH
<plugin-root>/.releaserc.json{
"plugins": [
"@semantic-release/commit-analyzer",
[
"semantic-release-replace-plugin",
{
"replacements": [
{
"files": ["composer.json"],
"from": "version\": \".*\"",
"to": "version\": \"${nextRelease.version}\""
}
]
}
],
[
"@semantic-release/git",
{
"assets": ["composer.json"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
],
[
"@semantic-release/exec",
{
"publishCmd": "curl --fail-with-body --header \"Job-Token: ${process.env.CI_JOB_TOKEN}\" --data tag=${nextRelease.gitTag} ${process.env.CI_API_V4_URL}/projects/${process.env.CI_PROJECT_ID}/packages/composer"
}
]
]
}
Dies wird:
- Die Commits seit dem letzten Release analysieren, um zu entscheiden, ob eine neue Version veröffentlicht werden soll
- Die Version in der
composer.jsonaktualisieren - Die
composer.jsonzurück in das Repository committen - Einen Tag erstellen
- Ein Composer-Paket von diesem Tag releasen
