akun
akun
发布于 2025-03-21 / 0 阅读
0
0

Gitee WebHooks 基础用法

本案例详细介绍了如何实现本地git push到Gitee仓库后,触发Gitee webhook,并在服务器端执行相应的shell脚本。以下是具体步骤:

准备工作

服务器端:

  • 安装Node.js环境,确保服务器能够运行Node.js应用程序。

本地:

  • 安装并配置Git,确保可以与远程Gitee仓库进行交互。

服务器端配置

  1. 创建Node项目:

    • 初始化一个新的Node项目,并安装必要的依赖包(如expressbody-parsercryptowinston)。

    • 创建一个名为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');
    });
    
  2. 代码解释:

    • 日志记录配置: 使用winston库配置日志记录,以便更好地跟踪和调试服务器行为。

    • 签名验证: 通过crypto库生成签名,并验证来自Gitee的请求是否合法。

    • 处理POST请求: 当收到POST请求时,检查请求头中的user-agent字段以确认请求来源,并验证签名。如果验证通过,则执行指定的shell命令(例如列出项目目录下的文件),并将结果返回给Gitee。

  3. 启动服务器:

Gitee网页端配置

  1. 创建仓库:

    • 登录Gitee,创建一个新的仓库用于存放项目代码。

  2. 配置Webhooks:

    • 进入仓库设置页面,找到Webhooks选项。

    • 配置Payload URL为服务器监听的地址(如`http://localhost:5330/update`)。

    • 设置签名密钥,确保与服务器端配置的secret一致。

    • 选择触发事件为push,即当有新的提交推送到仓库时触发。

    • 激活Webhook,并点击添加完成配置。

    githooks

本地配置

  1. 安装并配置Git:

    • 确保本地已安装Git,并正确配置用户名和邮箱。

  2. 添加SSH密钥:

    • 生成SSH密钥对,并将公钥添加到Gitee账户中,以便安全地与远程仓库通信。

  3. 创建本地项目:

    • 在本地创建一个新的项目目录,并初始化Git仓库。

  4. 关联远程仓库:

    • 将本地仓库与Gitee上的远程仓库关联起来,使用git remote add origin <远程仓库URL>命令。

  5. 提交并推送代码:

    • 修改本地项目内容,提交更改到本地仓库,然后使用git push命令将代码推送到远程Gitee仓库,触发Webhook执行。

通过以上步骤,可以成功实现从本地推送代码到Gitee仓库,并触发服务器端的自动化操作。


评论