mirror of
https://github.com/Ed1s0nZ/CyberStrikeAI.git
synced 2026-10-22 15:18:33 +02:00
fix: a rollback keeps the operator's edits, and a retry really compiles
The review found two failure paths that reported success for work the engine had not done. Rollback: it refused only when *non-protected* source files were modified, and then ran `git reset --hard` to the previous commit - which discards every local change to tracked files, not just the update's. Edits to roles/skills/tools (the update itself keeps those via its own stash) and edits made after the update were silently wiped, while Result said nothing: deployment.md's promise that "work done afterwards is not swept away" did not hold. Rollback now copies every protected file that differs right now into `.update-backup/rollback_<ts>/` before the reset, sets the copies back after it, re-applies hand deletions, and names what it kept in Result.KeptContent like an update does. Retry: Apply merges and writes the state file before it builds, so a failed (or toolchain-less) build leaves HEAD on the new commit with the old binary still in place. The retry then took the `!snap.UpdateAvailable` no-op branch, aligned the version and returned err=nil - the job was recorded as succeeded, the page said "update finished", the CLI printed that source and binary were in place, and the old executable kept running. The tree now carries a `.update-build-pending` marker, written the moment the merge lands (and when an adoption commits to its work tree) and cleared only after the new binary is in place. The no-op branch reads it: with a toolchain it compiles and reports the build (commits=0, binaryBuilt=true); without one it keeps refusing exactly like the first attempt, so "install go and click again" is now a real instruction. The console stops treating "nothing to pull" as "nothing to do" (the retry button stays live, the confirm dialog and the done toast say the build is what will happen), and the CLI's printResult no longer swallows the build-only result. Both paths are covered by regression tests that fail on the pre-fix tree: two rollback scenarios driven through real git (edit before and after the update, a hand deletion), and four retry scenarios driven through a scripted go on PATH (failed build, state-write failure, an adoption's failed build retried by the next update, and no toolchain then toolchain).
This commit is contained in:
1 parent
22a069849c
commit
9c6928074d
14 files changed
+632
-41
No files matched your search
@@ -185,6 +185,8 @@ SQLite 热备份时最好先停止服务,或至少复制 `*.db`、`*.db-wal`
|
||||
最新代码:fetch → 快进合并 → `go build` → 原子换二进制(旧的留作 `cyberstrike-ai.prev`),并把
|
||||
`roles/ skills/ tools/ agents/ knowledge_base/ data/ config.yaml` 等运维者内容先暂存再放回,结果里点名
|
||||
保留了哪些文件。本地源码有改动、或本地历史与更新源分叉时它会拒绝并说明原因,而不是硬来。
|
||||
构建失败或本机没有 Go 工具链时源码照样更新、二进制保持原样:欠编译会记在安装目录(`.update-build-pending`)
|
||||
并被页面标出,装好 go 后再点一次「一键更新」即补编译。
|
||||
细节见 [开发者指南](developer-guide.md) 的「一键更新」一节。
|
||||
|
||||
检测到 systemd/launchd(环境里有对应启动标记)时,"更新完成后退出进程"默认勾选:更新成功后进程退出、
|
||||
|
||||
@@ -97,6 +97,8 @@ update:
|
||||
`config.yaml` 的 `version` 字段(只动这一行、临时文件 + 原子替换;进度里会有一行「版本号已随新代码
|
||||
更新:v1.7.20 → v1.7.21」)。重启后页头的版本徽标与静态资源的 `?v=` 都跟代码对上——升级后前端缓存
|
||||
也因此自动失效。回滚会把版本号一起还原(前提是这期间没人手改过它);解压安装「接入」时同样同步一次。
|
||||
若 `version` 的写法无法行级替换(如 JSON 单行、多行标量),写入会安全跳过并提示,而不是产出打不开的
|
||||
配置——读取走 YAML 解析(认 `version` / `"version"` / `'version'` 三种写法),写入的行匹配与之口径一致。
|
||||
|
||||
### 四种拒绝场景
|
||||
|
||||
@@ -104,7 +106,7 @@ update:
|
||||
|---|---|---|
|
||||
| 本地改过**产品源码**(不在 protected 清单里的路径) | `local_source_edits` | 一键更新是"下载",不是"替你决定冲突"。点名文件,先提交或还原再重试 |
|
||||
| 分支与远端**分叉**(本地既领先又落后) | `diverged` | 那是合并决策,给出 ahead/behind 数字;手工处理后再点 |
|
||||
| 本机没有 Go 工具链 | `no_toolchain` | **源码照样更新**,只有二进制没换;装好 `go` 再点一次即可补上 |
|
||||
| 本机没有 Go 工具链 | `no_toolchain` | **源码照样更新**,只有二进制没换;欠编译记入 `.update-build-pending`(状态里 `buildPending`,页面照常开放「一键更新」),装好 `go` 再点一次会真的补编译 |
|
||||
| 这个目录不是 git 工作树 | `not_a_repo`(状态里 `installed: false`) | tarball 安装的目录没有可快进的远端,按发布包方式更新 |
|
||||
|
||||
`apply` 是异步的,所以它总是先回 `202`,上表的拒绝出现在轮询到的 `job.failure`(`reason`/`message`/`items`)里;
|
||||
@@ -119,6 +121,8 @@ update:
|
||||
`.update-backup/<时间戳>/` 并从工作树移开(你多出来的、上游没动的目录连碰都不碰),合并后再原样放回,
|
||||
于是"更新代码、留下我的工作"成立。结果里的 `keptContent` 逐个点名被保留的文件——绝不静默丢弃:
|
||||
当上游与你在同一个文件上都有改动,落地的是你的版本,而这件事写在结果里。
|
||||
**回滚遵循同一条规则**:`reset --hard` 会把受保护文件上现存的本地改动先暂存、重置后放回(更新前改的
|
||||
和更新后改的都算,本地删除的保持删除),`keptContent` 同样点名——回滚撤的是代码,不是你的内容。
|
||||
|
||||
### 回滚
|
||||
|
||||
|
||||
Reference in new issue
Block a user