Simple (Magento|Shopware) plugin release pipeline
Fabian Blechschmidt
We just finished a shipping plugin and were looking for a simple way to deploy it. Because we wanted to allow composer deployments having a git repository somewhere to get it from was already set, but the customer requested a link to a ZIP file.
We already had a private and a public repository and I wanted to have a small pipeline which takes care of everything, so here it is:
bitbucket-pipelines.yml
pipelines:
tags:
'v*.*.*':
- step:
name: ? Check Module version
image:
name: winkelwagen/php:8.3
username: $DOCKER_HUB_USERNAME
password: $DOCKER_HUB_PASSWORD
email: $DOCKER_HUB_EMAIL
script:
- php tools/checkNewVersion.php $BITBUCKET_TAG
- parallel: *php-compatibility-quick
- parallel: *php-compatibility-all
- parallel:
- step: *unit-tests
- step: *phpstan
- step:
name: ? Move latest tag and push to public
image:
name: winkelwagen/php:8.3
username: $DOCKER_HUB_USERNAME
password: $DOCKER_HUB_PASSWORD
email: $DOCKER_HUB_EMAIL
script:
- php tools/releaseNewVersion.php $BITBUCKET_TAG
First step is to check wether Magento’s module.xml is updated with the current version, then we run a bunch of tests to make sure we didn’t use any new php features, everything works as expected and hopefully phpstan doesn’t have to complain.
The final step is to set the latest tag to the newest version, merge the develop into the main and push the tags to the public repository.
The ZIP can be downloaded here: although it seems to be an undocumented function by bitbucket:
https://bitbucket.org/winkelwagen/magento-module-pub/get/latest.zip
Here are the small handy php scripts which take care of that:
checkNewVersion.php
<?php
if (count($argv) <= 1) {
echo "Usage: php releaseNewVersion.php <version>\n";
exit(1);
}
// Be careful, the prefixed v is removed here!
$version = str_replace('v', '', $argv[1]);
echo 'Updating Checking Namespace/Module/etc/module.xml for tag == version' . PHP_EOL;
$moduleXml = file_get_contents(__DIR__ . '/../src/Namespace/Module/etc/module.xml');
if (!str_contains($moduleXml, "setup_version=\"$version\"")) {
echo 'Setup version in module.xml does not match tag. Please check, and retag!' . PHP_EOL;
echo "setup_version=\"$version\"" . ' not found.' . PHP_EOL;
echo PHP_EOL . PHP_EOL . PHP_EOL . PHP_EOL;
echo $moduleXml;
exit(1);
}
releaseNewVersion.php
<?php
if (count($argv) <= 1) {
echo "Usage: php releaseNewVersion.php <version>\n";
exit(1);
}
// Be careful, this string is prefixed with v! Like in v47.1.1
$version = $argv[1];
$remote = 'https://x-token-auth:' . $_ENV['PUB_REPO_ACCESS_TOKEN'] . '@bitbucket.org/winkelwagen/magento-module-pub.git';
echo 'Moving latest tag' . PHP_EOL;
run("git tag -d latest");
run("git push --delete origin latest");
run('git tag -a latest -m "Release version ' . $version . '"');
run('git config remote.origin.fetch \'+refs/heads/*:refs/remotes/origin/*\'');
run('git fetch -o main --unshallow');
run('git checkout main');
run('git merge origin/develop -m "Release version ' . $version . '"');
run('git push origin main --tags');
echo 'Adding public repository' . PHP_EOL;
run('git remote add public ' . $remote);
echo 'Pushing release to public repository' . PHP_EOL;
run('git push --delete public latest');
run('git push public main --tags');
echo 'Done' . PHP_EOL;
function run($command): void
{
echo $command . "\n";
exec($command, $output, $returnCode);
if ($returnCode !== 0) {
echo 'Command failed.' . PHP_EOL;
echo 'Command: ' . $command . PHP_EOL;
echo 'Output: ' . implode("\n", $output) . PHP_EOL;
die(1);
}
}
Other articles from this category
ENABLE_SERVICES: the Shopware env var that quietly installs apps on your shop
I was grepping through vendor/shopware/core for the hidden-gems series and stumbled over Shopware\Core\Service\AllServiceInstaller. Two-argument constructor, twelve lines of logic, @internal. Nothing dramatic — until I read what it actually does: it installs apps on your shop. By itself. In production. Once a day. Unless you told it not to. So this one isn’t going to […]
Shopware 6 Hidden Gems #24: Lightning round — ten small gems that didn’t need their own post
Twenty-three parts into this series, my research folder still has a stack of finds that are real, useful, undocumented — and about two paragraphs big. Instead of stretching each into a full post, here’s the lightning round. One problem, one gem, one file reference. Go. 1. rawUrl() — URLs for mail templates that actually work […]
Shopware 6 Hidden Gems #23: Why your sitemap silently stopped updating (and sitemap:generate –force)
A slow-burn bug report, verbatim from memory: „Google Search Console shows our sitemap is three months old. New categories aren’t in it.“ Three months. No errors in the log worth noticing, the scheduled task looks healthy, and regenerating „worked“ — or seemed to. The cause turned out to be a mechanism that’s completely reasonable and […]