Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Publish projects during build #3138

Open
jaredpar opened this issue Mar 27, 2018 · 3 comments
Open

Publish projects during build #3138

jaredpar opened this issue Mar 27, 2018 · 3 comments

Comments

@jaredpar
Copy link
Member

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:

  • Build Roslyn.sln
  • For Each project that needs to be published run 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:

>msbuild /t:Build /t:path\to\project1:Publish /t:path\to\project2:Publish 

However Publish requires that a TargetFramework property also be set. How can that be combined with the target syntax above?

@rainersigwald
Copy link
Contributor

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.

@gitfool
Copy link

gitfool commented Jun 3, 2021

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".

@sjoerd222888
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants