Skip to content

Commit 85323c7

Browse files
authored
.NET 8 Upgrade (Multi Framework targetting) (#2181)
## Why make this change? - Closes #2140 ## What is this change? - Updates all `.csproj` files to target both .NET8 and .NET6. (source: [How to multi target](https://learn.microsoft.com/dotnet/core/tutorials/libraries#how-to-multitarget) ```xml <TargetFrameworks>net8.0;net6.0</TargetFrameworks> ``` - Update **Directory.Packages.Props** to include framework specific sections targeting dependency versions compatible with .NET6 - Ref: https://josef.codes/multi-targeting-your-nuget-packages/ ```xml <ItemGroup Condition="'$(TargetFramework)' == 'net8.0'"> <PackageVersion Include="Microsoft.AspNetCore.Authorization" Version="8.0.4" /> </ItemGroup> <ItemGroup Condition="'$(TargetFramework)' == 'net6.0'"> <PackageVersion Include="Microsoft.AspNetCore.TestHost" Version="6.0.29" /> </ItemGroup> ``` - Added framework specific constructors for EasyAuth/Simulator AuthenticationHandlers because `ISystemClock` was deprecated in .NET8 and is a required constructor parameter when overriding `AuthenticationHandler` dotnet class used for custom authentication handlers. - https://learn.microsoft.com/en-us/dotnet/core/compatibility/aspnet-core/8.0/isystemclock-obsolete - [Multi target dotnet project && code](https://learn.microsoft.com/nuget/create-packages/multiple-target-frameworks-project-file#create-a-project-that-supports-multiple-net-framework-versions) - Updated instances of pulling client role header value (GraphQLFilterParser, SqlMutationEngine) due to stricter nullability checks (now errors) in .NET 8. The following original code "possibly returns null" and needs to be handled. ```csharp GetHttpContext().Request.Headers[AuthorizationResolver.CLIENT_ROLE_HEADER]; ``` Changed to be a conditional check: ```csharp if (!GetHttpContext().Request.Headers.TryGetValue(AuthorizationResolver.CLIENT_ROLE_HEADER, out StringValues headerValues) && headerValues.Count != 1) ``` - Due to stricter .NET 8 nullability checks, DabCacheService specification of return type now specifies nullable jsonElement? to be consistent with method signature. ```csharp async (FusionCacheFactoryExecutionContext<JsonElement?> ctx, CancellationToken ct) => ``` - Startup class also gets a fix for stricter nullability when processing config file name. Previously a null value was possible according to the compiler: OLD: ```csharp string configFileName = Configuration.GetValue<string>("ConfigFileName", FileSystemRuntimeConfigLoader.DEFAULT_CONFIG_FILE_NAME); ``` NEW ```csharp string configFileName = Configuration.GetValue<string>("ConfigFileName") ?? FileSystemRuntimeConfigLoader.DEFAULT_CONFIG_FILE_NAME; ``` ## How was this tested? This isn't a feature addition, but ensure that all existing tests pass. - [x] Integration Tests - [x] Unit Tests
1 parent 7804517 commit 85323c7

37 files changed

+373
-142
lines changed

.pipelines/cosmos-pipelines.yml

+12-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,17 @@ steps:
3838
- task: NuGetAuthenticate@1
3939
displayName: 'NuGet Authenticate'
4040

41+
# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
42+
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
43+
# specifying the runtime version a project targets."
44+
- task: UseDotNet@2
45+
displayName: Setup .NET SDK v8.0.x
46+
inputs:
47+
packageType: sdk
48+
version: 8.0.x
49+
installationPath: $(Agent.ToolsDirectory)/dotnet
50+
51+
# Preserving .NET 6 for multi-targeting support
4152
- task: UseDotNet@2
4253
displayName: Setup .NET SDK v6.0.x
4354
inputs:
@@ -85,7 +96,7 @@ steps:
8596
inputs:
8697
folderPath: '$(System.DefaultWorkingDirectory)'
8798
fileType: 'json'
88-
targetFiles: 'src/out/tests/net6.0/dab-config.CosmosDb_NoSql.json'
99+
targetFiles: 'src/out/tests/*/dab-config.CosmosDb_NoSql.json'
89100

90101
- task: DotNetCoreCLI@2
91102
displayName: 'Run CosmosDb_NoSql Integration Tests'

.pipelines/dwsql-pipelines.yml

+22-2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,16 @@ jobs:
3131
- task: NuGetAuthenticate@1
3232
displayName: 'NuGet Authenticate'
3333

34+
# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
35+
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
36+
# specifying the runtime version a project targets."
37+
- task: UseDotNet@2
38+
displayName: Setup .NET SDK v8.0.x
39+
inputs:
40+
packageType: sdk
41+
version: 8.0.x
42+
43+
# Preserving .NET 6 for multi-targeting support
3444
- task: UseDotNet@2
3545
displayName: Setup .NET SDK v6.0.x
3646
inputs:
@@ -96,7 +106,7 @@ jobs:
96106
inputs:
97107
folderPath: '$(System.DefaultWorkingDirectory)'
98108
fileType: 'json'
99-
targetFiles: 'src/out/tests/net6.0/dab-config.DwSql.json'
109+
targetFiles: 'src/out/tests/*/dab-config.DwSql.json'
100110

101111
- task: DotNetCoreCLI@2
102112
displayName: 'Run DwSql Integration Tests'
@@ -160,7 +170,17 @@ jobs:
160170

161171
- task: NuGetAuthenticate@1
162172
displayName: 'NuGet Authenticate'
173+
174+
# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
175+
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
176+
# specifying the runtime version a project targets."
177+
- task: UseDotNet@2
178+
displayName: Setup .NET SDK v8.0.x
179+
inputs:
180+
packageType: sdk
181+
version: 8.0.x
163182

183+
# Preserving .NET 6 for multi-targeting support
164184
- task: UseDotNet@2
165185
displayName: Setup .NET SDK v6.0.x
166186
inputs:
@@ -220,7 +240,7 @@ jobs:
220240
inputs:
221241
folderPath: '$(System.DefaultWorkingDirectory)'
222242
fileType: 'json'
223-
targetFiles: 'src/out/tests/net6.0/dab-config.DwSql.json'
243+
targetFiles: 'src/out/tests/*/dab-config.DwSql.json'
224244

225245
- task: DotNetCoreCLI@2
226246
displayName: 'Run DwSql Integration Tests'

.pipelines/mssql-pipelines.yml

+22-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,17 @@ jobs:
3131
steps:
3232
- task: NuGetAuthenticate@1
3333
displayName: 'NuGet Authenticate'
34+
35+
# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
36+
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
37+
# specifying the runtime version a project targets."
38+
- task: UseDotNet@2
39+
displayName: Setup .NET SDK v8.0.x
40+
inputs:
41+
packageType: sdk
42+
version: 8.0.x
3443

44+
# Preserving .NET 6 for multi-targeting support
3545
- task: UseDotNet@2
3646
displayName: Setup .NET SDK v6.0.x
3747
inputs:
@@ -100,7 +110,7 @@ jobs:
100110
inputs:
101111
folderPath: '$(System.DefaultWorkingDirectory)'
102112
fileType: 'json'
103-
targetFiles: 'src/out/tests/net6.0/dab-config.MsSql.json'
113+
targetFiles: 'src/out/tests/*/dab-config.MsSql.json'
104114

105115
- task: DotNetCoreCLI@2
106116
displayName: 'Run MsSql Integration Tests'
@@ -164,7 +174,17 @@ jobs:
164174

165175
- task: NuGetAuthenticate@1
166176
displayName: 'NuGet Authenticate'
177+
178+
# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
179+
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
180+
# specifying the runtime version a project targets."
181+
- task: UseDotNet@2
182+
displayName: Setup .NET SDK v8.0.x
183+
inputs:
184+
packageType: sdk
185+
version: 8.0.x
167186

187+
# Preserving .NET 6 for multi-targeting support
168188
- task: UseDotNet@2
169189
displayName: Setup .NET SDK v6.0.x
170190
inputs:
@@ -224,7 +244,7 @@ jobs:
224244
inputs:
225245
folderPath: '$(System.DefaultWorkingDirectory)'
226246
fileType: 'json'
227-
targetFiles: 'src/out/tests/net6.0/dab-config.MsSql.json'
247+
targetFiles: 'src/out/tests/*/dab-config.MsSql.json'
228248

229249
- task: DotNetCoreCLI@2
230250
displayName: 'Run MsSql Integration Tests'

.pipelines/mysql-pipelines.yml

+11-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@ jobs:
3030
- task: NuGetAuthenticate@1
3131
displayName: 'NuGet Authenticate'
3232

33+
# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
34+
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
35+
# specifying the runtime version a project targets."
36+
- task: UseDotNet@2
37+
displayName: Setup .NET SDK v8.0.x
38+
inputs:
39+
packageType: sdk
40+
version: 8.0.x
41+
42+
# Preserving .NET 6 for multi-targeting support
3343
- task: UseDotNet@2
3444
displayName: Setup .NET SDK v6.0.x
3545
inputs:
@@ -96,7 +106,7 @@ jobs:
96106
inputs:
97107
folderPath: '$(System.DefaultWorkingDirectory)'
98108
fileType: 'json'
99-
targetFiles: 'src/out/tests/net6.0/dab-config.MySql.json'
109+
targetFiles: 'src/out/tests/*/dab-config.MySql.json'
100110

101111
- task: DotNetCoreCLI@2
102112
displayName: 'Run MySql Integration Tests'

.pipelines/pg-pipelines.yml

+11-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,16 @@ jobs:
2525
- task: NuGetAuthenticate@1
2626
displayName: 'NuGet Authenticate'
2727

28+
# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
29+
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
30+
# specifying the runtime version a project targets."
31+
- task: UseDotNet@2
32+
displayName: Setup .NET SDK v8.0.x
33+
inputs:
34+
packageType: sdk
35+
version: 8.0.x
36+
37+
# Preserving .NET 6 for multi-targeting support
2838
- task: UseDotNet@2
2939
displayName: Setup .NET SDK v6.0.x
3040
inputs:
@@ -91,7 +101,7 @@ jobs:
91101
inputs:
92102
folderPath: '$(System.DefaultWorkingDirectory)'
93103
fileType: 'json'
94-
targetFiles: 'src/out/tests/net6.0/dab-config.PostgreSql.json'
104+
targetFiles: 'src/out/tests/*/dab-config.PostgreSql.json'
95105

96106
- task: DotNetCoreCLI@2
97107
displayName: 'Run Postgres Integration Tests'

.pipelines/templates/build-pipelines.yml

+11
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ steps:
5050
echo "##vso[task.setvariable variable=\$id]$schemaId"
5151
displayName: Set dab version
5252

53+
# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
54+
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
55+
# specifying the runtime version a project targets."
56+
- task: UseDotNet@2
57+
displayName: Setup .NET SDK v8.0.x
58+
inputs:
59+
packageType: sdk
60+
version: 8.0.x
61+
installationPath: $(Agent.ToolsDirectory)/dotnet
62+
63+
# Preserving .NET 6 for multi-targeting support
5364
- task: UseDotNet@2
5465
displayName: Setup .NET SDK v6.0.x
5566
inputs:

global.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"sdk": {
3-
"version": "6.0.100",
3+
"version": "8.0.100",
44
"rollForward": "latestFeature"
55
}
66
}

