新增: 无人值守安全系列(H1-H3) + P5 审计日志与部署运维 + #14 异步委托
- H3 外部干预感知: run_agentic_loop 增 h3_watch_dir 参数, loop 启动取 git HEAD 基线, 每 5 轮探测, HEAD 被外部改写(切分支/reset/他话提交)即 emit_task_parked(stop_kind=external_change) + teardown 停靠; 4 调用方(发送/编辑/强制发送/审批续跑)从 allowed_dirs.persistent 排序取首目录, 修复初版 current_dir 恒空缺陷 - P5 审计日志: df-im-gateway audit.rs append-only SQLite(tunnel_audit 表, payload 4KB 截断, recent/by_request 查询), main.rs 8 打点点位(inbound/command/outbound), 写失败不阻断主链路, 17 tests passed - P5 部署运维: publish-im-gateway.ps1(musl 交叉编译→scp .new→systemd 原子切换→9191 验证→自动回滚) + systemd unit + nginx im.1216.top 反代 + 运维手册 - #14 异步委托: 受理/完成两段式 + 桌面任务卡(后台进行中徽章/轮次/切换) + 飞书双端同构, 关联缺陷 #8-#12 速清 验收: cargo check workspace EXIT 0, cargo test workspace 全绿(711+560+33+12...), vue-tsc EXIT 0
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
# df-im-gateway 一键发布脚本(复用 publish-u-relay 模式)
|
||||
# 用法: powershell -File scripts\publish-im-gateway.ps1 [-SkipBuild] [-SkipDeploy]
|
||||
# 流程: cargo test → musl 交叉编译 → scp 上传(.new 中转) → systemd 原子切换 → 9191 验证
|
||||
param(
|
||||
[switch]$SkipBuild,
|
||||
[switch]$SkipDeploy
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
$Repo = "E:/wk-lab/devflow"
|
||||
$Target = "x86_64-unknown-linux-musl"
|
||||
$Server = "root@39.99.243.191"
|
||||
$RemoteDir = "/opt/df-im-gateway"
|
||||
$ServiceName = "df-im-gateway"
|
||||
$LocalBin = "$Repo/target-musl/$Target/release/df-im-gateway"
|
||||
|
||||
function Step($msg) { Write-Host "`n=== $msg ===" -ForegroundColor Cyan }
|
||||
|
||||
if (-not $SkipBuild) {
|
||||
Step "Step 0: 单测基线(df-im-gateway)"
|
||||
cargo test -p df-im-gateway --manifest-path "$Repo/Cargo.toml"
|
||||
if ($LASTEXITCODE -ne 0) { throw "单测失败,中止发布" }
|
||||
|
||||
Step "Step 1: musl 交叉编译(rust-lld self-contained)"
|
||||
$env:CARGO_TARGET_DIR = "$Repo/target-musl"
|
||||
cargo build --release -p df-im-gateway --manifest-path "$Repo/Cargo.toml" --target $Target
|
||||
if ($LASTEXITCODE -ne 0) { throw "编译失败,中止发布" }
|
||||
Remove-Item Env:\CARGO_TARGET_DIR -ErrorAction SilentlyContinue
|
||||
if (-not (Test-Path $LocalBin)) { throw "产物不存在: $LocalBin" }
|
||||
$size = [math]::Round((Get-Item $LocalBin).Length / 1MB, 1)
|
||||
Write-Host "产物: $LocalBin (${size}MB)"
|
||||
}
|
||||
|
||||
if ($SkipDeploy) { Write-Host "`nSkipDeploy: 仅构建完成"; exit 0 }
|
||||
|
||||
Step "Step 2: 服务器预检 + 备份"
|
||||
ssh $Server "mkdir -p $RemoteDir && test -f $RemoteDir/df-im-gateway && cp $RemoteDir/df-im-gateway $RemoteDir/df-im-gateway.bak.`$(date +%Y%m%d%H%M%S) || echo '首次部署,无备份'"
|
||||
|
||||
Step "Step 3: 上传(.new 中转防 Text file busy)"
|
||||
scp $LocalBin "${Server}:$RemoteDir/df-im-gateway.new"
|
||||
if ($LASTEXITCODE -ne 0) { throw "scp 失败" }
|
||||
|
||||
Step "Step 4: 原子切换 + systemd 重启"
|
||||
ssh $Server "bash -s" @'
|
||||
set -e
|
||||
cd /opt/df-im-gateway
|
||||
systemctl stop df-im-gateway 2>/dev/null || true
|
||||
mv -f df-im-gateway.new df-im-gateway
|
||||
chmod +x df-im-gateway
|
||||
systemctl start df-im-gateway
|
||||
sleep 1
|
||||
systemctl is-active df-im-gateway
|
||||
'@
|
||||
if ($LASTEXITCODE -ne 0) { throw "切换/启动失败,检查 journalctl -u df-im-gateway"; }
|
||||
|
||||
Step "Step 5: 健康验证"
|
||||
ssh $Server "ss -tlnp | grep 9191 && journalctl -u df-im-gateway -n 5 --no-pager | sed 's/\x1b\[[0-9;]*m//g'"
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "❌ 9191 未监听,执行回滚..." -ForegroundColor Red
|
||||
ssh $Server "bash -s" @'
|
||||
set -e
|
||||
cd /opt/df-im-gateway
|
||||
systemctl stop df-im-gateway
|
||||
LATEST=$(ls -t df-im-gateway.bak.* 2>/dev/null | head -1)
|
||||
if [ -n "$LATEST" ]; then cp "$LATEST" df-im-gateway; chmod +x df-im-gateway; systemctl start df-im-gateway; echo "回滚完成: $LATEST"; else echo "无备份可回滚(首次部署失败,保持停止)"; fi
|
||||
'@
|
||||
throw "健康检查失败,已回滚"
|
||||
}
|
||||
|
||||
Write-Host "`n✅ df-im-gateway 发布完成 (9191)" -ForegroundColor Green
|
||||
Reference in New Issue
Block a user