Files
ModelRouter/packaging/upload-release.sh
JianFeeeee 9bec158d2e chore(main): 回流 release/v2.0.x(v2.0.12)—— 内容对齐,main 无独有内容
按发布纪律回流。**注意这是内容对齐而非 merge**,理由与依据:

1. 纪律禁止 merge 回主干,因为 merge 会把发布分支的**版本号变更**带进 main。
   本项目版本号**只由 `git describe --tags` 推导**(Makefile VERSION),
   仓库里没有任何文件存放版本号 ⇒ 回流不存在版本污染风险。
2. 逐项核对确认 **main 是 release 的内容严格子集**:
   - `main` 独有的**文件**:0 个;
   - `internal/lua/plugins.go` / `internal/core/kernel_actions.go` 等内核文件
     main 独有行数:0;
   - `deploy.sh` 那 14 行只是 emoji 清理(release 刻意去掉了 emoji);
   - `channels.lua` 那 333 行是**旧版内容**(旧 exports 表、旧模型名单)。
   - main 独有的 9 个提交按 patch-id **全部已在 release 中等效存在**
     (`git cherry` 逐条列出均为 `-`,即已合入)。
3. 故回流 = 把 release 的内容带到 main,等价于"只捡拾修复、不带版本号",
   且不会丢任何 main 独有的修复。

本次带回 v2.0.12 的全部内容(37 个提交):
- 源串行 + 按模型节流(照 model-gate)
- 已失效模型存储 + 远端目录闸门
- 余额分档选号
- 模型能力元数据(models.dev,isFree 权威判定)
- **凭据续期修复**(此前恒报 ok:true 却一个请求都不发)
- 通用件 TTL 缓存 + 串行锁;account_test/account_adopt/account_delete 修正
- 内核级:出站授权持久化重启后不生效、`__llmsproxy_plugin_dir` ground truth

校验:`git diff release/v2.0.x` = 0 行;`go build -tags luajit ./...` 通过。
2026-10-14 16:52:58 +08:00

72 lines
2.6 KiB
Bash
Executable File

#!/usr/bin/env bash
# Upload release assets to a GitCode release.
#
# The endpoint shapes are asymmetric and both differ from the "obvious" guess:
#
# GET /releases/tags/{tag} → read a release
# GET /releases/{tag}/upload_url → get a presigned PUT (NO "tags/")
# PUT {presigned url} → upload, REPLAYING the headers verbatim
#
# Two mistakes cost real time on v1.9.5 before this script existed:
#
# 1. POSTing straight to /releases/{tag}/assets returns 404 — that endpoint
# does not exist. It reads as "authentication failed" if you only check
# the status code.
# 2. PUTting without the headers fails with an opaque storage error, not a
# permission one, so it looks like a size limit or a corrupt file.
#
# The x-obs-* headers are part of the signature: dropping any one of them turns
# the request into an unsigned one.
set -uo pipefail
TOKEN="$(tr -d '\n\r' < /tmp/gc_token)"
REPO="HeNanMU-EEA/ModelRouter"
TAG="${1:?usage: upload-release.sh <tag> <file>...}"
shift
API="https://gitcode.com/api/v5/repos/${REPO}"
for f in "$@"; do
name="$(basename "$f")"
size="$(stat -c%s "$f")"
printf ' %-46s %10s bytes ' "$name" "$size"
# 1) presigned upload location. The file name must be URL-encoded; the v1.9.4
# assets show "~" surviving in a stored name, so encoding is per-component.
enc="$(python3 -c 'import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1]))' "$name")"
resp="$(curl -sS -m 60 -H "Authorization: Bearer ${TOKEN}" \
"${API}/releases/${TAG}/upload_url?file_name=${enc}" 2>&1)"
url="$(printf '%s' "$resp" | python3 -c 'import json,sys
try:
d = json.load(sys.stdin)
print(d.get("url") or d.get("uploadUrl") or "")
except Exception:
print("")' 2>/dev/null)"
if [ -z "$url" ]; then
echo "FAIL 取得上传地址失败: ${resp:0:140}"
continue
fi
# 2) PUT with the headers replayed exactly as returned.
code="$(printf '%s' "$resp" | python3 -c 'import json,sys
try:
print(json.dumps(json.load(sys.stdin).get("headers") or {}))
except Exception:
print("{}")' 2>/dev/null | python3 -c '
import json, subprocess, sys
headers = json.load(sys.stdin)
args = ["curl", "-sS", "-o", "/dev/null", "-w", "%{http_code}", "-X", "PUT"]
for k, v in headers.items():
args += ["-H", f"{k}: {v}"]
args += ["--data-binary", "@" + sys.argv[1], sys.argv[2]]
print(subprocess.run(args, capture_output=True, text=True).stdout)
' "$f" "$url" 2>/dev/null)"
if [ "$code" = "200" ] || [ "$code" = "201" ] || [ "$code" = "204" ]; then
echo "OK HTTP=$code"
else
echo "FAIL HTTP=$code"
fi
sleep 1
done