這是用戶在 2025-1-21 8:47 為 https://medium.com/@kedargmnv/automating-code-review-with-openai-in-your-gitlab-workflow-c18b894bf63... 保存的雙語快照頁面,由 沉浸式翻譯 提供雙語支持。了解如何保存?

Automating Code Review with OpenAI in Your GitLab Workflow
在您的 GitLab 工作流程中使用 OpenAI 自動化代碼審查

Kedar GMNV
7 min readApr 12, 2024

In today’s software development world, ensuring code quality remains a top priority. Code reviews are a crucial step in the development process, but they can be time-consuming, especially for large projects with frequent changes. This is where automation comes in. In this article, we’ll explore a PowerShell script designed to analyze code changes in GitLab MRs using OpenAI within your GitLab workflow.
在當今的軟體開發世界中,確保代碼質量仍然是首要任務。代碼審查是開發過程中的一個關鍵步驟,但對於經常變更的大型項目來說,它們可能會耗時。這就是自動化的用武之地。在本文中,我們將探討一個旨在使用 OpenAI 分析 GitLab 合併請求中的代碼變更的 PowerShell 腳本,並將其整合到您的 GitLab 工作流程中。

Overview of the script  腳本概述

Parameters:  參數:

  • GitLabToken: Your private access token for interacting with the GitLab API.
    GitLabToken: 您與 GitLab API 互動的私人訪問令牌。
  • GitLabApiUrl: The base URL for the GitLab API.
    GitLabApiUrl: GitLab API 的基本 URL。
  • RepositoryId: The specific GitLab repository where the merge request resides.
    RepositoryId: 合併請求所在的特定 GitLab 倉庫。
  • OpenAiApiKey: Your API key for accessing the OpenAI service.
    OpenAiApiKey: 您用於訪問 OpenAI 服務的 API 密鑰。
  • Model : The OpenAI model to be used for code analysis (we are using “gpt-4–1106-preview”).
    模型:用於代碼分析的 OpenAI 模型(我們使用“gpt-4–1106-preview”)。

I securely stored sensitive information such as the GitLab token and OpenAI API key as GitLab variables, avoiding hardcoding them directly into the script. This approach not only enhances security but also offers flexibility for future updates, as the credentials can be easily managed and updated within GitLab’s environment variables.
我安全地將敏感信息,例如 GitLab 令牌和 OpenAI API 密鑰,存儲為 GitLab 變量,避免將它們直接硬編碼到腳本中。這種方法不僅增強了安全性,還為未來的更新提供了靈活性,因為憑據可以在 GitLab 的環境變量中輕鬆管理和更新。

Key Functions:  主要功能:

The script is divided into several functions, each performing a specific task. The main tasks include:
該腳本被分為幾個函數,每個函數執行特定的任務。主要任務包括:

  1. Checking for existing comments on the merge request.
    檢查合併請求上的現有評論。
  2. Retrieving the changes made in the merge request.
    檢索合併請求中所做的更改。
  3. Invoking the OpenAI model to analyze the changes.
    調用 OpenAI 模型來分析變化。
  4. Posting the AI’s analysis as a comment on the merge request.
    將 AI 的分析作為評論發佈在合併請求上。

Let’s dive into each function.
讓我們深入了解每個功能。

  • Get-ExistingComments: This function checks if a previous comment containing “Code Analysis by AI” already exists for the merge request. This helps avoid redundant analysis.
    Get-ExistingComments: 此功能檢查合併請求中是否已存在包含「AI 代碼分析」的先前評論。這有助於避免冗餘分析。
function Get-ExistingComments {
param (
[string]$GitLabToken,
[string]$GitLabApiUrl,
[string]$RepositoryId,
[string]$MergeRequestId
)

try {
Write-Host "Checking for existing comments..."
$Uri = "$GitLabApiUrl/$RepositoryId/merge_requests/$MergeRequestId/notes"

$Response = Invoke-RestMethod -Uri $Uri -Headers @{
"PRIVATE-TOKEN" = $GitLabToken
} -Method Get

if ($null -eq $Response) {
Write-Host "No comments in the response from GitLab API."
return $false
}

$ExistingComment = $Response | Where-Object { $_.body -like "*Code Analysis by AI*" }

if ($ExistingComment) {
Write-Host "A comment containing 'Code Analysis by AI' already exists."
return $true
} else {
Write-Host "No existing comment contains 'Code Analysis by AI'."
return $false
}
} catch {
Write-Host "Error in Get-ExistingComments : $_"
}
}
  • Split-String: This function splits a large string (analysis results) into smaller, manageable chunks for easier processing and commenting.
    分割字串:此函數將大型字串(分析結果)分割成較小、可管理的部分,以便於處理和註解。
