實驗在 GitLab Merge Request 之 CI Pipeline 中使用 CodeGPT 提供 Code review 建議

2023 GPT 熱潮,市面上出現各種能夠輔助軟體開發工程師的新工具,那麼有沒有工具是適合放進 CI/CD Pipeline 的呢?剛好看見 AppleBoy 開發的 CodeGPT 可能會是其中一個選項!

2023 年,ChatGPT 與 OpenAI 議題大熱門,全球都在探討可以將它們運用在哪些工作領域中,當然軟體開發工程師也不例外,舉凡寫程式、程式碼重構、產生 Commit messages、code review、pair programming、寫測試⋯⋯,幾乎每一個動作都有人在嘗試結合這波「AI」熱潮,希望讓這些任務能做得又快又好。

最近剛好看見台灣知名的講師與開源專案貢獻者 AppleBoy 也投身在此議題,開發了名為 CodeGPT 的工具,不僅能用它來自動生成 Commit 總結,甚至能做出 Code review 提供一些程式碼的改善建議。

按著 AppleBoy 的 CodeGPT 工具說明,我第一時間的想法即是,這樣的一個工具是不是適合放進 CI Pipeline 中呢?如果能讓隨著 Merge request (或 Pull request) 而執行的 CI Pipeline 能自動產生一份由 GPT 提供的 Code review 程式碼改善建議,這樣我們就可以自動額外獲得一份來自「非真人觀點」的 Code review 建議;即便這些「非真人的觀點」不一定正確或準確(因為 GPT 已被證實有時會一本正經的說瞎話),但它的建議依然有機會幫助真人跳脫自己固有的觀點,以不同的角度思考同一個問題。

以下我們就搶先試驗,試著將 CodeGPT 放進 GitLab Merge request CI Pipeline 吧!

(本文初版撰寫於 2023.04.02,於 2023.04.04 更新。本文使用的 CodeGPT 版本為 v0.1.5,當你閱讀本文時,很可能 CodeGPT 已經改版與本文下述的操作步驟不同,還請自行關注各工具的最新異動資訊。)

操作步驟

下面我們就用一個最輕鬆的方式,來做出一個 Merge request 之 CI Pipeline,來實驗 CodeGPT。既然是最輕鬆的方式,所以我就直接在 gitlab.com 上建立一個乾淨的 Project,並使用公用的 Shared Runner。

註冊 OpenAI API 取得 API Secret Key

要使用 CodeGPT 我們需要準備 OpenAI API 的 API Secret Key,這就只能請各位讀者自行前往 Open AI 原廠網站註冊申請了。因為 OpenAI API 不是免費的,因此申請需要用到信用卡,當然原廠有提供免費試用的額度,還請各位讀者按著本文實驗時,自己注意免費與付費的問題。

將 OpenAI API Secret Key 設定為 GitLab CI/CD Variables

CodeGPT 可以直接讀取環境變數 OPENAI_API_KEY,因此我們只需要善用 GitLab CI/CD Variables 即可安全的將 Secret Key 提供給 CodeGPT 使用。

因為 OpenAI API Secret Key 是重要的私密資訊,因此在設定 GitLab CI/CD Variables 時,記得勾選 Mask variable 做基本的保護。 (如果你對於重要的 Secret key 有更高的安全考量,你也可以考慮在 CI Pipeline 中整合其他更安全的服務。)

準備 GitLab Runner

接著我們要準備一個能夠執行測試實驗的 GitLab Runner,前面提過這次我不打算自行準備 GitLab Runner,而是直接使用 gitlab.com 的 Shared runner;我們要使用的 Runner 就如下圖是帶有 Tag docker 的 Shared Runner。

(當然如果你不放心使用這種會跟別人共用資源的 Shared Runner,你還是可以自架 GitLab Runner。)

設置 Merge request 之 CI Pipeline

接著我們編輯 .gitlab-ci.yml,建立 Merge request 專用之 CI Pipeline。

stages:
- test

gpt-code-review:
  only:
  - merge_requests
  tags:
  - docker
  # 這裡偷懶,直接使用方便但比較胖的 debian container image
  image: debian:latest
  stage: test
  script:
  # 準備安裝必要的軟體
  - apt update
  # 安裝 wget 與 get,因為 CodeGPT 相依 Git,所以還要額外安裝 Git
  - apt install -y wget git
  # 下載 CodeGPT v0.1.5
  - wget https://github.com/appleboy/CodeGPT/releases/download/v0.1.5/CodeGPT-0.1.5-linux-amd64
  # 改檔名,並給予足夠的執行權限
  - mv CodeGPT-0.1.5-linux-amd64 codegpt
  - chmod 755 codegpt
  # 測試執行 CodeGPT 指令
  - ./codegpt version
  # 讓 CodeGPT 根據最後一次 Commit 進行 Code review
  - ./codegpt review --amend

