iT邦幫忙

2024 iThome 鐵人賽

DAY 3
1
DevOps

將 AI Code Review 整進 CICD系列 第 3

將 AI Code Review 整進 CICD Day3

  • 分享至 

  • xImage
  •  

Day 2 我們成功從 A repo trigger B repo,但我們的目的是為了讓 B repo 可以因為 merge request 被觸發後,拿著這個merge request 的 event 來做 ai code review。所以我們現在要來看 A 的 payload 如何讓 B 拿到。

這段其實在 A repo trigger webhook 的時候就會帶進去了,所以難度沒有很高,我們來看一下官網,我們在 B repo(被 trigger 的) gitlab ci 內加上 cat payload

 cat $TRIGGER_PAYLOAD

https://ithelp.ithome.com.tw/upload/images/20240817/20118525VpT7onDWMX.png

commit 後在 A repo 再 test 一次 webhook,就可以拿到以下資料,而其中最重要的就是我們在 Day 1 自己手動帶入的 merge request url。在這邊則是 object_attributes[“url“]

$ cat $TRIGGER_PAYLOAD
{
"object_kind":"merge_request",
"event_type":"merge_request",
"user":{
"id":12081700,
"name":"Alvin",
"username":"ooii8929",
...
},
"project":{
"id":60505829,
"name":"main-feature",
"description":null,
...
},
"object_attributes":{
"url":"https://gitlab.com/ooii8929/main-feature/-/merge_requests/2",
  ...
},
"labels":[
...
],
"changes":{
},
"repository":{
...
}

根據官網介紹,TRIGGER_PAYLOAD 是 file type 的變數(指向包含 JSON 數據的臨時文件的路徑),所以我們使用 jq -r 來讓 jq 向路徑上的文件進行讀取

    - URL=$(jq -r '.object_attributes.url' $TRIGGER_PAYLOAD)
    - echo $URL

為了使用 jq,我們也拉一個乾淨的 image 來進行安裝

build_job:
  stage: build
  image: alpine:latest
  before_script:
  - apk add --no-cache jq
  script:
    - cat $TRIGGER_PAYLOAD
    - URL=$(jq -r '.object_attributes.url' $TRIGGER_PAYLOAD)
    - echo $URL

在 Runner 運作 AI

為了達到我們原本在 local 可以用 python 運行的方式,我們想像會執行以下動作

python3 -m pr_agent.cli --pr_url $URL review

所以我會拆出另一個 stage,使用 python image,並且用 artifacts 在不同 stage 之間共享 $URL

stages:
  - pre-set
  - run

build_job:
  stage: pre-set
  image: alpine:latest
  before_script:
    - apk add --no-cache jq
  script:
    - cat $TRIGGER_PAYLOAD
    - URL=$(jq -r '.object_attributes.url' $TRIGGER_PAYLOAD)
    - echo "URL=$URL" > build.env
    - cat build.env
  artifacts:
    reports:
      dotenv: build.env

run_code:
  stage: run
  image: python:3-alpine
  script:
    - echo $URL
    # - python3 -m pr_agent.cli --pr_url $URL review

一樣回到 main-feature webhook 測試,確認在 run stage 有 echo 出來 URL

再來我們要將程式推上 git,因為程式內會填入兩個 sensitive info(OpenAI key & personal access token),所以我們會善用 gitlab cicd variables 來做資安保護。

先來到 ai-review-runner 的 settings → cicd → Variables ,建立兩個 Variables: OPEN_AI_TOKEN 跟 PERSONAL_ACCESS_TOKEN ,並且各別設置 MASK

https://ithelp.ithome.com.tw/upload/images/20240817/20118525BcmFus3VHA.png

好了之後,我們前往原本設定的 pr-agent 的 .secret.toml 設定成變數

[openai]
key = "$OPEN_AI_TOKEN" 

[gitlab]
# Gitlab personal access token
personal_access_token = "$PERSONAL_ACCESS_TOKEN"

然後在 .gitignore 我們將 pr_agent/settings/.secrets.toml 給註解掉。不然推的時候會少這個 file。然後我們在 ai-review-runner 建立一個 pr-agent folder 將 pr_agent 整個檔案都放進去。

# 放之前

tree -L 1 -a
.
├── .git
├── .gitlab-ci.yml
└── README.md

# 放之後
  
tree -L 2 -a
.
├── .git
│   ├── COMMIT_EDITMSG
│   ├── FETCH_HEAD
│   ├── HEAD
│   ├── ORIG_HEAD
│   ├── config
│   ├── description
│   ├── gc.log
│   ├── hooks
│   ├── index
│   ├── info
│   ├── logs
│   ├── objects
│   ├── packed-refs
│   └── refs
├── .gitignore
├── .gitlab-ci.yml
├── README.md
└── pr-agent
    ├── .dockerignore
    ├── .gitignore
    ├── .pr_agent.toml
    ├── CHANGELOG.md
    ├── Dockerfile.github_action
    ├── Dockerfile.github_action_dockerhub
    ├── LICENSE
    ├── MANIFEST.in
    ├── README.md
    ├── RELEASE_NOTES.md
    ├── action.yaml
    ├── docker
    ├── docs
    ├── github_action
    ├── pr_agent
    ├── pr_agent.egg-info
    ├── pyproject.toml
    ├── requirements-dev.txt
    ├── requirements.txt
    ├── setup.py
    └── tests

推上 gitlab 並且在 .gitlab-ci.yml 使用 python

run_code:
  stage: run
  image: python:3-alpine
  script:
    - echo $URL
    - cd pr-agent
    - python3 -m pr_agent.cli --pr_url $URL review

然後再來測試一次。但我們會發現它會遇到 get git provider 錯誤問題,看樣子是 personal access token 沒有權限,但我們之前在 Local 用同一把是成功的,所以應該是設定沒設定好

  File "/builds/ooii8929/ai-review-runner/pr-agent/pr_agent/git_providers/__init__.py", line 62, in get_git_provider_with_context
    raise ValueError(f"Failed to get git provider for {pr_url}") from e
ValueError: Failed to get git provider for https://gitlab.com/ooii8929/main-feature/-/merge_requests/2

我們在 gitlab provider 新增 print 看看我們的參數有沒有正常帶進去。會發現它會印出

class GitLabProvider(GitProvider):

    def __init__(self, merge_request_url: Optional[str] = None, incremental: Optional[bool] = False):
        gitlab_url = get_settings().get("GITLAB.URL", None)
        if not gitlab_url:
            raise ValueError("GitLab URL is not set in the config file")
        print("for test", get_settings().get("GITLAB.PERSONAL_ACCESS_TOKEN", None))
        gitlab_access_token = get_settings().get("GITLAB.PERSONAL_ACCESS_TOKEN", None)
for test ${PERSONAL_ACCESS_KEY}

代表沒有真的完成變數帶入

這邊也額外補充一下,我們改成讓他每次 trigger 才會觸發

  rules:
    - if: $CI_PIPELINE_SOURCE == "trigger"

上一篇
將 AI Code Review 整進 CICD Day2
下一篇
將 AI Code Review 整進 CICD Day4
系列文
將 AI Code Review 整進 CICD28
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言