Sooua
登录
返回文章列表
Claude Code··15 分钟阅读·2814 次阅读

CI/CD 集成:GitHub Actions / GitLab

graph LR

目标:将 Claude Code 集成到 CI/CD 流水线,实现自动化代码审查和测试
预计时间:30 分钟
对应官方文档:GitHub ActionsGitLab CI/CD


CI/CD 流水线架构


CI/CD 中的 Claude Code

使用场景

场景说明
自动代码审查PR 创建时自动审查代码
测试生成为新增代码自动生成测试
文档更新API 变更时自动更新文档
安全扫描检查潜在的安全漏洞
依赖更新自动审查依赖升级影响

GitHub Actions 集成

基础配置

# .github/workflows/claude-review.yaml
name: Claude Code Review
 
on:
  pull_request:
    types: [opened, synchronize]
 
jobs:
  review:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
    
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      
      - name: Setup Claude Code
        uses: anthropic/claude-code-action@v1
        with:
          api-key: ${{ secrets.ANTHROPIC_API_KEY }}
          
      - name: Run Code Review
        run: |
          claude review-pr \
            --pr ${{ github.event.pull_request.number }} \
            --repo ${{ github.repository }} \
            --output review.md
        
      - name: Post Review
        uses: actions/github-script@v7
        with:
          script: |
            const fs = require('fs');
            const review = fs.readFileSync('review.md', 'utf8');
            
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: review
            });

高级:多维度审查

# .github/workflows/claude-advanced-review.yaml
name: Advanced Claude Review
 
on:
  pull_request:
    paths:
      - 'src/**'
      - 'tests/**'
 
jobs:
  security-review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: anthropic/claude-code-action@v1
        with:
          api-key: ${{ secrets.ANTHROPIC_API_KEY }}
      
      - name: Security Review
        run: |
          claude review \
            --focus security \
            --files ${{ steps.changed-files.outputs.all }} \
            --output security-report.md
      
      - name: Upload Security Report
        uses: actions/upload-artifact@v4
        with:
          name: security-report
          path: security-report.md
 
  performance-review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: anthropic/claude-code-action@v1
      
      - name: Performance Review
        run: |
          claude review \
            --focus performance \
            --output performance-report.md
 
  test-generation:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: anthropic/claude-code-action@v1
      
      - name: Generate Tests
        run: |
          claude generate-tests \
            --for-files ${{ steps.changed-files.outputs.added }} \
            --output new-tests/
      
      - name: Commit Tests
        run: |
          git config user.name "Claude CI"
          git config user.email "[email protected]"
          git add new-tests/
          git commit -m "test: auto-generated tests for PR #${{ github.event.pull_request.number }}"
          git push

GitLab CI/CD 集成

基础配置

# .gitlab-ci.yml
stages:
  - review
  - test
 
variables:
  ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY
 
claude-review:
  stage: review
  image: anthropic/claude-code:latest
  script:
    - claude review-mr
      --mr-id $CI_MERGE_REQUEST_IID
      --project $CI_PROJECT_PATH
      --output claude-review.md
  artifacts:
    reports:
      codequality: claude-review.md
    expire_in: 1 week
  only:
    - merge_requests
 
claude-test-gen:
  stage: test
  image: anthropic/claude-code:latest
  script:
    - claude generate-tests
      --diff-from $CI_MERGE_REQUEST_DIFF_BASE_SHA
      --output generated-tests/
    - pytest generated-tests/ -v
  artifacts:
    when: always
    reports:
      junit: generated-tests/report.xml

自动化测试生成

配置

# .github/workflows/auto-test.yaml
name: Auto Generate Tests
 
on:
  push:
    branches: [main]
 
jobs:
  generate-tests:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Detect New Functions
        id: detect
        run: |
          # 找出新增的无测试函数
          python scripts/find_untested.py > untested.json
      
      - name: Generate Tests with Claude
        run: |
          claude generate-tests \
            --functions $(cat untested.json | jq -r '.[].name') \
            --style pytest \
            --output tests/auto/
      
      - name: Run Generated Tests
        run: pytest tests/auto/ -v --tb=short
      
      - name: Create PR with Tests
        uses: peter-evans/create-pull-request@v6
        with:
          title: "test: auto-generated tests"
          body: "Generated by Claude Code CI"
          branch: auto-tests

