在构建后事件中更新本地 nuget 包

发布于 2024-10-19 00:24:14 字数 455 浏览 8 评论 0原文

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

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

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

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

在项目构建上:

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

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

所以我的要求就是以上。还有其他人完成过这个吗?

I have my local nuget library repository separately both for my personal and work releted class libraries.

I have created some of the nuget packages for the libraries which are no longer in development. I did this only for them because I do not know how to update them automatically as soon as my project builds.

I have figured that all the work is being done by nuget command line with Visual Studio Command Prompt. So I can easily do the work I needed (of course I would know commands perfectly and I do not !)

Basically I want the following tasks to execute on the post-build event of my project.

On project build:

  1. copying project dll into a specific folder (lib folder of the nuget package)
  2. updating nuspec file for new file version (my project is increasing the file version on every build)
  3. creating new nupkg file with new file version

Phil Haack shows some of this feature but it is still a prototype as far as I can tell.

So my requirement is the above. Has anyone else accomplished this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

一曲琵琶半遮面シ 2024-10-26 00:24:14

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

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

C:\<Path to project>\nuget spec

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

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

然后...

对于 .Net Framework(老式)项目,在您可以在项目的构建后事件中执行以下操作:(

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 "<您托管本地的路径nuget repo>"

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

The selected solution looks like it would work but it seems like there is a simpler solution for your requirements.

You can create a nuspec file that will read data from the project's metadata. You only need to do this once with this command:

C:\<Path to project>\nuget spec

This creates 'tokens' in the spec file that will will be replaced by the project's metadata when you create the nuget package. This includes the file version. You will want to replace and because all projects are technically suppose to have them.

More details can be found here: http://docs.nuget.org/docs/creating-packages/Creating-and-Publishing-a-Package#From_a_project

Then...

For .Net Framework (old-school) projects, in you project's Post build events you can do this:

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

(assuming nuget.exe is available on your system PATH).

For .Net Core and Standard projects, nuget can't pack them (see https://github.com/NuGet/Home/issues/4491). Instead, use this as your post-build step:

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

Of course you can adjust the options to meet your needs. See https://learn.microsoft.com/en-us/dotnet/core/tools/dotnet-pack?tabs=netcore2x for dotnet pack command options.

菊凝晚露 2024-10-26 00:24:14

以防万一其他人(像我一样)遇到这个古老的问题 - 在当前时代(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>

Update

For较新的 NuGet 版本,它会切断最后的 0(来自 0.0.0.0 版本的补丁)符号),您将需要正则表达式 PackageVersion:

  <Target Name="CopyPackage" AfterTargets="Pack">
    <Copy SourceFiles="$(OutputPath)$(PackageId).$([System.Text.RegularExpressions.Regex]::Replace("$(PackageVersion)", "^(.+?)(\.0+)
amp;quot;, "$1")).nupkg" DestinationFolder="G:\imbVelesOpenSource\LocalNuGet\imbVelesSecondGeneration\" />
  </Target>

Just in case someone else (like me) come across this ancient question - in the current era (VS2017, SDK/NugetReference format/ .NET Core / .NET Standard / Multi-target projects), where creation of NuGet package is an option in the Project Properties - so, only issue of local repository has to be solved:

If you have single-target project, to copy your .nupkg file to local NuGet repository, add Post-build event (Project properties > Build Events > Post-build event command line):

xcopy $(TargetDir)*.nupkg [path to your local nuget repository] /s

Like:

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


If you have multi-target project, to copy your .nupkg file to local NuGet repository:
add Post-build event (Project properties > Build Events > Post-build event command line):

xcopy $(TargetDir)..*.nupkg [path to your local nuget repository] /s

Like:

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


Update:
Forget post-build events, there is a cleaner way (xcopy approach works strange for multi-target projects), just add this in project XML:

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

Update

