Skip to content
赞助商赞助商
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待
虚位以待

Laravel Envoy

介绍

Laravel Envoy 是一个用于在远程服务器上执行常见任务的工具。使用 Blade 风格的语法,您可以轻松设置部署、Artisan 命令等任务。目前,Envoy 仅支持 Mac 和 Linux 操作系统。然而,通过使用 WSL2,可以实现对 Windows 的支持。

安装

首先,使用 Composer 包管理器将 Envoy 安装到您的项目中:

shell
composer require laravel/envoy --dev

一旦安装了 Envoy,Envoy 二进制文件将在您的应用程序的 vendor/bin 目录中可用:

shell
php vendor/bin/envoy

编写任务

定义任务

任务是 Envoy 的基本构建块。任务定义了在任务被调用时应在远程服务器上执行的 shell 命令。例如,您可以定义一个任务,在应用程序的所有队列工作服务器上执行 php artisan queue:restart 命令。

所有的 Envoy 任务都应该在应用程序根目录下的 Envoy.blade.php 文件中定义。以下是一个示例:

blade
@servers(['web' => ['user@192.168.1.1'], 'workers' => ['user@192.168.1.2']])

@task('restart-queues', ['on' => 'workers'])
    cd /home/user/example.com
    php artisan queue:restart
@endtask

如您所见,文件顶部定义了一个 @servers 数组,允许您通过任务声明的 on 选项引用这些服务器。@servers 声明应始终放在一行中。在您的 @task 声明中,您应该放置在任务被调用时应在服务器上执行的 shell 命令。

本地任务

您可以通过将服务器的 IP 地址指定为 127.0.0.1 来强制脚本在本地计算机上运行:

blade
@servers(['localhost' => '127.0.0.1'])

导入 Envoy 任务

使用 @import 指令,您可以导入其他 Envoy 文件,以便将它们的故事和任务添加到您的文件中。导入文件后,您可以像在自己的 Envoy 文件中定义的那样执行它们包含的任务:

blade
@import('vendor/package/Envoy.blade.php')

多个服务器

Envoy 允许您轻松地在多个服务器上运行任务。首先,将其他服务器添加到您的 @servers 声明中。每个服务器都应分配一个唯一的名称。一旦定义了其他服务器,您可以在任务的 on 数组中列出每个服务器:

blade
@servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])

@task('deploy', ['on' => ['web-1', 'web-2']])
    cd /home/user/example.com
    git pull origin {{ $branch }}
    php artisan migrate --force
@endtask

并行执行

默认情况下,任务将在每个服务器上串行执行。换句话说,任务将在第一个服务器上完成运行后,才会继续在第二个服务器上执行。如果您希望在多个服务器上并行运行任务,请在任务声明中添加 parallel 选项:

blade
@servers(['web-1' => '192.168.1.1', 'web-2' => '192.168.1.2'])

@task('deploy', ['on' => ['web-1', 'web-2'], 'parallel' => true])
    cd /home/user/example.com
    git pull origin {{ $branch }}
    php artisan migrate --force
@endtask

设置

有时,您可能需要在运行 Envoy 任务之前执行任意 PHP 代码。您可以使用 @setup 指令定义一个在任务之前执行的 PHP 代码块:

php
@setup
    $now = new DateTime;
@endsetup

如果您需要在任务执行之前引入其他 PHP 文件,可以在 Envoy.blade.php 文件的顶部使用 @include 指令:

blade
@include('vendor/autoload.php')

@task('restart-queues')
    # ...
@endtask

变量

如果需要,您可以通过在调用 Envoy 时在命令行上指定参数来传递参数给 Envoy 任务:

shell
php vendor/bin/envoy run deploy --branch=master

您可以使用 Blade 的 "echo" 语法在任务中访问这些选项。您还可以在任务中定义 Blade if 语句和循环。例如,让我们在执行 git pull 命令之前验证 $branch 变量的存在:

blade
@servers(['web' => ['user@192.168.1.1']])

@task('deploy', ['on' => 'web'])
    cd /home/user/example.com

    @if ($branch)
        git pull origin {{ $branch }}
    @endif

    php artisan migrate --force
@endtask

故事

故事将一组任务组合在一个方便的名称下。例如,一个 deploy 故事可以通过在其定义中列出任务名称来运行 update-codeinstall-dependencies 任务:

blade
@servers(['web' => ['user@192.168.1.1']])

@story('deploy')
    update-code
    install-dependencies
@endstory

@task('update-code')
    cd /home/user/example.com
    git pull origin master
@endtask

@task('install-dependencies')
    cd /home/user/example.com
    composer install
@endtask

