You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
It would be useful if you can share how you used this flag
Agreed. Getting all the use cases for why this switch is useful helps us understand whether to put it back or not.
One of the use cases I've recently encountered was the F# team (specifically @KevinRansom) was using this switch to publish a project's references, but he didn't want the project's output (its .dll) published. The replacement in that case is to add the MSBuild property <CopyBuildOutputToPublishDirectory>false</CopyBuildOutputToPublishDirectory> in your .csproj. That way, the current project's .dll isn't published.
In step 2, all the product dlls are built again. Depending on the number projects published, some of the common dependencies could be built multiple times.
Update: our build process had a race condition on resources files which was slowing down the process. As @eerhardt notes below, msbuild incremental build does kick in, it is not a significant overhead for us now.
Reacted by Damian Turczyński, Vitaliy K, jcyamacho-axa, Tugberk Ugurlu, evgenisokolov, Stephen Drew, George Helyar, Matt Davis, Michael Budnik and AraHaan
@piotrpMSFT We used to have our own publish target and run in AfterBuild. Without no-build switch, the publish target will invoke a build and cause a infinite loop, unless we add a condition.
dotnet pack still supports no-build switch. I think the usage should be similar.
As I see it, there should be an option to have the output of a build be the output of what you call "publish". I'd say that this should be the default behavior but that is debatable. As far as I understand it from reading the issues and documentation, this discrepancy is a workaround to speed up the build time of console apps (e.g. use the nuget cache to save on checksum calculations?!).
.Net is used for more than console apps and as such that workaround is not applicable to hosts different than dotnet run. For those cases, the actual dependencies are needed as part of the build output so it is runnable.
For such cases, I've managed to make dotnet publish output what is the real build output. To have it integrated with the VS Run command, I'd like to have the MSBuild Build target run the Publish target logic. This leads me to the infinite loop that @hongdai is talking about.
For me the no-build switch is a workaround. Ideally I would like you to support the case where the output of the build contains all the required runtime dependencies.
Same issue here -- Why wasn't this BREAKING CHANGE announced on the announcement repo? I've just converted all our stuff to csproj and now this broke our whole ci/azure setup.
We have 3 deployments setup on AppVeyor for a single solution, so we have 3 configurations that do the following:
Build all the specific projects for this config
Run all the specific tests for this config
Publish to folder to be deployed by AppVeyor to Azure
Reacted by Brian Canzanella, Darrell, Listbd, Chris, Eternal21, Ryan Sorensen, Damian Turczyński, quetzalcoatl, Oleg Karasik, Dalin Williams and 1 more
Let's say it is kicking in (which I think it is) -- just the fact the it has to run msbuild, scan for the project(s), see if they need building, etc -- all takes time; time I don't want to be waiting for my CI to finish. For example, on one of my projects it takes about 23s to build it the first time and then 9s to build it the second time (the one that used to be skipped). Yeah, 9s isn't that long in the scheme of things, but it isn't nothing either.
Also, given this flag is seemingly just a simple -- don't run msbuild -- I don't understand why it is so desirable to not support it?
I think this is caused by the current situations that large package graphs (netstandard.library, m.n.app) slow down msbuild projects which is causing project references to slow down linear (1 project 1 sec, 10 projects 10 sec) and has been discussed in https://github.com/dotnet/cli/issues/5918, #1116, dotnet/msbuild#1276 and maybe even more.
Even if build targets are avoided for publish, I believe RunResolvePackageDependencies and ResolveAssemblyReferences would still need to be run to determine the proper publish output (I might be wrong) - and those are the targets that cause the slow incremental builds.
What does --no-build mean? In reality in project.json world, it really meant something closer to --no-compile. But the Build target in MSBuild does so much more than just Compile your source code.
It resolves references
It resolves NuGet assets (managed and native libraries, content files, even pre-processed content files)
It gathers your project's Content files that need to be copied to the output
Doing a Publish without the things that happen during the Build target in MSBuild is almost pointless. What do you expect to have happened?
Another thing to understand is that dotnet publish really means "run the Publish MSBuild target". So it obviously isn't as simple as "don't run msbuild", since you can't run the Publish target without MSBuild.
So the reason there is push back to supporting it is because it isn't clear what the option is supposed to do/mean. And once we settle on a definition, the next decision to make is - is the scenario we are enabling a high-priority scenario that many customers need?
From that description why wouldn't --no-build mean don't run the Build target and only run the Publish target. Because if you've already run it without the --no-build flag then the Build target has already been run -- so everything is all prepared for the Publish target?
Like @dasMulli says above, there are shared targets between Build and Publish that will still need to be executed when just executing Publish. And the savings above and beyond an incremental build is usually negligible.
For example, on one of my projects it takes about 23s to build it the first time and then 9s to build it the second time (the one that used to be skipped). Yeah, 9s isn't that long in the scheme of things, but it isn't nothing either.
If you are interested in tracking down why the 2nd time is taking 9s, you can pass /v:diag into both dotnet build and dotnet publish. This will print out a lot of information (you probably want to pipe it to a file), but what you are interested in comes at the end. There is a table that shows where all the time is being spent in the build. For example, here is the table of publishing an ASP.NET 2.0 app on my local machine:
First Time
Project Performance Summary:
6806 ms F:\DotNetTest\TestWeb\TestWeb.csproj 1 calls
6806 ms Publish 1 calls
Target Performance Summary:
0 ms _DotNetCLIPrePublish 1 calls
0 ms ComputeAndCopyFilesToPublishDirectory 1 calls
0 ms BeforeResGen 1 calls
0 ms PrepareResourceNames 1 calls
0 ms _DotNetCLIPostPublish 1 calls
0 ms ResGen 1 calls
0 ms AfterBuild 1 calls
0 ms GetFrameworkPaths 1 calls
0 ms ResolveReferences 1 calls
0 ms GetReferenceAssemblyPaths 1 calls
0 ms PrepareResources 1 calls
0 ms _AspNetCoreProjectSystemPrePublish 1 calls
0 ms BeforeBuild 1 calls
0 ms Compile 1 calls
0 ms AfterResGen 1 calls
0 ms SetWin32ManifestProperties 1 calls
0 ms CreateCustomManifestResourceNames 1 calls
0 ms GenerateUserSecretsAttribute 1 calls
0 ms CoreBuild 1 calls
0 ms GenerateAssemblyInfo 1 calls
0 ms BeforePublish 1 calls
0 ms _AspNetCoreProjectSystemPostPublish 1 calls
0 ms AfterPublish 1 calls
0 ms _CopySourceItemsToOutputDirectory 1 calls
0 ms CreateSatelliteAssemblies 1 calls
0 ms AfterCompile 1 calls
0 ms PrepareForRun 1 calls
0 ms AfterResolveReferences 1 calls
0 ms InjectReference_efa7ce74-36bd-481a-bac0-42e316fc1d57 1 calls
0 ms IncludeTransitiveProjectReferences 1 calls
0 ms InjectReference_095e2d6d-4484-4c4e-b23a-d4bd8983312a 1 calls
0 ms BeforeCompile 1 calls
0 ms BeforeResolveReferences 1 calls
0 ms Build 1 calls
0 ms CopyFilesToPublishDirectory 1 calls
0 ms PrepareProjectReferences 1 calls
0 ms _DefaultMicrosoftNETPlatformLibrary 1 calls
0 ms ResolvePackageDependenciesForBuild 1 calls
0 ms ResolveSDKReferences 1 calls
0 ms _SetTargetFrameworkMonikerAttribute 1 calls
0 ms ResolveLockFileAnalyzers 1 calls
0 ms BuildOnlySettings 1 calls
0 ms PublishWithAspNetCoreTargetManifest 1 calls
0 ms ComputePrivateAssetsPackageReferences 1 calls
0 ms ExpandSDKReferences 1 calls
0 ms GetInstalledSDKLocations 1 calls
0 ms GetTargetPath 1 calls
0 ms InjectReference_324b1a06-f466-4b33-a9b7-baf91ae299f2 1 calls
0 ms ComputeDependencyFileCompilerOptions 1 calls
0 ms _CheckForUnsupportedSelfContained 1 calls
0 ms _ComputeNetPublishAssets 1 calls
0 ms _GenerateRunCommandFile 1 calls
0 ms _SplitProjectReferencesByFileExistence 1 calls
0 ms _GenerateCompileInputs 1 calls
0 ms CoreResGen 1 calls
0 ms _DetermineProjectType 1 calls
0 ms Publish 1 calls
0 ms _InitPublishIntermediateOutputPath 1 calls
0 ms _InitProjectCapabilityProperties 1 calls
0 ms _CheckForCompileOutputs 1 calls
0 ms PrepareForPublish 1 calls
0 ms _GenerateEFSQLScripts 1 calls
0 ms _GenerateSatelliteAssemblyInputs 1 calls
0 ms _ComputeLockFileFrameworks 1 calls
0 ms _TransformAppSettings 1 calls
0 ms ResolveProjectReferences 1 calls
1 ms _ComputeNETCoreBuildOutputFiles 1 calls
1 ms SplitResourcesByCulture 1 calls
1 ms _SetEmbeddedWin32ManifestProperties 1 calls
1 ms ComputeFilesToPublish 1 calls
1 ms GeneratePublishRuntimeConfigurationFile 1 calls
1 ms GetAssemblyVersion 1 calls
1 ms GetCopyToOutputDirectoryItems 1 calls
2 ms DefaultCopyToPublishDirectoryMetadata 1 calls
2 ms _HandlePublishFileConflicts 1 calls
2 ms IncrementalClean 1 calls
2 ms AssignTargetPaths 1 calls
2 ms GenerateTargetFrameworkMonikerAttribute 1 calls
2 ms _ComputeCopyToPublishDirectoryItems 1 calls
2 ms GetCopyToPublishDirectoryItems 1 calls
2 ms _ComputeLockFileAnalyzers 1 calls
3 ms CoreGenerateUserSecretsAttribute 1 calls
3 ms _ComputeActiveTFMFileDependencies 1 calls
4 ms _GetProjectReferenceTargetFrameworkProperties 1 calls
4 ms PrepareForBuild 1 calls
4 ms _ComputeTransitiveProjectReferences 1 calls
4 ms _CheckForInvalidConfigurationAndPlatform 1 calls
4 ms CheckForDuplicateItems 1 calls
5 ms _ComputeTFMOnlyFileDependencies 1 calls
5 ms CopyFilesToOutputDirectory 1 calls
6 ms CoreGenerateAssemblyInfo 1 calls
6 ms _CopyOutOfDateSourceItemsToOutputDirectory 1 calls
6 ms _ComputeActiveTFMPackageDependencies 1 calls
7 ms _CheckForUnsupportedTargetFramework 1 calls
15 ms CheckForImplicitPackageReferenceOverrides 1 calls
19 ms _TransformWebConfig 1 calls
22 ms _ComputeResolvedFilesToPublishTypes 1 calls
24 ms RunResolvePublishAssemblies 1 calls
26 ms _GenerateCompileDependencyCache 1 calls
27 ms _CleanGetCurrentAndPriorFileWrites 1 calls
30 ms _IncludePrePublishGeneratedContent 1 calls
40 ms ComputeRefAssembliesToPublish 1 calls
62 ms _CopyResolvedFilesToPublishPreserveNewest 1 calls
64 ms GenerateBuildRuntimeConfigurationFiles 1 calls
74 ms _ComputeLockFileReferences 1 calls
81 ms GeneratePublishDependencyFile 1 calls
82 ms ResolveLockFileReferences 1 calls
87 ms RunProduceContentAssets 1 calls
148 ms GenerateBuildDependencyFile 1 calls
244 ms _ComputeLockFileCopyLocal 1 calls
247 ms _HandlePackageFileConflicts 1 calls
249 ms _CopyResolvedFilesToPublishAlways 1 calls
276 ms RunResolvePackageDependencies 1 calls
1166 ms CoreCompile 1 calls
3721 ms ResolveAssemblyReferences 1 calls
Task Performance Summary:
0 ms Delete 1 calls
0 ms ReadLinesFromFile 1 calls
0 ms AssignCulture 1 calls
0 ms RemoveDuplicates 2 calls
0 ms GetFrameworkPath 1 calls
1 ms FindAppConfigFile 1 calls
1 ms FindUnderPath 5 calls
1 ms MSBuild 1 calls
1 ms GetAssemblyVersion 1 calls
1 ms Message 4 calls
2 ms AssignTargetPath 6 calls
2 ms WriteLinesToFile 2 calls
3 ms MakeDir 2 calls
4 ms CheckForDuplicateItems 3 calls
7 ms CheckForImplicitPackageReferenceOverrides 1 calls
8 ms WriteCodeFragment 2 calls
10 ms Hash 1 calls
17 ms TransformWebConfig 1 calls
18 ms ProduceContentAssets 1 calls
22 ms ConvertToAbsolutePath 2 calls
24 ms ResolvePublishAssemblies 1 calls
64 ms GenerateRuntimeConfigurationFiles 2 calls
144 ms ResolvePackageFileConflicts 2 calls
229 ms GenerateDepsFile 2 calls
274 ms ResolvePackageDependencies 1 calls
316 ms Copy 5 calls
1164 ms Csc 1 calls
3719 ms ResolveAssemblyReference 1 calls
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:07.19
Second Time
Project Performance Summary:
5923 ms F:\DotNetTest\TestWeb\TestWeb.csproj 1 calls
5923 ms Publish 1 calls
Target Performance Summary:
0 ms ResGen 1 calls
0 ms BeforeResGen 1 calls
0 ms PrepareResourceNames 1 calls
0 ms ResolveReferences 1 calls
0 ms Compile 1 calls
0 ms _DotNetCLIPostPublish 1 calls
0 ms _DotNetCLIPrePublish 1 calls
0 ms ComputeAndCopyFilesToPublishDirectory 1 calls
0 ms _AspNetCoreProjectSystemPrePublish 1 calls
0 ms AfterBuild 1 calls
0 ms GetFrameworkPaths 1 calls
0 ms PrepareResources 1 calls
0 ms AfterResGen 1 calls
0 ms SetWin32ManifestProperties 1 calls
0 ms BeforeBuild 1 calls
0 ms PrepareProjectReferences 1 calls
0 ms CreateSatelliteAssemblies 1 calls
0 ms BeforePublish 1 calls
0 ms CreateCustomManifestResourceNames 1 calls
0 ms GenerateUserSecretsAttribute 1 calls
0 ms BeforeCompile 1 calls
0 ms CoreBuild 1 calls
0 ms AfterCompile 1 calls
0 ms AfterResolveReferences 1 calls
0 ms GenerateAssemblyInfo 1 calls
0 ms CopyFilesToPublishDirectory 1 calls
0 ms _CopySourceItemsToOutputDirectory 1 calls
0 ms ResolvePackageDependenciesForBuild 1 calls
0 ms InjectReference_efa7ce74-36bd-481a-bac0-42e316fc1d57 1 calls
0 ms Build 1 calls
0 ms BuildOnlySettings 1 calls
0 ms GetReferenceAssemblyPaths 1 calls
0 ms _AspNetCoreProjectSystemPostPublish 1 calls
0 ms AfterPublish 1 calls
0 ms BeforeResolveReferences 1 calls
0 ms PrepareForRun 1 calls
0 ms IncludeTransitiveProjectReferences 1 calls
0 ms ExpandSDKReferences 1 calls
0 ms ResolveLockFileAnalyzers 1 calls
0 ms _DefaultMicrosoftNETPlatformLibrary 1 calls
0 ms InjectReference_095e2d6d-4484-4c4e-b23a-d4bd8983312a 1 calls
0 ms _SetTargetFrameworkMonikerAttribute 1 calls
0 ms PublishWithAspNetCoreTargetManifest 1 calls
0 ms ComputePrivateAssetsPackageReferences 1 calls
0 ms ResolveSDKReferences 1 calls
0 ms ComputeDependencyFileCompilerOptions 1 calls
0 ms _CheckForUnsupportedSelfContained 1 calls
0 ms _ComputeNetPublishAssets 1 calls
0 ms GetTargetPath 1 calls
0 ms _SplitProjectReferencesByFileExistence 1 calls
0 ms PrepareForPublish 1 calls
0 ms _GenerateRunCommandFile 1 calls
0 ms GetInstalledSDKLocations 1 calls
0 ms CoreResGen 1 calls
0 ms InjectReference_324b1a06-f466-4b33-a9b7-baf91ae299f2 1 calls
0 ms _DetermineProjectType 1 calls
0 ms _CheckForCompileOutputs 1 calls
0 ms _InitProjectCapabilityProperties 1 calls
0 ms _GenerateSatelliteAssemblyInputs 1 calls
0 ms GenerateBuildDependencyFile 1 calls
0 ms _GenerateCompileInputs 1 calls
0 ms _InitPublishIntermediateOutputPath 1 calls
0 ms Publish 1 calls
0 ms ResolveProjectReferences 1 calls
0 ms _GenerateEFSQLScripts 1 calls
0 ms _ComputeLockFileFrameworks 1 calls
0 ms _TransformAppSettings 1 calls
1 ms _ComputeNETCoreBuildOutputFiles 1 calls
1 ms SplitResourcesByCulture 1 calls
1 ms IncrementalClean 1 calls
1 ms _SetEmbeddedWin32ManifestProperties 1 calls
1 ms DefaultCopyToPublishDirectoryMetadata 1 calls
1 ms GetCopyToOutputDirectoryItems 1 calls
1 ms _HandlePublishFileConflicts 1 calls
1 ms GeneratePublishRuntimeConfigurationFile 1 calls
2 ms CoreGenerateUserSecretsAttribute 1 calls
2 ms ComputeFilesToPublish 1 calls
2 ms CoreGenerateAssemblyInfo 1 calls
2 ms CopyFilesToOutputDirectory 1 calls
2 ms _ComputeLockFileAnalyzers 1 calls
2 ms AssignTargetPaths 1 calls
2 ms GenerateTargetFrameworkMonikerAttribute 1 calls
2 ms GetAssemblyVersion 1 calls
3 ms PrepareForBuild 1 calls
3 ms _GetProjectReferenceTargetFrameworkProperties 1 calls
3 ms _ComputeActiveTFMFileDependencies 1 calls
3 ms _ComputeCopyToPublishDirectoryItems 1 calls
3 ms CheckForDuplicateItems 1 calls
3 ms GetCopyToPublishDirectoryItems 1 calls
4 ms _ComputeTFMOnlyFileDependencies 1 calls
4 ms _CheckForInvalidConfigurationAndPlatform 1 calls
4 ms _ComputeTransitiveProjectReferences 1 calls
6 ms _ComputeActiveTFMPackageDependencies 1 calls
8 ms _CheckForUnsupportedTargetFramework 1 calls
13 ms CheckForImplicitPackageReferenceOverrides 1 calls
14 ms CoreCompile 1 calls
16 ms _TransformWebConfig 1 calls
16 ms _ComputeResolvedFilesToPublishTypes 1 calls
24 ms _CleanGetCurrentAndPriorFileWrites 1 calls
25 ms RunResolvePublishAssemblies 1 calls
36 ms _CopyOutOfDateSourceItemsToOutputDirectory 1 calls
41 ms ComputeRefAssembliesToPublish 1 calls
50 ms _GenerateCompileDependencyCache 1 calls
72 ms _IncludePrePublishGeneratedContent 1 calls
72 ms _ComputeLockFileReferences 1 calls
80 ms GenerateBuildRuntimeConfigurationFiles 1 calls
83 ms ResolveLockFileReferences 1 calls
86 ms RunProduceContentAssets 1 calls
159 ms GeneratePublishDependencyFile 1 calls
202 ms _CopyResolvedFilesToPublishAlways 1 calls
228 ms _HandlePackageFileConflicts 1 calls
236 ms _ComputeLockFileCopyLocal 1 calls
273 ms _CopyResolvedFilesToPublishPreserveNewest 1 calls
275 ms RunResolvePackageDependencies 1 calls
3835 ms ResolveAssemblyReferences 1 calls
Task Performance Summary:
0 ms Delete 1 calls
0 ms AssignCulture 1 calls
0 ms RemoveDuplicates 2 calls
1 ms GetFrameworkPath 1 calls
1 ms FindAppConfigFile 1 calls
1 ms ReadLinesFromFile 1 calls
1 ms MSBuild 1 calls
1 ms FindUnderPath 5 calls
1 ms WriteLinesToFile 1 calls
1 ms Message 4 calls
2 ms MakeDir 2 calls
2 ms AssignTargetPath 6 calls
2 ms GetAssemblyVersion 1 calls
3 ms CheckForDuplicateItems 3 calls
6 ms CheckForImplicitPackageReferenceOverrides 1 calls
10 ms Hash 1 calls
14 ms TransformWebConfig 1 calls
18 ms ProduceContentAssets 1 calls
20 ms ConvertToAbsolutePath 2 calls
25 ms ResolvePublishAssemblies 1 calls
81 ms GenerateRuntimeConfigurationFiles 2 calls
143 ms ResolvePackageFileConflicts 2 calls
159 ms GenerateDepsFile 1 calls
204 ms Copy 3 calls
268 ms ResolvePackageDependencies 1 calls
3833 ms ResolveAssemblyReference 1 calls
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:06.18
As you can see, CSC is only taking a little over 1s the first time. However, even in the 2nd time ResolveAssemblyReference is taking ~65% of the time (3835 ms / 5923 ms). As I asked above, do you expect that when you dotnet publish --no-build that you shouldn't get any referenced assemblies copied to your output directory?
(Now granted, we probably have some sort of perf bug in ResolveAssemblyReference, but that is a different discussion.)
Anyway, I'd be interested in learning what you find is taking 9s on your 2nd build. I'm sure you would be too 😉.
Thanks for the information! I will try that out and see what the bottleneck is.
As for the ResolveAssemblyReference -- If that isn't done as part of the Build task, then I would expect it to be done, but if it isn't done as part of the Build task, then I would expect it to be done.
Basically I just want to avoid doing duplicate work.
Same problem. Trying to automate publishing Asp.NET Core project. There is no way to force publish after build, so I ended up adding a 'dotnet publish' post-build event. Sadly it results in recursive builds that never end. A --no-build switch would fix something that I will now have to spend hours trying to work around.
Hey @gulbanana : thanks for the tip but for me msbuild still rebuilds dependent projects. So it's different than the former --no-build options that didn't even tried to build anything and just assumed the right dll was here.
There's also the /p:BuildProjectReferences=false switch that indicates that all dependencies are up-to-date and don't need to be rebuilt (see ProjectReference protocol)
Reacted by Vincent de Lagabbe, Eternal21, Ruben Delange, Viktors Telle, Daniel Sagita, Arish Labroo, Maksym Koshovyi and AraHaan
As you can see, we use a /p msbuild option for dotnet build to specify the version that we want for our assembly. This used to work great.
With .NET Core 2, since the dotnet publish does on dotnet build, the result of dotnet publish recompiles the assembly without using the 6.6.6 assembly version. We therefore end-up with a docker container that contains assemblies that:
were not used during the tests
don't have the good assembly version
I can fix this problem using dotnet publish /p:Version=6.6.6. But in fact, the problem is more complex since we also use dotnet lambda package that does an implicit dotnet publish that does not allow me to specify the /p:Version=6.6.6 parameters. See aws/aws-lambda-dotnet#210 for more details.
Activity
livarcocc commentedon Jan 18, 2017
@dsplaisted @nguerrera @eerhardt Is there a way to trigger a publish without build?
TheRealPiotrP commentedon Jan 18, 2017
@hongdai It would be useful if you can share how you used this flag. I think there was some debate about whether it is still useful.
eerhardt commentedon Jan 18, 2017
Agreed. Getting all the use cases for why this switch is useful helps us understand whether to put it back or not.
One of the use cases I've recently encountered was the F# team (specifically @KevinRansom) was using this switch to publish a project's references, but he didn't want the project's output (its .dll) published. The replacement in that case is to add the MSBuild property
<CopyBuildOutputToPublishDirectory>false</CopyBuildOutputToPublishDirectory>in your .csproj. That way, the current project's .dll isn't published.FYI - @livarcocc and @piotrpMSFT, we could use this switch in the dotnet/cli ourselves in https://github.com/dotnet/cli/blob/rel/1.0.0/src/redist/redist.csproj. Then we wouldn't need to delete the
redist.dllafter publish, like we are currently doing.codito commentedon Feb 10, 2017
It will be great to have
--no-buildsupported.We do the following in vstest repo:
In step 2, all the product dlls are built again. Depending on the number projects published, some of the common dependencies could be built multiple times.Update: our build process had a race condition on resources files which was slowing down the process. As @eerhardt notes below, msbuild incremental build does kick in, it is not a significant overhead for us now.
eerhardt commentedon Feb 10, 2017
Why is incremental building not kicking in? MSBuild knows if a project is already built, and doesn't need to build it again.
hongdai commentedon Feb 10, 2017
@piotrpMSFT We used to have our own publish target and run in AfterBuild. Without no-build switch, the publish target will invoke a build and cause a infinite loop, unless we add a condition.
dotnet pack still supports no-build switch. I think the usage should be similar.
atanasa commentedon Mar 13, 2017
+1
As I see it, there should be an option to have the output of a build be the output of what you call "publish". I'd say that this should be the default behavior but that is debatable. As far as I understand it from reading the issues and documentation, this discrepancy is a workaround to speed up the build time of console apps (e.g. use the nuget cache to save on checksum calculations?!).
.Net is used for more than console apps and as such that workaround is not applicable to hosts different than
dotnet run. For those cases, the actual dependencies are needed as part of the build output so it is runnable.For such cases, I've managed to make
dotnet publishoutput what is the real build output. To have it integrated with the VS Run command, I'd like to have the MSBuild Build target run the Publish target logic. This leads me to the infinite loop that @hongdai is talking about.For me the no-build switch is a workaround. Ideally I would like you to support the case where the output of the build contains all the required runtime dependencies.
eamodio commentedon Apr 28, 2017
Same issue here -- Why wasn't this BREAKING CHANGE announced on the announcement repo? I've just converted all our stuff to csproj and now this broke our whole ci/azure setup.
We have 3 deployments setup on AppVeyor for a single solution, so we have 3 configurations that do the following:
eerhardt commentedon May 1, 2017
@eamodio - same question as above - Why is incremental building not kicking in?
eamodio commentedon May 1, 2017
Let's say it is kicking in (which I think it is) -- just the fact the it has to run msbuild, scan for the project(s), see if they need building, etc -- all takes time; time I don't want to be waiting for my CI to finish. For example, on one of my projects it takes about 23s to build it the first time and then 9s to build it the second time (the one that used to be skipped). Yeah, 9s isn't that long in the scheme of things, but it isn't nothing either.
Also, given this flag is seemingly just a simple -- don't run msbuild -- I don't understand why it is so desirable to not support it?
dasMulli commentedon May 1, 2017
I think this is caused by the current situations that large package graphs (netstandard.library, m.n.app) slow down msbuild projects which is causing project references to slow down linear (1 project 1 sec, 10 projects 10 sec) and has been discussed in https://github.com/dotnet/cli/issues/5918, #1116, dotnet/msbuild#1276 and maybe even more.
Even if build targets are avoided for publish, I believe
RunResolvePackageDependenciesandResolveAssemblyReferenceswould still need to be run to determine the proper publish output (I might be wrong) - and those are the targets that cause the slow incremental builds.eerhardt commentedon May 2, 2017
@dasMulli hit the nail on the head.
What does
--no-buildmean? In reality in project.json world, it really meant something closer to--no-compile. But theBuildtarget in MSBuild does so much more than justCompileyour source code.Contentfiles that need to be copied to the outputDoing a
Publishwithout the things that happen during theBuildtarget in MSBuild is almost pointless. What do you expect to have happened?Another thing to understand is that
dotnet publishreally means "run thePublishMSBuild target". So it obviously isn't as simple as "don't run msbuild", since you can't run thePublishtarget without MSBuild.So the reason there is push back to supporting it is because it isn't clear what the option is supposed to do/mean. And once we settle on a definition, the next decision to make is - is the scenario we are enabling a high-priority scenario that many customers need?
eamodio commentedon May 2, 2017
From that description why wouldn't
--no-buildmean don't run theBuildtarget and only run thePublishtarget. Because if you've already run it without the--no-buildflag then theBuildtarget has already been run -- so everything is all prepared for thePublishtarget?eerhardt commentedon May 2, 2017
Like @dasMulli says above, there are shared targets between
BuildandPublishthat will still need to be executed when just executingPublish. And the savings above and beyond an incremental build is usually negligible.If you are interested in tracking down why the 2nd time is taking 9s, you can pass
/v:diaginto bothdotnet buildanddotnet publish. This will print out a lot of information (you probably want to pipe it to a file), but what you are interested in comes at the end. There is a table that shows where all the time is being spent in the build. For example, here is the table of publishing an ASP.NET 2.0 app on my local machine:First Time
Second Time
As you can see,
CSCis only taking a little over 1s the first time. However, even in the 2nd timeResolveAssemblyReferenceis taking ~65% of the time (3835 ms / 5923 ms). As I asked above, do you expect that when youdotnet publish --no-buildthat you shouldn't get any referenced assemblies copied to your output directory?(Now granted, we probably have some sort of perf bug in
ResolveAssemblyReference, but that is a different discussion.)Anyway, I'd be interested in learning what you find is taking 9s on your 2nd build. I'm sure you would be too 😉.
eamodio commentedon May 2, 2017
Thanks for the information! I will try that out and see what the bottleneck is.
As for the
ResolveAssemblyReference-- If that isn't done as part of theBuildtask, then I would expect it to be done, but if it isn't done as part of theBuildtask, then I would expect it to be done.Basically I just want to avoid doing duplicate work.
23 remaining items
Eternal21 commentedon Oct 20, 2017
Same problem. Trying to automate publishing Asp.NET Core project. There is no way to force publish after build, so I ended up adding a 'dotnet publish' post-build event. Sadly it results in recursive builds that never end. A --no-build switch would fix something that I will now have to spend hours trying to work around.
gulbanana commentedon Oct 21, 2017
try
dotnet msbuild /t:publish /p:NoBuild=Truevineus commentedon Oct 31, 2017
Hey @gulbanana : thanks for the tip but for me msbuild still rebuilds dependent projects. So it's different than the former
--no-buildoptions that didn't even tried to build anything and just assumed the right dll was here.dasMulli commentedon Oct 31, 2017
There's also the
/p:BuildProjectReferences=falseswitch that indicates that all dependencies are up-to-date and don't need to be rebuilt (see ProjectReference protocol)vineus commentedon Nov 2, 2017
@dasMulli : thanks a lot! works great! (and I can finally publish my 5 projects without having to rebuild everything all the time :-) )
mabead commentedon Jan 24, 2018
Here's how our build process used to look like with the 1.0.4 .NET Core SDK:
As you can see, we use a /p msbuild option for
dotnet buildto specify the version that we want for our assembly. This used to work great.With .NET Core 2, since the
dotnet publishdoes ondotnet build, the result ofdotnet publishrecompiles the assembly without using the 6.6.6 assembly version. We therefore end-up with a docker container that contains assemblies that:I can fix this problem using
dotnet publish /p:Version=6.6.6. But in fact, the problem is more complex since we also usedotnet lambda packagethat does an implicitdotnet publishthat does not allow me to specify the/p:Version=6.6.6parameters. See aws/aws-lambda-dotnet#210 for more details.Please add the --no-build option ;)
Fix publish version
diegohb commentedon Feb 8, 2018
Is there plans to add the no-build option back? Not building the references isn’t quite the same thing.. thanks!
brainwipe commentedon Feb 9, 2018
@diegohb At the top of this issue, you can see that it's slated for release with milestone 2.1.3xx.
Check out all the issues in that milestone here: https://github.com/dotnet/cli/milestone/17
nguerrera commentedon Feb 9, 2018
I will try to get to this soon.
nguerrera commentedon Apr 3, 2018
#2111 (in PR) implements the dotnet/sdk half of this. After that, we just need to wire --no-build to /p:NoBuild=true here.