如今,持续集成 (CI) 工作流被认为是最佳实践。也就是说,您使用版本控制系统 (Git),并在使用过程中,CI 会为您完成一些工作,例如运行测试、发送通知和部署代码。最后一步称为持续部署 (CD)。但是,将代码交付到生产服务器通常需要付费服务。借助 GitHub Actions,持续部署对每个人都是免费的。让我们探索如何设置它。
DevOps 适用于所有人
作为一名前端开发人员,持续部署工作流曾经令我兴奋,但也很神秘。我记得很多次都害怕接触部署配置。我选择走简单的路线——通常是让其他人设置和维护它,或者在最坏的情况下手动复制粘贴一些东西。
一旦我了解了 rsync 的基础知识,CD 最终对我来说变得易于理解。通过以下 GitHub Action 工作流,您无需成为 DevOps 专家;但您仍然可以随时使用工具来设置最佳实践部署工作流。
持续部署工作流的基础知识
那么,到底是怎么回事,它是如何工作的?这一切都始于 CI,这意味着您将代码提交到共享的远程存储库,例如 GitHub,并且每次向其推送都会在远程服务器上运行自动化任务。这些任务可能包括测试和构建过程,例如代码风格检查、连接、压缩和图像优化等。
CD 还将代码交付到生产网站服务器。这可以通过复制已验证和构建的代码并将其通过 FTP、SSH 或通过将容器发送到基础设施放置在服务器上。虽然每个共享主机套餐都具有 FTP 访问权限,但将许多文件发送到服务器的方式相当不可靠且缓慢。虽然发送应用程序容器是发布复杂应用程序的安全方法,但基础设施和设置也可能相当复杂。但是,通过 SSH 部署代码速度快、安全且灵活。此外,许多主机套餐都支持它。
如何使用 rsync 部署
通过 SSH 将文件交付到服务器的一种简单有效的方法是 rsync,这是一个在源文件夹、驱动器或计算机与目标文件夹、驱动器或计算机之间同步文件的实用程序工具。它只会同步已更改或目标位置尚不存在的文件。由于它已成为流行 Linux 发行版上的标准工具,因此很有可能您甚至不需要安装它。
最基本的操作与调用 rsync SRC DEST
以将文件从一个目录同步到另一个目录一样简单。但是,您需要考虑几个选项
-c
通过校验和比较文件更改,而不是修改时间-h
以更易于人类阅读的格式输出数字-a
保留文件属性和权限,并递归复制文件和目录-v
显示状态输出--delete
删除目标中在源(不再)中找不到的文件--exclude
阻止同步指定的文件,例如.git
目录和node_modules
最后,您需要将文件发送到远程服务器,这使得完整命令如下所示
rsync -chav --delete --exclude /.git/ --exclude /node_modules/ ./ [email protected]:/mydir
您可以从本地计算机运行该命令以部署到任何实时服务器。但是,如果它在干净状态的受控环境中运行会怎么样?没错,这就是您来这里的目的。让我们继续吧。
创建 GitHub Actions 工作流
使用 GitHub Actions,您可以 配置工作流 以在任何 GitHub 事件上运行。虽然有一个 GitHub Actions 市场,但我们不需要其中的任何一个,而是将构建自己的工作流。
要开始,请转到存储库的“Actions”选项卡,然后单击“自己设置工作流”。这将打开工作流编辑器,其中包含一个 .yaml
模板,该模板将提交到存储库的 .github/workflows
目录。

