AI革新:自动化PR审查与GitLab集成指南

随着人工智能技术的突飞猛进,我们终于迎来了代码审查的新纪元。

AI技术已被应用于自动化识别代码中的潜在问题,包括但不限于代码风格一致性、潜在的bug、性能问题、安全漏洞等。

通过训练模型识别代码模式和已知问题,AI可以在代码提交到版本控制系统之前或之后自动进行审查。以此提高开发效率和代码质量。

阅读本文将学习到

  1. AI自动点评的整体流程
  2. gitlab webhook的基础使用、配置
  3. gitlab api的调用、使用场景及相关字段说明
  4. 网络穿透 工具ngroklocaltunnel的使用
  5. openai的基础调用

AI自动点评的整体流程

触发AI点评流程图:

流程说明

设置webhook地址

设置--webhooks中配置接口(node服务)地址、触发来源,如无webhooks入口需申请相应的权限。

gitlab上创建合并请求

在gitlab上发起合并请求,将触发webhook

此时将发起post请求、并携带相关gitlabbody参数进入到上面的配置的node服务,其中主要用到的参数是body.project(项目信息)body.object_attributes(触发的hook类型对应的属性信息)

注意: 在更新或合并请求时也会触发hook,如果只想要创建时触发、需要过滤掉这些情况。

要区分创建、更新或合并操作,可以使用object_attributes字段中的action字段。其值有:

  • open:表示Merge Request被创建。
  • update:表示现有的Merge Request被更新。
  • merge:表示Merge Request被合并。
  • close:表示Merge Request被关闭

另外在测试webhooks时会要用到合并状态object_attributes.state,其值有:

  • opened:表示合并请求已被打开,正在等待处理。
  • closed:表示合并请求已被关闭,但并未合并。
  • merged:表示合并请求已被接受并合并到目标分支。
  • locked:表示合并请求因为某些原因被锁定。

过滤具体实现如下:

javascript 复制代码
const action = body.object_attributes && body.object_attributes.action

const state = body.object_attributes && body.object_attributes.state

// 在gitlab上测试时其值为undefined
const isHookTest = action === undefined && /^opened|merged|closed|locked$/.test(state)

// 满足该条件时拦截(不去请求openai服务)
if(!(action === 'open' || isHookTest) && !query.project_id) {
  return
}

如上,只允许以下三种情况去请求openai服务

  • 创建合并请求时
  • 外部使用Get方法传入project_id直接调用node服务时(本地调试、手动触发)
  • gitlab上点击合并请求测试时,此时action===undefined,state值是不固定的

手动触发测试webhook

为什么直接使用本地 IP 可能不行?

  • 网络可达性:GitLab 实例必须能够访问 webhook 配置的地址。如果 GitLab 托管在云端或另一个网络环境中,而 webhook 目标地址是本地网络中的 IP 地址,则 GitLab 可能无法直接访问该地址。
  • 安全策略:一些网络和托管环境可能出于安全考虑,默认阻止出站连接到内网地址。

在测试时,由于本地node服务地址和gitlab部署的服务器不在同一局域网,将无法触发webhook。此时需要进行本地网络穿透。

本地网络穿透

可实现外网访问,在本地调试时非常有用。场景:如webhook地址、企微告警等第三方配置时无法识别本地localhost的情况下,实现本地实时调试(无需反复发版 )。这里主要介绍两种:ngroklocaltunnel,推荐使用localtunnel、比较稳定,使用ngrok测试时 有时无法成功触发hook。

ngrok使用简介

安装

brew install ngrok

去官网获取令牌

ngrok官网:dashboard.ngrok.com/tunnels/aut...

设置令牌

ngrok authtoken 授权令牌

启动

后续使用执行该命令即可

yaml 复制代码
ngrok http 8000

外网访问

查看访问记录

localtunnel使用简介

安装:

npm install -g localtunnel

启动:

css 复制代码
lt --port 8000

或 使用自定义子域名 启动

css 复制代码
lt --port 8000 --subdomain yourcustomsubdomain

验证:

访问loca.lt/mytunnelpas...(固定地址)获取到通往外网的隧道密码

外网访问:

默认支持https,本地修改时、自动同步,无需再部署。非常适合本地调试


node服务处理

调用gitlab api获取到diff信息

创建项目令牌,获取token(用户请求gitlab api):

根据project_id和request_id调用gitlab api获取到diff信息:

javascript 复制代码
const gitlabAPI = `https://gitlab.com/api/v4/projects/${project_id}/merge_requests/${request_id}/changes`;
  const token = 'xxx'
  await new Promise((resolve, reject)=>{
    request({
      url: gitlabAPI,
      method: 'GET',
      timeout: 3000,
      headers: {
        'Content-Type': 'application/json',
        'Private-Token': token
      }
    },async (error, response, body) => {
      if(error) {
        throw new Error(error)
      }
      // 拿到body
      apiOpenAi(body.changes)
    })
  })

附: 更多使用请阅读gitlab api的文档地址:archives.docs.gitlab.com/15.11/ee/ap...

