spatie/scotty
Scotty is a beautiful SSH task runner for executing scripted tasks on remote servers. Define tasks in a Scotty.sh file (bash with annotations), run them with clear output, and use it as a drop-in, Envoy-compatible alternative for deploys and ops.
Scotty can read existing Laravel Envoy files out of the box. If your project has an Envoy.blade.php, you can run it with Scotty without changing anything. Just run scotty run deploy (or whatever your task is called) and it works.
This page documents the Blade file format that Envoy uses, so you can understand your existing file before deciding whether to migrate to the Scotty.sh format.
All tasks should be defined in an Envoy.blade.php file at the root of your project.
Define your servers with the [@servers](https://github.com/servers) directive at the top of the file:
[@servers](https://github.com/servers)(['web' => ['user@192.168.1.1'], 'workers' => ['user@192.168.1.2']])
The [@servers](https://github.com/servers) declaration should always be placed on a single line.
Tasks are the basic building block. They contain the shell commands that should execute on your remote servers:
[@servers](https://github.com/servers)(['web' => ['user@192.168.1.1']])
[@task](https://github.com/task)('deploy', ['on' => 'web'])
cd /home/user/example.com
git pull origin main
php artisan migrate --force
[@endtask](https://github.com/endtask)
To run a script on your local machine, use 127.0.0.1 as the server address:
[@servers](https://github.com/servers)(['localhost' => '127.0.0.1'])
List multiple servers in the on array to run a task on each one:
[@servers](https://github.com/servers)(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])
[@task](https://github.com/task)('deploy', ['on' => ['web-1', 'web-2']])
cd /home/user/example.com
git pull origin {{ $branch }}
php artisan migrate --force
[@endtask](https://github.com/endtask)
By default, the task finishes on the first server before starting on the second.
To run on all servers at the same time, add the parallel option:
[@task](https://github.com/task)('deploy', ['on' => ['web-1', 'web-2'], 'parallel' => true])
cd /home/user/example.com
git pull origin {{ $branch }}
[@endtask](https://github.com/endtask)
Add confirm to prompt before running:
[@task](https://github.com/task)('deploy', ['on' => 'web', 'confirm' => true])
cd /home/user/example.com
git pull origin main
[@endtask](https://github.com/endtask)
If you need to execute PHP code before your tasks run, use the [@setup](https://github.com/setup) directive:
[@setup](https://github.com/setup)
$now = new DateTime;
$branch = 'main';
$releaseName = $now->format('YmdHis');
[@endsetup](https://github.com/endsetup)
To require other PHP files, use [@include](https://github.com/include) at the top of your file:
[@include](https://github.com/include)('vendor/autoload.php')
You can pass arguments from the command line:
scotty run deploy --branch=master
Access them in your tasks using Blade's echo syntax:
[@task](https://github.com/task)('deploy', ['on' => 'web'])
cd /home/user/example.com
[@if](https://github.com/if) ($branch)
git pull origin {{ $branch }}
[@endif](https://github.com/endif)
php artisan migrate --force
[@endtask](https://github.com/endtask)
Stories group tasks under a single name:
[@servers](https://github.com/servers)(['web' => ['user@192.168.1.1']])
[@story](https://github.com/story)('deploy')
update-code
install-dependencies
[@endstory](https://github.com/endstory)
[@task](https://github.com/task)('update-code')
cd /home/user/example.com
git pull origin main
[@endtask](https://github.com/endtask)
[@task](https://github.com/task)('install-dependencies')
cd /home/user/example.com
composer install
[@endtask](https://github.com/endtask)
Run a story the same way you run a task:
scotty run deploy
Hooks run at different points during execution. All hook code is interpreted as PHP and executed locally.
Runs before each task:
[@before](https://github.com/before)
if ($task === 'deploy') {
// ...
}
[@endbefore](https://github.com/endbefore)
Runs after each task:
[@after](https://github.com/after)
if ($task === 'deploy') {
// ...
}
[@endafter](https://github.com/endafter)
Runs when a task fails (exit code greater than 0):
[@error](https://github.com/error)
if ($task === 'deploy') {
// ...
}
[@enderror](https://github.com/enderror)
Runs if all tasks executed without errors:
[@success](https://github.com/success)
// ...
[@endsuccess](https://github.com/endsuccess)
Runs after all tasks, regardless of the outcome:
[@finished](https://github.com/finished)
if ($exitCode > 0) {
// ...
}
[@endfinished](https://github.com/endfinished)
You can import other Envoy files:
[@import](https://github.com/import)('vendor/package/Envoy.blade.php')
For the full Blade format reference, see the Laravel Envoy documentation.
How can I help you explore Laravel packages today?