這裡我也是偷懶,可以的話建議大家事先 build 一個已經安裝好 git 與 CodeGPT 的 container image,這樣就能省去我上面的那些 apt updateapt install 的動作;舉例來說如果你有事先準備好 image,應該只需要如下的 .gitlab-ci.yml

stages:
- test

gpt-code-review:
  only:
  - merge_requests
  tags:
  - docker
  image: your_code_gpt_container_image:latest
  stage: test
  script:
  - codegpt version
  - codegpt review --amend

除了 --amend 之外,CodeGPT 還有其他的參數可以使用,像是 --lang zh-tw 讓他輸出中文,或 --max_tokens 控制輸出內容的長度,以及用 --exclude_list 略過不想被看的檔案。

2023.04.04 更新,感謝 AppleBoy 很迅速的幫大家 build 好 image 了,所以上面的 .gitlab-ci.yml 可以改成如下,直接使用現成的 image。

stages:
- test

gpt-code-review:
  only:
  - merge_requests
  tags:
  - docker
  image: ghcr.io/appleboy/codegpt:latest
  #或者是 image: appleboy/codegpt:0.1.6
  stage: test
  script:
  - codegpt version
  - codegpt review --amend

實驗結果

完成了前述的準備動作,剩下就是查看實驗結果了。

我建立了一個新的 branch,嘗試在上面改 Code,並送出 Merge request。

查看 Merge reqeust 之 CI Pipeline 的結果。 結果得到了一段好笑的內容啊,畢竟我沒有真的 commit 什麼可以運作的 Code,所以當然給不出太多有用的意見。

再次微調 Pipeline,讓結果更一目了然

最後,讓我再次微調一下 .gitlab-ci.yml,我希望能將 CodeGPT 的回應特別標示出來,以便未來在查看 CI Pipeline 結果時能夠更一目了然。

stages:
- test

gpt-code-review:
  only:
  - merge_requests
  tags:
  - docker
  image: debian:latest
  stage: test
  script:
  - echo -e "section_start:`date +%s`:install_codegpt[collapsed=true]\r\e[0KInstall CodeGPT"
  - apt update
  - apt install -y wget git
  - wget https://github.com/appleboy/CodeGPT/releases/download/v0.1.5/CodeGPT-0.1.5-linux-amd64
  - mv CodeGPT-0.1.5-linux-amd64 codegpt
  - chmod 755 codegpt
  - ./codegpt version
  - echo -e "section_end:`date +%s`:install_codegpt\r\e[0K"
  - echo -e "section_start:`date +%s`:run_codegpt\r\e[0KRun CodeGPT"
  - ./codegpt review --amend
  - echo -e "section_end:`date +%s`:run_codegpt\r\e[0K"

在上面的微調中,我使用了 GitLab CI 的 Custom collapsible sections 功能。這個功能可以讓我們自行控制 Job 的 Log 要如何分段,以及是否預設將該段落「折疊」。

- echo -e "section_start:`date +%s`:install_codegpt[collapsed=true]\r\e[0KInstall CodeGPT"

這一行宣告我要建立一個 Custom section,名為 Install CodeGPT。

續上,其中的 install_codegptSECTION_NAME;而 [collapsed=true] 則表示該 Section 預設要折疊起來不展開;接著 Install CodeGPTTEXT_OF_SECTION_HEADER

- echo -e "section_end:`date +%s`:install_codegpt\r\e[0K"

宣告該 Section 的結尾。

- echo -e "section_start:`date +%s`:run_codegpt\r\e[0KRun CodeGPT"
- echo -e "section_end:`date +%s`:run_codegpt\r\e[0K"

同理,上面這兩行則是另一個 Section 的開頭與結尾。

經過這樣的修改,最後成果如下圖,前面一整段安裝 CodeGPT 的過程 Log,全都被自動摺疊收藏在 Section: Install CodeGPT 裡面,我可以直接看到 Section: Run CodeGPT 的內容。

總結

