14

我的本地 nuget 库存储库分别用于我的个人和工作相关的类库。

我为不再开发的库创建了一些 nuget 包。我只为他们这样做,因为我不知道如何在我的项目构建后立即自动更新它们。

我认为所有工作都是通过带有 Visual Studio 命令提示符的 nuget 命令行完成的。所以我可以轻松地完成我需要的工作(当然我会完全了解命令,但我不会!)

基本上我希望在我的项目的构建后事件上执行以下任务。

在项目构建上:

  1. 将项目dll复制到特定文件夹(nuget包的lib文件夹)
  2. 为新文件版本更新 nuspec 文件(我的项目正在增加每个构建的文件版本)
  3. 使用新文件版本创建新的 nupkg 文件

Phil Haack 展示了其中的一些功能,但据我所知,它仍然是一个原型。

所以我的要求就是以上。有没有其他人做到这一点?

4

6 回答 6

16

所选解决方案看起来可行,但似乎有一个更简单的解决方案可以满足您的要求。

您可以创建一个 nuspec 文件,该文件将从项目的元数据中读取数据。您只需使用此命令执行一次:

C:\<Path to project>\nuget spec

这会在规范文件中创建“令牌”,当您创建 nuget 包时,它将被项目的元数据替换。这包括文件版本。你会想要替换,因为所有项目在技术上都假设有它们。

更多细节可以在这里找到:http: //docs.nuget.org/docs/creating-packages/Creating-and-Publishing-a-Package#From_a_project

然后...

对于 .Net Framework (old-school) 项目,在项目的 Post build 事件中,您可以执行以下操作:

nuget pack "$(ProjectPath)"  
xcopy "$(TargetDir)*.nupkg" "<path where you are hosting your local nuget repo>" /C /Y

(假设 nuget.exe 在您的系统路径上可用)。

