Skip to content

Commit 388e0a8

Browse files
authored
Don't publish assets with Vertical visibility as part of the merged manifest for a vertical. (#45553)
1 parent ba3841c commit 388e0a8

File tree

4 files changed

+71
-31
lines changed

4 files changed

+71
-31
lines changed

src/SourceBuild/content/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/GetKnownArtifactsFromAssetManifests.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public sealed class GetKnownArtifactsFromAssetManifests : Build.Utilities.Task
2424
private const string RepoOriginAttributeName = "RepoOrigin";
2525
private const string NonShippingAttributeName = "NonShipping";
2626
private const string DotNetReleaseShippingAttributeName = "DotNetReleaseShipping";
27+
private const string VisibilityAttributeName = "Visibility";
28+
private const string DefaultVisibility = "External";
2729

2830
// Package metadata
2931
private const string PackageElementName = "Package";
@@ -69,7 +71,8 @@ public override bool Execute()
6971
{ PackageVersionAttributeName, package.Attribute(PackageVersionAttributeName)!.Value },
7072
{ RepoOriginAttributeName, package.Attribute(RepoOriginAttributeName)?.Value ?? string.Empty },
7173
{ NonShippingAttributeName, package.Attribute(NonShippingAttributeName)?.Value ?? string.Empty },
72-
{ DotNetReleaseShippingAttributeName, package.Attribute(DotNetReleaseShippingAttributeName)?.Value ?? string.Empty }
74+
{ DotNetReleaseShippingAttributeName, package.Attribute(DotNetReleaseShippingAttributeName)?.Value ?? string.Empty },
75+
{ VisibilityAttributeName, package.Attribute(VisibilityAttributeName)?.Value ?? DefaultVisibility },
7376
}))
7477
.Distinct(TaskItemManifestEqualityComparer.Instance)
7578
.ToArray();
@@ -81,7 +84,8 @@ public override bool Execute()
8184
{
8285
{ RepoOriginAttributeName, blob.Attribute(RepoOriginAttributeName)?.Value ?? string.Empty },
8386
{ NonShippingAttributeName, blob.Attribute(NonShippingAttributeName)?.Value ?? string.Empty },
84-
{ DotNetReleaseShippingAttributeName, blob.Attribute(DotNetReleaseShippingAttributeName)?.Value ?? string.Empty }
87+
{ DotNetReleaseShippingAttributeName, blob.Attribute(DotNetReleaseShippingAttributeName)?.Value ?? string.Empty },
88+
{ VisibilityAttributeName, blob.Attribute(VisibilityAttributeName)?.Value ?? DefaultVisibility },
8589
}))
8690
.Distinct(TaskItemManifestEqualityComparer.Instance)
8791
.ToArray();
@@ -110,4 +114,4 @@ public bool Equals(TaskItem? x, TaskItem? y)
110114

111115
public int GetHashCode([DisallowNull] TaskItem obj) => HashCode.Combine(obj.ItemSpec, obj.GetMetadata(PackageVersionAttributeName));
112116
}
113-
}
117+
}

src/SourceBuild/content/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/JoinVerticals.cs

Lines changed: 46 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ public class JoinVerticals : Microsoft.Build.Utilities.Task
6868
private const string _packageElementName = "Package";
6969
private const string _blobElementName = "Blob";
7070
private const string _idAttribute = "Id";
71+
private const string _visibilityAttribute = "Visibility";
72+
private const string _externalVisibility = "External";
73+
private const string _internalVisibility = "Internal";
74+
private const string _verticalVisibility = "Vertical";
7175
private const string _verticalNameAttribute = "VerticalName";
7276
private const string _artifactNameSuffix = "_Artifacts";
7377
private const string _assetsFolderName = "assets";
@@ -110,7 +114,7 @@ private async Task ExecuteAsync()
110114

