新增生产一键部署脚本实施计划
This commit is contained in:
@@ -0,0 +1,385 @@
|
||||
# Production One-Click Deploy Backend Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED: Use superpowers:executing-plans to implement this plan in this repository. Do not use subagents. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 新增一份生产一键部署脚本,在脚本同目录完成发布包校验、旧版后端备份、后端进程停止、新版 `jar` 替换、后端重启和部署结果验证。
|
||||
|
||||
**Architecture:** 以现有 [bin/prod/deploy_release.sh](/Users/wkc/Desktop/loan-pricing/loan-pricing/bin/prod/deploy_release.sh) 和 [bin/prod/restart_java.sh](/Users/wkc/Desktop/loan-pricing/loan-pricing/bin/prod/restart_java.sh) 为参考,但将解包、备份、PID 管理、进程识别、端口等待全部内联到新的单脚本 [bin/prod/deploy_from_package.sh](/Users/wkc/Desktop/loan-pricing/loan-pricing/bin/prod/deploy_from_package.sh)。实现只覆盖单实例发布链路,不接入 Nginx、不拆独立启停脚本、不引入额外配置文件。
|
||||
|
||||
**Tech Stack:** POSIX shell、`unzip`、`find`、`pgrep`、`nohup`、`ss`、`sh -n`
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 锁定脚本接口与参考实现边界
|
||||
|
||||
**Files:**
|
||||
- Inspect: `docs/superpowers/specs/2026-04-01-production-one-click-deploy-design.md`
|
||||
- Inspect: `bin/prod/deploy_release.sh`
|
||||
- Inspect: `bin/prod/restart_java.sh`
|
||||
|
||||
- [ ] **Step 1: 核对设计文档中的后端职责边界**
|
||||
|
||||
Run: `rg -n "单脚本|JAVA_BIN|backend/backend.pid|63310|loan.pricing.home|TERM|KILL" docs/superpowers/specs/2026-04-01-production-one-click-deploy-design.md`
|
||||
Expected: 能定位单脚本、自定义 `JAVA_BIN`、PID 文件、进程标记和端口等待等核心约束。
|
||||
|
||||
- [ ] **Step 2: 抽取现有生产脚本中可复用的后端逻辑**
|
||||
|
||||
Run: `rg -n "assert_single_jar|extract_release_package|cleanup|BACKEND_JAR|collect_backend_pids|stop_backend|start_backend|BACKEND_MARKER|BACKEND_PORT" bin/prod/deploy_release.sh bin/prod/restart_java.sh`
|
||||
Expected: 能定位现有发布包解压校验、PID 管理和端口等待逻辑,作为新脚本参考来源。
|
||||
|
||||
- [ ] **Step 3: 确认新脚本目标文件尚不存在**
|
||||
|
||||
Run: `test ! -f bin/prod/deploy_from_package.sh && echo "missing"`
|
||||
Expected: 输出 `missing`,说明可以新增独立脚本而不覆盖现有 `/home/webapp` 发布脚本。
|
||||
|
||||
- [ ] **Step 4: 提交本任务**
|
||||
|
||||
```bash
|
||||
git add docs/superpowers/plans/2026-04-01-production-one-click-deploy-backend-plan.md
|
||||
git commit -m "新增生产一键部署后端计划"
|
||||
```
|
||||
|
||||
### Task 2: 创建单脚本基础骨架与公共函数
|
||||
|
||||
**Files:**
|
||||
- Create: `bin/prod/deploy_from_package.sh`
|
||||
|
||||
- [ ] **Step 1: 写入脚本头部配置和使用说明**
|
||||
|
||||
在 [bin/prod/deploy_from_package.sh](/Users/wkc/Desktop/loan-pricing/loan-pricing/bin/prod/deploy_from_package.sh) 顶部写入最小骨架:
|
||||
|
||||
```sh
|
||||
#!/bin/sh
|
||||
|
||||
set -eu
|
||||
|
||||
JAVA_BIN="/home/webapp/env/java/bin/java"
|
||||
BACKEND_PORT=63310
|
||||
SPRING_PROFILE="pro"
|
||||
JAVA_OPTS="-Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError"
|
||||
```
|
||||
|
||||
并补齐以下说明函数:
|
||||
|
||||
```sh
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
用法:
|
||||
./bin/prod/deploy_from_package.sh
|
||||
EOF
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 实现脚本目录定位和路径常量**
|
||||
|
||||
至少补齐以下路径变量:
|
||||
|
||||
```sh
|
||||
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
||||
BACKEND_DIR="$SCRIPT_DIR/backend"
|
||||
FRONTEND_DIR="$SCRIPT_DIR/frontend"
|
||||
BACKEND_JAR_TARGET="$BACKEND_DIR/ruoyi-admin.jar"
|
||||
BACKEND_PID_FILE="$BACKEND_DIR/backend.pid"
|
||||
BACKEND_LOG_FILE="$BACKEND_DIR/backend-console.log"
|
||||
FRONTEND_DIST_ARCHIVE="$FRONTEND_DIR/dist.zip"
|
||||
FRONTEND_DIST_DIR="$FRONTEND_DIR/dist"
|
||||
BACKEND_MARKER="-Dloan.pricing.home=$SCRIPT_DIR"
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 实现日志、时间戳和清理函数**
|
||||
|
||||
至少补齐:
|
||||
|
||||
```sh
|
||||
timestamp() {
|
||||
date "+%Y%m%d%H%M%S"
|
||||
}
|
||||
|
||||
log_info() {
|
||||
printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$1"
|
||||
}
|
||||
|
||||
log_error() {
|
||||
printf '[%s] %s\n' "$(date '+%Y-%m-%d %H:%M:%S')" "$1" >&2
|
||||
}
|
||||
```
|
||||
|
||||
以及:
|
||||
|
||||
```sh
|
||||
cleanup() {
|
||||
if [ -n "${WORK_DIR:-}" ] && [ -d "$WORK_DIR" ]; then
|
||||
rm -rf "$WORK_DIR"
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 做语法校验**
|
||||
|
||||
Run: `sh -n bin/prod/deploy_from_package.sh`
|
||||
Expected: 无输出,返回码为 0。
|
||||
|
||||
- [ ] **Step 5: 提交本任务**
|
||||
|
||||
```bash
|
||||
git add bin/prod/deploy_from_package.sh
|
||||
git commit -m "新增生产一键部署脚本骨架"
|
||||
```
|
||||
|
||||
### Task 3: 实现发布包发现、解压和后端备份
|
||||
|
||||
**Files:**
|
||||
- Modify: `bin/prod/deploy_from_package.sh`
|
||||
|
||||
- [ ] **Step 1: 实现目录与命令前置校验**
|
||||
|
||||
补齐以下校验:
|
||||
|
||||
```sh
|
||||
require_dir() {
|
||||
if [ ! -d "$1" ]; then
|
||||
log_error "缺少目录: $1"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
require_command() {
|
||||
if ! command -v "$1" >/dev/null 2>&1; then
|
||||
log_error "缺少命令: $1"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
在主流程中校验:
|
||||
|
||||
```sh
|
||||
require_dir "$BACKEND_DIR"
|
||||
require_dir "$FRONTEND_DIR"
|
||||
require_command unzip
|
||||
require_command find
|
||||
require_command pgrep
|
||||
require_command ss
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 实现同目录唯一发布 zip 查找**
|
||||
|
||||
新增函数:
|
||||
|
||||
```sh
|
||||
find_release_archive() {
|
||||
archives=$(find "$SCRIPT_DIR" -maxdepth 1 -type f -name '*.zip' ! -name 'dist.zip')
|
||||
count=$(printf '%s\n' "$archives" | sed '/^$/d' | wc -l | tr -d ' ')
|
||||
if [ "$count" -ne 1 ]; then
|
||||
log_error "脚本同目录发布 zip 数量不正确,期望 1 个,实际 $count 个"
|
||||
exit 1
|
||||
fi
|
||||
printf '%s\n' "$archives"
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 实现解压与唯一 `jar` 校验**
|
||||
|
||||
补齐:
|
||||
|
||||
```sh
|
||||
extract_release_package() {
|
||||
release_archive="$1"
|
||||
release_extract_dir="$2"
|
||||
mkdir -p "$release_extract_dir"
|
||||
unzip -oq "$release_archive" -d "$release_extract_dir"
|
||||
}
|
||||
|
||||
assert_single_jar() {
|
||||
search_dir="$1"
|
||||
count=$(find "$search_dir" -type f -name '*.jar' | wc -l | tr -d ' ')
|
||||
if [ "$count" -ne 1 ]; then
|
||||
log_error "后端 jar 数量不正确,期望 1 个,实际 $count 个"
|
||||
exit 1
|
||||
fi
|
||||
find "$search_dir" -type f -name '*.jar' | head -n 1
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 实现旧版后端备份和新 `jar` 替换**
|
||||
|
||||
补齐:
|
||||
|
||||
```sh
|
||||
backup_backend_jar() {
|
||||
if [ -f "$BACKEND_JAR_TARGET" ]; then
|
||||
mv "$BACKEND_JAR_TARGET" "$BACKEND_JAR_TARGET.$(timestamp).bak"
|
||||
fi
|
||||
}
|
||||
|
||||
deploy_backend_jar() {
|
||||
source_jar="$1"
|
||||
mv "$source_jar" "$BACKEND_JAR_TARGET"
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 5: 用临时目录构造后端备份场景做静态验证**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
tmpdir=$(mktemp -d)
|
||||
mkdir -p "$tmpdir/backend" "$tmpdir/frontend/package"
|
||||
touch "$tmpdir/backend/ruoyi-admin.jar"
|
||||
touch "$tmpdir/frontend/dist.zip"
|
||||
touch "$tmpdir/package/app.jar"
|
||||
(cd "$tmpdir/package" && zip -q release.zip app.jar >/dev/null)
|
||||
test -f "$tmpdir/backend/ruoyi-admin.jar"
|
||||
rm -rf "$tmpdir"
|
||||
```
|
||||
|
||||
Expected: 命令执行成功,用于确认计划中的文件命名和目录约定可被临时目录复现。
|
||||
|
||||
- [ ] **Step 6: 做语法校验**
|
||||
|
||||
Run: `sh -n bin/prod/deploy_from_package.sh`
|
||||
Expected: 无输出,返回码为 0。
|
||||
|
||||
- [ ] **Step 7: 提交本任务**
|
||||
|
||||
```bash
|
||||
git add bin/prod/deploy_from_package.sh
|
||||
git commit -m "实现生产部署脚本后端发布包处理"
|
||||
```
|
||||
|
||||
### Task 4: 实现后端进程停止、启动与端口等待
|
||||
|
||||
**Files:**
|
||||
- Modify: `bin/prod/deploy_from_package.sh`
|
||||
|
||||
- [ ] **Step 1: 实现托管进程识别函数**
|
||||
|
||||
补齐以下函数:
|
||||
|
||||
```sh
|
||||
is_managed_backend_pid() {
|
||||
pid="$1"
|
||||
if [ -z "${pid:-}" ] || ! kill -0 "$pid" 2>/dev/null; then
|
||||
return 1
|
||||
fi
|
||||
args=$(ps -o args= -p "$pid" 2>/dev/null || true)
|
||||
case "$args" in
|
||||
*"$BACKEND_MARKER"*"$BACKEND_JAR_TARGET"*|*"$BACKEND_JAR_TARGET"*"$BACKEND_MARKER"*)
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 实现 PID 收集与停止流程**
|
||||
|
||||
补齐:
|
||||
|
||||
```sh
|
||||
collect_backend_pids() {
|
||||
pids=""
|
||||
if [ -f "$BACKEND_PID_FILE" ]; then
|
||||
file_pid=$(cat "$BACKEND_PID_FILE" 2>/dev/null || true)
|
||||
if [ -n "${file_pid:-}" ] && is_managed_backend_pid "$file_pid"; then
|
||||
pids="$pids $file_pid"
|
||||
fi
|
||||
fi
|
||||
marker_pids=$(pgrep -f "$BACKEND_MARKER" 2>/dev/null || true)
|
||||
for pid in $marker_pids; do
|
||||
if is_managed_backend_pid "$pid"; then
|
||||
pids="$pids $pid"
|
||||
fi
|
||||
done
|
||||
printf '%s\n' "$(echo "$pids" | xargs 2>/dev/null || true)"
|
||||
}
|
||||
```
|
||||
|
||||
以及 `stop_backend()`,要求:
|
||||
|
||||
- 先发 `TERM`
|
||||
- 等待最多 30 秒
|
||||
- 超时后发 `KILL`
|
||||
- 最后删除 `backend.pid`
|
||||
|
||||
- [ ] **Step 3: 实现启动流程**
|
||||
|
||||
补齐 `start_backend()`,要求:
|
||||
|
||||
```sh
|
||||
nohup "$JAVA_BIN" $JAVA_OPTS "$BACKEND_MARKER" -jar "$BACKEND_JAR_TARGET" \
|
||||
--spring.profiles.active="$SPRING_PROFILE" \
|
||||
--server.port="$BACKEND_PORT" >> "$BACKEND_LOG_FILE" 2>&1 &
|
||||
```
|
||||
|
||||
并在启动后:
|
||||
|
||||
- 写入 `backend/backend.pid`
|
||||
- 轮询 `ss -lnt | grep ":63310 "` 最长 30 秒
|
||||
- 若未监听成功则报错退出
|
||||
|
||||
- [ ] **Step 4: 实现主流程调用顺序**
|
||||
|
||||
主流程必须按以下顺序调用:
|
||||
|
||||
```sh
|
||||
backup_backend_jar
|
||||
stop_backend
|
||||
deploy_backend_jar "$backend_jar_source"
|
||||
start_backend
|
||||
```
|
||||
|
||||
不得把 `stop_backend` 放到备份后面之外的位置,避免旧进程继续占用将被替换的 `jar`。
|
||||
|
||||
- [ ] **Step 5: 做语法校验**
|
||||
|
||||
Run: `sh -n bin/prod/deploy_from_package.sh`
|
||||
Expected: 无输出,返回码为 0。
|
||||
|
||||
- [ ] **Step 6: 提交本任务**
|
||||
|
||||
```bash
|
||||
git add bin/prod/deploy_from_package.sh
|
||||
git commit -m "实现生产部署脚本后端启停逻辑"
|
||||
```
|
||||
|
||||
### Task 5: 补后端实施记录并验证关键链路
|
||||
|
||||
**Files:**
|
||||
- Modify: `bin/prod/deploy_from_package.sh`
|
||||
- Create: `doc/implementation-report-2026-04-01-production-one-click-deploy-backend.md`
|
||||
|
||||
- [ ] **Step 1: 做脚本静态语法校验**
|
||||
|
||||
Run: `sh -n bin/prod/deploy_from_package.sh`
|
||||
Expected: 无输出,返回码为 0。
|
||||
|
||||
- [ ] **Step 2: 检查脚本中的关键配置与标记是否落位**
|
||||
|
||||
Run: `rg -n "JAVA_BIN=|BACKEND_PORT=63310|SPRING_PROFILE=|BACKEND_MARKER=|backend.pid|backend-console.log|pgrep -f|ss -lnt" bin/prod/deploy_from_package.sh`
|
||||
Expected: 能看到 Java 路径、端口、进程标记、PID 文件、日志文件和端口等待逻辑都已写入脚本。
|
||||
|
||||
- [ ] **Step 3: 编写后端实施记录**
|
||||
|
||||
在 [doc/implementation-report-2026-04-01-production-one-click-deploy-backend.md](/Users/wkc/Desktop/loan-pricing/loan-pricing/doc/implementation-report-2026-04-01-production-one-click-deploy-backend.md) 至少记录:
|
||||
|
||||
```markdown
|
||||
- 新增脚本 `bin/prod/deploy_from_package.sh`
|
||||
- 脚本内固定 `JAVA_BIN`
|
||||
- 后端发布包解压与唯一 jar 校验规则
|
||||
- 旧版 jar 时间戳备份规则
|
||||
- PID 文件、进程标记、端口 63310 等待逻辑
|
||||
- 执行的验证命令与结果
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 核对实施记录路径**
|
||||
|
||||
Run: `ls doc/implementation-report-2026-04-01-production-one-click-deploy-backend.md`
|
||||
Expected: 文件存在于仓库 `doc/` 目录。
|
||||
|
||||
- [ ] **Step 5: 提交本任务**
|
||||
|
||||
```bash
|
||||
git add bin/prod/deploy_from_package.sh doc/implementation-report-2026-04-01-production-one-click-deploy-backend.md
|
||||
git commit -m "完成生产一键部署后端实现"
|
||||
```
|
||||
@@ -0,0 +1,208 @@
|
||||
# Production One-Click Deploy Frontend Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED: Use superpowers:executing-plans to implement this plan in this repository. Do not use subagents. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 在不修改 `ruoyi-ui` 源码的前提下,补齐生产一键部署脚本中的前端静态包替换、旧版 `dist` 备份、`dist.zip` 解压验证和实施留痕。
|
||||
|
||||
**Architecture:** 本次前端交付不涉及 Vue 页面、接口契约或构建配置,而是通过 [bin/prod/deploy_from_package.sh](/Users/wkc/Desktop/loan-pricing/loan-pricing/bin/prod/deploy_from_package.sh) 管理发布目录中的 `frontend/dist.zip` 和 `frontend/dist/`。因此前端计划的重点是约束脚本里的静态包部署链路,验证旧 `dist` 目录时间戳备份、新 `dist.zip` 落盘和解压结果,并明确 `ruoyi-ui` 在本次任务中保持不变。
|
||||
|
||||
**Tech Stack:** shell、ZIP 静态资源包、`unzip`、`find`、`rg`
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 确认本次任务无 `ruoyi-ui` 源码改动范围
|
||||
|
||||
**Files:**
|
||||
- Inspect: `docs/superpowers/specs/2026-04-01-production-one-click-deploy-design.md`
|
||||
- Inspect: `ruoyi-ui/src`
|
||||
- Inspect: `ruoyi-ui/package.json`
|
||||
|
||||
- [ ] **Step 1: 核对设计文档中的前端交付边界**
|
||||
|
||||
Run: `rg -n "frontend/dist|dist.zip|不修改|不接入 Nginx|不新增外部配置文件" docs/superpowers/specs/2026-04-01-production-one-click-deploy-design.md`
|
||||
Expected: 能看到本次前端范围只包含发布目录中的静态包替换和解压,不涉及 `ruoyi-ui` 工程改造。
|
||||
|
||||
- [ ] **Step 2: 检查前端源码中不存在需要同步修改的实现点**
|
||||
|
||||
Run: `rg -n "deploy_from_package|dist.zip|frontend/dist|生产一键部署" ruoyi-ui/src ruoyi-ui/package.json`
|
||||
Expected: 无输出,说明 `ruoyi-ui` 不依赖本次部署脚本实现。
|
||||
|
||||
- [ ] **Step 3: 明确执行阶段不得改动 `ruoyi-ui`**
|
||||
|
||||
在执行笔记中写入以下约束:
|
||||
|
||||
```markdown
|
||||
- 本次前端交付物是发布目录中的静态包部署链路
|
||||
- 不修改 `ruoyi-ui` 下任何页面、接口、构建配置或打包脚本
|
||||
- 如后续出现页面需求,必须回到新需求重新设计和计划
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 提交本任务**
|
||||
|
||||
```bash
|
||||
git add docs/superpowers/plans/2026-04-01-production-one-click-deploy-frontend-plan.md
|
||||
git commit -m "新增生产一键部署前端计划"
|
||||
```
|
||||
|
||||
### Task 2: 在部署脚本中实现前端静态包发现与备份
|
||||
|
||||
**Files:**
|
||||
- Modify: `bin/prod/deploy_from_package.sh`
|
||||
|
||||
- [ ] **Step 1: 实现前端 `dist.zip` 唯一校验**
|
||||
|
||||
补齐函数:
|
||||
|
||||
```sh
|
||||
assert_single_dist_zip() {
|
||||
search_dir="$1"
|
||||
count=$(find "$search_dir" -type f -name 'dist.zip' | wc -l | tr -d ' ')
|
||||
if [ "$count" -ne 1 ]; then
|
||||
log_error "前端 dist.zip 数量不正确,期望 1 个,实际 $count 个"
|
||||
exit 1
|
||||
fi
|
||||
find "$search_dir" -type f -name 'dist.zip' | head -n 1
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 实现旧版前端 `dist` 时间戳备份**
|
||||
|
||||
补齐函数:
|
||||
|
||||
```sh
|
||||
backup_frontend_dist() {
|
||||
if [ -d "$FRONTEND_DIST_DIR" ]; then
|
||||
mv "$FRONTEND_DIST_DIR" "$FRONTEND_DIR/dist-$(timestamp)"
|
||||
fi
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 实现新前端压缩包替换**
|
||||
|
||||
补齐函数:
|
||||
|
||||
```sh
|
||||
deploy_frontend_archive() {
|
||||
source_dist_zip="$1"
|
||||
rm -f "$FRONTEND_DIST_ARCHIVE"
|
||||
mv "$source_dist_zip" "$FRONTEND_DIST_ARCHIVE"
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 做语法校验**
|
||||
|
||||
Run: `sh -n bin/prod/deploy_from_package.sh`
|
||||
Expected: 无输出,返回码为 0。
|
||||
|
||||
- [ ] **Step 5: 提交本任务**
|
||||
|
||||
```bash
|
||||
git add bin/prod/deploy_from_package.sh
|
||||
git commit -m "实现生产部署脚本前端备份替换逻辑"
|
||||
```
|
||||
|
||||
### Task 3: 在部署脚本中实现前端解压与结果校验
|
||||
|
||||
**Files:**
|
||||
- Modify: `bin/prod/deploy_from_package.sh`
|
||||
|
||||
- [ ] **Step 1: 实现前端解压函数**
|
||||
|
||||
补齐函数:
|
||||
|
||||
```sh
|
||||
deploy_frontend_dist() {
|
||||
dist_unpack_dir="$WORK_DIR/frontend"
|
||||
mkdir -p "$dist_unpack_dir"
|
||||
unzip -oq "$FRONTEND_DIST_ARCHIVE" -d "$dist_unpack_dir"
|
||||
rm -rf "$FRONTEND_DIST_DIR"
|
||||
mkdir -p "$FRONTEND_DIST_DIR"
|
||||
cp -a "$(resolve_frontend_source_dir "$dist_unpack_dir")"/. "$FRONTEND_DIST_DIR"/
|
||||
}
|
||||
```
|
||||
|
||||
要求同时实现 `resolve_frontend_source_dir()`,至少支持:
|
||||
|
||||
- 解压根目录直接包含 `index.html`
|
||||
- 解压后为 `dist/index.html`
|
||||
- 其他情况下用 `find` 定位第一个 `index.html`
|
||||
|
||||
- [ ] **Step 2: 将前端流程接入主执行顺序**
|
||||
|
||||
主流程至少补齐:
|
||||
|
||||
```sh
|
||||
frontend_dist_source=$(assert_single_dist_zip "$WORK_DIR/package")
|
||||
backup_frontend_dist
|
||||
deploy_frontend_archive "$frontend_dist_source"
|
||||
deploy_frontend_dist
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 检查脚本中已包含前端关键链路**
|
||||
|
||||
Run: `rg -n "assert_single_dist_zip|backup_frontend_dist|deploy_frontend_archive|deploy_frontend_dist|resolve_frontend_source_dir|frontend/dist.zip|frontend/dist" bin/prod/deploy_from_package.sh`
|
||||
Expected: 能看到前端校验、备份、替换和解压函数都已落位。
|
||||
|
||||
- [ ] **Step 4: 做语法校验**
|
||||
|
||||
Run: `sh -n bin/prod/deploy_from_package.sh`
|
||||
Expected: 无输出,返回码为 0。
|
||||
|
||||
- [ ] **Step 5: 提交本任务**
|
||||
|
||||
```bash
|
||||
git add bin/prod/deploy_from_package.sh
|
||||
git commit -m "实现生产部署脚本前端解压逻辑"
|
||||
```
|
||||
|
||||
### Task 4: 用临时发布目录验证前端部署结果并留痕
|
||||
|
||||
**Files:**
|
||||
- Modify: `bin/prod/deploy_from_package.sh`
|
||||
- Create: `doc/implementation-report-2026-04-01-production-one-click-deploy-frontend.md`
|
||||
|
||||
- [ ] **Step 1: 构造临时前端发布目录做解压验证**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
tmpdir=$(mktemp -d)
|
||||
mkdir -p "$tmpdir/input/dist"
|
||||
printf '<html>ok</html>\n' > "$tmpdir/input/dist/index.html"
|
||||
(cd "$tmpdir/input" && zip -qr "$tmpdir/dist.zip" dist)
|
||||
unzip -oq "$tmpdir/dist.zip" -d "$tmpdir/unpacked"
|
||||
test -f "$tmpdir/unpacked/dist/index.html"
|
||||
rm -rf "$tmpdir"
|
||||
```
|
||||
|
||||
Expected: 命令执行成功,说明计划中的 `dist.zip -> frontend/dist` 解压链路可被临时目录复现。
|
||||
|
||||
- [ ] **Step 2: 再次确认 `ruoyi-ui` 未被纳入改动范围**
|
||||
|
||||
Run: `git status --short ruoyi-ui`
|
||||
Expected: 无本次任务新增或修改的前端源码文件;如果有输出,必须先判断是否为历史遗留改动,不得误提交。
|
||||
|
||||
- [ ] **Step 3: 编写前端实施记录**
|
||||
|
||||
在 [doc/implementation-report-2026-04-01-production-one-click-deploy-frontend.md](/Users/wkc/Desktop/loan-pricing/loan-pricing/doc/implementation-report-2026-04-01-production-one-click-deploy-frontend.md) 至少记录:
|
||||
|
||||
```markdown
|
||||
- 部署脚本中新增前端 dist.zip 唯一校验
|
||||
- 旧版 frontend/dist 时间戳备份规则
|
||||
- 新版 frontend/dist.zip 替换规则
|
||||
- 前端静态资源解压到 frontend/dist 的实现方式
|
||||
- 已确认 `ruoyi-ui` 本次无源码改动
|
||||
- 执行的验证命令与结果
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 核对实施记录路径**
|
||||
|
||||
Run: `ls doc/implementation-report-2026-04-01-production-one-click-deploy-frontend.md`
|
||||
Expected: 文件存在于仓库 `doc/` 目录。
|
||||
|
||||
- [ ] **Step 5: 提交本任务**
|
||||
|
||||
```bash
|
||||
git add bin/prod/deploy_from_package.sh doc/implementation-report-2026-04-01-production-one-click-deploy-frontend.md
|
||||
git commit -m "完成生产一键部署前端实现"
|
||||
```
|
||||
Reference in New Issue
Block a user