简介
本指南解释了如何将 OpenAI 推理模型集成到您的 GitHub Pull Request (PR) 工作流程中,以自动审查代码的质量、安全性和企业标准合规性。通过在开发过程的早期利用 AI 驱动的洞察,您可以更快地发现问题,减少手动工作量,并在整个代码库中保持一致的最佳实践。
为什么要在 PR 中集成 OpenAI 推理模型?
• 通过自动检测代码异味、安全漏洞和样式不一致性,节省代码审查时间。
• 在整个组织范围内强制执行编码标准,以获得一致、可靠的代码。
• 为开发人员提供关于潜在改进的及时、AI 引导的反馈。
用例示例
• 审查者希望在合并之前获得关于新代码更改安全性的反馈。
• 团队寻求强制执行标准编码指南,确保整个组织代码质量的一致性。
先决条件
1. 生成 OpenAI “项目密钥”
- 访问 platform.openai.com/api-keys 并点击创建新的密钥。
- 将令牌安全地存储在您的 GitHub 仓库 secrets 中,命名为 OPENAI_API_KEY。
2. 选择您的 OpenAI 模型
使用 OpenAI 推理模型 对代码更改进行深入分析。从最先进的模型开始,并根据需要优化您的提示。
3. 选择一个 Pull Request
- 确认您的仓库已启用 GitHub Actions。
- 确保您有权限配置仓库 secrets 或变量(例如,用于您的 PROMPT、MODELNAME 和 BEST_PRACTICES 变量)。
4. 定义企业编码标准
将您的标准存储为仓库变量 (BEST_PRACTICES)。这些可能包括
• 代码风格 & 格式化
• 可读性 & 可维护性
• 安全性 & 合规性
• 错误处理 & 日志记录
• 性能 & 可扩展性
• 测试 & 质量保证
• 文档 & 版本控制
• 可访问性 & 国际化
5. 定义提示内容
构建一个元提示,以指导 OpenAI 进行安全性、质量和最佳实践检查。包括
- 代码质量 & 标准
- 安全性 & 漏洞分析
- 容错性 & 错误处理
- 性能 & 资源管理
- 逐步验证
鼓励 OpenAI 提供彻底的、逐行审查,并附带明确的建议。
创建您的 GitHub Actions 工作流程
此 GitHub Actions 工作流程在每次针对主分支的 pull request 时触发,并包含两个 job。第一个 job 收集所有更改文件的差异(排除 .json 和 .png 文件),并将这些更改发送到 OpenAI 进行分析。来自 OpenAI 的任何建议修复都包含在 PR 的评论中。第二个 job 根据您定义的企业标准评估 PR,并返回一个 markdown 表格,总结代码对这些标准的遵守情况。您可以通过更新变量(如提示、模型名称和最佳实践)轻松调整或优化工作流程。
name: PR Quality and Security Check
on:
pull_request:
branches: [main]
permissions:
contents: read
pull-requests: write
jobs:
quality-security-analysis:
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v3
with:
fetch-depth: 0 # Ensure full history for proper diff
- name: Gather Full Code From Changed Files
run: |
CHANGED_FILES=$(git diff --name-only origin/main...HEAD)
echo '{"original files": [' > original_files_temp.json
for file in $CHANGED_FILES; do
if [[ $file == *.json ]] || [[ $file == *.png ]]; then
continue
fi
if [ -f "$file" ]; then
CONTENT=$(jq -Rs . < "$file")
echo "{\"filename\": \"$file\", \"content\": $CONTENT}," >> original_files_temp.json
fi
done
sed -i '$ s/,$//' original_files_temp.json
echo "]}" >> original_files_temp.json
- name: Display Processed Diff (Debug)
run: cat original_files_temp.json
- name: Get Diff
run: |
git diff origin/main...HEAD \
| grep '^[+-]' \
| grep -Ev '^(---|\+\+\+)' > code_changes_only.txt
jq -Rs '{diff: .}' code_changes_only.txt > diff.json
if [ -f original_files_temp.json ]; then
jq -s '.[0] * .[1]' diff.json original_files_temp.json > combined.json
mv combined.json diff.json
- name: Display Processed Diff (Debug)
run: cat diff.json
- name: Analyze with OpenAI
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
DIFF_CONTENT=$(jq -r '.diff' diff.json)
ORIGINAL_FILES=$(jq -r '."original files"' diff.json)
PROMPT="Please review the following code changes for any obvious quality or security issues. Provide a brief report in markdown format:\n\nDIFF:\n${DIFF_CONTENT}\n\nORIGINAL FILES:\n${ORIGINAL_FILES}"
jq -n --arg prompt "$PROMPT" '{
"model": "gpt-4",
"messages": [
{ "role": "system", "content": "You are a code reviewer." },
{ "role": "user", "content": $prompt }
]
}' > request.json
curl -sS https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer ${OPENAI_API_KEY}" \
-d @request.json > response.json
- name: Extract Review Message
id: extract_message
run: |
ASSISTANT_MSG=$(jq -r '.choices[0].message.content' response.json)
{
echo "message<<EOF"
echo "$ASSISTANT_MSG"
echo "EOF"
} >> $GITHUB_OUTPUT
- name: Post Comment to PR
env:
COMMENT: ${{ steps.extract_message.outputs.message }}
GH_TOKEN: ${{ github.token }}
run: |
gh api \
repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments \
-f body="$COMMENT"
enterprise-standard-check:
runs-on: ubuntu-latest
needs: [quality-security-analysis]
steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0 # ensures we get both PR base and head
- name: Gather Full Code From Changed Files
run: |
# Identify changed files from the base (origin/main) to the pull request HEAD
CHANGED_FILES=$(git diff --name-only origin/main...HEAD)
# Build a JSON array containing filenames and their content
echo '{"original files": [' > original_files_temp.json
for file in $CHANGED_FILES; do
# Skip .json and .txt files
if [[ $file == *.json ]] || [[ $file == *.txt ]]; then
continue
fi
# If the file still exists (i.e., wasn't deleted)
if [ -f "$file" ]; then
CONTENT=$(jq -Rs . < "$file")
echo "{\"filename\": \"$file\", \"content\": $CONTENT}," >> original_files_temp.json
fi
done
# Remove trailing comma on the last file entry and close JSON
sed -i '$ s/,$//' original_files_temp.json
echo "]}" >> original_files_temp.json
- name: Analyze Code Against Best Practices
id: validate
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
set -e
# Read captured code
ORIGINAL_FILES=$(cat original_files_temp.json)
# Construct the prompt:
# - Summarize each best-practice category
# - Provide a rating for each category: 'extraordinary', 'acceptable', or 'poor'
# - Return a Markdown table titled 'Enterprise Standards'
PROMPT="You are an Enterprise Code Assistant. Review each code snippet below for its adherence to the following categories:
1) Code Style & Formatting
2) Security & Compliance
3) Error Handling & Logging
4) Readability & Maintainability
5) Performance & Scalability
6) Testing & Quality Assurance
7) Documentation & Version Control
8) Accessibility & Internationalization
Using \${{ vars.BEST_PRACTICES }} as a reference, assign a rating of 'extraordinary', 'acceptable', or 'poor' for each category. Return a markdown table titled 'Enterprise Standards' with rows for each category and columns for 'Category' and 'Rating'.
Here are the changed file contents to analyze:
$ORIGINAL_FILES"
# Create JSON request for OpenAI
jq -n --arg system_content "You are an Enterprise Code Assistant ensuring the code follows best practices." \
--arg user_content "$PROMPT" \
'{
"model": "${{ vars.MODELNAME }}",
"messages": [
{
"role": "system",
"content": $system_content
},
{
"role": "user",
"content": $user_content
}
]
}' > request.json
# Make the API call
curl -sS https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d @request.json > response.json
# Extract the model's message
ASSISTANT_MSG=$(jq -r '.choices[0].message.content' response.json)
# Store for next step
{
echo "review<<EOF"
echo "$ASSISTANT_MSG"
echo "EOF"
} >> $GITHUB_OUTPUT
- name: Post Table Comment
env:
COMMENT: ${{ steps.validate.outputs.review }}
GH_TOKEN: ${{ github.token }}
run: |
# If COMMENT is empty or null, skip posting
if [ -z "$COMMENT" ] || [ "$COMMENT" = "null" ]; then
echo "No comment to post."
exit 0
fi
gh api \
repos/${{ github.repository }}/issues/${{ github.event.pull_request.number }}/comments \
-f body="$COMMENT"
测试工作流程
将此工作流程提交到您的仓库,然后打开一个新的 PR。工作流程将自动运行,并将 AI 生成的反馈作为 PR 评论发布。
对于公开示例,请参阅 OpenAI-Forum 仓库的工作流程:pr_quality_and_security_check.yml。