fix: ensure symlinked git directories work#2394
fix: ensure symlinked git directories work#2394dballance wants to merge 2 commits intoactions:mainfrom
Conversation
|
Tested this against my environment and it resolves the issue! |
There was a problem hiding this comment.
Pull request overview
Fixes credential includeIf "gitdir:..." matching on self-hosted runners where the workspace path includes symlinks by resolving the host .git directory path before writing includeIf.gitdir:* entries.
Changes:
- Resolve symlinks for the host
.gitdirectory used inincludeIf.gitdir:keys (with a fallback when resolution fails). - Update the bundled
dist/index.jsto reflect the source change. - Add Jest coverage for symlink resolution and the fallback path behavior.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/git-auth-helper.ts | Resolves the host .git path via realpath to make includeIf gitdir matching work with symlinked workspaces. |
| dist/index.js | Compiled/bundled output updated to include the new symlink-resolution logic. |
| test/git-auth-helper.test.ts | Adds tests verifying symlink resolution in includeIf keys and fallback behavior when resolution fails. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| await fs.promises.symlink(workspace, symlinkPath) | ||
|
|
||
| // Make git appear to be operating from the symlink path | ||
| ;(git.getWorkingDirectory as jest.Mock).mockReturnValue(symlinkPath) |
| const realGitDir = ( | ||
| await fs.promises.realpath(path.join(symlinkPath, '.git')) | ||
| ).replace(/\\/g, '/') | ||
| const symlinkGitDir = path.join(symlinkPath, '.git').replace(/\\/g, '/') |
There was a problem hiding this comment.
Personally, I'd be inclined to have a function:
function convertBackslashes(file: string) {
return file.replace(/\\/g, '/')
}...
const realGitDir = convertBackslashes(
await fs.promises.realpath(path.join(symlinkPath, '.git'))
)
const symlinkGitDir = convertBackslashes(path.join(symlinkPath, '.git'))...
const fallbackGitDir = convertBackslashes(
path.join(nonexistentPath, '.git')
)I'm not entirely sure about house style, but I occasionally encourage DRY. It helps understand that strings of code are the same.
| // Arrange | ||
| await setup(configureAuth_fallsBackWhenRealpathSyncFails) | ||
|
|
||
| // Use a non-existent path so realpathSync throws ENOENT naturally, |
There was a problem hiding this comment.
| // Use a non-existent path so realpathSync throws ENOENT naturally, | |
| // Use a nonexistent path so realpathSync throws ENOENT naturally, |
(This matches your variable in the const below and is a real word)
| // Use a non-existent path so realpathSync throws ENOENT naturally, | ||
| // exercising the catch fallback in configureToken() | ||
| const nonexistentPath = path.join(runnerTemp, 'does-not-exist') | ||
| ;(git.getWorkingDirectory as jest.Mock).mockReturnValue(nonexistentPath) |
There was a problem hiding this comment.
| ;(git.getWorkingDirectory as jest.Mock).mockReturnValue(nonexistentPath) | |
| (git.getWorkingDirectory as jest.Mock).mockReturnValue(nonexistentPath) |
?
Resolves #2393