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

Laravel Envoy

介绍

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

安装

首先,使用 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 的“回显”语法在任务中访问选项。您还可以在任务中定义 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 或大于等于 0 的整数:

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 控制面板中创建“传入 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(必需)、一条消息、主题颜色(成功、信息、警告、错误)和一个选项数组。您可以通过创建一个新的 传入 webhook 来获取您的 Teams Webhook。Teams API 还有许多其他属性可以自定义您的消息框,如标题、摘要和部分。您可以在 Microsoft Teams 文档 中找到更多信息。您应将整个 Webhook URL 传递给 @microsoftTeams 指令:

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