这是一个常见情况:您创建了一个网站,并且准备就绪。它都在 GitHub 上。但是您还没有 *真正完成*。您需要设置部署。您需要设置一个为您运行测试的过程,而不是始终手动运行命令。理想情况下,每次您推送到主分支时,所有操作都会为您运行:测试、部署…所有操作都在一个地方。
以前,只有几个选项可以帮助解决这个问题。您可以将其他服务拼凑在一起,进行设置,并将它们与 GitHub 集成。您还可以编写提交后钩子,这些钩子也有帮助。
但是现在,**推出 GitHub Actions。**

Actions 是可以根据各种 GitHub 事件运行的小片段代码,其中最常见的是推送到主分支。但这并不局限于此。它们都与 GitHub 直接集成,这意味着您不再需要中间件服务,也不必自己编写解决方案。而且它们已经有很多可供您选择的选项。例如,您可以直接发布到 npm,并部署到各种云服务(Azure、AWS、Google Cloud、Zeit…应有尽有),仅举几例。
但是 Actions 不仅仅是部署和发布。这就是它们如此酷的地方。它们一直都是容器,所以您实际上可以做 *几乎任何事情*——可能性是无限的!您可以使用它们来缩小和连接 CSS 和 JavaScript,在有人在您的存储库中创建问题时向您发送信息,等等…一切皆有可能。
您也不需要自己配置/创建容器。Actions 允许您指向其他人的存储库、现有的 Dockerfile 或路径,并且 Action 将相应地运行。这对开源的可能性和生态系统来说是一个全新的挑战。
设置您的第一个 Action
您可以通过两种方式设置 Action:通过工作流 GUI 或通过手动编写和提交文件。我们将从 GUI 开始,因为它很容易理解,然后转向手动编写,因为这提供了最大的控制权。
首先,我们将点击 此处的大蓝色按钮 注册 beta 版。他们可能需要一些时间才能将您加入 beta 版,所以请耐心等待。

现在让我们创建一个存储库。我创建了一个 小型演示存储库,其中包含一个很小的 Node.js 示例网站。我已经注意到我的存储库上有一个新的选项卡,名为 Actions。

如果我点击 Actions 选项卡,将显示此屏幕

我点击“创建新工作流”,然后将显示以下屏幕。这告诉我一些信息。首先,我正在创建一个名为 .github
的隐藏文件夹,并在其中创建一个名为 main.workflow
的文件。如果您要从头开始创建工作流(我们将讨论这个问题),您需要执行相同的操作。

现在,我们看到在这个 GUI 中,我们正在启动一个新的工作流。如果我们从这里到第一个 Action 画一条线,一个侧边栏就会出现,其中包含大量选项。

这里有针对 npm、Filters、Google Cloud、Azure、Zeit、AWS、Docker Tags、Docker Registry 和 Heroku 的 Actions。如前所述,您不限于这些选项——它能够做的事情远不止这些!
我在 Azure 工作,所以我会以它为例,但每个 Action 都为您提供了相同的选项,我们将一起逐步了解。

在您看到标题“GitHub Action for Azure”的顶部,有一个“查看源代码”链接。它将直接带您到 用于运行此 Action 的存储库。这非常棒,因为您也可以提交拉取请求来改进任何这些操作,并且可以使用 Actions 面板中的“uses”选项灵活地更改您使用的 Action。
以下是我们提供的选项的概要
- 标签:顾名思义,这是 Action 的名称。此名称由工作流中的
resolves
数组引用——这就是在它们之间建立连接的方式。这部分在 GUI 中是抽象的,但是您将在下一节看到,如果您是在代码中工作,则需要保持引用相同,以使链接正常工作。 - 运行 允许您覆盖入口点。这非常棒,因为如果您想在容器中运行诸如
git
之类的东西,您可以这样做! - 参数:这是您所期望的——它允许您将参数传递给容器。
- secrets 和 env:它们都非常重要,因为这是您在不直接将它们提交到存储库的情况下使用密码和保护数据的方式。如果您使用需要一个令牌进行部署的工具,您可能会在这里使用一个 secret 来传递该令牌。
许多这些 Actions 都有自述文件,告诉您需要什么。通常,“secrets”和“env”的设置类似于以下内容
action "deploy" {
uses = ...
secrets = [
"THIS_IS_WHAT_YOU_NEED_TO_NAME_THE_SECRET",
]
}
您也可以在这个 GUI 中将多个 Actions 串联在一起。一次运行一个 Action 或并行运行都很容易。这意味着您可以通过在界面中将它们链接在一起来轻松地运行异步代码。
在代码中编写 Action
那么,如果这里显示的任何 Action 都不是我们想要的呢?幸运的是,编写 Actions 真的很棒!我编写了一个 Action 来将 Node.js Web 应用程序部署到 Azure,因为这将使我能够在每次推送到存储库的主分支时进行部署。这太有趣了,因为现在我可以将它重新用于我剩余的 Web 应用程序。开心的 Sarah!
创建应用程序服务帐户
如果您使用的是其他服务,这部分将会有所不同,但是您确实需要在您要部署的任何服务中创建一个现有服务。
首先,您需要获取您的 免费 Azure 帐户。我喜欢使用 Azure CLI,所以如果您还没有安装它,您可以运行
brew update && brew install azure-cli
然后,我们将通过运行以下命令登录到 Azure
az login
现在,我们将通过运行以下命令创建一个 服务主体
az ad sp create-for-rbac --name ServicePrincipalName --password PASSWORD
它将向我们传递以下输出,我们将使用它来创建我们的 Action
{
"appId": "APP_ID",
"displayName": "ServicePrincipalName",
"name": "http://ServicePrincipalName",
"password": ...,
"tenant": "XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
Action 中包含什么?
以下是一个工作流和 Action 的基本示例,以便您可以看到它的基本结构
workflow "Name of Workflow" {
on = "push"
resolves = ["deploy"]
}
action "deploy" {
uses = "actions/someaction"
secrets = [
"TOKEN",
]
}
我们可以看到,我们启动了工作流,并指定我们希望它在 **推送** 时运行 (on = "push"
)。您还可以使用许多其他选项,完整的列表在此处。
它下面的 **resolves** 行 resolves = ["deploy"]
是一个数组,其中包含将在工作流之后链接的 Action。这没有指定顺序,而是一个所有项目的完整列表。您可以看到我们在“deploy”之后调用了 Action——这些字符串需要匹配,这就是它们相互引用的方式。
接下来,我们将查看该 **action** 块。第一个 **uses** 行非常有趣:从一开始,您就可以使用我们之前提到的任何预定义 Action(所有 Action 的列表在此处)。但是您也可以使用其他人的存储库,甚至使用托管在 Docker 网站上的文件。例如,如果我们想要在一个容器中执行 git,我们将使用这个。我可以用以下方法做到这一点:uses = "docker://alpine/git:latest"
。(感谢 Matt Colyer 为我指明了正确的 URL。)
我们可能需要在此处定义一些 secrets 或环境变量,我们将像这样使用它们
action "Deploy Webapp" {
uses = ...
args = "run some code here and use a $ENV_VARIABLE_NAME"
secrets = ["SECRET_NAME"]
env = {
ENV_VARIABLE_NAME = "myEnvVariable"
}
}
创建自定义 Action
我们将使用自定义操作来执行通常用于将 Web 应用部署到 Azure 的命令,并将它们编写成只需传入几个值就能执行所有操作的方式。这些文件看起来比实际复杂,我们实际上是在之前在 GUI 中看到的第一个 Azure 基本操作的基础上构建的。
在 entrypoint.sh 中
#!/bin/sh
set -e
echo "Login"
az login --service-principal --username "${SERVICE_PRINCIPAL}" --password "${SERVICE_PASS}" --tenant "${TENANT_ID}"
echo "Creating resource group ${APPID}-group"
az group create -n ${APPID}-group -l westcentralus
echo "Creating app service plan ${APPID}-plan"
az appservice plan create -g ${APPID}-group -n ${APPID}-plan --sku FREE
echo "Creating webapp ${APPID}"
az webapp create -g ${APPID}-group -p ${APPID}-plan -n ${APPID} --deployment-local-git
echo "Getting username/password for deployment"
DEPLOYUSER=`az webapp deployment list-publishing-profiles -n ${APPID} -g ${APPID}-group --query '[0].userName' -o tsv`
DEPLOYPASS=`az webapp deployment list-publishing-profiles -n ${APPID} -g ${APPID}-group --query '[0].userPWD' -o tsv`
git remote add azure https://${DEPLOYUSER}:${DEPLOYPASS}@${APPID}.scm.azurewebsites.net/${APPID}.git
git push azure master
关于此文件,需要注意一些有趣的事项
set -e
在 shell 脚本中将确保如果任何东西发生故障,文件其余部分不会继续执行。- “获取用户名/密码”后面的几行看起来有点复杂,实际上它们是在从 Azure 的发布配置文件中提取用户名和密码。然后,我们可以将其用于添加远程的下一行代码。
- 您可能还会注意到,在这些行中,我们传入了
-o tsv
,这是我们为格式化代码所做的操作,这样我们就可以将其直接传递到环境变量中,因为 tsv 会去除多余的标题等。
现在我们可以处理我们的 main.workflow
文件了!
workflow "New workflow" {
on = "push"
resolves = ["Deploy to Azure"]
}
action "Deploy to Azure" {
uses = "./.github/azdeploy"
secrets = ["SERVICE_PASS"]
env = {
SERVICE_PRINCIPAL="http://sdrasApp",
TENANT_ID="72f988bf-86f1-41af-91ab-2d7cd011db47",
APPID="sdrasMoonshine"
}
}
工作流部分应该看起来很熟悉,它在推送时启动并解析为名为“部署到 Azure”的操作。
uses
指向目录内,这是我们存放另一个文件的地方。我们需要添加一个秘密,以便我们可以存储应用程序的密码。我们将此服务称为服务密码,我们可以通过转到此处并在设置中添加它来进行配置。

最后,我们拥有运行命令所需的所有环境变量。我们从前面的部分获得了所有这些变量,我们在该部分创建了我们的应用服务帐户。来自前面的 tenant
变成 TENANT_ID
,name
变成 SERVICE_PRINCIPAL
,APPID
实际上是您想为其命名的任何内容:)
您也可以使用此操作!所有代码都在此存储库中开源。请记住,由于我们手动创建了 main.workflow
,因此您也必须手动编辑 main.workflow
文件中的环境变量 - 一旦您停止使用 GUI,它就不再以相同的方式工作了。
在这里,您可以看到一切都很好地部署了,变成了绿色,我们拥有了很棒的“Hello World”应用程序,它会在我们每次推送到 master 分支时重新部署🎉