不同版本的gitlab,其文档会有差异,具体可通过gitlab后台--帮助--进入对应文档

调用openai接口

openai在国内无法直接调用,有两个解决方案

  1. 设置baseURL,通过baseURL转发调用,比较容易实现
  2. 将openAI的api部署到国外服务器,本地请求国外服务器接口,由国外服务器去请求openai api即可,其原理也是服务转发而已。
arduino 复制代码
生成AI实例
const ai = new OpenAI({
  baseURL,
  apiKey,
  timeout: 60000, // 超时时间
});
kotlin 复制代码
// 获取AI评审内容
const notes = []
for (const change of content) {
      // 需要忽略的diff文件
      if (
        /^(.|public|dist|build)/.test(change.new_path) ||
        /(.s?css)$/.test(change.new_path) ||
        /package-lock|package.json/.test(change.new_path)
      ) {
        continue;
      }
      const data = await ai.chat.completions.create({
        model: 'gpt-4',
        messages: [
          {
            role: 'system',
            // 这里和用户内容都可以做成配置化,以实现不同项目的AI定制
            content: '你是资深的程序专家,对用户提供的diff内容进行review,并指出明显的问题、错误',
          },
          {
            role: 'user',
            content: change.diff,
          },
        ],
      }).catch(console.error);
      if(!data) continue
      notes.push(data.choices?.[0].message?.content || '');
    }
// 除了notes,也可以收集token的使用情况
return notes

在openai调用这里可以做一些处理:

  1. 过滤掉非必要的文件diff,以减少token损耗
  2. 可以做成项目定制化(可配置)
  3. 可以收集token使用情况
  4. 可以做消耗及反馈和使用情况的统计报表

单次调用openai 4的最大输入token数为8192,超过将报错、需要对此做些方案应对:

OpenAI计费情况说明

OpanAI3.5调用api也不是免费的,只是费用相对较低而已。openAI4的收费相对较高,一个大需求diff一次可能要花费好几刀🤔🤣🤗。
因此在使用时务必要控制成本(减少非必要的diff、过滤无需diff的文件【如样式文件、第三方sdk文件、lock文件等】、把控好diff的时机【避免频繁、重复的diff】等)

调用gitlab点评接口

传入AI结果、请求gitlab api点评接口后,AI点评的结果将出现的pr评论区域:

javascript 复制代码
const url = `https://gitlab.com/api/v4/projects/${project_id}/merge_requests/${request_id}/notes`
request({
    url: ,
    method: 'POST',
    json: {
      body: `消费总token: ${_total_tokens}个,输入token:${_prompt_tokens}个,输出token:${_completion_tokens}个。\n AI总耗时:${answer.costTime}ms。 \n;${answer.choices[0].message.content}` , 
      id: project_id, 
      merge_request_iid: request_id
    },
    headers: {
      'Content-Type': 'application/json',
      'Private-Token': token
    }
  }, async (_error, _response, _body) => {
    if(_error) {
      console.error('ai点评error', error);
      return
    } else {
      console.log('ai点评ok :>> 点评成功');
    }
  })

gitlab上查看点评结果:

至此,完成AI自动点评的整个过程。 如果有多个项目时,其gitlab的项目令牌需要做成可配置化。可以借助Appollozookeeper等第三方工具并以项目名称作为key来实现可配置化。也可以将整个过程搬到管理后台(项目展示、AI人设配置、点评结果汇总及展示、手动操作点击触发AI点评),实现完全可控的定制化。

总结

通过将AI集成至GitLab,我们不仅能够提高代码质量,还能极大提升审查效率,从而加速产品迭代过程。

AI自动化代码审查不仅可以提高代码质量,还可以释放开发者的时间,让开发者专注于更重要的任务 。将AI审查集成至GitLab,可以让整个开发流程更加流畅高效。

随着AI技术的不断发展,未来AI在代码审查领域的应用将更加广泛和深入。

相关推荐
我曾经是个程序员2 分钟前
鸿蒙学习记录
开发语言·前端·javascript
羊小猪~~16 分钟前
前端入门之VUE--ajax、vuex、router,最后的前端总结
前端·javascript·css·vue.js·vscode·ajax·html5
摸鱼了31 分钟前
🚀 从零开始搭建 Vue 3+Vite+TypeScript+Pinia+Vue Router+SCSS+StyleLint+CommitLint+...项目
前端·vue.js
程序员shen16161142 分钟前
抖音短视频saas矩阵源码系统开发所需掌握的技术
java·前端·数据库·python·算法
理想不理想v1 小时前
node.js的简单示例
node.js
Ling_suu1 小时前
SpringBoot3——Web开发
java·服务器·前端
yrldjsbk1 小时前
使用Node.js搭配express框架快速构建后端业务接口模块Demo
node.js·express
Yvemil71 小时前
《开启微服务之旅:Spring Boot Web开发》(二)
前端·spring boot·微服务
hanglove_lucky1 小时前
本地摄像头视频流在html中打开
前端·后端·html
维李设论1 小时前
Node.js的Web服务在Nacos中的实践
前端·spring cloud·微服务·eureka·nacos·node.js·express