Skip to content

Commit deb6996

Browse files
[Rollout] Production rollout 2025-04-02 (#4615)
<!-- Link the GitHub or AzDO issue this pull request is associated with. Please copy and paste the full URL rather than using the dotnet/arcade-services# syntax --> Rollout issue: #4614
2 parents 553d7c3 + 34f8361 commit deb6996

File tree

72 files changed

+2077
-306
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

72 files changed

+2077
-306
lines changed

arcade-services.sln

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProductConstructionService.
9696
EndProject
9797
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FlatFlowMigrationCli", "tools\FlatFlowMigrationCli\FlatFlowMigrationCli.csproj", "{89DF188B-B1FC-D3C4-A76E-019144ABA9CB}"
9898
EndProject
99+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tools.Common", "tools\Tools.Common\Tools.Common.csproj", "{977060F4-EEEF-420D-02E8-5E58D3E51942}"
100+
EndProject
99101
Global
100102
GlobalSection(SolutionConfigurationPlatforms) = preSolution
101103
Debug|Any CPU = Debug|Any CPU
@@ -514,6 +516,18 @@ Global
514516
{89DF188B-B1FC-D3C4-A76E-019144ABA9CB}.Release|x64.Build.0 = Release|Any CPU
515517
{89DF188B-B1FC-D3C4-A76E-019144ABA9CB}.Release|x86.ActiveCfg = Release|Any CPU
516518
{89DF188B-B1FC-D3C4-A76E-019144ABA9CB}.Release|x86.Build.0 = Release|Any CPU
519+
{977060F4-EEEF-420D-02E8-5E58D3E51942}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
520+
{977060F4-EEEF-420D-02E8-5E58D3E51942}.Debug|Any CPU.Build.0 = Debug|Any CPU
521+
{977060F4-EEEF-420D-02E8-5E58D3E51942}.Debug|x64.ActiveCfg = Debug|Any CPU
522+
{977060F4-EEEF-420D-02E8-5E58D3E51942}.Debug|x64.Build.0 = Debug|Any CPU
523+
{977060F4-EEEF-420D-02E8-5E58D3E51942}.Debug|x86.ActiveCfg = Debug|Any CPU
524+
{977060F4-EEEF-420D-02E8-5E58D3E51942}.Debug|x86.Build.0 = Debug|Any CPU
525+
{977060F4-EEEF-420D-02E8-5E58D3E51942}.Release|Any CPU.ActiveCfg = Release|Any CPU
526+
{977060F4-EEEF-420D-02E8-5E58D3E51942}.Release|Any CPU.Build.0 = Release|Any CPU
527+
{977060F4-EEEF-420D-02E8-5E58D3E51942}.Release|x64.ActiveCfg = Release|Any CPU
528+
{977060F4-EEEF-420D-02E8-5E58D3E51942}.Release|x64.Build.0 = Release|Any CPU
529+
{977060F4-EEEF-420D-02E8-5E58D3E51942}.Release|x86.ActiveCfg = Release|Any CPU
530+
{977060F4-EEEF-420D-02E8-5E58D3E51942}.Release|x86.Build.0 = Release|Any CPU
517531
EndGlobalSection
518532
GlobalSection(SolutionProperties) = preSolution
519533
HideSolutionNode = FALSE
@@ -556,6 +570,7 @@ Global
556570
{B95B12A8-FCE1-618A-CA77-134B59A5C050} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
557571
{261CB211-6023-8025-48E1-D11953F4C61C} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
558572
{89DF188B-B1FC-D3C4-A76E-019144ABA9CB} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
573+
{977060F4-EEEF-420D-02E8-5E58D3E51942} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
559574
EndGlobalSection
560575
GlobalSection(ExtensibilityGlobals) = postSolution
561576
SolutionGuid = {32B9C883-432E-4FC8-A1BF-090EB033DD5B}

azure-pipelines-pr.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ stages:
8989
displayName: Build Docker Image
9090
pool:
9191
name: NetCore-Public
92-
demands: ImageOverride -equals 1es-ubuntu-2004-open
92+
demands: ImageOverride -equals build.ubuntu.2204.amd64.open
9393

9494
steps:
9595
- checkout: self

azure-pipelines.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ extends:
164164
displayName: Build/publish docker image
165165
pool:
166166
name: NetCore1ESPool-Internal
167-
demands: ImageOverride -equals 1es-ubuntu-2004
167+
demands: ImageOverride -equals 1es-ubuntu-2204
168168
os: linux
169169

170170
steps:

docs/DevGuide.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ When running locally:
7272
}
7373
}
7474
}
75+
```
7576

7677
# Running the service locally
7778

src/Maestro/Maestro.MergePolicies/AllChecksSuccessfulMergePolicy.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public AllChecksSuccessfulMergePolicy(HashSet<string> ignoreChecks)
2626

2727
public override string DisplayName => "All Checks Successful";
2828

29-
public override async Task<MergePolicyEvaluationResult> EvaluateAsync(IPullRequest pr, IRemote darc)
29+
public override async Task<MergePolicyEvaluationResult> EvaluateAsync(PullRequestUpdateSummary pr, IRemote darc)
3030
{
3131
IEnumerable<Check> checks = await darc.GetPullRequestChecksAsync(pr.Url);
3232
IEnumerable<Check> notIgnoredChecks = checks.Where(c => !_ignoreChecks.Contains(c.Name) && !c.IsMaestroMergePolicy);
@@ -72,7 +72,7 @@ public class AllChecksSuccessfulMergePolicyBuilder : IMergePolicyBuilder
7272
{
7373
public string Name => MergePolicyConstants.AllCheckSuccessfulMergePolicyName;
7474

75-
public Task<IReadOnlyList<IMergePolicy>> BuildMergePoliciesAsync(MergePolicyProperties properties, IPullRequest pr)
75+
public Task<IReadOnlyList<IMergePolicy>> BuildMergePoliciesAsync(MergePolicyProperties properties, PullRequestUpdateSummary pr)
7676
{
7777
var ignoreChecks = new HashSet<string>(properties.Get<string[]>("ignoreChecks") ?? []);
7878
return Task.FromResult<IReadOnlyList<IMergePolicy>>([new AllChecksSuccessfulMergePolicy(ignoreChecks)]);
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
namespace Maestro.MergePolicies;
5+
6+
public enum CodeFlowDirection
7+
{
8+
None = 0,
9+
ForwardFlow = 1,
10+
BackFlow = 2
11+
}

src/Maestro/Maestro.MergePolicies/DontAutomergeDowngradesMergePolicy.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public class DontAutomergeDowngradesMergePolicy : MergePolicy
1414
{
1515
public override string DisplayName => "Do not automerge downgrades";
1616

17-
public override Task<MergePolicyEvaluationResult> EvaluateAsync(IPullRequest pr, IRemote darc)
17+
public override Task<MergePolicyEvaluationResult> EvaluateAsync(PullRequestUpdateSummary pr, IRemote darc)
1818
{
1919
try
2020
{
@@ -44,7 +44,7 @@ you can ignore the check in this case.
4444
}
4545
}
4646

47-
private static List<string> GetDowngradeOrInvalidVersionMessages(IPullRequest pr)
47+
private static List<string> GetDowngradeOrInvalidVersionMessages(PullRequestUpdateSummary pr)
4848
{
4949
List<string> messages = [];
5050

@@ -76,7 +76,7 @@ private static List<string> GetDowngradeOrInvalidVersionMessages(IPullRequest pr
7676
public class DontAutomergeDowngradesMergePolicyBuilder : IMergePolicyBuilder
7777
{
7878
public string Name => MergePolicyConstants.DontAutomergeDowngradesPolicyName;
79-
public Task<IReadOnlyList<IMergePolicy>> BuildMergePoliciesAsync(MergePolicyProperties properties, IPullRequest pr)
79+
public Task<IReadOnlyList<IMergePolicy>> BuildMergePoliciesAsync(MergePolicyProperties properties, PullRequestUpdateSummary pr)
8080
{
8181
IReadOnlyList<IMergePolicy> policies = new List<IMergePolicy> { new DontAutomergeDowngradesMergePolicy() };
8282
return Task.FromResult(policies);
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
// Licensed to the .NET Foundation under one or more agreements.
2+
// The .NET Foundation licenses this file to you under the MIT license.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
using System.Threading.Tasks;
8+
using Maestro.MergePolicyEvaluation;
9+
using Microsoft.DotNet.DarcLib;
10+
using Microsoft.DotNet.DarcLib.Helpers;
11+
using Microsoft.DotNet.DarcLib.Models.VirtualMonoRepo;
12+
using Microsoft.DotNet.DarcLib.VirtualMonoRepo;
13+
14+
namespace Maestro.MergePolicies;
15+
internal class ForwardFlowMergePolicy : MergePolicy
16+
{
17+
public override string DisplayName => "ForwardFlow";
18+
19+
private static readonly string configurationErrorsHeader = """
20+
### :x: Check Failed
21+
22+
The following error(s) were encountered:
23+
24+
25+
""";
26+
27+
private static readonly string seekHelpMessage = $"""
28+
29+
30+
### :exclamation: IMPORTANT
31+
32+
The `{VmrInfo.DefaultRelativeSourceManifestPath}` and `{VersionFiles.VersionDetailsXml}` files are managed by Maestro/darc. Outside of exceptional circumstances, these files should not be modified manually.
33+
**Unless you are sure that you know what you are doing, we recommend reaching out for help**. You can receive assistance by:
34+
- tagging the **@dotnet/product-construction** team in a PR comment
35+
- using the [First Responder channel](https://teams.microsoft.com/l/channel/19%3Aafba3d1545dd45d7b79f34c1821f6055%40thread.skype/First%20Responders?groupId=4d73664c-9f2f-450d-82a5-c2f02756606dhttps://teams.microsoft.com/l/channel/19%3Aafba3d1545dd45d7b79f34c1821f6055%40thread.skype/First%20Responders?groupId=4d73664c-9f2f-450d-82a5-c2f02756606d),
36+
- [opening an issue](https://github.com/dotnet/arcade-services/issues/new?template=BLANK_ISSUE) in the dotnet/arcade-services repo
37+
- contacting the [.NET Product Construction Services team via e-mail](mailto:[email protected]).
38+
""";
39+
40+
41+
public override async Task<MergePolicyEvaluationResult> EvaluateAsync(PullRequestUpdateSummary pr, IRemote remote)
42+
{
43+
SourceManifest sourceManifest;
44+
try
45+
{
46+
sourceManifest = await remote.GetSourceManifestAsync(pr.TargetRepoUrl, pr.HeadBranch);
47+
}
48+
catch (Exception)
49+
{
50+
return Fail(
51+
"Error while retrieving source manifest",
52+
$"An issue occurred while retrieving the source manifest. This could be due to a misconfiguration of the `{VmrInfo.DefaultRelativeSourceManifestPath}` file, or because of a server error."
53+
+ seekHelpMessage);
54+
}
55+
56+
Dictionary<string, int?> repoNamesToBarIds;
57+
Dictionary<string, string> repoNamesToCommitSha;
58+
if (!TryCreateBarIdDictionaryFromSourceManifest(sourceManifest, out repoNamesToBarIds) ||
59+
!TryCreateCommitShaDictionaryFromSourceManifest(sourceManifest, out repoNamesToCommitSha))
60+
{
61+
return Fail(
62+
"The source manifest file is malformed",
63+
$"Duplicate repository URIs were found in {VmrInfo.DefaultRelativeSourceManifestPath}." + seekHelpMessage);
64+
}
65+
66+
List<string> configurationErrors = CalculateConfigurationErrors(pr, repoNamesToBarIds, repoNamesToCommitSha);
67+
68+
if (configurationErrors.Any())
69+
{
70+
string failureMessage = string.Concat(
71+
configurationErrorsHeader,
72+
string.Join(Environment.NewLine, configurationErrors),
73+
seekHelpMessage);
74+
return Fail($"Missing or mismatched values found in {VmrInfo.DefaultRelativeSourceManifestPath}", failureMessage);
75+
}
76+
77+
return Succeed($"Forward-flow checks succeeded.");
78+
}
79+
80+
private List<string> CalculateConfigurationErrors(
81+
PullRequestUpdateSummary pr,
82+
Dictionary<string, int?> repoNamesToBarIds,
83+
Dictionary<string, string> repoNamesToCommitSha)
84+
{
85+
List<string> configurationErrors = new();
86+
foreach (SubscriptionUpdateSummary PRUpdateSummary in pr.ContainedUpdates)
87+
{
88+
if (!repoNamesToBarIds.TryGetValue(PRUpdateSummary.SourceRepo, out int? sourceManifestBarId) || sourceManifestBarId == null)
89+
{
90+
configurationErrors.Add($"""
91+
#### {configurationErrors.Count + 1}. Missing BAR ID in `{VmrInfo.DefaultRelativeSourceManifestPath}`
92+
- **Source Repository**: {PRUpdateSummary.SourceRepo}
93+
- **Error**: The BAR ID for the current update from the source repository is not found in the source manifest.
94+
""");
95+
}
96+
if (sourceManifestBarId != null && sourceManifestBarId != PRUpdateSummary.BuildId)
97+
{
98+
configurationErrors.Add($"""
99+
#### {configurationErrors.Count + 1}. BAR ID Mismatch in `{VmrInfo.DefaultRelativeSourceManifestPath}`
100+
- **Source Repository**: {PRUpdateSummary.SourceRepo}
101+
- **Error**: BAR ID `{sourceManifestBarId}` found in the source manifest does not match the build ID of the current update (`{PRUpdateSummary.BuildId}`).
102+
""");
103+
}
104+
if (!repoNamesToCommitSha.TryGetValue(PRUpdateSummary.SourceRepo, out string sourceManifestCommitSha) || string.IsNullOrEmpty(sourceManifestCommitSha))
105+
{
106+
configurationErrors.Add($"""
107+
#### {configurationErrors.Count + 1}. Missing Commit SHA in `{VmrInfo.DefaultRelativeSourceManifestPath}`
108+
- **Source Repository**: {PRUpdateSummary.SourceRepo}
109+
- **Error**: The commit SHA for the current update from the source repository is not found in the source manifest.
110+
""");
111+
}
112+
if (!string.IsNullOrEmpty(sourceManifestCommitSha) && sourceManifestCommitSha != PRUpdateSummary.CommitSha)
113+
{
114+
configurationErrors.Add($"""
115+
#### {configurationErrors.Count + 1}. Commit SHA Mismatch in `{VmrInfo.DefaultRelativeSourceManifestPath}`
116+
- **Source Repository**: {PRUpdateSummary.SourceRepo}
117+
- **Error**: Commit SHA `{sourceManifestCommitSha}` found in the source manifest does not match the commit SHA of the current update (`{PRUpdateSummary.CommitSha}`).
118+
""");
119+
}
120+
}
121+
return configurationErrors;
122+
}
123+
124+
private bool TryCreateBarIdDictionaryFromSourceManifest(SourceManifest sourceManifest, out Dictionary<string, int?> repoNamesToBarIds)
125+
{
126+
repoNamesToBarIds = new Dictionary<string, int?>();
127+
foreach (var repo in sourceManifest.Repositories)
128+
{
129+
if (repoNamesToBarIds.ContainsKey(repo.RemoteUri))
130+
{
131+
return false;
132+
}
133+
repoNamesToBarIds.Add(repo.RemoteUri, repo.BarId);
134+
}
135+
return true;
136+
}
137+
138+
139+
private bool TryCreateCommitShaDictionaryFromSourceManifest(SourceManifest sourceManifest, out Dictionary<string, string> repoNamesToCommitSha)
140+
{
141+
repoNamesToCommitSha = new Dictionary<string, string>();
142+
foreach (var repo in sourceManifest.Repositories)
143+
{
144+
if (repoNamesToCommitSha.ContainsKey(repo.RemoteUri))
145+
{
146+
return false;
147+
}
148+
repoNamesToCommitSha.Add(repo.RemoteUri, repo.CommitSha);
149+
}
150+
return true;
151+
}
152+
}
153+
154+
public class ForwardFlowMergePolicyBuilder : IMergePolicyBuilder
155+
{
156+
public string Name => MergePolicyConstants.ForwardFlowMergePolicyName;
157+
158+
public Task<IReadOnlyList<IMergePolicy>> BuildMergePoliciesAsync(MergePolicyProperties properties, PullRequestUpdateSummary pr)
159+
{
160+
return Task.FromResult<IReadOnlyList<IMergePolicy>>([new ForwardFlowMergePolicy()]);
161+
}
162+
}
163+

src/Maestro/Maestro.MergePolicies/IPullRequest.cs

Lines changed: 0 additions & 24 deletions
This file was deleted.

src/Maestro/Maestro.MergePolicies/MergePolicy.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ public string Name
4848

4949
public abstract string DisplayName { get; }
5050

51-
public abstract Task<MergePolicyEvaluationResult> EvaluateAsync(IPullRequest pr, IRemote darc);
51+
public abstract Task<MergePolicyEvaluationResult> EvaluateAsync(PullRequestUpdateSummary pr, IRemote darc);
5252

5353
public MergePolicyEvaluationResult Pending(string title) => new(MergePolicyEvaluationStatus.Pending, title, string.Empty, this);
5454

@@ -61,7 +61,7 @@ public string Name
6161

6262
public interface IMergePolicy : IMergePolicyInfo
6363
{
64-
Task<MergePolicyEvaluationResult> EvaluateAsync(IPullRequest pr, IRemote darc);
64+
Task<MergePolicyEvaluationResult> EvaluateAsync(PullRequestUpdateSummary pr, IRemote darc);
6565
}
6666

6767
public interface IMergePolicyBuilder
@@ -74,5 +74,5 @@ public interface IMergePolicyBuilder
7474
/// In most cases it will return array of exactly one merge policy, but in special cases like standard-policy
7575
/// it will return multiple pre-configured policies which that policies template consist of
7676
/// </summary>
77-
Task<IReadOnlyList<IMergePolicy>> BuildMergePoliciesAsync(MergePolicyProperties properties, IPullRequest pr);
77+
Task<IReadOnlyList<IMergePolicy>> BuildMergePoliciesAsync(MergePolicyProperties properties, PullRequestUpdateSummary pr);
7878
}

0 commit comments

Comments
 (0)