# Nexus 发布前清单(2026-07-08) ## 结论 当前本地快照已经通过完整发布前 Gate: ```text py_compile + /app-v2 build:safe + app-v2 sensitive scan + 宝塔 pytest ``` 最终结果: ```text [release-gate] OK 60 passed in 5.33s ``` ## 当前源码快照 ```text C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042 ``` 对比基准快照: ```text C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-070236 ``` 完整差异清单: ```text C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\Nexus-release-diff-manifest-20260708.md ``` ## 差异清单汇总 重新生成后的清单已经排除: - `.git` - `node_modules` - `.venv-*` - `venv` - `__pycache__` - `.ruff_cache` - `.playwright-mcp` - `.cursor` - `.pytest_cache` - `*.pyc` - `*.pyo` - `*.bak-` - `2025.2` - `=2025.2` - `tmp/nexus-frontend.tar.gz` 当前差异统计: ```text added=381 modified=26 deleted=347 ``` 注意:差异里包含大量旧 `/app/` 静态构建产物变动。如果只发布本轮宝塔稳定性与 `/app-v2`,可以优先发布“核心发布集合”,不要盲目同步整个快照目录。 ## 核心发布集合 ### 后端宝塔一键登录稳定性 ```text server/application/services/btpanel_service.py server/infrastructure/btpanel/bootstrap_lock.py server/infrastructure/btpanel/login_url_lock.py server/infrastructure/btpanel/ssh_bootstrap.py server/main.py ``` ### API / 服务相关历史改动 差异清单中还有以下后端文件发生变化,发布前需要按实际范围确认是否一起发布: ```text server/api/assets.py server/api/scripts.py server/api/sync_v2.py server/application/services/server_file_transfer_service.py server/infrastructure/ssh/remote_archive.py server/utils/files_chmod_policy.py ``` 这些文件属于此前安全巡检/文件传输/脚本执行相关改动,不是本轮宝塔一键登录最小集合;如果线上已经发布过,可跳过或只按 diff 覆盖。 ### `/app-v2` 双后台 源码: ```text frontend-v2/ ``` 构建产物: ```text web/app-v2/ ``` 后端静态挂载: ```text server/main.py ``` Docker: ```text Dockerfile Dockerfile.prod ``` ### 测试与发布脚本 ```text requirements-dev.txt scripts/check_backend_test_env.py scripts/generate_release_diff.py scripts/run_btpanel_tests.py scripts/run_btpanel_tests_docker.cmd scripts/run_btpanel_tests_docker.sh scripts/run_local_release_gate.py scripts/scan_release_manifest.py ``` ### 测试文件 ```text tests/test_btpanel_bootstrap_lock.py tests/test_btpanel_get_config.py tests/test_btpanel_login_url.py tests/test_btpanel_login_url_route.py tests/test_btpanel_ssh_bootstrap.py ``` ## 发布前验证命令 ### 1. 重新生成差异清单 ```cmd .venv-py312-codex\Scripts\python.exe scripts\generate_release_diff.py --old C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-070236 --new C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042 --output C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\Nexus-release-diff-manifest-20260708.md ``` 结果: ```text added=369 modified=21 deleted=347 ``` ### 2. 扫描发布候选文件是否包含已知环境泄露标记 ```cmd .venv-py312-codex\Scripts\python.exe scripts\scan_release_manifest.py --root C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042 --manifest C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\Nexus-release-diff-manifest-20260708.md ``` 结果: ```text OK: no known environment leak markers found in release manifest entries ``` ### 3. 完整发布前 Gate ```cmd .venv-py312-codex\Scripts\python.exe scripts\run_local_release_gate.py --with-pytest ``` 结果: ```text [app-v2-sensitive-scan] OK: scanned 9 file(s), no high-confidence secrets found collected 60 items 60 passed in 1.79s [release-gate] OK ``` 最新 Gate 追加确认: ```text bash -n deploy/sync_webapp_to_container.sh 60 passed in 1.70s [release-gate] OK ``` ### 4. 生成干净发布包 ```cmd .venv-py312-codex\Scripts\python.exe scripts\generate_release_bundle.py --root C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-112042 --output C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\nexus-release-20260708.tar.gz ``` 结果: ```text files=2409 ``` 发布包位置: ```text C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\nexus-release-20260708.tar.gz ``` 发布包元数据: ```text C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\nexus-release-20260708.metadata.json C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\Nexus-release-artifact-metadata-20260708.md ``` SHA256: ```text 46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b ``` ### 5. 扫描发布包 ```cmd .venv-py312-codex\Scripts\python.exe scripts\scan_release_bundle.py C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\nexus-release-20260708.tar.gz ``` 结果: ```text size_mb=27.02 entries=2409 OK: release bundle looks clean ``` ### 6. 部署排除规则自检 `scripts/run_local_release_gate.py` 现在会自动执行: ```cmd .venv-py312-codex\Scripts\python.exe scripts\check_deploy_excludes.py ``` 结果: ```text OK: deploy exclusion patterns are present ``` ### 7. 发布后线上验证脚本 新增: ```text scripts/verify_online_release.py ``` 用途: - 检查 `/health` - 检查旧后台 `/app/` - 检查新后台 `/app-v2/` - 检查页面里不要出现 `全局 API Key`、`Global API Key`、`tmp_login`、`tmp_token` 发布后执行: ```cmd .venv-py312-codex\Scripts\python.exe scripts\verify_online_release.py --base-url https://api.synaglobal.vip ``` ## 明确不发布 以下内容不要同步到正式服务器: ```text .venv-py312-codex/ .venv-py314/ venv/ frontend-v2/node_modules/ .pytest_cache/ __pycache__/ .ruff_cache/ .cursor/ .playwright-mcp/ frontend-v2/node_modules/ *.pyc *.pyo *.bak- 2025.2 =2025.2 tmp/nexus-frontend.tar.gz ``` 其中 `2025.2` / `=2025.2` 是 Windows CMD 执行 `tzdata>=2025.2` 时可能产生的重定向误文件,绝对不要发布。 ## 建议发布顺序 ### 方案 A:Docker 镜像重建发布(推荐) 1. 使用当前快照作为构建上下文,但确保 `.dockerignore` 排除虚拟环境、node_modules、缓存和临时文件。 2. 构建生产镜像。 3. 启动新容器前备份旧容器镜像/tag 和数据库。 4. 发布后执行线上验证。 优点:静态资源、后端代码、依赖环境一致性更好。 当前已修复: - `.dockerignore` 已排除 `frontend-v2/node_modules`、`.venv-*`、`.pytest_cache`、`2025.2`、`*.bak-` 等。 - `deploy/rsync-local-to-server.sh` 已排除 `frontend-v2/node_modules`、`.venv-*`、`.pytest_cache`、`2025.2`、`*.bak-` 等。 - `scripts/run_local_release_gate.py` 已增加 `bash -n` 检查 `deploy/deploy-production.sh` 与 `deploy/rsync-local-to-server.sh`。 - `deploy/deploy-production.sh` 发布后健康检查已增加 `/app-v2/`。 - `deploy/deploy-production.sh` 已显式构建并上传 `web/app-v2`,不只依赖 Dockerfile 构建。 - `deploy/apply-release-bundle.sh` 已新增,可在服务器侧对 tar.gz 发布包执行 SHA256 校验、备份、解包、重建和本机验证。 - `deploy/sync_webapp_to_container.sh` 已同步 `web/app-v2` 到容器,并校验 `/app-v2/` 主 bundle。 - `scripts/run_local_release_gate.py` 已增加 `bash -n deploy/sync_webapp_to_container.sh`。 - `scripts/check_deploy_excludes.py` 会防止发布排除规则未来被误删。 ### 当前远程执行状态 本轮尝试对线上 `Host nexus` 做只读 SSH 探测时,Codex 审批系统返回 404 并拒绝执行。不是 SSH 凭据或代码错误,而是自动审批代理不可用。 因此本轮没有实际修改线上服务器。当前状态是: ```text 本地发布包:已生成 发布包扫描:通过 完整 release gate:通过 线上部署:尚未执行 ``` 如果要由 Codex 继续实际发布,需要在下一步明确允许 SSH 发布操作。 ## 手动发布命令清单 已生成: ```text C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\Nexus-manual-deploy-commands-20260708.md ``` 该文档包含: - `deploy/deploy-production.sh` 一键发布方式。 - tar.gz 发布包上传方式。 - 线上 SHA256 校验。 - 线上备份、解包、Docker 重建。 - 发布后 `/health`、`/app/`、`/app-v2/` 验证。 - 宝塔专项验证。 - 回滚命令。 ## 最新最终验证 发布包扫描: ```text size_mb=27.02 entries=2409 OK: release bundle looks clean ``` 完整 Gate: ```text 60 passed in 1.70s [release-gate] OK ``` ### 方案 B:只同步核心文件到现有线上目录 适合快速热修: 1. 同步后端核心文件。 2. 同步 `web/app-v2/`。 3. 重启后端服务。 4. 验证宝塔一键登录和 `/app-v2/`。 缺点:如果线上依赖、静态目录或 Dockerfile 状态与本地不一致,容易遗漏。 ## 线上验证清单 发布到: ```text https://api.synaglobal.vip ``` 后验证: 1. `/app/` 旧后台仍可访问。 2. `/app-v2/` 新后台可访问。 3. `/api/btpanel/servers/{id}/login-url` 正常返回登录地址。 4. 同一台宝塔短时间重复点一键登录,应该只允许一个签发流程,冲突时返回 HTTP 409。 5. 新增宝塔或配置缺失宝塔,在一键登录前会触发 session cleanup TTL 兜底检测/修复。 6. 多台宝塔同时打开,2 小时后刷新不应因为 `task.py hardcoded_3600` 陆续掉线。 7. 线上页面不显示全局 API Key 明文。 ## 回滚点 发布前建议备份: ```text server/application/services/btpanel_service.py server/infrastructure/btpanel/bootstrap_lock.py server/infrastructure/btpanel/login_url_lock.py server/infrastructure/btpanel/ssh_bootstrap.py server/main.py web/app-v2/ Dockerfile Dockerfile.prod ``` 如果发布后宝塔一键登录异常: 1. 先回滚上述后端文件。 2. 重启后端服务。 3. 保留 `/app-v2/` 不影响旧 `/app/`,必要时可以只移除 `web/app-v2/` 静态目录或取消 `server/main.py` 挂载。 ## 2026-07-08 validate-only verification The server-side release applier now supports validate-only mode. Command verified locally with Git Bash: ```bash bash deploy/apply-release-bundle.sh --validate-only --tarball /c/Users/uzuma/Documents/Codex/2026-07-06/yuu/outputs/nexus-release-20260708.tar.gz --sha256 46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b ` Result: ` ext SHA256 OK: 46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b Extracted release tree validation OK Validate-only mode: tarball checksum and content validation passed ` Network/SSH production execution is still not performed because Codex approval auto-review returned HTTP 404 for read-only checks. ## 2026-07-08 one-command local artifact preparation A single local command now prepares and verifies the release artifact end-to-end: `cmd .venv-py312-codex\Scripts\python.exe scripts\prepare_release_artifact.py --old-snapshot C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\work\nexus_code_context\snapshots\nexus-source-20260707-070236 --output-dir C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs --name nexus-release-20260708 ` Verified result: ` ext [prepare-release-artifact] OK added=381 modified=26 deleted=347 files=2409 entries=2409 size_mb=27.02 sha256=46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b 60 passed in 1.70s ` ## 2026-07-08 release index and checksum file Release index: ` ext C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\Nexus-release-index-20260708.md ` Standard SHA256 checksum file: ` ext C:\Users\uzuma\Documents\Codex\2026-07-06\yuu\outputs\nexus-release-20260708.tar.gz.sha256 ` The checksum file contains: ` ext 46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b nexus-release-20260708.tar.gz ` ## Server preflight command Before applying the release on the production host, run: ```bash bash /tmp/nexus-release/deploy/preflight-release-host.sh \ --tarball /tmp/nexus-release-20260708.tar.gz \ --sha256 46299832fb78e8cc196f85cf1928f34eea4deee82dbc83b67883394f0359036b \ --deploy-path /opt/nexus ``` This checks required commands, checksum, release tar paths, deploy path, runtime hints, disk space, and current local endpoints before applying changes.