Skip to content

Commit d213c5c

Browse files
committed
Update azure git provider to work with self hosted server
Applying the same logic as github and gitlab git-provider in the azure provider. The provider will accept if the ProviderName 'azure' is part of the hostname.
1 parent 5f4832a commit d213c5c

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

internal/gitprovider/azure/azure.go

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ func NewProvider(
7979
}
8080

8181
// CreatePullRequest implements gitprovider.Interface.
82+
const errConvertPullRequestFmt = "error converting pull request %d: %w"
83+
8284
func (p *provider) CreatePullRequest(
8385
ctx context.Context,
8486
opts *gitprovider.CreatePullRequestOpts,
@@ -119,7 +121,7 @@ func (p *provider) CreatePullRequest(
119121
}
120122
pr, err := convertADOPullRequest(adoPR)
121123
if err != nil {
122-
return nil, fmt.Errorf("error converting pull request %d: %w", adoPR.PullRequestId, err)
124+
return nil, fmt.Errorf(errConvertPullRequestFmt, adoPR.PullRequestId, err)
123125
}
124126
return pr, nil
125127
}
@@ -143,7 +145,7 @@ func (p *provider) GetPullRequest(
143145
}
144146
pr, err := convertADOPullRequest(adoPR)
145147
if err != nil {
146-
return nil, fmt.Errorf("error converting pull request %d: %w", id, err)
148+
return nil, fmt.Errorf(errConvertPullRequestFmt, id, err)
147149
}
148150
return pr, nil
149151
}
@@ -174,7 +176,7 @@ func (p *provider) ListPullRequests(
174176
for _, adoPR := range *adoPRs {
175177
pr, err := convertADOPullRequest(&adoPR)
176178
if err != nil {
177-
return nil, fmt.Errorf("error converting pull request %d: %w", adoPR.PullRequestId, err)
179+
return nil, fmt.Errorf(errConvertPullRequestFmt, adoPR.PullRequestId, err)
178180
}
179181
pts = append(pts, *pr)
180182
}
@@ -218,15 +220,19 @@ func parseRepoURL(repoURL string) (string, string, string, error) {
218220
return parseModernRepoURL(u)
219221
} else if strings.HasSuffix(u.Host, legacyHostSuffix) {
220222
return parseLegacyRepoURL(u)
223+
} else if strings.Contains(u.Host, ProviderName) {
224+
return parseSelfHostedRepoUrl(u)
221225
}
222226
return "", "", "", fmt.Errorf("unsupported host %q", u.Host)
223227
}
224228

229+
const errExtractRepoInfoFmt = "could not extract repository organization, project, and name from URL %q"
230+
225231
// parseModernRepoURL parses a modern Azure DevOps repository URL.
226232
func parseModernRepoURL(u *url.URL) (string, string, string, error) {
227233
parts := strings.Split(u.Path, "/")
228234
if len(parts) != 5 {
229-
return "", "", "", fmt.Errorf("could not extract repository organization, project, and name from URL %q", u)
235+
return "", "", "", fmt.Errorf(errExtractRepoInfoFmt, u)
230236
}
231237
return parts[1], parts[2], parts[4], nil
232238
}
@@ -236,7 +242,21 @@ func parseLegacyRepoURL(u *url.URL) (string, string, string, error) {
236242
organization := strings.TrimSuffix(u.Host, ".visualstudio.com")
237243
parts := strings.Split(u.Path, "/")
238244
if len(parts) != 4 {
239-
return "", "", "", fmt.Errorf("could not extract repository organization, project, and name from URL %q", u)
245+
return "", "", "", fmt.Errorf(errExtractRepoInfoFmt, u)
240246
}
241247
return organization, parts[1], parts[3], nil
242248
}
249+
250+
// parseSelfHostedRepoUrl parses a self hosted Azure DevOps Server URL.
251+
func parseSelfHostedRepoUrl(u *url.URL) (string, string, string, error) {
252+
parts := strings.Split(u.Path, "/")
253+
// Handle the case where the URL is in the format https://<host>/<collection>/<project>/_git/<repo>
254+
if len(parts) == 5 {
255+
return parts[1], parts[2], parts[4], nil
256+
}
257+
// Handle the case where the URL is in the format https://<host>/tfs/<collection>/<project>/_git/<repo>
258+
if len(parts) == 6 && parts[1] == "tfs" {
259+
return parts[2], parts[3], parts[5], nil
260+
}
261+
return "", "", "", fmt.Errorf(errExtractRepoInfoFmt, u)
262+
}

internal/gitprovider/azure/azure_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,38 @@ func TestParseRepoURL(t *testing.T) {
7575
expectedRepo: "my.repo",
7676
errExpected: false,
7777
},
78+
{
79+
name: "self hosted URL format with missing parts",
80+
url: "https://azure.mycompany.org/mycollection/myproject",
81+
expectedOrg: "mycollection",
82+
expectedProj: "myproject",
83+
expectedRepo: "myrepo",
84+
errExpected: true,
85+
},
86+
{
87+
name: "self hosted URL format with unsupported path segment /foo",
88+
url: "https://azure.mycompany.org/foo/mycollection/myproject/_git/myrepo",
89+
expectedOrg: "mycollection",
90+
expectedProj: "myproject",
91+
expectedRepo: "myrepo",
92+
errExpected: true,
93+
},
94+
{
95+
name: "self hosted URL format with 5 parts",
96+
url: "https://azure.mycompany.org/mycollection/myproject/_git/myrepo",
97+
expectedOrg: "mycollection",
98+
expectedProj: "myproject",
99+
expectedRepo: "myrepo",
100+
errExpected: false,
101+
},
102+
{
103+
name: "self hosted URL format with 6 parts",
104+
url: "https://azure.mycompany.org/tfs/mycollection/myproject/_git/myrepo",
105+
expectedOrg: "mycollection",
106+
expectedProj: "myproject",
107+
expectedRepo: "myrepo",
108+
errExpected: false,
109+
},
78110
}
79111

80112
for _, tc := range testCases {

0 commit comments

Comments
 (0)