From f1175458d415eb5b6141703e8c137ea7a9933ddf Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 11 Apr 2026 02:11:32 +0000 Subject: [PATCH] Fix ADO PR mapping: use lastMergeCommit nested object instead of flat mergeCommitId The Azure DevOps GitPullRequest API returns lastMergeCommit as a nested GitCommitRef object (with commitId), not as a flat mergeCommitId string. The previous code deserialized a non-existent mergeCommitId field, which always returned null from real API calls, breaking commit-to-PR mapping for all merge strategies (including squash merges). - Add AzureDevOpsGitCommitRef record to model the nested commit reference - Change AzureDevOpsPullRequest to deserialize LastMergeCommit (nested object) - Add convenience MergeCommitId property to minimize downstream changes - Update mock handler to emit lastMergeCommit: { commitId: ... } format Agent-Logs-Url: https://github.com/demaconsulting/BuildMark/sessions/18090e6e-03fe-4772-8b1e-8e8c33c87fdb Co-authored-by: Malcolmnixon <1863707+Malcolmnixon@users.noreply.github.com> --- .../AzureDevOps/AzureDevOpsApiTypes.cs | 22 ++++++++++++++++--- .../MockAzureDevOpsHttpMessageHandler.cs | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/DemaConsulting.BuildMark/RepoConnectors/AzureDevOps/AzureDevOpsApiTypes.cs b/src/DemaConsulting.BuildMark/RepoConnectors/AzureDevOps/AzureDevOpsApiTypes.cs index 5d1ae90..9e94cee 100644 --- a/src/DemaConsulting.BuildMark/RepoConnectors/AzureDevOps/AzureDevOpsApiTypes.cs +++ b/src/DemaConsulting.BuildMark/RepoConnectors/AzureDevOps/AzureDevOpsApiTypes.cs @@ -40,6 +40,13 @@ internal sealed record AzureDevOpsCommit( string CommitId, string Comment); +/// +/// Minimal Git commit reference containing only the commit SHA. +/// +/// Full commit SHA hash. +internal sealed record AzureDevOpsGitCommitRef( + string CommitId); + /// /// Pull request data returned by the Azure DevOps pull requests endpoint. /// @@ -47,7 +54,10 @@ internal sealed record AzureDevOpsCommit( /// Pull request title. /// Pull request web URL. /// Pull request status (active, completed, abandoned). -/// Merge commit SHA when completed, null otherwise. +/// +/// The commit of the most recent pull request merge. Null when the merge is in progress or was unsuccessful. +/// This field is populated for all merge strategies (no-fast-forward, squash, rebase, rebase-merge). +/// /// Source branch reference name. /// Pull request description body. internal sealed record AzureDevOpsPullRequest( @@ -55,9 +65,15 @@ internal sealed record AzureDevOpsPullRequest( string Title, string? Url, string Status, - string? MergeCommitId, + AzureDevOpsGitCommitRef? LastMergeCommit, string? SourceRefName, - string? Description); + string? Description) +{ + /// + /// Gets the merge commit SHA from the last merge commit reference, or null if not available. + /// + public string? MergeCommitId => LastMergeCommit?.CommitId; +} /// /// Work item data returned by the Azure DevOps work items endpoint with all fields expanded. diff --git a/test/DemaConsulting.BuildMark.Tests/RepoConnectors/AzureDevOps/MockAzureDevOpsHttpMessageHandler.cs b/test/DemaConsulting.BuildMark.Tests/RepoConnectors/AzureDevOps/MockAzureDevOpsHttpMessageHandler.cs index 6473111..ae0b11a 100644 --- a/test/DemaConsulting.BuildMark.Tests/RepoConnectors/AzureDevOps/MockAzureDevOpsHttpMessageHandler.cs +++ b/test/DemaConsulting.BuildMark.Tests/RepoConnectors/AzureDevOps/MockAzureDevOpsHttpMessageHandler.cs @@ -172,7 +172,7 @@ public MockAzureDevOpsHttpMessageHandler AddPullRequestsResponse(params MockAdoP title = pr.Title, url = $"https://dev.azure.com/org/project/_git/repo/pullrequest/{pr.PullRequestId}", status = pr.Status, - mergeCommitId = pr.MergeCommitId, + lastMergeCommit = pr.MergeCommitId != null ? new { commitId = pr.MergeCommitId } : null, sourceRefName = "refs/heads/feature", description = pr.Description });