使用github的webhook实现自动化部署

前言:

我们原始的项目部署方式,是在本地打包之后,手动上传到服务器。这篇文章主要记录,我使用github上面的webhook来实现:当你push代码之后,项目就开始自动部署。

环境

linux

node

pm2

  1. 首先进入服务器
1
2
3
4
5
mkdir /var/webhooks/
cd /var/webhooks/
npm init -y
npm i express body-parser crypto child_process
vi webhooks-blog-nest.js
  1. 完成webhooks-blog-nest.js内容
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
const express = require('express');
const bodyParser = require('body-parser');
const crypto = require('crypto');
const { exec } = require('child_process');

const app = express();
const PORT = 3001; // 监听端口
const SECRET = '*******'; // 与 GitHub Webhook Secret 保持一致

// 解析 JSON 数据
app.use(bodyParser.json());

// 校验 GitHub Webhook 请求的签名
function verifySignature(req) {
const signature = `sha256=${crypto
.createHmac('sha256', SECRET)
.update(JSON.stringify(req.body))
.digest('hex')}`;
return signature === req.headers['x-hub-signature-256'];
}

// 处理 Webhook 请求
app.post('/webhook', (req, res) => {
if (!verifySignature(req)) {
res.status(401).send('Invalid signature');
return;
}

console.log('Received Webhook event');

// 执行部署脚本
exec('bash /var/www/blog-react/deploy.sh', (err, stdout, stderr) => {
if (err) {
console.error(`Deploy failed: ${stderr}`);
res.status(500).send('Deploy failed');
return;
}
console.log(`Deploy succeeded: ${stdout}`);
res.status(200).send('Deployed successfully ^^');
});
});

// 启动服务器
app.listen(PORT, () => {
console.log(`Webhook server running on port ${PORT}`);
});
  1. 在你的项目下新建部署文件deploy.sh
1
2
cd /var/www/blog-react/
vi deploy.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# deploy.sh
#!/bin/bash

#echo "Current user: $(whoami)" >> /var/log/webhook-user.log
echo "开始部署 NestJS 项目..."
cd /var/www/blog-react/
git config --global --add safe.directory /var/www/blog-react
# 处理本地修改并拉取最新代码
git stash && git pull && git stash pop

# 停止当前服务(如果运行中)
pm2 stop blog-react || true

# 拉取最新代码
git pull origin main

# 安装依赖
yarn

# 移除旧版本
#rm -rf dist/

#pwd
# 构建项目
yarn build

# 重启服务
pm2 start dist/main.js --name blog-react

echo "部署完成!"

如果没有pm2先下载npm install -g pm2

  1. 打开github,进入你需要部署的项目,顶部有一排选项,找到settings

  2. 进入settings之后,点击左侧导航栏webhook,然后点击右上角 add webhook

  3. 显示add表单后,填写payload url: (你自己的webhook服务地址类似:https://xxx.com:443/webhook/blog-react),content-type选择json,自定义你的secret(记录下来这个secret,后面有用),启用ssl verification,选择just the push event(只当你push的时候出发部署),点击保存 dansroh-scecret-blog-react-adlic8asi3

  4. 再次进入服务器,编辑deploy.sh,将你填写的secret复制到secret那里

  5. 编辑nginx配置,代理webhook服务,并重启nginx

1
2
3
4
5
6
location /webhook/blog-react{
proxy_pass http://127.0.0.1:3002; # 使用pm2启动webhook服务的端口
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
  1. 使用pm2 启动webhook服务

pm2 start /var/webhooks/webhook-blog-react.js --env PORT 3002

至此,完成