Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions .aireviewrc.yml

This file was deleted.

123 changes: 123 additions & 0 deletions .github/generate-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#!/usr/bin/env node
/* eslint-disable node/prefer-global/process */
/* eslint-disable no-console */
/**
* AI代码审查配置文件生成脚本 (Node.js版本)
*
* 用法:
* node generate-config.js [--output <配置文件路径>]
*/

const fs = require('node:fs')
const path = require('node:path')
const yaml = require('yaml')

// 解析命令行参数
function parseArgs() {
const args = process.argv.slice(2)
const params = { output: '.aireviewrc.yml' }

for (let i = 0; i < args.length; i++) {
if (args[i] === '--output' && i + 1 < args.length) {
params.output = args[i + 1]
i++
}
}

return params
}

// 构建配置对象
function buildConfig() {
return {
ai: {
provider: process.env.AI_REVIEWER_PROVIDER || 'openai',
model: process.env.AI_REVIEWER_MODEL || 'gpt-3.5-turbo',
apiKey: process.env.AI_REVIEWER_OPENAI_KEY || '',
baseUrl: process.env.AI_REVIEWER_BASE_URL || 'https://api.openai.com/v1',
temperature: Number.parseFloat(process.env.AI_REVIEWER_TEMPERATURE || '0.1'),
maxTokens: Number.parseInt(process.env.AI_REVIEWER_MAX_TOKENS || '4000', 10),
},
platform: {
type: process.env.AI_REVIEWER_PLATFORM_TYPE || 'github',
token: process.env.GITHUB_TOKEN || process.env.AI_REVIEWER_PLATFORM_TOKEN || '',
url: process.env.AI_REVIEWER_PLATFORM_URL || '',
},
notifications: {
gitlab_comment: process.env.AI_REVIEWER_GITLAB_COMMENT === 'true',
wecom: {
enabled: process.env.WECOM_ENABLED === 'true',
webhook: process.env.WECOM_WEBHOOK || '',
},
},
review: {
prompts: {
system: process.env.AI_REVIEWER_PROMPT_SYSTEM
|| '你是一个代码审查助手,擅长识别代码中的问题并提供改进建议。审核报告最后需要加上审核平台来自:https://github.com/h7ml/ai-code-reviewer AI Code Reviewer 的 workflow工作流',
review: process.env.AI_REVIEWER_PROMPT_REVIEW
|| '请审查此代码: {{filePath}}',
summary: process.env.AI_REVIEWER_PROMPT_SUMMARY
|| '请总结代码审查结果',
},
ignoreFiles: [
'*.lock',
'package-lock.json',
'*.min.js',
],
ignorePaths: [
'node_modules/',
'dist/',
],
},
}
}

// 生成配置文件
function generateConfig() {
const args = parseArgs()
const outputFile = args.output

console.log(`正在生成配置文件: ${outputFile}`)

try {
// 构建配置对象
const config = buildConfig()

// 转换为YAML格式
const yamlContent = yaml.stringify(config)

// 确保输出目录存在
const outputDir = path.dirname(outputFile)
if (!fs.existsSync(outputDir)) {
fs.mkdirSync(outputDir, { recursive: true })
}

// 写入文件
fs.writeFileSync(outputFile, yamlContent, 'utf8')

// 验证文件是否写入成功
if (!fs.existsSync(outputFile)) {
console.error(`错误: 配置文件 ${outputFile} 未成功创建`)
process.exit(1)
}

const stats = fs.statSync(outputFile)
if (stats.size < 10) {
console.error(`错误: 配置文件 ${outputFile} 为空或几乎为空`)
process.exit(1)
}

console.log(`配置文件 ${outputFile} 创建成功,大小: ${stats.size} 字节`)

// 可选: 输出配置文件内容
// console.log('配置内容预览:');
// console.log(yamlContent.split('\n').slice(0, 5).join('\n'));
}
catch (error) {
console.error(`生成配置文件时出错: ${error.message}`)
process.exit(1)
}
}

// 执行主函数
generateConfig()
104 changes: 104 additions & 0 deletions .github/generate-config.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/bin/bash

# AI代码审查配置文件生成脚本
# 用法: ./generate-config.sh [--output <配置文件路径>]

set -e

# 默认配置文件路径
OUTPUT_FILE=".aireviewrc.yml"