保存后,工作流会检出您的存储库代码并运行一些 echo
命令。name
有助于稍后跟踪状态和结果。run
包含您希望在每个步骤中运行的 shell 命令。
定义部署触发器
理论上,每次提交到主分支都应该是生产就绪的。但是,现实告诉您,您还需要在部署后在生产服务器上测试结果,并且需要安排它。我们在 bleech 认为,最佳实践是在工作日(除周五外)且仅在下午 4:00 之前进行部署,以确保如果出现任何问题,我们在工作时间内有时间回滚或解决问题。
获得手动级别控制的一种简单方法是设置一个仅用于触发部署的分支。这样,您就可以在准备好时将其合并到其中。将该分支称为 production,让团队中的每个人都知道仅允许从主分支推送更改,并告诉他们按照以下方式操作
git push origin master:production
以下是如何更改工作流触发器,使其仅在向该 production
分支推送时运行
name: Deployment
on:
push:
branches: [ production ]
构建和验证主题
我假设您正在使用我们的 WordPress 启动主题 Flynt,它通过 Composer 和 npm 提供依赖项管理,以及预配置的构建过程。如果您使用的是其他主题,则构建过程可能类似,但可能需要进行调整。如果您将构建的资源检入存储库,则可以跳过除 checkout
命令之外的所有步骤。
对于我们的示例,让我们确保以所需版本执行 node,并在构建之前安装依赖项
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 12.x
- name: Install dependencies
run: |
composer install -o
npm install
- name: Build
run: npm run build
Flynt 构建任务最终需要检查代码风格、编译和转换 Sass 和 JavaScript 文件,然后为资源添加修订以防止浏览器缓存问题。如果构建步骤中的任何内容失败,工作流将停止执行,从而防止您部署有问题的版本。
配置服务器访问和目标
要使 rsync
命令成功运行,GitHub 需要能够通过 SSH 访问您的服务器。这可以通过执行以下操作来实现
- 生成新的 SSH 密钥(无密码)
- 将公钥添加到生产服务器上的
~/.ssh/authorized_keys
中 - 将私钥作为名称为
DEPLOY_KEY
的密钥添加到存储库

