Skip to content

Commit

Permalink
feat: allow to disable asset copying and theme compiling
Browse files Browse the repository at this point in the history
  • Loading branch information
shyim committed Apr 18, 2024
1 parent eec4968 commit 6117bac
Show file tree
Hide file tree
Showing 10 changed files with 206 additions and 21 deletions.
18 changes: 16 additions & 2 deletions src/Command/RunCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
use Shopware\Deployment\Services\InstallationManager;
use Shopware\Deployment\Services\ShopwareState;
use Shopware\Deployment\Services\UpgradeManager;
use Shopware\Deployment\Struct\RunConfiguration;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand('run', description: 'Install or Update Shopware')]
Expand All @@ -23,16 +25,28 @@ public function __construct(
parent::__construct();
}

protected function configure(): void
{
$this->addOption('skip-theme-compile', null, InputOption::VALUE_OPTIONAL, 'Skip theme compile (should be used when the Theme has been compiled before in the CI/CD)', false);
$this->addOption('skip-asset-install', null, InputOption::VALUE_OPTIONAL, 'Skip asset install (should be used when the Assets has been copied before in the CI/CD)', false);
}


protected function execute(InputInterface $input, OutputInterface $output): int
{
$config = new RunConfiguration(
skipThemeCompile: (bool) $input->getOption('skip-theme-compile'),
skipAssetInstall: (bool) $input->getOption('skip-asset-install'),
);

$installed = $this->state->isInstalled();

$this->hookExecutor->execute(HookExecutor::PRE);

if ($installed) {
$this->upgradeManager->run($output);
$this->upgradeManager->run($config, $output);
} else {
$this->installationManager->run($output);
$this->installationManager->run($config, $output);
}

$this->hookExecutor->execute(HookExecutor::POST);
Expand Down
32 changes: 27 additions & 5 deletions src/Services/InstallationManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Doctrine\DBAL\Connection;
use Shopware\Deployment\Helper\EnvironmentHelper;
use Shopware\Deployment\Helper\ProcessHelper;
use Shopware\Deployment\Struct\RunConfiguration;
use Symfony\Component\Console\Output\OutputInterface;

class InstallationManager
Expand All @@ -18,7 +19,7 @@ public function __construct(
private readonly HookExecutor $hookExecutor,
) {}

public function run(OutputInterface $output): void
public function run(RunConfiguration $configuration, OutputInterface $output): void
{
$output->writeln('Shopware is not installed, starting installation');

Expand All @@ -30,20 +31,41 @@ public function run(OutputInterface $output): void
$adminPassword = EnvironmentHelper::getVariable('INSTALL_ADMIN_PASSWORD', 'shopware');
$appUrl = EnvironmentHelper::getVariable('APP_URL', 'http://localhost');

$this->processHelper->console(['system:install', '--create-database', '--shop-locale=' . $shopLocale, '--shop-currency=' . $shopCurrency, '--force']);
$additionalInstallParameters = [];

if ($configuration->skipThemeCompile) {
$additionalInstallParameters[] = '--no-assign-theme';
}

if ($configuration->skipAssetInstall) {
$additionalInstallParameters[] = '--skip-assets-install';
}

$this->processHelper->console(['system:install', '--create-database', '--shop-locale=' . $shopLocale, '--shop-currency=' . $shopCurrency, '--force', ...$additionalInstallParameters]);
$this->processHelper->console(['user:create', (string) $adminUser, '--password=' . $adminPassword]);

if ($this->state->isStorefrontInstalled()) {
$this->removeExistingHeadlessSalesChannel();
$this->processHelper->console(['sales-channel:create:storefront', '--name=Storefront', '--url=' . $appUrl]);
$this->processHelper->console(['theme:change', '--all', 'Storefront']);

$themeChangeParameters = [];
if ($configuration->skipThemeCompile) {
$themeChangeParameters[] = '--no-compile';
}

$this->processHelper->console(['theme:change', '--all', 'Storefront', ...$themeChangeParameters]);

if ($configuration->skipThemeCompile) {
$this->processHelper->console(['theme:dump']);
}
}

$this->state->disableFirstRunWizard();
$this->state->setVersion($this->state->getCurrentVersion());

$this->processHelper->console(['plugin:refresh']);
$this->pluginHelper->installPlugins();
$this->pluginHelper->updatePlugins();
$this->pluginHelper->installPlugins($configuration->skipAssetInstall);
$this->pluginHelper->updatePlugins($configuration->skipAssetInstall);
$this->appHelper->installApps();
$this->appHelper->updateApps();

Expand Down
22 changes: 17 additions & 5 deletions src/Services/PluginHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,14 @@ public function __construct(
private readonly ProjectConfiguration $configuration,
) {}

public function installPlugins(): void
public function installPlugins(bool $skipAssetInstall = false): void
{
$additionalParameters = [];

if ($skipAssetInstall) {
$additionalParameters[] = '--skip-asset-build';
}

foreach ($this->pluginLoader->all() as $plugin) {
if (!$this->configuration->isExtensionManaged($plugin['name'])) {
continue;
Expand All @@ -30,17 +36,23 @@ public function installPlugins(): void

// plugin is installed, but not active
if ($plugin['installedAt'] !== null) {
$this->processHelper->console(['plugin:activate', $plugin['name']]);
$this->processHelper->console(['plugin:activate', $plugin['name'], ...$additionalParameters]);

continue;
}

$this->processHelper->console(['plugin:install', $plugin['name'], '--activate']);
$this->processHelper->console(['plugin:install', $plugin['name'], '--activate', ...$additionalParameters]);
}
}

public function updatePlugins(): void
public function updatePlugins(bool $skipAssetInstall = false): void
{
$additionalParameters = [];

if ($skipAssetInstall) {
$additionalParameters[] = '--skip-asset-build';
}

foreach ($this->pluginLoader->all() as $plugin) {
if (!$this->configuration->isExtensionManaged($plugin['name'])) {
continue;
Expand All @@ -50,7 +62,7 @@ public function updatePlugins(): void
continue;
}

$this->processHelper->console(['plugin:update', $plugin['name']]);
$this->processHelper->console(['plugin:update', $plugin['name'], ...$additionalParameters]);
}
}
}
6 changes: 6 additions & 0 deletions src/Services/ShopwareState.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,12 @@ public function setVersion(string $version): void
}
}