# 解析命令行参数
while [[ $# -gt 0 ]]; do
case $1 in
--output)
OUTPUT_FILE="$2"
shift 2
;;
*)
echo "未知参数: $1"
echo "用法: ./generate-config.sh [--output <配置文件路径>]"
exit 1
;;
esac
done

echo "正在生成配置文件: $OUTPUT_FILE"

# 验证API密钥
if [ -z "$AI_REVIEWER_OPENAI_KEY" ]; then
echo "错误: AI_REVIEWER_OPENAI_KEY 环境变量未设置"
exit 1
fi

# 验证API密钥格式
if [[ ! "$AI_REVIEWER_OPENAI_KEY" =~ ^(sk-|sk-or-) ]]; then
echo "错误: AI_REVIEWER_OPENAI_KEY 格式不正确"
echo "API密钥应以sk-或sk-or-开头"
echo "当前密钥前缀: ${AI_REVIEWER_OPENAI_KEY:0:5}..."
exit 1
fi

# 创建配置文件
cat > "$OUTPUT_FILE" << EOF
ai:
provider: 'openai'
model: 'deepseek/deepseek-chat-v3-0324:free'
apiKey: '${AI_REVIEWER_OPENAI_KEY}'
baseUrl: 'https://openrouter.ai'
temperature: '0.1'
maxTokens: '4000'

platform:
type: 'github'
token: '${AI_REVIEWER_GITHUB_TOKEN}'
url: 'https://api.github.com'

notifications:
gitlab_comment: 'false'
wecom:
enabled: 'false'
webhook: ''

