feat(integrations): support automatic branch cleanup after merge
Add a new git::review_cleanup module that implements a CleanupPlan with prepare() and finish() routines to safely remove/clean tracking and local branches after a PR/MR is merged. The cleanup logic validates branch names, ensures a clean worktree, checks remotes/URLs, verifies commits/ancestry, protects against concurrent worktrees or divergent local/remote commits, and performs authenticated fetch/push and ref updates. Unit tests for the cleanup behavior are included. Wire provider-side cleanup into integrations: - add an integrations/cleanup module to read provider PR payloads and derive cleanup inputs - run cleanup::prepare(...) before performing a merge when an optional cleanup_path is provided - after a successful provider merge, run cleanup::finish(...); any failure is reported as MERGE_ACCEPTED_CLEANUP_FAILED Also: - export the new git review_cleanup module (src-tauri/src/git.rs) - accept an optional cleanup_path parameter in run_integration_review_action - remove the previous REVIEW_REQUEST_TIMEOUT wrapper around the spawned blocking task (the integration action is no longer wrapped with the 35s timeout)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
mod cleanup;
|
||||
mod merge;
|
||||
pub use merge::get_integration_review_merge_options;
|
||||
use merge::merge_payload;
|
||||
@@ -1197,26 +1198,31 @@ pub async fn run_integration_review_action(
|
||||
number: u64,
|
||||
action: String,
|
||||
merge_method: Option<String>,
|
||||
cleanup_path: Option<String>,
|
||||
) -> Result<(), String> {
|
||||
tokio::time::timeout(
|
||||
REVIEW_REQUEST_TIMEOUT,
|
||||
tauri::async_runtime::spawn_blocking(move || {
|
||||
tauri::async_runtime::spawn_blocking(move || {
|
||||
if token.trim().is_empty() { return Err("No token is stored for this integration.".to_string()); }
|
||||
if !matches!(action.as_str(), "merge" | "approve" | "close" | "reopen") { return Err("Unsupported review action.".to_string()); }
|
||||
if action == "merge" { merge_payload(&provider, merge_method.as_deref())?; }
|
||||
let base_url = normalized_base_url(&base_url)?;
|
||||
let client = client()?;
|
||||
let cleanup = if action == "merge" {
|
||||
cleanup_path.as_deref().map(|path| cleanup::prepare(&client, &base_url, &username, &token, &provider, &repository_id, &repository_name, number, path)).transpose()?
|
||||
} else { None };
|
||||
match provider.as_str() {
|
||||
"github" => github_review_action(&client, &base_url, &token, &repository_name, number, &action, merge_method.as_deref()),
|
||||
"gitlab" | "gitlab-self-hosted" => gitlab_review_action(&client, &base_url, &token, &repository_id, number, &action, merge_method.as_deref()),
|
||||
"gitea" => gitea_review_action(&client, &base_url, &token, &repository_name, number, &action, merge_method.as_deref()),
|
||||
"azure-devops" => azure_review_action(&client, &base_url, &username, &token, &repository_name, &repository_id, number, &action, merge_method.as_deref()),
|
||||
_ => Err("Unsupported integration provider.".to_string()),
|
||||
}?;
|
||||
if let Some(cleanup) = cleanup {
|
||||
cleanup::finish(&cleanup, &client, &base_url, &username, &token, &provider, &repository_id, &repository_name, number)
|
||||
.map_err(|err| format!("MERGE_ACCEPTED_CLEANUP_FAILED: {err}"))?;
|
||||
}
|
||||
}),
|
||||
)
|
||||
Ok(())
|
||||
})
|
||||
.await
|
||||
.map_err(|_| "The integration API did not respond within 35 seconds.".to_string())?
|
||||
.map_err(|err| format!("Could not update review request: {err}"))?
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user