robertmiles3
robertmiles3

Reputation: 919

dotnet publish outputs old packages

I must be going crazy. I am hitting an issue where a dotnet publish is outputting older versions of some packages (specifically Microsoft.Extensions.Configuration.dll) and it's causing a runtime issue. My (simplified) .csproj is as follows...

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <VersionPrefix>1.0.0</VersionPrefix>
    <TargetFrameworks>net462</TargetFrameworks>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Hosting.WindowsServices" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc" Version="1.1.2" />
    <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Configuration" Version="1.1.2" />
    <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="1.1.2" />
  </ItemGroup>
  <ItemGroup>
    <DotNetCliToolReference Include="BundlerMinifier.Core" Version="2.3.327" />
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="1.0.1" />
    <DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="1.0.1" />
  </ItemGroup>

</Project>

When I run a dotnet publish on my dev machine, it outputs the proper version of Microsoft.Extensions.Configuration.dll (1.1.2.30427). However, my TeamCity build server outputs a super old version of it (1.0.0.20622). I have tried several things including:

I am referencing some libraries that have dependencies on Microsoft.Extensions.Configuration 1.1.0, but to my knowledge that would just be the minimum. I'm explicitly telling the main app to use 1.1.2.

What am I missing? Why won't it output the packages that I'm telling it explicitly to pull?

Upvotes: 15

Views: 3978

Answers (3)

Alexandre Hamon
Alexandre Hamon

Reputation: 1402

Thank you for pointing out issue with --output argument !

I had a simple build mecanism :

dotnet restore src
dotnet publish src --configuration Release --output out

Everything running fine inside docker image mcr.microsoft.com/dotnet/core/sdk:3.1.

When migrating CICD from Jenkins to GitlabCI, using the same comand inside the same Docker image, I found out that my application no longer worked and I had the following error :

Could not load file or assembly 'Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed'

Further investigation led me to understand that dependencies put in the out folder where not the same between Jenkins build and GitlabCI build.

I had to use theses build command to understand that the copy order was not the same with GitlabCI :

dotnet restore src
dotnet publish src --configuration Release
dotnet publish src --configuration Release --output out --no-build

The last command will output the copy order for output :

Microsoft (R) Build Engine version 16.7.2+b60ddb6f4 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.   

  SubProject1 -> /app/out/
  SubProject2 -> /app/out/
  SubProject3 -> /app/out/
  SubProject4 -> /app/out/

The order was changing whith GitlabCI.

The fix I found was to force the same order doing this :

dotnet restore src
dotnet publish src --configuration Release
dotnet publish src/SubProject1 --configuration Release --output out --no-build
dotnet publish src/SubProject2 --configuration Release --output out --no-build
dotnet publish src/SubProject3 --configuration Release --output out --no-build
dotnet publish src/SubProject4 --configuration Release --output out --no-build

If anyone can find how these subproject are ordered for the output folder, I'm interested !

Upvotes: 0

Caius Jard
Caius Jard

Reputation: 74595

I recently had this issue too and went round in circles for hours. No matter what I did I was finding that dotnet publish MySolution.sln --configuration Release --output dist kept outputting v2.0 of Microsoft.Extensions.FileSystemGlobbing.dll to the dist folder even though the only project in the whole solution that had any dependency on it at all (via a refernce to Microsoft.Extensions.Configuation.Json was definitely using v3.1.0 from the .NET 3.1 SDK (and later v3.1.2 as a direct NuGet add)

VS 2019 build would succeed, and put a v3.1 DLL in the output folder. As you found, calling dotnet publish without the --output flag would drop the correct v3.1 DLL in the bin\release\publish folder...

And that was when the penny dropped; --ouput X collates all the published files into X and subsequent outputting of files with a same name as the existing, would overwrite earlier outputted files. I did a windows file search for *globbing.dll and found that when I didn't use --output there were two versions of the DLL in different subfolders:

MySolution\MyProject1\bin\release\publish\Microsoft.Extensions.FileSystemGlobbing.dll  <-- v3.1 as expected
MySolution\MyProject1.UnitTests\bin\release\publish\Microsoft.Extensions.FileSystemGlobbing.dll  <-- v2.0 !

The UnitTests project recently added is, for some reason, outputting v2.0 of the DLL. It's not cited as a dependency in the solution explorer so I'm not sure why, but because it was being built later, --output was collecting the later-built-but-earlier-versioned file and overwriting the earlier-built-but-later-versioned file..

Now I need to find out why the UnitTests are outputting this old version, but there's an explanation for why --output leaves you with an old version; possibly the new version was written, but then was later overwritten with an old version as part of the --output process

Upvotes: 8

robertmiles3
robertmiles3

Reputation: 919

For those looking here later...

After hours of wasted life, it seems something is awry when using the --output flag with dotnet publish.

This was what I was using that was causing older libraries to write out:

dotnet publish Foo.sln --framework net462 --configuration Release --output C:\test\dist

And this (taking out --output) works just fine and outputs the proper libraries:

dotnet publish Foo.sln --framework net462 --configuration Release

To make it weirder, my local dev machine works fine in either case (with or without --output). I've spent too much time fighting tooling to figure out what is actually wrong, so if someone does just let me know for future reference.

Upvotes: 9

Related Questions