function Split-String {
param (
[string]$String,
[int]$ChunkSize
)

$Chunks = @()
$CurrentChunk = ""
$Lines = $String -split "`n"

foreach ($Line in $Lines) {
if (($CurrentChunk.Length + $Line.Length) -le $ChunkSize) {
$CurrentChunk += $Line + "`n"
} else {
$Chunks += $CurrentChunk
$CurrentChunk = $Line + "`n"
}
}

if ($CurrentChunk.Length -gt 0) {
$Chunks += $CurrentChunk
}

return $Chunks
}
  • Get-MergeRequestChanges: This function retrieves the code changes from the specified GitLab merge request. It groups changes by file path and creates objects containing file details like name, changes (diff), and extension.
    Get-MergeRequestChanges:此函數從指定的 GitLab 合併請求中檢索代碼更改。它按文件路徑對更改進行分組,並創建包含文件詳細信息的對象,如名稱、更改(差異)和擴展名。
function Get-MergeRequestChanges {
param (
[string]$GitLabToken,
[string]$GitLabApiUrl,
[string]$RepositoryId,
[string]$MergeRequestId
)

try {
Write-Host "Getting merge request changes..."
$Uri = "$GitLabApiUrl/$RepositoryId/merge_requests/$MergeRequestId/changes"

$Response = Invoke-RestMethod -Uri $Uri -Headers @{
"PRIVATE-TOKEN" = $GitLabToken
} -Method Get

if ($null -eq $Response.changes) {
Write-Host "No changes in the response from GitLab API."
return $null
}

# Group diffs by file path
$GroupedChanges = $Response.changes | Group-Object -Property old_path

$Changes = $GroupedChanges | ForEach-Object {
New-Object PSObject -Property @{
FileName = $_.Name
Changes = ($_.Group | ForEach-Object { $_.diff }) -join "`n"
Extension = [System.IO.Path]::GetExtension($_.Name)
}
}

Write-Host "Successfully retrieved merge request changes."
return $Changes
} catch {
Write-Host "Error in Get-MergeRequestChanges : $_"
}
}
  • Invoke-OpenAiCodeAnalysis: This function is the heart of the script. It sends the retrieved code changes to the OpenAI API for analysis using the specified model. It then processes the response and returns a list of analysis chunks.
    Invoke-OpenAiCodeAnalysis:此函數是腳本的核心。它將檢索到的代碼更改發送到 OpenAI API 進行分析,使用指定的模型。然後,它處理響應並返回分析片段的列表。
function Invoke-OpenAiCodeAnalysis {
param (
[string]$OpenAiApiKey,
[string]$CodeChanges,
[string]$Model
)

try {
Write-Host "Invoking OpenAI code analysis..."
$Prompt = @"
As an AI code reviewer, your role is to analyze the changes in a Merge Request (MR) within a software development project. You will provide feedback on potential bugs and critical issues. The changes in the MR are provided in the standard git diff (unified diff) format.

Your responsibilities include:

- Analyzing only the lines of code that have been added, edited, or deleted in the MR. For example, in a git diff, these would be the lines starting with a '+' or '-'.
```diff
- old line of code
+ new line of code
```
- Ignoring any code that hasn't been modified. In a git diff, these would be the lines starting with a ' ' (space).
```diff
unchanged line of code
```
- Avoiding repetition in your reviews if the line of code is correct. For example, if the same line of code appears multiple times in the diff, you should only comment on it once.
- Overlooking the absence of a new line at the end of all files. This is typically represented in a git diff as '\ No newline at end of file'.
- Using bullet points for clarity if you have multiple comments.
```markdown
- Comment 1
- Comment 2
```
- Leveraging Markdown to format your feedback effectively. For example, you can use backticks to format code snippets.
```markdown
`code snippet`
```
- Writing 'EMPTY_CODE_REVIEW' if there are no bugs or critical issues identified.
- Refraining from writing 'EMPTY_CODE_REVIEW' if there are bugs or critical issues.

Here are the code changes:

$CodeChanges
"
@

$Body = @{
model = $Model
messages = @(
@{
role = "system"
content = "As as AI assistant, your role is to provide a detailed code review. Analyze the provided code changes, identify potential issues, suggest improvements, and adhere to best coding practices. Your analysis should be through and consider all aspects of code, including syntax, logic, efficiency and style."
},
@{
role = "user"
content = $Prompt
}
)
} | ConvertTo-Json

$Response = Invoke-RestMethod -Uri "https://api.openai.com/v1/chat/completions" -Headers @{
"Authorization" = "Bearer $OpenAiApiKey"
} -Method Post -ContentType "application/json" -Body $Body

if ($null -eq $Response.choices) {
Write-Host "No choices in the response from OpenAI API."
return $null
}

$AnalysisChunks = $Response.choices[0].message.content -split "(?<=\.\s)"

Write-Host "Successfully invoked OpenAI code analysis."
return $AnalysisChunks
} catch {
Write-Host "Error in Invoke-OpenAiCodeAnalysis : $_"
}
}
  • PostCommentToMergeRequest: This function takes the generated analysis and posts it as a comment on the corresponding GitLab merge request.
    PostCommentToMergeRequest: 此功能將生成的分析作為評論發佈到相應的 GitLab 合併請求上。
