fix: prevent cache poisoning by force-resetting worktree on failed PR remediation#6368
fix: prevent cache poisoning by force-resetting worktree on failed PR remediation#6368AftAb-25 wants to merge 1 commit into
Conversation
evankanderson
left a comment
There was a problem hiding this comment.
Nice find! A few minor cleanups, but I'd love to merge this soon.
There was a problem hiding this comment.
Can you add this to pull_request_test.go, rather than creating a new test file (which doesn't correspond to any of the regular .go files in this directory)?
| f, err = mfs.Create("README.md") | ||
| require.NoError(t, err) | ||
| _, err = f.Write([]byte("dirty content from failed remediation")) | ||
| require.NoError(t, err) | ||
| require.NoError(t, f.Close()) |
There was a problem hiding this comment.
util.WriteFile from go-billy/v5/util might be simpler:
| f, err = mfs.Create("README.md") | |
| require.NoError(t, err) | |
| _, err = f.Write([]byte("dirty content from failed remediation")) | |
| require.NoError(t, err) | |
| require.NoError(t, f.Close()) | |
| require.NoError(util.WriteFile(mfs, "README.md", []byte("dirty content from failed remediation"), 0644)) |
| ) { | ||
| err := wt.Checkout(&git.CheckoutOptions{ | ||
| Branch: originallyFetchedBranch, | ||
| Force: true, |
There was a problem hiding this comment.
It looks like the default behavior is MixedReset, which will reset the index but not the working tree. This should prevent importing already-changed files into the branch in most cases, but the worktree corruption could affect future evaluations, since the order is currently "evaluate one rule, then evaluate its actions".
|
Hi @evankanderson, thank you for the review and the thoughtful suggestion! I looked into relying solely on According to the official
My local test assertions confirmed this limitation:
Because we are checking out over a natively shared Let me know if this context makes sense, or if you'd like me to look into implementing this via a different |
Yes, I agreed with you in this comment: #6368 (comment) (We shouldn't have any untracked files except in very unusual circumstances, but it looks like even tracked file changes may persist in the worktree for future evaluations.) However, I had two other requests as well: |
Fixes #6367
Description
This fixes a cache poisoning bug in the PR remediator where failed remediations would leak uncommitted changes into the shared ingest cache, causing silent evaluation failures for subsequent rules.
When pull_request.go aborts a remediation and runs checkoutToOriginallyFetchedBranch, it previously used the default
go-gitcheckout which preserves modifications to the worktree/index. Because the executor uses a single sharedingestCache.Fsper run, those left-behind dirty files would then be incorrectly evaluated by subsequent rules.This PR aggressively resets the worktree during the checkout cleanup phase:
Force: trueto the checkout options to discard modified tracked files.wt.Clean(&git.CleanOptions{Dir: true})to remove any untracked leftover files.I've also added a unit test (checkout_cleanup_test.go) that simulates a dirty worktree and ensures both tracked modifications and untracked files are correctly wiped out.
Checklist