Skip to content

Commit

Permalink
.NET 8 Upgrade (Multi Framework targetting) (#2181)
Browse files Browse the repository at this point in the history
## 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
  • Loading branch information
seantleonard committed May 9, 2024
1 parent 7804517 commit 85323c7
Show file tree
Hide file tree
Showing 37 changed files with 373 additions and 142 deletions.
13 changes: 12 additions & 1 deletion .pipelines/cosmos-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,17 @@ steps:
- task: NuGetAuthenticate@1
displayName: 'NuGet Authenticate'

# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
# specifying the runtime version a project targets."
- task: UseDotNet@2
displayName: Setup .NET SDK v8.0.x
inputs:
packageType: sdk
version: 8.0.x
installationPath: $(Agent.ToolsDirectory)/dotnet

# Preserving .NET 6 for multi-targeting support
- task: UseDotNet@2
displayName: Setup .NET SDK v6.0.x
inputs:
Expand Down Expand Up @@ -85,7 +96,7 @@ steps:
inputs:
folderPath: '$(System.DefaultWorkingDirectory)'
fileType: 'json'
targetFiles: 'src/out/tests/net6.0/dab-config.CosmosDb_NoSql.json'
targetFiles: 'src/out/tests/*/dab-config.CosmosDb_NoSql.json'

- task: DotNetCoreCLI@2
displayName: 'Run CosmosDb_NoSql Integration Tests'
Expand Down
24 changes: 22 additions & 2 deletions .pipelines/dwsql-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,16 @@ jobs:
- task: NuGetAuthenticate@1
displayName: 'NuGet Authenticate'

# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
# specifying the runtime version a project targets."
- task: UseDotNet@2
displayName: Setup .NET SDK v8.0.x
inputs:
packageType: sdk
version: 8.0.x

# Preserving .NET 6 for multi-targeting support
- task: UseDotNet@2
displayName: Setup .NET SDK v6.0.x
inputs:
Expand Down Expand Up @@ -96,7 +106,7 @@ jobs:
inputs:
folderPath: '$(System.DefaultWorkingDirectory)'
fileType: 'json'
targetFiles: 'src/out/tests/net6.0/dab-config.DwSql.json'
targetFiles: 'src/out/tests/*/dab-config.DwSql.json'

- task: DotNetCoreCLI@2
displayName: 'Run DwSql Integration Tests'
Expand Down Expand Up @@ -160,7 +170,17 @@ jobs:

- task: NuGetAuthenticate@1
displayName: 'NuGet Authenticate'

# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
# specifying the runtime version a project targets."
- task: UseDotNet@2
displayName: Setup .NET SDK v8.0.x
inputs:
packageType: sdk
version: 8.0.x

# Preserving .NET 6 for multi-targeting support
- task: UseDotNet@2
displayName: Setup .NET SDK v6.0.x
inputs:
Expand Down Expand Up @@ -220,7 +240,7 @@ jobs:
inputs:
folderPath: '$(System.DefaultWorkingDirectory)'
fileType: 'json'
targetFiles: 'src/out/tests/net6.0/dab-config.DwSql.json'
targetFiles: 'src/out/tests/*/dab-config.DwSql.json'

- task: DotNetCoreCLI@2
displayName: 'Run DwSql Integration Tests'
Expand Down
24 changes: 22 additions & 2 deletions .pipelines/mssql-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,17 @@ jobs:
steps:
- task: NuGetAuthenticate@1
displayName: 'NuGet Authenticate'

# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
# specifying the runtime version a project targets."
- task: UseDotNet@2
displayName: Setup .NET SDK v8.0.x
inputs:
packageType: sdk
version: 8.0.x

# Preserving .NET 6 for multi-targeting support
- task: UseDotNet@2
displayName: Setup .NET SDK v6.0.x
inputs:
Expand Down Expand Up @@ -100,7 +110,7 @@ jobs:
inputs:
folderPath: '$(System.DefaultWorkingDirectory)'
fileType: 'json'
targetFiles: 'src/out/tests/net6.0/dab-config.MsSql.json'
targetFiles: 'src/out/tests/*/dab-config.MsSql.json'

- task: DotNetCoreCLI@2
displayName: 'Run MsSql Integration Tests'
Expand Down Expand Up @@ -164,7 +174,17 @@ jobs:

- task: NuGetAuthenticate@1
displayName: 'NuGet Authenticate'

# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
# specifying the runtime version a project targets."
- task: UseDotNet@2
displayName: Setup .NET SDK v8.0.x
inputs:
packageType: sdk
version: 8.0.x

# Preserving .NET 6 for multi-targeting support
- task: UseDotNet@2
displayName: Setup .NET SDK v6.0.x
inputs:
Expand Down Expand Up @@ -224,7 +244,7 @@ jobs:
inputs:
folderPath: '$(System.DefaultWorkingDirectory)'
fileType: 'json'
targetFiles: 'src/out/tests/net6.0/dab-config.MsSql.json'
targetFiles: 'src/out/tests/*/dab-config.MsSql.json'

- task: DotNetCoreCLI@2
displayName: 'Run MsSql Integration Tests'
Expand Down
12 changes: 11 additions & 1 deletion .pipelines/mysql-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ jobs:
- task: NuGetAuthenticate@1
displayName: 'NuGet Authenticate'

# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
# specifying the runtime version a project targets."
- task: UseDotNet@2
displayName: Setup .NET SDK v8.0.x
inputs:
packageType: sdk
version: 8.0.x

# Preserving .NET 6 for multi-targeting support
- task: UseDotNet@2
displayName: Setup .NET SDK v6.0.x
inputs:
Expand Down Expand Up @@ -96,7 +106,7 @@ jobs:
inputs:
folderPath: '$(System.DefaultWorkingDirectory)'
fileType: 'json'
targetFiles: 'src/out/tests/net6.0/dab-config.MySql.json'
targetFiles: 'src/out/tests/*/dab-config.MySql.json'

- task: DotNetCoreCLI@2
displayName: 'Run MySql Integration Tests'
Expand Down
12 changes: 11 additions & 1 deletion .pipelines/pg-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ jobs:
- task: NuGetAuthenticate@1
displayName: 'NuGet Authenticate'

# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
# specifying the runtime version a project targets."
- task: UseDotNet@2
displayName: Setup .NET SDK v8.0.x
inputs:
packageType: sdk
version: 8.0.x

# Preserving .NET 6 for multi-targeting support
- task: UseDotNet@2
displayName: Setup .NET SDK v6.0.x
inputs:
Expand Down Expand Up @@ -91,7 +101,7 @@ jobs:
inputs:
folderPath: '$(System.DefaultWorkingDirectory)'
fileType: 'json'
targetFiles: 'src/out/tests/net6.0/dab-config.PostgreSql.json'
targetFiles: 'src/out/tests/*/dab-config.PostgreSql.json'

- task: DotNetCoreCLI@2
displayName: 'Run Postgres Integration Tests'
Expand Down
11 changes: 11 additions & 0 deletions .pipelines/templates/build-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,17 @@ steps:
echo "##vso[task.setvariable variable=\$id]$schemaId"
displayName: Set dab version

# The .NET CLI commands in proceeding tasks use the .NET SDK version specified ("selected") here.
# Per Microsoft Learn Docs, "Selecting the .NET SDK version is independent from
# specifying the runtime version a project targets."
- task: UseDotNet@2
displayName: Setup .NET SDK v8.0.x
inputs:
packageType: sdk
version: 8.0.x
installationPath: $(Agent.ToolsDirectory)/dotnet

# Preserving .NET 6 for multi-targeting support
- task: UseDotNet@2
displayName: Setup .NET SDK v6.0.x
inputs:
Expand Down
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"sdk": {
"version": "6.0.100",
"version": "8.0.100",
"rollForward": "latestFeature"
}
}
64 changes: 36 additions & 28 deletions scripts/create-manifest-file.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,21 @@ if ($isReleaseBuild -eq 'true')
}