完整的 GitHub Actions 生产配置

# .github/workflows/claude-prod-review.yaml
name: Claude Code Production Review
 
on:
  pull_request:
    types: [opened, synchronize, reopened]
    paths:
      - 'src/**'
      - 'lib/**'
      - 'app/**'
 
jobs:
  # 阶段 1:并行分析
  analyze:
    runs-on: ubuntu-latest
    outputs:
      files: ${{ steps.changes.outputs.files }}
      count: ${{ steps.changes.outputs.count }}
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
 
      - name: Detect Changes
        id: changes
        run: |
          files=$(git diff --name-only origin/${{ github.base_ref }}...HEAD | grep -E '\.(py|js|ts|go|rs)$' | tr '\n' ' ')
          echo "files=$files" >> $GITHUB_OUTPUT
          echo "count=$(echo $files | wc -w)" >> $GITHUB_OUTPUT
 
  # 阶段 2:安全审查(最高优先级)
  security-review:
    needs: analyze
    if: needs.analyze.outputs.count > 0
    runs-on: ubuntu-latest
    permissions:
      contents: read
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
 
      - name: Security Review with Claude
        uses: anthropic/claude-code-action@v1
        with:
          api-key: ${{ secrets.ANTHROPIC_API_KEY }}
          model: claude-opus-4-7
          prompt: |
            审查以下文件的安全性:
            ${{ needs.analyze.outputs.files }}
 
            重点关注:
            1. SQL 注入、XSS、CSRF
            2. 敏感信息硬编码
            3. 不安全的反序列化
            4. 权限绕过
            5. 依赖漏洞
 
            输出格式:
            - [CRITICAL/HIGH/MEDIUM/LOW] 问题描述
            - 具体位置(文件:行号)
            - 修复建议(含代码示例)
            - CVSS 评分(如适用)
 
      - name: Post Security Report
        uses: actions/github-script@v7
        with:
          script: |
            const report = require('fs').readFileSync('security-report.md', 'utf8');
            const critical = (report.match(/CRITICAL/g) || []).length;
            const high = (report.match(/HIGH/g) || []).length;
 
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: `## 🔒 Claude Code 安全审查报告\n\n${report}\n\n**统计**: CRITICAL ${critical} | HIGH ${high}`
            });
 
            // 如果有 CRITICAL,标记检查失败
            if (critical > 0) {
              core.setFailed('发现 CRITICAL 安全问题!');
            }
 
  # 阶段 3:性能审查
  performance-review:
    needs: [analyze, security-review]
    if: needs.analyze.outputs.count > 0
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - name: Performance Review
        uses: anthropic/claude-code-action@v1
        with:
          api-key: ${{ secrets.ANTHROPIC_API_KEY }}
          model: claude-sonnet-4-6
          prompt: |
            审查代码性能问题:
            ${{ needs.analyze.outputs.files }}
 
            关注:
            1. 时间复杂度(是否有 O(n²) 可以优化)
            2. 数据库查询(N+1 问题)
            3. 内存泄漏
            4. 不必要的 I/O
            5. 缓存策略
 
  # 阶段 4:自动测试生成
  auto-test:
    needs: [analyze, security-review]
    if: needs.analyze.outputs.count > 0
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
 
      - name: Generate Tests
        uses: anthropic/claude-code-action@v1
        with:
          api-key: ${{ secrets.ANTHROPIC_API_KEY }}
          model: claude-sonnet-4-6
          prompt: |
            为本次 PR 新增/修改的代码生成测试:
            ${{ needs.analyze.outputs.files }}
 
            要求:
            1. 覆盖所有新增功能
            2. 包含边界条件测试
            3. 包含异常处理测试
            4. 遵循项目现有测试风格
 
      - name: Commit Tests
        run: |
          git config user.name "Claude CI"
          git config user.email "[email protected]"
          git add tests/
          git diff --cached --quiet || git commit -m "test: auto-generated by Claude Code"
          git push
 
  # 阶段 5:汇总报告
  summary:
    needs: [security-review, performance-review, auto-test]
    runs-on: ubuntu-latest
    if: always()
    steps:
      - name: Generate Summary
        run: |
          echo "## Claude Code CI 审查总结" >> $GITHUB_STEP_SUMMARY
          echo "| 检查项 | 状态 |" >> $GITHUB_STEP_SUMMARY
          echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
          echo "| 安全审查 | ${{ needs.security-review.result }} |" >> $GITHUB_STEP_SUMMARY
          echo "| 性能审查 | ${{ needs.performance-review.result }} |" >> $GITHUB_STEP_SUMMARY
          echo "| 测试生成 | ${{ needs.auto-test.result }} |" >> $GITHUB_STEP_SUMMARY