111115
using var clientThrottle = new SemaphoreSlim(16, 16);
112116
List<Task> downloadTasks = new();
113-
117+
114118
foreach (XDocument verticalManifest in verticalManifests)
115119
{
116120
string verticalName = GetRequiredRootAttribute(verticalManifest, _verticalNameAttribute);
@@ -188,28 +192,28 @@ private async Task DownloadArtifactFiles(
188192

189193
await Task.WhenAll(fileNamesToDownload.Select(async fileName =>
190194
await DownloadFileFromArtifact(
191-
filesInformation,
192-
artifactName,
193-
azureDevOpsClient,
194-
buildId,
195-
fileName,
196-
outputDirectory,
195+
filesInformation,
196+
artifactName,
197+
azureDevOpsClient,
198+
buildId,
199+
fileName,
200+
outputDirectory,
197201
clientThrottle)));
198202
}
199203

200204
private async Task DownloadFileFromArtifact(
201-
ArtifactFiles artifactFilesMetadata,
202-
string azureDevOpsArtifact,
203-
AzureDevOpsClient azureDevOpsClient,
204-
string buildId,
205-
string manifestFile,
205+
ArtifactFiles artifactFilesMetadata,
206+
string azureDevOpsArtifact,
207+
AzureDevOpsClient azureDevOpsClient,
208+
string buildId,
209+
string manifestFile,
206210
string destinationDirectory,
207211
SemaphoreSlim clientThrottle)
208212
{
209213
try
210214
{
211215
await clientThrottle.WaitAsync();
212-
216+
213217
ArtifactItem fileItem;
214218

215219
var matchingFilePaths = artifactFilesMetadata.Items.Where(f => Path.GetFileName(f.Path) == Path.GetFileName(manifestFile));
@@ -260,7 +264,7 @@ private async Task DownloadFileFromArtifact(
260264
}
261265

262266
/// <summary>
263-
/// Copy all files from the source directory to the destination directory,
267+
/// Copy all files from the source directory to the destination directory,
264268
/// in a flat layout
265269
/// </summary>
266270
private void CopyMainVerticalAssets(string sourceDirectory, string destinationDirectory)
@@ -272,7 +276,7 @@ private void CopyMainVerticalAssets(string sourceDirectory, string destinationDi
272276
Directory.CreateDirectory(destinationDirectory);
273277
}
274278

275-
foreach (var sourceFile in sourceFiles)
279+
foreach (var sourceFile in sourceFiles)
276280
{
277281
string destinationFilePath = Path.Combine(destinationDirectory, Path.GetFileName(sourceFile));
278282

@@ -291,11 +295,35 @@ private List<string> AddMissingElements(Dictionary<string, AddedElement> addedAr
291295

292296
string verticalName = verticalManifest.Root!.Attribute(_verticalNameAttribute)!.Value;
293297

294-
foreach (XElement artifactElement in verticalManifest.Descendants(elementName))
298+
foreach (XElement artifactElement in verticalManifest.Descendants(elementName))
295299
{
296-
string elementId = artifactElement.Attribute(_idAttribute)?.Value
300+
string elementId = artifactElement.Attribute(_idAttribute)?.Value
297301
?? throw new ArgumentException($"Required attribute '{_idAttribute}' not found in {elementName} element.");
298302

303+
// Filter out artifacts that are not "External" visibility.
304+
// Artifacts of "Vertical" visibility should have been filtered out in each individual vertical,
305+
// but artifacts of "Internal" visibility would have been included in each vertical's manifest (to enable feeding into join verticals).
306+
// We need to remove them here so they don't get included in the final merged manifest.
307+
// As we're in the final join, there should be no jobs after us. Therefore, we can also skip uploading them to the final artifacts folders
308+
// as no job should run after this job that would consume them.
309+
string? visibility = artifactElement.Attribute(_visibilityAttribute)?.Value;
310+
311+
if (visibility == _verticalVisibility)
312+
{
313+
Log.LogError($"Artifact {elementId} has 'Vertical' visibility and should not be present in a vertical manifest.");
314+
continue;
315+
}
316+
else if (visibility == _internalVisibility)
317+
{
318+
Log.LogMessage(MessageImportance.High, $"Artifact {elementId} has 'Internal' visibility and will not be included in the final merged manifest.");
319+
continue;
320+
}
321+
else if (visibility is not (null or "" or _externalVisibility))
322+
{
323+
Log.LogError($"Artifact {elementId} has unknown visibility: '{visibility}'");
324+
continue;
325+
}
326+
299327
if (addedArtifacts.TryAdd(elementId, new AddedElement(verticalName, artifactElement)))
300328
{
301329
if (elementName == _packageElementName)
@@ -327,7 +355,7 @@ private List<string> AddMissingElements(Dictionary<string, AddedElement> addedAr
327355

328356
private static string GetRequiredRootAttribute(XDocument document, string attributeName)
329357
{
330-
return document.Root?.Attribute(attributeName)?.Value
358+
return document.Root?.Attribute(attributeName)?.Value
331359
?? throw new ArgumentException($"Required attribute '{attributeName}' not found in root element.");
332360
}
333361

src/SourceBuild/content/eng/tools/tasks/Microsoft.DotNet.UnifiedBuild.Tasks/MergeAssetManifests.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public override bool Execute()
5454

5555
VerifyAssetManifests(assetManifestXmls);
5656

57-
XElement mergedManifestRoot = assetManifestXmls.First().Root
57+
XElement mergedManifestRoot = assetManifestXmls.First().Root
5858
?? throw new ArgumentException("The root element of the asset manifest is null.");
5959

6060
// Set the BuildId and AzureDevOpsBuildNumber attributes to the value of VmrBuildNumber
@@ -67,10 +67,14 @@ public override bool Execute()
6767

6868
foreach (var assetManifestXml in assetManifestXmls)
6969
{
70-
packageElements.AddRange(assetManifestXml.Descendants("Package"));
71-
blobElements.AddRange(assetManifestXml.Descendants("Blob"));
70+
// We may encounter assets here with "Vertical", "Internal", or "External" visibility here.
71+
// We filter out "Vertical" visibility assets here, as they are not needed in the merged manifest.
72+
// We leave in "Internal" assets so they can be used in later build passes.
73+
// We leave in "External" assets as we will eventually ship them.
74+
packageElements.AddRange(assetManifestXml.Descendants("Package").Where(package => package.Attribute("Visibility")?.Value != "Vertical"));
75+
blobElements.AddRange(assetManifestXml.Descendants("Blob").Where(blob => blob.Attribute("Visibility")?.Value != "Vertical"));
7276
}
73-
77+
7478
packageElements = packageElements.OrderBy(packageElement => packageElement.Attribute("Id")?.Value).ToList();
7579
blobElements = blobElements.OrderBy(blobElement => blobElement.Attribute("Id")?.Value).ToList();
7680

@@ -97,18 +101,18 @@ private static void VerifyAssetManifests(IReadOnlyList<XDocument> assetManifestX
97101
.Root?
98102
.Attributes()
99103
.Select(attribute => attribute.ToString())
100-
.ToHashSet()
104+
.ToHashSet()
101105
?? throw new ArgumentException("The root element of the asset manifest is null.");
102106

103107
if (assetManifestXmls.Skip(1).Any(manifest => manifest.Root?.Attributes().Count() != rootAttributes.Count))
104108
{
105109
throw new ArgumentException("The asset manifests do not have the same number of root attributes.");
106110
}
107111

108-
if (assetManifestXmls.Skip(1).Any(assetManifestXml =>
112+
if (assetManifestXmls.Skip(1).Any(assetManifestXml =>
109113
!assetManifestXml.Root?.Attributes().Select(attribute => attribute.ToString())
110114
.All(attribute =>
111-
// Ignore BuildId and AzureDevOpsBuildNumber attributes, they're different for different repos,
115+
// Ignore BuildId and AzureDevOpsBuildNumber attributes, they're different for different repos,
112116
// TODO this should be fixed with https://github.com/dotnet/source-build/issues/3934
113117
_ignoredAttributes.Any(ignoredAttribute => attribute.StartsWith(ignoredAttribute)) || rootAttributes.Contains(attribute))
114118
?? false))

src/SourceBuild/content/repo-projects/Directory.Build.targets

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -554,9 +554,13 @@
554554
<ShippingFolder Condition="%(ProducedPackage.NonShipping) != 'true'">Shipping</ShippingFolder>
555555
</ProducedPackage>
556556

557-
<!-- When building from source, the Private.SourceBuilt.Artifacts archive already contains the nuget packages. -->
558-
<BinPlaceFile Include="@(ProducedPackage->'$(ArtifactsPackagesDir)%(ShippingFolder)/$(RepositoryName)/%(Identity).%(Version).nupkg')" Condition="'$(DotNetBuildSourceOnly)' != 'true'" />
559-
<BinPlaceFile Include="@(ProducedAsset->'$(ArtifactsAssetsDir)%(Identity)')" />
557+
<!--
558+
When building from source, the Private.SourceBuilt.Artifacts archive already contains the nuget packages so no need to binplace.
559+
In addition, don't binplace any packages or blobs with vertical visibility. These are only used for building other repos within this vertical
560+
and shouldn't be staged for upload.
561+
-->
562+
<BinPlaceFile Include="@(ProducedPackage->'$(ArtifactsPackagesDir)%(ShippingFolder)/$(RepositoryName)/%(Identity).%(Version).nupkg')" Condition="'$(DotNetBuildSourceOnly)' != 'true' and '%(Visibility)' != 'Vertical'" />
563+
<BinPlaceFile Include="@(ProducedAsset->'$(ArtifactsAssetsDir)%(Identity)')" Condition="'%(Visibility)' != 'Vertical'"/>
560564
</ItemGroup>
561565

562566
<!-- Add manifests from dependent verticals. -->

0 commit comments

Comments
 (0)