From b321ab570eb8985bd86439aacae7edd5bb2bcae2 Mon Sep 17 00:00:00 2001 From: hugocasa Date: Mon, 6 Jul 2026 22:20:09 +0200 Subject: [PATCH] fix(git-sync): address Codex nits (webhook orphan on cleared auto_pull, fork detection) - edit_git_sync_config: also delete a repo's old webhook when the save drops the repo OR clears its auto_pull. Webhook fields are only preserved onto a Some auto_pull, so a save that present-but-clears a repo would otherwise orphan its hook. - GitSyncRepositoryCard: isFork now uses parent_workspace_id OR the wm-fork- prefix (was AND), matching the backend/CLI rule, so prefix-less dev workspaces are detected as forks and don't show the parent fork-PR toggle. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01PP5gBSPfo1YtkL1sWVAjJm --- .../windmill-api-workspaces/src/workspaces.rs | 21 +++++++++++-------- .../git_sync/GitSyncRepositoryCard.svelte | 4 +++- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/backend/windmill-api-workspaces/src/workspaces.rs b/backend/windmill-api-workspaces/src/workspaces.rs index 7845e5489f..8183c60eed 100644 --- a/backend/windmill-api-workspaces/src/workspaces.rs +++ b/backend/windmill-api-workspaces/src/workspaces.rs @@ -2722,17 +2722,20 @@ async fn edit_git_sync_config( .map(|e| { e.repositories .iter() - .filter(|old| { - !git_sync_settings + .filter_map(|old| { + let hook = old.auto_pull.as_ref().and_then(|a| a.webhook_id)?; + // The save carries the hook forward (reconciled below) only + // when the repo is still present AND still has auto_pull — the + // preservation loop copies webhook fields only onto a Some + // auto_pull. Otherwise (repo dropped, or auto_pull cleared) the + // hook would orphan, so delete it. + let carried = git_sync_settings .repositories .iter() - .any(|n| n.git_repo_resource_path == old.git_repo_resource_path) - }) - .filter_map(|old| { - old.auto_pull - .as_ref() - .and_then(|a| a.webhook_id) - .map(|h| (old.git_repo_resource_path.clone(), h)) + .find(|n| n.git_repo_resource_path == old.git_repo_resource_path) + .map(|n| n.auto_pull.is_some()) + .unwrap_or(false); + (!carried).then_some((old.git_repo_resource_path.clone(), hook)) }) .collect() }) diff --git a/frontend/src/lib/components/git_sync/GitSyncRepositoryCard.svelte b/frontend/src/lib/components/git_sync/GitSyncRepositoryCard.svelte index 8f9c2c919e..771eaa86bb 100644 --- a/frontend/src/lib/components/git_sync/GitSyncRepositoryCard.svelte +++ b/frontend/src/lib/components/git_sync/GitSyncRepositoryCard.svelte @@ -80,8 +80,10 @@ // repo and applied to all of its forks, so hide it when the current workspace // is itself a fork. const currentWorkspaceData = $derived($userWorkspaces?.find((w) => w.id === $workspaceStore)) + // A fork or dev workspace: has a parent, or carries the wm-fork- id prefix + // (which survives if the parent is deleted). Mirrors the backend/CLI rule. const isFork = $derived( - ($workspaceStore?.startsWith('wm-fork-') ?? false) && + ($workspaceStore?.startsWith('wm-fork-') ?? false) || !!currentWorkspaceData?.parent_workspace_id ) function setForkOpenPrs(v: boolean) {