fix(release): 完善发布事务和状态隔离
bat-rust / Build and test Rust (push) Canceled after 0s
bat-rust / Build and test Go API (push) Canceled after 0s

This commit is contained in:
2026-09-12 17:50:09 +08:00
parent 30d1cd77e8
commit f2c20367a6
4 changed files with 208 additions and 23 deletions
+46 -20
View File
@@ -3255,9 +3255,21 @@ fn is_release_local_mutable_state(path: &Path) -> bool {
matches!(
path.file_name().and_then(|name| name.to_str()),
Some(
"translation-tasks.sqlite"
OFFICIAL_DOWNLOAD_MANIFEST_FILE
| OFFICIAL_SYNC_SNAPSHOT_FILE
| "official-parse-cache.json"
| "official-textunit-index.json"
| "official-textunit-tasks.json"
| "crowdin-textunit-queue.json"
| "official-resource-changes.json"
| "crowdin-translation-handoff.json"
| "translation-tasks.sqlite"
| "translation-tasks.sqlite-wal"
| "translation-tasks.sqlite-shm"
| "translation-handoff.json"
| OFFICIAL_LAUNCHER_BOOTSTRAP_FILE
| OFFICIAL_LAUNCHER_BOOTSTRAP_PENDING_FILE
| "official-cas-reuse-references.json"
)
)
}
@@ -4443,29 +4455,43 @@ mod tests {
let source = temp.path().join("old");
let destination = temp.path().join("new");
fs::create_dir_all(&source).unwrap();
fs::write(source.join("translation-tasks.sqlite"), b"old-db").unwrap();
fs::write(source.join("translation-tasks.sqlite-wal"), b"old-wal").unwrap();
let mutable_files = [
OFFICIAL_DOWNLOAD_MANIFEST_FILE,
OFFICIAL_SYNC_SNAPSHOT_FILE,
"official-parse-cache.json",
"official-textunit-index.json",
"official-textunit-tasks.json",
"crowdin-textunit-queue.json",
"official-resource-changes.json",
"crowdin-translation-handoff.json",
"translation-tasks.sqlite",
"translation-tasks.sqlite-wal",
"translation-tasks.sqlite-shm",
"translation-handoff.json",
OFFICIAL_LAUNCHER_BOOTSTRAP_FILE,
OFFICIAL_LAUNCHER_BOOTSTRAP_PENDING_FILE,
"official-cas-reuse-references.json",
];
for (index, name) in mutable_files.iter().enumerate() {
fs::write(source.join(name), format!("old-{index}")).unwrap();
}
fs::write(source.join("immutable.bundle"), b"payload").unwrap();
copy_tree_no_symlink(&source, &destination, false).unwrap();
let old_db_inode = fs::metadata(source.join("translation-tasks.sqlite"))
.unwrap()
.ino();
let new_db_inode = fs::metadata(destination.join("translation-tasks.sqlite"))
.unwrap()
.ino();
assert_ne!(old_db_inode, new_db_inode);
fs::write(destination.join("translation-tasks.sqlite"), b"new-db").unwrap();
fs::write(destination.join("translation-tasks.sqlite-wal"), b"new-wal").unwrap();
assert_eq!(
fs::read(source.join("translation-tasks.sqlite")).unwrap(),
b"old-db"
);
assert_eq!(
fs::read(source.join("translation-tasks.sqlite-wal")).unwrap(),
b"old-wal"
);
for (index, name) in mutable_files.iter().enumerate() {
assert_ne!(
fs::metadata(source.join(name)).unwrap().ino(),
fs::metadata(destination.join(name)).unwrap().ino(),
"mutable state unexpectedly hard-linked: {name}"
);
fs::write(destination.join(name), format!("new-{index}")).unwrap();
assert_eq!(
fs::read(source.join(name)).unwrap(),
format!("old-{index}").as_bytes(),
"historical mutable state changed: {name}"
);
}
assert_eq!(
fs::metadata(source.join("immutable.bundle")).unwrap().ino(),
fs::metadata(destination.join("immutable.bundle"))