Avoid buggy Remove-Item -Recurse in PsWriter.RmDir
What does this MR do?
Fixes intermittent build-directory cleanup failures on Windows PowerShell/pwsh executors.
Closes #38717 (closed)
Root cause
The fallback branch of the script generated by PsWriter.RmDir (shells/powershell.go) used:
Remove-Item -Force -Recurse <path>Remove-Item -Recurse has a documented known issue (see Example 4): deletion order is not guaranteed to be children-first, so it can intermittently fail with The directory is not empty. This surfaced during handleGetSourcesStrategy cleanup with GIT_STRATEGY: clone on projects with deep directory trees, failing the job before any user script ran.
The primary branch (Remove-Item2 from the NTFSSecurity module) is unaffected and unchanged; only runners without that module hit the buggy fallback.
The fix
Replace the fallback with the same Get-ChildItem pipeline pattern already used by RmFilesRecursive / RmDirsRecursive:
Get-ChildItem -Path <path> -Force -Recurse | Sort-Object { $_.FullName.Length } -Descending | Remove-Item -Force
Remove-Item -Force <path>- Sorting by path length descending guarantees children are deleted before their parents (a child path is always strictly longer than its parent's).
-ForceonGet-ChildItemincludes hidden/system files (e.g..gitcontents).- The now-empty root is then removed without
-Recurse, avoiding the buggy code path entirely.
Note this is broader than the one-liner proposed in the issue (Get-ChildItem <path> -Recurse | Remove-Item -Force), which would leave the root directory in place and still fail on non-empty subdirectories, since Get-ChildItem -Recurse yields parents before children.
Changes
shells/powershell.go-RmDirfallback branchshells/powershell_test.go- updated expected-script literals (rmdirtemplate test,cleanGitConfigsblocks inTestPowershell_GenerateScript)docs/shells/_index.md- example script synced (locale copies left to translation sync)
Verification
go test -race ./shells/... -count=1passes locally- Validated on a test runner instance (Windows, pwsh executor)
Triage note
/cc @adebayo_a - flagging per triage guidelines: the linked issue carries the Customer Interest label.