Reputation: 2003
I have a C# package which currently supports dotnet 8 and I'm trying to modify it to add dotnet 6 and 7 support as well. I've gotten it to build for all versions using dotnet 8 locally on my laptop, using <TargetFrameworks>net6.0;net7.0;net8.0</TargetFrameworks>
in the .csproj
file and removing all C# features added after net6.0. However when I push it to GitHub and my workflow runs in Github Actions, I test it against dotnet 6 and 7 as well as 8, and it breaks on the dotnet restore
step.
My workflow:
name: .NET
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
env:
DOTNET_CLI_TELEMETRY_OPTOUT: true
DOTNET_GENERATE_ASPNET_CERTIFICATE: false
jobs:
build:
runs-on: macos-latest
name: .NET ${{ matrix.dotnet }}
strategy:
matrix:
dotnet:
- 8.0 # EOL: 2026-11-10
- 7.0 # EOL: 2024-05-14
- 6.0 # EOL: 2024-11-12
# version support doc: https://dotnet.microsoft.com/en-us/platform/support/policy/dotnet-core
steps:
- uses: actions/checkout@v3
with:
repository: getargv/getargv
path: getargv
token: ${{ secrets.GH_PAT }}
- name: Build libgetargv
run: make install_dylib
working-directory: getargv
- uses: actions/checkout@v3
with:
path: getargv.cs
- name: Setup .NET
uses: actions/setup-dotnet@v4
id: setup
with:
dotnet-version: ${{ matrix.dotnet }}.x
- name: Create temporary global.json
run: "echo '{\"sdk\":{\"version\": \"${{ steps.setup.outputs.dotnet-version }}\"}}' > ./global.json"
working-directory: getargv.cs
- name: Restore dependencies
run: dotnet restore
working-directory: getargv.cs
- name: Build
run: dotnet build --no-restore --framework net${{ matrix.dotnet }}
working-directory: getargv.cs
- name: Test
run: dotnet test --no-build --verbosity normal
working-directory: getargv.cs
I can set the framework when building with a flag, but the restore step has no such flag.
The error I get is fairly predictable:
Error: /Users/runner/.dotnet/sdk/7.0.404/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.TargetFrameworkInference.targets(160,5): error NETSDK1045: The current .NET SDK does not support targeting .NET 8.0. Either target .NET 7.0 or lower, or use a version of the .NET SDK that supports .NET 8.0. Download the .NET SDK from https://aka.ms/dotnet/download [/Users/runner/work/getargv.cs/getargv.cs/getargv.cs/Getargv/Getargv.csproj::TargetFramework=net8.0]
Error: /Users/runner/.dotnet/sdk/7.0.404/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.TargetFrameworkInference.targets(160,5): error NETSDK1045: The current .NET SDK does not support targeting .NET 8.0. Either target .NET 7.0 or lower, or use a version of the .NET SDK that supports .NET 8.0. Download the .NET SDK from https://aka.ms/dotnet/download [/Users/runner/work/getargv.cs/getargv.cs/getargv.cs/Getargv.Tool/Getargv.Tool.csproj::TargetFramework=net8.0]
Error: /Users/runner/.dotnet/sdk/7.0.404/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.TargetFrameworkInference.targets(160,5): error NETSDK1045: The current .NET SDK does not support targeting .NET 8.0. Either target .NET 7.0 or lower, or use a version of the .NET SDK that supports .NET 8.0. Download the .NET SDK from https://aka.ms/dotnet/download [/Users/runner/work/getargv.cs/getargv.cs/getargv.cs/Getargv.Tests/Getargv.Tests.csproj::TargetFramework=net8.0]
Error: /Users/runner/.dotnet/sdk/6.0.417/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.TargetFrameworkInference.targets(144,5): error NETSDK1045: The current .NET SDK does not support targeting .NET 7.0. Either target .NET 6.0 or lower, or use a version of the .NET SDK that supports .NET 7.0. [/Users/runner/work/getargv.cs/getargv.cs/getargv.cs/Getargv/Getargv.csproj]
Error: /Users/runner/.dotnet/sdk/6.0.417/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.TargetFrameworkInference.targets(144,5): error NETSDK1045: The current .NET SDK does not support targeting .NET 7.0. Either target .NET 6.0 or lower, or use a version of the .NET SDK that supports .NET 7.0. [/Users/runner/work/getargv.cs/getargv.cs/getargv.cs/Getargv.Tool/Getargv.Tool.csproj]
Error: /Users/runner/.dotnet/sdk/6.0.417/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.TargetFrameworkInference.targets(144,5): error NETSDK1045: The current .NET SDK does not support targeting .NET 7.0. Either target .NET 6.0 or lower, or use a version of the .NET SDK that supports .NET 7.0. [/Users/runner/work/getargv.cs/getargv.cs/getargv.cs/Getargv.Tests/Getargv.Tests.csproj]
How do people test against older dotnet versions while also supporting newer versions?
Edit:
Changing the build command to: dotnet build --framework net${{ matrix.dotnet }}
doesn't use the specified framework for restore.
Upvotes: 3
Views: 2160
Reputation: 1576
Yes, things are a little more complicated for a multi-targeting project. This answer is just a summary how to build them using CLI when you have only one of the target frameworks installed.
Suppose you have .NET 6 SDK installed only and your solution projects multi-target net6.0 and net8.0.
Then the following commands work for me:
dotnet build -f net6.0 --no-restore
dotnet build -p:TargetFrameworks=net6.0
dotnet restore -p:TargetFrameworks=net6.0
dotnet restore -p:TargetFramework=net6.0
dotnet test -f net6.0 --no-restore
dotnet test -p:TargetFrameworks=net6.0
And the following ones do not work:
dotnet build
dotnet build -f net6.0
dotnet build -p:TargetFramework=net6.0
dotnet restore
dotnet test
dotnet test -f net6.0
dotnet test -p:TargetFramework=net6.0
As you can see, there is an inconsistency between using --framework
switch, TargetFramework
and TargetFrameworks
properties in the different dotnet
-subcommands.
My case is that I have multi-targeted solution (the main project targets net6.0 and the tests project targets net6.0 and net8.0 via TargetFrameworks
switch).
For me, having dotnet build -f net6.0
not working in that case is the strangiest thing with the dotnet
CLI, worthy of an issue on MS dotnet github page. Maybe it's already added, didn't check that.
P.S. Another case, you have .NET 8 SDK installed and the same multi-targeting solution (net6.0 main project and net6.0+net8.0 test project). Then the things are rather different, and the following commands succeeded:
dotnet build
dotnet build -f net6.0
dotnet restore
dotnet test -f net8.0
Upvotes: 0
Reputation: 2230
You can specify the target framework for dotnet restore with dotnet restore -p:TargetFramework=net7.0
.
dotnet restore
and dotnet build
are wrappers around dotnet msbuild
, and dotnet restore
is actually the same as calling dotnet msbuild -t:restore
.
Some additional information can be found in this question.
I would try changing your code like this:
- name: Restore dependencies
run: dotnet restore -p:TargetFramework=net${{ matrix.dotnet }}
Upvotes: 3
Reputation: 3270
<TargetFrameworks>
tag in the test csproj to pick the .net versions that should be tested. The testrunner will run each test in each .net version listed there.Thats sufficient for every project I have seen so far.
If your really really want to test, like you drafted, using a test matrix to ensure support / passed tests on lacking SDKs your approach seems to be reasonable. Things I fixed in your GHA workflow:
build:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
dotnet: [8, 7, 6]
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ matrix.dotnet }}.0.x
- name: Restore dependencies
run: dotnet restore
- name: Build
run: dotnet build --configuration Release --no-restore --framework net${{ matrix.dotnet }}.0
- name: Test
run: dotnet test --no-build --verbosity normal --configuration Release --framework net${{ matrix.dotnet }}.0
I skipped complexity of global.json and sdk pinning in Directory.Build.props. It does not really make sense in case of explicitly installing/omitting the SDK version anyway. And settings in global.json were related to NETSDK1045 in the past.
A starting point that does not fail (added latestMajor) is e.g.:
- name: Create temporary global.json
run: "echo '{\"sdk\":{\"version\": \"${{ matrix.dotnet }}.0.0\" ,\"rollForward\": \"latestMajor\" }}' > ./global.json"
Upvotes: 0
Reputation: 336
dotnet --version # Check the installed versions
dotnet --list-sdks # List all installed SDKs
dotnet --global install "desired_version" # Install the desired version
After specifying the .NET SDK version, execute the dotnet restore command for your multi-target framework project. This command will restore the NuGet packages required for your project.
# Navigate to your project directory
cd path/to/your/project
dotnet restore
Once the packages are restored, you can run your tests using the dotnet test command. This assumes you have unit tests set up for your project.
dotnet test
Make sure to adapt the version numbers and paths according to your project's requirements.
Example:
# Install .NET SDK 7.0.404
dotnet --global install 7.0.404
# Navigate to your project directory
cd path/to/your/project
# Restore packages
dotnet restore
# Run tests
dotnet test
Upvotes: 0