Comment on FF PRs that look good to merge#6435
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds an automated “looks good to merge” signal for forward-flow codeflow PRs by verifying that the VMR PR branch faithfully matches the source repo diff, then posting a PR comment when it does.
Changes:
- Introduces a
ICodeflowSourceDiffVerifierimplementation in DarcLib to compare source vs. VMR PR diffs for forward-flows. - Adds a new
CodeflowApprovalCheckwork item + processor in PCS DependencyFlow, scheduled after FF PR creation/update. - Extends/updates test coverage across PCS DependencyFlow tests and DarcLib codeflow tests to validate the new verification behavior.
Reviewed changes
Copilot reviewed 17 out of 17 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| test/ProductConstructionService/ProductConstructionService.ScenarioTests.Tests/TestHelpersTest.cs | Adds missing helper namespace import for scenario test helper usage. |
| test/ProductConstructionService/ProductConstructionService.DependencyFlow.Tests/UpdateAssetsForCodeFlowTests.cs | Updates expectations to include the new codeflow approval-check reminder. |
| test/ProductConstructionService/ProductConstructionService.DependencyFlow.Tests/PullRequestUpdaterTests.cs | Wires a mock ICodeflowSourceDiffVerifier into the DI container and adds a helper for asserting the new reminder. |
| test/Darc/Microsoft.DotNet.DarcLib.Tests/VirtualMonoRepo/CodeflowChangeAnalyzerTests.cs | Adds an import needed by updated VMR/codeflow-related test types. |
| test/Darc/Microsoft.DotNet.DarcLib.Codeflow.Tests/ForwardFlowTests.cs | Adds source-SHA capture + verification calls for forward-flow diffs. |
| test/Darc/Microsoft.DotNet.DarcLib.Codeflow.Tests/CodeFlowUpdatingPRsTests.cs | Validates source-diff verification behavior across PR-branch modifications and subsequent flows. |
| test/Darc/Microsoft.DotNet.DarcLib.Codeflow.Tests/CodeFlowTestsBase.cs | Adds a helper to run the same source-diff verification logic used by PCS. |
| test/Darc/Microsoft.DotNet.DarcLib.Codeflow.Tests/CodeflowSourceDiffVerifierTests.cs | New unit tests for the source-diff verifier (mocked git/VMR interactions). |
| src/ProductConstructionService/ProductConstructionService.DependencyFlow/WorkItems/CodeflowApprovalCheck.cs | New work item carrying the SHA range to verify for “looks good” commenting. |
| src/ProductConstructionService/ProductConstructionService.DependencyFlow/WorkItemProcessors/CodeflowApprovalCheckProcessor.cs | New processor that locates the subscription/updater and runs the approval check. |
| src/ProductConstructionService/ProductConstructionService.DependencyFlow/PullRequestUpdaters/CodeFlowPullRequestUpdater.cs | Schedules the new approval check reminder and implements the approval-check execution/commenting. |
| src/ProductConstructionService/ProductConstructionService.DependencyFlow/PullRequestStateManager.cs | Adds a Redis reminder manager to enqueue CodeflowApprovalCheck items. |
| src/ProductConstructionService/ProductConstructionService.DependencyFlow/IPullRequestStateManager.cs | Exposes a new API for scheduling the codeflow approval check. |
| src/ProductConstructionService/ProductConstructionService.DependencyFlow/DependencyFlowConfiguration.cs | Registers the new work item processor with DI. |
| src/Microsoft.DotNet.Darc/DarcLib/VirtualMonoRepo/CodeflowSourceDiffVerifier.cs | New verifier implementation that compares file sets and zero-context diffs. |
| src/Microsoft.DotNet.Darc/DarcLib/VirtualMonoRepo/CodeflowExtensions.cs | Registers ICodeflowSourceDiffVerifier in the codeflow DI setup. |
| arcade-services.slnx | Adds the ScenarioTests.Tests project to the solution. |
| if (matches) | ||
| { | ||
| await remote.CommentPullRequestAsync(pr.Url, "Looks good"); | ||
| } |
| inProgressPr.LastUpdate = DateTime.UtcNow; | ||
| await _stateManager.SetCheckReminderAsync(inProgressPr, pr, isCodeFlow: true); | ||
| await _stateManager.UnsetUpdateReminderAsync(isCodeFlow: true); | ||
| if (!skipCodeflowApprovalCheck && !string.IsNullOrEmpty(previousSourceSha)) |
There was a problem hiding this comment.
we should also check if this was a FF, will add
premun
left a comment
There was a problem hiding this comment.
Did you run this over some existing PRs to see the results? I am curious what would be the final behaviour
|
|
||
| var intersection = sourceRepoChangedFiles.Where(vmrPrChangedFiles.Contains).ToList(); | ||
| var sourceRepoOnlyChanges = sourceRepoChangedFiles.Where(f => !vmrPrChangedFiles.Contains(f)).ToList(); | ||
| var unexpectedFiles = vmrPrChangedFiles.Where(f => !sourceRepoChangedFiles.Contains(f)).ToList(); |
There was a problem hiding this comment.
I'd name this filesChangedInPrOnly then you might not need the comment below (btw this is always a good pointer to increase readability - to see if we can reflect purpose in variable names that can render a comment useless)
| HashSet<string> vmrPrChangedFiles = await GetChangedMappingFilesAsync( | ||
| vmr, mappingName, vmrTargetBranch, vmrHeadBranch, relativePath: srcMappingPrefix, cancellationToken: cancellationToken); | ||
|
|
||
| var intersection = sourceRepoChangedFiles.Where(vmrPrChangedFiles.Contains).ToList(); |
There was a problem hiding this comment.
I'd name intersection something better. Like filesChangedInBoth or something
| ILocalGitRepo sourceRepo, | ||
| ILocalGitRepo vmr, | ||
| string file, | ||
| string srcMappingPath, |
There was a problem hiding this comment.
srcMappingPath can be passed around as LocalPath and then you could have srcMappingPath / file instead of $"{srcMappingPath}/{file}".
Applies here and in other places
| } | ||
|
|
||
| public async Task SetCodeflowApprovalCheck(CodeflowApprovalCheck check) => | ||
| await _codeflowApprovalCheckReminders.SetReminderAsync(check, PullRequestUpdater.DefaultReminderDelay, true); |
There was a problem hiding this comment.
Are we sending it to the right queue? The codeflow workitem one
There was a problem hiding this comment.
yes, but it's missing the isCodeflow, will add so it's just not a naked true, my bad
I did yes. I ran it on some basic FFs that were supposed to pass the check maestro-auth-test/dotnet#259 |
| if (pr == null) | ||
| { | ||
| _logger.LogError("No in-progress PR found for codeflow approval check"); | ||
| return; |
There was a problem hiding this comment.
Would be nice to also store the PR url in the workitem and make sure it matches the tracked PR, to avoid any weird timing issues where the diff verifier runs on a PR that was just closed, and ends up commenting on a PR that was just opened
| "Skipping codeflow approval check for PR {prUrl} because it is no longer open (status: {status})", | ||
| pr.Url, | ||
| prInfo.Status); | ||
| return; |
There was a problem hiding this comment.
I don't think this gives any guarantee. If we don't want to trust the cached PR because its state could be out of date, maybe we should check only at the end before posting. or, never.
It's possible that a PR is closed or merged before the verifier can even run. IMO it can still be useful in that case for the verifier to post a comment on the closed PR - it can still alert you to a bad codeflow, or help in any investigations. I would just not care about the PR status
There was a problem hiding this comment.
this is getting info from GitHub/Azdo, not the cache
| return; | ||
| } | ||
|
|
||
| if (await _codeflowSourceDiffVerifier.ForwardFlowMatchesSourceDiffAsync( |
There was a problem hiding this comment.
nit: can this method call be taken out of the if and have its own var?
What's the expected action when the check fails? Should it post a comment about the failure, or should it just skip posting the approval and do nothing? |
nothing, this will eventually be an approval on the pr itself, the comment is there just temporarily |
| _logger.LogInformation( | ||
| "Codeflow approval check for PR {prUrl} passed; posting approval comment", | ||
| pr.Url); | ||
| await remote.CommentPullRequestAsync(pr.Url, "Looks good"); |
There was a problem hiding this comment.
Should this include build id, SHA, or some other information that can associate the comment with a specific codeflow, for PRs that flow multiple times and get multiple automatic checks?
There was a problem hiding this comment.
right now we don't have this information in this WorkItem, we'd have to provide it from the trigger.
But it might not be that useful too, you can get this info in a different way, so I guess it'd be a matter of convenience
#6142
The check has two layers.
First we do a
--name-onlydiff, where we check if the PR changed any files the source repo didn't. If it did, we don't give a go ahead.If the there are no PR only changed files, we do the second phase where we diffs the source repo diff and the PR diff with
-U0and then compare them line by line if they match.Last, if there's any files the source repo changed that don't appear in the VMR, we check if the VMR is already in the desired target state. If it is, we say it's good