pin reactive resume image digest

This commit is contained in:
2026-05-20 01:41:38 +08:00
parent 5c5d21bf43
commit 03c56a20db
12 changed files with 51 additions and 28 deletions

View File

@@ -9,7 +9,8 @@ QNAP_PATCH_DIR="$ROOT_DIR/packages/reactive-resume-personal-qnap-nas/patches"
DIRECT_PATCH_DIR="$ROOT_DIR/packages/reactive-resume-personal-direct/patches"
QNAP_ZIP="$ROOT_DIR/dist/reactive-resume-personal-qnap-nas-20260520.zip"
DIRECT_ZIP="$ROOT_DIR/dist/reactive-resume-personal-direct-20260520.zip"
IMAGE="amruthpillai/reactive-resume:latest"
IMAGE_REPO="amruthpillai/reactive-resume"
IMAGE_INDEX="$IMAGE_REPO@sha256:b760446c4301af067e7d595537a877e378363aa6ce921b7349e62983621826aa"
PROJECT="reactive-resume-personal"
log() {
@@ -64,6 +65,12 @@ unzip -l "$DIRECT_ZIP" | grep -q 'reactive-resume-personal-direct/patches/reacti
if unzip -p "$QNAP_ZIP" 'reactive_resume/*' 2>/dev/null | grep -E 'isiseg|10004|Reactive_Resume_Personal|/share/Container/Reactive_Resume_Personal' >/dev/null; then
fail "QNAP zip 中仍有旧域名、旧端口或旧路径"
fi
if unzip -p "$QNAP_ZIP" 'reactive_resume/*' 2>/dev/null | grep -E 'amruthpillai/reactive-resume:latest|snowdreamtech/frpc:latest' >/dev/null; then
fail "QNAP zip 中仍有 latest 镜像"
fi
if unzip -p "$DIRECT_ZIP" 'reactive-resume-personal-direct/*' 2>/dev/null | grep -E 'amruthpillai/reactive-resume:latest|snowdreamtech/frpc:latest' >/dev/null; then
fail "direct zip 中仍有 latest 镜像"
fi
log "真实启动 direct 包并检查健康状态"
cleanup_direct
@@ -102,7 +109,7 @@ fi
log "离线检查 arm64/QNAP 镜像布局"
ARM64_DIGEST="$(
docker manifest inspect "$IMAGE" \
docker manifest inspect "$IMAGE_INDEX" \
| node -e '
let source = "";
process.stdin.on("data", (chunk) => source += chunk);
@@ -116,15 +123,31 @@ process.stdin.on("end", () => {
)"
TMP_DIR="$(mktemp -d)"
CID="$(docker create --platform linux/arm64 "$IMAGE@$ARM64_DIGEST" 2>/dev/null || true)"
CID="$(docker create --platform linux/arm64 "$IMAGE_INDEX" 2>/dev/null || true)"
[ -n "$CID" ] || fail "无法创建 arm64 镜像容器用于离线检查"
docker export "$CID" -o "$TMP_DIR/arm64-root.tar"
docker rm "$CID" >/dev/null
mkdir -p "$TMP_DIR/arm64-root"
tar -xf "$TMP_DIR/arm64-root.tar" -C "$TMP_DIR/arm64-root"
[ -f "$TMP_DIR/arm64-root/app/apps/server/dist/index.mjs" ] || fail "arm64 镜像中未找到 /app/apps/server/dist/index.mjs"
[ -d "$TMP_DIR/arm64-root/app/apps/web/dist/assets" ] || fail "arm64 镜像中未找到 /app/apps/web/dist/assets"
if [ -f "$TMP_DIR/arm64-root/app/apps/server/dist/index.mjs" ]; then
ARM64_SERVER_ENTRY="$TMP_DIR/arm64-root/app/apps/server/dist/index.mjs"
ARM64_FILENAME_ENTRY="$ARM64_SERVER_ENTRY"
ARM64_ASSETS_DIR="$TMP_DIR/arm64-root/app/apps/web/dist/assets"
EXPECTED_ENTRYPOINT_PWD="$TMP_DIR/arm64-root/app"
EXPECTED_ENTRYPOINT_ARGS="node apps/server/dist/index.mjs"
elif [ -f "$TMP_DIR/arm64-root/app/apps/web/.output/server/index.mjs" ]; then
ARM64_SERVER_ENTRY="$TMP_DIR/arm64-root/app/apps/web/.output/server/index.mjs"
ARM64_FILENAME_ENTRY="$(grep -Rsl 'function generateFilename' "$TMP_DIR/arm64-root/app/apps/web/.output/server/_ssr" 2>/dev/null | head -n 1 || true)"
[ -n "$ARM64_FILENAME_ENTRY" ] || fail "arm64 .output 布局中未找到 generateFilename SSR bundle"
ARM64_ASSETS_DIR="$TMP_DIR/arm64-root/app/apps/web/.output/public/assets"
EXPECTED_ENTRYPOINT_PWD="$TMP_DIR/arm64-root/app/apps/web"
EXPECTED_ENTRYPOINT_ARGS="node .output/server/index.mjs"
else
find "$TMP_DIR/arm64-root/app" -maxdepth 6 \( -name index.mjs -o -name server.js -o -name main.js \) 2>/dev/null >&2 || true
fail "arm64 镜像中未找到支持的服务入口"
fi
[ -d "$ARM64_ASSETS_DIR" ] || fail "arm64 镜像中未找到 assets 目录:$ARM64_ASSETS_DIR"
perl -0pe "
s#/app/apps#$TMP_DIR/arm64-root/app/apps#g;
@@ -138,13 +161,13 @@ sh "$TMP_DIR/runtime-patch-arm64-test.sh" >/tmp/reactive-resume-arm64-runtime.lo
fail "arm64 离线运行 runtime patch 失败"
}
grep -R 'rr-browser-buffer-polyfill' "$TMP_DIR/arm64-root/app/apps/web/dist/assets" >/dev/null \
grep -R 'rr-browser-buffer-polyfill' "$ARM64_ASSETS_DIR" >/dev/null \
|| fail "arm64 public PDF bundle 未注入 Buffer polyfill"
grep -R -F 'replace(/[\\/:*?"<>|]/g' "$TMP_DIR/arm64-root/app/apps/web/dist/assets" >/dev/null \
grep -R -F 'replace(/[\\/:*?"<>|]/g' "$ARM64_ASSETS_DIR" >/dev/null \
|| fail "arm64 文件名 bundle 未改为按标题下载"
grep -q 'function generateFilename(prefix, extension)' "$TMP_DIR/arm64-root/app/apps/server/dist/index.mjs" \
grep -q 'function generateFilename(prefix, extension)' "$ARM64_FILENAME_ENTRY" \
|| fail "arm64 server entry 未包含 generateFilename"
grep -F 'filename.replace(/[\\/:*?"<>|]/g' "$TMP_DIR/arm64-root/app/apps/server/dist/index.mjs" >/dev/null \
grep -F 'filename.replace(/[\\/:*?"<>|]/g' "$ARM64_FILENAME_ENTRY" >/dev/null \
|| fail "arm64 server entry 未改为按标题生成下载文件名"
perl -0pe "
@@ -165,10 +188,10 @@ PATH="$TMP_DIR/fakebin:$PATH" sh "$TMP_DIR/entrypoint-arm64-test.sh" >/tmp/react
fail "arm64 entrypoint 选择测试失败"
}
grep -q "PWD=$TMP_DIR/arm64-root/app" "$TMP_DIR/entrypoint-result.txt" \
|| fail "arm64 entrypoint 未切换到 /app"
grep -q "ARGS=node apps/server/dist/index.mjs" "$TMP_DIR/entrypoint-result.txt" \
|| fail "arm64 entrypoint 未选择 apps/server/dist/index.mjs"
grep -q "PWD=$EXPECTED_ENTRYPOINT_PWD" "$TMP_DIR/entrypoint-result.txt" \
|| fail "arm64 entrypoint 未切换到预期目录:$EXPECTED_ENTRYPOINT_PWD"
grep -q "ARGS=$EXPECTED_ENTRYPOINT_ARGS" "$TMP_DIR/entrypoint-result.txt" \
|| fail "arm64 entrypoint 未选择预期入口:$EXPECTED_ENTRYPOINT_ARGS"
log "清理 direct 测试容器"
cleanup_direct