diff --git a/tools/azsdk-cli/Azure.Sdk.Tools.Cli.Tests/Mocks/Services/MockDevOpsService.cs b/tools/azsdk-cli/Azure.Sdk.Tools.Cli.Tests/Mocks/Services/MockDevOpsService.cs index d584ff9e6d2..6b8510256c9 100644 --- a/tools/azsdk-cli/Azure.Sdk.Tools.Cli.Tests/Mocks/Services/MockDevOpsService.cs +++ b/tools/azsdk-cli/Azure.Sdk.Tools.Cli.Tests/Mocks/Services/MockDevOpsService.cs @@ -13,7 +13,7 @@ public Task GetPackageWorkItemAsync(string packageName, string throw new NotImplementedException(); } - public Task RunPipelineAsync(int pipelineDefinitionId, Dictionary templateParams, string branchRef = "main") + public Task RunPipelineAsync(int pipelineDefinitionId, Dictionary templateParams, string apiSpecBranchRef = "main") { return Task.FromResult(new Build { @@ -97,7 +97,7 @@ Task IDevOpsService.LinkNamespaceApprovalIssueAsync(int releasePlanWorkIte return Task.FromResult(true); } - Task IDevOpsService.RunSDKGenerationPipelineAsync(string branchRef, string typespecProjectRoot, string apiVersion, string sdkReleaseType, string language, int workItemId) + Task IDevOpsService.RunSDKGenerationPipelineAsync(string apiSpecBranchRef, string typespecProjectRoot, string apiVersion, string sdkReleaseType, string language, int workItemId, string sdkRepoBranch) { throw new NotImplementedException(); } diff --git a/tools/azsdk-cli/Azure.Sdk.Tools.Cli.Tests/Tools/SpecWorkFlowToolTests.cs b/tools/azsdk-cli/Azure.Sdk.Tools.Cli.Tests/Tools/SpecWorkFlowToolTests.cs index e44cb9faf93..3969d65c7e0 100644 --- a/tools/azsdk-cli/Azure.Sdk.Tools.Cli.Tests/Tools/SpecWorkFlowToolTests.cs +++ b/tools/azsdk-cli/Azure.Sdk.Tools.Cli.Tests/Tools/SpecWorkFlowToolTests.cs @@ -193,7 +193,7 @@ public async Task GenerateSdk_Uses_WorkItemApi() .ReturnsAsync( new Octokit.PullRequest(123, null, null, null, null, null, null, null, 123, ItemState.Open, null, null, DateTimeOffset.Now, DateTimeOffset.Now, DateTimeOffset.Now, null, null, null, null, null, null, false, null, null, null, null, 0, 1, 1, 1, 1, null, false, null, null, null, labels, null)); - mockDevOpsService.Setup(x => x.RunSDKGenerationPipelineAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + mockDevOpsService.Setup(x => x.RunSDKGenerationPipelineAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(new Build() { Id = 100, @@ -208,6 +208,7 @@ public async Task GenerateSdk_Uses_WorkItemApi() pullRequestNumber: 123, workItemId: 456 ); + Assert.That(result.ToString(), Does.Contain("Azure DevOps pipeline https://dev.azure.com/azure-sdk/internal/_build/results?buildId=100 has been initiated to generate the SDK. Build ID is 100")); } @@ -219,7 +220,7 @@ public async Task GenerateSdk_Without_pr_and_workitem() mockTypeSpecHelper.Setup(x => x.IsValidTypeSpecProjectPath(It.IsAny())) .Returns(true); - mockDevOpsService.Setup(x => x.RunSDKGenerationPipelineAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + mockDevOpsService.Setup(x => x.RunSDKGenerationPipelineAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(new Build() { Id = 100, @@ -243,7 +244,7 @@ public async Task GenerateSdk_With_pr_and_no_workitem() mockTypeSpecHelper.Setup(x => x.IsValidTypeSpecProjectPath(It.IsAny())) .Returns(true); - mockDevOpsService.Setup(x => x.RunSDKGenerationPipelineAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) + mockDevOpsService.Setup(x => x.RunSDKGenerationPipelineAsync(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) .ReturnsAsync(new Build() { Id = 100, diff --git a/tools/azsdk-cli/Azure.Sdk.Tools.Cli/Services/DevOpsService.cs b/tools/azsdk-cli/Azure.Sdk.Tools.Cli/Services/DevOpsService.cs index 0fd502d456c..951925d85c1 100644 --- a/tools/azsdk-cli/Azure.Sdk.Tools.Cli/Services/DevOpsService.cs +++ b/tools/azsdk-cli/Azure.Sdk.Tools.Cli/Services/DevOpsService.cs @@ -89,7 +89,7 @@ public interface IDevOpsService public Task GetReleasePlanForWorkItemAsync(int workItemId); public Task GetReleasePlanAsync(string pullRequestUrl); public Task CreateReleasePlanWorkItemAsync(ReleasePlanDetails releasePlan); - public Task RunSDKGenerationPipelineAsync(string branchRef, string typespecProjectRoot, string apiVersion, string sdkReleaseType, string language, int workItemId); + public Task RunSDKGenerationPipelineAsync(string apiSpecBranchRef, string typespecProjectRoot, string apiVersion, string sdkReleaseType, string language, int workItemId, string sdkRepoBranch = ""); public Task GetPipelineRunAsync(int buildId); public Task GetSDKPullRequestFromPipelineRunAsync(int buildId, string language, int workItemId); public Task AddSdkInfoInReleasePlanAsync(int workItemId, string language, string sdkGenerationPipelineUrl, string sdkPullRequestUrl); @@ -98,7 +98,7 @@ public interface IDevOpsService public Task UpdateSpecPullRequestAsync(int releasePlanWorkItemId, string specPullRequest); public Task LinkNamespaceApprovalIssueAsync(int releasePlanWorkItemId, string url); public Task GetPackageWorkItemAsync(string packageName, string language, string packageVersion = ""); - public Task RunPipelineAsync(int pipelineDefinitionId, Dictionary templateParams, string branchRef = "main"); + public Task RunPipelineAsync(int pipelineDefinitionId, Dictionary templateParams, string apiSpecBranchRef = "main"); public Task>> GetPipelineLlmArtifacts(string project, int buildId); } @@ -540,7 +540,7 @@ public static bool IsSDKGenerationSupported(string language) }; } - public async Task RunSDKGenerationPipelineAsync(string branchRef, string typespecProjectRoot, string apiVersion, string sdkReleaseType, string language, int workItemId) + public async Task RunSDKGenerationPipelineAsync(string apiSpecBranchRef, string typespecProjectRoot, string apiVersion, string sdkReleaseType, string language, int workItemId, string sdkRepoBranch = "") { int pipelineDefinitionId = GetPipelineDefinitionId(language); if (pipelineDefinitionId == 0) @@ -550,6 +550,7 @@ public async Task RunSDKGenerationPipelineAsync(string branchRef, string var templateParams = new Dictionary { + { "SdkRepoBranch", sdkRepoBranch}, { "ConfigType", "TypeSpec"}, { "ConfigPath", $"{typespecProjectRoot}/tspconfig.yaml" }, { "ApiVersion", apiVersion }, @@ -557,7 +558,7 @@ public async Task RunSDKGenerationPipelineAsync(string branchRef, string { "CreatePullRequest", "true" }, { "ReleasePlanWorkItemId", $"{workItemId}"} }; - var build = await RunPipelineAsync(pipelineDefinitionId, templateParams, branchRef); + var build = await RunPipelineAsync(pipelineDefinitionId, templateParams, apiSpecBranchRef); var pipelineRunUrl = GetPipelineUrl(build.Id); logger.LogInformation($"Started pipeline run {pipelineRunUrl} to generate SDK."); if (workItemId != 0) @@ -569,7 +570,7 @@ public async Task RunSDKGenerationPipelineAsync(string branchRef, string return build; } - public async Task RunPipelineAsync(int pipelineDefinitionId, Dictionary templateParams, string branchRef = "main") + public async Task RunPipelineAsync(int pipelineDefinitionId, Dictionary templateParams, string apiSpecBranchRef = "main") { if (pipelineDefinitionId == 0) { @@ -587,7 +588,7 @@ public async Task RunPipelineAsync(int pipelineDefinitionId, Dictionary RunGenerateSdkAsync(string typespecProjec } string typeSpecProjectPath = typespecHelper.GetTypeSpecProjectRelativePath(typespecProjectRoot); - string branchRef = "main"; + string apiSpecBranchRef = "main"; if (pullRequestNumber > 0) { var pullRequest = await githubService.GetPullRequestAsync(REPO_OWNER, PUBLIC_SPECS_REPO, pullRequestNumber); - branchRef = (pullRequest?.Merged ?? false) ? pullRequest.Base.Ref : $"refs/pull/{pullRequestNumber}/merge"; + apiSpecBranchRef = (pullRequest?.Merged ?? false) ? pullRequest.Base.Ref : $"refs/pull/{pullRequestNumber}/merge"; } + + string sdkRepoBranch = ""; + var releasePlan = workItemId != 0 ? await devopsService.GetReleasePlanForWorkItemAsync(workItemId) : null; + var sdkPullRequestUrl = releasePlan?.SDKInfo.FirstOrDefault(s => s.Language == language)?.SdkPullRequestUrl; + if (!string.IsNullOrEmpty(sdkPullRequestUrl)) + { + var parsedUrl = DevOpsService.ParseSDKPullRequestUrl(sdkPullRequestUrl); + var sdkPullRequest = await githubService.GetPullRequestAsync(parsedUrl.RepoOwner, parsedUrl.RepoName, parsedUrl.PrNumber); + if (sdkPullRequest is not null && sdkPullRequest.State != "closed" && sdkPullRequest.Merged == false) + { + sdkRepoBranch = sdkPullRequest.Head.Ref; + } + } + logger.LogInformation("Running SDK generation pipeline"); - var pipelineRun = await devopsService.RunSDKGenerationPipelineAsync(branchRef, typeSpecProjectPath, apiVersion, sdkReleaseType, language, workItemId); + var pipelineRun = await devopsService.RunSDKGenerationPipelineAsync(apiSpecBranchRef, typeSpecProjectPath, apiVersion, sdkReleaseType, language, workItemId, sdkRepoBranch); response = new SDKWorkflowResponse() { Status = "Success",