review:
prompts:
system: |
${AI_REVIEWER_PROMPT_SYSTEM:-你是一个代码审查助手,擅长识别代码中的问题并提供改进建议。审核报告最后需要加上审核平台来自:https://github.com/h7ml/ai-code-reviewer AI Code Reviewer 的 workflow工作流}
review: |
${AI_REVIEWER_PROMPT_REVIEW:-请审查此代码: {{filePath}}}
summary: |
${AI_REVIEWER_PROMPT_SUMMARY:-请总结代码审查结果}
ignoreFiles:
- '*.lock'
- 'package-lock.json'
- '*.min.js'
ignorePaths:
- 'node_modules/'
- 'dist/'
EOF

# 验证配置文件是否生成成功
if [ ! -f "$OUTPUT_FILE" ]; then
echo "错误: 配置文件 $OUTPUT_FILE 未成功创建"
exit 1
fi

# 检查文件大小确保有内容
file_size=$(stat -c%s "$OUTPUT_FILE" 2>/dev/null || stat -f%z "$OUTPUT_FILE")
if [ "$file_size" -lt 10 ]; then
echo "错误: 配置文件 $OUTPUT_FILE 为空或几乎为空"
exit 1
fi

# 验证API密钥是否正确写入
if ! grep -q "apiKey: '${AI_REVIEWER_OPENAI_KEY}'" "$OUTPUT_FILE"; then
echo "错误: API密钥未正确写入配置文件"
exit 1
fi

echo "配置文件 $OUTPUT_FILE 创建成功,大小: $file_size 字节"

# 可选: 输出配置文件前5行进行检查
# head -n 5 "$OUTPUT_FILE"

exit 0
150 changes: 150 additions & 0 deletions .github/validate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
#!/bin/bash

echo "开始设置和验证..."

# 初始化错误收集
ERRORS=()

# 检查必要的环境变量
echo "检查环境变量..."
required_vars=(
"GITHUB_REPOSITORY"
"GITHUB_REPOSITORY_OWNER"
"GITHUB_EVENT_NAME"
"GITHUB_EVENT_PATH"
"GITHUB_OUTPUT"
)

for var in "${required_vars[@]}"; do
if [ -z "${!var}" ]; then
echo "::error::缺少必要的环境变量: $var"
ERRORS+=("缺少必要的环境变量: $var")
else
echo "环境变量 $var 已设置"
fi
done

# 生成配置文件
echo "正在生成配置文件..."
if ! .github/generate-config.sh --output .aireviewrc.yml; then
echo "::error::配置文件生成失败"
ERRORS+=("配置文件生成失败")
else
echo "配置文件生成成功"
fi

# 验证配置文件
echo "验证配置文件..."
if [ ! -f ".aireviewrc.yml" ]; then
echo "::error::配置文件不存在"
ERRORS+=("配置文件不存在")
else
file_size=$(stat -c%s ".aireviewrc.yml" 2>/dev/null || stat -f%z ".aireviewrc.yml")
echo "配置文件大小: $file_size 字节"
if [ "$file_size" -lt 10 ]; then
echo "::error::配置文件为空"
ERRORS+=("配置文件为空")
fi
fi

# 验证API密钥
echo "验证API密钥..."
if [ -z "$API_KEY" ]; then
echo "::error::API密钥未设置"
ERRORS+=("API密钥未设置")
elif [[ ! "$API_KEY" =~ ^(sk-|sk-or-) ]]; then
echo "::error::API密钥格式无效"
ERRORS+=("API密钥格式无效")
else
echo "API密钥验证成功"
fi

# 验证GitHub Token
echo "验证GitHub Token..."
if [ -z "$AI_REVIEWER_GITHUB_TOKEN" ]; then
echo "::error::GitHub Token未设置"
ERRORS+=("GitHub Token未设置")
else
# 测试API连接和权限
echo "测试仓库访问权限..."
repo_response=$(curl -s -w "%{http_code}" \
-H "Accept: application/vnd.github+json" \
-H "Authorization: token $AI_REVIEWER_GITHUB_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/$GITHUB_REPOSITORY")
repo_status=${repo_response: -3}
repo_body=${repo_response:0:${#repo_response}-3}

echo "测试Issues访问权限..."
issues_response=$(curl -s -w "%{http_code}" \
-H "Accept: application/vnd.github+json" \
-H "Authorization: token $AI_REVIEWER_GITHUB_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/$GITHUB_REPOSITORY/issues")
issues_status=${issues_response: -3}
issues_body=${issues_response:0:${#issues_response}-3}

if [ "$repo_status" = "200" ] && [ "$issues_status" = "200" ]; then
echo "GitHub Token权限验证成功"
echo "- 仓库访问权限: 通过"
echo "- Issues访问权限: 通过"
else
echo "::error::GitHub Token权限验证失败"
if [ "$repo_status" != "200" ]; then
echo "仓库访问失败: $repo_status"
echo "响应: $repo_body"
ERRORS+=("GitHub Token缺少仓库访问权限: $repo_status $repo_body")
fi
if [ "$issues_status" != "200" ]; then
echo "Issues访问失败: $issues_status"
echo "响应: $issues_body"
ERRORS+=("GitHub Token缺少Issues访问权限: $issues_status $issues_body")
fi
fi
fi

# 获取PR信息
echo "获取PR信息..."
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
# 从事件文件中获取PR编号
PR_NUMBER=$(jq -r '.pull_request.number' "$GITHUB_EVENT_PATH")
else
# 从输入参数获取PR编号
PR_NUMBER=${{ inputs.pr_number }}
fi

if [ -z "$PR_NUMBER" ]; then
echo "::error::无法获取PR编号"
ERRORS+=("无法获取PR编号")
else
echo "PR编号: $PR_NUMBER"
# 验证PR是否存在
response=$(curl -s -w "%{http_code}" \
-H "Accept: application/vnd.github+json" \
-H "Authorization: token $AI_REVIEWER_GITHUB_TOKEN" \
-H "X-GitHub-Api-Version: 2022-11-28" \
"https://api.github.com/repos/$GITHUB_REPOSITORY/pulls/$PR_NUMBER")
status_code=${response: -3}
body=${response:0:${#response}-3}

if [ "$status_code" = "200" ]; then
echo "PR验证成功"
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
else
echo "::error::PR #$PR_NUMBER 不存在或无法访问"
echo "状态码: $status_code"
echo "响应: $body"
ERRORS+=("PR #$PR_NUMBER 不存在或无法访问: $status_code $body")
fi
fi

# 设置验证状态
if [ ${#ERRORS[@]} -eq 0 ]; then
echo "所有验证通过"
echo "setup_valid=true" >> $GITHUB_OUTPUT
else
echo "发现 ${#ERRORS[@]} 个错误"
echo "setup_valid=false" >> $GITHUB_OUTPUT
# 将错误信息转换为单行字符串
echo "errors=$(printf '%s\n' "${ERRORS[@]}" | tr '\n' '|')" >> $GITHUB_OUTPUT
fi
Loading
Loading