# Generating hash for DAB packages
$dotnetTargetFrameworks = "net6.0", "net8.0"
$RIDs = "win-x64", "linux-x64", "osx-x64"
foreach ($RID in $RIDs) {
$fileName = "dab_$RID-$DabVersion.zip"
$filePath = "$BuildOutputDir/publish/$BuildConfiguration/$RID/$fileName"
$download_url = "https://github.com/Azure/data-api-builder/releases/download/$versionTag/$fileName"
$fileHashInfo = Get-FileHash $filePath
$hash = $fileHashInfo.Hash
switch ($RID) {
"win-x64"{
$win_file_hash = $hash
$download_url_win = $download_url
}
"linux-x64"{
$linux_file_hash = $hash
$download_url_linux = $download_url
}
"osx-x64"{
$osx_file_hash = $hash
$download_url_osx = $download_url
}
[hashtable]$frameworkPlatformDownloadMetadata = @{}
[hashtable]$frameworkPlatformFileHashMetadata = @{}

foreach ($targetFramework in $dotnetTargetFrameworks)
{
foreach ($RID in $RIDs) {
$fileName = "dab_${targetFramework}_${RID}-${DabVersion}.zip"
$filePath = "$BuildOutputDir/publish/$BuildConfiguration/$targetFramework/$RID/$fileName"
$download_url = "https://github.com/Azure/data-api-builder/releases/download/$versionTag/$fileName"
$fileHashInfo = Get-FileHash $filePath
$hash = $fileHashInfo.Hash
$frameworkPlatformDownloadMetadata.Add("${targetFramework}_${RID}", $download_url)
$frameworkPlatformFileHashMetadata.Add("${targetFramework}_${RID}", $hash)
}
}

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

# Creating new block to insert latest version
# String substitution requires hashtable to be wrapped in $( $hashtable['key'] ) to avoid parsing issues.
$latestBlock = @'
{
"version": "latest",
"versionId": "${versionId}",
"releaseType": "${releaseType}",
"releaseDate": "${releaseDate}",
"files": {
"linux-x64":{
"url": "${download_url_linux}",
"sha": "${linux_file_hash}"
"linux-x64-net6":{
"url": "$($frameworkPlatformDownloadMetadata["net6.0_linux-x64"])",
"sha": "$($frameworkPlatformFileHashMetadata["net6.0_linux-x64"])"
},
"linux-x64-net8":{
"url": "$($frameworkPlatformDownloadMetadata["net8.0_linux-x64"])",
"sha": "$($frameworkPlatformFileHashMetadata["net8.0_linux-x64"])"
},
"win-x64-net6":{
"url": "$($frameworkPlatformDownloadMetadata["net6.0_win-x64"])",
"sha": "$($frameworkPlatformFileHashMetadata["net6.0_win-x64"])"
},
"win-x64-net8":{
"url": "$($frameworkPlatformDownloadMetadata["net8.0_win-x64"])",
"sha": "$($frameworkPlatformFileHashMetadata["net8.0_win-x64"])"
},
"win-x64":{
"url": "${download_url_win}",
"sha": "${win_file_hash}"
"osx-x64-net6":{
"url": "$($frameworkPlatformDownloadMetadata["net6.0_osx-x64"])",
"sha": "$($frameworkPlatformFileHashMetadata["net6.0_osx-x64"])"
},
"osx-x64":{
"url": "${download_url_osx}",
"sha": "${osx_file_hash}"
"osx-x64-net8":{
"url": "$($frameworkPlatformDownloadMetadata["net8.0_osx-x64"])",
"sha": "$($frameworkPlatformFileHashMetadata["net8.0_osx-x64"])"
},
"nuget": {
"url": "${download_url_nuget}",
Expand Down
3 changes: 2 additions & 1 deletion scripts/notice-generation.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Invoke-WebRequest $chiliCreamLicenseMetadataURL -UseBasicParsing |

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

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

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

# Prepare license content for writing to file.
$sqlClientSNIComponentName = "`r`nMICROSOFT.DATA.SQLCLIENT.SNI`r`n`r`n"
Expand Down
36 changes: 26 additions & 10 deletions scripts/publish.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,39 @@ param (
)

$BuildRoot = Split-Path $PSScriptRoot -Parent

$dotnetTargetFrameworks = "net6.0", "net8.0"
$RIDs = "win-x64", "linux-x64", "osx-x64"

# Runs dotnet publish for each target framework and RID.
# Example results:
# \dotnetpublishout\publish\Release\net8.0\win-x64\dab
# \dotnetpublishout\publish\Release\net6.0\win-x64\dab
if ($Package)
{
foreach ($RID in $RIDs) {
$cmd = "dotnet publish --configuration $BuildConfiguration --output $BuildOutputDir/publish/$BuildConfiguration/$RID/dab --runtime $RID --self-contained true -p:Version=$DabVersion $BuildRoot/src/Cli/Cli.csproj"
Write-Host $cmd
Invoke-Expression $cmd
}
foreach ($targetFramework in $dotnetTargetFrameworks)
{
foreach ($RID in $RIDs) {
$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"
Write-Host $cmd
Invoke-Expression $cmd
}
}
}

# Zips the published output for each target framework and RID.
# For example:
# \dotnetpublishout\publish\Release\net8.0\win-x64\dab_net8.0_win-x64-0.14.123-rc.zip
# \dotnetpublishout\publish\Release\net6.0\win-x64\dab_net6.0_win-x64-0.14.123-rc.zip
if ($CreateZip)
{
foreach ($RID in $RIDs) {
$cmd = "Compress-Archive -Force -Path $BuildOutputDir/publish/$BuildConfiguration/$RID/dab/* -DestinationPath $BuildOutputDir/publish/$BuildConfiguration/$RID/dab_$RID-$DabVersion.zip"
Write-Host $cmd
Invoke-Expression $cmd
foreach ($targetFramework in $dotnetTargetFrameworks)
{
foreach ($RID in $RIDs) {
$filesToZipPath = "$BuildOutputDir/publish/$BuildConfiguration/$targetFramework/$RID/dab/*"
$archiveOutputPath = "$BuildOutputDir/publish/$BuildConfiguration/$targetFramework/$RID/dab_${targetFramework}_${RID}-${DabVersion}.zip"
$cmd = "Compress-Archive -Force -Path $filesToZipPath -DestinationPath $archiveOutputPath"
Write-Host $cmd
Invoke-Expression $cmd
}
}
}
2 changes: 1 addition & 1 deletion src/Auth/Azure.DataApiBuilder.Auth.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFrameworks>net8.0;net6.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<OutputPath>$(BaseOutputPath)\engine</OutputPath>
Expand Down
7 changes: 5 additions & 2 deletions src/Cli.Tests/Cli.Tests.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFrameworks>net8.0;net6.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
Expand All @@ -14,7 +14,10 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="coverlet.msbuild" />
<PackageReference Include="coverlet.msbuild">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="Moq" />
<PackageReference Include="MSTest.TestAdapter" />
Expand Down

0 comments on commit 85323c7

Please sign in to comment.