From 73f2b531d71075f8523829ce0bbeeac4fb7e10fa Mon Sep 17 00:00:00 2001 From: ochorocho Date: Wed, 13 Sep 2023 13:35:34 +0200 Subject: [PATCH] [TASK] Update TYPO3 recipe (#3674) * [TASK] Update TYPO3 recipe * Update recipe for TYPO3 v12 * Allow tasks to be added before or after a task in a given task group * Allow to hide spinner to enable interactive tasks on be run on the remote server Fixes #3667 * [TASK] Update docs * [TASK] Remove deploy:vendors from recipe We aim for minimal requirements on the target server. Thus, all preparation should be done in CI. * [TASK] Update comment --- docs/recipe/typo3.md | 143 ++++++++++++++++++++++++++++++++-------- recipe/typo3.php | 102 ++++++++++++++++++++++++---- src/Deployer.php | 2 +- src/Executor/Master.php | 4 +- src/Task/GroupTask.php | 27 ++++++++ src/Task/Task.php | 15 +++++ 6 files changed, 249 insertions(+), 44 deletions(-) diff --git a/docs/recipe/typo3.md b/docs/recipe/typo3.md index ad84e4a4..423bf089 100644 --- a/docs/recipe/typo3.md +++ b/docs/recipe/typo3.md @@ -28,37 +28,45 @@ Additionally, Deployer has a lot of other features, like: You can read more about Deployer in [Getting Started](/docs/getting-started.md). The [deploy](#deploy) task of **TYPO3** consists of: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) – Prepares a new release - * [deploy:info](/docs/recipe/deploy/info.md#deployinfo) – Displays info about deployment - * [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy - * [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy - * [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release - * [deploy:update_code](/docs/recipe/deploy/update_code.md#deployupdate_code) – Updates code - * [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs - * [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) – Installs vendors -* [deploy:publish](/docs/recipe/common.md#deploypublish) – Publishes the release - * [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release - * [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy - * [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases - * [deploy:success](/docs/recipe/common.md#deploysuccess) – +* [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) – Prepares host for deploy +* [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) – Locks deploy +* [deploy:release](/docs/recipe/deploy/release.md#deployrelease) – Prepares release +* [rsync](/docs/contrib/rsync.md#rsync) – Rsync local->remote +* [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) – Creates symlinks for shared files and dirs +* [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) – Makes writable dirs +* [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) – Creates symlink to release +* [typo3:extension:setup](/docs/recipe/typo3.md#typo3extensionsetup) – TYPO3 - Set up extensions +* [typo3:cache:flush](/docs/recipe/typo3.md#typo3cacheflush) – TYPO3 - Cache clearing for all caches +* [typo3:language:update](/docs/recipe/typo3.md#typo3languageupdate) – TYPO3 - Update the language files of all activated extensions +* [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) – Unlocks deploy +* [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) – Cleanup old releases The typo3 recipe is based on the [common](/docs/recipe/common.md) recipe. ## Configuration ### typo3_webroot -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L11) +[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L12) DocumentRoot / WebRoot for the TYPO3 installation ```php title="Default value" -'Web' +'public' +``` + + +### bin/typo3 +[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L17) + +Path to TYPO3 cli + +```php title="Default value" +'vendor/bin/typo3' ``` ### shared_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L26) +[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L22) Overrides [shared_dirs](/docs/recipe/deploy/shared.md#shared_dirs) from `recipe/deploy/shared.php`. @@ -74,7 +82,7 @@ Shared directories ### shared_files -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L35) +[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L31) Overrides [shared_files](/docs/recipe/deploy/shared.md#shared_files) from `recipe/deploy/shared.php`. @@ -82,13 +90,14 @@ Shared files ```php title="Default value" [ - '{{typo3_webroot}}/.htaccess' + '{{typo3_webroot}}/.htaccess', + 'config/system/settings.php', ] ``` ### writable_dirs -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L42) +[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L39) Overrides [writable_dirs](/docs/recipe/deploy/writable.md#writable_dirs) from `recipe/deploy/writable.php`. @@ -97,9 +106,28 @@ Writeable directories ```php title="Default value" [ '{{typo3_webroot}}/fileadmin', - '{{typo3_webroot}}/typo3temp', - '{{typo3_webroot}}/typo3conf', - '{{typo3_webroot}}/uploads' + 'var', +] +``` + + +### rsync +[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L65) + + + +```php title="Default value" +[ + 'exclude' => array_merge(get('shared_dirs'), get('shared_files'), $exclude), + 'exclude-file' => false, + 'include' => ['vendor'], + 'include-file' => false, + 'filter' => ['dir-merge,-n /.gitignore'], + 'filter-file' => false, + 'filter-perdir' => false, + 'flags' => 'avz', + 'options' => ['delete', 'keep-dirlinks', 'links'], + 'timeout' => 600 ] ``` @@ -107,17 +135,74 @@ Writeable directories ## Tasks +### typo3:cache:warmup +[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L79) + +TYPO3 - Cache warmup for all caches. + + + + +### typo3:cache:flush +[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L85) + +TYPO3 - Cache clearing for all caches. + + + + +### typo3:language:update +[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L91) + +TYPO3 - Update the language files of all activated extensions. + + + + +### typo3:extension:setup +[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L97) + +TYPO3 - Set up extensions. + + + + +### deploy:update_code +[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L105) + + + +Configure "deploy" task group. + + +### deploy:info +[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L106) + + + + + + ### deploy -[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L17) +[Source](https://github.com/deployphp/deployer/blob/master/recipe/typo3.php#L109) + +Deploys a TYPO3 project. -Deploys your project. -Main TYPO3 task This task is group task which contains next tasks: -* [deploy:prepare](/docs/recipe/common.md#deployprepare) -* [deploy:vendors](/docs/recipe/deploy/vendors.md#deployvendors) -* [deploy:publish](/docs/recipe/common.md#deploypublish) +* [deploy:setup](/docs/recipe/deploy/setup.md#deploysetup) +* [deploy:lock](/docs/recipe/deploy/lock.md#deploylock) +* [deploy:release](/docs/recipe/deploy/release.md#deployrelease) +* [rsync](/docs/contrib/rsync.md#rsync) +* [deploy:shared](/docs/recipe/deploy/shared.md#deployshared) +* [deploy:writable](/docs/recipe/deploy/writable.md#deploywritable) +* [deploy:symlink](/docs/recipe/deploy/symlink.md#deploysymlink) +* [typo3:extension:setup](/docs/recipe/typo3.md#typo3extensionsetup) +* [typo3:cache:flush](/docs/recipe/typo3.md#typo3cacheflush) +* [typo3:language:update](/docs/recipe/typo3.md#typo3languageupdate) +* [deploy:unlock](/docs/recipe/deploy/lock.md#deployunlock) +* [deploy:cleanup](/docs/recipe/deploy/cleanup.md#deploycleanup) diff --git a/recipe/typo3.php b/recipe/typo3.php index e01476e4..5a9b9231 100644 --- a/recipe/typo3.php +++ b/recipe/typo3.php @@ -2,23 +2,19 @@ namespace Deployer; require_once __DIR__ . '/common.php'; +require_once __DIR__ . '/../contrib/rsync.php'; add('recipes', ['typo3']); /** * DocumentRoot / WebRoot for the TYPO3 installation */ -set('typo3_webroot', 'Web'); +set('typo3_webroot', 'public'); /** - * Main TYPO3 task + * Path to TYPO3 cli */ -desc('Deploys your project'); -task('deploy', [ - 'deploy:prepare', - 'deploy:vendors', - 'deploy:publish', -]); +set('bin/typo3', 'vendor/bin/typo3'); /** * Shared directories @@ -33,7 +29,8 @@ set('shared_dirs', [ * Shared files */ set('shared_files', [ - '{{typo3_webroot}}/.htaccess' + '{{typo3_webroot}}/.htaccess', + 'config/system/settings.php', ]); /** @@ -41,7 +38,88 @@ set('shared_files', [ */ set('writable_dirs', [ '{{typo3_webroot}}/fileadmin', - '{{typo3_webroot}}/typo3temp', - '{{typo3_webroot}}/typo3conf', - '{{typo3_webroot}}/uploads' + 'var', ]); + +$exclude = [ + '.Build', + '.git', + '.gitlab', + '.ddev', + '.deployer', + '.idea', + '.DS_Store', + '.gitlab-ci.yml', + '.npm', + 'deploy.yaml', + 'package.json', + 'package-lock.json', + 'node_modules/', + 'var/', + 'public/fileadmin/', + 'public/typo3temp/', + 'config/system/additional.php', + 'config/system/settings.php', +]; + +set('rsync', [ + 'exclude' => array_merge(get('shared_dirs'), get('shared_files'), $exclude), + 'exclude-file' => false, + 'include' => ['vendor'], + 'include-file' => false, + 'filter' => ['dir-merge,-n /.gitignore'], + 'filter-file' => false, + 'filter-perdir' => false, + 'flags' => 'avz', + 'options' => ['delete', 'keep-dirlinks', 'links'], + 'timeout' => 600 +]); + +desc('TYPO3 - Cache warmup for all caches'); +task('typo3:cache:warmup', function () { + cd('{{release_path}}'); + run('{{bin/php}} {{bin/typo3}} cache:warmup'); +}); + +desc('TYPO3 - Cache clearing for all caches'); +task('typo3:cache:flush', function () { + cd('{{release_path}}'); + run('{{bin/php}} {{bin/typo3}} cache:flush'); +}); + +desc('TYPO3 - Update the language files of all activated extensions'); +task('typo3:language:update', function () { + cd('{{release_path}}'); + run('{{bin/php}} {{bin/typo3}} language:update'); +}); + +desc('TYPO3 - Set up extensions'); +task('typo3:extension:setup', function () { + cd('{{release_path}}'); + run('{{bin/php}} {{bin/typo3}} extension:setup'); +}); + +/** + * Configure "deploy" task group. + */ +task('deploy:update_code')->hidden()->disable(); +task('deploy:info')->hidden()->disable(); + +desc('Deploys a TYPO3 project'); +task('deploy', [ + 'deploy:setup', + 'deploy:lock', + 'deploy:release', + 'rsync', + 'deploy:shared', + 'deploy:writable', + 'deploy:symlink', + 'typo3:extension:setup', + 'typo3:cache:flush', + 'typo3:language:update', + 'deploy:unlock', + 'deploy:cleanup', + 'deploy:success' +]); + +after('deploy:failed', 'deploy:unlock'); diff --git a/src/Deployer.php b/src/Deployer.php index be8c9fc1..fec8d90e 100755 --- a/src/Deployer.php +++ b/src/Deployer.php @@ -321,7 +321,7 @@ class Deployer extends Container $output->setVerbosity(OutputInterface::VERBOSITY_DEBUG); } self::printException($output, $exception); - + exit(1); } } diff --git a/src/Executor/Master.php b/src/Executor/Master.php index 04224632..b7fa7e77 100644 --- a/src/Executor/Master.php +++ b/src/Executor/Master.php @@ -201,9 +201,9 @@ class Master } }); - $this->server->loop->addPeriodicTimer(0.03, function ($timer) use (&$processes, $callback) { + $this->server->loop->addPeriodicTimer(0.03, function ($timer) use (&$processes, $callback, $task) { $this->gatherOutput($processes, $callback); - if ($this->output->isDecorated() && !getenv('CI')) { + if ($this->output->isDecorated() && !getenv('CI') && $task->hasSpinner()) { $this->output->write(spinner()); } if ($this->allFinished($processes)) { diff --git a/src/Task/GroupTask.php b/src/Task/GroupTask.php index a43a77eb..57ac56ce 100644 --- a/src/Task/GroupTask.php +++ b/src/Task/GroupTask.php @@ -49,4 +49,31 @@ class GroupTask extends Task { $this->group = $group; } + + public function addTaskBefore(string $task, string $addTask): void + { + $this->addTask($task, $addTask); + } + + public function addTaskAfter(string $task, string $addTask): void + { + $this->addTask($task, $addTask, 'after'); + } + + public function addTask(string $task, string $addTask, string $position = 'before'): void + { + $taskPosition = array_search($task, $this->group); + if(!$taskPosition) { + throw new \InvalidArgumentException("Task `$task` not found."); + } + + switch ($position) { + case 'before': + array_splice($this->group, $taskPosition, 0, [$addTask]); + break; + case 'after': + array_splice($this->group, $taskPosition + 1, 0, [$addTask]); + break; + } + } } diff --git a/src/Task/Task.php b/src/Task/Task.php index 0dab358e..c7bb7628 100644 --- a/src/Task/Task.php +++ b/src/Task/Task.php @@ -60,6 +60,10 @@ class Task * @var bool */ private $verbose = false; + /** + * @var bool + */ + private $spinner = true; /** * @var bool */ @@ -254,6 +258,17 @@ class Task return $this; } + public function hasSpinner(): bool + { + return $this->spinner; + } + + public function spinner(bool $enabled = true): self + { + $this->spinner = $enabled; + return $this; + } + public function isEnabled(): bool { return $this->enabled;