同步工作流步骤需要将密钥保存到本地文件,调整文件权限并将文件传递给 rsync
命令。目标必须指向生产服务器上的 WordPress 主题目录。将其定义为变量很方便,这样您在将工作流重复用于未来项目时就知道需要更改哪些内容。
- name: Sync
env:
dest: '[email protected]:/mydir/wp-content/themes/mytheme'
run: |
echo "${{secrets.DEPLOY_KEY}}" > deploy_key
chmod 600 ./deploy_key
rsync -chav --delete \
-e 'ssh -i ./deploy_key -o StrictHostKeyChecking=no' \
--exclude /deploy_key \
--exclude /.git/ \
--exclude /.github/ \
--exclude /node_modules/ \
./ ${{env.dest}}
根据您的项目结构,您可能还需要部署插件和其他与主题相关的文件。为此,请将源和目标更改为所需的父目录,确保检查排除的文件是否需要更新,并检查构建过程中是否有任何路径需要调整。
将各个部分整合在一起
我们已经涵盖了持续交付流程中所有必要的步骤。现在我们需要按顺序运行它们,这些步骤应
- 在每次推送到
production
分支时触发 - 安装依赖项
- 构建并验证代码
- 通过 rsync 将结果发送到服务器
完整的 GitHub 工作流程 将如下所示
name: Deployment
on:
push:
branches: [ production ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
with:
node-version: 12.x
- name: Install dependencies
run: |
composer install -o
npm install
- name: Build
run: npm run build
- name: Sync
env:
dest: '[email protected]:/mydir/wp-content/themes/mytheme'
run: |
echo "${{secrets.DEPLOY_KEY}}" > deploy_key
chmod 600 ./deploy_key
rsync -chav --delete \
-e 'ssh -i ./deploy_key -o StrictHostKeyChecking=no' \
--exclude /deploy_key \
--exclude /.git/ \
--exclude /.github/ \
--exclude /node_modules/ \
./ ${{env.dest}}
要测试工作流程,请提交更改,将它们拉取到本地存储库,然后通过将您的 master
分支推送到 production
分支来触发部署。
git push origin master:production
您可以通过转到 GitHub 中的“操作”选项卡,然后选择最近的执行并点击“部署”作业来跟踪执行状态。绿色的勾号表示一切顺利。如果出现任何问题,请检查失败步骤的日志以修复它们。

恭喜!您已成功将 WordPress 主题部署到服务器。工作流程文件可以轻松地重复用于未来的项目,从而使持续部署设置变得轻而易举。
为了进一步优化您的部署流程,以下主题值得考虑
- 缓存依赖项 以加快 GitHub 工作流程
- 在同步文件时激活 WordPress 维护模式
- 部署后清除插件(如 Cache Enabler)的网站缓存
与直接拉取 Git 仓库相比,使用 rsync 的好处是什么?
在我看来,主要优势在于
不错的概述!我将在我的下一个项目中尝试一下。
太棒了!很高兴听到这个消息。
谢谢,谢谢,谢谢!
不客气 :)
谢谢,我一直在尝试解决这个问题。
我自己也花了很长时间才弄明白。此外,GitHub 更改了他们的 Actions API,这对我来说非常令人困惑,因为我找到了许多使用旧语法的示例。
感谢这篇文章。我想知道此命令中的
master:production
是什么意思。您的分支名称是否为
master:production
,或者这是某种其他 Git 魔法?感谢您的提问。该命令实现了以下功能
我的本地分支称为
master
,我想将其推送到名为production
的远程分支,该分支应与我的 master 分支相同。如果名为 production 的远程分支尚不存在,则将创建它。Git 参考 提供了有关冒号语法的更多信息。
感谢您提供的这个不错的介绍。在尝试此操作时,我注意到一个严重的缺陷,即推送到生产服务器的 deploy_key。幸运的是,在排除列表中添加
--exclude /deploy_key \
可以解决此问题。您完全正确!感谢您注意到这一点,Ismail。
deploy_key
文件包含私有 SSH 密钥,出于安全原因,不得将其传输到远程服务器。我刚刚相应地更新了帖子和示例存储库。不错!感谢分享。我们使用类似的方法,在某些情况下,我们拥有具有自己的独立 Git 仓库进行部署的托管主机。在这种情况下,我们不是使用 RSYNC,而是将我们的仓库与主机仓库同步并推送。然后,主机部署钩子处理其余操作。
这很棒,谢谢!我正在使用它来即时更新我在多个站点上拥有的自定义主题,它肯定会为我节省时间。
您对如何同时清除站点缓存有什么想法吗?我使用 SiteGround 进行托管,我知道 wp-cli 命令是“wp sg purge”。
在更新多个站点时,绝对是一个节省时间的利器。
要使用 SiteGround Optimizer 清除缓存,请在 rsync 命令下方添加 cli 命令
wp sg purge
。就是这样。您好,Steffen,我刚刚偶然发现了这篇文章,似乎生成 SSH 密钥的链接已损坏。
感谢您指出,Cyril。我刚刚修复了损坏的链接。
在配置
des
的代码片段中,提到了“[email protected]”这是什么电子邮件地址?是 GitHub 电子邮件地址吗?
好问题。我理所当然地认为一些明显不明显的东西。虽然它看起来像电子邮件,但实际上并非如此。它是使用给定的 SSH 用户名连接到服务器的语法。
@ 符号之前的第一个部分是用于身份验证的 SSH 用户名,第二个部分是连接到的服务器的主机名。
您的网络主机应提供此信息。
它让我困惑了很长时间,最终我发现对于 Google Cloud 虚拟服务器实例,可以使用您的电子邮件地址用户名替换
ssh-user
(或者使用在线 SSH 连接到您的实例并在控制台中检查用户名),并且 @ 后面的第二个部分,即example.com
,可以替换为您的 VM 实例的外部 IP 地址。希望有人会发现这一点很有用。您好,
-chav 用于什么?
我查看了文档,但没有找到相关内容。
不过,这篇文章很棒,我用 Rsync 替换了我的 git-ftp 操作,它实际上更快了 8)
对吧?!对我来说,从 git-ftp 切换到 rsync 的速度提升了 100 倍。
-chav 是 -c、-h、-a、-v 这些单独选项的简写。我在上面的 如何使用 rsync 部署 部分简要解释了这些选项。您可以在 rsync 手册 中找到有关每个选项的更多详细信息。
我尝试了一下,但它一直给我这个错误:您的 YAML 语法在第 32 行存在错误
这一行是
rsync -chav --delete \
这听起来像是 GitHub 抱怨的语法错误,与工作流程文件有关。请检查所有缩进是否与 示例 中的完全相同,并尝试重新格式化缩进。
如果这不能解决问题,请尝试将整个 rsync 命令 (从第 32 行到第 38 行) 放入一行中,但在之前删除每行末尾的反斜杠。
我认为问题在于这一行末尾有一个“智能单引号”:
dest: '[email protected]:/mydir/wp-content/themes/mytheme’
将其更改为普通撇号为我解决了同样的问题。
感谢你发现它,Dan!我刚刚在上面的示例代码中将结束的单引号替换为直单引号。
您好,为了将WordPress网站开发给客户,我需要将数据库以及WordPress文件从本地主机传输到客户的远程服务器。现在我仅使用All in One Migrate插件。我一直在寻找从本地主机到远程服务器自动部署的Git解决方案,我可以将WordPress文件从本地主机推送到服务器上的Git,但是数据库该怎么办呢?
您好,Bishan,我们正在使用WP-CLI将数据库从一个环境克隆到另一个环境。然后,我们使用rsync同步上传文件夹。这也可以在部署脚本中自动化。