Open jaredpar opened 6 years ago
I wanted to recommend using solution extensibility, so I documented that first (MicrosoftDocs/visualstudio-docs#816).
You can add a target to the solution build with AfterTargets="Build"
that calls Publish
in the desired targets, something like after.Roslyn.sln.targets
:
<Project>
<Target Name="PublishRoslynExecutableProjects"
AfterTargets="Build">
<ItemGroup>
<ProjectsToPublish Include="src/Compilers/CSharp/csc/csc.csproj" />
<ProjectsToPublish Include="src/Compilers/VisualBasic/vbc/vbc.csproj" />
<ProjectsToPublish Include="src/Compilers/Server/VBCSCompiler/VBCSCompiler.csproj" />
<ProjectsToPublish Include="src/Compilers/Core/MSBuildTask/MSBuildTask.csproj" />
</ItemGroup>
<Message Importance="high"
Text="Publishing .NET Core executables ..." />
<MSBuild Projects="@(ProjectsToPublish)"
Targets="PublishWithoutBuilding"
BuildInParallel="true"
Properties="TargetFramework=netcoreapp2.0" />
</Target>
</Project>
One thing that complicates this (rather a lot, unfortunately): when building individual projects, the solution passes configuration derived from solution configurations to the projects. That means that if you separately list projects and <MSBuild>
into them, as I'm doing here, you'll get a different instance of the project, which might cause rebuilding. Here it won't be a race condition since the build happens after, but it could cause lost time (to rebuilding) or inaccurate builds (especially around things that are signed in place). Ensuring that the custom MSBuild invocation collapses into the default one is quite difficult--you have to set all the same properties that the solution does, plus all the right properties set when going from the "outer" multitargeted project to the TF-specific inner project. I've fought that a bit this afternoon but haven't been able to solve it.
Since Roslyn already defined PublishWithoutBuilding
, I used that to avoid this problem--this gives the same experience as separately calling publish on the individual projects on the command line after the build.
I'm also looking into running the publish step for a project during solution build time. Has there been any work in this area since the above? Intuitively, it would be nice if I could simply add a property to a csproj
file to mark it as "publish on build".
I agree that a <PublishOnBuild>true</PublishOnBuild>
which would be similar to <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
from a semantic point of view would be really really helpful. This would make it a lot simpler to work with published resources without need of dedicatet setup in the build.
Actually I wanted to look into PublishWithoutBuilding
as @rainersigwald said that would be used in Roslyn. But I could not find this target definition in the repo. Has it disappeared? And how is it done right now? The project is really big, I could not quickly figure it out.
Are there any improvements on this :) ? Would love to see something like PublishOnBuild>true</PublishOnBuild>
Im also looking for a PublishOnBuild
feature
My hack:
<Target Name="PublishAsBuildAfterTarget" AfterTargets="Build" DependsOnTargets="Publish">
<!-- placeholder task to force Publish to happen during build -->
</Target>
The rosyln project has a solution with ~160 projects in it of which ~5 need to be published. Today our work flow is to do the following:
msbuild /t:Publish /p:TargetFramework=netcoreapp2.0 TheProject.csproj
Invoking MSBuild this many times is wasteful because every publish has to re-evaluate the state of our build before moving onto the publish step. It would be more efficient if during the build we could publish the set of projects that require publishing.
Chaining targets almost works by using this syntax:
However Publish requires that a TargetFramework property also be set. How can that be combined with the target syntax above?