Skip to content

Commit 2651ee2

Browse files
authored
Merge pull request caprover#1254 from bztes/git-deploy-user
Custom username for SSH git deployment
2 parents 513b781 + 2807bea commit 2651ee2

File tree

2 files changed

+83
-34
lines changed

2 files changed

+83
-34
lines changed

src/utils/GitHelper.ts

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,22 @@ import Utils from './Utils'
1010
const exec = util.promisify(childPross.exec)
1111

1212
export default class GitHelper {
13+
static #SSH_PATH_RE = new RegExp(
14+
[
15+
/^\s*/,
16+
/(?:(?<proto>[a-z]+):\/\/)?/,
17+
/(?:(?<user>[a-z_][a-z0-9_-]+)@)?/,
18+
/(?<domain>[^\s\/\?#:]+)/,
19+
/(?::(?<port>[0-9]{1,5}))?/,
20+
/(?:[\/:](?<owner>[^\s\/\?#:]+))?/,
21+
/(?:[\/:](?<repo>[^\s\/\?#:.]+))/,
22+
/(?:.git)?\/?\s*$/,
23+
]
24+
.map((r) => r.source)
25+
.join(''),
26+
'i'
27+
)
28+
1329
static getLastHash(directory: string) {
1430
return git(directory) //
1531
.silent(true) //
@@ -93,8 +109,7 @@ export default class GitHelper {
93109

94110
// input is like this: ssh://git@github.com:22/caprover/caprover-cli.git
95111
static getDomainFromSanitizedSshRepoPath(input: string) {
96-
input = input.substring(10)
97-
return input.substring(0, input.indexOf(':'))
112+
return GitHelper.sanitizeRepoPathSsh(input).domain
98113
}
99114

100115
// It returns a string like this "github.com/username/repository.git"
@@ -112,40 +127,22 @@ export default class GitHelper {
112127

113128
// It returns a string like this "ssh://git@github.com:22/caprover/caprover-cli.git"
114129
static sanitizeRepoPathSsh(input: string) {
115-
input = Utils.removeHttpHttps(input)
116-
if (!input.startsWith('git@')) {
117-
// If we get here, we have something like github.com/username/repository.git
118-
if (input.indexOf(':') < 0) {
119-
input = input.replace('/', ':')
120-
}
121-
input = `git@${input}`
122-
}
123-
124-
// At this point we have one of the following:
125-
// git@github.com:22/caprover/caprover
126-
// git@github.com:caprover/caprover
127-
128-
let port = '22'
129-
const split = input.split(':')
130-
if (split.length == 2) {
131-
const secondSplit = split[1].split('/')
132-
if (`${Number(secondSplit[0])}` === secondSplit[0]) {
133-
// input is already in this format: git@github.com:22/caprover/caprover
134-
port = `${Number(secondSplit[0])}`
135-
} else {
136-
input = `${split[0]}:22/${split[1]}`
137-
}
138-
} else {
130+
const found = input.match(GitHelper.#SSH_PATH_RE)
131+
if (!found) {
139132
throw new Error(`Malformatted SSH path: ${input}`)
140133
}
141134

142-
if (!input.toLowerCase().startsWith('ssh://')) {
143-
input = `ssh://${input}`
144-
}
145-
146135
return {
147-
repoPath: input.replace(/\/$/, ''),
148-
port: port,
136+
user: found.groups?.user ?? 'git',
137+
domain: found.groups?.domain,
138+
port: Number(found.groups?.port ?? 22),
139+
owner: found.groups?.owner ?? '',
140+
repo: found.groups?.repo,
141+
get repoPath() {
142+
return `ssh://${this.user}@${this.domain}:${this.port}/${
143+
this.owner
144+
}${this.owner && '/'}${this.repo}.git`
145+
},
149146
}
150147
}
151148
}

tests/GitHelper.test.ts

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@ test('Testing - sanitizeRepoPathSsh - port', () => {
2929
GitHelper.sanitizeRepoPathSsh(
3030
' git@github.com:username/repository.git/ '
3131
).port
32-
).toBe('22')
32+
).toBe(22)
3333
})
3434

3535
test('Testing - sanitizeRepoPathSsh - custom port', () => {
3636
expect(
3737
GitHelper.sanitizeRepoPathSsh(
3838
' git@github.com:1234/username/repository.git/ '
3939
).port
40-
).toBe('1234')
40+
).toBe(1234)
4141
})
4242

4343
test('Testing - sanitizeRepoPathSsh from HTTPS', () => {
@@ -48,6 +48,50 @@ test('Testing - sanitizeRepoPathSsh from HTTPS', () => {
4848
).toBe('ssh://git@github.com:22/username/repository.git')
4949
})
5050

51+
test('Testing - sanitizeRepoPathSsh - not git suffix', () => {
52+
expect(
53+
GitHelper.sanitizeRepoPathSsh(' github.com/owner/repository ').repoPath
54+
).toBe('ssh://git@github.com:22/owner/repository.git')
55+
})
56+
57+
test('Testing - sanitizeRepoPathSsh - alt domain', () => {
58+
expect(
59+
GitHelper.sanitizeRepoPathSsh(
60+
' git@git.alt-domain.com/owner/repository.git/ '
61+
).repoPath
62+
).toBe('ssh://git@git.alt-domain.com:22/owner/repository.git')
63+
})
64+
65+
test('Testing - sanitizeRepoPathSsh - alt user', () => {
66+
expect(
67+
GitHelper.sanitizeRepoPathSsh(
68+
' foobar@github.com/owner/repository.git/ '
69+
).repoPath
70+
).toBe('ssh://foobar@github.com:22/owner/repository.git')
71+
})
72+
73+
test('Testing - sanitizeRepoPathSsh - default user', () => {
74+
expect(
75+
GitHelper.sanitizeRepoPathSsh(' github.com/owner/repository.git/ ')
76+
.repoPath
77+
).toBe('ssh://git@github.com:22/owner/repository.git')
78+
})
79+
80+
test('Testing - sanitizeRepoPathSsh - no owner', () => {
81+
expect(
82+
GitHelper.sanitizeRepoPathSsh(' git@github.com:repository.git/ ')
83+
.repoPath
84+
).toBe('ssh://git@github.com:22/repository.git')
85+
})
86+
87+
test('Testing - sanitizeRepoPathSsh - invalid url', () => {
88+
expect(() =>
89+
GitHelper.sanitizeRepoPathSsh(
90+
' git:password@github.com/owner/repository.git/ '
91+
)
92+
).toThrow(Error)
93+
})
94+
5195
test('Testing - getDomainFromSanitizedSshRepoPath - pure', () => {
5296
expect(
5397
GitHelper.getDomainFromSanitizedSshRepoPath(
@@ -75,3 +119,11 @@ test('Testing - getDomainFromSanitizedSshRepoPath from HTTPS', () => {
75119
)
76120
).toBe('github.com')
77121
})
122+
123+
test('Testing - getDomainFromSanitizedSshRepoPath - alt domain', () => {
124+
expect(
125+
GitHelper.getDomainFromSanitizedSshRepoPath(
126+
' ssh://user@some.other-domain.com/owner/repository.git/ '
127+
)
128+
).toBe('some.other-domain.com')
129+
})

0 commit comments

Comments
 (0)