Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix RID regression by adding a task that calculates the best matching RID for platform #5695

Merged
merged 8 commits into from
Sep 20, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions Aspire.sln
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlServerEndToEnd.Common",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SqlServerEndToEnd.DbSetup", "playground\SqlServerEndToEnd\SqlServerEndToEnd.DbSetup\SqlServerEndToEnd.DbSetup.csproj", "{125C081D-7E5B-4F35-B5CD-E2B56140380F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Aspire.Hosting.Sdk.Tests", "tests\Aspire.Hosting.Sdk.Tests\Aspire.Hosting.Sdk.Tests.csproj", "{ABDC7DF8-7ACA-430C-9C91-983693DBBCB9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -1602,6 +1604,10 @@ Global
{125C081D-7E5B-4F35-B5CD-E2B56140380F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{125C081D-7E5B-4F35-B5CD-E2B56140380F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{125C081D-7E5B-4F35-B5CD-E2B56140380F}.Release|Any CPU.Build.0 = Release|Any CPU
{ABDC7DF8-7ACA-430C-9C91-983693DBBCB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{ABDC7DF8-7ACA-430C-9C91-983693DBBCB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{ABDC7DF8-7ACA-430C-9C91-983693DBBCB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{ABDC7DF8-7ACA-430C-9C91-983693DBBCB9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -1895,6 +1901,7 @@ Global
{F0C976EF-EE26-4EA9-B324-0CD21DCEA140} = {3FF3F00C-95C0-46FC-B2BE-A3920C71E393}
{1997067D-8EF2-43B3-AB13-9B2E12B52709} = {2CA6AB88-21EF-4488-BB1B-3A5BAD5FE2AD}
{125C081D-7E5B-4F35-B5CD-E2B56140380F} = {2CA6AB88-21EF-4488-BB1B-3A5BAD5FE2AD}
{ABDC7DF8-7ACA-430C-9C91-983693DBBCB9} = {4981B3A5-4AFD-4191-BF7D-8692D9783D60}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6DCEDFEC-988E-4CB3-B45B-191EB5086E0C}
Expand Down
1 change: 1 addition & 0 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
</ItemGroup>

<Import Project="$(RepositoryEngineeringDir)/apicompat/PublicApiAnalyzer.targets" />
<Import Project="$(RepositoryEngineeringDir)BuildTask.targets" Condition="'$(IsBuildTaskProject)' == 'true'" />

<!-- HACK: This resolves issues in CI builds where the extensions.json file is mapped to the incorrect directory. We only want
to copy the updated extensions.json file once the `_FunctionsExtensionUpdateMetadata` target has completed. -->
Expand Down
8 changes: 8 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,14 @@
<PackageVersion Include="Microsoft.Extensions.Primitives" Version="$(MicrosoftExtensionsPrimitivesPackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.Http.Resilience" Version="$(MicrosoftExtensionsHttpResiliencePackageVersion)" />
<PackageVersion Include="Microsoft.Extensions.TimeProvider.Testing" Version="$(MicrosoftExtensionsTimeProviderTestingVersion)" />
<!-- NuGet dependencies -->
<PackageVersion Include="NuGet.ProjectModel" Version="6.11.0" />
<PackageVersion Include="NuGet.Commands" Version="6.11.0" />
<PackageVersion Include="NuGet.Packaging" Version="6.11.0" />
<!-- MSBuild dependencies -->
<PackageVersion Include="Microsoft.Build" Version="17.8.3" />
<PackageVersion Include="Microsoft.Build.Framework" Version="17.8.3" />
<PackageVersion Include="Microsoft.Build.Utilities.Core" Version="17.8.3" />
<!-- external dependencies -->
<PackageVersion Include="Confluent.Kafka" Version="2.5.2" />
<PackageVersion Include="Dapper" Version="2.1.44" />
Expand Down
26 changes: 26 additions & 0 deletions eng/BuildTask.Packages.props
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project>

<!-- Don't go higher than binding redirects entries in the toolset MSBuild.exe.config file. -->
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
<PackageVersion Update="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" />
<PackageVersion Update="System.Collections.Immutable" Version="8.0.0" />
<PackageVersion Update="System.Reflection.Metadata" Version="8.0.0" />
<PackageVersion Update="System.Reflection.MetadataLoadContext" Version="8.0.0" />
<PackageVersion Update="System.Resources.Extensions" Version="8.0.0" />
<PackageVersion Update="System.Text.Encodings.Web" Version="8.0.0" />
<PackageVersion Update="System.Text.Json" Version="8.0.3" />
<PackageVersion Update="System.Threading.Tasks.Dataflow" Version="8.0.0" />

<!-- Packages that transitively bring above dependencies in. -->
<PackageVersion Update="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.0" />
<PackageVersion Update="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageVersion Update="Microsoft.Extensions.DependencyModel" Version="8.0.0" />
<PackageVersion Update="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
</ItemGroup>

<!-- Suppress System.Text.Json/8.0.0 advisory as desktop msbuild doesn't yet provide binding redirects for the non-vulnerable version (8.0.4). -->
<ItemGroup>
<NuGetAuditSuppress Include="https://github.com/advisories/GHSA-hh2w-p6rv-4g7w" />
</ItemGroup>

</Project>
100 changes: 100 additions & 0 deletions eng/BuildTask.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<Project>

<Import Project="BuildTask.Packages.props"/>

<PropertyGroup>
<IncludeBuildOutput>false</IncludeBuildOutput>
<IsPackable>true</IsPackable>
<!-- Build Tasks should not include any dependencies -->
<SuppressDependenciesWhenPacking Condition="'$(SuppressDependenciesWhenPacking)' == ''">true</SuppressDependenciesWhenPacking>
<!-- Build Tasks should have this set per https://github.com/dotnet/arcade/blob/master/Documentation/CorePackages/Versioning.md#recommended-settings -->
<AutoGenerateAssemblyVersion>true</AutoGenerateAssemblyVersion>
<BuildTaskTargetFolder Condition="'$(BuildTaskTargetFolder)' == ''">tools</BuildTaskTargetFolder>
<PackTasks Condition="'$(PackTasks)' == ''">true</PackTasks>
<TargetsForTfmSpecificContentInPackage Condition="'$(PackTasks)' == 'true'">$(TargetsForTfmSpecificContentInPackage);_AddBuildOutputToPackageCore;_AddBuildOutputToPackageDesktop</TargetsForTfmSpecificContentInPackage>
</PropertyGroup>

<!-- Don't include assemblies that MSBuild ships with. -->
<ItemGroup>
<PackageReference Update="Microsoft.Build" Publish="false" />
<PackageReference Update="Microsoft.Build.Framework" Publish="false" />
<PackageReference Update="Microsoft.Build.Tasks.Core" Publish="false" />
<PackageReference Update="Microsoft.Build.Utilities.Core" Publish="false" />
<PackageReference Update="Microsoft.NET.StringTools" Publish="false" />
<PackageReference Update="System.Resources.Extensions" Publish="false" />
</ItemGroup>

<!-- Don't include assemblies that are provided by the SDK, next to MSBuild. -->
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' and '$(SkipSDKInboxPublishExcludes)' != 'true'">
<PackageReference Update="Newtonsoft.Json" Publish="false" />
<PackageReference Update="NuGet.Commands" Publish="false" />
<PackageReference Update="NuGet.Common" Publish="false" />
<PackageReference Update="NuGet.Configuration" Publish="false" />
<PackageReference Update="NuGet.Frameworks" Publish="false" />
<PackageReference Update="NuGet.Packaging" Publish="false" />
<PackageReference Update="NuGet.ProjectModel" Publish="false" />
<PackageReference Update="NuGet.Versioning" Publish="false" />
<PackageReference Update="System.CodeDom" Publish="false" />
<PackageReference Update="System.Security.Cryptography.ProtectedData" Publish="false" />
<PackageReference Update="System.Text.Encoding.CodePages" Publish="false" />
</ItemGroup>

<!-- Don't include assemblies that are inbox in Desktop MSBuild -->
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETFramework'">
<PackageReference Update="Microsoft.Bcl.AsyncInterfaces" Publish="false" />
<PackageReference Update="System.Buffers" Publish="false" />
<PackageReference Update="System.Collections.Immutable" Publish="false" />
<PackageReference Update="System.Memory" Publish="false" />
<PackageReference Update="System.Numerics.Vectors" Publish="false" />
<PackageReference Update="System.Reflection.Metadata" Publish="false" />
<PackageReference Update="System.Reflection.MetadataLoadContext" Publish="false" />
<PackageReference Update="System.Runtime.CompilerServices.Unsafe" Publish="false" />
<PackageReference Update="System.Text.Encodings.Web" Publish="false" />
<PackageReference Update="System.Text.Json" Publish="false" />
<PackageReference Update="System.Threading.Channels" Publish="false" />
<PackageReference Update="System.Threading.Tasks.Dataflow" Publish="false" />
<PackageReference Update="System.Threading.Tasks.Extensions" Publish="false" />
<PackageReference Update="System.ValueTuple" Publish="false" />
</ItemGroup>

<ItemGroup>
<!--
Update all PackageReference items to default Publish to true.
This forces the publish output to contain the dlls.
-->
<PackageReference Update="@(PackageReference)">
<Publish Condition="'%(PackageReference.Publish)' == ''">true</Publish>
<ExcludeAssets Condition="'%(PackageReference.Publish)' == 'false'">runtime</ExcludeAssets>
</PackageReference>

<!--
Update all Reference items to have Pack="false"
This removes the frameworkDependency nodes from the generated nuspec
-->
<Reference Update="@(Reference)"
Pack="false" />
</ItemGroup>
joperezr marked this conversation as resolved.
Show resolved Hide resolved

<!-- Publish .NET Core assets and include them in the package under $(BuildTaskTargetFolder) directory. -->
<Target Name="_AddBuildOutputToPackageCore" DependsOnTargets="Publish" Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">
<PropertyGroup>
<BuildTaskTargetTfmSpecificFolder Condition="'$(BuildTaskTargetTfmSpecificFolder)' == ''">$(TargetFramework)</BuildTaskTargetTfmSpecificFolder>
</PropertyGroup>
<ItemGroup>
<TfmSpecificPackageFile Include="$(PublishDir)**"
Exclude="$(PublishDir)**/*.props;$(PublishDir)**/*.targets"
PackagePath="$(BuildTaskTargetFolder)/$(BuildTaskTargetTfmSpecificFolder)/%(RecursiveDir)%(FileName)%(Extension)"/>
</ItemGroup>
</Target>

<!-- Include .NET Framework build outputs in the package under $(BuildTaskTargetFolder) directory. -->
<Target Name="_AddBuildOutputToPackageDesktop" DependsOnTargets="Publish" Condition="'$(TargetFrameworkIdentifier)' != '.NETCoreApp'">
<PropertyGroup>
<BuildTaskTargetTfmSpecificFolder Condition="'$(BuildTaskTargetTfmSpecificFolder)' == ''">$(TargetFramework)</BuildTaskTargetTfmSpecificFolder>
</PropertyGroup>
<ItemGroup>
<TfmSpecificPackageFile Include="$(PublishDir)*.*" PackagePath="$(BuildTaskTargetFolder)/$(BuildTaskTargetTfmSpecificFolder)/%(FileName)%(Extension)"/>
</ItemGroup>
</Target>

</Project>
joperezr marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 2 additions & 2 deletions eng/dashboardpack/Sdk.in.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@

<!-- *** BEGIN *** -->

<PropertyGroup Condition="'$(NETCoreSdkRuntimeIdentifier)' == '@PlatformRuntime@'">
<PropertyGroup>
joperezr marked this conversation as resolved.
Show resolved Hide resolved
<AspireDashboardDir Condition=" '$(AspireDashboardDir)' == '' ">$([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory), '..', 'tools'))</AspireDashboardDir>
<AspireDashboardDir>$([MSBuild]::EnsureTrailingSlash('$(AspireDashboardDir)'))</AspireDashboardDir>
<AspireDashboardPath Condition=" '$(AspireDashboardPath)' == '' ">$([MSBuild]::NormalizePath($(AspireDashboardDir), 'Aspire.Dashboard'))</AspireDashboardPath>
<AspireDashboardPath Condition=" '$(OS)' == 'Windows_NT' and !$(AspireDashboardPath.EndsWith('.exe')) ">$(AspireDashboardPath).exe</AspireDashboardPath>
<AspireDashboardPath Condition="$([MSBuild]::IsOsPlatform('OSX')) and !$(AspireDashboardPath.EndsWith('.dll'))">$(AspireDashboardPath).dll</AspireDashboardPath>
</PropertyGroup>

<ItemGroup Condition="'$(NETCoreSdkRuntimeIdentifier)' == '@PlatformRuntime@'">
<ItemGroup>
<ProjectCapability Include="AspireDashboard" />
</ItemGroup>

Expand Down
2 changes: 1 addition & 1 deletion eng/dcppack/Aspire.Hosting.Orchestration.in.targets
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project>

<PropertyGroup Condition="'$(NETCoreSdkRuntimeIdentifier)' == '@PlatformRuntime@'">
<PropertyGroup>
joperezr marked this conversation as resolved.
Show resolved Hide resolved
<DcpDir Condition=" '$(DcpDir)' == '' ">$([MSBuild]::NormalizeDirectory($(MSBuildThisFileDirectory), '..', 'tools'))</DcpDir>
<DcpDir>$([MSBuild]::EnsureTrailingSlash('$(DcpDir)'))</DcpDir>
<DcpExtensionsDir Condition=" '$(DcpExtensionsDir)' == '' ">$([MSBuild]::NormalizeDirectory($(DcpDir), 'ext'))</DcpExtensionsDir>
Expand Down
21 changes: 20 additions & 1 deletion src/Aspire.Hosting.Sdk/Aspire.Hosting.Sdk.csproj
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
<Project Sdk="Microsoft.Build.NoTargets">
<Project Sdk="Microsoft.NET.Sdk">

joperezr marked this conversation as resolved.
Show resolved Hide resolved
<Import Project="$(SharedDir)Workload.targets" />

<PropertyGroup>
<TargetFrameworks>$(DefaultTargetFramework);$(NetFrameworkToolCurrent);</TargetFrameworks>
<PackageTags>aspire hosting sdk</PackageTags>
joperezr marked this conversation as resolved.
Show resolved Hide resolved
<Description>.NET Aspire Hosting SDK. Enabled via &lt;IsAspireHost&gt;true&lt;/IsAspireHost&gt;.</Description>
<UsePublicApiAnalyzers>false</UsePublicApiAnalyzers>
<!--
CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member'
CS8002: Referenced assembly does not have a strong name
-->
joperezr marked this conversation as resolved.
Show resolved Hide resolved
<NoWarn>$(NoWarn);CS1591;CS8002</NoWarn>
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
<IsBuildTaskProject>true</IsBuildTaskProject>
joperezr marked this conversation as resolved.
Show resolved Hide resolved
</PropertyGroup>

<PropertyGroup>
Expand All @@ -18,4 +27,14 @@
<None Update="SDK\Sdk.in.targets" Pack="true" PerformTextReplacement="True" PackagePath="Sdk\Sdk.targets" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="NuGet.ProjectModel" />
<PackageReference Include="Microsoft.Build" />
<PackageReference Include="Microsoft.Build.Framework" />
<PackageReference Include="Microsoft.Build.Utilities.Core" />
<PackageReference Include="Newtonsoft.Json" />
<PackageReference Include="NuGet.Commands" />
<PackageReference Include="NuGet.Packaging" />
</ItemGroup>

</Project>
42 changes: 42 additions & 0 deletions src/Aspire.Hosting.Sdk/FindBestRidForPlatform.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using Microsoft.Build.Framework;
using NuGet.RuntimeModel;
using Task = Microsoft.Build.Utilities.Task;

namespace Aspire.Hosting.Sdk;
#pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor.
joperezr marked this conversation as resolved.
Show resolved Hide resolved
public class FindBestRidForPlatform : Task
{
[Required]
public string RuntimeGraphPath { get; set; }

[Required]
public ITaskItem[] SupportedRids { get; set; }

[Required]
public string NETCoreSdkRuntimeIdentifier { get; set; }

[Output]
public string? BestRidForPlatform { get; set; }

public override bool Execute()
{
var supportedRids = SupportedRids
.Select(item => item.ItemSpec);

RuntimeGraph graph = JsonRuntimeFormat.ReadRuntimeGraph(RuntimeGraphPath);

BestRidForPlatform = NuGetUtils.GetBestMatchingRid(graph, NETCoreSdkRuntimeIdentifier, supportedRids, out bool wasInGraph);

if (!wasInGraph)
{
base.Log.LogError("Rid {0} was not found in the runtime graph.", NETCoreSdkRuntimeIdentifier);
joperezr marked this conversation as resolved.
Show resolved Hide resolved
return false;
}

return true;
}
}
#pragma warning restore CS8618
50 changes: 50 additions & 0 deletions src/Aspire.Hosting.Sdk/NuGetUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using NuGet.RuntimeModel;

namespace Aspire.Hosting.Sdk;

/*
* These utility methods were copied from the sdk repository to mimic the behavior used when selecting the best matching RID
* for a a given runtime identifier. For more information, please see the original source code at:
joperezr marked this conversation as resolved.
Show resolved Hide resolved
* https://github.com/dotnet/sdk/blob/e6da8ca6de3ec8f392dc87b8529415e1ef59b7ea/src/Tasks/Microsoft.NET.Build.Tasks/NuGetUtils.NuGet.cs#L76-L109
*/

internal static class NuGetUtils
{
public static string? GetBestMatchingRid(RuntimeGraph runtimeGraph, string runtimeIdentifier,
IEnumerable<string> availableRuntimeIdentifiers, out bool wasInGraph)
{
return GetBestMatchingRidWithExclusion(runtimeGraph, runtimeIdentifier,
runtimeIdentifiersToExclude: null,
availableRuntimeIdentifiers, out wasInGraph);
}

public static string? GetBestMatchingRidWithExclusion(RuntimeGraph runtimeGraph, string runtimeIdentifier,
IEnumerable<string>? runtimeIdentifiersToExclude,
IEnumerable<string> availableRuntimeIdentifiers, out bool wasInGraph)
{
wasInGraph = runtimeGraph.Runtimes.ContainsKey(runtimeIdentifier);

string? bestMatch = null;

HashSet<string> availableRids = new(availableRuntimeIdentifiers, StringComparer.Ordinal);
HashSet<string>? excludedRids = runtimeIdentifiersToExclude switch { null => null, _ => new HashSet<string>(runtimeIdentifiersToExclude, StringComparer.Ordinal) };
foreach (var candidateRuntimeIdentifier in runtimeGraph.ExpandRuntime(runtimeIdentifier))
{
if (bestMatch == null && availableRids.Contains(candidateRuntimeIdentifier))
{
bestMatch = candidateRuntimeIdentifier;
}

if (excludedRids != null && excludedRids.Contains(candidateRuntimeIdentifier))
{
// Don't treat this as a match
return null;
}
}

return bestMatch;
}
}
Loading
Loading