Claude Code生产级落地:三层隔离架构与CI/CD工程化实践
1. 项目概述这不是又一个“AI插件安装指南”而是一套可落地的工程化协作系统Claude Code 不是 VS Code 里点几下就能跑起来的玩具它本质是一套需要嵌入真实开发节奏的智能编码协作者。我从 2023 年底开始在三个不同规模的团队中推动 Claude Code 的规模化落地——一个 8 人前端中台组、一个 25 人全栈 SaaS 产品线、还有一个承接银行核心系统重构的 40 人外包联合团队。过程中踩过的坑、调过的参数、写过的适配脚本、改过的 CI/CD 流水线远比官网文档里那几行“npm install -g claude-code”要复杂得多。这本手册不讲“怎么打开 UI”而是直击生产环境最痛的五个断点本地开发环境与 CI 环境的技能一致性缺失、多仓库间提示词策略无法复用、敏感上下文如数据库连接串、密钥在自动补全中意外泄露、团队级代码规范无法被模型实时理解、以及当 DeepSeek-R1 或 Qwen2.5 接入后原有 skill 链路彻底失效。你看到的“安装”二字背后实际是 Node.js 版本锁、Python 运行时隔离、Git 钩子拦截逻辑、Docker 容器内证书信任链、以及 Windows MSI 安装包签名验证失败等一整套工程问题。所谓“2026年5月版”核心不是时间戳而是指代我们已将 Claude Code 深度集成进 GitLab CI 的 job stage、Jenkins 的 pipeline script、以及内部知识库的语义检索层——它不再是一个 IDE 插件而是一个可编排、可审计、可回滚的代码生成服务节点。如果你还在用“CtrlEnter”触发补全那你离生产级还有三道防火墙没翻过去。2. 核心设计思路为什么必须放弃“一键安装”转而构建三层隔离架构2.1 传统安装路径的致命缺陷环境污染与技能漂移绝大多数教程教你在全局 npm 下装claude-code-cli再配个~/.claude/config.json就完事。这在单机 demo 场景下确实能跑通但一旦进入团队协作立刻暴露出三个硬伤第一Node.js 版本强耦合。Claude Code CLI v3.2.7 要求 Node.js ≥ 18.17.0但你的遗留项目可能还卡在 Node 14 上跑 Jenkins 构建而新项目又强制要求 Node 20.12 以支持 WebAssembly 加速。全局安装意味着你只能在一台机器上做取舍要么牺牲旧项目稳定性要么放弃新特性。我亲眼见过某金融客户因全局升级 Node 导致 CI 流水线中npm ci --no-audit命令静默失败排查三天才发现是claude/code-core依赖的node-fetch3.3.2在 Node 14 下会跳过 TLS 证书校验造成 API 请求被网关拦截。第二技能Skill配置无法版本化。官方文档说“把 skill 写进skills/目录就行”但没人告诉你这些.ts文件不会被 Git 自动追踪——因为默认.gitignore里有node_modules/和dist/而 skill 编译产物恰恰落在dist/skills/。结果就是A 同学在本地写了sql-injection-guardskillB 同学拉代码后发现claude code run --skill sql-injection-guard报错Cannot find module sql-injection-guard。更糟的是skill 里写的process.env.DB_PASSWORD在本地是明文推到 GitHub 后就成了公开密码库。第三UI 与 CLI 行为不一致。桌面版Windows MSI和 CLI 版使用完全不同的配置加载逻辑前者读C:\Users\{user}\AppData\Roaming\Claude Code\config.json后者读$HOME/.claude/config.json。当你在 UI 里配置了--model deepseek-r1CLI 却固执地调用claude-3-haiku这种割裂直接导致“本地测试通过CI 失败”的经典幻觉。提示不要试图用nvm或fnm解决 Node 版本问题。它们管理的是 shell 环境变量而 CI 工具如 GitLab Runner启动的是 clean environmentnvm use命令根本不会被执行。真正的解法是让 Claude Code 自身具备运行时环境感知能力。2.2 三层隔离架构Runtime / Skill / Config 的物理分离我们最终采用的方案是把整个 Claude Code 生态拆成三个物理隔离层每层独立构建、独立部署、独立审计Runtime 层用 Docker 容器封装完整运行时。基础镜像不是node:20-alpine而是基于ubuntu:22.04从源码编译 Node 20.12 Python 3.11 Git 2.40所有二进制文件静态链接避免 glibc 版本冲突。关键动作是在容器启动时自动检测宿主机/proc/sys/fs/inotify/max_user_watches值若低于 524288 则报错退出——这是防止--watch模式下文件变更监听丢失的根本保障。Skill 层所有 skill 必须以 TypeScript 编写且强制遵循“零外部依赖”原则。我们自研了一个claude/skill-kit库提供safeExec()沙箱进程执行、maskEnv()环境变量脱敏、gitContext()当前分支/提交哈希/差异行号注入三个核心 API。每个 skill 目录下必须有skill.manifest.json声明其输入 schema如{ table: string, columns: string[] }和输出 schema如{ query: string, explain: string }。构建时tsc编译 esbuild打包 sha256sum生成指纹最终产出skill-{fingerprint}.js。Git 提交时只允许提交源码和 manifestdist/目录禁止入 Git。Config 层配置文件不再是 JSON而是用 YAML 编写的claude.config.yml支持 Jinja2 模板语法。例如model: {{ env.CLAUDE_MODEL or claude-3-sonnet }} timeout: {{ 30 if env.CI else 120 }} skills: - name: sql-validator path: ./skills/sql-validator/dist/skill-abc123.js enabled: {{ not env.CI }} # CI 环境禁用耗时 skill这样同一份配置文件在本地开发机上渲染出timeout: 120在 GitLab CI job 中渲染出timeout: 30且sql-validatorskill 自动关闭。YAML 解析器由我们自己用 Rust 编写claude-config-parser确保无 JS 依赖可在任何环境运行。这套架构的收益是立竿见影的某电商客户将 Runtime 镜像推送到私有 HarborSkill 层代码纳入 Git 主干分支受 CR 流程管控Config 层则按环境拆分为claude.prod.yml/claude.staging.yml全部走 Argo CD 同步。现在他们新增一个k8s-manifest-generatorskill从编码、测试、上线到全集群生效全程 17 分钟且每次变更都有完整的 Git commit hash Docker image digest config SHA256 三重溯源。2.3 为什么放弃官方桌面版MSI 安装包的隐藏陷阱标题里提到的 “cc switch windows 安装” 和 “msi文件怎么安装”暴露了大量用户卡在第一步的真实困境。官方 Windows MSI 安装包截至 2026 年 5 月最新版为ClaudeCode-3.2.7-x64.msi存在三个未公开的硬性限制证书链强制验证安装程序会调用 Windows CryptoAPI 验证自身签名证书是否在Trusted Root Certification Authorities存储中。很多企业域控策略会禁用外部根证书导致双击 MSI 后弹出“此安装包无法验证”错误且错误日志藏在C:\Windows\Temp\MSI*.log里普通用户根本找不到。我们实测即使手动导入 DigiCert Global Root G3 证书若域策略启用了Certificate Trust List (CTL)强制模式安装仍会失败。注册表写入权限锁定安装过程试图向HKEY_LOCAL_MACHINE\SOFTWARE\Claude\Code写入配置但标准域用户账户默认无 HKLM 写权限。解决方案不是提权而是用msiexec /i ClaudeCode-3.2.7-x64.msi ALLUSERS2参数以每用户模式安装此时配置写入HKEY_CURRENT_USER\Software\Claude\Code且后续更新无需管理员密码。UI 进程与 CLI 进程内存隔离桌面版启动后会在后台常驻一个claude-code-ui.exe进程占用 450MB 内存而 CLI 版执行claude code run时会另起一个claude-code-cli.exe进程。两者配置文件路径不同且 UI 进程会劫持http://localhost:3000端口导致 CLI 的--ui参数失效。我们最终选择完全卸载桌面版所有开发人员统一使用 CLI VS Code 插件组合用code --install-extension claude.code命令安装插件再通过claude code serve --port 3001启动独立服务端彻底规避进程冲突。注意不要相信网上流传的“修改 MSI 注册表权限”的批处理脚本。那些脚本会破坏 Windows Installer 的事务完整性导致后续热更新hotfix失败且在 Windows 11 23H2 及以上版本中已被系统策略拦截。3. 实操细节解析从零构建可审计的生产级环境3.1 Runtime 层Docker 镜像构建的 7 个关键步骤构建一个真正可用于生产的 Claude Code Runtime 镜像绝非FROM node:20然后RUN npm install -g claude-code-cli那么简单。以下是我们在 Ubuntu 22.04 环境下验证通过的完整构建流程每一步都附带原理说明和避坑点步骤 1基础系统初始化FROM ubuntu:22.04 # 关键禁用 systemd启用 sysvinit避免容器内 init 进程冲突 RUN apt-get update apt-get install -y \ curl wget git ca-certificates gnupg2 \ rm -rf /var/lib/apt/lists/* # 设置时区避免日志时间戳混乱 ENV TZAsia/Shanghai RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime echo $TZ /etc/timezone原理Ubuntu 22.04 默认使用 systemd但 Docker 容器最佳实践是使用 PID 1 进程直接运行应用。ca-certificates包含全球可信根证书gnupg2是后续验证 CLI 二进制签名所必需。步骤 2Node.js 源码编译非 apt 安装# 下载 Node.js v20.12.2 源码官方 tar.xz 包 RUN cd /tmp \ curl -fsSL https://nodejs.org/download/release/v20.12.2/node-v20.12.2.tar.xz | tar -xJ \ cd node-v20.12.2 \ ./configure --prefix/opt/node --without-snapshot --without-intl \ make -j$(nproc) make install ENV PATH/opt/node/bin:$PATH原理--without-snapshot禁用 V8 快照减小镜像体积--without-intl禁用 ICU 国际化支持避免libicu动态链接问题make -j$(nproc)利用全部 CPU 核心加速编译。apt 安装的 Node 会依赖系统libssl.so.1.1而 Alpine 镜像用libssl.so.3跨平台兼容性差。步骤 3Python 运行时嵌入# 安装 Python 3.11.9源码编译静态链接 OpenSSL RUN cd /tmp \ curl -fsSL https://www.python.org/ftp/python/3.11.9/Python-3.11.9.tgz | tar -xzf - \ cd Python-3.11.9 \ ./configure --prefix/opt/python --enable-optimizations --with-openssl/usr \ make -j$(nproc) make install ENV PATH/opt/python/bin:$PATH # 验证 pip 源为国内镜像避免 CI 构建超时 RUN pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple原理Claude Code 的某些 skill如涉及数据清洗需调用 Python。源码编译确保libpython3.11.a静态链接避免容器内缺少libpython3.11.so的报错。清华镜像源是必须项否则pip install在 CI 中平均耗时 8 分钟。步骤 4Git 配置与凭证管理# 安装 Git 2.40Ubuntu 22.04 默认 2.34不支持 sparse-checkout v2 RUN cd /tmp \ curl -fsSL https://github.com/git/git/archive/refs/tags/v2.40.1.tar.gz | tar -xzf - \ cd git-2.40.1 make configure ./configure --prefix/usr make -j$(nproc) make install # 配置 Git 凭据助手为 store非 cache避免内存凭据丢失 RUN git config --global credential.helper store原理sparse-checkout是 Claude Code 分析大型单体仓库的关键特性v2.34 不支持cone mode会导致claude code analyze --repo .命令卡死。credential.helper store将 token 明文存于~/.git-credentials虽不安全但在 CI 容器内是唯一可靠方案cache依赖内存容器重启即失。步骤 5Claude Code CLI 安装与验证# 下载官方 CLI 二进制非 npm install避免依赖树污染 RUN cd /tmp \ curl -fsSL https://github.com/anthropic/claude-code/releases/download/v3.2.7/claude-code_3.2.7_linux_amd64.tar.gz | tar -xzf - \ mv claude-code /usr/local/bin/ \ chmod x /usr/local/bin/claude-code # 验证签名官方提供 .sig 文件 RUN curl -fsSL https://github.com/anthropic/claude-code/releases/download/v3.2.7/claude-code_3.2.7_linux_amd64.tar.gz.sig -o /tmp/claude-code.sig \ gpg --verify /tmp/claude-code.sig /tmp/claude-code_3.2.7_linux_amd64.tar.gz原理npm 全局安装会创建node_modules目录占用空间且易受恶意包攻击。官方二进制经 GPG 签名gpg --verify是生产环境必备校验步骤。注意GPG 密钥需提前导入命令为gpg --import /path/to/anthropic-public-key.asc。步骤 6Inotify 与 Limits 调优# 设置容器内 inotify 限制关键 RUN echo fs.inotify.max_user_watches524288 /etc/sysctl.conf \ echo fs.inotify.max_user_instances1024 /etc/sysctl.conf # 设置 ulimit避免 open files 耗尽 RUN echo * soft nofile 65536 /etc/security/limits.conf \ echo * hard nofile 65536 /etc/security/limits.conf原理max_user_watches控制可监听的文件数量。一个中型项目10k 文件至少需要 20w watches否则--watch模式下新增文件不会触发分析。ulimit设置确保 CLI 进程可同时打开足够多的文件描述符。步骤 7健康检查与入口点# 添加健康检查脚本 COPY healthcheck.sh /healthcheck.sh RUN chmod x /healthcheck.sh HEALTHCHECK --interval30s --timeout3s --start-period5s --retries3 \ CMD /healthcheck.sh # 入口点启动前执行环境检查 COPY entrypoint.sh /entrypoint.sh RUN chmod x /entrypoint.sh ENTRYPOINT [/entrypoint.sh]healthcheck.sh内容#!/bin/bash # 检查 CLI 是否能响应基本命令 if claude-code --version /dev/null 21; then exit 0 else exit 1 fientrypoint.sh内容#!/bin/bash # 检查必要环境变量 if [ -z $CLAUDE_API_KEY ]; then echo ERROR: CLAUDE_API_KEY is required 2 exit 1 fi # 检查磁盘空间避免 /tmp 写满 if [ $(df /tmp | tail -1 | awk {print $5} | sed s/%//) -gt 90 ]; then echo ERROR: /tmp usage 90% 2 exit 1 fi exec $原理Kubernetes 的 liveness probe 必须能快速判断容器是否真正在工作而非仅进程存活。claude-code --version是最轻量的健康检查耗时 100ms。entrypoint.sh的环境变量校验避免容器启动后因缺 key 而无限重试拖垮整个 Pod。最终镜像大小约 1.2GB但换来的是100% 可复现的构建过程、零 npm 依赖风险、完整的安全签名验证、以及 Kubernetes 环境下的稳定生命周期管理。3.2 Skill 层从零编写一个可上线的 SQL 安全校验 Skill以sql-validator为例展示如何编写一个符合生产要求的 Skill。这不是简单的“用正则匹配DROP TABLE”而是融合了 AST 解析、上下文感知、以及动态规则引擎的完整方案。第一步定义 Skill Manifestskills/sql-validator/skill.manifest.json{ name: sql-validator, version: 1.0.0, description: Validate SQL queries against security policies and schema constraints, input: { type: object, properties: { query: { type: string }, schema: { type: string, enum: [postgres, mysql, sqlite] }, context: { type: object, properties: { table: { type: string } } } }, required: [query, schema] }, output: { type: object, properties: { valid: { type: boolean }, issues: { type: array, items: { type: string } }, suggestion: { type: string } } } }原理manifest 是 Skill 的契约。input.schema和output.schema被用于自动生成 OpenAPI 文档并作为 CI 流水线中claude-code validate-skill命令的校验依据。enum限定schema类型避免运行时类型错误。第二步编写 TypeScript 源码skills/sql-validator/src/index.tsimport { safeExec, maskEnv, gitContext } from claude/skill-kit; import * as postgresParser from postgres-ast-parser; // 专为 PostgreSQL 设计的 AST 解析器 import * as mysqlParser from mysql-ast-parser; // MySQL 专用解析器 export async function run(input: any): Promiseany { const { query, schema, context } input; // 步骤1脱敏敏感环境变量防止日志泄露 const maskedEnv maskEnv(process.env, [DB_PASSWORD, API_KEY]); // 步骤2获取 Git 上下文谁在什么分支上提交了这个 SQL const gitInfo await gitContext(); // 步骤3根据 schema 类型选择解析器 let ast; try { if (schema postgres) { ast postgresParser.parse(query); } else if (schema mysql) { ast mysqlParser.parse(query); } else { throw new Error(Unsupported schema: ${schema}); } } catch (e) { return { valid: false, issues: [SQL syntax error: ${e.message}], suggestion: Check your SQL syntax using an online validator }; } // 步骤4AST 遍历执行安全规则 const issues: string[] []; const visitor { visitDropStatement(node: any) { if (node.objectType TABLE) { issues.push(DROP TABLE is prohibited in production); } }, visitInsertStatement(node: any) { // 检查是否使用了 VALUES 子句而非 SELECT防止注入 if (!node.values) { issues.push(INSERT without VALUES clause may be unsafe); } }, visitSelectStatement(node: any) { // 检查是否包含 LIMIT防全表扫描 if (!node.limit context.table context.table ! logs) { issues.push(SELECT without LIMIT on table ${context.table} may cause performance issues); } } }; // 步骤5执行遍历这里简化为伪代码实际用递归下降 traverseAST(ast, visitor); // 步骤6返回结构化结果 return { valid: issues.length 0, issues, suggestion: issues.length 0 ? Fix the above issues before deploying : Query is safe to execute }; } // 辅助函数AST 遍历实际实现略 function traverseAST(node: any, visitor: any) { // 实际代码会深度遍历所有节点类型 }第三步构建与发布skills/sql-validator/package.json{ name: sql-validator, version: 1.0.0, main: dist/index.js, types: dist/index.d.ts, scripts: { build: tsc esbuild src/index.ts --bundle --platformnode --targetnode18 --outfiledist/index.js --minify, hash: sha256sum dist/index.js | cut -d -f1 } }构建命令cd skills/sql-validator npm install npm run build npm run hash # 输出a1b2c3d4e5f6...生成的dist/index.js文件名重命名为skill-a1b2c3d4e5f6.js并提交skill.manifest.json到 Git。实操心得我们曾因忘记在package.json中设置type: module导致 ES Module 语法在 Node 20 下报错ERR_REQUIRE_ESM。解决方案是在tsconfig.json中添加module: commonjs或直接使用esbuild输出 CJS 格式。另外postgres-ast-parser库体积较大2.1MB我们将其从dependencies移至devDependencies并在构建时用esbuild --external:postgres-ast-parser排除改由 Runtime 层预装最终 skill 包体积从 3.2MB 压缩到 89KB。3.3 Config 层YAML 配置的动态渲染与环境分发生产环境中claude.config.yml不是静态文件而是由 CI 流水线动态生成。以下是 GitLab CI 的.gitlab-ci.yml片段展示如何为不同环境生成配置stages: - build - deploy variables: CONFIG_TEMPLATE: claude.config.yml.j2 build:config:prod: stage: build image: python:3.11 script: - pip install jinja2 - | python3 -c import os, jinja2, yaml template jinja2.Template(open($CONFIG_TEMPLATE).read()) rendered template.render( envprod, claude_modelclaude-3-opus-20240229, timeout60, skills[sql-validator, k8s-manifest-generator] ) with open(claude.prod.yml, w) as f: f.write(rendered) print(Generated claude.prod.yml) artifacts: paths: - claude.prod.yml deploy:to-prod: stage: deploy image: docker:20.10.16 services: - docker:dind script: - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - docker build -t $CI_REGISTRY_IMAGE:prod . - docker push $CI_REGISTRY_IMAGE:prod - | # 将配置挂载到容器 kubectl create configmap claude-config-prod \ --from-fileclaude.prod.yml \ --dry-runclient -o yaml | kubectl apply -f -claude.config.yml.j2模板# {{ env }} environment configuration model: {{ claude_model }} timeout: {{ timeout }} max-retries: 3 skills: {% for skill_name in skills %} - name: {{ skill_name }} path: /app/skills/{{ skill_name }}/skill-{{ lookup(env, SKILL_ ~ skill_name | upper ~ _HASH) }}.js enabled: true {% endfor %} # 动态注入 Git 信息 git: branch: {{ lookup(env, CI_COMMIT_BRANCH) }} commit: {{ lookup(env, CI_COMMIT_SHORT_SHA) }} author: {{ lookup(env, GITLAB_USER_NAME) }}关键技巧SKILL_SQL_VALIDATOR_HASH这类环境变量是在build:skill:sql-validatorjob 中计算并导出的。我们用artifacts:reports:dotenv功能让一个 job 的输出自动成为下一个 job 的环境变量。这样sql-validator的 SHA256 哈希值在构建完成后就自动注入到所有后续 job 的环境变量中无需人工维护。最终claude.prod.yml渲染结果示例# prod environment configuration model: claude-3-opus-20240229 timeout: 60 max-retries: 3 skills: - name: sql-validator path: /app/skills/sql-validator/skill-a1b2c3d4e5f6.js enabled: true - name: k8s-manifest-generator path: /app/skills/k8s-manifest-generator/skill-7890abcd1234.js enabled: true git: branch: main commit: a1b2c3d author: Zhang San这个文件被挂载为 Kubernetes ConfigMap容器启动时通过--config /config/claude.prod.yml参数加载。任何配置变更只需提交新的模板或环境变量CI 自动完成重建、推送、滚动更新全程无人工干预。4. 生产级工作流实现从本地开发到 CI/CD 的全链路贯通4.1 本地开发工作流VS Code 插件 CLI 服务端的黄金组合放弃官方桌面版后我们为开发者定制了一套 VS Code 插件与 CLI 服务端协同的工作流。这不是简单的“装个插件”而是重新定义了人机协作的边界。插件配置.vscode/settings.json{ claude-code.enable: true, claude-code.serverUrl: http://localhost:3001, claude-code.model: claude-3-sonnet-20240229, claude-code.timeout: 120, claude-code.skills: [ sql-validator, git-diff-explainer ], claude-code.autoTrigger: { onSave: true, onType: false, delayMs: 800 } }原理serverUrl指向本地 CLI 启动的服务端而非插件内置的 Electron 进程。autoTrigger.onSave表示每次保存文件时自动触发分析delayMs: 800避免频繁保存导致请求风暴。onType: false是关键——我们禁用实时补全因为生产代码必须经过人工审查AI 的“建议”应作为辅助参考而非自动插入。CLI 服务端启动脚本dev-server.sh#!/bin/bash # 启动 Claude Code 服务端绑定到 localhost:3001 claude-code serve \ --port 3001 \ --config ./claude.dev.yml \ --cors-allowed-origins http://localhost:3000 \ --log-level debug \ --watch \ --watch-debounce 1000 \ --watch-ignore **/node_modules/** \ --watch-ignore **/dist/** \ --watch-ignore **/build/**claude.dev.yml内容model: claude-3-sonnet-20240229 timeout: 120 skills: - name: sql-validator path: ./skills/sql-validator/dist/skill-a1b2c3d4e5f6.js enabled: true - name: git-diff-explainer path: ./skills/git-diff-explainer/dist/skill-fedcba987654.js enabled: true # 开发环境特有启用详细日志便于调试 logging: level: debug file: ./logs/claude-dev.log max-size: 10M max-backups: 5工作流实操场景开发者在 VS Code 中编辑user-service/src/db/query.ts写入一个DELETE FROM users WHERE id ${id}查询。保存文件CtrlSVS Code 插件捕获事件向http://localhost:3001/analyze发送 POST 请求携带文件内容、当前光标位置、Git 分支信息。CLI 服务端收到请求加载sql-validatorskill解析 AST发现DELETE语句返回{valid: false, issues: [DELETE statement is prohibited]}。VS Code 插件在编辑器底部状态栏显示红色警告“⚠️ SQL 安全检查失败DELETE statement is prohibited”并提供 Quick Fix点击后自动替换为UPDATE users SET deleted_at NOW() WHERE id ${id}由 skill 内置的修复逻辑生成。开发者确认修复提交代码。实操心得我们最初将--watch间隔设为500ms结果在大型 monorepo 中每次保存触发 20 个文件分析CPU 占用飙到 95%。改为1000ms并增加--watch-debounce后性能恢复平稳。另外--cors-allowed-origins必须精确匹配 VS Code 插件的 originhttp://localhost:3000否则浏览器会拦截请求且错误信息极其隐蔽——只在 DevTools Console 显示CORS policy: No Access-Control-Allow-Origin header新手往往卡在这里数小时。4.2 CI/CD 工作流GitLab CI 中的自动化代码审查将 Claude Code 接入 CI不是为了“炫技”而是建立一道不可绕过的质量门禁。我们的规则是任何未通过 Claude Code 安全检查的 MRMerge Request禁止合并。.gitlab-ci.yml关键 jobstages: - test - security - deploy # Stage: security claude-code:security-check: stage: security image: name: registry.example.com/claude-runtime:prod entrypoint: [] variables: # 从 CI 变量注入 API Key已加密 CLAUDE_API_KEY: $CLAUDE_API_KEY_ENCRYPTED before_script: - claude-code --version - claude-code config list script: # 分析本次 MR 修改的所有 .sql 文件 - | git diff --name-only $CI_MERGE_REQUEST_TARGET_BRANCH_NAME...$CI_COMMIT_SHA -- *.sql | while read file; do echo Analyzing $file... claude-code analyze \ --file $file \ --skill sql-validator \ --config /config/claude.prod.yml \