はじめに
ChatGPT
を使用して、マージリクエストのレビューをしてもらいたいという気持ちがあり、
実際にできそうなので構築をしてみる。
作業ログ編で構築したので清書をしたものを記載する。
環境
Windows 10 Professional
WSL2 (Ubuntu22.04 LTS)
docker version 23.0.5
Docker Compose version v2.17.3
GitLab
gitlab-runner latest
目指すべきアーキテクチャ
ローカルPC上で起動したDocker
のGitLab
コンテナを利用して、MR時にOpenAI API
にMRの内容をリクエストする。
全体シーケンス図
完成後の動作
構築
全体の流れ
全体の構築手順としては以下になる。
前提として、Docker
, GitLab
, gitlab-runner
は構築済みとする。
また、適用するプロジェクトも作成済みとする。
- GitLab-runner の登録
- GitLabのレビューコメントをするユーザの作成
- 作成したユーザの
Personal Access Token
の取得 - 作成したユーザに対してレビュー対象のプロジェクトを見られるようにする。
- 取得した
Personal Access Token
をCI/CDの変数へ設定 - OpenAIのAPIKeyもCI/CDの変数へ設定
.gitlab-ci.yml
の作成およびAPIのリクエスト用のpython
プログラム作成- 実際にMRを作ってレビューしてもらう。
前提: GitLabのDockerの設定
※以前設定したものと同様ではあるが、compose.yml
を記載しておく。
services:
gitlab:
build: ./gitlab
hostname: 'gitlab.example.com'
environment:
GITLAB_OMNIBUS_CONFIG:
external_url 'http://gitlab.example.com/'
volumes:
- '$GITLAB_HOME/config:/etc/gitlab'
- '$GITLAB_HOME/logs:/var/log/gitlab'
- '$GITLAB_HOME/data:/var/opt/gitlab'
ports:
- '80:80'
- '443:443'
- '22:22'
shm_size: '256m'
restart: unless-stopped
runner:
image: 'gitlab/gitlab-runner:latest'
restart: always
volumes:
- ./srv/gitlab-runner/config:/etc/gitlab-runner
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "8093:8093"
links:
- "gitlab:gitlab.example.com"
1. GitLab-runner の登録
gitlab-runner
コンテナへ入る。
docker compose exec runner bash
gitlab-runner register
を実行する
root@1ce083816d04:/# gitlab-runner register
URL
とtoken
を入力する。
※token
は GitlabRunnerをDockerで構築する で記載しているので参照する。
URL
はローカルだと、IPアドレスを設定しているのでローカルIPを設定している。
ここは、構築しているURLに依存するので注意
項目名 | 設定値 |
---|---|
URL | http://192.168.0.20/ |
token | glrt-ctnzpdPRws3J43rsgP-7 |
runner name | mr-review |
executor | docker |
Docker image | python:3.11.4-buster |
root@5e286da6b99a:/# gitlab-runner register
Runtime platform arch=amd64 os=linux pid=40 revision=85586bd1 version=16.0.2
Running in system-mode.
Enter the GitLab instance URL (for example, https://gitlab.com/):
http://192.168.0.20/
Enter the registration token:
glrt-ctnzpdPRws3J43rsgP-7
Verifying runner... is valid runner=ctnzpdPRw
Enter a name for the runner. This is stored only in the local config.toml file:
[5e286da6b99a]: mr-review
Enter an executor: shell, virtualbox, docker+machine, instance, kubernetes, custom, docker, ssh, docker-autoscaler, docker-windows, parallels:
docker
Enter the default Docker image (for example, ruby:2.7):
python:3.11.4-buster
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
Configuration (with the authentication token) was saved in "/etc/gitlab-runner/config.toml"
root@5e286da6b99a:/#
image
は python3.11.4-buster
を使用した。DockerHub から使用できるイメージを参照する。
※作成した runner
に shared
タグを付けておくと、 他のプロジェクトでも使用可能になる。
また、clone_url
は自動的に設定されないため、設定ファイルを編集する。runner
コンテナの設定ファイルを編集する。
今回は、sudo vi srv/gitlab-runner/config/config.toml
で編集する。
コンテナ内のファイルは、 /etc/gitlab-runner/config.toml
[[runners]]
name = "mr-review"
url = "http://192.168.0.20/"
+ clone_url = "http://192.168.0.20/"
id = 4
token = "glrt-ctnzpdPRws3J43rsgP-7"
token_obtained_at = 2023-08-05T05:18:41Z
token_expires_at = 0001-01-01T00:00:00Z
executor = "docker"
[runners.cache]
MaxUploadedArchiveSize = 0
[runners.docker]
tls_verify = false
image = "python:3.11.4-buster"
privileged = false
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = ["/cache"]
shm_size = 0
2. GitLabのレビューコメントをするユーザの作成
3. 作成したユーザのPersonal Access Token
の取得
Personal Access Tokens
から、Token name
の入力とSelect Scopes
->api
を選択し、Create personal access token
を押す。
4. 作成したユーザに対してレビュー対象のプロジェクトを見られるようにする。
※プロジェクトの編集権限を持っているユーザでログインをする。
5. 取得したPersonal Access Token
をCI/CDの変数へ設定
※プロジェクトの編集権限を持っているユーザでログインをする。
設定したいプロジェクトのページに移動する。
Key
,Value
をセットし、Add variable
を押す。
※Protect variable
はチェックを外しておき、Mask variable
はチェックを付けておく。
6. OpenAI のAPIkeyもCI/CDの変数へ設定
上記と同じ手順で、今度はOpenAI
のAPI Key
を設定する。
7. .gitlab-ci.yml
の作成およびAPIのリクエスト用のpython
プログラム作成
プロジェクトをクローンする。
.gitlab-ci.yml
を作成する。
before_script:
- python -V
- pip install virtualenv
- virtualenv venv
- source venv/bin/activate
build:
script:
- echo Hello,World
mr-review-gpt:
stage: test
script:
- pip install -r requirements.txt
- python mr_review.py
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
# - if: $CI_MERGE_REQUEST_ID
# (https://gitlab-docs.creationline.com/ee/ci/parent_child_pipelines.html) でもOK
※ test
用で Hello,World
も用意している。
3. requirements.txt
を作成する。
requests
openai
mr_review.py
を作成する。
※gitlab_url = 'http://192.168.0.20'
の部分だけ注意。
import openai
import requests
import os
# GitLabのURL、アクセストークン、プロジェクトID、マージリクエストのIIDを指定します
gitlab_url = 'http://192.168.0.20'
access_token = os.environ.get('PERSONAL_ACCESS_TOKEN')
project_id = os.environ.get('CI_PROJECT_ID')
merge_request_iid = os.environ.get('CI_MERGE_REQUEST_IID')
# OpenAIのAPI_KEYとModelを指定します
openai.api_key = os.environ.get('OPENAI_API_KEY')
model = 'gpt-3.5-turbo'
# リクエストヘッダーにアクセストークンを設定します
headers = {'PRIVATE-TOKEN': access_token}
# マージリクエストの変更内容を取得するAPIエンドポイントを構築します
gitlab_api_url = f'{gitlab_url}/api/v4/projects/{project_id}/merge_requests/{merge_request_iid}/changes'
# APIリクエストを送信してマージリクエストの変更内容を取得します
mr_changes_response = requests.get(gitlab_api_url, headers=headers)
# レスポンスのJSONデータから変更内容を抽出します
mr_changes_data = mr_changes_response.json()
code_changes = mr_changes_data['changes']
print(code_changes)
response = openai.ChatCompletion.create(
model=model,
messages = [
{"role": "system", "content": "あなたはプログラミングのスペシャリストでコードレビューをするアシスタントです。"},
{"role": "user", "content":f"次のコード変更を分析し、修正が必要な問題がある場合は見つけます。 コードの変更は git diff 表記で行われ、- で始まる行が削除され、+ で始まる行が追加されます。" +
f": {code_changes}",
}
],
max_tokens=2000,
)
analysis = f"This comment is auto generated by OpenAI {model} : {response['choices'][0]['message']['content']} "
print(analysis)
# Make comment on merge request with the analysis
comment_url = f"{gitlab_url}/api/v4/projects/{project_id}/merge_requests/{merge_request_iid}/discussions"
comment_data = {
"body": analysis
}
comment_response = requests.post(comment_url, headers=headers, data=comment_data)
print(comment_response)
8. 実際にMRを作ってレビューしてもらう。
- 下記のようなファイルを追加で作成する。
def fibonacci(n):
if n <= 0:
return []
elif n == 1:
return [0]
elif n == 2:
return [0, 1]
else:
fib_sequence = [0, 1]
for i in range(2, n):
next_fib = fib_sequence[i-1] + fib_sequence[i-2]
fib_sequence.append(next_fib)
return fib_sequence
# フィボナッチ数列の長さを指定して計算
length = int(input("フィボナッチ数列の長さを入力してください: "))
sequence = fibonacci(length)
print(sequence)
ChatGPT
に作成してもらったフィボナッチ数列を計算するプログラムを作成する。fibonacci.py
で作成する。
feat-add-fibonacci
というブランチを作成してプッシュ- MRを作成する。
上記のようにジョブが走っていることがわかる。 ChatGPT-Review-BOT
のユーザがコメントできていることを確認。
できた!
注意するべき点について
- プロジェクトのユーザの権限
- CI/CD variableの変数の設定 (保護の有無)
- .gitlab-ci.ymlの設定について
url
,clone_url
の設定について
上記を気をつけておけば、構築できるはず…。
デバッグなどは、作業ログ編を見ていただくと解決できると思う。
改善したい点
MRの変更があるたびに
job
が走るので、その度にすべての変更点のレビューが再度されてしまう。
→この辺りどうにかうまい仕組みにしたい。運用で解決という手もあるが…。コメントをしても、ChatGPT-Review-BOTは反応してくれない。
Assignee
,Reviewer
に特定のユーザが設定された場合に限りレビューするようにしたい。
参考
作業ログ編の#参考を参照
おわりに
作業ログとして残したものを清書版として記事にした。
現在では、GitHubActionでこういう物があると思うので、あまり需要がなさそうだが、GitLabCI/CDの使い方が少しだけ分かって嬉しい。
もう少し活用できるようにスキルアップしたい。