Skip to content

Commit 6062de6

Browse files
authored
Merge pull request #1366 from markphip/issue-1365
Add support for `--target-api-url` to `rewire-pipeline` command
2 parents a51bfe1 + 7b42179 commit 6062de6

File tree

7 files changed

+151
-10
lines changed

7 files changed

+151
-10
lines changed

src/Octoshift/Services/AdoApi.cs

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -533,34 +533,59 @@ public virtual async Task ShareServiceConnection(string adoOrg, string adoTeamPr
533533
return (defaultBranch, clean, checkoutSubmodules);
534534
}
535535

536-
public virtual async Task ChangePipelineRepo(string adoOrg, string teamProject, int pipelineId, string defaultBranch, string clean, string checkoutSubmodules, string githubOrg, string githubRepo, string connectedServiceId)
536+
public virtual async Task ChangePipelineRepo(string adoOrg, string teamProject, int pipelineId, string defaultBranch, string clean, string checkoutSubmodules, string githubOrg, string githubRepo, string connectedServiceId, string targetApiUrl = null)
537537
{
538538
var url = $"{_adoBaseUrl}/{adoOrg.EscapeDataString()}/{teamProject.EscapeDataString()}/_apis/build/definitions/{pipelineId}?api-version=6.0";
539539

540540
var response = await _client.GetAsync(url);
541541
var data = JObject.Parse(response);
542542

543+
// Determine base URLs
544+
string apiUrl, webUrl, cloneUrl, branchesUrl, refsUrl, manageUrl;
545+
if (targetApiUrl.HasValue())
546+
{
547+
var apiUri = new Uri(targetApiUrl.TrimEnd('/'));
548+
var webHost = apiUri.Host.StartsWith("api.") ? apiUri.Host[4..] : apiUri.Host;
549+
var webScheme = apiUri.Scheme;
550+
var webBase = $"{webScheme}://{webHost}";
551+
apiUrl = $"{targetApiUrl.TrimEnd('/')}/repos/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}";
552+
webUrl = $"{webBase}/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}";
553+
cloneUrl = $"{webBase}/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}.git";
554+
branchesUrl = $"{targetApiUrl.TrimEnd('/')}/repos/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}/branches";
555+
refsUrl = $"{targetApiUrl.TrimEnd('/')}/repos/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}/git/refs";
556+
manageUrl = webUrl;
557+
}
558+
else
559+
{
560+
apiUrl = $"https://api.github.com/repos/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}";
561+
webUrl = $"https://github.com/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}";
562+
cloneUrl = $"https://github.com/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}.git";
563+
branchesUrl = $"https://api.github.com/repos/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}/branches";
564+
refsUrl = $"https://api.github.com/repos/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}/git/refs";
565+
manageUrl = webUrl;
566+
}
567+
543568
var newRepo = new
544569
{
545570
properties = new
546571
{
547-
apiUrl = $"https://api.github.com/repos/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}",
548-
branchesUrl = $"https://api.github.com/repos/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}/branches",
549-
cloneUrl = $"https://github.com/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}.git",
572+
apiUrl,
573+
branchesUrl,
574+
cloneUrl,
550575
connectedServiceId,
551576
defaultBranch,
552577
fullName = $"{githubOrg}/{githubRepo}",
553-
manageUrl = $"https://github.com/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}",
578+
manageUrl,
554579
orgName = githubOrg,
555-
refsUrl = $"https://api.github.com/repos/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}/git/refs",
580+
refsUrl,
556581
safeRepository = $"{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}",
557582
shortName = githubRepo,
558583
reportBuildStatus = true
559584
},
560585
id = $"{githubOrg}/{githubRepo}",
561586
type = "GitHub",
562587
name = $"{githubOrg}/{githubRepo}",
563-
url = $"https://github.com/{githubOrg.EscapeDataString()}/{githubRepo.EscapeDataString()}.git",
588+
url = cloneUrl,
564589
defaultBranch,
565590
clean,
566591
checkoutSubmodules

src/OctoshiftCLI.Tests/Octoshift/Services/AdoApiTests.cs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,6 +1022,88 @@ public async Task ChangePipelineRepo_Should_Send_Correct_Payload()
10221022
_mockAdoClient.Verify(m => m.PutAsync(endpoint, It.Is<object>(y => y.ToJson() == newJson.ToJson())));
10231023
}
10241024

1025+
[Fact]
1026+
public async Task ChangePipelineRepo_Should_Send_Correct_Payload_With_TargetApiUrl()
1027+
{
1028+
var githubRepo = "foo-repo";
1029+
var serviceConnectionId = Guid.NewGuid().ToString();
1030+
var defaultBranch = "foo-branch";
1031+
var pipelineId = 123;
1032+
var clean = "true";
1033+
var checkoutSubmodules = "false";
1034+
var targetApiUrl = "https://custom.api.githubenterprise.com";
1035+
1036+
var oldJson = new
1037+
{
1038+
something = "foo",
1039+
somethingElse = new
1040+
{
1041+
blah = "foo",
1042+
repository = "blah"
1043+
},
1044+
repository = new
1045+
{
1046+
testing = true,
1047+
moreTesting = default(string)
1048+
},
1049+
oneLastThing = false
1050+
};
1051+
1052+
var endpoint = $"https://dev.azure.com/{ADO_ORG.EscapeDataString()}/{ADO_TEAM_PROJECT.EscapeDataString()}/_apis/build/definitions/{pipelineId}?api-version=6.0";
1053+
1054+
var apiUri = new Uri(targetApiUrl.TrimEnd('/'));
1055+
var webHost = apiUri.Host.StartsWith("api.") ? apiUri.Host[4..] : apiUri.Host;
1056+
var webScheme = apiUri.Scheme;
1057+
var webBase = $"{webScheme}://{webHost}";
1058+
var apiUrl = $"{targetApiUrl.TrimEnd('/')}/repos/{GITHUB_ORG}/{githubRepo}";
1059+
var webUrl = $"{webBase}/{GITHUB_ORG}/{githubRepo}";
1060+
var cloneUrl = $"{webBase}/{GITHUB_ORG}/{githubRepo}.git";
1061+
var branchesUrl = $"{targetApiUrl.TrimEnd('/')}/repos/{GITHUB_ORG}/{githubRepo}/branches";
1062+
var refsUrl = $"{targetApiUrl.TrimEnd('/')}/repos/{GITHUB_ORG}/{githubRepo}/git/refs";
1063+
var manageUrl = webUrl;
1064+
1065+
var newJson = new
1066+
{
1067+
something = "foo",
1068+
somethingElse = new
1069+
{
1070+
blah = "foo",
1071+
repository = "blah"
1072+
},
1073+
repository = new
1074+
{
1075+
properties = new
1076+
{
1077+
apiUrl,
1078+
branchesUrl,
1079+
cloneUrl,
1080+
connectedServiceId = serviceConnectionId,
1081+
defaultBranch,
1082+
fullName = $"{GITHUB_ORG}/{githubRepo}",
1083+
manageUrl,
1084+
orgName = GITHUB_ORG,
1085+
refsUrl,
1086+
safeRepository = $"{GITHUB_ORG}/{githubRepo}",
1087+
shortName = githubRepo,
1088+
reportBuildStatus = true
1089+
},
1090+
id = $"{GITHUB_ORG}/{githubRepo}",
1091+
type = "GitHub",
1092+
name = $"{GITHUB_ORG}/{githubRepo}",
1093+
url = cloneUrl,
1094+
defaultBranch,
1095+
clean,
1096+
checkoutSubmodules
1097+
},
1098+
oneLastThing = false
1099+
};
1100+
1101+
_mockAdoClient.Setup(m => m.GetAsync(endpoint).Result).Returns(oldJson.ToJson());
1102+
await sut.ChangePipelineRepo(ADO_ORG, ADO_TEAM_PROJECT, pipelineId, defaultBranch, clean, checkoutSubmodules, GITHUB_ORG, githubRepo, serviceConnectionId, targetApiUrl);
1103+
1104+
_mockAdoClient.Verify(m => m.PutAsync(endpoint, It.Is<object>(y => y.ToJson() == newJson.ToJson())));
1105+
}
1106+
10251107
[Fact]
10261108
public async Task GetBoardsGithubRepoId_Should_Return_RepoId()
10271109
{

src/OctoshiftCLI.Tests/ado2gh/Commands/RewirePipeline/RewirePipelineCommandHandlerTests.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,33 @@ public async Task Happy_Path()
4848
};
4949
await _handler.Handle(args);
5050

51-
_mockAdoApi.Verify(x => x.ChangePipelineRepo(ADO_ORG, ADO_TEAM_PROJECT, pipelineId, defaultBranch, clean, checkoutSubmodules, GITHUB_ORG, GITHUB_REPO, SERVICE_CONNECTION_ID));
51+
_mockAdoApi.Verify(x => x.ChangePipelineRepo(ADO_ORG, ADO_TEAM_PROJECT, pipelineId, defaultBranch, clean, checkoutSubmodules, GITHUB_ORG, GITHUB_REPO, SERVICE_CONNECTION_ID, null));
52+
}
53+
54+
[Fact]
55+
public async Task Uses_TargetApiUrl_When_Provided()
56+
{
57+
var pipelineId = 1234;
58+
var defaultBranch = "default-branch";
59+
var clean = "true";
60+
var checkoutSubmodules = "null";
61+
var targetApiUrl = "https://api.ghec.example.com";
62+
63+
_mockAdoApi.Setup(x => x.GetPipelineId(ADO_ORG, ADO_TEAM_PROJECT, ADO_PIPELINE).Result).Returns(pipelineId);
64+
_mockAdoApi.Setup(x => x.GetPipeline(ADO_ORG, ADO_TEAM_PROJECT, pipelineId).Result).Returns((defaultBranch, clean, checkoutSubmodules));
65+
66+
var args = new RewirePipelineCommandArgs
67+
{
68+
AdoOrg = ADO_ORG,
69+
AdoTeamProject = ADO_TEAM_PROJECT,
70+
AdoPipeline = ADO_PIPELINE,
71+
GithubOrg = GITHUB_ORG,
72+
GithubRepo = GITHUB_REPO,
73+
ServiceConnectionId = SERVICE_CONNECTION_ID,
74+
TargetApiUrl = targetApiUrl
75+
};
76+
await _handler.Handle(args);
77+
78+
_mockAdoApi.Verify(x => x.ChangePipelineRepo(ADO_ORG, ADO_TEAM_PROJECT, pipelineId, defaultBranch, clean, checkoutSubmodules, GITHUB_ORG, GITHUB_REPO, SERVICE_CONNECTION_ID, targetApiUrl));
5279
}
5380
}