最佳实践

✅ 推荐❌ 避免
限制 AI 的权限(只读审查)给 CI 完全写入权限
人工最终确认重要修改自动合并 AI 的更改
并行运行多个审查维度串行执行浪费时间
保存审查报告备查审查结果不保存
设置超时防止挂起无限制运行

流水线触发与决策路径

上面给的工作流是「PR 一进来全跑」,但生产环境往往要按改动范围裁剪,否则成本和耗时都顶不住。下面这张图把触发条件、跳过逻辑、并行/串行关系画清楚:

关键设计:

  • dorny/paths-filter 把每个 job 的触发条件拆开,避免改个 README 也跑全套;
  • 安全/性能/风格三个 review 必须并行;
  • auto-test 只在所有 review 通过后跑,避免给坏代码生成测试;
  • 自动合并必须由仓库管理员手动加标签触发,AI 没有越过 branch protection 的权限。

GitLab CI 完整模板(带审计落库)

下面这份模板把审查结果同时写进 GitLab Merge Request Note 和企业内的 PostgreSQL 审计库:

# .gitlab-ci.yml
stages:
  - prepare
  - review
  - publish
 
variables:
  CLAUDE_VERSION: "latest"
  CLAUDE_MAX_TURNS: "15"
 
.claude-base:
  image: anthropic/claude-code:${CLAUDE_VERSION}
  before_script:
    - mkdir -p .claude-runtime
    - cp $CLAUDE_POLICY .claude-runtime/settings.json
  variables:
    ANTHROPIC_API_KEY: $ANTHROPIC_API_KEY_REVIEW
    CLAUDE_CONFIG_DIR: .claude-runtime
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
  artifacts:
    when: always
    expire_in: 30 days
    paths:
      - reports/
 
prepare:diff:
  stage: prepare
  script:
    - git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME --depth=50
    - git diff origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME...HEAD --name-only > reports/changed-files.txt
    - git diff origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME...HEAD > reports/diff.patch
  artifacts:
    paths: [reports/]
 
review:security:
  extends: .claude-base
  stage: review
  needs: [prepare:diff]
  script:
    - |
      claude --print --max-turns $CLAUDE_MAX_TURNS \
        --allowed-tools "Read,Grep,Glob" \
        --output-format json \
        "$(cat ci/prompts/security-review.md)" \
        > reports/security.json
    - python3 ci/scripts/grade.py reports/security.json security
 
review:performance:
  extends: .claude-base
  stage: review
  needs: [prepare:diff]
  script:
    - |
      claude --print --max-turns $CLAUDE_MAX_TURNS \
        --allowed-tools "Read,Grep,Glob" \
        --output-format json \
        "$(cat ci/prompts/performance-review.md)" \
        > reports/performance.json
    - python3 ci/scripts/grade.py reports/performance.json performance
 
publish:mr-comment:
  stage: publish
  image: alpine:3.20
  needs: [review:security, review:performance]
  before_script:
    - apk add --no-cache curl jq postgresql-client python3 py3-pip
    - pip install --quiet psycopg[binary]
  script:
    - python3 ci/scripts/publish_review.py
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
      when: always