scripts/create-manifest-file.ps1

+36-28
Original file line numberDiff line numberDiff line change
@@ -21,26 +21,21 @@ if ($isReleaseBuild -eq 'true')
2121
}
2222

2323
# Generating hash for DAB packages
24+
$dotnetTargetFrameworks = "net6.0", "net8.0"
2425
$RIDs = "win-x64", "linux-x64", "osx-x64"
25-
foreach ($RID in $RIDs) {
26-
$fileName = "dab_$RID-$DabVersion.zip"
27-
$filePath = "$BuildOutputDir/publish/$BuildConfiguration/$RID/$fileName"
28-
$download_url = "https://github.com/Azure/data-api-builder/releases/download/$versionTag/$fileName"
29-
$fileHashInfo = Get-FileHash $filePath
30-
$hash = $fileHashInfo.Hash
31-
switch ($RID) {
32-
"win-x64"{
33-
$win_file_hash = $hash
34-
$download_url_win = $download_url
35-
}
36-
"linux-x64"{
37-
$linux_file_hash = $hash
38-
$download_url_linux = $download_url
39-
}
40-
"osx-x64"{
41-
$osx_file_hash = $hash
42-
$download_url_osx = $download_url
43-
}
26+
[hashtable]$frameworkPlatformDownloadMetadata = @{}
27+
[hashtable]$frameworkPlatformFileHashMetadata = @{}
28+
29+
foreach ($targetFramework in $dotnetTargetFrameworks)
30+
{
31+
foreach ($RID in $RIDs) {
32+
$fileName = "dab_${targetFramework}_${RID}-${DabVersion}.zip"
33+
$filePath = "$BuildOutputDir/publish/$BuildConfiguration/$targetFramework/$RID/$fileName"
34+
$download_url = "https://github.com/Azure/data-api-builder/releases/download/$versionTag/$fileName"
35+
$fileHashInfo = Get-FileHash $filePath
36+
$hash = $fileHashInfo.Hash
37+
$frameworkPlatformDownloadMetadata.Add("${targetFramework}_${RID}", $download_url)
38+
$frameworkPlatformFileHashMetadata.Add("${targetFramework}_${RID}", $hash)
4439
}
4540
}
4641

@@ -52,24 +47,37 @@ $nuget_file_hash = $fileHashInfo.Hash
5247
$download_url_nuget = "https://github.com/Azure/data-api-builder/releases/download/$versionTag/$nugetFileName"
5348

5449
# Creating new block to insert latest version
50+
# String substitution requires hashtable to be wrapped in $( $hashtable['key'] ) to avoid parsing issues.
5551
$latestBlock = @'
5652
{
5753
"version": "latest",
5854
"versionId": "${versionId}",
5955
"releaseType": "${releaseType}",
6056
"releaseDate": "${releaseDate}",
6157
"files": {
62-
"linux-x64":{
63-
"url": "${download_url_linux}",
64-
"sha": "${linux_file_hash}"
58+
"linux-x64-net6":{
59+
"url": "$($frameworkPlatformDownloadMetadata["net6.0_linux-x64"])",
60+
"sha": "$($frameworkPlatformFileHashMetadata["net6.0_linux-x64"])"
61+
},
62+
"linux-x64-net8":{
63+
"url": "$($frameworkPlatformDownloadMetadata["net8.0_linux-x64"])",
64+
"sha": "$($frameworkPlatformFileHashMetadata["net8.0_linux-x64"])"
65+
},
66+
"win-x64-net6":{
67+
"url": "$($frameworkPlatformDownloadMetadata["net6.0_win-x64"])",
68+
"sha": "$($frameworkPlatformFileHashMetadata["net6.0_win-x64"])"
69+
},
70+
"win-x64-net8":{
71+
"url": "$($frameworkPlatformDownloadMetadata["net8.0_win-x64"])",
72+
"sha": "$($frameworkPlatformFileHashMetadata["net8.0_win-x64"])"
6573
},
66-
"win-x64":{
67-
"url": "${download_url_win}",
68-
"sha": "${win_file_hash}"
74+
"osx-x64-net6":{
75+
"url": "$($frameworkPlatformDownloadMetadata["net6.0_osx-x64"])",
76+
"sha": "$($frameworkPlatformFileHashMetadata["net6.0_osx-x64"])"
6977
},
70-
"osx-x64":{
71-
"url": "${download_url_osx}",
72-
"sha": "${osx_file_hash}"
78+
"osx-x64-net8":{
79+
"url": "$($frameworkPlatformDownloadMetadata["net8.0_osx-x64"])",
80+
"sha": "$($frameworkPlatformFileHashMetadata["net8.0_osx-x64"])"
7381
},
7482
"nuget": {
7583
"url": "${download_url_nuget}",

scripts/notice-generation.ps1

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Invoke-WebRequest $chiliCreamLicenseMetadataURL -UseBasicParsing |
1515

1616
# Download and save the Microsoft.Data.SqlClient.SNI.runtime license
1717
$sqlClientSNILicenseSavePath = "$BuildArtifactStagingDir/sqlclient_sni_runtime.txt"
18-
$sqlClientSNILicenseMetadataURL = "https://www.nuget.org/packages/Microsoft.Data.SqlClient.SNI.runtime/5.0.1/License"
18+
$sqlClientSNILicenseMetadataURL = "https://www.nuget.org/packages/Microsoft.Data.SqlClient.SNI.runtime/5.2.0/License"
1919
$pageContent = Invoke-WebRequest $sqlClientSNILicenseMetadataURL -UseBasicParsing
2020

2121
# Regular expression with three capture groups.
@@ -31,6 +31,7 @@ $noticeFilePath = "$BuildSourcesDir/NOTICE.txt"
3131

3232
# Replace erroneous copyright, using [System.IO.File] for better performance than Get-Content and Set-Content
3333
$content = [System.IO.File]::ReadAllText($noticeFilePath).Replace("(c) Microsoft 2023`r`n", "")
34+
$content = [System.IO.File]::ReadAllText($noticeFilePath).Replace("(c) Microsoft 2024`r`n", "")
3435

3536
# Prepare license content for writing to file.
3637
$sqlClientSNIComponentName = "`r`nMICROSOFT.DATA.SQLCLIENT.SNI`r`n`r`n"

scripts/publish.ps1

+26-10
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,39 @@ param (
1010
)
1111

1212
$BuildRoot = Split-Path $PSScriptRoot -Parent
13-
13+
$dotnetTargetFrameworks = "net6.0", "net8.0"
1414
$RIDs = "win-x64", "linux-x64", "osx-x64"
1515

16+
# Runs dotnet publish for each target framework and RID.
17+
# Example results:
18+
# \dotnetpublishout\publish\Release\net8.0\win-x64\dab
19+
# \dotnetpublishout\publish\Release\net6.0\win-x64\dab
1620
if ($Package)
1721
{
18-
foreach ($RID in $RIDs) {
19-
$cmd = "dotnet publish --configuration $BuildConfiguration --output $BuildOutputDir/publish/$BuildConfiguration/$RID/dab --runtime $RID --self-contained true -p:Version=$DabVersion $BuildRoot/src/Cli/Cli.csproj"
20-
Write-Host $cmd
21-
Invoke-Expression $cmd
22-
}
22+
foreach ($targetFramework in $dotnetTargetFrameworks)
23+
{
24+
foreach ($RID in $RIDs) {
25+
$cmd = "dotnet publish --framework $targetFramework --configuration $BuildConfiguration --output $BuildOutputDir/publish/$BuildConfiguration/$targetFramework/$RID/dab --runtime $RID --self-contained true -p:Version=$DabVersion $BuildRoot/src/Cli/Cli.csproj"
26+
Write-Host $cmd
27+
Invoke-Expression $cmd
28+
}
29+
}
2330
}
2431

32+
# Zips the published output for each target framework and RID.
33+
# For example:
34+
# \dotnetpublishout\publish\Release\net8.0\win-x64\dab_net8.0_win-x64-0.14.123-rc.zip
35+
# \dotnetpublishout\publish\Release\net6.0\win-x64\dab_net6.0_win-x64-0.14.123-rc.zip
2536
if ($CreateZip)
2637
{
27-
foreach ($RID in $RIDs) {
28-
$cmd = "Compress-Archive -Force -Path $BuildOutputDir/publish/$BuildConfiguration/$RID/dab/* -DestinationPath $BuildOutputDir/publish/$BuildConfiguration/$RID/dab_$RID-$DabVersion.zip"
29-
Write-Host $cmd
30-
Invoke-Expression $cmd
38+
foreach ($targetFramework in $dotnetTargetFrameworks)
39+
{
40+
foreach ($RID in $RIDs) {
41+
$filesToZipPath = "$BuildOutputDir/publish/$BuildConfiguration/$targetFramework/$RID/dab/*"
42+
$archiveOutputPath = "$BuildOutputDir/publish/$BuildConfiguration/$targetFramework/$RID/dab_${targetFramework}_${RID}-${DabVersion}.zip"
43+
$cmd = "Compress-Archive -Force -Path $filesToZipPath -DestinationPath $archiveOutputPath"
44+
Write-Host $cmd
45+
Invoke-Expression $cmd
46+
}
3147
}
3248
}

src/Auth/Azure.DataApiBuilder.Auth.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
4+
<TargetFrameworks>net8.0;net6.0</TargetFrameworks>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
<OutputPath>$(BaseOutputPath)\engine</OutputPath>

src/Cli.Tests/Cli.Tests.csproj

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>net6.0</TargetFramework>
4+
<TargetFrameworks>net8.0;net6.0</TargetFrameworks>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
77
<IsPackable>false</IsPackable>
@@ -14,7 +14,10 @@
1414
<PrivateAssets>all</PrivateAssets>
1515
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
1616
</PackageReference>
17-
<PackageReference Include="coverlet.msbuild" />
17+
<PackageReference Include="coverlet.msbuild">
18+
<PrivateAssets>all</PrivateAssets>
19+
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
20+
</PackageReference>
1821
<PackageReference Include="Microsoft.NET.Test.Sdk" />
1922
<PackageReference Include="Moq" />
2023
<PackageReference Include="MSTest.TestAdapter" />

0 commit comments

Comments
 (0)