Skip to content

Commit 5edcb41

Browse files
authored
XS✔ ◾ Added .NET 10 dual targeting (#779)
* Added double targeting = UT failing * Modified reference condition to include the TODO PBI * Formatting * Reverting previous changes * Applied comments * Removed unused package * Applied missing configurations * Simplified namespace for validation static methods * Removed redundant .NET 8 install * Testing assumption based on [this](github/codeql#20827 (comment)) * Revert "Testing assumption based on [this](github/codeql#20827 (comment))" This reverts commit 9111113. * Removed custom CodeQL action * Revert "Removed custom CodeQL action" This reverts commit 2d84785.
1 parent bbbf76b commit 5edcb41

File tree

10 files changed

+59
-48
lines changed

10 files changed

+59
-48
lines changed

.github/pipelines/dotnet-initialize.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ steps:
1111
- task: NuGetAuthenticate@1
1212
displayName: NuGet Authenticate
1313
- task: UseDotNet@2
14-
displayName: Temporarily install .NET 8 SDK while dual targeting
14+
displayName: Temporarily install .NET 9 SDK while dual targeting
1515
inputs:
16-
version: "8.0.x"
16+
version: "9.0.x"
1717
- task: UseDotNet@2
1818
displayName: Use .NET SDK from global.json
1919
inputs:

.github/workflows/build.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,14 @@ jobs:
4141
steps:
4242
- name: Checkout repository
4343
uses: actions/checkout@v6
44-
- name: Install .NET 8 SDK
45-
uses: actions/setup-dotnet@v5
46-
with:
47-
dotnet-version: '8.0.x'
4844
- name: Install .NET 9 SDK
4945
uses: actions/setup-dotnet@v5
5046
with:
5147
dotnet-version: '9.0.x'
48+
- name: Install .NET 10 SDK
49+
uses: actions/setup-dotnet@v5
50+
with:
51+
dotnet-version: '10.0.x'
5252
- name: Install SF SDK
5353
shell: powershell
5454
run: |

.github/workflows/codeql-analysis.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ jobs:
3131
steps:
3232
- name: Checkout repository
3333
uses: actions/checkout@v6
34-
- name: Install .NET 8 SDK
35-
uses: actions/setup-dotnet@v5
36-
with:
37-
dotnet-version: '8.0.x'
3834
- name: Install .NET 9 SDK
3935
uses: actions/setup-dotnet@v5
4036
with:
4137
dotnet-version: '9.0.x'
38+
- name: Install .NET 10 SDK
39+
uses: actions/setup-dotnet@v5
40+
with:
41+
dotnet-version: '10.0.x'
4242

4343
# Initializes the CodeQL tools for scanning.
4444
- name: Initialize CodeQL

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<RepoRoot Condition="'$(RepoRoot)' == ''">$([System.IO.Path]::GetDirectoryName($([MSBuild]::GetPathOfFileAbove('global.json', '$(MSBuildProjectDirectory)'))))</RepoRoot>
44
</PropertyGroup>
55
<PropertyGroup Label="Target Platforms">
6-
<LatestSupportedDotNetVersion>net9.0</LatestSupportedDotNetVersion>
6+
<LatestSupportedDotNetVersion>net10.0</LatestSupportedDotNetVersion>
77
<OldestSupportedDotNetVersion>net9.0</OldestSupportedDotNetVersion>
88
<NetCoreVersions>$(LatestSupportedDotNetVersion)</NetCoreVersions>
99
<NetCoreVersions Condition="'$(LatestSupportedDotNetVersion)' != '$(OldestSupportedDotNetVersion)'">$(LatestSupportedDotNetVersion);$(OldestSupportedDotNetVersion)</NetCoreVersions>

Directory.Packages.props

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,25 @@
55
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
66
</PropertyGroup>
77
<ItemGroup Label="Latest DotNet Package Versions. AutoUpdate" Condition="'$(TargetFramework)' == '$(LatestSupportedDotNetVersion)' OR '$(IsNetStandard)'">
8+
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="10.0.0" PreserveMajor="true"/>
9+
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="10.0.0" PreserveMajor="true"/>
10+
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="10.0.0" PreserveMajor="true"/>
11+
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" PreserveMajor="true"/>
12+
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="10.0.0" PreserveMajor="true"/>
13+
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.0" PreserveMajor="true"/>
14+
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.0" PreserveMajor="true"/>
15+
<PackageVersion Include="Microsoft.Extensions.Http" Version="10.0.0" PreserveMajor="true"/>
16+
<PackageVersion Include="Microsoft.Extensions.Logging" Version="10.0.0" PreserveMajor="true"/>
17+
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" PreserveMajor="true"/>
18+
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="10.0.0" PreserveMajor="true"/>
19+
<PackageVersion Include="Microsoft.Extensions.ObjectPool" Version="10.0.0" PreserveMajor="true"/>
20+
<PackageVersion Include="Microsoft.Extensions.Options" Version="10.0.0" PreserveMajor="true"/>
21+
<PackageVersion Include="Microsoft.Extensions.Options.DataAnnotations" Version="10.0.0" PreserveMajor="true"/>
22+
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.0" PreserveMajor="true"/>
23+
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="10.0.0" PreserveMajor="true"/>
24+
<PackageVersion Include="System.Text.Json" Version="10.0.0" PreserveMajor="true"/>
25+
</ItemGroup>
26+
<ItemGroup Label="Previous DotNet Package Versions. AutoUpdate" Condition="'$(TargetFramework)' == '$(OldestSupportedDotNetVersion)' And '$(OldestSupportedDotNetVersion)' != '$(LatestSupportedDotNetVersion)'">
827
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="9.0.11" PreserveMajor="true"/>
928
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="9.0.11" PreserveMajor="true"/>
1029
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="9.0.11" PreserveMajor="true"/>
@@ -20,42 +39,21 @@
2039
<PackageVersion Include="Microsoft.Extensions.Options" Version="9.0.11" PreserveMajor="true"/>
2140
<PackageVersion Include="Microsoft.Extensions.Options.DataAnnotations" Version="9.0.11" PreserveMajor="true"/>
2241
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="9.0.11" PreserveMajor="true"/>
23-
<PackageVersion Include="Microsoft.FeatureManagement" Version="4.3.0"/>
24-
<PackageVersion Include="Microsoft.SourceLink.AzureRepos.Git" Version="8.0.0"/>
25-
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0"/>
2642
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="9.0.11" PreserveMajor="true"/>
27-
<PackageVersion Include="System.Linq.Async" Version="6.0.3"/>
2843
<PackageVersion Include="System.Text.Json" Version="9.0.11" PreserveMajor="true"/>
2944
</ItemGroup>
30-
<ItemGroup Label="Previous DotNet Package Versions. AutoUpdate" Condition="'$(TargetFramework)' == '$(OldestSupportedDotNetVersion)' And '$(OldestSupportedDotNetVersion)' != '$(LatestSupportedDotNetVersion)'">
31-
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" PreserveMajor="true"/>
32-
<PackageVersion Include="Microsoft.Extensions.Caching.Memory" Version="8.0.1" PreserveMajor="true"/>
33-
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.2" PreserveMajor="true"/>
34-
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" PreserveMajor="true"/>
35-
<PackageVersion Include="Microsoft.Extensions.Diagnostics.HealthChecks" Version="8.0.22" PreserveMajor="true"/>
36-
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="8.0.1" PreserveMajor="true"/>
37-
<PackageVersion Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.1" PreserveMajor="true"/>
38-
<PackageVersion Include="Microsoft.Extensions.Http" Version="8.0.1" PreserveMajor="true"/>
39-
<PackageVersion Include="Microsoft.Extensions.Logging" Version="8.0.1" PreserveMajor="true"/>
40-
<PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.3" PreserveMajor="true"/>
41-
<PackageVersion Include="Microsoft.Extensions.Logging.Console" Version="8.0.1" PreserveMajor="true"/>
42-
<PackageVersion Include="Microsoft.Extensions.ObjectPool" Version="8.0.22" PreserveMajor="true"/>
43-
<PackageVersion Include="Microsoft.Extensions.Options" Version="8.0.2" PreserveMajor="true"/>
44-
<PackageVersion Include="Microsoft.Extensions.Options.DataAnnotations" Version="8.0.0" PreserveMajor="true"/>
45-
<PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="8.0.0" PreserveMajor="true"/>
46-
<PackageVersion Include="Microsoft.SourceLink.AzureRepos.Git" Version="8.0.0" PreserveMajor="true"/>
47-
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" PreserveMajor="true"/>
48-
<PackageVersion Include="System.Diagnostics.DiagnosticSource" Version="8.0.1" PreserveMajor="true"/>
49-
<PackageVersion Include="System.Text.Json" Version="8.0.6" PreserveMajor="true"/>
50-
</ItemGroup>
5145
<ItemGroup Label="Package Versions. AutoUpdate">
5246
<PackageVersion Include="MSTest.TestAdapter" Version="4.0.2" />
5347
<PackageVersion Include="MSTest.TestFramework" Version="4.0.2" />
5448
<PackageVersion Include="Microsoft.CodeAnalysis.Common" Version="4.14.0" />
5549
<PackageVersion Include="Microsoft.CodeAnalysis.Csharp" Version="4.14.0" />
50+
<PackageVersion Include="Microsoft.FeatureManagement" Version="4.3.0"/>
5651
<PackageVersion Include="Microsoft.Net.Test.Sdk" Version="18.0.1" />
52+
<PackageVersion Include="Microsoft.SourceLink.AzureRepos.Git" Version="8.0.0"/>
53+
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0"/>
5754
<PackageVersion Include="Newtonsoft.Json" Version="13.0.4" />
5855
<PackageVersion Include="System.ComponentModel.Annotations" Version="5.0.0" />
56+
<PackageVersion Include="System.Linq.Async" Version="6.0.3"/>
5957
<PackageVersion Include="System.Threading.Tasks" Version="4.3.0" />
6058
<PackageVersion Include="System.Threading.Tasks.Extensions" Version="4.6.3" />
6159
</ItemGroup>

global.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"sdk": {
3-
"version": "9.0.308",
3+
"version": "10.0.100",
44
"rollForward": "latestMajor"
55
}
66
}

src/Hosting.Services.Web/HostBuilderExtensions.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
using Microsoft.Omex.Extensions.Hosting.Services.Web;
1919
using Microsoft.ServiceFabric.Services.Communication.AspNetCore;
2020

21+
using OmexValidation = Microsoft.Omex.Extensions.Abstractions.Validation;
22+
2123
namespace Microsoft.Extensions.Hosting
2224
{
2325
/// <summary>
@@ -99,8 +101,8 @@ public static IHost BuildStatelessWebService<TStartup>(
99101
{
100102
if (endpoint.UseHttps)
101103
{
102-
string settingForCertificateCommonName = Validation.ThrowIfNullOrWhiteSpace(endpoint.SettingForCertificateCommonName);
103-
string certificateSubject = Validation.ThrowIfNullOrWhiteSpace(context.Configuration.GetValue<string>(settingForCertificateCommonName));
104+
string settingForCertificateCommonName = OmexValidation.ThrowIfNullOrWhiteSpace(endpoint.SettingForCertificateCommonName);
105+
string certificateSubject = OmexValidation.ThrowIfNullOrWhiteSpace(context.Configuration.GetValue<string>(settingForCertificateCommonName));
104106
listenOptions.UseHttps(StoreName.My, certificateSubject, true, StoreLocation.LocalMachine);
105107
}
106108
});

tests/FeatureManagement.UnitTests/ExtendedFeatureManagerTests.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4+
extern alias SystemLinqAsync;
5+
46
namespace Microsoft.Omex.Extensions.FeatureManagement.UnitTests;
57

68
using System;
@@ -17,6 +19,7 @@ namespace Microsoft.Omex.Extensions.FeatureManagement.UnitTests;
1719
using Microsoft.Omex.Extensions.Testing.Helpers.HttpContext;
1820
using Microsoft.VisualStudio.TestTools.UnitTesting;
1921
using Moq;
22+
using LinqAsync = SystemLinqAsync::System.Linq.AsyncEnumerable;
2023

2124
[TestClass]
2225
public sealed class ExtendedFeatureManagerTests
@@ -281,16 +284,16 @@ public void GetOverride_WhenFeatureNotInAnyOverride_ReturnsNull()
281284
public async Task GetFeatureNamesAsync_WhenCalled_DelegatesCallToFeatureManager()
282285
{
283286
// ARRANGE
284-
IAsyncEnumerable<string> expectedNames = s_expected.ToAsyncEnumerable();
287+
IAsyncEnumerable<string> expectedNames = LinqAsync.ToAsyncEnumerable(s_expected);
285288
m_featureManagerMock.Setup(m => m.GetFeatureNamesAsync()).Returns(expectedNames);
286289

287290
// ACT
288291
IAsyncEnumerable<string> result = m_extendedFeatureManager.GetFeatureNamesAsync();
289-
List<string> resultList = await result.ToListAsync(TestContext.CancellationTokenSource.Token);
292+
List<string> resultList = await LinqAsync.ToListAsync(result, TestContext.CancellationTokenSource.Token);
290293

291294
// ASSERT
292295
m_featureManagerMock.Verify(m => m.GetFeatureNamesAsync(), Times.Once);
293-
CollectionAssert.AreEqual(await expectedNames.ToListAsync(TestContext.CancellationTokenSource.Token), resultList);
296+
CollectionAssert.AreEqual(await LinqAsync.ToListAsync(expectedNames, TestContext.CancellationTokenSource.Token), resultList);
294297
}
295298

296299
#endregion

tests/FeatureManagement.UnitTests/FeatureGatesServiceTests.cs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT license.
33

4+
extern alias SystemLinqAsync;
5+
46
namespace Microsoft.Omex.Extensions.FeatureManagement.UnitTests;
57

68
using System;
@@ -14,6 +16,7 @@ namespace Microsoft.Omex.Extensions.FeatureManagement.UnitTests;
1416
using Microsoft.Omex.Extensions.FeatureManagement.Experimentation;
1517
using Microsoft.VisualStudio.TestTools.UnitTesting;
1618
using Moq;
19+
using LinqAsync = SystemLinqAsync::System.Linq.AsyncEnumerable;
1720

1821
[TestClass]
1922
public sealed class FeatureGatesServiceTests
@@ -81,7 +84,7 @@ public async Task GetFeatureGatesAsync_WhenFeaturesPresent_ReturnsExpectedDictio
8184
{
8285
// ARRANGE
8386
List<string> features = ["FE_Test1", "FE_Test2", "Other"];
84-
m_featureManagerMock.Setup(m => m.GetFeatureNamesAsync()).Returns(features.ToAsyncEnumerable());
87+
m_featureManagerMock.Setup(m => m.GetFeatureNamesAsync()).Returns(LinqAsync.ToAsyncEnumerable(features));
8588
m_featureManagerMock.Setup(m => m.IsEnabledAsync("FE_Test1")).ReturnsAsync(true);
8689
m_featureManagerMock.Setup(m => m.IsEnabledAsync("FE_Test2")).ReturnsAsync(false);
8790
m_featureManagerMock.Setup(m => m.EnabledFeaturesList).Returns(["FE_Test2"]);
@@ -101,7 +104,7 @@ public async Task GetFeatureGatesAsync_WhenNoFrontendFeatures_ReturnsEmptyDictio
101104
{
102105
// ARRANGE
103106
List<string> features = ["Other1", "Other2"];
104-
m_featureManagerMock.Setup(m => m.GetFeatureNamesAsync()).Returns(features.ToAsyncEnumerable());
107+
m_featureManagerMock.Setup(m => m.GetFeatureNamesAsync()).Returns(LinqAsync.ToAsyncEnumerable(features));
105108
m_featureManagerMock.Setup(m => m.EnabledFeaturesList).Returns([]);
106109
m_featureManagerMock.Setup(m => m.DisabledFeaturesList).Returns([]);
107110

@@ -117,7 +120,7 @@ public async Task GetFeatureGatesAsync_WhenFeatureAlreadyExistsInMap_DoesNotOver
117120
{
118121
// ARRANGE
119122
List<string> features = ["FE_Test1", "fe_test1"]; // Different casing
120-
m_featureManagerMock.Setup(m => m.GetFeatureNamesAsync()).Returns(features.ToAsyncEnumerable());
123+
m_featureManagerMock.Setup(m => m.GetFeatureNamesAsync()).Returns(LinqAsync.ToAsyncEnumerable(features));
121124
m_featureManagerMock.Setup(m => m.IsEnabledAsync("FE_Test1")).ReturnsAsync(true);
122125
m_featureManagerMock.Setup(m => m.IsEnabledAsync("fe_test1")).ReturnsAsync(false);
123126
m_featureManagerMock.Setup(m => m.EnabledFeaturesList).Returns([]);
@@ -136,7 +139,7 @@ public async Task GetFeatureGatesAsync_WithEnabledFeaturesListWithoutPrefix_Hand
136139
{
137140
// ARRANGE
138141
List<string> features = [];
139-
m_featureManagerMock.Setup(m => m.GetFeatureNamesAsync()).Returns(features.ToAsyncEnumerable());
142+
m_featureManagerMock.Setup(m => m.GetFeatureNamesAsync()).Returns(LinqAsync.ToAsyncEnumerable(features));
140143
m_featureManagerMock.Setup(m => m.EnabledFeaturesList).Returns(["Test1", "FE_Test2"]);
141144
m_featureManagerMock.Setup(m => m.DisabledFeaturesList).Returns([]);
142145

@@ -154,7 +157,7 @@ public async Task GetFeatureGatesAsync_WithDisabledFeaturesListWithoutPrefix_Han
154157
{
155158
// ARRANGE
156159
List<string> features = [];
157-
m_featureManagerMock.Setup(m => m.GetFeatureNamesAsync()).Returns(features.ToAsyncEnumerable());
160+
m_featureManagerMock.Setup(m => m.GetFeatureNamesAsync()).Returns(LinqAsync.ToAsyncEnumerable(features));
158161
m_featureManagerMock.Setup(m => m.EnabledFeaturesList).Returns([]);
159162
m_featureManagerMock.Setup(m => m.DisabledFeaturesList).Returns(["Test1", "FE_Test2"]);
160163

tests/FeatureManagement.UnitTests/Microsoft.Omex.Extensions.FeatureManagement.UnitTests.csproj

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,13 @@
44
<TargetFrameworks>$(UnitTestTargetFrameworks)</TargetFrameworks>
55
</PropertyGroup>
66

7+
<!--
8+
TODO 10880196 - Remove this package when migrating directly to .NET 10.
9+
Please refer to this article for more information about this specific migration instance:
10+
https://learn.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/10.0/asyncenumerable
11+
-->
712
<ItemGroup>
8-
<PackageReference Include="System.Linq.Async"/>
13+
<PackageReference Include="System.Linq.Async" Aliases="SystemLinqAsync"/>
914
</ItemGroup>
1015

1116
<ItemGroup>

0 commit comments

Comments
 (0)