
Hermes 在 CI/CD 中的完整 DevOps 流水线:从 PR 审查到自动部署,让 Agent 接管你的发布流程
每次提交代码都要手动跑测试、写 Release Notes、部署?是时候把这些重复劳动交给 AI 了。本文将带你用 Hermes 智能体打造完整的 DevOps 流水线------PR 自动审查、合并后自动构建部署、CHANGELOG 自动生成,全程无人值守,安全可控。
前言:为什么 CI/CD 需要 AI?
现代软件开发离不开 CI/CD(持续集成/持续部署)流水线。典型的流水线包括代码提交触发测试、构建、部署等步骤。但传统的 CI/CD 工具(如 Jenkins、GitHub Actions、GitLab CI)本质上是"规则引擎"------你写什么脚本,它就执行什么。
这种方式的局限性在于:
- 静态规则:无法根据 PR 内容智能调整审查标准
- 缺乏上下文:无法理解代码变更的业务含义,生成的 Release Notes 干巴巴
- 手动干预多:许多步骤(如判断是否应该部署、撰写发布说明)仍需要人工
现在,Hermes 智能体可以嵌入 CI/CD 流水线,扮演一个"智能协调者"的角色。它能够:
- 接收 GitHub Webhook,自动触发流水线
- 对 PR 进行代码审查并给出有意义的评论(不仅仅是 Lint 错误)
- 合并后调用终端执行 Docker 构建和推送
- 根据 commit 历史自动生成高质量的 CHANGELOG.md
更重要的是,Hermes 可以区分哪些操作是低风险的(自动执行),哪些需要人工确认(如生产环境部署)。
本文将完整实现这样一个流水线。全文包含 6 张 mermaid 流程图和完整的 YAML/Skill 代码示例。
1. 架构:GitHub Webhook → Hermes Gateway → 自动触发
1.1 整体设计
我们的目标是:当 GitHub 仓库发生特定事件(如 PR 打开、代码合并、发布创建)时,GitHub 发送 Webhook 到 Hermes 网关,Hermes 根据事件类型触发对应的 Skill 执行相应任务。
#mermaid-svg-84JNsO8ZPihx9TIz{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-84JNsO8ZPihx9TIz .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-84JNsO8ZPihx9TIz .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-84JNsO8ZPihx9TIz .error-icon{fill:#552222;}#mermaid-svg-84JNsO8ZPihx9TIz .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-84JNsO8ZPihx9TIz .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-84JNsO8ZPihx9TIz .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-84JNsO8ZPihx9TIz .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-84JNsO8ZPihx9TIz .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-84JNsO8ZPihx9TIz .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-84JNsO8ZPihx9TIz .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-84JNsO8ZPihx9TIz .marker{fill:#333333;stroke:#333333;}#mermaid-svg-84JNsO8ZPihx9TIz .marker.cross{stroke:#333333;}#mermaid-svg-84JNsO8ZPihx9TIz svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-84JNsO8ZPihx9TIz p{margin:0;}#mermaid-svg-84JNsO8ZPihx9TIz .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-84JNsO8ZPihx9TIz .cluster-label text{fill:#333;}#mermaid-svg-84JNsO8ZPihx9TIz .cluster-label span{color:#333;}#mermaid-svg-84JNsO8ZPihx9TIz .cluster-label span p{background-color:transparent;}#mermaid-svg-84JNsO8ZPihx9TIz .label text,#mermaid-svg-84JNsO8ZPihx9TIz span{fill:#333;color:#333;}#mermaid-svg-84JNsO8ZPihx9TIz .node rect,#mermaid-svg-84JNsO8ZPihx9TIz .node circle,#mermaid-svg-84JNsO8ZPihx9TIz .node ellipse,#mermaid-svg-84JNsO8ZPihx9TIz .node polygon,#mermaid-svg-84JNsO8ZPihx9TIz .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-84JNsO8ZPihx9TIz .rough-node .label text,#mermaid-svg-84JNsO8ZPihx9TIz .node .label text,#mermaid-svg-84JNsO8ZPihx9TIz .image-shape .label,#mermaid-svg-84JNsO8ZPihx9TIz .icon-shape .label{text-anchor:middle;}#mermaid-svg-84JNsO8ZPihx9TIz .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-84JNsO8ZPihx9TIz .rough-node .label,#mermaid-svg-84JNsO8ZPihx9TIz .node .label,#mermaid-svg-84JNsO8ZPihx9TIz .image-shape .label,#mermaid-svg-84JNsO8ZPihx9TIz .icon-shape .label{text-align:center;}#mermaid-svg-84JNsO8ZPihx9TIz .node.clickable{cursor:pointer;}#mermaid-svg-84JNsO8ZPihx9TIz .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-84JNsO8ZPihx9TIz .arrowheadPath{fill:#333333;}#mermaid-svg-84JNsO8ZPihx9TIz .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-84JNsO8ZPihx9TIz .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-84JNsO8ZPihx9TIz .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-84JNsO8ZPihx9TIz .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-84JNsO8ZPihx9TIz .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-84JNsO8ZPihx9TIz .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-84JNsO8ZPihx9TIz .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-84JNsO8ZPihx9TIz .cluster text{fill:#333;}#mermaid-svg-84JNsO8ZPihx9TIz .cluster span{color:#333;}#mermaid-svg-84JNsO8ZPihx9TIz div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-84JNsO8ZPihx9TIz .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-84JNsO8ZPihx9TIz rect.text{fill:none;stroke-width:0;}#mermaid-svg-84JNsO8ZPihx9TIz .icon-shape,#mermaid-svg-84JNsO8ZPihx9TIz .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-84JNsO8ZPihx9TIz .icon-shape p,#mermaid-svg-84JNsO8ZPihx9TIz .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-84JNsO8ZPihx9TIz .icon-shape .label rect,#mermaid-svg-84JNsO8ZPihx9TIz .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-84JNsO8ZPihx9TIz .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-84JNsO8ZPihx9TIz .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-84JNsO8ZPihx9TIz :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 外部
Hermes 服务
GitHub
push/pr/release
POST Webhook
pr_opened
push_to_main
release_created
评论
docker build/push
git commit
GitHub 仓库
Webhook 配置
Hermes Gateway
HTTP 端点
事件路由器
PR 审查 Skill
部署 Skill
Changelog Skill
PR 评论
Docker Registry
Git 仓库
1.2 GitHub Webhook 配置
-
在 GitHub 仓库的 Settings → Webhooks 中添加:
- Payload URL:
https://hermes.yourdomain.com/github/webhook - Content type:
application/json - Secret: 一个随机字符串(用于验证)
- Events: 选择
Pull requests、Pushes、Releases
- Payload URL:
-
在 Hermes 中配置 Webhook 接收端点(使用
webhook工具或自定义网关)。
1.3 Hermes 网关配置
在 config.yaml 中添加:
yaml
gateways:
github:
enabled: true
webhook_endpoint: "/github/webhook"
secret: "${GITHUB_WEBHOOK_SECRET}"
allowed_events:
- pull_request
- push
- release
1.4 事件路由 Skill
编写一个路由器 Skill,根据 Webhook 内容分发到不同的子任务:
yaml
name: github_webhook_router
trigger: "internal" # 由 webhook 直接调用
steps:
- tool: extract_json
params:
data: "{{webhook_body}}"
path: "$.action"
output: action
- tool: extract_json
params:
data: "{{webhook_body}}"
path: "$.pull_request"
output: is_pr
- condition: "{{is_pr}} and {{action}} == 'opened'"
then:
- tool: delegate_task
params:
skill: "pr_reviewer"
task: "审查这个 PR: {{webhook_body}}"
- condition: "{{webhook_body.ref}} == 'refs/heads/main' and {{webhook_body.created}} == false"
then:
- tool: delegate_task
params:
skill: "auto_deploy"
task: "合并到 main,执行部署"
- condition: "{{webhook_body.release}}"
then:
- tool: delegate_task
params:
skill: "changelog_generator"
task: "生成发布日志"
接下来,我们详细实现三个核心 Skill。
2. 场景一:PR 自动审查 + 评论
2.1 Skill 设计思路
当一个新的 Pull Request 被打开时,Hermes 需要:
- 获取 PR 的变更文件列表和 diff 内容
- 调用 LLM 进行代码审查(检查代码风格、潜在 bug、安全问题)
- 将审查结果以评论形式发布到 PR 中
2.2 实现 Skill:pr_reviewer
yaml
name: pr_reviewer
description: "自动审查 PR 并添加评论"
trigger: "internal"
params:
- name: webhook_body
type: json
required: true
steps:
# 1. 提取 PR 信息
- tool: extract_json
params:
data: "{{webhook_body}}"
path: "$.pull_request.html_url"
output: pr_url
- tool: extract_json
params:
data: "{{webhook_body}}"
path: "$.pull_request.number"
output: pr_number
- tool: extract_json
params:
data: "{{webhook_body}}"
path: "$.repository.full_name"
output: repo_full_name
# 2. 获取 PR 的 diff(通过 GitHub API)
- tool: web_get
params:
url: "https://api.github.com/repos/{{repo_full_name}}/pulls/{{pr_number}}"
headers:
Authorization: "token {{env.GITHUB_TOKEN}}"
output: pr_data
- tool: extract_json
params:
data: "{{pr_data}}"
path: "$.diff_url"
output: diff_url
- tool: web_get
params:
url: "{{diff_url}}"
output: diff_content
# 3. 调用 LLM 审查
- tool: llm_generate
params:
prompt: |
你是一个资深的代码审查专家。请审查以下 PR 的 diff 内容,给出:
1. 总结变更的主要功能
2. 指出潜在的问题(bug 风险、性能、安全、可读性)
3. 给出改进建议
Diff:
{{diff_content}}
max_tokens: 2000
output: review_comment
# 4. 将审查评论发布到 PR
- tool: web_post
params:
url: "https://api.github.com/repos/{{repo_full_name}}/issues/{{pr_number}}/comments"
headers:
Authorization: "token {{env.GITHUB_TOKEN}}"
Content-Type: "application/json"
body:
body: |
🤖 **Hermes 自动审查报告**
{{review_comment}}
output: post_result
- tool: reply
params:
message: "PR 审查完成,已添加评论: {{pr_url}}"
2.3 效果展示
当开发者打开 PR 后,几秒内就会看到 Hermes 的评论,内容示例:
🤖 Hermes 自动审查报告
变更总结:添加了用户登录的 JWT 验证逻辑。
潜在问题:
auth.py第 23 行:硬编码了 secret key,建议使用环境变量。login_handler没有对密码长度做校验,可能导致 DoS。改进建议:
- 将 secret key 移到配置文件。
- 添加密码复杂度验证。
这比静态的 Lint 检查更有价值,因为它理解了业务逻辑。
2.4 安全考虑
- 使用 GitHub Token 时,只授予
repo或pull_request写权限 - 对 LLM 生成的评论内容进行安全过滤,防止注入恶意 Markdown
3. 场景二:合并后自动部署:Hermes 调用 terminal 执行 docker build/push
3.1 场景描述
当代码合并到 main 分支后,自动触发构建 Docker 镜像并推送到镜像仓库(如 Docker Hub、阿里云 ACR)。Hermes 调用 terminal 工具执行 Docker 命令。
3.2 Skill 实现:auto_deploy
yaml
name: auto_deploy
description: "合并到 main 后自动构建并推送 Docker 镜像"
trigger: "internal"
steps:
# 1. 提取仓库信息
- tool: extract_json
params:
data: "{{webhook_body}}"
path: "$.repository.clone_url"
output: clone_url
- tool: extract_json
params:
data: "{{webhook_body}}"
path: "$.after" # 最新 commit SHA
output: commit_sha
# 2. 克隆仓库(使用临时目录)
- tool: terminal
params:
command: "mkdir -p /tmp/hermes_deploy && cd /tmp/hermes_deploy && git clone {{clone_url}} . && git checkout {{commit_sha}}"
timeout: 120
output: clone_result
# 3. 获取版本号(从 git tag 或 commit)
- tool: terminal
params:
command: "cd /tmp/hermes_deploy && git describe --tags --abbrev=0 2>/dev/null || echo 'latest'"
output: version
# 4. 构建 Docker 镜像
- tool: terminal
params:
command: "cd /tmp/hermes_deploy && docker build -t myapp:{{version}} -t myapp:latest ."
timeout: 300
output: build_result
# 5. 登录镜像仓库(使用环境变量中的凭证)
- tool: terminal
params:
command: "echo '{{env.DOCKER_PASSWORD}}' | docker login -u '{{env.DOCKER_USERNAME}}' --password-stdin"
timeout: 30
output: login_result
# 6. 推送镜像
- tool: terminal
params:
command: "docker push myapp:{{version}} && docker push myapp:latest"
timeout: 180
output: push_result
# 7. 清理临时目录
- tool: terminal
params:
command: "rm -rf /tmp/hermes_deploy"
output: cleanup
# 8. 发送部署成功通知到 Slack
- tool: web_post
params:
url: "{{env.SLACK_WEBHOOK}}"
body:
text: "✅ 部署成功!版本: {{version}},镜像: myapp:{{version}}"
output: notify
- tool: reply
params:
message: "自动部署完成,版本 {{version}}"
3.3 安全红线:哪些操作必须人工确认
自动部署到生产环境风险较高,建议在真正执行 docker push 之前增加人工确认环节。第 5 节会详细讨论。
3.4 注意事项
- Docker 命令需要在 Hermes 所在服务器上安装好 Docker 引擎
- 确保 Hermes 运行的用户有 docker 权限(建议加入 docker 组)
- 镜像仓库的凭证通过环境变量传入,禁止硬编码
4. 场景三:发布日志自动生成:从 commit 到 CHANGELOG.md
4.1 场景描述
当创建一个新的 Release 时(或手动触发),自动从上一个 tag 到当前 commit 之间的提交记录生成结构化的 CHANGELOG.md 文件,并提交到仓库。
4.2 Skill 实现:changelog_generator
yaml
name: changelog_generator
description: "从 git log 生成 CHANGELOG.md"
trigger: "internal"
steps:
# 1. 获取仓库信息
- tool: extract_json
params:
data: "{{webhook_body}}"
path: "$.repository.clone_url"
output: clone_url
- tool: extract_json
params:
data: "{{webhook_body}}"
path: "$.release.tag_name"
output: new_tag
- tool: extract_json
params:
data: "{{webhook_body}}"
path: "$.release.target_commitish"
output: branch
# 2. 克隆仓库
- tool: terminal
params:
command: "rm -rf /tmp/hermes_changelog && mkdir -p /tmp/hermes_changelog && cd /tmp/hermes_changelog && git clone {{clone_url}} . && git checkout {{branch}}"
timeout: 60
# 3. 获取上一个 tag
- tool: terminal
params:
command: "cd /tmp/hermes_changelog && git describe --tags --abbrev=0 {{new_tag}}^ 2>/dev/null || echo ''"
output: prev_tag
# 4. 获取 commit log
- tool: terminal
params:
command: "cd /tmp/hermes_changelog && git log {{prev_tag}}..{{new_tag}} --pretty=format:'- %s (%h) - %an' --no-merges"
timeout: 30
output: commits
# 5. 使用 LLM 整理成 CHANGELOG 格式
- tool: llm_generate
params:
prompt: |
请将以下 git commit 消息整理成符合 Keep a Changelog 格式的版本日志。
将提交分类为:Added, Changed, Fixed, Removed, Security。
输出 Markdown 格式,每个分类下用列表呈现。
Commit 列表:
{{commits}}
版本号:{{new_tag}}
max_tokens: 1500
output: changelog_section
# 6. 读取现有的 CHANGELOG.md(如果存在)
- tool: file_read
params:
path: "/tmp/hermes_changelog/CHANGELOG.md"
output: existing_changelog
on_error: "ignore"
# 7. 合并(将新内容插到顶部)
- tool: llm_generate
params:
prompt: |
将新的版本日志插入到现有 CHANGELOG.md 的开头(标题下方)。
新内容:
{{changelog_section}}
现有内容:
{{existing_changelog}}
output: merged_changelog
# 8. 写回文件
- tool: file_write
params:
path: "/tmp/hermes_changelog/CHANGELOG.md"
content: "{{merged_changelog}}"
# 9. 提交并推送
- tool: terminal
params:
command: |
cd /tmp/hermes_changelog && \
git config user.name "Hermes Bot" && \
git config user.email "bot@hermes.local" && \
git add CHANGELOG.md && \
git commit -m "docs: 更新 CHANGELOG for {{new_tag}}" && \
git push origin {{branch}}
timeout: 60
output: push_result
# 10. 清理
- tool: terminal
params:
command: "rm -rf /tmp/hermes_changelog"
- tool: reply
params:
message: "CHANGELOG.md 已更新并推送"
4.3 效果
生成的 CHANGELOG.md 片段:
markdown
## [1.2.0] - 2025-04-25
### Added
- 新增用户登录 JWT 验证 (#45)
- 添加 Docker 构建脚本 (#43)
### Changed
- 升级依赖库版本 (#44)
### Fixed
- 修复 PR 评论重复问题 (#42)
5. 安全红线:哪些操作必须人工确认
在 DevOps 流水线中,某些操作风险较高,例如:
- 部署到生产环境(尤其是
docker push后实际启动服务) - 强制推送 git 分支
- 删除资源
- 修改生产配置
Hermes 支持为高风险 Skill 设置人工审批模式。
5.1 配置人工审批
在 config.yaml 中:
yaml
skills:
auto_deploy:
approval:
required: true
approvers:
- "admin@example.com"
- "devops-lead@example.com"
channel: "slack"
timeout_minutes: 30
当 auto_deploy Skill 被触发时,Hermes 会暂停执行,发送审批请求到 Slack(或其他渠道),包含任务详情和"批准/拒绝"按钮。只有管理员点击批准后,才会继续执行。
5.2 审批请求示例
json
{
"text": "⚠️ 需要审批:自动部署到生产环境",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "版本: v1.2.0\n环境: production\n变更: 添加 JWT 验证"
}
},
{
"type": "actions",
"elements": [
{
"type": "button",
"text": "✅ 批准",
"value": "approve",
"style": "primary"
},
{
"type": "button",
"text": "❌ 拒绝",
"value": "reject",
"style": "danger"
}
]
}
]
}
5.3 其他安全措施
- 最小权限 :Hermes 使用的 GitHub Token 只授予必要的权限(如
repo的读、issues的写,但没有admin)。 - 命令白名单 :
terminal工具可以限制允许执行的命令(如只允许docker build/push、git相关)。 - 环境变量隔离:所有敏感信息通过环境变量注入,不写入日志。
6. 总结:开发自动化的进阶版
6.1 流水线全景
#mermaid-svg-QygcHGGat3iWGWwU{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QygcHGGat3iWGWwU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QygcHGGat3iWGWwU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QygcHGGat3iWGWwU .error-icon{fill:#552222;}#mermaid-svg-QygcHGGat3iWGWwU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QygcHGGat3iWGWwU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QygcHGGat3iWGWwU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QygcHGGat3iWGWwU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QygcHGGat3iWGWwU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QygcHGGat3iWGWwU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QygcHGGat3iWGWwU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QygcHGGat3iWGWwU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QygcHGGat3iWGWwU .marker.cross{stroke:#333333;}#mermaid-svg-QygcHGGat3iWGWwU svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QygcHGGat3iWGWwU p{margin:0;}#mermaid-svg-QygcHGGat3iWGWwU .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-QygcHGGat3iWGWwU .cluster-label text{fill:#333;}#mermaid-svg-QygcHGGat3iWGWwU .cluster-label span{color:#333;}#mermaid-svg-QygcHGGat3iWGWwU .cluster-label span p{background-color:transparent;}#mermaid-svg-QygcHGGat3iWGWwU .label text,#mermaid-svg-QygcHGGat3iWGWwU span{fill:#333;color:#333;}#mermaid-svg-QygcHGGat3iWGWwU .node rect,#mermaid-svg-QygcHGGat3iWGWwU .node circle,#mermaid-svg-QygcHGGat3iWGWwU .node ellipse,#mermaid-svg-QygcHGGat3iWGWwU .node polygon,#mermaid-svg-QygcHGGat3iWGWwU .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QygcHGGat3iWGWwU .rough-node .label text,#mermaid-svg-QygcHGGat3iWGWwU .node .label text,#mermaid-svg-QygcHGGat3iWGWwU .image-shape .label,#mermaid-svg-QygcHGGat3iWGWwU .icon-shape .label{text-anchor:middle;}#mermaid-svg-QygcHGGat3iWGWwU .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-QygcHGGat3iWGWwU .rough-node .label,#mermaid-svg-QygcHGGat3iWGWwU .node .label,#mermaid-svg-QygcHGGat3iWGWwU .image-shape .label,#mermaid-svg-QygcHGGat3iWGWwU .icon-shape .label{text-align:center;}#mermaid-svg-QygcHGGat3iWGWwU .node.clickable{cursor:pointer;}#mermaid-svg-QygcHGGat3iWGWwU .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-QygcHGGat3iWGWwU .arrowheadPath{fill:#333333;}#mermaid-svg-QygcHGGat3iWGWwU .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QygcHGGat3iWGWwU .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QygcHGGat3iWGWwU .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QygcHGGat3iWGWwU .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-QygcHGGat3iWGWwU .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QygcHGGat3iWGWwU .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-QygcHGGat3iWGWwU .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QygcHGGat3iWGWwU .cluster text{fill:#333;}#mermaid-svg-QygcHGGat3iWGWwU .cluster span{color:#333;}#mermaid-svg-QygcHGGat3iWGWwU div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QygcHGGat3iWGWwU .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-QygcHGGat3iWGWwU rect.text{fill:none;stroke-width:0;}#mermaid-svg-QygcHGGat3iWGWwU .icon-shape,#mermaid-svg-QygcHGGat3iWGWwU .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-QygcHGGat3iWGWwU .icon-shape p,#mermaid-svg-QygcHGGat3iWGWwU .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-QygcHGGat3iWGWwU .icon-shape .label rect,#mermaid-svg-QygcHGGat3iWGWwU .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-QygcHGGat3iWGWwU .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-QygcHGGat3iWGWwU .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-QygcHGGat3iWGWwU :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Hermes 流水线
开发流程
自动生成日志
自动部署
自动 PR 审查
GitHub
提交代码
开发者
Pull Request
main 分支
Release
Webhook 接收器
PR 审查 Skill
添加评论
部署 Skill
Docker build
Docker push
人工审批
Changelog Skill
生成 CHANGELOG
提交到仓库
6.2 收益总结
| 场景 | 传统方式 | 使用 Hermes | 节省时间 |
|---|---|---|---|
| PR 审查 | 人工审查,30分钟 | 自动初筛 + 人工复核,5分钟 | 83% |
| 部署 | 手动运行命令,10分钟 | 自动触发 + 一键审批,2分钟 | 80% |
| 更新 CHANGELOG | 手动整理 commit,15分钟 | 自动生成,1分钟 | 93% |
6.3 扩展方向
- 智能回滚:当部署后监控告警时,Hermes 自动回滚到上一个版本。
- 性能基准测试:在 PR 中自动运行性能测试,对比 main 分支。
- 文档自动更新:根据代码变更自动更新 API 文档。
6.4 一句话总结
将 Hermes 嵌入 CI/CD 流水线,让 AI 接管 PR 审查、自动部署、CHANGELOG 生成等重复劳动------你的团队可以专注于写代码,而机器人负责把代码变成产品。
下一步:在你的仓库中配置 GitHub Webhook,部署 Hermes 网关,然后打开第一个 PR,体验自动审查的乐趣。但别忘了为生产部署加上"人工审批"这条安全红线。
附录:完整配置示例
.env 文件
bash
GITHUB_TOKEN=ghp_xxxxxxxx
GITHUB_WEBHOOK_SECRET=supersecret
DOCKER_USERNAME=myusername
DOCKER_PASSWORD=mypassword
SLACK_WEBHOOK=https://hooks.slack.com/services/xxx/yyy
config.yaml 关键片段
yaml
gateways:
github:
enabled: true
webhook_endpoint: "/github/webhook"
secret: ${GITHUB_WEBHOOK_SECRET}
tools:
terminal:
enabled: true
mode: docker # 隔离执行
allowed_commands:
- "git"
- "docker build"
- "docker push"
- "docker login"
skills:
auto_deploy:
approval: required
approvers: ["admin@example.com"]
版权声明:本文为原创技术博客,采用 CC BY-NC-SA 4.0 许可。欢迎转载,请保留出处。如有 CI/CD 实践问题,欢迎评论区交流。
本文作者 :RickyIT
原创不易,欢迎点赞、收藏、转发