核心摘要
- 通过EventBridge Rule监测CodeCommit的Pull Request事件,实现代码审核流程与业务CI/CD流水线的完全解耦
- Amazon Q Developer CLI作为核心审核引擎,结合自定义规则模板生成结构化的代码审核报告
- 审核结果自动以评论形式发布到对应Pull Request,支持S3备份存储,实现全流程自动化
Amazon Q Developer CLI 集成 CodeCommit 实现智能代码审核完整指南
代码审核的现实挑战与AI驱动的解决思路
代码质量保障在现代软件工程中扮演着至关重要的角色,而代码审核作为质量控制的核心手段,直接决定了软件产品的稳定性和长期可维护性。传统企业普遍依赖人工代码审核模式,由经验丰富的开发工程师对每次代码变更进行逐一检查和评估。这种方式虽然能够发挥人类专家的判断力,但也带来了显著的效率瓶颈:人工审核消耗大量人力资源和时间成本,而且由于审核人员的技术背景和经验存在差异,审核标准往往缺乏一致性,容易出现遗漏或过度审核的情况。
Amazon Q Developer是亚马逊云科技推出的AI驱动代码助手,能够在IDE和终端环境中提供代码生成、调试、优化建议以及AWS服务操作指导。与此同时,亚马逊云科技提供了完整的Code系列服务,支持端到端的CI/CD流水线解决方案,包括CodeCommit(Git代码仓库)、CodeBuild(构建和测试)、CodeDeploy(自动化部署)、CodePipeline(流水线编排)以及CodeGuru(代码质量和性能分析)。这套工具链为开发团队提供了从源码管理到生产部署的全链路自动化能力。
针对代码审核的效率和一致性挑战,将Amazon Q Developer CLI与Amazon CodeCommit、Amazon CodeBuild等服务进行集成,可以在现有的Amazon CodePipeline业务流水线基础上构建智能化的生成式AI代码审核解决方案。对于正在寻找多云账单代付解决方案的企业而言,这种架构设计同样适用于多云环境下的DevOps实践。
重要提示:本方案仅适用于现有Amazon CodeCommit用户。从2024年7月24日开始,新用户将无法创建Amazon CodeCommit仓库。
整体架构设计与技术选型
该方案的核心设计理念是通过EventBridge Rule监测CodeCommit中的Pull Request创建事件以及Pull Request源分支更新事件,触发CodeBuild构建代码审核源码,运行Amazon Q Developer CLI完成代码审核,并将审核结果以评论的形式发布到对应的Pull Request中。
这种架构的最大优势在于无需改动现有的业务流水线。通过独立部署代码审核方案所需的CodeCommit代码仓库、CodeBuild项目以及EventBridge Rule,即可实现完整的自动化代码审核流程,与业务CI/CD流水线完全解耦。
核心组件技术概览
整个方案的触发源为业务CI/CD流水线,代码审核方案与业务CI/CD流水线解耦,主要由以下服务构成:
- Amazon EventBridge Rule:由业务CI/CD流水线中的CodeCommit仓库作为触发源,在创建Pull Request或更新Pull Request源分支的情况下,触发代码审核方案中的CodeBuild构建流程。源仓库的Pull Request ID等信息会通过EventBridge Rule解析源分支中的Pull Request事件后传递给CodeBuild项目
- Amazon CodeCommit:代码仓库中包含buildspec.yml(实现代码审核的逻辑)以及code review prompts(代码审核所需的规范文件和prompt格式规范文件)
- Amazon Elastic Container Registry:存储包含Python、AWS CLI、Amazon Q Developer CLI等预装软件的Docker镜像
- Amazon CodeBuild:使用ECR镜像仓库中的Docker镜像作为基础环境,对CodeCommit仓库中的代码进行构建和审核
CodeCommit代码仓库结构详解
代码审核方案的CodeCommit仓库包含以下核心文件结构:
├── buildspec.yml # CodeBuild需要构建的环境 ├── code-review-rules/ # 审核规则目录 │ ├── improved_code_review_standards_part1.md # 一般原则、代码审查流程和检查清单(代码风格和代码质量) │ ├── improved_code_review_standards_part2.md # 功能实现、安全性和性能部分 │ ├── improved_code_review_standards_part3.md # 测试、日志记录、可维护性和特定场景 │ ├── improved_code_review_standards_part4.md # 语言特定检查点、中间件使用指南 │ └── llm_code_review_feedback_format.md # 审核报告规则 └── code-review-prompt.txt # Amazon Q Developer调用的代码审核提示词
代码审核提示词设计
code-review-prompt.txt文件定义了Amazon Q Developer CLI执行代码审核时使用的完整提示词。这个提示词的设计直接影响审核结果的质量和一致性:
你是一位专业的代码审核助手,负责根据预定义的代码审核规则对提交的代码变更进行全面审核。 审核规则文件 以下文件包含你需要遵循的详细代码审核规则: 1. code-review-rules/improved_code_review_standards_part1.md - 包含一般原则、代码审查流程和检查清单的第一部分(代码风格和代码质量) 2. code-review-rules/improved_code_review_standards_part2.md - 包含功能实现、安全性和性能部分 3. code-review-rules/improved_code_review_standards_part3.md - 包含测试、日志记录、可维护性和特定场景,如并发、事务、幂等性和远程调用 4. code-review-rules/improved_code_review_standards_part4.md - 包含语言特定的检查点、中间件使用指南、通信指南、工具推荐和持续改进 5. code-review-rules/llm_code_review_feedback_format.md - 审核反馈格式规范 审核流程 1. 首先,请仔细阅读并理解上述所有规则文件中的内容 2. 然后,审核 changes.txt 内列出的本次变更的代码文件 3. 根据 code-review-rules/llm_code_review_feedback_format.md 中定义的格式,生成审核反馈 4. 将审核结果以中文输出到 amazon_q_review.md 文件中 输出要求 • 审核反馈必须使用中文 • 严格遵循 llm_code_review_feedback_format.md 中的格式要求 • 提供具体、有建设性的反馈,包括问题描述和改进建议 • 只输出最终的审核报告内容,不要包含工具调用过程、文件操作详情或调试信息 • 直接输出markdown格式的审核报告,不要显示文件写入过程 • 对代码的优点也要给予肯定 • 只报告紧急程度为【阻塞】、【重要】和【一般】的问题,不要提供紧急程度为"建议"的问题 • 根据问题的严重程度进行分类: • 【阻塞】:必须修复才能合并的严重问题 • 【重要】:应当修复但不阻止合并的问题 • 【一般】:可以考虑修复的问题 完成后操作 1. 检查 amazon_q_review.md 文件,确保内容完整且符合格式要求 2. 完成后简单回复"完成",无需对任务做总结 请注意:整个过程中不要修改任何原始文件,只生成审核结果文件。
Buildspec.yml核心逻辑解析
buildspec.yml文件包含了代码审核的核心逻辑,涵盖凭证同步、参数获取、变更文件下载、审核执行和结果发布等完整流程。
Amazon Q凭证同步
在本地登录Amazon Q Developer后,通过以下命令将预配置的Amazon Q认证信息同步到CodeBuild环境中。~/.local/share/amazon-q/为Amazon Q Developer CLI的标准凭证目录:
aws s3 sync s3://code-family-code-review/amazonq-credentials/amazon-q/ ~/.local/share/amazon-q/
获取EventBridge传递的核心参数
从EventBridge传递的环境变量中获取PULL_REQUEST_ID和REPOSITORY_NAME,并通过AWS CLI准确获取创建的PR相关信息。使用AWS CLI获取业务CI/CD流水线中的commit和diff信息,避免使用git命令混淆业务目录和代码审核使用的CodeCommit目录:
PR_ID="${PULL_REQUEST_ID:-}"
REPO_NAME="${REPOSITORY_NAME:-unicorn-web-project}"
REGION="us-east-1"
aws codecommit get-pull-request \
--pull-request-id "$PR_ID" \
--region "$REGION" > pr_details.json
提取Commit信息
PR_SOURCE_COMMIT=$(grep -o '"sourceCommit"[[:space:]]*:[[:space:]]*"[^"]*"' pr_details.json | sed 's/.*"sourceCommit"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' | head -1) PR_DEST_COMMIT=$(grep -o '"destinationCommit"[[:space:]]*:[[:space:]]*"[^"]*"' pr_details.json | sed 's/.*"destinationCommit"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' | head -1)
获取变更文件列表
aws codecommit get-differences \
--repository-name "$REPO_NAME" \
--before-commit-specifier "$PR_DEST_COMMIT" \
--after-commit-specifier "$PR_SOURCE_COMMIT" \
--region "$REGION" \
--query 'differences[].afterBlob.path' \
--output text > changes.txt
调用Amazon Q Developer CLI执行代码审核
q chat -a -- "$(cat code-review-prompt.txt)"
发布审核结果
通过AWS CLI将审核结果以PR Comment的形式发布,同时可选择发布到S3中做备份:
# 可选:发布到S3进行备份
TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
BUILD_NUM=${CODEBUILD_BUILD_NUMBER:-$(date +%s)}
COMMIT_ID=$(git rev-parse --short HEAD)
S3_KEY="review-results/${TIMESTAMP}-build${BUILD_NUM}-${COMMIT_ID}-review.md"
aws s3 cp amazon_q_review_${CODEBUILD_BUILD_NUMBER}.md s3://code-family-code-review/${S3_KEY}
# 发布审核结果到PR Comment
aws codecommit post-comment-for-pull-request \
--pull-request-id "$PR_ID" \
--repository-name "$REPO_NAME" \
--before-commit-id "$PR_DEST_COMMIT" \
--after-commit-id "$PR_SOURCE_COMMIT" \
--content "$(cat comment_content.md)" \
--region us-east-1
完整Buildspec.yml参考配置
以下为完整的buildspec.yml配置,请根据实际需求定义Amazon Q Developer CLI凭证存储路径、代码审核结果存储的S3路径以及区域等参数信息:
version: 0.2
phases:
install:
commands:
- echo Installing prerequisites...
- aws s3 sync s3://<请填入您的s3文件夹路径> ~/.local/share/amazon-q/
- echo Amazon Q credentials synced.
pre_build:
commands:
- echo Initializing environment
- echo "=== Getting PR Information from EventBridge ==="
- |
# 从EventBridge传递的环境变量获取PR信息
PR_ID="${PULL_REQUEST_ID:-}"
REPO_NAME="${REPOSITORY_NAME:-unicorn-web-project}"
# 请替换为您的服务所在的区域信息
REGION="us-east-1"
echo "PR ID from EventBridge: $PR_ID"
echo "Repository Name: $REPO_NAME"
if [ -z "$PR_ID" ]; then
echo "ERROR: No PR ID provided from EventBridge"
exit 1
fi
echo "=== Getting PR Details ==="
aws codecommit get-pull-request \
--pull-request-id "$PR_ID" \
--region "$REGION" > pr_details.json
if [ $? -ne 0 ]; then
echo "ERROR: Failed to get PR details for PR ID: $PR_ID"
exit 1
fi
# 提取sourceCommit和destinationCommit
PR_SOURCE_COMMIT=$(grep -o '"sourceCommit"[[:space:]]*:[[:space:]]*"[^"]*"' pr_details.json | sed 's/.*"sourceCommit"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' | head -1)
PR_DEST_COMMIT=$(grep -o '"destinationCommit"[[:space:]]*:[[:space:]]*"[^"]*"' pr_details.json | sed 's/.*"destinationCommit"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/' | head -1)
echo "✓ Successfully retrieved PR details:"
echo "✓ PR ID: $PR_ID"
echo "✓ Source commit: $PR_SOURCE_COMMIT"
echo "✓ Destination commit: $PR_DEST_COMMIT"
# 验证commit信息
if [ -z "$PR_SOURCE_COMMIT" ] || [ -z "$PR_DEST_COMMIT" ] || [ "$PR_SOURCE_COMMIT" = "null" ] || [ "$PR_DEST_COMMIT" = "null" ]; then
echo "ERROR: Invalid commit information retrieved"
exit 1
fi
echo "=== Getting Changed Files via AWS CLI ==="
aws codecommit get-differences \
--repository-name "$REPO_NAME" \
--before-commit-specifier "$PR_DEST_COMMIT" \
--after-commit-specifier "$PR_SOURCE_COMMIT" \
--region "$REGION" \
--query 'differences[].afterBlob.path' \
--output text > changes.txt
echo "Changed files:"
cat changes.txt
# 确保changes.txt不为空
if [ ! -s changes.txt ]; then
echo "No changes detected in PR"
echo "No files to review" > changes.txt
fi
echo "=== Downloading Changed Files for Review ==="
mkdir -p review-files
while IFS= read -r file_path; do
if [ -n "$file_path" ] && [ "$file_path" != "No files to review" ]; then
echo "Downloading file: $file_path"
mkdir -p "review-files/$(dirname "$file_path")" 2>/dev/null || true
if aws codecommit get-file \
--repository-name "$REPO_NAME" \
--commit-specifier "$PR_SOURCE_COMMIT" \
--file-path "$file_path" \
--region "$REGION" \
--query 'fileContent' \
--output text | base64 -d > "review-files/$file_path"; then
echo "✓ Downloaded: $file_path"
else
echo "⚠ Failed to download: $file_path"
fi
fi
done < changes.txt
build:
commands:
- echo Build started on `date`
- echo "=== Running Amazon Q Developer CLI for code review ==="
- |
echo "Running Amazon Q with standardized prompt..."
q chat -a -- "$(cat code-review-prompt.txt)"
cp amazon_q_review.md amazon_q_review_${CODEBUILD_BUILD_NUMBER}.md
post_build:
commands:
- echo Build completed on `date`
- echo "=== Processing Review Results ==="
- |
if [ -f "amazon_q_review_${CODEBUILD_BUILD_NUMBER}.md" ]; then
TIMESTAMP=$(date +"%Y%m%d-%H%M%S")
BUILD_NUM=${CODEBUILD_BUILD_NUMBER:-$(date +%s)}
COMMIT_ID=$(git rev-parse --short HEAD)
S3_KEY="review-results/${TIMESTAMP}-build${BUILD_NUM}-${COMMIT_ID}-review.md"
# 上传到S3(可选)
aws s3 cp amazon_q_review_${CODEBUILD_BUILD_NUMBER}.md s3://code-family-code-review/${S3_KEY}
echo "Review report uploaded to s3://code-family-code-review/${S3_KEY}"
fi
- echo "=== Adding Comment to Pull Request ==="
- |
if [ -f "amazon_q_review_${CODEBUILD_BUILD_NUMBER}.md" ]; then
REPO_NAME="${REPOSITORY_NAME:-unicorn-web-project}"
if [ -n "$PR_ID" ] && [ -n "$PR_DEST_COMMIT" ] && [ -n "$PR_SOURCE_COMMIT" ]; then
# 创建comment内容
cat > comment_content.md << EOF
## 自动代码审查报告
---
**生成时间:** $(date +"%Y-%m-%d %H:%M:%S")
**构建编号:** ${BUILD_NUM}
**审查范围:** ${PR_DEST_COMMIT:0:8}...${PR_SOURCE_COMMIT:0:8}
---
EOF
cat amazon_q_review_${CODEBUILD_BUILD_NUMBER}.md >> comment_content.md
# 发布到PR
aws codecommit post-comment-for-pull-request \
--pull-request-id "$PR_ID" \
--repository-name "$REPO_NAME" \
--before-commit-id "$PR_DEST_COMMIT" \
--after-commit-id "$PR_SOURCE_COMMIT" \
--content "$(cat comment_content.md)" \
--region us-east-1
fi
fi
artifacts:
files:
- amazon_q_review_*.md
- review_summary.md
- comment_content.md
- review-files/**/*
discard-paths: no
CodeBuild部署配置
构建Dockerfile并上传ECR
以下为参考的Dockerfile,主要实现AWS CLI、Python库、Amazon Q Developer CLI等软件安装的预置环境:
# 基于官方Ubuntu 22.04基础镜像
FROM ubuntu:22.04
# 避免交互提示
ENV DEBIAN_FRONTEND=noninteractive
ENV TZ=Asia/Shanghai
# 设置时区
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安装基础依赖软件包
RUN apt-get update && apt-get install -y --no-install-recommends \
curl \
python3 \
python3-pip \
git \
unzip \
ca-certificates \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
# 安装AWS CLI v2
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && \
unzip awscliv2.zip && \
./aws/install && \
rm -rf awscliv2.zip aws/
# 安装Amazon Q Developer CLI
RUN curl --proto '=https' --tlsv1.2 -sSf https://desktop-release.q.us-east-1.amazonaws.com/latest/amazon-q.deb -o amazon-q.deb && \
apt-get update && \
apt-get install -y ./amazon-q.deb && \
rm amazon-q.deb && \
rm -rf /var/lib/apt/lists/*
# 安装Python库
RUN pip3 install --no-cache-dir \
requests \
boto3 \
aiohttp \
asyncio \
pathlib
# 设置工作目录
WORKDIR /build
# 默认Entrypoint为bash
ENTRYPOINT [ "bash" ]
CodeBuild核心设置要点
配置CodeBuild项目时需要注意以下关键设置:
- IAM角色权限:确保CodeBuild的角色可以访问CloudWatch(用于发布CodeBuild相关日志信息)、S3桶(用于上传Amazon Q Developer CLI凭证以及代码审核结果)、ECR(用于获取Docker镜像)以及对应的CodeCommit仓库
- Source provider:选择代码审核方案使用的CodeCommit仓库地址,不要选择业务CI/CD流水线中的CodeCommit仓库
- Reference type:确保固定为main分支
- 环境设置:选择Amazon ECR,添加前面Dockerfile使用的ECR仓库地址
EventBridge Rule配置详解
通过EventBridge Rule设置触发源为业务CodeCommit仓库,从而解耦业务CI/CD流水线与代码审核的CI/CD流水线。这种设计允许灵活添加触发源,无需将代码审核的逻辑更新到所有的业务CI/CD中。
创建EventBridge Rule
创建EventBridge Rule时,Rule type选择“Rule with an event pattern”。可以选择”AWS events or EventBridge partner events”使用预置的事件模板,也可以选择Other类型自定义事件模式。
本方案选择的事件类型为pullRequestCreated和pullRequestSourceBranchUpdated。在”Custom pattern(JSON editor)”中填入以下JSON事件模式,注意在”resources”字段填入需要进行代码审核的CodeCommit repository ARN:
{
"source": ["aws.codecommit"],
"detail-type": ["CodeCommit Pull Request State Change"],
"resources": ["<请填入需要进行代码审核的CodeCommit repository ARN>"],
"detail": {
"event": ["pullRequestCreated", "pullRequestSourceBranchUpdated"]
}
}
配置Target
在”Select target(s)”部分选择CodeBuild project作为目标,填入Project ARN(可在CodeBuild Project的”Project Details”中找到),选择默认创建新的角色。
配置Input Transformer
展开”Additional settings”部分,选择Input transformer作为”Configure target input”。
Input Path(从原始事件中提取特定字段):
{
"destinationReference": "$.detail.destinationReference",
"pullRequestId": "$.detail.pullRequestId",
"repositoryName": "$.detail.repositoryNames[0]",
"sourceReference": "$.detail.sourceReference"
}
Input Template(将提取的数据重新格式化为CodeBuild所需的参数):
{
"environmentVariablesOverride": [
{
"name": "PULL