function PostCommentToMergeRequest {
param (
[string]$GitLabToken,
[string]$GitLabApiUrl,
[string]$RepositoryId,
[string]$MergeRequestId,
[string]$Comment
)

try {
Write-Host "Posting comment to merge request..."
$Uri = "$GitLabApiUrl/$RepositoryId/merge_requests/$MergeRequestId/notes"
$Body = @{
body = $Comment
} | ConvertTo-Json

Invoke-RestMethod -Uri $Uri -Headers @{
"PRIVATE-TOKEN" = $GitLabToken
} -Method Post -ContentType "application/json" -Body $Body

Write-Host "Successfully posted comment to merge request."
} catch {
Write-Host "Error in PostCommentToMergeRequest : $_"
}
}

Main Script:  主腳本:

  1. Retrieving Merge Request ID: The script starts by retrieving the merge request ID from the environment variable CI_MERGE_REQUEST_IID. This variable is typically available within GitLab CI/CD pipelines.
    檢索合併請求 ID:該腳本首先從環境變數 CI_MERGE_REQUEST_IID 中檢索合併請求 ID。該變數通常在 GitLab CI/CD 管道中可用。
  2. Checking for Existing Analysis: It then uses Get-ExistingComments to see if a previous "Code Analysis by AI" comment exists. If found, the script skips further processing to avoid duplicate analysis.
    檢查現有分析:然後它使用 Get-ExistingComments 來查看是否存在先前的「AI 代碼分析」評論。如果找到,腳本將跳過進一步處理以避免重複分析。
  3. Fetching Code Changes: If no prior analysis exists, the script retrieves the code changes for the merge request using Get-MergeRequestChanges.
    獲取代碼變更:如果不存在先前的分析,則腳本使用 Get-MergeRequestChanges 獲取合併請求的代碼變更。
  4. Analyzing Individual Files: It iterates through each changed file:
    分析個別檔案:它遍歷每個已更改的檔案:
  • Skipping Ignored Files: Files listed in the .aiignore file (similar to .gitignore) are skipped using $skipExtensions. This allows you to exclude specific files or file types from analysis.
    跳過被忽略的檔案:在 .aiignore 檔案中列出的檔案(類似於 .gitignore )將使用 $skipExtensions 被跳過。這使您可以排除特定的檔案或檔案類型進行分析。
  • OpenAI Analysis: The script calls Invoke-OpenAiCodeAnalysis to send the code changes of the current file to OpenAI for analysis.
    OpenAI 分析:該腳本調用 Invoke-OpenAiCodeAnalysis 將當前文件的代碼更改發送給 OpenAI 進行分析。
  • Chunking Analysis Results: The lengthy analysis response from OpenAI is split into smaller chunks using Split-String for easier comment creation.
    分塊分析結果:來自 OpenAI 的冗長分析回應被拆分成較小的部分,以便使用 Split-String 進行更容易的評論創建。
  • Posting Comments: For each analysis chunk:
    發表評論:對於每個分析區塊:
  • If the filename changes, a new comment is created with the filename and a disclaimer about potential inaccuracies in the analysis results.
    如果檔案名稱更改,將會創建一個新的註解,包含檔案名稱和有關分析結果潛在不準確性的免責聲明。
  • Otherwise, the analysis chunk is appended to the existing comment for the file.
    否則,分析區塊將附加到該文件的現有註釋中。
  • Finally, the script uses PostCommentToMergeRequest to post the generated comment to the GitLab merge request.
    最後,腳本使用 PostCommentToMergeRequest 將生成的評論發佈到 GitLab 合併請求中。