对于 .Net Core 和 Standard 项目,nuget 无法打包它们(请参阅https://github.com/NuGet/Home/issues/4491)。相反,将其用作您的后期构建步骤:

dotnet pack "$(ProjectPath)" --no-build --include-source --include-symbols --output "<path where you are hosting your local nuget repo>"

当然,您可以调整选项以满足您的需求。有关命令选项,请参阅https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-pack?tabs=netcore2x 。dotnet pack

于 2013-01-23T20:34:57.843 回答
7

以防万一其他人(比如我)遇到这个古老的问题 - 在当前时代(VS2017,SDK/NugetReference 格式/.NET Core/.NET Standard/多目标项目),创建 NuGet 包是一个选项项目属性 - 因此,只需解决本地存储库的问题:

如果您有单目标项目,要将 .nupkg 文件复制到本地 NuGet 存储库,请添加构建后事件(项目属性 > 构建事件 > 构建后事件命令行):

xcopy $(TargetDir)*.nupkg [本地 nuget 存储库的路径] /s

像:

xcopy $(TargetDir)*.nupkg G:\imbVelesOpenSource\LocalNuGet\imbVelesSecondGeneration\ /s


如果您有多目标项目,请将 .nupkg 文件复制到本地 NuGet 存储库:添加构建后事件(项目属性 > 构建事件 > 构建后事件命令行):

xcopy $(TargetDir)..*.nupkg [本地 nuget 存储库的路径] /s

像:

xcopy $(TargetDir)..*.nupkg G:\imbVelesOpenSource\LocalNuGet\imbVelesSecondGeneration\ /s


更新:忘记构建后事件,有一种更简洁的方法(xcopy 方法对于多目标项目很奇怪),只需在项目 XML 中添加:

  <Target Name="CopyPackage" AfterTargets="Pack">
    <Copy SourceFiles="$(OutputPath)$(PackageId).$(PackageVersion).nupkg" DestinationFolder="G:\imbVelesOpenSource\LocalNuGet\imbVelesSecondGeneration\" />
  </Target>

更新

对于较新的 NuGet 版本,它切断了最后一个 0(来自 0.0.0.0 版本表示法的补丁),您需要正则表达式 PackageVersion:

  <Target Name="CopyPackage" AfterTargets="Pack">
    <Copy SourceFiles="$(OutputPath)$(PackageId).$([System.Text.RegularExpressions.Regex]::Replace(&quot;$(PackageVersion)&quot;, &quot;^(.+?)(\.0+)$&quot;, &quot;$1&quot;)).nupkg" DestinationFolder="G:\imbVelesOpenSource\LocalNuGet\imbVelesSecondGeneration\" />
  </Target>
于 2018-06-21T19:39:15.620 回答
5

Jeremy Skinner 写了一篇关于他如何执行包的自动构建并将它们上传到 NuGet 库的博客文章。我认为它符合您的要求。

基本上,他使用 MsBuild 将版本(使用MsBuild Community Extensions UpdateXml 任务)应用到 nuspec 文件并调用 nuget.exe 将其打包。

于 2011-02-25T15:04:28.737 回答
0

我最近为此发布了一个解决方案,它实际上在构建期间创建/更新了 nuspec 文件,因此不必手动执行此操作,然后创建 nupkg 文件。

您只需添加一个用于将包复制到其目的地的构建后事件(或将其作为可选阶段添加到我的解决方案中)。

您可以在此处找到包含演练指南的文章,并在此处找到源代码 + 二进制文件

于 2014-08-05T22:49:21.987 回答
0

使用使用“PackageReference”标签的最新 nuget 包格式,您可以在 csproj 中使用以下简单的 postbuild 事件来更新具有最新依赖项的 nuspec 文件。

  <Target Name="AfterBuild">
     <WriteLinesToFile File="dependencies.xml" Overwrite="true" Lines=""/>
     <WriteLinesToFile File="dependencies.xml" Overwrite="false" Lines="&lt;dependencies&gt;"/>
     <WriteLinesToFile File="dependencies.xml" Overwrite="false" Lines="&lt;dependency id=&quot;%(PackageReference.Identity)&quot; version=&quot;%(PackageReference.Version)&quot; /&gt;" />
     <WriteLinesToFile File="dependencies.xml" Overwrite="false" Lines="&lt;/dependencies &gt;"/>
     <Exec Command="powershell -NonInteractive -executionpolicy Unrestricted -command &quot;$xml = [xml] (Get-Content Project.nuspec); $xml.package.metadata.RemoveChild($xml.package.metadata.dependencies); $dependencies = [xml](Get-Content dependencies.xml); $xml.Package.Metadata.AppendChild($xml.ImportNode($dependencies.Dependencies, $true)); $xml.Save('Project.nuspec')&quot;"/>
     <Delete Files="dependencies.xml" />
  </Target>

唯一的前提是您有一个 nuspec 文件,其中包含项目目录中提到的其余元数据。这是一个示例 nuspec 文件:

<?xml version="1.0"?>
<package>
   <metadata>
      <id>Package Id</id>
      <version>1.0.0</version>
      <authors>Author name</authors>
      <owners>Owner name</owners>
      <description>Description</description>
      <contentFiles>
         <files include="**/content.zip" buildAction="None" copyToOutput="true" flatten="false" />
      </contentFiles>
      <dependencies>
      </dependencies>
   </metadata>
   <files>
      <file src="bin\Release\Project.dll" target="lib\net462" />
      <file src="bin\Release\Project.pdb" target="lib\net462" />
      <file src="bin\Release\file.zip" target="Content" />
   </files>
</package>
于 2019-01-26T17:54:24.027 回答
0

我通过使用命令行解决了它假设您已将 NuGet 的位置添加到路径环境或将稳定版本复制到给定目录(这就是我所做的)

我在名为 D:\Build 的文件夹中有我的 NuGet.exe 和证书,您可能需要更新它以适应您的路径。

然后假设您有一个名为“CodeSignCertificate.pfx”的代码签名证书文件,密码为:pa$$w0rd

您可以从 Ascertia 获得 17 欧元的简单代码签名证书。他们还拥有有效期为 10 天的免费试用证书。链接https://account.ascertia.com/onlineCA/default

然后作为一个衬里我使用:

for %f in (X:\Packages\*.nupkg) do D:\Build\nuget sign %f -CertificatePath D:\Build\CodeSignCertificate.pfx -Timestamper http://timestamp.digicert.com -CertificatePassword pa$$w0rd

这在我的输出目录中签署了我所有的包

如果您只想签署最新的 NuGet 包,因为这可能是您刚刚编译的包,那么您可以使用类似的东西。

set Path="X:\ASP-WAF\DLL"
for /f "tokens=*" %%a in ('dir /A:-D /B /O:-D /S %Path%') do set NEW=%%a&& goto:n 
:n
sign %NEW% -CertificatePath D:\Build\CodeSignCertificate.pfx -Timestamper http://timestamp.digicert.com -CertificatePassword pa$$w0rd

它不是单行的,但您可以将它放在一个 bat 文件中并在您的后期构建中调用它。

于 2020-09-05T11:47:54.390 回答