发布于 2026-01-05 4 阅读
0

如何使用 GitHub Actions 为 Node.js 应用设置 CI/CD 流水线

如何使用 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
Enter fullscreen mode Exit fullscreen mode

然后运行以下命令创建package.json文件,添加所需的依赖项和其他内容,再运行以下命令安装依赖项。以下是我们使用的一些软件包的说明。

npm init // fill the required things CLI asked
npm i express
npm i mocha supertest --save-dev
Enter fullscreen mode Exit fullscreen mode
  • 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;
Enter fullscreen mode Exit fullscreen mode

现在您可以使用以下命令运行上述代码。然后访问http://localhost:7000查看“Hello World”输出。

node index.js
Enter fullscreen mode Exit fullscreen mode

编写测试用例

现在我们要编写测试用例来验证“/”端点的响应是否等于“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);
      })
    });
Enter fullscreen mode Exit fullscreen mode

要运行测试,请将以下内容添加到您的package.json文件中。

"scripts": {
    "test": "mocha ./test/* --exit"
}
Enter fullscreen mode Exit fullscreen mode

现在只需运行以下命令来运行你编写的测试用例,看看是否通过。

npm test
Enter fullscreen mode Exit fullscreen mode

以下是输出结果。

现在我们可以将更改推送到我们创建的 GitHub 仓库了。在此之前,请创建一个.gitignore文件,并将需要从 Git 仓库中忽略的文件/文件夹添加到其中。以下是我在本指南中使用的.gitignore 文件示例。现在让我们将文件推送到 GitHub。

git add .
git commit -m "node app with test cases"
git push origin master
Enter fullscreen mode Exit fullscreen mode

创建我们的服务器(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
Enter fullscreen mode Exit fullscreen mode

在服务器上部署 NodeJS 应用

现在我们需要将应用程序部署到 DigitalOcean 服务器上。为此,我们将创建一个新用户。

ssh root@SERVER.IP
adduser <lastname>
usermod -a -G sudo <username>
su — username
Enter fullscreen mode Exit fullscreen mode

运行以下命令,即可授予该用户通过 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/*
Enter fullscreen mode Exit fullscreen mode

现在在服务器上安装 Git。然后拉取源代码并在服务器上运行。

sudo apt-get install git
ssh-keygen
cat ~/.ssh/id_rsa.pub #copy the text
Enter fullscreen mode Exit fullscreen mode

现在我们已经复制了新的用户 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
Enter fullscreen mode Exit fullscreen mode

现在我们的应用通过 PM2 作为 node 应用运行。我刚刚访问了http://SERVER.IP:7000来验证这一点。

应用正在运行!应用正在运行!

在 GitHub Actions 上创建 CI/CD 流水线

首先,添加以下密钥以用于 GitHub Actions 工作流脚本。要获取 SSH_KEY,只需在已拥有 DigitalOcean 服务器访问权限的本地计算机上运行以下命令。然后复制命令内容并将其值粘贴到 SSH_KEY 密钥中。

cat ~/.ssh/id_rsa
Enter fullscreen mode Exit fullscreen mode

现在我们可以创建 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
Enter fullscreen mode Exit fullscreen mode

我将解释上述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
Enter fullscreen mode Exit fullscreen mode

通过设置使用方式,我们可以运行不同的操作。在上面的例子中,我们检出了仓库的一个副本。在下一行,我们为这个任务设置了一个名称。在下一行,我们使用了带有 v1 git 标签的 setup-node 操作。此外,我们还为操作传递了一个名为 node-version 的输入参数。在这种情况下,对于矩阵构建,我们需要动态设置该版本。

    uses: actions/setup-node@v1
    with:
      node-version: ${{ matrix.node-version }}
Enter fullscreen mode Exit fullscreen mode

下一行,我们也为该任务设置了名称。之后,通过设置 `run`,我们在操作系统 shell 中运行了多个命令。在本例中,操作系统是 Ubuntu。通过设置 `env`,我们将 CI 环境变量设置为 true(我们可以根据需要设置任何其他环境变量)。
第 30-46 行:我们创建了另一个名为 `deploy` 的作业。在这种情况下,我们也使用了与上面相同的语法。唯一新用到的是 `needs`。它用于指定只有特定的一个或多个作业通过后才运行此作业。在本例中,`deploy` 作业仅在测试作业通过后运行。
这里我们使用了另一个名为 `appleboy/ ssh-action@master`的 GitHub Action 。它需要一些输入参数,我们已经设置好了。(在本例中,这些参数包括 SSH 主机、密钥、用户名、端口以及通过 SSH 连接到服务器后需要在服务器上运行的脚本)。

然后点击“开始提交”并提交更改。现在脚本会运行,以查看更改。让我们修改源代码并将其推送到主分支。

您可以看到我们的测试失败了,因为它没有运行部署。我们在工作流 yml 文件中设置了……

    deploy:
        needs: [test]
Enter fullscreen mode Exit fullscreen mode

这样一来,部署作业只有在测试作业通过后才会运行。因此,我们现在可以更新测试并重新检查它。

是的,现在可以了!部署任务也运行成功了。我们可以通过访问 toSERVER.IP:7000 来查看更改。

注意:本教程中使用了GitHub Actions的 matrixbuild。这意味着它会在不同的 NodeJS 版本上运行测试(在本例中)我们也可以将其扩展到在不同操作系统上的不同 NodeJS 版本上运行。点击此处了解更多信息。

参考资料: https ://medium.com/@mosheezderman/how-to-set-up-ci-cd-pipeline-for-a-node-js-app-with-jenkins-c51581cc783c

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