src/OctoshiftCLI.Tests/ado2gh/Commands/RewirePipeline/RewirePipelineCommandTests.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public void Should_Have_Options()
3131
{
3232
Assert.NotNull(_command);
3333
Assert.Equal("rewire-pipeline", _command.Name);
34-
Assert.Equal(8, _command.Options.Count);
34+
Assert.Equal(9, _command.Options.Count);
3535

3636
TestHelpers.VerifyCommandOption(_command.Options, "ado-org", true);
3737
TestHelpers.VerifyCommandOption(_command.Options, "ado-team-project", true);
@@ -41,6 +41,7 @@ public void Should_Have_Options()
4141
TestHelpers.VerifyCommandOption(_command.Options, "service-connection-id", true);
4242
TestHelpers.VerifyCommandOption(_command.Options, "ado-pat", false);
4343
TestHelpers.VerifyCommandOption(_command.Options, "verbose", false);
44+
TestHelpers.VerifyCommandOption(_command.Options, "target-api-url", false);
4445
}
4546

4647
[Fact]

src/ado2gh/Commands/RewirePipeline/RewirePipelineCommand.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ public RewirePipelineCommand() : base(
2323
AddOption(ServiceConnectionId);
2424
AddOption(AdoPat);
2525
AddOption(Verbose);
26+
AddOption(TargetApiUrl);
2627
}
2728

