Skip to content

Commit aadbd4a

Browse files
authored
Merge pull request #720 from dotnet-maestro-bot/merge/release/2.1-to-release/2.2
[automated] Merge branch 'release/2.1' => 'release/2.2'
2 parents 1a13665 + bb2b2d1 commit aadbd4a

File tree

3 files changed

+150
-13
lines changed

3 files changed

+150
-13
lines changed

dir.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
<PackageReportDataFile>$(PackageReportDir)prebuilt-usage.json</PackageReportDataFile>
7070
<ProdConManifestFile>$(PackageReportDir)prodcon-build.xml</ProdConManifestFile>
7171
<PoisonedReportFile>$(PackageReportDir)poisoned.txt</PoisonedReportFile>
72+
<ConflictingPackageReportDir>$(BaseOutputPath)conflict-report/</ConflictingPackageReportDir>
7273
</PropertyGroup>
7374

7475
<!-- Import Build tools common props file where repo-independent properties are found -->

repos/dir.targets

Lines changed: 46 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
</ItemGroup>
88

99
<UsingTask AssemblyFile="$(TasksBinDir)Microsoft.DotNet.SourceBuild.Tasks.dll" TaskName="AddSourceToNuGetConfig" />
10+
<UsingTask AssemblyFile="$(TasksBinDir)Microsoft.DotNet.SourceBuild.Tasks.dll" TaskName="GetSourceBuiltNupkgCacheConflicts" />
1011
<UsingTask AssemblyFile="$(TasksBinDir)Microsoft.DotNet.SourceBuild.Tasks.dll" TaskName="ReadNuGetPackageInfos" />
1112
<UsingTask AssemblyFile="$(TasksBinDir)Microsoft.DotNet.SourceBuild.Tasks.dll" TaskName="RemoveInternetSourcesFromNuGetConfig" />
1213
<UsingTask AssemblyFile="$(TasksBinDir)Microsoft.DotNet.SourceBuild.Tasks.dll" TaskName="UpdateJson" />
@@ -155,7 +156,8 @@
155156
<Target Name="CreateBuildOutputProps"
156157
BeforeTargets="Build">
157158
<ItemGroup>
158-
<_PreviouslySourceBuiltPackages Include="$(SourceBuiltPackagesPath)*.nupkg" />
159+
<_PreviouslySourceBuiltPackages Include="$(SourceBuiltPackagesPath)*.nupkg"
160+
Exclude="$(SourceBuiltPackagesPath)*.symbols.nupkg" />
159161
</ItemGroup>
160162
<WriteBuildOutputProps NuGetPackages="@(_PreviouslySourceBuiltPackages)"
161163
ExtraPackageInfo="@(ExtraPackageVersionPropsPackageInfo)"
@@ -170,6 +172,34 @@
170172

171173
<Message Importance="High" Text="$(RepositoryName) is using versions $(PackageVersionPropsPath)" />
172174
<Message Importance="High" Text="%(VersionProperties.Identity)" />
175+
176+
<ReadNuGetPackageInfos PackagePaths="@(_PreviouslySourceBuiltPackages)">
177+
<Output TaskParameter="PackageInfoItems" ItemName="_PreviouslySourceBuiltPackageInfos" />
178+
</ReadNuGetPackageInfos>
179+
180+
<GetSourceBuiltNupkgCacheConflicts SourceBuiltPackageInfos="@(_PreviouslySourceBuiltPackageInfos)"
181+
PackageCacheDir="$(PackagesDir)">
182+
<Output TaskParameter="ConflictingPackageInfos" ItemName="ConflictingPackageInfos" />
183+
</GetSourceBuiltNupkgCacheConflicts>
184+
</Target>
185+
186+
<Target Name="CheckSourceBuiltNupkgConflictUsages"
187+
DependsOnTargets="GetAllProjectDirectories"
188+
AfterTargets="CreateBuildOutputProps"
189+
Condition="'@(ConflictingPackageInfos)' != ''">
190+
<PropertyGroup>
191+
<_ReportDir>$(ConflictingPackageReportDir)before-$(RepositoryName)/</_ReportDir>
192+
<_ReportDataFile>$(_ReportDir)usage.json</_ReportDataFile>
193+
</PropertyGroup>
194+
195+
<WritePackageUsageData NuGetPackageInfos="@(ConflictingPackageInfos)"
196+
ProjectDirectories="@(ProjectDirectories)"
197+
DataFile="$(_ReportDataFile)" />
198+
199+
<WriteUsageReports DataFile="$(_ReportDataFile)"
200+
OutputDirectory="$(_ReportDir)" />
201+
202+
<Warning Text="Detected package id/version(s) in the cache that were source-built, but contents don't match. They were probably downloaded. See $(_ReportDir) for usage details. @(ConflictingPackageInfos->'%(PackageId) %(PackageVersion)', ', ')" />
173203
</Target>
174204

175205
<Target Name="CreateRestoreSourceProps"
@@ -318,18 +348,8 @@
318348
</ItemGroup>
319349
</Target>
320350