public function disableFirstRunWizard(): void
{
$payload = json_encode(['_value' => '2021-01-01 00:00:00'], JSON_THROW_ON_ERROR);
$this->connection->executeStatement('INSERT INTO system_config (id, configuration_key, configuration_value, sales_channel_id, created_at) VALUES (0x0353f2502acd5dbdfe797c1cc4af9bfc, "core.frw.completedAt", ?, NULL, NOW())', [$payload]);
}

public function getCurrentVersion(): string
{
if (InstalledVersions::isInstalled('shopware/platform')) {
Expand Down
20 changes: 15 additions & 5 deletions src/Services/UpgradeManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Shopware\Deployment\Services;

use Shopware\Deployment\Helper\ProcessHelper;
use Shopware\Deployment\Struct\RunConfiguration;
use Symfony\Component\Console\Output\OutputInterface;

class UpgradeManager
Expand All @@ -16,26 +17,35 @@ public function __construct(
private readonly OneTimeTasks $oneTimeTasks,
) {}

public function run(OutputInterface $output): void
public function run(RunConfiguration $configuration, OutputInterface $output): void
{
$this->hookExecutor->execute(HookExecutor::PRE_UPDATE);

$output->writeln('Shopware is installed, running update tools');

if ($this->state->getPreviousVersion() !== $this->state->getCurrentVersion()) {
$output->writeln(sprintf('Updating Shopware from %s to %s', $this->state->getPreviousVersion(), $this->state->getCurrentVersion()));
$this->processHelper->console(['system:update:finish']);

$additionalUpdateParameters = [];

if ($configuration->skipAssetInstall) {
$additionalUpdateParameters[] = '--skip-asset-build';
}

$this->processHelper->console(['system:update:finish', ...$additionalUpdateParameters]);
$this->state->setVersion($this->state->getCurrentVersion());
}

$this->processHelper->console(['plugin:refresh']);

$this->pluginHelper->installPlugins();
$this->pluginHelper->updatePlugins();
$this->pluginHelper->installPlugins($configuration->skipAssetInstall);
$this->pluginHelper->updatePlugins($configuration->skipAssetInstall);
$this->appHelper->installApps();
$this->appHelper->updateApps();

$this->processHelper->console(['theme:compile', '--active-only']);
if (!$configuration->skipThemeCompile) {
$this->processHelper->console(['theme:compile', '--active-only']);
}

$this->oneTimeTasks->execute($output);

Expand Down
8 changes: 8 additions & 0 deletions src/Struct/RunConfiguration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php declare(strict_types=1);

namespace Shopware\Deployment\Struct;

class RunConfiguration
{
public function __construct(public readonly bool $skipThemeCompile = false, public readonly bool $skipAssetInstall = false) {}
}
35 changes: 33 additions & 2 deletions tests/Services/InstallationManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Shopware\Deployment\Services\InstallationManager;
use Shopware\Deployment\Services\PluginHelper;
use Shopware\Deployment\Services\ShopwareState;
use Shopware\Deployment\Struct\RunConfiguration;
use Symfony\Component\Console\Output\OutputInterface;

#[CoversClass(InstallationManager::class)]
Expand All @@ -32,7 +33,7 @@ public function testRun(): void
$hookExecutor,
);

$manager->run($this->createMock(OutputInterface::class));
$manager->run(new RunConfiguration(), $this->createMock(OutputInterface::class));
}

public function testRunNoStorefront(): void
Expand All @@ -56,6 +57,36 @@ public function testRunNoStorefront(): void
$this->createMock(HookExecutor::class),
);

