fix(environments): remove deleted branches from UI when synced from Git#4770
Conversation
|
Related Documentation Checked 3 published document(s). No updates required. You have 3 draft document(s). Publish docs to keep them always up-to-date |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## v2 #4770 +/- ##
==========================================
+ Coverage 58.36% 58.46% +0.09%
==========================================
Files 134 134
Lines 16777 16852 +75
==========================================
+ Hits 9792 9852 +60
- Misses 6300 6314 +14
- Partials 685 686 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
b390adc to
a0ccadf
Compare
When a branch is merged and deleted in Git, the Flipt UI was continuing to show the branch because RefreshEnvironment only added new branches but never removed deleted ones from the internal cache. This fix updates RefreshEnvironment to: 1. Track which branches still exist in the Git repository 2. Remove branches from the environment's internal cache when they no longer exist 3. Return the list of deleted branch keys so the EnvironmentStore can remove them 4. Add a Remove method to EnvironmentStore for proper cleanup Changes: - Modified RefreshEnvironment signature to return deleted branch keys - Added Remove method to EnvironmentStore - Updated subscriber in environments.go to handle deleted branches - Added comprehensive test for branch deletion sync Fixes the customer-reported issue where deleted branches persist in the UI. Signed-off-by: Mark Phelps <[email protected]>
…returns Improved the RefreshEnvironment API to return a single RefreshResult struct instead of multiple return values (newBranches, deletedBranchKeys, error). This makes the API cleaner and more maintainable: - Easier to extend with additional fields in the future - More explicit about what data is being returned - Better aligns with Go best practices for multiple return values Changes: - Added RefreshResult struct with NewBranches and DeletedBranchKeys fields - Updated RefreshEnvironment signature to return (*RefreshResult, error) - Updated all callers to use the struct fields - Updated tests to access result.NewBranches and result.DeletedBranchKeys Signed-off-by: Mark Phelps <[email protected]>
Co-authored-by: Roman Dmytrenko <[email protected]> Signed-off-by: Mark Phelps <[email protected]>
Fixed compilation error where map lookup was not properly checking key existence. Changed from direct boolean check to proper two-value lookup pattern. Signed-off-by: Mark Phelps <[email protected]>
Co-authored-by: Roman Dmytrenko <[email protected]> Signed-off-by: Mark Phelps <[email protected]>
a0ccadf to
584f7bc
Compare
Signed-off-by: Mark Phelps <[email protected]>
RefreshEnvironment was modifying shared state (e.branches, e.refs) without proper mutex protection, creating a race condition. Other methods like Branch(), DeleteBranch(), and EvaluationStore() correctly use the mutex. Changes: - Added RLock/RUnlock when reading e.branches and e.refs - Added Lock/Unlock when modifying e.branches and e.refs - Used fine-grained locking to avoid deadlocks with updateSnapshot() - Maintained consistency with existing locking patterns in the codebase This prevents race conditions when RefreshEnvironment is called concurrently with other operations that access the branches map or refs map. Signed-off-by: Mark Phelps <[email protected]>
Remove dagger.io/dagger/dag import that keeps appearing due to variable named 'dag' in the code. The import is unused and causes build issues. Signed-off-by: Mark Phelps <[email protected]>
Signed-off-by: Mark Phelps <[email protected]>
The Notify method was accessing e.refs map without holding the mutex, creating a race condition with RefreshEnvironment. Added fine-grained RLock/Lock usage to protect reads and writes to e.refs. This follows the same locking pattern used in RefreshEnvironment. Signed-off-by: Mark Phelps <[email protected]>
|
something is not right for my gitea setup. I still see the deleted branch as environment. When snapshot is updated it still holds the ref to the deleted branch. |
Added detailed debug logging to help diagnose branch deletion issues: - Log environment key when removing from cache - Log key when removing from EnvironmentStore This will help identify any key mismatch issues between the branch environment cache and the global EnvironmentStore. Signed-off-by: Mark Phelps <[email protected]>
Added comprehensive debug logging for Git branch synchronization: - Log when scanning for branches in Git - Log each branch found with both the environment name and Git branch path - Log cache vs Git branch counts before deletion check This will help diagnose branch deletion issues by showing exactly what branches Git sees vs what's cached, making it easier to identify ref pattern mismatches or sync issues. Signed-off-by: Mark Phelps <[email protected]>
yup also reproduced. working on a fix |
Added Prune: true to FetchOptions to ensure deleted remote branches are removed from local tracking refs. Without this, when a branch is deleted upstream, the local ref refs/remotes/origin/branch-name persists, causing the branch to still appear as existing in Git. This is the root cause of the bug where deleted Git branches continue to show in the Flipt UI. The branch detection logic scans refs/remotes/origin/* refs, and without pruning, deleted upstream branches remain in the local repository indefinitely. With pruning enabled, git fetch will remove stale tracking branches, allowing RefreshEnvironment to correctly detect and remove deleted branches. Signed-off-by: Mark Phelps <[email protected]>
Removed verbose debug logs that were added for investigation: - "scanning for branch environments in Git" - "found branch in Git" per-branch logs - "checking for deleted branches" with counts - "removing environment from store" Kept the "removing deleted branch from cache" log as it provides useful visibility when branches are actually deleted. Signed-off-by: Mark Phelps <[email protected]>
|
@erka fixed. Was missing the Pre-Delete
Post Delete (on GitHub)
Note: This required a UI refresh, we should make the UI auto refresh on changes like this if possible, but we can do that in another PR |
|
Documentation Updates Checked 3 published document(s). No updates required. You have 3 draft document(s). Publish docs to keep them always up-to-date |
The environment picker was showing stale data for deleted/merged branches and closed pull requests until the user performed a hard refresh. This occurred because RTK Query's default caching behavior doesn't automatically refetch data when the browser tab regains focus or when network reconnects. Changes: - Added refetchOnFocus and refetchOnReconnect to environmentsApi config - Added refetchOnMountOrArgChange to useListEnvironmentsQuery in Layout - Added refetchOnMountOrArgChange to useListBranchEnvironmentsQuery in BranchActionsDropdown Now when users switch back to the Flipt tab or reconnect to the network, the environment list will automatically refetch, removing any deleted branches or closed PRs from the picker without requiring a manual refresh. Fixes #4770 Signed-off-by: Mark Phelps <[email protected]>
The environment picker was showing stale data for deleted/merged branches and closed pull requests until the user performed a hard refresh. This occurred because: 1. RTK Query's default caching doesn't automatically refetch on focus/reconnect 2. The backend polls upstream every 30s, but the UI wasn't polling for updates Changes: - Added refetchOnFocus and refetchOnReconnect to environmentsApi config - Added refetchOnMountOrArgChange to useListEnvironmentsQuery in Layout - Added 30s pollingInterval to useListEnvironmentsQuery to match backend fetch interval - Added refetchOnMountOrArgChange to useListBranchEnvironmentsQuery in BranchActionsDropdown - Added conditional 30s polling to namespace query when environment switcher is open Now the UI automatically refetches environments when: - The browser tab regains focus (refetchOnFocus) - Network reconnects (refetchOnReconnect) - Every 30 seconds via polling (matching backend Git fetch interval) This ensures deleted branches and closed PRs are removed from the environment picker within 30 seconds without requiring a manual page refresh. Fixes #4770 Signed-off-by: Mark Phelps <[email protected]>
…it (flipt-io#4770) * fix(environments): remove deleted branches from UI when synced from Git When a branch is merged and deleted in Git, the Flipt UI was continuing to show the branch because RefreshEnvironment only added new branches but never removed deleted ones from the internal cache. This fix updates RefreshEnvironment to: 1. Track which branches still exist in the Git repository 2. Remove branches from the environment's internal cache when they no longer exist 3. Return the list of deleted branch keys so the EnvironmentStore can remove them 4. Add a Remove method to EnvironmentStore for proper cleanup Changes: - Modified RefreshEnvironment signature to return deleted branch keys - Added Remove method to EnvironmentStore - Updated subscriber in environments.go to handle deleted branches - Added comprehensive test for branch deletion sync Fixes the customer-reported issue where deleted branches persist in the UI. Signed-off-by: Mark Phelps <[email protected]> * refactor(environments): use RefreshResult struct instead of multiple returns Improved the RefreshEnvironment API to return a single RefreshResult struct instead of multiple return values (newBranches, deletedBranchKeys, error). This makes the API cleaner and more maintainable: - Easier to extend with additional fields in the future - More explicit about what data is being returned - Better aligns with Go best practices for multiple return values Changes: - Added RefreshResult struct with NewBranches and DeletedBranchKeys fields - Updated RefreshEnvironment signature to return (*RefreshResult, error) - Updated all callers to use the struct fields - Updated tests to access result.NewBranches and result.DeletedBranchKeys Signed-off-by: Mark Phelps <[email protected]> * chore: Apply suggestions from code review Co-authored-by: Roman Dmytrenko <[email protected]> Signed-off-by: Mark Phelps <[email protected]> * fix: correct map lookup syntax in branch deletion check Fixed compilation error where map lookup was not properly checking key existence. Changed from direct boolean check to proper two-value lookup pattern. Signed-off-by: Mark Phelps <[email protected]> * chore: add DCO sign-off for code review changes Co-authored-by: Roman Dmytrenko <[email protected]> Signed-off-by: Mark Phelps <[email protected]> * chore: fix build/main import Signed-off-by: Mark Phelps <[email protected]> * fix(environments): add proper mutex locking to RefreshEnvironment RefreshEnvironment was modifying shared state (e.branches, e.refs) without proper mutex protection, creating a race condition. Other methods like Branch(), DeleteBranch(), and EvaluationStore() correctly use the mutex. Changes: - Added RLock/RUnlock when reading e.branches and e.refs - Added Lock/Unlock when modifying e.branches and e.refs - Used fine-grained locking to avoid deadlocks with updateSnapshot() - Maintained consistency with existing locking patterns in the codebase This prevents race conditions when RefreshEnvironment is called concurrently with other operations that access the branches map or refs map. Signed-off-by: Mark Phelps <[email protected]> * chore: fix build/main import Remove dagger.io/dagger/dag import that keeps appearing due to variable named 'dag' in the code. The import is unused and causes build issues. Signed-off-by: Mark Phelps <[email protected]> * chore: mod tidy Signed-off-by: Mark Phelps <[email protected]> * fix(environments): add mutex locking to Notify method The Notify method was accessing e.refs map without holding the mutex, creating a race condition with RefreshEnvironment. Added fine-grained RLock/Lock usage to protect reads and writes to e.refs. This follows the same locking pattern used in RefreshEnvironment. Signed-off-by: Mark Phelps <[email protected]> * chore(environments): add debug logging for branch deletion Added detailed debug logging to help diagnose branch deletion issues: - Log environment key when removing from cache - Log key when removing from EnvironmentStore This will help identify any key mismatch issues between the branch environment cache and the global EnvironmentStore. Signed-off-by: Mark Phelps <[email protected]> * chore(environments): enhance branch sync debug logging Added comprehensive debug logging for Git branch synchronization: - Log when scanning for branches in Git - Log each branch found with both the environment name and Git branch path - Log cache vs Git branch counts before deletion check This will help diagnose branch deletion issues by showing exactly what branches Git sees vs what's cached, making it easier to identify ref pattern mismatches or sync issues. Signed-off-by: Mark Phelps <[email protected]> * fix(git): enable pruning when fetching to remove deleted remote branches Added Prune: true to FetchOptions to ensure deleted remote branches are removed from local tracking refs. Without this, when a branch is deleted upstream, the local ref refs/remotes/origin/branch-name persists, causing the branch to still appear as existing in Git. This is the root cause of the bug where deleted Git branches continue to show in the Flipt UI. The branch detection logic scans refs/remotes/origin/* refs, and without pruning, deleted upstream branches remain in the local repository indefinitely. With pruning enabled, git fetch will remove stale tracking branches, allowing RefreshEnvironment to correctly detect and remove deleted branches. Signed-off-by: Mark Phelps <[email protected]> * chore(environments): remove excessive debug logging Removed verbose debug logs that were added for investigation: - "scanning for branch environments in Git" - "found branch in Git" per-branch logs - "checking for deleted branches" with counts - "removing environment from store" Kept the "removing deleted branch from cache" log as it provides useful visibility when branches are actually deleted. Signed-off-by: Mark Phelps <[email protected]> --------- Signed-off-by: Mark Phelps <[email protected]> Co-authored-by: Roman Dmytrenko <[email protected]> Signed-off-by: tejasvini1 <[email protected]>




Summary
Fixes a customer-reported bug where deleted Git branches persist in the Flipt Pro UI after being merged and deleted from the repository.
Root Cause
The bug had two components:
Missing pruning on fetch: When fetching from remote, Git was not configured to prune (remove) deleted remote tracking branches. This meant that when a branch was deleted upstream, the local ref
refs/remotes/origin/flipt/env/branchwould persist indefinitely.No cleanup in RefreshEnvironment: The
RefreshEnvironmentmethod only added new branches and updated existing ones, but never removed branches that had been deleted from Git.Solution
1. Enable Pruning on Fetch
Added
Prune: truetoFetchOptionsin the Repository'sFetchmethod. This ensures that deleted remote branches are removed from local tracking refs, matching the behavior ofgit fetch --prune.2. Branch Cleanup in RefreshEnvironment
Updated
RefreshEnvironmentto:e.branches) and the globalEnvironmentStoreRefreshResultstruct containing both new and deleted branches for cleaner API3. Fixed Data Race Conditions
RefreshEnvironmentto protect concurrent access toe.branchesande.refsmapsNotifymethod which was accessinge.refswithout holding the mutexBehavior
Deleted branches will be automatically removed from the UI on the next Git sync cycle (default: 30 seconds). The fix is backwards compatible and follows existing patterns in the codebase.