nuget 打包 pre-release 版本需要注意的文件版本问题

今天在发布 EnyimMemcachedCore 的一个预览版 nuget 包时遇到的问题,在这篇博文中记录一下。

当时发布的版本是 2.6.0-preview1,使用的打包脚本如下

version=$1
project=Enyim.Caching
dotnet build -p:Version=$version -c Release $project
dotnet pack $project -c Release -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg --include-source -p:Version=$version -o ./artifacts

发布后在一个项目中将 EnyimMemcachedCore 升级到这个版本,运行时报错

System.IO.FileNotFoundException: Could not load file or assembly 'EnyimMemcachedCore, Version=2.5.3.0, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified

这个项目在升级到 2.6.0-preview1 之前使用的版本是 2.5.7,而 2.5.3 是这个项目引用的另外一个项目依赖的 EnyimMemcachedCore 版本,正常情况下 .NET 会自动使用最新版,之前发布 release 版本都没遇到这个问题,问题与 pre-release 版本有关。

查看打包时生成的 EnyimMemcachedCore.dll 的文件版本(右键点击文件 -> Details 中的 File version),发现版本号竟然是 1.0.0.0,应该就是这个错误的文件版本号引起的问题,由于 1.0.0.0 小于 2.5.3.0,所以 .NET 继续使用 2.5.3 版,结果找不到而报错。

针对这个情况进行了试验,发现 .NET 程序集的 file version 与 assembly version 都不支持除点号之外的非数字版本号,所以通过 Version 属性传递给 msbuild 的 2.6.0-preview1 版本号会被忽略,从而使用默认版本号 1.0.0.0,而只有 nuget 的 PackageVersion 认这个版本号。

知道了问题所在,通过改进打包脚本解决了问题,对于 2.6.0-preview1 这样的 pre-release 版本号,只完整传给 PackageVersion,传给 Version 属性的是过滤掉 -preview1 的版本号 2.6.0,这样打包出来的 file version 与 assembly version 都是 2.6.0.0

version=$1
project=src/Enyim.Caching
dotnet build -p:Version=${version-*} -c Release $project 
dotnet pack $project -c Release -p:IncludeSymbols=true -p:SymbolPackageFormat=snupkg --include-source -p:PackageVersion=$version -p:Version=${version-*} -o ./artifacts

参考资料:Version vs VersionSuffix vs PackageVersion: What do they all mean?

posted @ 2023-01-12 14:25  dudu  阅读(168)  评论(0编辑  收藏  举报