# ci/scripts/publish_review.py
"""汇总 Claude 审查结果,写回 GitLab MR 评论 + 落库审计。"""
import json
import os
import pathlib
import urllib.request
 
import psycopg
 
REPORTS = pathlib.Path("reports")
MR_IID = os.environ["CI_MERGE_REQUEST_IID"]
PROJECT = os.environ["CI_PROJECT_ID"]
GL_TOKEN = os.environ["GITLAB_BOT_TOKEN"]
GL_API = os.environ.get("CI_API_V4_URL", "https://gitlab.com/api/v4")
DB_DSN = os.environ["AUDIT_DB_DSN"]
 
 
def load(name: str) -> dict:
    path = REPORTS / f"{name}.json"
    if not path.exists():
        return {"summary": f"⚠️ {name} 报告缺失", "findings": []}
    return json.loads(path.read_text())
 
 
def render(parts: dict[str, dict]) -> str:
    lines = ["## 🤖 Claude Code 自动审查\n"]
    for name, data in parts.items():
        lines.append(f"### {name}")
        lines.append(data.get("summary", ""))
        for f in data.get("findings", []):
            sev = f.get("severity", "info").upper()
            file = f.get("file", "-")
            line = f.get("line", "-")
            msg = f.get("message", "")
            lines.append(f"- **[{sev}]** `{file}:{line}` — {msg}")
        lines.append("")
    return "\n".join(lines)
 
 
def post_comment(body: str) -> None:
    url = f"{GL_API}/projects/{PROJECT}/merge_requests/{MR_IID}/notes"
    req = urllib.request.Request(
        url,
        method="POST",
        headers={"PRIVATE-TOKEN": GL_TOKEN, "Content-Type": "application/json"},
        data=json.dumps({"body": body}).encode(),
    )
    with urllib.request.urlopen(req, timeout=20) as resp:
        resp.read()
 
 
def audit(parts: dict[str, dict]) -> None:
    with psycopg.connect(DB_DSN, autocommit=True) as conn, conn.cursor() as cur:
        cur.execute(
            """INSERT INTO ai_review_audit (project_id, mr_iid, sha, payload, ts)
               VALUES (%s, %s, %s, %s, now())""",
            (PROJECT, MR_IID, os.environ.get("CI_COMMIT_SHA", ""),
             json.dumps(parts, ensure_ascii=False)),
        )
 
 
def main() -> int:
    parts = {"安全审查": load("security"), "性能审查": load("performance")}
    body = render(parts)
    post_comment(body)
    audit(parts)
    high = sum(1 for p in parts.values()
               for f in p.get("findings", [])
               if f.get("severity") in {"high", "critical"})
    return 1 if high else 0
 
 
if __name__ == "__main__":
    raise SystemExit(main())

配套的成绩判定脚本:

# ci/scripts/grade.py
import json, sys
 
THRESHOLDS = {
    "security": {"critical": 0, "high": 0, "medium": 5},
    "performance": {"critical": 0, "high": 2, "medium": 10},
}
 
report_path, kind = sys.argv[1], sys.argv[2]
data = json.loads(open(report_path).read())
counts = {"critical": 0, "high": 0, "medium": 0, "low": 0}
for f in data.get("findings", []):
    counts[f.get("severity", "low")] = counts.get(f.get("severity", "low"), 0) + 1
 
limits = THRESHOLDS[kind]
failed = [k for k, v in limits.items() if counts.get(k, 0) > v]
print(json.dumps({"counts": counts, "failed": failed}, ensure_ascii=False))
sys.exit(1 if failed else 0)

企业级实战场景

场景一:Monorepo 增量审查(节省 80% Token)

背景:8 万文件、30 个子项目的 monorepo,PR 平均改 12 个文件,跨 3 个子项目;如果每次都把整个仓库喂给模型,单次审查就要 60k+ token。我们用「文件级 CODEOWNERS + AI 路由」让每个 PR 只走需要的子项目。