經過這次的實驗,我目前認為 v0.1.5 的 CodeGPT 可能還不是那麼適合放在 Merge request 的 CI Pipeline,原因如其面的示範,我們使用的指令是 codegpt review --amend,這個指令只會針對前一個 Commit 提供 Code review,但正常來說,當我們在 Feature branch 開發程式,並最後送出從 Feature branch 合併回 Main branch 的 Merge request 時,這一整個 Merge request 多半是包含了數個 Commit、異動多個檔案。

(如上圖,這個 MR 有 8 個 Commit)

而 Merge request 執行之 CI Pipeline,其 Git HEAD 則會停留在該 Branch 的最新 Commit 的位置。以我的示範為例,即是 Feature branch 的最後一個 Commit,如下面兩張圖片,可以發現 Job 是對 efda1906 這個 HEAD 的 Code 執行的。

因此延續上面的範例,我在 Job 中執行的 codegpt review --amend,想當然就只是針對 efda1906 這個 Commit 提供 Code review 而已。

這樣一來,就跟我原本的期待不合,我本來是希望 CodeGPT 能針對整個 Merge request 共 8 個 Commit 的異動範圍提供 Code review 建議的。

當然這個狀況,目前也不是沒有其他解決方法,例如我可以辛苦一點,在建立 MR 之前,先將 Feature branch 上的 Commit 用 git rebase 的方式將 8 個 Commits 給 squash 整理成 1 個 Commit(做法可參閱龍哥的教學),這不就能餵給 CodeGPT 一個超大包的 Commit 了嗎,可是別忘了 OpenAI API 每次互動是有 Token 上限的,所以太大包的 Commit 也是不可行的。

基於以上的原因,目前想要在 Merge request 之 CI Pipeline 利用 CodeGPT 去做自動 Code review 可能還不太適合,也許還要再等一些日子,讓子彈飛一下,未來可能會有更好更適合的工具會出現。以目前現況來說,與其在 Merge request 之 CI Pipeline 才利用 CodeGPT,倒不如開發者直接在 Local 或開發環境中安裝 CodeGPT,讓每一次的 Commit 都有 GPT 自動就地幫忙做 Code review 還比較實際一些。

2023.04.04 更新: 另外雖然在上面的結論中,我覺得只能針對前一個 Commit 自動做出 Code review 有些美中不足;但如果你的工作流程是先開好 Merge request,然後逐次送出每個 commit 就會去查看 MR 之 CI pipeline 的執行結果,那麼 CodeGPT 目前是已經可用的!而且相信很快作者就會有更多改版,可以實現針對整個 MR 的異動範圍做出 Code review。(畢竟隔壁棚 Azure DevOps 已經有人做出可以對整個 PR 做自動 Code Review 的工具了。)

如果對你的團隊而言,每一次的 Merge request 都是重要的 Code review、程式碼檢核點,那麼你必然會在 Merge request 之 CI Pipeline 設計各種 Job,讓它可以自動幫你掃瞄或檢核程式碼,讓 CI Service 能確實做好「守門員」的角色。

而既然這位「守門員」是按著你賦予它多少「能力」來達成守門的任務,那麼現在世界上出現了 GPT 這麼厲害的工具,確實讓我們心癢難耐,是否 GPT 有機會替這位「守門員」灌注更多的能力?讓 CI Pipeline 能更好的完成任務呢。

(在實驗過程中,我也遇過 Timeout 的狀況,只能說 OpenAI 服務的穩定度⋯⋯)

2023.04.04 更新: 今天也看到 91 哥在 FB 分享他對於「自動 Code review」的看法,提醒大家不要因為這些工具,就捨棄了團隊原有的溝通與互動;個人十分認同他的看法,引入這些新工具並不是要來取代團隊原有的 Code review 行為與活動,而是提供更多的輔助,幫助我們讓原有的溝通與互動可以更好。

AppleBoy 開發的 CodeGPT 開啟了更多運用 GPT 及 CI / CD Pipeline 的想像及可能性,期盼各種運用 GPT 的工具能變得更強更好,也許過些時日,人人都會將它們整合至 CI / CD Pipeline 中;相信未來不只是 CodeGPT,世界上還會誕生更多不同的工具,下一個時代的 CI / CD 不知道又會出現什麼樣的神奇變化?

最後,如果你也是開源軟體愛好者、也正投身在研究這波 GPT 熱潮,不妨參與 AppleBoy 的 CodeGPT 專案,幫他按個 Star 或一起加入開源軟體的開發工作喔!

參考資料

轉貼本文時禁止修改,禁止商業使用,並且必須註明來自「艦長,你有事嗎?」原創作者 Cheng Wei Chen,及附上原文連結。

工商服務

更多文章