For newer NuGet versions, which cut off the last 0 (patch from a 0.0.0.0 version notation), you will need to regex the PackageVersion:

  <Target Name="CopyPackage" AfterTargets="Pack">
    <Copy SourceFiles="$(OutputPath)$(PackageId).$([System.Text.RegularExpressions.Regex]::Replace("$(PackageVersion)", "^(.+?)(\.0+)
amp;quot;, "$1")).nupkg" DestinationFolder="G:\imbVelesOpenSource\LocalNuGet\imbVelesSecondGeneration\" />
  </Target>
内心荒芜 2024-10-26 00:24:14

杰里米·斯金纳 (Jeremy Skinner) 撰写了 关于他如何执行包的自动构建并将其上传到 NuGet Gallery 的博客文章。我认为它符合您的要求。

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

Jeremy Skinner has written a blog post on how he performs automated builds of packages and uploads them to the NuGet Gallery. I think that it matches your requirements.

Basically he uses MsBuild to apply the version (with the MsBuild Community Extensions UpdateXml task) to the nuspec file and invoke the nuget.exe to package it up.

寄与心 2024-10-26 00:24:14

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

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

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

I recently published a solution for this that actually creates/updates the nuspec files during the build, so don't have to do so manually, then creates the nupkg files.

All you will have to add is a post-build event for copying the packages to their destination (or add it as an optional stage to my solution).

You can find an article with a walk-through guide here and the source code + binary here.

偷得浮生 2024-10-26 00:24:14

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

  <Target Name="AfterBuild">
     <WriteLinesToFile File="dependencies.xml" Overwrite="true" Lines=""/>
     <WriteLinesToFile File="dependencies.xml" Overwrite="false" Lines="<dependencies>"/>
     <WriteLinesToFile File="dependencies.xml" Overwrite="false" Lines="<dependency id="%(PackageReference.Identity)" version="%(PackageReference.Version)" />" />
     <WriteLinesToFile File="dependencies.xml" Overwrite="false" Lines="</dependencies >"/>
     <Exec Command="powershell -NonInteractive -executionpolicy Unrestricted -command "$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')""/>
     <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>

With the latest nuget package format using "PackageReference" tags you can use the following simple postbuild event in your csproj to update nuspec file with latest dependencies.

  <Target Name="AfterBuild">
     <WriteLinesToFile File="dependencies.xml" Overwrite="true" Lines=""/>
     <WriteLinesToFile File="dependencies.xml" Overwrite="false" Lines="<dependencies>"/>
     <WriteLinesToFile File="dependencies.xml" Overwrite="false" Lines="<dependency id="%(PackageReference.Identity)" version="%(PackageReference.Version)" />" />
     <WriteLinesToFile File="dependencies.xml" Overwrite="false" Lines="</dependencies >"/>
     <Exec Command="powershell -NonInteractive -executionpolicy Unrestricted -command "$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')""/>
     <Delete Files="dependencies.xml" />
  </Target>

Only premise for this is that you have a nuspec file with rest of the metadata mentioned in the project directory. Here is a sample nuspec file:

<?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>
倾其所爱 2024-10-26 00:24:14

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

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

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

您可以花 17 欧元从 Ascertia 获得一个简单的协同设计证书。他们还有有效期为 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 文件中并在后期构建中调用它。

I solved it by using a command line
Let's assume you have added the location of NuGet to your path environment or copies a stable version to a given directory (this is what I did)

I have my NuGet.exe as well as my certificate in a folder named D:\Build, you may need to update this to fit your path.

Then let's assume you have a codesign certificate file named: "CodeSignCertificate.pfx"
with a password: pa$$w0rd

You can get a simple codesign certificate for 17 euro from Ascertia. they also have free trial certificates that are valid for 10 days. the link https://account.ascertia.com/onlineCA/default

then as a one liner I use :

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

This sign all my packages in my output directory

if you only want to sign the lastest the NuGet package as this might be the one you just compiled then you can use something like this.

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

it's not a one-line but you can put it in a bat file and call that in your post build.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文