游戏规则改变
GitHub 操作不仅仅是关于网站的,尽管您可以看到它们对于网站来说是多么方便。这是一种关于我们如何处理基础设施、事件甚至托管的全新思维方式。考虑一下此模型中的 Docker。
通常,当您创建 Dockerfile 时,您需要编写 Dockerfile、使用 Docker 构建镜像,然后将镜像推送到某个地方以便将其托管供其他人下载。在此范式中,您可以将其指向包含现有 Dockerfile 的 git 存储库,或指向直接托管在 Docker 上的内容。
您也不需要在任何地方托管镜像,因为 GitHub 会在您需要时为您构建它。这将所有内容都保留在 GitHub 生态系统中,这对开源来说非常重要,并且可以更容易地进行分叉和共享。您也可以将 Dockerfile 直接放在您的操作中,这意味着您不必为这些 Dockerfile 维护单独的存储库。
总而言之,这非常令人兴奋。部分原因在于其灵活性:一方面,您可以选择进行大量抽象,并使用 GUI 和现有操作创建您需要的工作流程,另一方面,您可以自己编写代码,在容器内构建和微调任何您想要的内容,甚至将多个可重复使用的自定义操作链接在一起。所有这些都在您托管代码的同一位置。
太棒了<3
这太棒了。迫不及待地想试试。
所以,几个问题。如果我错过了明显的东西,请原谅我。
1) 关于 Azure 的 GitHub 操作的第一部分。我有点困惑。它到底做了什么?你说了吗,因为我认为我错过了?你转到展示部署,但那第一件事本身是为了做一些事情吗?
2) 为什么秘密是数组?我的意思是与简单的哈希相比,这样您就可以将某种标签与秘密相关联。
秘密看起来是命名数组,因为您将该文件提交到 GitHub,任何人都可以查看它。我认为您在操作界面中的某个地方输入秘密值(以及名称,以便可以匹配),GitHub 在该界面中单独存储这些值,并仅向管理员提供访问权限。
秘密是工作流文件中的标签数组,因为这些值不包含在其中(您不希望将秘密提交到存储库中,而工作流文件位于存储库中)。当您在 GitHub.com 或 Actions UI 中创建秘密时,该值将在您的浏览器中加密,然后再进行存储,它只在操作运行时对操作可用。
哦,哇。所以,如果我理解正确,是否可以通过 GitHub 操作直接通过 ssh 部署网站,而不是使用 Deploybot 等服务?
太棒了,这对我的项目真的很重要。将所有内容都集中在一个地方。
感谢您的示例,Sarah。一个小小的注释:在“设置您的第一个操作”部分之前的句子中,您写道,“这对开源的可能性来说是一个全新的问题”。我认为您不应该在这里使用“问题”,它表示“可能令人尴尬或难堪的复杂问题”。希望 GitHub 操作不会成为一个问题!:-)
作为不使用 Azure 的人,我对实际的部署部分有点困惑。
看起来诀窍在于使用
--deployment-local-git
参数的az webapp create
命令。这将在您的 Node Web 应用根目录中创建一个 .git 存储库。GitHub 操作随后会将新代码推送到此存储库。我很高兴 GitHub 赶上了 Gitlab。我喜欢使用容器创建您自己的构建步骤的灵活性。没有意见化的作业和管道!