github-actionsnuget-package-restoredotnet-sdk

dotnet restore solution is restoring projects like they are .net framework projects when called from GitHub Actions


I have a solution with many projects, and we are migrating to .NET SDK style projects, but for now we have a mix of .NET framework style projects and .NET SDK style projects.

We are also migrating to GitHub actions, and this solution was building without errors previously, but the restore action started failing when dotnet was updated from 6.0.300 to 6.0.400 (update: I tried targeting 6.0.300 specifically in the setup-dotnet action, but it's throwing the same errors, so I'm not sure what changed to cause it to fail like this when it was working before.)

I updated our local action server to 6.0.400, and when I run the command dotnet restore ./path/to/solution.sln it is restoring the NuGet packages for just the .NET SDK style projects as expected.

dotnet is installed with this GitHub action

    - name: Setup .NET
      uses: actions/setup-dotnet@v2
      with:
        dotnet-version: 6.0.x

and restore is being called with this GitHub action

    - name: Restore dependencies
      run: dotnet restore ${{env.SOLUTION_FILE_PATH}}

and when dotnet restore is being run from the GitHub action, I am getting the following error error MSB4057: The target "Restore" does not exist in the project. for all of the .NET SDK style projects. It's as if it's trying to restore NuGet packages using the older .NET Framework style NuGet packages. This is very different than what I've seen before and is unexpected. I have a separate action for calling nuget restore ./path/to/solution.sln for restoring packages for the .NET framework style projects, and I'm expecting dotnet restore to only restore the .NET SDK style projects.

Has anyone else run into similar problems with dotnet 6.0.400? Are there better options for restoring NuGet packages in GitHub actions?

I'm not really sure where to look next because running the command line commands locally work exactly how I would expect them to, and it only behaves oddly when getting called from GitHub actions.

Update: I've been able to reproduce the failure locally by running the dotnet version that is being installed locally as part of actions/setup-dotnet@v2

If I run dotnet restore ... from the global install location C:\Program Files\dotnet\dotnet.exe then I get the following output which is what I expect

Determining projects to restore...
Restored C:\actions-runner\_work\MySolution\MySolution\src\FirstSdkProject\FirstSdkProject.csproj (in 335 ms). Restored C:\actions-runner\_work\MySolution\MySolution\src\SecondSdkProject\SecondSdkProject.csproj ( in 357 ms).

If I restore from the locally installed dotnet at C:\Users\MyUser\AppData\Local\Microsoft\dotnet then I get the unexpected output that I'm getting in the GitHub action

Determining projects to restore...
Determining projects to restore...
C:\actions-runner\_work\MySolution\MySolution\src\FirstSdkProject\FirstSdkProject.csproj : error MSB4057: The target "Restore" does not exist in the project.
Nothing to do. None of the projects specified contain packages to restore.
Determining projects to restore...
Nothing to do. None of the projects specified contain packages to restore.
Nothing to do. None of the projects specified contain packages to restore.
Determining projects to restore...
C:\actions-runner\_work\MySolution\MySolution\src\SecondSdkProject\SecondSdkProject.csproj : error MSB4057: The target "Restore" does not exist in the project.
Nothing to do. None of the projects specified contain packages to restore.
Nothing to do. None of the projects specified contain packages to restore.
Determining projects to restore...
Nothing to do. None of the projects specified contain packages to restore.
Nothing to do. None of the projects specified contain packages to restore.
Nothing to do. None of the projects specified contain packages to restore.
Nothing to do. None of the projects specified contain packages to restore.

Comparing the information on dotnet.exe, they are the exact same version of dotnet and using a file compare program they are binary the same, and the folders they are in are seemingly the same as well with only a few minor differences. Why would running restore have two very different outcomes just running from different locations?


Solution

  • One of the main differences between a legacy .NET Framework project style csproj project (VS 2017 or earlier) and the current .NET SDK project style csproj is how NuGet package references are managed. With legacy csproj projects, NuGet references are managed in packages.config. To build and restore including packages.config references you need the following

    msbuild -t:build -restore -p:RestorePackagesConfig=true ./path/to/solution.sln

    If you don't have mixed projects and they all follow the current .NET SDK style csproj format (which can still target .NET framework, it's just the newer style of csproj), then you won't have any packages.config references and you can build and restore with this.

    msbuild -t:build -restore ./path/to/solution.sln

    The option RestorePackagesConfig is only available on msbuild 16.5+ https://learn.microsoft.com/en-us/nuget/reference/msbuild-targets#restoring-packagereference-and-packagesconfig-projects-with-msbuild