.. -*- coding: utf-8 -*- with BOM. .. include:: ../Includes.txt ===== Tasks ===== Since a deployment configuration is just a plain PHP file you can create custom tasks by creating for example a **NpmInstallTask** class which itself must extend in the whole inheritance chain the abstract class **\\TYPO3\\Surf\\Domain\\Model\\Task** shipped with Surf:: defineTask('NpmInstallTask', \TYPO3\Surf\Task\LocalShellTask::class, [ 'command' => [ 'cd {workspacePath} && npm install', ] ]); This way you create a task dynamically by extending the base task \\TYPO3\\Surf\\Task\\LocalShellTask::class with an array of options. In this case the command option is mandatory for the LocalShellTask. We will show you another convenient and often used way to customize the deployment workflow with your own tasks:: defineTask('CopyEnvFileTask', \TYPO3\Surf\Task\ShellTask::class, [ 'command' => [ 'cp {sharedPath}/.env {releasePath}/.env', 'cd {releasePath}', ] ]); In this case we create a task dynamically based on the ShellTask. The ShellTask execute one or more provided commands on the target machine. As you can see, we have used some other placeholders compared to the LocalShellTask above. For the remote ShellTask the following placeholders are available: .. _tasks-placeholders: Placeholders ------------ * **workspacePath**: The path to the local workspace directory * **deploymentPath**: The path to the deployment base directory * **releasePath**: The path to the release directory in work (typically referenced by *next*) * **sharedPath**: The path to the shared directory for all releases * **currentPath**: The path that points to the *current* release * **previousPath**: The path that points to the *previous* release Add task to the deployment flow ------------------------------- So we have seen how to create custom tasks in different ways. In the following we will see how we add these tasks to the deployment flow:: onInitialize(function () use ($deployment, $application) { $deployment->getWorkflow() ->defineTask('CopyEnvFileTask', \TYPO3\Surf\Task\ShellTask::class, [ 'command' => [ 'cp {sharedPath}/.env {releasePath}/.env', 'cd {releasePath}', ] ]) ->afterStage('transfer', 'CopyEnvFileTask', $application); }); This will execute the new task after the stage transfer only for the application referenced by $application. Besides specifying the execution point via a stage, you can also give an existing task as an anchor and specify the task execution with **afterTask** or **beforeTask**:: onInitialize(function () use ($deployment, $application) { $deployment->getWorkflow() ->beforeTask(SomeTask::class, [ 'CopyEnvFileTask' ]); }); The following table shows all the methods to manipulate the tasks in the deployment flow (part of the abstract Workflow class): ====================== ================================= =============================================================================== Method Arguments Description ====================== ================================= =============================================================================== defineTask $taskName, $taskType, ($options) Defines a new task with name $taskName based on $taskType with custom options. addTask $tasks, $stage, ($application) Add one or more tasks to the workflow that should run in the given stage. removeTask $taskName Removes the task with the given name from all stages and applications. afterTask $taskName, $tasks, ($application) Adds one or more tasks that should run *after* the given task name. beforeTask $taskName, $tasks, ($application) Adds one or more tasks that should run *before* the given task name. ====================== ================================= =============================================================================== Options for Task ---------------- In order to customize options of existing tasks you can do it the following ways:: setOption(RsyncTask::class . '[rsyncExcludes]', [ '.git', 'web/fileadmin', 'web/uploads', ]); // Customize the option for the task only for a specific node $node->setOption(RsyncTask::class . '[rsyncExcludes]', [ 'web/fileadmin', 'web/uploads', ]); // Customize the option for the whole deployment $deployment->setOption(RsyncTask::class . '[rsyncExcludes]', [ '.git', ]); The **order is important** because application options override node options and node options override deployment options.