$manager->run($this->createMock(OutputInterface::class));
$manager->run(new RunConfiguration(), $this->createMock(OutputInterface::class));
}

public function testRunDisabledAssetCopyAndThemeCompile(): void
{
$state = $this->createMock(ShopwareState::class);
$state->method('isStorefrontInstalled')
->willReturn(true);

$processHelper = $this->createMock(ProcessHelper::class);
$consoleCommands = [];

$processHelper
->method('console')
->willReturnCallback(function (array $command) use (&$consoleCommands): void {
$consoleCommands[] = $command;
});

$manager = new InstallationManager(
$state,
$this->createMock(Connection::class),
$processHelper,
$this->createMock(PluginHelper::class),
$this->createMock(AppHelper::class),
$this->createMock(HookExecutor::class),
);

$manager->run(new RunConfiguration(true, true), $this->createMock(OutputInterface::class));

static::assertCount(6, $consoleCommands);
static::assertSame(['system:install', '--create-database', '--shop-locale=en-GB', '--shop-currency=EUR', '--force', '--no-assign-theme', '--skip-assets-install'], $consoleCommands[0]);
}
}
28 changes: 28 additions & 0 deletions tests/Services/PluginHelperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@ public function testInstallNotInstalled(): void
$helper->installPlugins();
}

public function testInstallNotInstalledSkipAssets(): void
{
$processHelper = $this->createMock(ProcessHelper::class);
$processHelper->expects(static::once())->method('console')->with(['plugin:install', 'TestPlugin', '--activate', '--skip-asset-build']);

$helper = new PluginHelper(
$this->getPluginLoader(active:false, installedAt: null),
$processHelper,
new ProjectConfiguration(),
);

$helper->installPlugins(true);
}

public function testInstalledButNotActive(): void
{
$processHelper = $this->createMock(ProcessHelper::class);
Expand Down Expand Up @@ -117,6 +131,20 @@ public function testUpdate(): void
$helper->updatePlugins();
}

public function testUpdateDisableAssetBuild(): void
{
$processHelper = $this->createMock(ProcessHelper::class);
$processHelper->expects(static::once())->method('console')->with(['plugin:update', 'TestPlugin', '--skip-asset-build']);

$helper = new PluginHelper(
$this->getPluginLoader(upgradeVersion: '1.0.1'),
$processHelper,
new ProjectConfiguration(),
);

$helper->updatePlugins(true);
}

public function getPluginLoader(bool $active = true, ?string $installedAt = 'test', ?string $upgradeVersion = null): PluginLoader&MockObject
{
$loader = $this->createMock(PluginLoader::class);
Expand Down
10 changes: 10 additions & 0 deletions tests/Services/ShopwareStateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ public function testSetVersion(): void
$this->state->setVersion('v1.0.0');
}

public function testDisableFRW(): void
{
$this->connection
->expects(static::once())
->method('executeStatement')
->with('INSERT INTO system_config (id, configuration_key, configuration_value, sales_channel_id, created_at) VALUES (0x0353f2502acd5dbdfe797c1cc4af9bfc, "core.frw.completedAt", ?, NULL, NOW())', ['{"_value":"2021-01-01 00:00:00"}']);

$this->state->disableFirstRunWizard();
}

public function testSetVersionInsert(): void
{
$this->connection
Expand Down
Loading

0 comments on commit 6117bac

Please sign in to comment.