Visual Studio Version: 16.3.1
Summary / Steps to Reproduce / Behavior:
I have a .NET Core 3.0 WinForms application and I have added a prebuild event to my project. It gets added to the csproj like this:
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
  <Exec Command="$(ProjectDir)PreBuildTasks.exe" />
</Target>
It basically launches my prebuild exe, which does a few things, like increment the version in AssemblyInfo. This has always worked fine until I started experimenting with .NET Core and publishing.
For context, I am going to add this right before the Exec Command:
<Message Importance="high" Text="This is a message" />
When I publish the project (right click project, Publish), this is what I see:

It's clear the prebuild task is running twice. I spent a while researching a way to resolve this problem. The closest solution I found was this. I added Condition="'$(DeployOnBuild)' != 'true'" as directed, but unfortunately it did not do anything. The other solution in that thread says the issue is fixed, so what is happening here?
This behavior may be by design, but I decided to open this issue in case it is not, and because I'd like some guidance on the correct way to solve this problem if I am going at this the wrong way. I only want my prebuild task to run on Build, not Publish.
@EatonZ have you used this tool before? http://msbuildlog.com/
To use it, generate a binary log file for your build, then open it in the viewer. It'll show you lots of information about what properties are available, and when different target/tasks are executed and why.
To generate the binlog, you pass /bl to msbuild.exe from the command line. Something like:
msbuild /bl /t:Build,Publish
                    @drewnoakes I have not - thank you for the link.
I used it to check what other properties could potentially be checked to determine if it's a Publish build. The best one I found was PublishProtocol. I added the following to my csproj:
Condition="'$(PublishProtocol)'==''"
...and it worked! My prebuild exe is only run once now.
While this solution is fine, I feel there can be a better one. Maybe a property like "IsPublishing" or "IsPublishBuild" could be added, or maybe an option to not run prebuild on publish at all. What do you think?
By the way, when publishing a .NET Framework web app, this doesn't happen - the prebuild event is run once. So this is unique to .NET Core it seems.
Can you define such a property yourself with something like:
<Target Name="MyPrePublish" BeforeTargets="Publish">
  <PropertyGroup>
    <IsPublishing>true</IsPublishing>
  </PropertyGroup>
</Target>
                    I suppose that will work fine too. Is there no desire to add a built-in property like this?
Shouldn't this issue go to the github.com/dotnet/sdk repo?
@jmarolf @davidwengier Ok, thanks for moving. At first glance it seemed like the project repo was the best place.
cc @dsplaisted @nguerrera
Any further thoughts on this?
Also curious to hear if there are any updates on this. Experienced a similar issue with "dotnet publish" running pre-build tasks twice when executed from a directory containing the .sln file, but not when running it from sub-folders containing their own .csproj files.
Can it be that the project in question targets multiple <TargetFrameworks>? Because then prebuild MSBuild Targets will run for each target framework. 
(VS Pro 16.8.0 Preview 2.1 + .NET SDK v5.0.0-preview.8)
Blazor WebAssembly App's folder publish seems to call CoreBuild target twice as well (probably other pre-build ones as well). Once during Build and once during Publish.
<PropertyGroup>
  <TargetFramework>net5.0</TargetFramework>
  <RuntimeIdentifier>browser-wasm</RuntimeIdentifier>
  <UseBlazorWebAssembly>true</UseBlazorWebAssembly>
</PropertyGroup>
Condition="'$(DeployOnBuild)' != 'true'" helped here though (properties set under this condition, will only be set for the Build).
No change in .NET 5 and VS 16.8. Would love to hear if any consideration is being given to this.
I don't think we have any real plans to fix this.  From the command line, the target would probably be called only once if you ran dotnet publish.  If it's getting run twice, then investigating a binary log should help reveal the reason why.  From VS, I'm not sure there's any way to stop it from calling the build targets twice.
FYI @vijayrkn @richlander @KathleenDollard
@dsplaisted @vijayrkn @richlander @KathleenDollard If there is no plan to fix, then can you make the workaround a little better? Such as a new property I suggested in https://github.com/dotnet/sdk/issues/3707#issuecomment-537161696.
Most helpful comment
Also curious to hear if there are any updates on this. Experienced a similar issue with "dotnet publish" running pre-build tasks twice when executed from a directory containing the .sln file, but not when running it from sub-folders containing their own .csproj files.