Integrating the Script into GitLab CI/CD Pipeline
將腳本整合到 GitLab CI/CD 管道中

To seamlessly incorporate the code analysis script into your GitLab workflow, you can add it as a dedicated stage in your .gitlab-ci.yml file. By doing so, the script will be invoked automatically whenever a new merge request event is created, ensuring thorough code review before merging changes into the main branch.
要將代碼分析腳本無縫地整合到您的 GitLab 工作流程中,您可以將其作為專用階段添加到您的 .gitlab-ci.yml 文件中。這樣,當創建新的合併請求事件時,該腳本將自動被調用,確保在將更改合併到主分支之前進行徹底的代碼審查。

1. Configure Parameters  1. 配置參數

Before integrating the script, ensure that you have configured the necessary parameters at the beginning of the script. This includes specifying GitLab API details, repository ID, and the OpenAI API key.
在整合腳本之前,請確保您已在腳本的開頭配置必要的參數。這包括指定 GitLab API 詳細信息、存儲庫 ID 和 OpenAI API 密鑰。

2. Define a New Stage
2. 定義一個新階段

In your .gitlab-ci.yml file, define a new stage specifically for invoking the code analysis script. This stage should trigger on the merge_request event to execute whenever a new merge request is created.
在您的 .gitlab-ci.yml 文件中,專門定義一個新階段以調用代碼分析腳本。此階段應在 merge_request 事件上觸發,以便在創建新的合併請求時執行。

stages:
- code_analysis

code_analysis:
stage: code_analysis
script:
- powershell -File path/to/your/script.ps1 -GitLabToken $GITLAB_TOKEN -GitLabApiUrl $GITLAB_API_URL -RepositoryId $REPOSITORY_ID -OpenAiApiKey $OPENAI_API_KEY
only:
- merge_requests

3. Trigger Execution  3. 觸發執行

Once you’ve added the script as a stage in your pipeline configuration, any new merge request event will trigger its execution. The script will automatically fetch the changes in the MR, analyze them using OpenAI, and post comments back to the MR with the analysis results.
一旦您將腳本添加為管道配置中的一個階段,任何新的合併請求事件將觸發其執行。該腳本將自動獲取合併請求中的變更,使用 OpenAI 進行分析,並將分析結果的評論發回合併請求。

Benefits and Considerations:
好處與考量:

This script offers several benefits:
這個腳本提供了幾個好處:

  • Automated Code Review: It automates the initial code analysis stage, saving developers valuable time.
    自動化代碼審查:它自動化了初始代碼分析階段,為開發人員節省了寶貴的時間。
  • Scalability: The script can handle large codebases with frequent changes efficiently.
    可擴展性:該腳本可以高效處理大型代碼庫及其頻繁變更。
  • Customization: You can configure the OpenAI model used for analysis and exclude specific files/extensions using the .aiignore file.
    自訂:您可以使用 .aiignore 檔案配置用於分析的 OpenAI 模型,並排除特定檔案/擴展名。

However, it’s important to consider these points:
然而,考慮這些要點是很重要的:

  • Accuracy: OpenAI models are still under development, and their analysis results might not always be accurate. Treat them as suggestions and conduct thorough human reviews alongside this automated analysis.
    準確性:OpenAI 模型仍在開發中,其分析結果可能並不總是準確的。將其視為建議,並在此自動分析的同時進行徹底的人類審查。
  • Security: Ensure your GitLab token and OpenAI API key are securely stored and not directly embedded in the script. Consider environment variables or secure credential storage solutions.
    安全性:確保您的 GitLab 令牌和 OpenAI API 密鑰安全存儲,並且不直接嵌入腳本中。考慮使用環境變量或安全憑證存儲解決方案。

Conclusion:  結論:

This script demonstrates how to leverage OpenAI’s capabilities to automate code analysis within your GitLab workflow. It streamlines the code review process and provides developers with additional insights into code changes. Remember, this automation serves as a helpful tool, but human expertise remains crucial for ensuring code quality.
此腳本演示了如何利用 OpenAI 的能力在您的 GitLab 工作流程中自動化代碼分析。它簡化了代碼審查過程,並為開發人員提供了有關代碼變更的額外見解。請記住,這種自動化作為一個有用的工具,但人類專業知識仍然對確保代碼質量至關重要。

The full code is available on GitHub. You can access it here
完整的代碼可在 GitHub 上獲得。您可以在這裡訪問它。

No responses yet  尚未收到回覆

To respond to this story,
get the free Medium app.

Recommended from Medium  來自 Medium 的推薦

Lists  列表

See more recommendations