How to get version number in post-build event

10,179

Solution 1

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"

Solution 2

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>

Solution 3

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)

Solution 4

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.

Share:
10,179
sventevit
Author by

sventevit

Updated on June 15, 2022

Comments

  • sventevit
    sventevit about 2 years

    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?

  • sventevit
    sventevit almost 12 years
    This works if the Configuration is set to Debug. But as soon as I change it to Release, then I get an exception "Unable to find path\bin\Debug\MyDll.dll". Make sure the project has been built. That means, that nuget is still looking in Debug folder instead of Release. Any ideas?
  • sesispla
    sesispla almost 12 years
    I have found this problem too. I should inform Nuget Team. To fix it, DEBUG and RELEASE folder should be equal. The only thing to take care about is the that you should a Rebuild solution when you switch from one mode to other. 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) With this fix, Nuget.exe will generate de Packages in both DEBUG and RELEASE
  • Andrew Hanlon
    Andrew Hanlon over 7 years
    @sesispla @sventevit You need to add an additional pack setting: -Properties "Configuration=$(Configuration);Platform=$(Platform)" which will allow it to work in release without changing the output dir.