【Node】如何用 Webhook 实现 CI/CD

CI 持续集成: 代码提交后自动构建和测试 CD 持续部署: 测试通过后自动部署到目标环境

关于 CI/CD 有多种方式,比如

  • 基于工具的 CI/CD
    • Jenkis
    • GitLab CI/CD
    • Github Actions
    • CircleCI
    • Travis CI
  • 容器化 CI/CD
    • 使用 Docker 实现 CI/CD, 使用 Dokcerfile 定义构建环境
    • 在 CI/CD 构建容器镜像并推送到镜像仓库(Dokcer Hub、 AWS ECR)
    • 通过 Kunbernetes 或者其他容器编排工具实现自动化部署
  • 无服务器(Serverless) CI/CD
  • 蓝绿部署与金丝雀
  • 使用 webhook

WebHook

Webhook 是一种基于 HTTP 的通信机制,通常被用作一种事件驱动的集成方式。它在 CI/CD 中也扮演重要角色,尤其是在自动化流程的触发环节。简单来说,Webhook 是"反向 API",它允许一个系统在特定事件发生时主动向另一个系统发送实时通知,而不是让后者不断轮询检查状态

Webhook 的工作原理

  1. 事件触发:当某个系统发生特定事件(例如代码提交、构建完成)时,会生成一个事件。
  2. HTTP 请求:该系统通过 HTTP POST 请求将事件数据(通常是 JSON 格式)发送到一个预先配置的 URL(即 Webhook 的目标地址)。
  3. 接收与处理:目标系统接收到请求后,根据数据执行相应操作,比如触发构建、部署或发送通知。

在 CI/CD 中的应用

Webhook 常用于连接代码仓库与 CI/CD 工具,典型场景包括:

  • 代码提交触发构建:例如,GitHub 或 GitLab 在代码推送(Push)或合并请求(Pull Request)发生时,通过 Webhook 通知 Jenkins 或 GitLab CI,开始构建和测试。

  • 状态反馈:CI/CD 工具完成任务后,可以通过 Webhook 将结果(成功/失败)发送给其他系统,比如通知 Slack 或更新代码仓库的状态。

  • 外部服务集成:比如部署完成后,通过 Webhook 通知监控系统或日志系统。

我的实战当中没有利用 jenkis, 因为我这是个小型项目。如果是复杂的场景,可以配置 Webhook 到 Jenkins,然后在 Jenkins 定义完整的流水线

WebHook + 自定义脚本

1、 在【宝塔 Linux】安装 Webhook

添加 hook ,输入CI/CD的脚本(拉取代码、build、start)

bash 复制代码
#!/bin/bash

# 定义变量
REPO_PATH="xx"
FRONTEND_PATH="xx"
REPO_URL="your github url"

# 日志文件
LOG_FILE="/var/log/deploy.log"
echo "$(date) - 开始部署" >> $LOG_FILE
echo "当前用户: $(whoami)" >> $LOG_FILE
echo "PATH: $PATH" >> $LOG_FILE

# 确认 pnpm 可用性
echo "测试 pnpm 版本..." >> $LOG_FILE
/www/server/nodejs/v23.7.0/bin/pnpm -v >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "错误: 无法运行 pnpm" >> $LOG_FILE
    exit 1
fi

# 检查仓库目录是否存在
echo "检查仓库目录..." >> $LOG_FILE
if [ ! -d "$REPO_PATH" ]; then
    echo "仓库目录 $REPO_PATH 不存在,执行 git clone..." >> $LOG_FILE
    mkdir -p $REPO_PATH
    cd $REPO_PATH
    git clone $REPO_URL . >> $LOG_FILE 2>&1
    if [ $? -ne 0 ]; then
        echo "错误: git clone 失败" >> $LOG_FILE
        exit 1
    fi