一旦故事被编写,您可以像调用任务一样调用它:

shell
php vendor/bin/envoy run deploy

钩子

当任务和故事运行时,会执行许多钩子。Envoy 支持的钩子类型有 @before@after@error@success@finished。这些钩子中的所有代码都被解释为 PHP 并在本地执行,而不是在任务与之交互的远程服务器上执行。

您可以定义任意数量的每种钩子。它们将按照它们在 Envoy 脚本中出现的顺序执行。

@before

在每次任务执行之前,Envoy 脚本中注册的所有 @before 钩子将执行。@before 钩子接收将要执行的任务的名称:

blade
@before
    if ($task === 'deploy') {
        // ...
    }
@endbefore

@after

在每次任务执行之后,Envoy 脚本中注册的所有 @after 钩子将执行。@after 钩子接收已执行的任务的名称:

blade
@after
    if ($task === 'deploy') {
        // ...
    }
@endafter

@error

在每次任务失败(以状态码大于 0 退出)后,Envoy 脚本中注册的所有 @error 钩子将执行。@error 钩子接收已执行的任务的名称:

blade
@error
    if ($task === 'deploy') {
        // ...
    }
@enderror

@success

如果所有任务都已无错误地执行,Envoy 脚本中注册的所有 @success 钩子将执行:

blade
@success
    // ...
@endsuccess

@finished

在所有任务执行完毕后(无论退出状态如何),所有的 @finished 钩子将被执行。@finished 钩子接收已完成任务的状态码,该状态码可能为 null 或大于等于 0integer

blade
@finished
    if ($exitCode > 0) {
        // 在某个任务中出现了错误...
    }
@endfinished

运行任务

要运行定义在应用程序的 Envoy.blade.php 文件中的任务或故事,执行 Envoy 的 run 命令,并传递您想要执行的任务或故事的名称。Envoy 将执行任务并在任务运行时显示来自远程服务器的输出:

shell
php vendor/bin/envoy run deploy

确认任务执行

如果您希望在服务器上运行给定任务之前提示确认,您应该在任务声明中添加 confirm 指令。此选项对于破坏性操作特别有用:

blade
@task('deploy', ['on' => 'web', 'confirm' => true])
    cd /home/user/example.com
    git pull origin {{ $branch }}
    php artisan migrate
@endtask

通知

Slack

Envoy 支持在每个任务执行后向 Slack 发送通知。@slack 指令接受一个 Slack 钩子 URL 和一个频道/用户名。您可以通过在 Slack 控制面板中创建一个 "Incoming WebHooks" 集成来获取您的 webhook URL。

您应该将整个 webhook URL 作为传递给 @slack 指令的第一个参数。传递给 @slack 指令的第二个参数应该是一个频道名称(#channel)或用户名(@user):

blade
@finished
    @slack('webhook-url', '#bots')
@endfinished

默认情况下,Envoy 通知将向通知频道发送一条描述已执行任务的消息。然而,您可以通过传递第三个参数给 @slack 指令来覆盖此消息:

blade
@finished
    @slack('webhook-url', '#bots', 'Hello, Slack.')
@endfinished

Discord

Envoy 还支持在每个任务执行后向 Discord 发送通知。@discord 指令接受一个 Discord 钩子 URL 和一条消息。您可以通过在服务器设置中创建一个 "Webhook" 并选择 webhook 应发布到的频道来获取您的 webhook URL。您应该将整个 Webhook URL 传递给 @discord 指令:

blade
@finished
    @discord('discord-webhook-url')
@endfinished

Telegram

Envoy 还支持在每个任务执行后向 Telegram 发送通知。@telegram 指令接受一个 Telegram Bot ID 和一个 Chat ID。您可以通过使用 BotFather 创建一个新机器人来获取您的 Bot ID。您可以使用 @username_to_id_bot 获取有效的 Chat ID。您应该将整个 Bot ID 和 Chat ID 传递给 @telegram 指令:

blade
@finished
    @telegram('bot-id','chat-id')
@endfinished

Microsoft Teams

Envoy 还支持在每个任务执行后向 Microsoft Teams 发送通知。@microsoftTeams 指令接受一个 Teams Webhook(必需)、一条消息、主题颜色(success、info、warning、error)和一个选项数组。您可以通过创建一个新的 incoming webhook 来获取您的 Teams Webhook。Teams API 还有许多其他属性可以自定义您的消息框,如标题、摘要和部分。您可以在 Microsoft Teams 文档 中找到更多信息。您应该将整个 Webhook URL 传递给 @microsoftTeams 指令:

blade
@finished
    @microsoftTeams('webhook-url')
@endfinished