Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to publish for all target frameworks

I am building a set of build template in TeamCity for .Net Core projects. Everything is working great, except for console projects. The problem is that when I go to publish the solution, I need to specify the framework version. At no other point in the build do I need to know the framework. At least this is true when publishing .sln files, with a console project that only has a single framework targeted.

So now I am in a situation where I need to figure out what framework the console project should target. I could read various XML files, but I'm hoping I don't need to. Is there some builtin way that I can query for the frameworks in use for a given solution?

For example, something like (PowerShell)

$frameworks = & dotnet.exe --<what I want> .\MySolution.sln
for ($framework in $frameworks) {
  & dotnet.exe publish -f $framework .\MySolution.sln
}

That way I don't need to modify the build system every time a new framework is in use. I've poked around in the CLI repo, but I can't find a command that does what I need. Is opening .csproj files my only hope?

like image 839
Erick T Avatar asked May 12 '17 23:05

Erick T


1 Answers

If you want to publish projects that target multiple frameworks, the default Publish target fails, but you can create a custom target that performs the multi-targeting itself. To do this, create a file named Directory.Build.props in the solution folder (with MSBuild > 15.1 this can and should be named Directory.Build.targets because there was a bug with multi-targeting projects):

<Project>
  <Target Name="PublishProjectIfFrameworkSet"
          DependsOnTargets="Publish"
          Condition=" '$(TargetFramework)' != '' " />

  <Target Name="PublishProjectForAllFrameworksIfFrameworkUnset" Condition=" '$(TargetFramework)' == '' ">
    <ItemGroup>
      <_PublishFramework Include="$(TargetFrameworks)" />
    </ItemGroup>
    <MSBuild Projects="$(MSBuildProjectFile)" Targets="Publish" Properties="TargetFramework=%(_PublishFramework.Identity)" />
  </Target>

  <Target Name="PublishAll"
          DependsOnTargets="PublishProjectIfFrameworkSet;PublishProjectForAllFrameworksIfFrameworkUnset" />
</Project>

Then you can publish the projects for all defined frameworks by executing this in the solution directory:

$ dotnet msbuild /t:PublishAll /p:Configuration=Release
Microsoft (R) Build Engine version 15.1.1012.6693
Copyright (C) Microsoft Corporation. All rights reserved.

  app2 -> /Users/martin/testproj/app2/bin/Release/netcoreapp1.1/app2.dll
  app1 -> /Users/martin/testproj/app1/bin/Release/netcoreapp1.1/app1.dll
  app1 -> /Users/martin/testproj/app1/bin/Release/netcoreapp1.0/app1.dll
like image 78
Martin Ullrich Avatar answered Oct 13 '22 19:10

Martin Ullrich