else
    # 切换到仓库目录
    cd $REPO_PATH
    # 确保是 Git 仓库
    if [ ! -d ".git" ]; then
        echo "目录 $REPO_PATH 不是 Git 仓库,执行 git init 并关联远程仓库..." >> $LOG_FILE
        git init >> $LOG_FILE 2>&1
        git remote add origin $REPO_URL >> $LOG_FILE 2>&1
    fi
    # 拉取最新代码
    echo "拉取最新代码..." >> $LOG_FILE
    git fetch origin >> $LOG_FILE 2>&1
    git reset --hard origin/main >> $LOG_FILE 2>&1
    if [ $? -ne 0 ]; then
        echo "错误: git pull 失败" >> $LOG_FILE
        exit 1
    fi
fi

# 检查前端目录是否存在
echo "检查前端目录..." >> $LOG_FILE
if [ ! -d "$FRONTEND_PATH" ]; then
    echo "错误: 前端目录 $FRONTEND_PATH 不存在" >> $LOG_FILE
    exit 1
fi

# 切换到前端目录
cd $FRONTEND_PATH

# 安装前端依赖
echo "运行 pnpm install (前端)..." >> $LOG_FILE
/www/server/nodejs/v23.7.0/bin/pnpm install >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "错误: 前端 pnpm install 失败" >> $LOG_FILE
    exit 1
fi

# 构建前端
echo "运行 pnpm run build (前端)..." >> $LOG_FILE
/www/server/nodejs/v23.7.0/bin/pnpm run build >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "错误: 前端 pnpm run build 失败" >> $LOG_FILE
    exit 1
fi
chown -R www:www $FRONTEND_PATH
echo "前端构建完成" >> $LOG_FILE

# 启动前端服务
echo "启动前端服务 .." >> $LOG_FILE
# 检查前端进程是否存在
if /www/server/nodejs/v23.7.0/bin/pm2 list | grep -q "nanlan-blog-client"; then
    echo "删除现有 nanlan-blog-client 进程..." >> $LOG_FILE
    /www/server/nodejs/v23.7.0/bin/pm2 delete nanlan-blog-client >> $LOG_FILE 2>&1
    if [ $? -ne 0 ]; then
        echo "错误: 删除 nanlan-blog-client 进程失败" >> $LOG_FILE
        exit 1
    fi
else
    echo "nanlan-blog-client 进程不存在,跳过删除..." >> $LOG_FILE
fi
/www/server/nodejs/v23.7.0/bin/pm2 start pnpm --name nanlan-blog-client -- start  >> $LOG_FILE 2>&1
if [ $? -ne 0 ]; then
    echo "错误: 前端 pnpm start 失败" >> $LOG_FILE
    exit 1
fi
echo "前端服务启动完成" >> $LOG_FILE

2、 设置 Webhook 触发器

上述步骤完成之后,会有 web hook url

将这个 url 拷贝,到 github 去设置 Webhook

设置 payload url、 trigger event、content type

3、 测试

只要往 github push 代码,就能自动触发 CI/CD 流程

相关推荐
Mintopia18 分钟前
计算机图形学学习指南
前端·javascript·计算机图形学
Mintopia19 分钟前
three.js 中的动画(animation)
前端·javascript·three.js
AI大模型顾潇21 分钟前
[特殊字符] Prompt如何驱动大模型对本地文件实现自主变更:Cline技术深度解析
前端·人工智能·llm·微调·prompt·编程·ai大模型
小小小小宇32 分钟前
React中 useEffect和useLayoutEffect源码原理
前端
AlexJee34 分钟前
在vue3中使用vue-cropper完成头像裁剪上传图片功能
前端
清晨細雨36 分钟前
uniapp微信小程序:WIFI设备配网之TCP/UDP开发AP配网
前端·物联网·小程序·uni-app
阿廖沙102437 分钟前
Rust核心概念
前端
阿廖沙102439 分钟前
🚀 从“值放哪了”聊起:Rust 内存管理通透讲解(适合前端工程师)
前端
打野赵怀真40 分钟前
如何提高前端应用的性能?
前端·javascript