Skip to content

Commit 6c2d399

Browse files
authored
feat: add support for .NET 10 (#837)
This PR adds support for [.NET 10](https://dotnet.microsoft.com/en-us/download/dotnet/10.0) by upgrading the .NET SDK version and integrating new .NET 10 features across the codebase. The changes include updating build configurations, feature flags, test frameworks, and implementing new APIs introduced in .NET 10. ### Key Changes - Added .NET 10 target framework support and new .NET 10 feature flags for UTF-8 GUID parsing, random string generation, and async compression operations - Implemented new API methods for random string generation - `IRandom.GetHexString(int, bool)` - `IRandom.GetHexString(Span<char>, bool)` - `IRandom.GetString(ReadOnlySpan<char>, int)` for UTF-8 GUID parsing - `Guid.Parse(ReadOnlySpan<byte>)` - `Guid.Parse(ReadOnlySpan<byte>, IFormatProvider)` - `Guid.TryParse(ReadOnlySpan<byte>, out Guid)` - `Guid.TryParse(ReadOnlySpan<byte>, IFormatProvider, out Guid)` and the async compression operations - `IZipArchive.CreateEntryFromFileAsync(string, string, CancellationToken)` - `IZipArchive.CreateEntryFromFileAsync(string, string, CompressionLevel, CancellationToken)` - `IZipArchive.ExtractToDirectoryAsync(string, CancellationToken)` - `IZipArchive.ExtractToDirectoryAsync(string, bool, CancellationToken)` - `IZipArchiveEntry.ExtractToFileAsync(string, CancellationToken)` - `IZipArchiveEntry.ExtractToFileAsync(string, bool, CancellationToken)` - `IZipArchiveEntry.OpenAsync(CancellationToken)` - `IZipFile.CreateFromDirectoryAsync(string, Stream, CancellationToken)` - `IZipFile.CreateFromDirectoryAsync(string, Stream, CompressionLevel , bool, CancellationToken)` - `IZipFile.CreateFromDirectoryAsync(string, Stream, CompressionLevel , bool, Encoding, CancellationToken)` - `IZipFile.CreateFromDirectoryAsync(string, string, CancellationToken)` - `IZipFile.CreateFromDirectoryAsync(string, string, CompressionLevel , bool, CancellationToken)` - `IZipFile.CreateFromDirectoryAsync(string, string, CompressionLevel , bool, Encoding, CancellationToken)` - `IZipFile.ExtractToDirectoryAsync(Stream, string, CancellationToken)` - `IZipFile.ExtractToDirectoryAsync(Stream, string, bool, CancellationToken)` - `IZipFile.ExtractToDirectoryAsync(Stream, string, Encoding, CancellationToken)` - `IZipFile.ExtractToDirectoryAsync(Stream, string, Encoding, bool, CancellationToken)` - `IZipFile.ExtractToDirectoryAsync(string, string, CancellationToken)` - `IZipFile.ExtractToDirectoryAsync(string, string, bool, CancellationToken)` - `IZipFile.ExtractToDirectoryAsync(string, string, Encoding, CancellationToken)` - `IZipFile.ExtractToDirectoryAsync(string, string, Encoding, bool, CancellationToken)` - `IZipFile.OpenAsync(string, ZipArchiveMode, CancellationToken)` - `IZipFile.OpenAsync(string, ZipArchiveMode, Encoding?, CancellationToken)` - `IZipFile.OpenReadAsync(string, CancellationToken)` - Added tests for the new features - Updated build pipeline and CI/CD workflows to include .NET 10 support
1 parent ef1d79e commit 6c2d399

File tree

51 files changed

+3825
-109
lines changed

Some content is hidden

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

51 files changed

+3825
-109
lines changed

.github/workflows/build.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ jobs:
2525
6.0.x
2626
8.0.x
2727
9.0.x
28+
10.0.x
2829
- name: Run unit tests (windows)
2930
if: matrix.os == 'windows-latest'
3031
run: ./build.ps1 CodeCoverage
@@ -56,6 +57,7 @@ jobs:
5657
6.0.x
5758
8.0.x
5859
9.0.x
60+
10.0.x
5961
- name: API checks
6062
run: ./build.sh ApiChecks
6163
- name: Upload artifacts
@@ -85,6 +87,7 @@ jobs:
8587
6.0.x
8688
8.0.x
8789
9.0.x
90+
10.0.x
8891
- name: Run sonarcloud analysis
8992
run: ./build.sh CodeAnalysis
9093

@@ -124,6 +127,7 @@ jobs:
124127
6.0.x
125128
8.0.x
126129
9.0.x
130+
10.0.x
127131
- name: Pack nuget packages
128132
run: ./build.sh Pack
129133
- name: Upload packages

.github/workflows/ci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ jobs:
2424
6.0.x
2525
8.0.x
2626
9.0.x
27+
10.0.x
2728
- name: Run unit tests (windows)
2829
if: matrix.os == 'windows-latest'
2930
run: ./build.ps1 CodeCoverage
@@ -55,6 +56,7 @@ jobs:
5556
6.0.x
5657
8.0.x
5758
9.0.x
59+
10.0.x
5860
- name: API checks
5961
run: ./build.sh ApiChecks
6062
- name: Upload artifacts
@@ -86,6 +88,7 @@ jobs:
8688
6.0.x
8789
8.0.x
8890
9.0.x
91+
10.0.x
8992
- name: Run mutation tests
9093
run: ./build.sh MutationTestsLinux MutationComment
9194
env:
@@ -111,6 +114,7 @@ jobs:
111114
6.0.x
112115
8.0.x
113116
9.0.x
117+
10.0.x
114118
- name: Run mutation tests
115119
run: ./build.ps1 MutationTestsWindows MutationComment
116120
env:
@@ -135,6 +139,7 @@ jobs:
135139
6.0.x
136140
8.0.x
137141
9.0.x
142+
10.0.x
138143
- name: Run sonarcloud analysis
139144
run: ./build.sh CodeAnalysis
140145

Directory.Packages.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@
4747
<PackageVersion Include="NUnit3TestAdapter" Version="5.2.0"/>
4848
</ItemGroup>
4949
<ItemGroup>
50-
<PackageVersion Include="Testably.Abstractions.Interface" Version="9.0.0"/>
51-
<PackageVersion Include="Testably.Abstractions" Version="9.0.0"/>
50+
<PackageVersion Include="Testably.Abstractions.Interface" Version="10.0.0-pre.1"/>
51+
<PackageVersion Include="Testably.Abstractions" Version="10.0.0-pre.1"/>
5252
<PackageVersion Include="Testably.Abstractions.Testing" Version="4.3.9"/>
5353
</ItemGroup>
5454
<ItemGroup>

Feature.Flags.props

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<Project>
22

33
<PropertyGroup>
4-
<IS_NET21_OR_HIGHER Condition="'$(TargetFramework)' == 'net6.0' OR '$(TargetFramework)' == 'net8.0' OR '$(TargetFramework)' == 'net9.0' OR '$(TargetFramework)' == 'netstandard2.1'">1</IS_NET21_OR_HIGHER>
5-
<IS_NET6_OR_HIGHER Condition="'$(TargetFramework)' == 'net6.0' OR '$(TargetFramework)' == 'net8.0' OR '$(TargetFramework)' == 'net9.0'">1</IS_NET6_OR_HIGHER>
6-
<IS_NET8_OR_HIGHER Condition="'$(TargetFramework)' == 'net8.0' OR '$(TargetFramework)' == 'net9.0'">1</IS_NET8_OR_HIGHER>
7-
<IS_NET9_OR_HIGHER Condition="'$(TargetFramework)' == 'net9.0'">1</IS_NET9_OR_HIGHER>
4+
<IS_NET21_OR_HIGHER Condition="'$(TargetFramework)' == 'net6.0' OR '$(TargetFramework)' == 'net8.0' OR '$(TargetFramework)' == 'net9.0' OR '$(TargetFramework)' == 'net10.0' OR '$(TargetFramework)' == 'netstandard2.1'">1</IS_NET21_OR_HIGHER>
5+
<IS_NET6_OR_HIGHER Condition="'$(TargetFramework)' == 'net6.0' OR '$(TargetFramework)' == 'net8.0' OR '$(TargetFramework)' == 'net9.0' OR '$(TargetFramework)' == 'net10.0'">1</IS_NET6_OR_HIGHER>
6+
<IS_NET8_OR_HIGHER Condition="'$(TargetFramework)' == 'net8.0' OR '$(TargetFramework)' == 'net9.0' OR '$(TargetFramework)' == 'net10.0'">1</IS_NET8_OR_HIGHER>
7+
<IS_NET9_OR_HIGHER Condition="'$(TargetFramework)' == 'net9.0' OR '$(TargetFramework)' == 'net10.0'">1</IS_NET9_OR_HIGHER>
8+
<IS_NET10_OR_HIGHER Condition="'$(TargetFramework)' == 'net10.0'">1</IS_NET10_OR_HIGHER>
89

910
<DefineConstants Condition="'$(TargetFramework)' == 'net48' OR '$(TargetFramework)' == 'netstandard2.0'">$(DefineConstants);NETFRAMEWORK</DefineConstants>
1011
<DefineConstants Condition="'$(IS_NET6_OR_HIGHER)' == '1'">$(DefineConstants);CAN_SIMULATE_OTHER_OS</DefineConstants>
@@ -35,6 +36,9 @@
3536
<DefineConstants Condition="'$(IS_NET9_OR_HIGHER)' == '1'">$(DefineConstants);FEATURE_PATH_SPAN</DefineConstants>
3637
<DefineConstants Condition="'$(IS_NET9_OR_HIGHER)' == '1'">$(DefineConstants);FEATURE_FILE_SPAN</DefineConstants>
3738
<DefineConstants Condition="'$(IS_NET9_OR_HIGHER)' == '1'">$(DefineConstants);FEATURE_GUID_V7</DefineConstants>
39+
<DefineConstants Condition="'$(IS_NET10_OR_HIGHER)' == '1'">$(DefineConstants);FEATURE_GUID_PARSE_UTF8</DefineConstants>
40+
<DefineConstants Condition="'$(IS_NET10_OR_HIGHER)' == '1'">$(DefineConstants);FEATURE_RANDOM_STRINGS</DefineConstants>
41+
<DefineConstants Condition="'$(IS_NET10_OR_HIGHER)' == '1'">$(DefineConstants);FEATURE_COMPRESSION_ASYNC</DefineConstants>
3842
</PropertyGroup>
3943

4044
</Project>

Pipeline/Build.ApiChecks.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,16 @@ partial class Build
1313
.DependsOn(Compile)
1414
.Executes(() =>
1515
{
16-
Project[] projects =
17-
[
18-
Solution.Tests.Api.Testably_Abstractions_Api_Tests,
19-
Solution.Tests.Api.Testably_Abstractions_Core_Api_Tests,
20-
];
16+
Project[] projects = BuildScope switch
17+
{
18+
BuildScope.CoreOnly => [Solution.Tests.Api.Testably_Abstractions_Core_Api_Tests,],
19+
BuildScope.MainOnly => [Solution.Tests.Api.Testably_Abstractions_Api_Tests,],
20+
_ =>
21+
[
22+
Solution.Tests.Api.Testably_Abstractions_Api_Tests,
23+
Solution.Tests.Api.Testably_Abstractions_Core_Api_Tests,
24+
],
25+
};
2126

2227
DotNetTest(s => s
2328
.SetConfiguration(Configuration)

Pipeline/Build.CodeAnalysis.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ partial class Build
1313
.Unlisted()
1414
.Before(Compile)
1515
.Before(CodeCoverage)
16+
.OnlyWhenDynamic(() => BuildScope == BuildScope.Default)
1617
.Executes(() =>
1718
{
1819
SonarScannerTasks.SonarScannerBegin(s => s
@@ -29,7 +30,7 @@ partial class Build
2930
.Unlisted()
3031
.DependsOn(Compile)
3132
.DependsOn(CodeCoverage)
32-
.OnlyWhenDynamic(() => IsServerBuild)
33+
.OnlyWhenDynamic(() => IsServerBuild && BuildScope == BuildScope.Default)
3334
.Executes(() =>
3435
{
3536
SonarScannerTasks.SonarScannerEnd(s => s

Pipeline/Build.CodeCoverage.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ partial class Build
1111
{
1212
Target CodeCoverage => _ => _
1313
.DependsOn(UnitTests)
14+
.OnlyWhenDynamic(() => BuildScope != BuildScope.CoreOnly)
1415
.Executes(() =>
1516
{
1617
ReportGenerator(s => s

Pipeline/Build.MutationTests.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ partial class Build
2727
.After(MutationTestsLinux)
2828
.After(MutationTestsWindows)
2929
.OnlyWhenDynamic(() => GitHubActions.IsPullRequest)
30+
.OnlyWhenDynamic(() => BuildScope == BuildScope.Default)
3031
.Executes(async () =>
3132
{
3233
int? prId = GitHubActions.PullRequestNumber;
@@ -83,6 +84,7 @@ await gitHubClient.Issue.Comment.Update("Testably", "Testably.Abstractions",
8384
});
8485

8586
Target MutationTestPreparation => _ => _
87+
.OnlyWhenDynamic(() => BuildScope == BuildScope.Default)
8688
.Executes(() =>
8789
{
8890
StrykerToolPath.CreateOrCleanDirectory();
@@ -97,11 +99,13 @@ await gitHubClient.Issue.Comment.Update("Testably", "Testably.Abstractions",
9799
Target MutationTests => _ => _
98100
.DependsOn(MutationTestsWindows)
99101
.DependsOn(MutationTestsLinux)
100-
.DependsOn(MutationComment);
102+
.DependsOn(MutationComment)
103+
.OnlyWhenDynamic(() => BuildScope == BuildScope.Default);
101104

102105
Target MutationTestsLinux => _ => _
103106
.DependsOn(Compile)
104107
.DependsOn(MutationTestPreparation)
108+
.OnlyWhenDynamic(() => BuildScope == BuildScope.Default)
105109
.Executes(() =>
106110
{
107111
AbsolutePath configFile = StrykerToolPath / "Stryker.Config.json";
@@ -210,6 +214,7 @@ await gitHubClient.Issue.Comment.Update("Testably", "Testably.Abstractions",
210214
Target MutationTestsWindows => _ => _
211215
.DependsOn(Compile)
212216
.DependsOn(MutationTestPreparation)
217+
.OnlyWhenDynamic(() => BuildScope == BuildScope.Default)
213218
.Executes(() =>
214219
{
215220
AbsolutePath configFile = StrykerToolPath / "Stryker.Config.json";

Pipeline/Build.Pack.cs

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,47 +24,53 @@ partial class Build
2424
packagesDirectory.CreateOrCleanDirectory();
2525

2626
List<string> packages = new();
27-
Directory.CreateDirectory(packagesDirectory / "Main");
28-
foreach (Project mainProject in MainProjects)
27+
if (BuildScope != BuildScope.CoreOnly)
2928
{
30-
foreach (string package in
31-
Directory.EnumerateFiles(mainProject.Directory / "bin", "*.nupkg",
32-
SearchOption.AllDirectories))
29+
Directory.CreateDirectory(packagesDirectory / "Main");
30+
foreach (Project mainProject in MainProjects)
3331
{
34-
File.Move(package, packagesDirectory / "Main" / Path.GetFileName(package));
35-
Debug("Found nuget package: {PackagePath}", package);
36-
packages.Add(Path.GetFileName(package));
37-
}
32+
foreach (string package in
33+
Directory.EnumerateFiles(mainProject.Directory / "bin", "*.nupkg",
34+
SearchOption.AllDirectories))
35+
{
36+
File.Move(package, packagesDirectory / "Main" / Path.GetFileName(package));
37+
Debug("Found nuget package: {PackagePath}", package);
38+
packages.Add(Path.GetFileName(package));
39+
}
3840

39-
foreach (string symbolPackage in
40-
Directory.EnumerateFiles(mainProject.Directory / "bin", "*.snupkg",
41-
SearchOption.AllDirectories))
42-
{
43-
File.Move(symbolPackage,
44-
packagesDirectory / "Main" / Path.GetFileName(symbolPackage));
45-
Debug("Found symbol package: {PackagePath}", symbolPackage);
41+
foreach (string symbolPackage in
42+
Directory.EnumerateFiles(mainProject.Directory / "bin", "*.snupkg",
43+
SearchOption.AllDirectories))
44+
{
45+
File.Move(symbolPackage,
46+
packagesDirectory / "Main" / Path.GetFileName(symbolPackage));
47+
Debug("Found symbol package: {PackagePath}", symbolPackage);
48+
}
4649
}
4750
}
4851

49-
Directory.CreateDirectory(packagesDirectory / "Core");
50-
foreach (Project coreProject in CoreProjects)
52+
if (BuildScope != BuildScope.MainOnly)
5153
{
52-
foreach (string package in
53-
Directory.EnumerateFiles(coreProject.Directory / "bin", "*.nupkg",
54-
SearchOption.AllDirectories))
54+
Directory.CreateDirectory(packagesDirectory / "Core");
55+
foreach (Project coreProject in CoreProjects)
5556
{
56-
File.Move(package, packagesDirectory / "Core" / Path.GetFileName(package));
57-
Debug("Found nuget package: {PackagePath}", package);
58-
packages.Add(Path.GetFileName(package));
59-
}
57+
foreach (string package in
58+
Directory.EnumerateFiles(coreProject.Directory / "bin", "*.nupkg",
59+
SearchOption.AllDirectories))
60+
{
61+
File.Move(package, packagesDirectory / "Core" / Path.GetFileName(package));
62+
Debug("Found nuget package: {PackagePath}", package);
63+
packages.Add(Path.GetFileName(package));
64+
}
6065

61-
foreach (string symbolPackage in
62-
Directory.EnumerateFiles(coreProject.Directory / "bin", "*.snupkg",
63-
SearchOption.AllDirectories))
64-
{
65-
File.Move(symbolPackage,
66-
packagesDirectory / "Core" / Path.GetFileName(symbolPackage));
67-
Debug("Found symbol package: {PackagePath}", symbolPackage);
66+
foreach (string symbolPackage in
67+
Directory.EnumerateFiles(coreProject.Directory / "bin", "*.snupkg",
68+
SearchOption.AllDirectories))
69+
{
70+
File.Move(symbolPackage,
71+
packagesDirectory / "Core" / Path.GetFileName(symbolPackage));
72+
Debug("Found symbol package: {PackagePath}", symbolPackage);
73+
}
6874
}
6975
}
7076

Pipeline/Build.UnitTest.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ partial class Build
1818
Target DotNetUnitTests => _ => _
1919
.Unlisted()
2020
.DependsOn(Compile)
21+
.OnlyWhenDynamic(() => BuildScope != BuildScope.CoreOnly)
2122
.Executes(() =>
2223
{
2324
string[] excludedFrameworks =

0 commit comments

Comments
 (0)