Search code examples
visual-studiomsbuildmsbuild-target

MSBuild Target not running in NET Core Project


I am using Visual Studio 2019, .NET Core 3.1

I create a new Project and use template Class Library (.NET Core)

I right-click on the project in the solution explorer and click Edit Project File

and add the following target:

  <Target Name="Test" AfterTargets="Build">
    <Message Text="This is a test" Importance="high" />
  </Target>

When I publish... it hits this target a few times and in the Output pane i see "This is a test" a few times.

I would like this target to execute after the Publish instead of the build.

This works in a .NET Core Web API solution where before the Publish event i am executing an ng build on an angular project that's included in the published result.

But in a Class Library its like the Publish msbuild target never gets executed even though I am doing an actual Publish.

So...

  <Target Name="Test" AfterTargets="Publish">
    <Message Text="This is a test" Importance="high" />
  </Target>

This message never displays in my Output pane.

This class library is going to be published to a private NuGet server and I'd like to execute a nuget push after the Publish action has completed. I can easily execute a command to push to the NuGet server once i get the msbuild target to actually run at the right time.

Am I missing something here? How can I execute a target after the Publish action finishes on a .NET Core Library solution?

EDIT: That raises another question. When i publish, i get this output:

1>------ Build started: Project: ClassLibrary1, Configuration: Release Any CPU ------
1>ClassLibrary1 -> C:\Users\11016409\Documents\source\Libraries\NET Core\ClassLibrary1\ClassLibrary1\bin\Release\netcoreapp3.1\ClassLibrary1.dll
1>This is a test
2>------ Publish started: Project: ClassLibrary1, Configuration: Release Any CPU ------
2>ClassLibrary1 -> C:\Users\11016409\Documents\source\Libraries\NET Core\ClassLibrary1\ClassLibrary1\bin\Release\netcoreapp3.1\ClassLibrary1.dll
2>This is a test
2>Successfully created package 'C:\Users\11016409\Documents\source\Libraries\NET Core\ClassLibrary1\ClassLibrary1\bin\Release\netcoreapp3.1\publish\ClassLibrary1.1.0.0.nupkg'.
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
========== Publish: 1 succeeded, 0 failed, 0 skipped ==========

why Does it run the build phase twice?


Solution

  • There are certain built in targets that never get hit like Publish for a .NET Core Class Library project. I even set the publishable property to true to no avail. I was never able to figure that one out. But I did find that it was executing a built-in target "Pack" that I could hook into.

      <Target Name="nuget push" AfterTargets="Pack">
        <Exec WorkingDirectory="$(PackageOutputPath)" Command="nuget push $(PackageId).$(PackageVersion).nupkg -source http://DevServices/NuGet" />
      </Target>
    

    Pack is where it generates the actual .nupkg file. Once the Pack target is finished, i can push to my local NuGet server.

    Make sure you have the checkbox unchecked on the project properties for generating the Nuget Package on each build because the Pack target will execute each time you build.

    This way it will only do a Pack when you do a Publish of the project. You can publish to any location and it will run the nuget push on the generated .nupkg regardless of the location you published to.

    If you really need to generate a .nupkg on each build but want to only do a nuget push when you use publish, then use this target instead and have it only push the nuget package to your nuget server if the output path matches your publish folder location:

      <Target Name="nuget push" AfterTargets="Pack" Condition="$(PackageOutputPath.EndsWith('\publish\'))">
        <Exec WorkingDirectory="$(PackageOutputPath)" Command="nuget push $(PackageId).$(PackageVersion).nupkg -source http://DevServices/NuGet" />
      </Target>
    

    Note: With this nuget push method, its very handy if your nuget server is set up to not allow you to overwrite existing package versions (which is how it should be) then it requires those pushing packages to update the version number before it will work. Otherwise it will get an error on publish that it cannot overwrite an existing package version. Everything right in the GUI like this makes it easy to jump in and update the version of the library and try the publish again. Super quick. Super easy.

    Edit: This no longer works after Visual Studio 17.3.6 It appears that it does not automatically do a Pack to the nuget package unless you want it to do it on every build via the project properties. You can right click the project in the solution explorer and select Pack and the above

    AfterTargets="Pack"

    will execute your code.