如何使用 GitHub Actions 为 Node.js 应用设置 CI/CD 流水线
GitHub Actions
GitHub Actions是一款工具/服务,它可以通过创建 CI/CD 流水线来测试、构建和部署代码。它像Jenkins、GitLab CI等其他工具/服务一样,可以帮助您实现工作流程自动化。GitHub Actions 使用YAML作为编写作业/步骤的语言,这些作业/步骤会在特定事件发生时执行。它可以用于多种用途,例如部署 Web 服务、构建容器应用程序、将软件包发布到注册表,或者自动欢迎新用户加入您的开源项目。对我来说,GitHub Actions 最强大的功能是矩阵构建(在本教程中,我也使用它进行演示)。这意味着您可以运行工作流程,同时在多个操作系统和运行时版本上进行测试。(例如,您可以在 Windows、Mac 和 Linux 上运行工作流程,并使用 NodeJS 8.x 和 10.x 版本。)
我们要建造什么?
我们将构建一个简单的 NodeJS 应用并将其托管(本指南中我将使用 DigitalOcean 实例,您可以根据自己的喜好选择)。本指南将向您展示如何配置和使用 GitHub Actions 将 NodeJS 应用部署到您的服务器。每当您更改代码并推送时,GitHub 都会触发一个事件,并开始执行我们预先设定的操作。在这里,我们将安装依赖项,运行我们编写的测试,如果所有测试都通过,GitHub Actions 会将应用部署到服务器。此外,我们还将运行矩阵构建。这意味着我们将在多个 NodeJS 版本上运行测试(您也可以使用多个操作系统)。这将帮助我们确认应用在多个操作系统和多个 NodeJS 版本上都能正常运行。
创建一个 NodeJS 应用
本指南的第一部分,我们将在本地创建一个 NodeJS 应用程序。这里我们创建一个简单的应用程序,它会返回“Hello World”文本。首先,我们需要创建一个 GitHub 仓库。下面的截图展示了我的创建过程。您可以根据需要更改设置,例如设置仓库的私有/公开访问权限。
现在让我们克隆这个仓库并进入它:
git clone [git@github.com](mailto:git@github.com):<username>/node-github-demo.git
cd node-github-demo
然后运行以下命令创建package.json文件,添加所需的依赖项和其他内容,再运行以下命令安装依赖项。以下是我们使用的一些软件包的说明。
npm init // fill the required things CLI asked
npm i express
npm i mocha supertest --save-dev
-
express:Node框架
-
mocha:NodeJS 测试框架(您也可以选择其他测试框架,例如 Jasmin、Jest、Tape 等)。
-
supertest:为 HTTP 测试提供高级抽象。
npm 安装
好了,现在一切准备就绪。让我们创建一个名为index.js 的文件,用来编写创建 Express 服务器的代码,并将“Hello World”文本显示为“/”端点的响应。
// importing express framework
const express = require("express");
const app = express();
// Respond with "hello world" for requests that hit our root "/"
app.get("/", function (req, res) {
return res.send("Hello World");
});
// listen to port 7000 by default
app.listen(process.env.PORT || 7000, () => {
console.log("Server is running");
});
module.exports = app;
现在您可以使用以下命令运行上述代码。然后访问http://localhost:7000查看“Hello World”输出。
node index.js
编写测试用例
现在我们要编写测试用例来验证“/”端点的响应是否等于“Hello World”。为此,我们创建一个名为“/test/”的文件夹,并在其中创建一个名为“test.js”的文件test.js。现在,让我们编写如下的测试代码。
const request = require("supertest");
const app = require("../index");
describe("GET /", () => {
it("respond with Hello World", (done) => {
request(app).get("/").expect("Hello World", done);
})
});
要运行测试,请将以下内容添加到您的package.json文件中。
"scripts": {
"test": "mocha ./test/* --exit"
}
现在只需运行以下命令来运行你编写的测试用例,看看是否通过。
npm test
以下是输出结果。
现在我们可以将更改推送到我们创建的 GitHub 仓库了。在此之前,请创建一个.gitignore文件,并将需要从 Git 仓库中忽略的文件/文件夹添加到其中。以下是我在本指南中使用的.gitignore 文件示例。现在让我们将文件推送到 GitHub。
git add .
git commit -m "node app with test cases"
git push origin master
创建我们的服务器(DigitalOcean)
好了,现在我们已经完成了 NodeJS 应用的编写,接下来需要创建一个服务器来部署它,以便向全世界提供服务。正如我之前提到的,本指南将使用DigitalOcean Droplet。下面的截图将展示在DigitalOcean中创建 Droplet 时需要填写哪些信息,以及创建完成后的样子。在本指南中,我使用的是DigitalOcean Marketplace提供的现有 NodeJS 镜像 Droplet。您也可以通过导航至“创建(顶部栏)”->“Droplet”->“Marketplace ”来完成相同的操作。
注意:如果您创建 Droplet 时选择SSH 密钥作为身份验证选项,则需要将本地计算机的 SSH 密钥添加到 Droplet。为此,请先生成密钥,然后复制并粘贴* (要粘贴,请单击“新建 SSH 密钥”按钮) *。要生成并获取 SSH 密钥副本,请运行以下命令。
注意:这里我使用的是 Linux 系统。如果您使用的是其他操作系统,操作步骤会略有不同。此方法在 Linux 和 Mac 系统上均有效。
ssh-keygen -t rsa
cat ~/.ssh/id_rsa.pub
在服务器上部署 NodeJS 应用
现在我们需要将应用程序部署到 DigitalOcean 服务器上。为此,我们将创建一个新用户。
ssh root@SERVER.IP
adduser <lastname>
usermod -a -G sudo <username>
su — username
运行以下命令,即可授予该用户通过 SSH 无密码登录权限。然后,您可以通过运行 ssh @SERVER.IP 轻松登录服务器。
cd
mkdir .ssh
chmod 700 .ssh/
vim ~/.ssh/authorized_keys # here paste your local ssh key as we did earlier
chmod 600 ~/.ssh/*
现在在服务器上安装 Git。然后拉取源代码并在服务器上运行。
sudo apt-get install git
ssh-keygen
cat ~/.ssh/id_rsa.pub #copy the text
现在我们已经复制了新的用户 SSH 密钥。只需将其粘贴为 GitHub 仓库部署密钥。然后克隆仓库并在服务器上运行它。
git clone [git@github.com](mailto:git@github.com):<username>/node-github-demo.git
cd node-github-demo
npm install --production
sudo ufw allow 7000 # this will open port 7000 to access via web
sudo npm install pm2 -g
pm2 start index.js --name node-app
现在我们的应用通过 PM2 作为 node 应用运行。我刚刚访问了http://SERVER.IP:7000来验证这一点。
在 GitHub Actions 上创建 CI/CD 流水线
首先,添加以下密钥以用于 GitHub Actions 工作流脚本。要获取 SSH_KEY,只需在已拥有 DigitalOcean 服务器访问权限的本地计算机上运行以下命令。然后复制命令内容并将其值粘贴到 SSH_KEY 密钥中。
cat ~/.ssh/id_rsa
现在我们可以创建 GitHub Actions CI/CD 流水线了。只需转到代码仓库,然后点击“Actions”选项卡即可。
点击“Node.js 设置工作流”按钮,它将打开一个文本编辑器。粘贴以下 yml 文件内容。
name: Node Github CI
on:
push:
branches:
- master
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [8.x, 10.x, 12.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: npm install and test
run: |
npm install
npm test
env:
CI: true
deploy:
needs: [test]
runs-on: ubuntu-latest
steps:
- name: SSH and deploy node app
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USERNAME }}
key: ${{ secrets.SSH_KEY }}
port: ${{ secrets.SSH_PORT }}
script: |
cd ~/node-github-demo
git pull origin master
npm install --production
pm2 restart node-app
我将解释上述YAML内容。
第 1 行:`name` 设置工作流名称。
第 3-6 行:`on` 将检查我们需要运行作业的 Git 事件。这里我们设置了当有内容推送到 master 分支时,运行以下作业(在本例中是 test 和 deploy)。
第 8-28 行:在 `jobs` 中,我们创建了一个名为 test 的作业。通过设置 `runs-on`,我们可以设置运行器。在本例中,我们将其设置为 ubuntu-latest。如果需要,我们也可以使用 Windows 和 Mac。通过设置 `astrategy`,我们可以设置构建矩阵。目前,它用于在不同的 Node 版本下运行此 test 作业。在 `setps` 下,我们可以设置需要在特定作业(在本例中为 test 作业)上运行的不同任务。
uses: actions/checkout@v2
通过设置使用方式,我们可以运行不同的操作。在上面的例子中,我们检出了仓库的一个副本。在下一行,我们为这个任务设置了一个名称。在下一行,我们使用了带有 v1 git 标签的 setup-node 操作。此外,我们还为操作传递了一个名为 node-version 的输入参数。在这种情况下,对于矩阵构建,我们需要动态设置该版本。
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
下一行,我们也为该任务设置了名称。之后,通过设置 `run`,我们在操作系统 shell 中运行了多个命令。在本例中,操作系统是 Ubuntu。通过设置 `env`,我们将 CI 环境变量设置为 true(我们可以根据需要设置任何其他环境变量)。
第 30-46 行:我们创建了另一个名为 `deploy` 的作业。在这种情况下,我们也使用了与上面相同的语法。唯一新用到的是 `needs`。它用于指定只有特定的一个或多个作业通过后才运行此作业。在本例中,`deploy` 作业仅在测试作业通过后运行。
这里我们使用了另一个名为 `appleboy/ ssh-action@master`的 GitHub Action 。它需要一些输入参数,我们已经设置好了。(在本例中,这些参数包括 SSH 主机、密钥、用户名、端口以及通过 SSH 连接到服务器后需要在服务器上运行的脚本)。
然后点击“开始提交”并提交更改。现在脚本会运行,以查看更改。让我们修改源代码并将其推送到主分支。
您可以看到我们的测试失败了,因为它没有运行部署。我们在工作流 yml 文件中设置了……
deploy:
needs: [test]
这样一来,部署作业只有在测试作业通过后才会运行。因此,我们现在可以更新测试并重新检查它。
是的,现在可以了!部署任务也运行成功了。我们可以通过访问 toSERVER.IP:7000 来查看更改。
注意:本教程中使用了GitHub Actions的 matrixbuild。这意味着它会在不同的 NodeJS 版本上运行测试(在本例中)。我们也可以将其扩展到在不同操作系统上的不同 NodeJS 版本上运行。点击此处了解更多信息。
https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions
https://help.github.com/en/actions/language-and-framework-guides/using-nodejs-with-github-actions
特别感谢appleboy创建了 ssh-deploy Github action。
如有任何疑问,请告诉我。
源代码
在Twitter上关注我,在LinkedIn 上
与我联系。在 Twitter 上关注我,在LinkedIn上与我联系。
原文发表于Medium
文章来源:https://dev.to/chathula/how-to-set-up-a-ci-cd-pipeline-for-a-node-js-app-with-github-actions-32h0














