fix(gitea-integration): 删除项目登记时一并解除 Gitea 绑定,轮询不再写入已删除或已解绑的项目(G8) #35
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "fix/gitea-unbind-on-unregister"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
做了什么
蓝图卡:
.blueprint/modules/gitea-integration.mdG8(complexity M)。起因:删除项目登记时不清理 Gitea 仓库绑定,后台轮询每 10 分钟仍把 commit 和 PR 事件写到已删除的项目 ID 下(重复登记排查会话发现)。
gitea::remove_repo_link_records只改数据库,可以放进调用方的事务;gitea::cleanup_removed_repo_link在提交后尽力删除 Gitea 侧 webhook(加了 10 秒超时)和本机的签名凭证。UI「解绑」和删除登记都调用这两段。projects::delete_project_registration(conn, store, id),连接和凭证存储都由调用方注入。它先调delete_project_records,在同一个事务里删关联表、Gitea 绑定、workspace 和孤儿 profile;提交后再做 Gitea 外部清理。UI 的delete_project(薄包装)和 MCP 的unregister_project都走这个本体。load_poll_targets跳过所属项目已不存在的遗留绑定。每条遗留绑定每次运行只记一次 warn,日志里写明清理办法:对该 ID 调 unregister_project。ingest_polled_commits/ingest_polled_prs,写之前用poll_target_still_bound复核两件事:绑定还在(owner/repo 一致),项目仍在登记中。gitea_unlink_repo:读和删放进同一个事务。unregister_project的描述补上「Gitea 仓库绑定(含 Gitea 侧 webhook 与本机签名凭证)」,docs/ai-context/project-context.yaml同步更新。Tauri command 签名没变,前端和 schema 都没改。自验
cargo test(src-tauri):310 passed,0 failed,5 ignored,编译无警告。projects::tests::deleting_project_registration_unbinds_its_gitea_repo:修复前失败,残留 1 条绑定。gitea_unbinding_rolls_back_with_failed_project_deletion:用触发器让删除 workspace 失败,确认绑定被回滚。deleting_project_registration_removes_its_webhook_secret:被删项目的签名凭证已清理,另一个项目的凭证保留。unregistering_orphaned_binding_id_cleans_the_binding:对孤儿绑定的 ID 删除登记,绑定和凭证都被清掉。gitea::tests::poll_targets_skip_bindings_whose_project_no_longer_existspolled_results_are_dropped_when_binding_is_gone_mid_round:快照里有三个项目,之后删除一个登记、UI 解绑另一个,只有仍绑定的那个写入了 commit 和 PR 事件。unlink_removes_binding_and_webhook_secret_referencedelete_project_registration去掉外部清理。审查处置
独立只读审查对象是 c1632a0,结论为可合并,共 5 条发现:
delete_project_registration,补了凭证清理测试。变异「去掉清理」会让测试失败。gitea_unlink_repo的读和删不在同一个事务里(���有问题)。处理:改用 unchecked_transaction 包住,并发设置 webhook 时由 WAL 读快照过期报 busy,整体回滚。-DSQLITE_DEFAULT_FOREIGN_KEYS=1(libsqlite3-sys 0.30.1 build.rs:123),所以每条新连接默认 foreign_keys=1。我写了一个临时探针测试:从 r2d2 内存池取 3 条连接,另开 1 条裸连接,PRAGMA foreign_keys都是 1。探针跑完已还原,没有提交。测试环境和生产一致,ON DELETE CASCADE 照常生效,不需要修改。断言变更报备:没有修改任何已有断言,只新增了 3 条测试。
没验什么
webhook_id非空时的删除分支没对真实 Gitea 验证。测试特意把 webhook_id 设成 NULL,避免发网络请求。gitea_unlink_repo事务化没实测:它的效果是按 SQLite WAL 语义推理出来的,没做并发实测(不对真实 DB 做并发实验)。delete_project没测:它本身(取连接、purge_project、remove_project_mcp 和本体的先后顺序)没有测试,只测了本体。🤖 Generated with Claude Code