321-
<Target Name="WritePrebuiltUsageData">
322-
<ItemGroup>
323-
<AllRepoProjects Include="$(ProjectDir)repos\*.proj" />
324-
</ItemGroup>
325-
326-
<Message Importance="High" Text="Finding project directories..." />
327-
328-
<MSBuild Projects="@(AllRepoProjects)"
329-
Targets="GetProjectDirectory">
330-
<Output TaskParameter="TargetOutputs" ItemName="ProjectDirectories" />
331-
</MSBuild>
332-
351+
<Target Name="WritePrebuiltUsageData"
352+
DependsOnTargets="GetAllProjectDirectories">
333353
<ItemGroup>
334354
<PrebuiltPackages Include="$(PrebuiltPackagesPath)*.nupkg" />
335355
<PrebuiltPackages Include="$(TarballPrebuiltPackagesPath)*.nupkg" Condition="'$(TarballPrebuiltPackagesPath)' != ''"/>
@@ -354,6 +374,19 @@
354374
DataFile="$(PackageReportDataFile)" />
355375
</Target>
356376

377+
<Target Name="GetAllProjectDirectories">
378+
<ItemGroup>
379+
<AllRepoProjects Include="$(ProjectDir)repos\*.proj" />
380+
</ItemGroup>
381+
382+
<Message Importance="High" Text="Finding project directories..." />
383+
384+
<MSBuild Projects="@(AllRepoProjects)"
385+
Targets="GetProjectDirectory">
386+
<Output TaskParameter="TargetOutputs" ItemName="ProjectDirectories" />
387+
</MSBuild>
388+
</Target>
389+
357390
<Target Name="ReportPrebuiltUsage"
358391
DependsOnTargets="GetPreviousReleasePrebuiltPackageInfos">
359392
<ItemGroup>
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
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+
// See the LICENSE file in the project root for more information.
4+
5+
using Microsoft.Build.Framework;
6+
using Microsoft.Build.Utilities;
7+
using System;
8+
using System.IO;
9+
using System.Linq;
10+
11+
namespace Microsoft.DotNet.SourceBuild.Tasks
12+
{
13+
/// <summary>
14+
/// For each source-built nupkg info given, ensure that if the package cache contains a package
15+
/// with the same id and version, the cached nupkg is the same as the source-built one.
16+
///
17+
/// If the package cache contains a package with the same package id and version as a
18+
/// source-built one, nuget restore short-circuits and doesn't look for the source-built one.
19+
/// This usually results in prebuilt packages being used, which can either break the build or
20+
/// end up in the outputs.
21+
/// </summary>
22+
public class GetSourceBuiltNupkgCacheConflicts : Task
23+
{
24+
/// <summary>
25+
/// Items containing package id and version of each source-built package.
26+
/// ReadNuGetPackageInfos is recommended to generate these.
27+
///
28+
/// %(Identity): Path to the original nupkg.
29+
/// %(PackageId): Identity of the package.
30+
/// %(PackageVersion): Version of the package.
31+
/// </summary>
32+
[Required]
33+
public ITaskItem[] SourceBuiltPackageInfos { get; set; }
34+
35+
/// <summary>
36+
/// Package cache dir containing nupkgs to compare. Path is expected to be like:
37+
///
38+
/// {PackageCacheDir}/{lowercase id}/{version}/{lowercase id}.{version}.nupkg
39+
/// </summary>
40+
[Required]
41+
public string PackageCacheDir { get; set; }
42+
43+
[Output]
44+
public ITaskItem[] ConflictingPackageInfos { get; set; }
45+
46+
public override bool Execute()
47+
{
48+
DateTime startTime = DateTime.Now;
49+
50+
ConflictingPackageInfos = SourceBuiltPackageInfos
51+
.Where(item =>
52+
{
53+
string sourceBuiltPath = item.ItemSpec;
54+
string id = item.GetMetadata("PackageId");
55+
string version = item.GetMetadata("PackageVersion");
56+
57+
string packageCachePath = Path.Combine(
58+
PackageCacheDir,
59+
id.ToLowerInvariant(),
60+
version,
61+
$"{id.ToLowerInvariant()}.{version}.nupkg");
62+
63+
if (!File.Exists(packageCachePath))
64+
{
65+
Log.LogMessage(
66+
MessageImportance.Low,
67+
$"OK: Package not found in package cache: {id} {version}");
68+
return false;
69+
}
70+
71+
Log.LogMessage(
72+
MessageImportance.Low,
73+
$"Package id/version found in package cache, verifying: {id} {version}");
74+
75+
bool identical = File.ReadAllBytes(sourceBuiltPath)
76+
.SequenceEqual(File.ReadAllBytes(packageCachePath));
77+
78+
if (!identical)
79+
{
80+
Log.LogMessage(
81+
MessageImportance.Low,
82+
"BAD: Source-built nupkg is not byte-for-byte identical " +
83+
$"to nupkg in cache: {id} {version}");
84+
return true;
85+
}
86+
87+
Log.LogMessage(
88+
MessageImportance.Low,
89+
$"OK: Package in cache is identical to source-built: {id} {version}");
90+
return false;
91+
})
92+
.ToArray();
93+
94+
// Tell the user about this task, in case it takes a while.
95+
Log.LogMessage(
96+
MessageImportance.High,
97+
"Checked cache for conflicts with source-built nupkgs. " +
98+
$"Took {DateTime.Now - startTime}");
99+
100+
return !Log.HasLoggedErrors;
101+
}
102+
}
103+
}

0 commit comments

Comments
 (0)