2829
public Option<string> AdoOrg { get; } = new("--ado-org")
@@ -52,6 +53,10 @@ public RewirePipelineCommand() : base(
5253
};
5354
public Option<string> AdoPat { get; } = new("--ado-pat");
5455
public Option<bool> Verbose { get; } = new("--verbose");
56+
public Option<string> TargetApiUrl { get; } = new("--target-api-url")
57+
{
58+
Description = "The URL of the target API, if not migrating to github.com. Defaults to https://api.github.com"
59+
};
5560

5661
public override RewirePipelineCommandHandler BuildHandler(RewirePipelineCommandArgs args, IServiceProvider sp)
5762
{

src/ado2gh/Commands/RewirePipeline/RewirePipelineCommandArgs.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@ public class RewirePipelineCommandArgs : CommandArgs
1212
public string ServiceConnectionId { get; set; }
1313
[Secret]
1414
public string AdoPat { get; set; }
15+
public string TargetApiUrl { get; set; }
1516
}
1617
}

src/ado2gh/Commands/RewirePipeline/RewirePipelineCommandHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public async Task Handle(RewirePipelineCommandArgs args)
2727

2828
var adoPipelineId = await _adoApi.GetPipelineId(args.AdoOrg, args.AdoTeamProject, args.AdoPipeline);
2929
var (defaultBranch, clean, checkoutSubmodules) = await _adoApi.GetPipeline(args.AdoOrg, args.AdoTeamProject, adoPipelineId);
30-
await _adoApi.ChangePipelineRepo(args.AdoOrg, args.AdoTeamProject, adoPipelineId, defaultBranch, clean, checkoutSubmodules, args.GithubOrg, args.GithubRepo, args.ServiceConnectionId);
30+
await _adoApi.ChangePipelineRepo(args.AdoOrg, args.AdoTeamProject, adoPipelineId, defaultBranch, clean, checkoutSubmodules, args.GithubOrg, args.GithubRepo, args.ServiceConnectionId, args.TargetApiUrl);
3131

3232
_log.LogSuccess("Successfully rewired pipeline");
3333
}

0 commit comments

Comments
 (0)