Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions Documentation/Examples/TYPO3/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,34 @@ If you would like to deploy a TYPO3 website a good starting point is to use TYPO
->afterStage('switch', \TYPO3\Surf\Task\Php\WebOpcacheResetExecuteTask::class, $application);
}
);

Configuration file in TYPO3 12 and later
========================================

Since TYPO3 12 the configuration lives in :file:`config/system/settings.php`
instead of :file:`typo3conf/LocalConfiguration.php`. Replace the symlink of the
example above with::

$application->addSymlink('config/system/settings.php', '../../../../shared/Configuration/settings.php');

Publishing extension assets (TYPO3 14.2 and later)
==================================================

For how TYPO3 publishes extension assets, see
`Assets <https://docs.typo3.org/m/typo3/tutorial-sitepackage/14.3/en-us/Assets/Index.html>`__
and
`Feature #109163 <https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/14.2/Feature-109163-Implement-public-system-resources-publishing.html>`__.

If the Composer install runs without the complete TYPO3 configuration, skip
the publishing there and publish on the node with the
``AssetPublishTask`` instead::

$deployment->onInitialize(
function () use ($deployment, $application) {
$deployment->getWorkflow()
->setTaskOptions('TYPO3\\Surf\\DefinedTask\\Composer\\LocalInstallTask', [
'composerCommandPath' => 'TYPO3_SKIP_ASSET_PUBLISH=1 composer',
])
->addTask(\TYPO3\Surf\Task\TYPO3\CMS\AssetPublishTask::class, 'migrate', $application);
}
);
55 changes: 55 additions & 0 deletions src/Task/TYPO3/CMS/AssetPublishTask.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

declare(strict_types=1);

/*
* This file is part of TYPO3 Surf.
*
* For the full copyright and license information, please view the LICENSE.txt
* file that was distributed with this source code.
*/

namespace TYPO3\Surf\Task\TYPO3\CMS;

use Symfony\Component\OptionsResolver\Options;
use Symfony\Component\OptionsResolver\OptionsResolver;
use TYPO3\Surf\Application\TYPO3\CMS;
use TYPO3\Surf\Domain\Model\Application;
use TYPO3\Surf\Domain\Model\Deployment;
use TYPO3\Surf\Domain\Model\Node;
use Webmozart\Assert\Assert;

/**
* Publishes the public resources of all extensions to public/_assets via the TYPO3 Core CLI.
* Requires TYPO3 14.2 or later.
*/
class AssetPublishTask extends AbstractCliTask
{
/**
* @param array<string,mixed> $options
*/
public function execute(Node $node, Application $application, Deployment $deployment, array $options = []): void
{
Assert::isInstanceOf($application, CMS::class);
/** @var CMS $application */
$options = $this->configureOptions($options);

$this->executeCliCommand(
array_merge(
[$this->getTypo3CoreCliFileName($node, $application, $deployment, $options), 'asset:publish'],
$options['arguments']
),
$node,
$application,
$deployment,
$options
);
}

protected function resolveOptions(OptionsResolver $resolver): void
{
$resolver->setDefault('arguments', [])
->setAllowedTypes('arguments', ['array', 'string'])
->setNormalizer('arguments', fn (Options $options, $value): array => (array)$value);
}
}
105 changes: 105 additions & 0 deletions tests/Unit/Task/TYPO3/CMS/AssetPublishTaskTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

declare(strict_types=1);

/*
* This file is part of TYPO3 Surf.
*
* For the full copyright and license information, please view the LICENSE.txt
* file that was distributed with this source code.
*/

namespace TYPO3\Surf\Tests\Unit\Task\TYPO3\CMS;

use InvalidArgumentException;
use TYPO3\Surf\Application\BaseApplication;
use TYPO3\Surf\Application\TYPO3\CMS;
use TYPO3\Surf\Exception\InvalidConfigurationException;
use TYPO3\Surf\Task\TYPO3\CMS\AssetPublishTask;
use TYPO3\Surf\Tests\Unit\Task\BaseTaskTest;

class AssetPublishTaskTest extends BaseTaskTest
{
protected function setUp(): void
{
parent::setUp();
$this->application = new CMS('TestApplication');
$this->application->setDeploymentPath('/home/jdoe/app');
}

protected function createTask(): AssetPublishTask
{
return new AssetPublishTask();
}

/**
* @test
*/
public function wrongApplicationTypeGivenThrowsException(): void
{
$invalidApplication = new BaseApplication('Hello world app');
$this->expectException(InvalidArgumentException::class);
$this->task->execute($this->node, $invalidApplication, $this->deployment, []);
}

/**
* @test
*/
public function missingTypo3CliFailsTheDeploymentInsteadOfSkippingThePublishing(): void
{
$this->expectException(InvalidConfigurationException::class);
$this->task->execute($this->node, $this->application, $this->deployment, []);
}

/**
* @test
*/
public function executeWithWrongArgumentsTypeThrowsException(): void
{
$this->expectException(InvalidConfigurationException::class);
$options = [
'typo3CliFileName' => 'typo3',
'arguments' => 1
];
$this->task->execute($this->node, $this->application, $this->deployment, $options);
}

/**
* @test
*/
public function executeWithoutArgumentsExecutesAssetPublish(): void
{
$options = [
'typo3CliFileName' => 'vendor/bin/typo3'
];
$this->task->execute($this->node, $this->application, $this->deployment, $options);
$this->assertCommandExecuted("/^cd '\/releases\/[0-9]+'$/");
$this->assertCommandExecuted("/php 'vendor\/bin\/typo3' 'asset:publish'$/");
}

/**
* @test
*/
public function executeWithArgumentsPassesThemToAssetPublish(): void
{
$options = [
'typo3CliFileName' => 'vendor/bin/typo3',
'arguments' => ['-v']
];
$this->task->execute($this->node, $this->application, $this->deployment, $options);
$this->assertCommandExecuted("/php 'vendor\/bin\/typo3' 'asset:publish' '-v'$/");
}

/**
* @test
*/
public function executeWithContextOptionSetsTypo3Context(): void
{
$options = [
'typo3CliFileName' => 'vendor/bin/typo3',
'context' => 'Production'
];
$this->task->execute($this->node, $this->application, $this->deployment, $options);
$this->assertCommandExecuted("/TYPO3_CONTEXT='Production' php 'vendor\/bin\/typo3' 'asset:publish'$/");
}
}
Loading