From 84b51a039890efad78c12f1abdd8871c1d593b4f Mon Sep 17 00:00:00 2001 From: let5sne Date: Tue, 14 Jul 2026 07:07:20 +0800 Subject: [PATCH] chore(release): add read-only preflight manifest --- docs/BRD_IMPLEMENTATION_AUDIT.md | 1 + docs/DEV_SETUP.md | 9 +++++ scripts/release-preflight.sh | 68 ++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100755 scripts/release-preflight.sh diff --git a/docs/BRD_IMPLEMENTATION_AUDIT.md b/docs/BRD_IMPLEMENTATION_AUDIT.md index ec614e32..39a069cf 100644 --- a/docs/BRD_IMPLEMENTATION_AUDIT.md +++ b/docs/BRD_IMPLEMENTATION_AUDIT.md @@ -104,3 +104,4 @@ - 2026-07-14 移动端短信登录租户修复:手机号查询补充 `tenant_id` 条件,避免同一手机号在不同租户登录时复用其他租户的 `sys_user`;新增认证策略边界回归测试。正式多租户登录仍需用测试租户账号做 HTTP 回归。 - 2026-07-14 测试租户 HTTP 回归:在本地临时建立 `codex-a`/`codex-b` 两个租户,用同一手机号分别登录并授予各自 `superadmin` 测试角色;两租户分别调用异步上传和目录导入接口。A 查询不到 B 的上传批次/导入任务,B 也查询不到 A;两个目录导入任务均完成 `1/1`。后台 worker 的队列加工、目录导入、任务进度和查询均保持租户隔离。测试产生的租户、用户、角色、知识库行和临时文件已清理为 0。该证据只覆盖本地测试环境,不替代正式组织同步和生产多租户验收。 - 2026-07-14 上传队列上下文收口:`AihrUploadQueueService` 的同步请求租户读取改为 `TenantHelper.getTenantId()`,动态租户上下文优先于登录态,避免重试/嵌套任务回退到错误租户;`AihrUploadQueueServiceTest` 已补对应源码契约断言。AIHR 定向测试与模块编译通过。 +- 2026-07-14 发布前检查补齐:新增只读 `scripts/release-preflight.sh`,统一核验当前 commit、管理端/H5/后端产物存在性、入口 JS 和 SHA-256;传入 `RELEASE_REMOTE_URL` 时只做公开根站点与租户列表 HTTP 检查,不执行 SSH、rsync、服务重启或生产写入。`docs/DEV_SETUP.md` 已同步发布证据与回滚留痕要求。 diff --git a/docs/DEV_SETUP.md b/docs/DEV_SETUP.md index aa0b3a8e..2e85fae9 100644 --- a/docs/DEV_SETUP.md +++ b/docs/DEV_SETUP.md @@ -158,6 +158,15 @@ rsync -az --delete mobile-uni/dist/build/h5/ YCWY:/opt/wygj/www/h5/ curl -k -s https://peilian.njzhmj.top/h5/ | sed -n '1,20p' ``` +发布前先运行只读产物检查,记录 commit、管理端/H5/后端 hash;它不会连接 SSH、同步文件或重启服务: + +```bash +./scripts/release-preflight.sh +RELEASE_REMOTE_URL=https://peilian.njzhmj.top ./scripts/release-preflight.sh +``` + +发布时必须保留 preflight 输出、远端备份目录和发布后浏览器回归结果;回滚优先使用对应备份目录恢复,再重启后端服务,不能直接覆盖当前线上目录而不留证据。 + ## MVP 页面验证 登录后侧栏应只展示以下入口: diff --git a/scripts/release-preflight.sh b/scripts/release-preflight.sh new file mode 100755 index 00000000..4b4a5424 --- /dev/null +++ b/scripts/release-preflight.sh @@ -0,0 +1,68 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$ROOT_DIR" + +fail() { + echo "release-preflight: $*" >&2 + exit 1 +} + +require_file() { + [[ -f "$1" ]] || fail "missing artifact: $1; build it before release" +} + +sha256() { + if command -v shasum >/dev/null 2>&1; then + shasum -a 256 "$1" | awk '{print $1}' + else + sha256sum "$1" | awk '{print $1}' + fi +} + +frontend_index="frontend/dist/index.html" +mobile_index="mobile-uni/dist/build/h5/index.html" +backend_jar="backend/ruoyi-admin/target/ruoyi-admin.jar" +require_file "$frontend_index" +require_file "$mobile_index" +require_file "$backend_jar" + +frontend_asset="$(sed -nE 's/.*src="([^"]+\.js)".*/\1/p' "$frontend_index" | head -1)" +mobile_asset="$(sed -nE 's/.*src="([^"]+\.js)".*/\1/p' "$mobile_index" | head -1)" +[[ -n "$frontend_asset" ]] || fail "frontend index does not reference a JavaScript entry" +[[ -n "$mobile_asset" ]] || fail "mobile H5 index does not reference a JavaScript entry" + +frontend_asset_path="frontend/dist/${frontend_asset#/}" +mobile_asset_rel="${mobile_asset#/}" +mobile_asset_rel="${mobile_asset_rel#h5/}" +mobile_asset_path="mobile-uni/dist/build/h5/$mobile_asset_rel" +require_file "$frontend_asset_path" +require_file "$mobile_asset_path" +grep -q '/h5/' "$mobile_index" || fail "mobile H5 index does not contain the /h5/ base path" + +changed_files="$(git status --porcelain)" +[[ -z "$changed_files" ]] || fail "worktree has uncommitted changes; commit the release batch before publishing" + +echo "commit=$(git rev-parse HEAD)" +echo "worktree=clean" +echo "frontend_index_sha256=$(sha256 "$frontend_index")" +echo "frontend_asset=$frontend_asset" +echo "frontend_asset_sha256=$(sha256 "$frontend_asset_path")" +echo "mobile_index_sha256=$(sha256 "$mobile_index")" +echo "mobile_asset=$mobile_asset" +echo "mobile_asset_sha256=$(sha256 "$mobile_asset_path")" +echo "backend_jar_sha256=$(sha256 "$backend_jar")" + +if [[ -n "${RELEASE_REMOTE_URL:-}" ]]; then + remote="${RELEASE_REMOTE_URL%/}" + curl -fsS --max-time 15 "$remote/" >/dev/null || fail "remote root check failed: $remote/" + echo "remote_root=200 $remote/" + if curl -fsS --max-time 15 "$remote/prod-api/auth/tenant/list" >/dev/null; then + echo "remote_tenant_list=200 $remote/prod-api/auth/tenant/list" + else + fail "remote tenant list check failed: $remote/prod-api/auth/tenant/list" + fi +fi + +echo "release-preflight: read-only checks passed"