Skip to content

Commit ed390c1

Browse files
committed
feat: support custom SSH user in git auth configuration
- Allow sshUser setting to override default 'git' user in insteadOf config - When sshUser is empty, default to 'git@github.com' - When sshUser is provided (e.g., 'customuser'), use 'customuser@github.com' - Updated tests to verify custom SSH user behavior in auth configuration Co-Authored-By: Claude:Qwen3-Coder-Next-4bit
1 parent 900f221 commit ed390c1

3 files changed

Lines changed: 94 additions & 2 deletions

File tree

__test__/git-auth-helper.test.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,6 +974,91 @@ describe('git-auth-helper tests', () => {
974974
).toBe(false)
975975
expect((authHelper as any).testCredentialsConfigPath('')).toBe(false)
976976
})
977+
978+
const configureAuth_uses_default_git_user_when_sshUser_empty =
979+
'configureAuth uses default git user when sshUser is empty'
980+
it(configureAuth_uses_default_git_user_when_sshUser_empty, async () => {
981+
// Arrange
982+
await setup(configureAuth_uses_default_git_user_when_sshUser_empty)
983+
settings.sshUser = ''
984+
settings.sshKey = ''
985+
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
986+
987+
// Act
988+
await authHelper.configureAuth()
989+
await authHelper.configureGlobalAuth()
990+
991+
// Assert - verify that git@github.com is in the insteadOf config
992+
const home = git.env['HOME'] || tempHomedir
993+
const configContent = (
994+
await fs.promises.readFile(path.join(home, '.gitconfig'))
995+
).toString()
996+
expect(configContent.indexOf('url.https://github.com/.insteadOf git@github.com')).toBeGreaterThanOrEqual(0)
997+
})
998+
999+
const configureAuth_uses_custom_ssh_user_when_sshUser_provided =
1000+
'configureAuth uses custom SSH user when sshUser is provided'
1001+
it(configureAuth_uses_custom_ssh_user_when_sshUser_provided, async () => {
1002+
// Arrange
1003+
await setup(configureAuth_uses_custom_ssh_user_when_sshUser_provided)
1004+
settings.sshUser = 'customuser'
1005+
settings.sshKey = ''
1006+
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
1007+
1008+
// Act
1009+
await authHelper.configureAuth()
1010+
await authHelper.configureGlobalAuth()
1011+
1012+
// Assert - verify that customuser@github.com is in the insteadOf config
1013+
const home = git.env['HOME'] || tempHomedir
1014+
const configContent = (
1015+
await fs.promises.readFile(path.join(home, '.gitconfig'))
1016+
).toString()
1017+
expect(configContent.indexOf('url.https://github.com/.insteadOf customuser@github.com')).toBeGreaterThanOrEqual(0)
1018+
})
1019+
1020+
const configureGlobalAuth_with_custom_sshUser =
1021+
'configureGlobalAuth with custom sshUser'
1022+
it(configureGlobalAuth_with_custom_sshUser, async () => {
1023+
// Arrange
1024+
await setup(configureGlobalAuth_with_custom_sshUser)
1025+
settings.sshUser = 'admin'
1026+
settings.sshKey = ''
1027+
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
1028+
1029+
// Act
1030+
await authHelper.configureAuth()
1031+
await authHelper.configureGlobalAuth()
1032+
1033+
// Assert - verify the .insteadOf config contains the custom user
1034+
const home = git.env['HOME'] || tempHomedir
1035+
const configContent = (
1036+
await fs.promises.readFile(path.join(home, '.gitconfig'))
1037+
).toString()
1038+
expect(configContent.indexOf('url.https://github.com/.insteadOf admin@github.com')).toBeGreaterThanOrEqual(0)
1039+
})
1040+
1041+
const configureSubmoduleAuth_with_custom_sshUser =
1042+
'configureSubmoduleAuth with custom sshUser'
1043+
it(configureSubmoduleAuth_with_custom_sshUser, async () => {
1044+
// Arrange
1045+
await setup(configureSubmoduleAuth_with_custom_sshUser)
1046+
settings.sshUser = 'deploy'
1047+
settings.sshKey = ''
1048+
const authHelper = gitAuthHelper.createAuthHelper(git, settings)
1049+
await authHelper.configureAuth()
1050+
const mockSubmoduleForeach = git.submoduleForeach as jest.Mock<any, any>
1051+
mockSubmoduleForeach.mockClear()
1052+
1053+
// Act
1054+
await authHelper.configureSubmoduleAuth()
1055+
1056+
// Assert - verify the insteadOf config uses the custom user
1057+
expect(mockSubmoduleForeach).toHaveBeenCalledTimes(3)
1058+
expect(mockSubmoduleForeach.mock.calls[1][0]).toMatch(
1059+
/url.*insteadOf.*deploy@github.com:/
1060+
)
1061+
})
9771062
})
9781063

9791064
async function setup(testName: string): Promise<void> {

dist/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,10 @@ class GitAuthHelper {
174174
this.tokenConfigValue = `AUTHORIZATION: basic ${basicCredential}`;
175175
// Instead of SSH URL
176176
this.insteadOfKey = `url.${serverUrl.origin}/.insteadOf`; // "origin" is SCHEME://HOSTNAME[:PORT]
177-
this.insteadOfValues.push(`git@${serverUrl.hostname}:`);
177+
const sshUser = this.settings.sshUser && this.settings.sshUser.length > 0
178+
? this.settings.sshUser
179+
: 'git';
180+
this.insteadOfValues.push(`${sshUser}@${serverUrl.hostname}:`);
178181
if (this.settings.workflowOrganizationId) {
179182
this.insteadOfValues.push(`org-${this.settings.workflowOrganizationId}@github.com:`);
180183
}

src/git-auth-helper.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,11 @@ class GitAuthHelper {
6565

6666
// Instead of SSH URL
6767
this.insteadOfKey = `url.${serverUrl.origin}/.insteadOf` // "origin" is SCHEME://HOSTNAME[:PORT]
68-
this.insteadOfValues.push(`git@${serverUrl.hostname}:`)
68+
const sshUser =
69+
this.settings.sshUser && this.settings.sshUser.length > 0
70+
? this.settings.sshUser
71+
: 'git'
72+
this.insteadOfValues.push(`${sshUser}@${serverUrl.hostname}:`)
6973
if (this.settings.workflowOrganizationId) {
7074
this.insteadOfValues.push(
7175
`org-${this.settings.workflowOrganizationId}@github.com:`

0 commit comments

Comments
 (0)