# .github/workflows/monorepo-claude-review.yml
name: Monorepo Claude Review
on:
  pull_request:
    branches: [main]
 
jobs:
  detect-changes:
    runs-on: ubuntu-latest
    outputs:
      modules: ${{ steps.filter.outputs.changes }}
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - id: filter
        uses: dorny/paths-filter@v3
        with:
          list-files: json
          filters: |
            payments: services/payments/**
            risk:     services/risk/**
            ledger:   services/ledger/**
            web:      apps/web/**
            shared:   packages/**
 
  review-module:
    needs: detect-changes
    if: needs.detect-changes.outputs.modules != '[]'
    runs-on: ubuntu-latest
    strategy:
      matrix:
        module: ${{ fromJSON(needs.detect-changes.outputs.modules) }}
      fail-fast: false
    steps:
      - uses: actions/checkout@v4
      - name: Build module context
        run: |
          python3 ci/scripts/build_module_context.py \
            --module "${{ matrix.module }}" \
            --diff-file <(git diff origin/main...HEAD -- "services/${{ matrix.module }}") \
            --out reports/${{ matrix.module }}-context.md
      - name: Claude review (module-scoped)
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY_REVIEW }}
        run: |
          claude --print --max-turns 8 \
            --allowed-tools "Read,Grep,Glob" \
            --add-dir "services/${{ matrix.module }}" \
            --add-dir "packages" \
            --output-format json \
            "$(cat reports/${{ matrix.module }}-context.md)" \
            > reports/${{ matrix.module }}-review.json
      - uses: actions/upload-artifact@v4
        with:
          name: review-${{ matrix.module }}
          path: reports/${{ matrix.module }}-review.json
# ci/scripts/build_module_context.py
"""为单个模块拼接评审上下文,只送相关文件给模型。"""
import argparse
import pathlib
import subprocess
 
TEMPLATE = """\
# 评审任务:{module}
 
## 模块职责
{owner_doc}
 
## 本次改动 diff
```diff
{diff}

相关测试

{tests}

评审要求

  1. 只评审本模块代码,不要扩展到其他模块。
  2. 输出 JSON:{{ "summary": str, "findings": [{{ "severity": "critical|high|medium|low", "file": str, "line": int, "message": str }}] }}
  3. severity 判定标准见 ci/prompts/severity.md。 """

def read(p: pathlib.Path) -> str: return p.read_text() if p.exists() else "(空)"

def collect_tests(module: str) -> str: p = pathlib.Path(f"services/{module}/tests") if not p.exists(): return "无测试目录" files = [str(f.relative_to(".")) for f in p.rglob("test_*.py")][:20] return "\n".join(f"- {f}" for f in files)

def main() -> None: ap = argparse.ArgumentParser() ap.add_argument("--module", required=True) ap.add_argument("--diff-file", required=True) ap.add_argument("--out", required=True) args = ap.parse_args()

diff = pathlib.Path(args.diff_file).read_text() if len(diff) > 60_000: diff = diff[:60_000] + "\n... [truncated, see full diff in artifact]"

owner_doc = read(pathlib.Path(f"services/{args.module}/OWNERS.md")) tests = collect_tests(args.module)

pathlib.Path(args.out).write_text(TEMPLATE.format( module=args.module, diff=diff, owner_doc=owner_doc, tests=tests))

if name == "main": main()


落地效果:
- 矩阵 job 自动按改动模块并行拉起,没改动的子项目 0 token 消耗;
- 上下文只塞「diff + OWNERS.md + 相关测试列表」,单 PR token 从 60k 降到 8–12k;
- 各模块的 review JSON 单独入库,可以按模块统计 false-positive 率,逐月调优 prompt。

---

### 场景二:合规线「评审 + 蓝绿发布」全自动闭环

**背景**:金融科技团队要求每次发版必须有 AI 审查 + SAST + 灰度回归 + 人工放行四个 gate,且产物必须包含可追溯的 SBOM 和审计签名。

```mermaid
flowchart LR
    A[Tag 推送 v*] --> B[build & sign<br/>cosign + SBOM]
    B --> C[claude:release-review]
    B --> D[SAST: semgrep]
    B --> E[license-scan]
    C & D & E --> F{全部 pass?}
    F -->|否| G[gate-fail<br/>通知 release manager]
    F -->|是| H[deploy-staging]
    H --> I[smoke-test + 合成监控]
    I --> J{SLO 守住?}
    J -->|否| K[auto-rollback]
    J -->|是| L[等待 release manager 批准]
    L --> M[deploy-prod 蓝绿切流]
    M --> N[审计归档<br/>S3 + WORM]
# .github/workflows/release-pipeline.yml
name: Release Pipeline
on:
  push:
    tags: ["v*.*.*"]
 
permissions:
  contents: read
  id-token: write          # cosign keyless
  packages: write
 
jobs:
  build:
    runs-on: ubuntu-latest
    outputs:
      digest: ${{ steps.push.outputs.digest }}
    steps:
      - uses: actions/checkout@v4
      - uses: docker/setup-buildx-action@v3
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - id: push
        uses: docker/build-push-action@v6
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}
          provenance: true
          sbom: true
      - uses: sigstore/cosign-installer@v3
      - run: cosign sign --yes ghcr.io/${{ github.repository }}@${{ steps.push.outputs.digest }}
 
  ai-release-review:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with: { fetch-depth: 0 }
      - name: Diff since last release
        run: |
          PREV=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
          if [ -n "$PREV" ]; then
            git log --oneline "$PREV"..HEAD > reports/changes.txt
            git diff "$PREV"..HEAD > reports/release.patch
          else
            echo "(initial release)" > reports/changes.txt
            git diff $(git rev-list --max-parents=0 HEAD)..HEAD > reports/release.patch
          fi
      - name: Claude release review
        env:
          ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY_REVIEW }}
        run: |
          claude --print --max-turns 12 \
            --allowed-tools "Read,Grep,Glob" \
            --output-format json \
            "$(cat ci/prompts/release-review.md)" \
            > reports/release-review.json
      - name: Gate
        run: python3 ci/scripts/grade.py reports/release-review.json security
      - uses: actions/upload-artifact@v4
        with:
          name: release-review
          path: reports/
 
  sast:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: returntocorp/semgrep-action@v1
        with:
          config: p/ci
          generateSarif: "1"
 
  deploy-staging:
    needs: [ai-release-review, sast]
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - run: ./deploy/staging.sh ${{ github.ref_name }}
      - run: ./deploy/smoke-tests.sh staging
 
  deploy-prod:
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://app.example.com
    steps:
      - name: Blue/green switch
        run: ./deploy/blue-green.sh ${{ github.ref_name }}
      - name: Audit archive
        run: |
          aws s3 cp reports/ s3://compliance-audit/${{ github.ref_name }}/ \
            --recursive --sse aws:kms --acl bucket-owner-full-control

ci/prompts/release-review.md 关键段:

你是发布安全评审员。基于 reports/release.patch 与 reports/changes.txt:
1. 标记任何涉及 ① 鉴权/会话 ② 加密 ③ 数据导出 ④ 第三方依赖 ⑤ 数据库 schema 的变更,标 severity=high 起。
2. 对每条 finding 给出受影响场景、可观测信号、建议回滚开关。
3. 输出严格 JSON,schema 见 ci/prompts/severity.md。
4. 不要给出无法在 diff 中验证的"建议改进"——必须基于实际改动。

落地要点:

  • AI review、SAST、license-scan 三个 gate 任意一个失败都会阻断 staging 部署;
  • staging 通过且 release manager 在 GitHub Environment 批准后才进生产,蓝绿切流配合自动回滚;
  • 所有 review 报告、SBOM、cosign 签名一并归档到带 WORM 的 S3 桶,满足审计追溯。

下一步

08. OpenTelemetry 监控与可观测性

分享

评论

登录 后参与讨论。

加载中…

相关文章