10 KiB
CLIProxyAPI 升级、构建与部署记录
当前基线
| 项目 | 当前值 |
|---|---|
| CLIProxyAPI Tag | v7.2.135 |
| submodule 提交 | ee2c494788f8a089c58f7ae9aa6ebd1b422211cb |
| patched 构建版本 | v7.2.135-dev |
| Native ABI | 1 |
| RPC schema | 4 |
| Go | 1.26.6 |
| 本地运行目录 | .runtime |
| 本地管理页面 | http://127.0.0.1:8317/management.html |
| 远端目录 | root@akko.pchuan.top:/root/cpa |
DeepSeek 必须配置在 CPA 的 codex-api-key 通道,base-url 使用 https://api.deepseek.com。不要把该凭证配置为 openai-compatibility。Windows Codex CLI 连接本地 CPA 时,provider 的 base_url 使用 http://127.0.0.1:8317/v1,wire_api 使用 responses。
当前本地测试状态保存在被 Git 忽略的 .runtime:
- CPA 配置:
.runtime/config.yaml; - billing 数据库:
.runtime/data/billing.db; - 管理 Key 和默认下游 Key:
000000; - 测试模型:
deepseek-v4-flash; - 默认额度:
$10,最大并发数:4; - 当前价格是本地验收价格,不作为生产价格依据。
升级宿主或插件时保留配置和数据库,不重复初始化 Key、价格和额度。
已知上游测试失败
CLIProxyAPI ee2c4947 在 Debian WSL 中运行 go test ./... -count=1 时有以下失败:
| 测试 | 实际值 | 期望值 |
|---|---|---|
TestApplyClaudeHeaders_DisableDeviceProfileStabilization |
X-Stainless-Os=MacOS |
Linux |
TestApplyClaudeHeaders_LegacyModePreservesConfiguredUserAgentOverrideForClaudeClients |
X-Stainless-Os=MacOS |
Linux |
TestClaudeExecutor_NonClaudeRequestUsesClaudeCode220CLIFingerprint |
X-Stainless-Os=MacOS |
Linux |
2026-08-18 已在未应用任何 billing 补丁的纯上游 ee2c4947 临时 worktree 中复现相同结果。三项补丁没有修改 internal/runtime/executor,因此同一提交、同一 WSL 环境、同一失败内容再次出现时,直接记为已知上游失败,不再创建干净 worktree复测。
出现以下任一情况时重新验证:
- submodule 提交不再是
ee2c4947; - 上游修改了
internal/runtime/executor/claude_executor_test.go、claude_executor_request.go或helps/claude_device_profile.go; - 失败测试、行号、实际值或期望值发生变化;
- 三项补丁开始修改
internal/runtime/executor。
submodule 升级
当前 submodule 工作区包含三项已应用补丁。升级前必须按反方向撤销,再切换上游提交:
git -C .externals/CLIProxyAPI apply --reverse ../../patch/cli-proxy-api-request-lifecycle-cancel.patch
git -C .externals/CLIProxyAPI apply --reverse ../../patch/cli-proxy-api-usage-identity.patch
git -C .externals/CLIProxyAPI apply --reverse ../../patch/cli-proxy-api-usage-context.patch
git -C .externals/CLIProxyAPI fetch --tags --prune origin
git -C .externals/CLIProxyAPI switch --detach origin/main
重新应用补丁:
git -C .externals/CLIProxyAPI apply ../../patch/cli-proxy-api-usage-context.patch
git -C .externals/CLIProxyAPI apply ../../patch/cli-proxy-api-usage-identity.patch
git -C .externals/CLIProxyAPI apply ../../patch/cli-proxy-api-request-lifecycle-cancel.patch
git -C .externals/CLIProxyAPI diff --check
应用后 submodule 显示 dirty 是预期结果。根仓库提交新的 gitlink 指针和必要的 patch/ 更新,不在 submodule 中创建派生提交。
测试顺序
WSL 使用以下环境。Go bootstrap 可能低于 1.26.6,有效 toolchain 由 Go 自动下载;gofmt 位于有效 GOROOT/bin,因此需要补充 PATH:
export GOPROXY=https://goproxy.cn,direct
export PATH="$(go env GOROOT)/bin:$PATH"
go version
gofmt -h >/dev/null
从 PowerShell 调用包含 Bash 变量、命令替换或多层引号的命令时,把内容写入 .runtime/tmp/*.sh 后交给 WSL 执行。.runtime/tmp 不提交。
每次升级执行以下检查:
cd .externals/CLIProxyAPI
go test -race ./internal/pluginhost ./sdk/api/handlers ./sdk/cliproxy/usage -count=1
go test ./... -count=1
cd ../..
go test ./... -count=1
go test -race ./... -count=1
补丁正确性的最低标准如下:
- 三项补丁按顺序应用成功,
git diff --check通过; internal/pluginhost、sdk/api/handlers、sdk/cliproxy/usagerace 测试通过;- billing 全量测试和全量 race 测试通过;
- CPA 全量测试除已记录的纯上游失败外通过;
- CPA 和 billing 均可编译。
构建
CPA 版本必须使用当前最新 Tag 加 -dev,提交取 submodule HEAD:
cd .externals/CLIProxyAPI
version=v7.2.135-dev
commit="$(git rev-parse --short=8 HEAD)"
build_date="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
CGO_ENABLED=1 go build -buildvcs=false \
-ldflags="-s -w -X main.Version=$version -X main.Commit=$commit -X main.BuildDate=$build_date" \
-o ../../.runtime/bin/cli-proxy-api.new ./cmd/server/
../../.runtime/bin/cli-proxy-api.new -h >/dev/null
-h 会在第一行输出完整版本。上游没有 --version 参数,不要使用该参数核对版本。
构建插件:
cd ../..
bash scripts/build.sh
cp bin/billing.so .runtime/plugins/billing.so.new
sha256sum bin/billing.so .runtime/plugins/billing.so.new
两个插件哈希必须一致。
本地替换与验收
本地 CPA 只使用 .runtime。替换前停止进程并保存旧产物:
bash scripts/stop-test-host.sh
backup=".runtime/backups/$(date +%Y%m%d-%H%M%S)"
mkdir -p "$backup"
cp .runtime/bin/cli-proxy-api "$backup/"
cp .runtime/plugins/billing.so "$backup/"
mv .runtime/bin/cli-proxy-api.new .runtime/bin/cli-proxy-api
mv .runtime/plugins/billing.so.new .runtime/plugins/billing.so
bash scripts/run-test-host.sh
启动后检查:
/healthz返回status=ok;/v0/management/plugins中 billing 的registered、enabled、effective_enabled都为true;- 日志版本与构建参数一致,且没有插件错误或 panic;
- 无下游 Key 的请求返回 401;
- 有效 billing Key 的
/v1/responses请求返回 200; - 请求只新增一条明细,包含唯一 Request ID 和 Token;
- 额度只扣减一次,
active_requests回到 0。
本地 CPA 通过 WSL localhost 转发供 Windows 使用。取消链路测试需要在 WSL 内直连 127.0.0.1:8317,避免 Windows localhost 转发延迟传递断开。
远端发布
核心升级使用 PowerShell 脚本:
./scripts/push.ps1
脚本默认执行以下操作:
- fetch
origin/main并要求 submodule HEAD 与其一致; - 要求 submodule 修改文件集合与
patch/*.patch声明一致; - 运行三个补丁相关包的 race 测试;
- 使用最新 Tag 加
-dev和当前提交、构建时间编译核心; - 生成 gzip 最高压缩级别的核心包和 SHA-256;
- 上传后在远端重新校验压缩包、版本和核心哈希;
- 等待 billing
active_requests=0,备份后只替换 CPA 核心; - 核对配置、所有插件动态库、插件注册状态和独立 keeper;
- 失败时恢复旧核心并按部署前状态启动 CPA Manager Plus。
只执行本地构建、测试和打包,不上传或部署:
./scripts/push.ps1 -WhatIf
复用已有核心时使用 -SkipBuild -BinaryPath <path>;跳过补丁相关 race 测试使用 -SkipTests;部署锁定但不是当前 origin/main 的提交时显式使用 -SkipUpstreamCheck。请求排空默认等待 120 秒,可通过 -DrainTimeoutSeconds 和 -DrainPollSeconds 调整。
远端只部署本项目的 billing 和已要求启用的 keeper。发布步骤如下:
- 本地完成真实模型请求、协议、计费和取消链路验收;
- 对 CPA 二进制和插件计算 SHA-256;
- 使用 gzip、tar.gz 或
scp -C上传; - 停止
/root/cpa/cpa.sh管理的进程; - 把旧 CPA、billing、keeper 和
data/cpa-ext.db*保存到/root/cpa/backups/<timestamp>/; - 替换二进制和插件,保留配置及 secret 文件;
- 启动进程并检查健康状态、版本、插件注册状态和日志;
- 启动失败时恢复同一备份目录中的文件并重启。
远端不发送 /v1/responses、/v1/chat/completions 或 compact 请求。管理密钥和下游 Key 在远端脚本内部从 secret 文件或管理 API 读取,不输出到终端和普通日志。
cpa.sh start 会先把管理 Key 同步到 config.yaml,CPA 启动后会重新保存该字段的哈希,因此每次启动后 config.yaml 的原始 SHA-256 可能变化。部署校验应把 remote-management.secret-key 的值归一化后比较其余配置内容,不得因为原始配置哈希变化回滚核心。
远端存在持续请求时,在远端部署脚本内部先完成压缩包和插件检查,再每 5 秒读取 billing active_requests。检测到 0 后立即停止 CPA,避免在本地轮询与远端执行之间出现新请求。
2026-08-18 验证记录
v7.2.135 / ee2c4947 已完成以下验证:
- 三项补丁重新应用成功,共修改 11 个文件,增加 289 行,删除 10 行;
- 补丁相关三个包的 race 测试通过;
- billing 全量测试和全量 race 测试通过;
- CPA 和 billing Linux amd64 产物编译成功;
- CPA 运行版本为
v7.2.135-dev / ee2c4947; - billing
0.1.0加载并注册; - DeepSeek Codex
/v1/responses返回 200 和CODEX_READY; - 该请求记录 129 Token,只产生一条计费记录,
active_requests=0; - 本地替换前产物保存在
.runtime/backups/20260818-154252-v7.2.135/。
同日已完成远端核心升级:
- 只替换
/root/cpa/bin/cli-proxy-api,插件、配置、数据库和独立 keeper 未替换; - 远端运行版本为
v7.2.135-dev / ee2c4947,核心 SHA-256 为d702d8d65a06911b5bec78476d84e228bcfb57e03c511b4c1d89df8f460c41fd; - CPA PID 为
278177,独立 keeper PID 保持为230299; - billing 和 keeper
0.1.0均已加载、注册和启用; /healthz正常,启动日志没有 panic 或插件错误;- 未向远端模型端点发送验收请求;
- 升级前文件保存在
/root/cpa/backups/20260818T081102Z-core-v7.2.135/。