背景
代码质量保障是现代软件工程中不可或缺的重要组成部分,而代码审核作为质量控制的核心手段,直接影响着软件产品的稳定性和可维护性。长期以来,企业普遍采用人工代码审核模式,主要由经验丰富的开发工程师对代码变更进行逐一检查和评估。但是人工审核不仅消耗大量人力资源和时间成本,并且由于审核人员的技术背景和经验差异,容易导致审核标准缺乏一致性。
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代码审核解决方案,以实现更高效、标准化的代码审核流程。
在开始本文之前,如果您希望了解如何将Amazon Q Developer集成到其他CI/CD工具中,请参考:
**** *请注意,本文仅适用于现有Amazon CodeCommit* *用户,* *从2024* *年7* *月24* *日开始新用户将无法创建Amazon CodeCommit*
架构设计
本文主要通过Event Bridge Rule监测CodeCommit中的pull request创建事件以及pull request源分支更新事件触发CodeBuild,构建代码审核源码,运行Amazon Q Developer CLI完成代码审核并将审核结果以评论的形式发布到对应的pull request中。
本文所涉及的方案无需改动现有的业务流水线,通过部署代码审核方案所需的CodeCommit代码仓库, CodeBuild项目,以及 Event Bridge Rule即可实现完整的自动化代码审核流程。
架构图
技术概览
从上述架构图中可以看到,整个方案的触发源为业务CI/CD流水线,代码审核方案与业务CI/CD流水线解耦,主要由以下服务构成:
- Amazon Event Bridge Rule: 由业务CI/CD流水线中的CodeCommit仓库作为触发源,在创建pull request或更新pull request源分支的情况下,会触发代码审核方案中的CodeBuild构建代码审核流程。其中源仓库的pull request ID等信息会通过Event Bridge rule解析源分支中的pull request事件之后传递给代码审核方案中的CodeBuild项目
- Amazon CodeCommit: CodeCommit代码仓库中主要包含了以下核心文件
- yml: 实现代码审核的逻辑
- code review prompts: 主要包含代码审核所需的规范文件,prompt格式规范文件等
- Amazon Elastic Container Registry:包含Python、AWS CLI、Amazon Q Developer CLI等预装软件的Docker镜像存储在ECR仓库中。
- Amazon CodeBuild: 使用ECR镜像仓库中的Docker镜像作为基础环境,对CodeCommit仓库中的代码进行构建。
Code Commit 代码仓库
以下为CodeCommit的代码仓库中包含的内容
├── buildspec.yml #Code Build需要构建的环境
├── 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_rules中的规则模板
code-review-rules
可以通过该GitHub找到
code-review-prompt.txt:
你是一位专业的代码审核助手,负责根据预定义的代码审核规则对提交的代码变更进行全面审核。
审核规则文件
以下文件包含你需要遵循的详细代码审核规则:
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 中的格式要求,参考llm_code_review_feedback_format.md中的输出格式
• 提供具体、有建设性的反馈,包括问题描述和改进建议
• 只输出最终的审核报告内容,不要包含工具调用过程、文件操作详情或调试信息
• 直接输出markdown格式的审核报告,不要显示文件写入过程
• 对代码的优点也要给予肯定
• 只报告紧急程度为【阻塞】、【重要】和【一般】的问题,不要提供紧急程度为”建议”的问题
• 根据问题的严重程度进行分类:
• 【阻塞】:必须修复才能合并的严重问题
• 【重要】:应当修复但不阻止合并的问题
• 【一般】:可以考虑修复的问题
完成后操作
1. 检查 amazon_q_review.md 文件,确保内容完整且符合格式要求
2. 完成后简单回复”完成”,无需对任务做总结
请注意:整个过程中不要修改任何原始文件,只生成审核结果文件。
Buildspec.yml
buildspec.yml中包含了代码审核的核心逻辑,具体实现如下:
- Amazon Q凭证同步:在本地登陆Amazon Q Developer后,通过如下命令将预配置的Amazon Q认证信息同步,~/.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中传递过来的核心参数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″
… …
GenDev 智能开发:Amazon Q Developer CLI 赋能Amazon Code Family实现代码审核
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供参考,请根据需求定义Amazon Q Developer CLI凭证存存储的路径,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 ===”
直接使用EventBridge传递的PR ID获取PR详细信息
echo “Getting PR details for PR: $PR_ID”
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”
echo “Source commit: ‘$PR_SOURCE_COMMIT'”
echo “Destination commit: ‘$PR_DEST_COMMIT'”
exit 1
fi
echo “=== Getting Changed Files via AWS CLI ===”
使用AWS CLI获取变更文件列表,替代git clone + git diff
echo “Getting differences between commits via AWS CodeCommit API”
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
if [ $? -ne 0 ]; then
echo “ERROR: Failed to get differences for repository: $REPO_NAME”
exit 1
fi
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
echo “=== Files ready for review ===”
find review-files -type f 2>/dev/null | head -10
build:
commands:
- echo Build started on `date`
- echo “=== Running Amazon Q Developer CLI for code review ===”
- |
运行Amazon Q审查(使用预创建的prompt文件)
echo “Running Amazon Q with standardized prompt…”
echo “Prompt file size: $(wc -c < code-review-prompt.txt) characters"
运行Q命令
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}”
创建摘要文件
cat > review_summary.md << EOF
代码审查报告链接
审查报告已上传到: s3://code-family-code-review/${S3_KEY}
构建编号: ${BUILD_NUM}
提交ID: ${COMMIT_ID}
审查时间: $(date)
EOF
aws s3 cp review_summary.md s3://code-family-code-review/review-results/${TIMESTAMP}-build${BUILD_NUM}-${COMMIT_ID}-summary.md
echo “Review summary uploaded to S3”
else
echo “Warning: amazon_q_review_${CODEBUILD_BUILD_NUMBER}.md not found, skipping S3 upload”
fi
echo “=== Adding Comment to Pull Request ===”
if [ -f “amazon_q_review_${CODEBUILD_BUILD_NUMBER}.md” ]; then
使用前面获取的PR变量
REPO_NAME=”${REPOSITORY_NAME:-unicorn-web-project}”
if [ -n “$PR_ID” ] && [ “$PR_ID” != “” ] && [ -n “$PR_DEST_COMMIT” ] && [ -n “$PR_SOURCE_COMMIT” ]; then
echo “Adding comment to Pull Request #$PR_ID in repository $REPO_NAME”
准备元数据
BUILD_NUM=${CODEBUILD_BUILD_NUMBER:-$(date +%s)}
TIMESTAMP=$(date +”%Y%m%d-%H%M%S”)
COMMIT_ID=$(git rev-parse –short HEAD)
S3_KEY=”review-results/${TIMESTAMP}-build${BUILD_NUM}-${COMMIT_ID}-review.md”
创建带有元数据的comment内容
cat > comment_content.md << EOF
自动代码审查报告
—
生成时间: $(date +”%Y-%m-%d %H:%M:%S”)
构建编号: ${BUILD_NUM}
提交ID: ${COMMIT_ID}
审查范围: ${PR_DEST_COMMIT:0:8}…${PR_SOURCE_COMMIT:0:8}
S3报告链接: s3://<请填入您的s3桶名称>/${S3_KEY}
变更文件数: $(wc -l < changes.txt)
Repository: ${REPO_NAME}
—
变更文件列表:
EOF
while IFS= read -r file; do
echo “- \$file\
” >> comment_content.md
done < changes.txt
echo “” >> comment_content.md
echo “—” >> comment_content.md
echo “” >> comment_content.md
添加审查内容
cat amazon_q_review_${CODEBUILD_BUILD_NUMBER}.md >> comment_content.md
使用AWS CLI添加comment到Pull Request
echo “Posting comment to Pull Request: $PR_ID”
echo “Repository: $REPO_NAME”
echo “Before commit: $PR_DEST_COMMIT”
echo “After commit: $PR_SOURCE_COMMIT”
执行AWS CLI命令添加comment
if 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; then
echo “Successfully added comment to Pull Request #$PR_ID”
else
echo “Failed to add comment to Pull Request #$PR_ID”
fi
else
echo “PR information not available or incomplete, skipping comment”
echo “PR_ID: ‘$PR_ID'”
echo “PR_DEST_COMMIT: ‘$PR_DEST_COMMIT'”
echo “PR_SOURCE_COMMIT: ‘$PR_SOURCE_COMMIT'”
fi
else
echo “amazon_q_review_${CODEBUILD_BUILD_NUMBER}.md not found, skipping PR comment”
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等软件安装的预置环境。创建私有存储库请参考Amazon ECR文档
基于官方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,方便CodeBuild执行命令
ENTRYPOINT [ “bash” ]
CodeBuild核心设置
- 确保CodeBuild的角色可以访问Cloudwatch(用于发布 CodeBuild相关日志信息), S3桶(用于上传Amazon Q Developer CLI凭证以及代码审核结果), ECR (用于获取docker镜像),以及对应的CodeCommit(代码仓库存储在CodeCommit中)
- Source provider选择代码审核方案使用的CodeCommit仓库地址,不要选择业务CI/CD 流水线中的CodeCommit仓库
- 确保固定Reference type为main分支
- 环境设置选择Amazon ECR, 添加前面Dockerfile使用的ECR仓库地址
部署EventBridge Rule 触发CodeBuild编译
通过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”,这里面预置好了大部份的亚马逊云科技中托管服务的事件,其中也包含CodeCommit的“CodeCommit Pull Request State Change”等事件。具体的事件列表可以参考文档。
本文所选择的事件类型为pullRequestCreated和pullRequestSourceBranchUpdated。您选择Other类型的Events以实现本文的配置,在“Custom pattern(JSON editor)”中填入下面的json事件模式。注意在“resources”字段填入您需要进行代码审核的CodeCommit repository ARN
Event pattern:
{
“source”: [“aws.codecommit”],
“detail-type”: [“CodeCommit Pull Request State Change”],
“resources”: [“<请填入需要进行代码审核的code commit repository ARN>“],
“detail”: {
“event”: [“pullRequestCreated”, “pullRequestSourceBranchUpdated”]
}
}
“Select target(s)”部分选择codebuild project作为目标,并填入Project ARN(ARN的信息可以在CodeBuild Project的“Project Details”中找到),选择默认创建新的角色
展开下面的“Additional settings”部分,选择Input transformer作为“Configure target input”,点击“configure input transformer”
编辑Input Path和Input Template, 填入下面的json配置。CodeCommit的pull request创建事件模式请参考文档,以方便构建字段提取和转换的逻辑
Input Path
Input Path主要从原始事件中提取特定字段,使用JSONPath语法选择需要的数据
{
“destinationReference”: “$.detail.destinationReference”,
“pullRequestId”: “$.detail.pullRequestId”,
“repositoryName”: “$.detail.repositoryNames[0]”,
“sourceReference”: “$.detail.sourceReference”
}
Input Template
将提取的数据重新格式化为CodeBuild所需的参数,用于在buildspec.yml中调用
{
“environmentVariablesOverride”: [
{
“name”: “PULL_REQUEST_ID”,
“value”: “”
},
{
“name”: “REPOSITORY_NAME”,
“value”: “”
},
{
“name”: “IS_PR_BUILD”,
“value”: “true”
},
{
“name”: “SOURCE_BRANCH”,
“value”: “”
},
{
“name”: “TARGET_BRANCH”,
“value”: “”
}
]
}
完成EventBridge Rule的创建之后,您会发现在CodeBuild Project的Build triggers中出现配置完成的EventBridge Rule。该规则将在满足源事件时被触发,构建代码审核的CodeBuild Project。
实现效果
完成上述配置后,您在提交一个代码合并的请求之后,会自动触发代码审核的CodeBuild项目,针对源代码仓库进行代码审核,生成代码审核结果并发布到PR的评论中:
总结
文详细介绍了如何将Amazon Q Developer CLI与Amazon Code系列产品集成,构建独立的代码审核CI/CD管道。通过与现有业务CodeCommit代码仓库集成,利用EventBridge实现代码审核工作流与业务工作流的解耦,从而建立智能化的代码审核流程。通过这种架构整合,开发团队能够在亚马逊云平台的持续集成与持续部署过程中获得AI驱动的代码质量反馈,有效提升代码可靠性并加速开发周期。
*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。