本案例详细介绍了如何实现本地git push到Gitee仓库后,触发Gitee webhook,并在服务器端执行相应的shell脚本。以下是具体步骤:
准备工作
服务器端:
安装Node.js环境,确保服务器能够运行Node.js应用程序。
本地:
安装并配置Git,确保可以与远程Gitee仓库进行交互。
服务器端配置
创建Node项目:
初始化一个新的Node项目,并安装必要的依赖包(如
express
、body-parser
、crypto
和winston
)。创建一个名为
index.js
的文件,用于监听来自Gitee的webhook请求。
const { exec } = require('child_process'); const express = require('express'); const bodyParser = require('body-parser'); const crypto = require('crypto'); const winston = require('winston'); // 配置日志记录 const logger = winston.createLogger({ level: 'info', format: winston.format.combine( winston.format.timestamp(), winston.format.json() ), transports: [ new winston.transports.Console(), new winston.transports.File({ filename: 'error.log', level: 'error' }), new winston.transports.File({ filename: 'combined.log' }) ] }); const app = express(); const secret = 'shieru'; // 使用环境变量存储密钥 // 配置body-parser中间件,用于解析请求体 app.use(bodyParser.json({ verify: (req, res, buf) => { req.rawBody = buf; } })); // 生成签名密钥,签名算法为sha256,官网算法说明:https://gitee.com/help/articles/4290 function generateSignature(secret, timestamp) { const stringToSign = `${timestamp}\n${secret}`; const hmac = crypto.createHmac('sha256', secret); return hmac.update(stringToSign).digest('base64'); } // 验证签名 function verifySignature(req) { // 获取请求头中的时间戳 const timestamp = req.headers['x-gitee-timestamp']; // 获取请求头中的签名和token const token = req.headers['x-gitee-token']; if (!timestamp || !token) { return false; } const expectedToken = generateSignature(secret, timestamp); return expectedToken === token; } // 处理POST请求 app.post('/update', (req, res) => { try { // 检查请求头中是否包含 git-oschina-hook,判断是否是Gitee的请求 if (req.headers['user-agent']?.includes('git-oschina-hook') && verifySignature(req)) { // 执行shell脚本 exec('cd /home/ && ls', (error, stdout, stderr) => { if (error) { console.error(`执行错误: ${error}`); } console.log(`输出: ${stdout}`); // 返回更新结果,通知gitee验证结果 res.status(200).send(`更新成功: ${stdout}`); }); } else { res.status(403).send('Webhook 验证失败'); } } catch (error) { logger.error(`服务器错误: ${error.message}`); res.status(500).send('服务器内部错误'); } }); // 启动服务器 app.listen(5330, () => { logger.info('Server is running on port 5330'); });
代码解释:
日志记录配置: 使用
winston
库配置日志记录,以便更好地跟踪和调试服务器行为。签名验证: 通过
crypto
库生成签名,并验证来自Gitee的请求是否合法。处理POST请求: 当收到POST请求时,检查请求头中的
user-agent
字段以确认请求来源,并验证签名。如果验证通过,则执行指定的shell命令(例如列出项目目录下的文件),并将结果返回给Gitee。
启动服务器:
使用
node index.js
命令启动服务器,监听地址为`http://localhost:5330/update`,仅接受POST请求。
Gitee网页端配置
创建仓库:
登录Gitee,创建一个新的仓库用于存放项目代码。
配置Webhooks:
进入仓库设置页面,找到Webhooks选项。
配置Payload URL为服务器监听的地址(如`http://localhost:5330/update`)。
设置签名密钥,确保与服务器端配置的
secret
一致。选择触发事件为
push
,即当有新的提交推送到仓库时触发。激活Webhook,并点击添加完成配置。
本地配置
安装并配置Git:
确保本地已安装Git,并正确配置用户名和邮箱。
添加SSH密钥:
生成SSH密钥对,并将公钥添加到Gitee账户中,以便安全地与远程仓库通信。
创建本地项目:
在本地创建一个新的项目目录,并初始化Git仓库。
关联远程仓库:
将本地仓库与Gitee上的远程仓库关联起来,使用
git remote add origin <远程仓库URL>
命令。
提交并推送代码:
修改本地项目内容,提交更改到本地仓库,然后使用
git push
命令将代码推送到远程Gitee仓库,触发Webhook执行。
通过以上步骤,可以成功实现从本地推送代码到Gitee仓库,并触发服务器端的自动化操作。