Question

I want to use post-build event to automatically create a nuget package and then copy it to a shared folder on our network, something like this (the version number 1.0.0.0. is specified inside the MyLib.nuspec file):

nuget.exe pack "$(SolutionDir)MyLib.nuspec"
xcopy /Y "$(TargetDir)MyLib.1.0.0.0.nupkg" \\folder\subfolder\NuGetPackages

This works, but now I would like to update this script, so that it would include the assembly version also, but I cannot get assembly version inside the post-build event. I would need something like this:

nuget.exe pack -Version $(AssemblyVersion) "$(SolutionDir)MyLib.nuspec"
xcopy /Y "$(TargetDir)MyLib." + $(AssemblyVersion) + ".nupkg" \\folder\subfolder\NuGetPackages

But the $(AssemblyVersion) variable does not exists... Any ideas?

Was it helpful?

Solution

This post build script works for me. It packages and publishes my dev versions on each build. Pretty simple.

del $(ProjectDir)bin\Debug\*.nupkg
"$(ProjectDir)NuGet.exe" pack "$(ProjectDir)MyProject.csproj"
forfiles /P $(ProjectDir)bin\Debug\ /m *.nupkg /c "cmd /c "$(ProjectDir)NuGet.exe" push @FILE -Source \\SHARE\NuGet"

OTHER TIPS

Try the following:

1) Rename you .nuspec to match the .csproj name:

If your project is: MyLib.csproj

Rename MyLib.nuspec to MyLib.csproj.nuspec

2) Modify your .nuspec file as follows:

<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <metadata>
    <version>$version$</version>
    <authors>$author$</authors>
    <id>$id$</id>
    <title>$id$</title>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>$description$</description>
    <summary>$description$</summary>
  </metadata>
</package>

Here, the job is done by Nuget's "$version$" token (and others)

Take a look to this Nuget article for more tokens and information.

3) Use the following Post Build Event in every project you put a .csproj.nuspec file (please remove the Enter keys):

mkdir "$(SolutionDir)GeneratedPackages"

"$(SolutionDir).nuget\nuget.exe" pack "$(ProjectPath)" 
-OutputDirectory "$(SolutionDir)GeneratedPackages" 
-basepath "$(SolutionDir)$(ProjectName)\$(OutDir)"

If we have a solution C:\MySolution\MyLib.sln and the project at c:\MySolution\MyLib\MyLib.csproj, our .nuspec file should be c:\MySolution\MyLib\MyLib.csproj.nuspec and the Post Build Event Command would look like:

mkdir "C:\MySolution\GeneratedPackages"

"C:\MySolution\.nuget\nuget.exe" pack "C:\MySolution\MyLib\MyLib.csproj" 
-OutputDirectory "C:\MySolution\GeneratedPackages" 
-basepath "C:\MySolution\MyLib\bin\debug\"

Fix the path to the nuget.exe. In my case I am using the Nuget "auto-regenerate missing dependencies on build", and I have a local copy in the solution, under the .nuget folder.

Please note that we're not calling nuget with the .nuspec file, we're calling it with the .csproj directly!!

This strategy will also include all the Project dependendencies declared in the packages.xml that Nuget creates when you install packages. (automatically, every time you build)

And you're done! Now change the Assembly and File Version in

Project > Properties > Assembly information

IMPORTANT: If you set the $author$ and/or $description$ tokens, fill also the Assembly's Company and Description fields here. If you have troubles, remove the $author$ and/or $description$ tokens and try to compile again.

and build your Project, you'll see in /GeneratedPackages folder the MyLib.X.X.X.X.nupack with the version you set in the Project Properties. If you set dependencies, you'll see that it has been automatically included as Package Dependencies.

We are using this strategy with a Jenkins CI server to build automaticaly the solution and copy the packages from the GeneratedPackages to our custom NugetServer.

You can also complete the Post Build Event with a

nuget push

To send the generated package to a Nuget Server

ISSUE IN RELEASE:

As mentioned in comments, there is an issue that don't allow Nuget.exe to generate the packages in RELEASE mode.

Do this in order to fix it:

For every project with this script:

  1. Project Properties > Build
  2. In the "Configuration" dropdown choose "All configurations"
  3. In the "Ouput" section, change the "Output path:" field, for example, I am currently using "bin\" (without cuotes)

Try this:

Edit your .csproj file and add this block:

<Target Name="AfterBuild">
    <GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
        <Output TaskParameter="Assemblies" ItemName="CurrentAssembly" />
    </GetAssemblyIdentity>
    <Exec Command="xcopy /Y $(TargetDir)MyLib.%(CurrentAssembly.Version).nupkg \\folder\subfolder\NuGetPackages"></Exec>
</Target>

I tried what giammin suggested, and with a few tweaks got this working for me:

<Target Name="AfterBuild">
    <GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
       <Output TaskParameter="Assemblies" ItemName="CurrentAssembly" />
    </GetAssemblyIdentity>
    <Exec Command="copy /Y $(TargetPath) $(ProjectDir)Versions\$(TargetName)_%(CurrentAssembly.Version).dll" Condition="'$(ConfigurationName)' == 'Stage'" />
</Target>

I added the "Condition attribute so that I could specify when I would have this built to a specific location (in my case creating a backup for rollbacks). Also, the "xcopy" was giving me errors...but a normal "copy" was not.

Then, in my post-build event I have something like this:

copy $(TargetDir)*.dll \\dev-server\folder

IF NOT "$(ConfigurationName)" == "Stage" EXIT

mkdir "$(ProjectDir)Versions"
copy /Y "$(TargetPath)" \\stage-server\folder

I hope that all helps in some way.

Note that the post-build event is executed BEFORE the "AfterBuild" element of the csproj XML.

So you could just use in you post build event: nuget.exe pack "$(SolutionDir)MyLib.nuspec" and add the afterbuild element for the copy and you should be fine.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top