Uh oh!
There was an error while loading. Please reload this page.
Find the repository root from the session location, not the process working directory - #3015
Merged
Conversation
nohwnd
commented
Aug 29, 2026
MemberAuthor
No checks run on this PR: The branch contains both commits, so I dispatched the two workflows against it directly, which tests exactly the state that lands on
Once #3014 merges this retargets to Worth considering separately: adding a base pattern for stacked release branches to 🤖 |
…orking directory Run.RepoRoot decides which Pester.BeforeContainer.ps1 files apply, and its default is found by walking up for a .git directory. The walk ran in C# from Directory.GetCurrentDirectory(), the process working directory, and Set-Location does not change that. So a session that started somewhere else and then changed directory into a repository kept a RepoRoot pointing at the old place, and the whole setup chain silently did not apply, with nothing to say why: pwsh # process working directory is now ~ cd ~/p/myrepo Invoke-Pester ./tests # RepoRoot was ~, no Pester.BeforeContainer.ps1 applied FindRepoRoot takes the directory to start from now, and Invoke-Pester resolves RepoRoot from $ExecutionContext.SessionState.Path.CurrentFileSystemLocation before the run, next to where the shuffle seed is resolved. Same place Pester.Parallel.ps1 already takes the working directory it hands to workers. Only when the option was not set, an explicit RepoRoot is the user's to decide and is left alone. The parameterless overload stays as the value an unused configuration object shows, so [PesterConfiguration]::Default still reports a directory rather than nothing. Tests: the cascade applies after Set-Location with no RepoRoot set, and the test asserts the two locations actually disagree so it cannot pass by accident; an explicit RepoRoot survives the run; FindRepoRoot falls back to the directory it started from when there is no .git. Verified the first one fails without the change (43/44) and passes with it (44/44). Full suite on PS 7.5 macOS: P phase clean, RSpec 2921 passed, 0 failed, 3 skipped. about_PesterConfiguration.help.txt is regenerated by build.ps1 -Clean, so it is in the same commit. 🤖
nohwndforce-pushed
the
fix-reporoot-session-location
branch
from
August 29, 2026 07:55
1ffed2f to
2528764CompareThe test set Run.RepoRoot to 'TestDrive:not-a-real-path-but-mine' to prove an explicit value is not overwritten. Resolving the chain runs that value through GetFullPath, and the made up path is not portable: on Unix it is a legal relative file name, on Windows it reads as a drive qualifier and throws, so the run died and $r was not a result object. Both Windows PowerShell 5.1 legs failed on it while every PS7 leg passed. Use a real temp directory, and assert the run itself passed before reading the value back, so a throw shows up as a failed run rather than as a missing property. The two tests that cover the actual change both passed on 5.1. 🤖
Uh oh!
There was an error while loading. Please reload this page.
nohwnd added a commit
that referenced
this pull request
Sep 5, 2026
Stacked pull requests target the branch below them, not main, and the branches filter on pull_request meant they got no CI at all. #3015 sat on release-6.2.0-alpha1 and only started running checks when #3014 merged and GitHub retargeted it to main, so while working on it there was no way to tell if the change was correct. The filter never protected anything. With the pull_request trigger a run from a fork gets a read-only token and no secrets no matter what branch it targets, so dropping it does not change what untrusted code can reach. It only ever skipped runs we wanted. Also drop paths-ignore from pull_request in ci.yml. Done is a required check on main and it lives in that workflow, so a run skipped by the filter means Done never reports and the pull request stays blocked with nothing to click. Runners are free for public repos. code-analysis.yml was narrower than ci.yml, it only ran for pull requests onto main, so rel/* and dev/* never got PSScriptAnalyzer either. 🤖
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found while writing the 6.2.0-alpha1 notes: I wrote a repository with
Pester.BeforeContainer.ps1at three levels, ran it, and none of them applied. It took two runs to work out why.Run.RepoRootdecides which setup files apply, and its default is found by walking up for a.gitdirectory. The walk runs in C# fromDirectory.GetCurrentDirectory(), the process working directory, andSet-Locationdoes not change that:The run is green, the setup silently did nothing, and there is no warning. It is pre-existing,
Run.RepoRootshipped in 6.1.0, but #2993 made the whole folder cascade depend on it so it is worth fixing before the alpha goes out.Change
FindRepoRoottakes the directory to start from, andInvoke-PesterresolvesRepoRootfrom$ExecutionContext.SessionState.Path.CurrentFileSystemLocationbefore the run, next to where the shuffle seed is resolved. That is the same sourcePester.Parallel.ps1already uses for the working directory it hands to workers.Only when the option was not set. An explicit
Run.RepoRootis the user's to decide and is left alone.The parameterless overload stays as the value an unused configuration object shows, so
[PesterConfiguration]::Defaultstill reports a directory rather than nothing.Verification
Three tests next to the existing cascade tests:
Set-Locationwith noRepoRootset. It also asserts the process directory and the session location actually disagree, so it cannot pass by accident on a runner that happens to start in the right placeRun.RepoRootsurvives the runFindRepoRootfalls back to the directory it started from when there is no.gitabove itThe first one fails without the change (43/44) and passes with it (44/44). Full suite on PS 7.5 macOS: P phase clean, RSpec 2921 passed, 0 failed, 3 skipped.
about_PesterConfiguration.help.txtis regenerated bybuild.ps1 -Clean, so it is in the same commit.Based on
release-6.2.0-alpha1(#3014) because it adds its entry todocs/NEXT-RELEASE.md, which that PR introduces. Retargets tomainon its own once #3014 merges.🤖