Merge pull request 'Migrate e2e.sh seeding to the login-key credential contract' (#581) from fix/e2e-seed-credential-contract into main
ci / svc-realcombo (push) Successful in 1m57s
ci / test (push) Successful in 6m13s
ci / test-pg (push) Successful in 8m17s

This commit was merged in pull request #581.
This commit is contained in:
2026-10-16 07:53:46 +00:00
2 changed files with 291 additions and 20 deletions
File diff suppressed because one or more lines are too long
Executable → Regular
+26 -20
View File
@@ -5,8 +5,9 @@
# 1. 构建:RDM 二进制(RDM 仓 origin/main 临时 worktree,pins 物化)
# + 基座 CLI(本 worktree modules/backend,建号用)
# + frontend dist(本 worktree modules/frontend)
# 2. 种子:RDM -bootstrap-admin(域管理员)→ 基座 user create(登录账号)
# → serve(auth on)→ API rdm.project.create×2 + rdm.ingest(主项目)
# 2. 种子:RDM -bootstrap-admin(域管理员)→ serve 首启建基座存储 → identity ensure →
# 基座 user bootstrap-admin(login-key 激活契约;--password 已被拒绝)→
# redeem+设密 → API rdm.project.create×2 + rdm.ingest(主项目)
# 3. 验收:vite preview(dist+/api 代理)→ npx playwright test
# 4. 收尾:停 serve/preview,保存认证/失败工件到 $E2E_OUT
#
@@ -87,7 +88,7 @@ trap cleanup EXIT
(cd "$RDM_WT" && go build -o "$OUT/agent-system-rdm" .) || die "rdm build failed"
log "rdm binary: $OUT/agent-system-rdm (RDM@${RDM_SHA:0:12}, pins@${PIN_SHA_WANT:0:12})"
log "build base CLI (user create) from the same pinned backend as the RDM binary"
log "build base CLI (account bootstrap/activation) from the same pinned backend as the RDM binary"
# 版本一致性:建号 CLI 必须与被测 RDM 二进制共用同一基座 pin——用 Dev 顶层
# backend(main 最新)建号会把库迁到更高 schema,RDM pins(较旧)打不开。
(cd "$RDM_WT/pins/agent-system-backend" && go build -o "$OUT/agent-system" ./cmd/agent-system) \
@@ -104,11 +105,10 @@ RDM="$OUT/agent-system-rdm -data $DATA"
log "bootstrap: RDM domain admin = $OWNER"
$RDM -bootstrap-admin "$OWNER" >/dev/null
log "bootstrap: base account $OWNER (admin)"
"$OUT/agent-system" user create --data "$DATA" --owner "$OWNER" --name "E2E 审计员" \
--password "$PASSWORD" --admin >/dev/null
log "serve RDM at $API_BASE (auth on)"
# ── 凭据契约(2026-10-13 起):--password 建号被 RECOVERY_CONTRACT_REPLACED 拒绝,
# 改走 login-key 激活:serve 首启创建基座存储 → identity ensure → 基座首位账号
# bootstrap-admin(激活 Key 交付)→ API redeem → 设密(PASSWORD2 为登录密码)。
log "serve RDM at $API_BASE (auth on;首启创建基座存储)"
start_serve() {
"$OUT/agent-system-rdm" -data "$DATA" -addr "127.0.0.1:$API_PORT" -auth on \
>"$OUT/serve.log" 2>&1 &
@@ -136,16 +136,6 @@ login() {
done
die "login failed"
}
# CLI 建号留下 must_change_password。会话在改密前不能调用业务命令。
# 强制设密会作废当前会话,所以设密后用新密码再登录。
finish_password_gate() {
curl -sf -b "$JAR" -c "$JAR" -X POST "$API_BASE/api/auth/password" \
-H 'Content-Type: application/json' \
-d "{\"next\":\"$PASSWORD2\"}" >/dev/null || die "password setup failed"
PASSWORD=$PASSWORD2
login
}
cmd() { # cmd <id> <params-json> → payload(失败即死,种子步骤不容忍部分成功)
local id=$1 params=${2:-{\}}
curl -sf -b "$JAR" -X POST "$API_BASE/api/commands/$id" \
@@ -154,11 +144,27 @@ cmd() { # cmd <id> <params-json> → payload(失败即死,种子步骤不容
|| die "command $id rejected"
}
# 阶段①:建项目与需求台账(API;需 serve)。
# 阶段①:激活账号并建项目与需求台账(API;需 serve)。
start_serve
JAR="$OUT/cookies.txt"
log "seed: identity ensure + base first account (login-key 契约)"
ID_OK=0
for i in $(seq 1 15); do
if "$OUT/agent-system" identity ensure --data "$DATA" --instance-id "e2e-audit" >/dev/null 2>&1; then ID_OK=1; break; fi
sleep 1 # 服务端受控迁移(含 identity 表)可能晚于 HTTP 就绪
done
[ "$ID_OK" = 1 ] || { tail -5 "$OUT/serve.log"; die "identity ensure failed"; }
"$OUT/agent-system" user bootstrap-admin --data "$DATA" --owner "$OWNER" \
--name "E2E 审计员" --out-file "$OUT/$OWNER.bootstrap.key" >/dev/null \
|| die "base bootstrap-admin failed"
K=$(cat "$OUT/$OWNER.bootstrap.key")
curl -sf -c "$JAR" -X POST "$API_BASE/api/auth/login-key/redeem" \
-H 'Content-Type: application/json' -d "{\"key\":\"$K\"}" >/dev/null || die "login-key redeem failed"
# 激活会话仅能设密:设为 PASSWORD2(后续登录与规格消费一致)。
curl -sf -b "$JAR" -c "$JAR" -X POST "$API_BASE/api/auth/password" \
-H 'Content-Type: application/json' -d "{\"next\":\"$PASSWORD2\"}" >/dev/null || die "password setup failed"
PASSWORD=$PASSWORD2
login
finish_password_gate
log "seed: create projects"
PID_MAIN=$(cmd rdm.project.create "{\"name\":\"$PROJ_MAIN\"}" | python3 -c 'import json,sys; print(json.load(sys.stdin)["projectId"])')
PID_ISO=$(cmd rdm.project.create "{\"name\":\"$PROJ_ISO\"}" | python3 -c 'import json,sys; print(json.load(sys.stdin)["projectId"])')