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

Pack in Visual Studio fails with transitive project reference in a clean state #5870

Open
TFTomSun opened this issue Nov 7, 2020 · 11 comments

Comments

@TFTomSun
Copy link

TFTomSun commented Nov 7, 2020

Visual Studio Version: 16.8.0
Steps to reproduce:

  • clone master of https://github.com/AppGates/AppGates.Build.Versioning
  • pack external library (it's not relevant for this scenario, but I used that repo for another issue too)
  • clean referencing library
  • pack referencing library
    -> build error, the transitive library (project reference) is not built during pack

Expected behavior:
The transitive project reference is built, like the direct project references of the packed project.

@TFTomSun TFTomSun added bug needs-triage Have yet to determine what bucket this goes in. labels Nov 7, 2020
@benvillalobos
Copy link
Member

Team Triage: Does this fail only in Visual Studio? Have you tried on the command line?

@LeonsBuntis
Copy link

This fails also by directly using msbuild.

@TFTomSun
Copy link
Author

In case somebody is interested. I implemented a workaround, by bypassing the visual studio pack and trigger a build with GeneratePackageOnBuild=true instead.

 <PropertyGroup>
    <IsPackableCopy>true</IsPackableCopy>
    <IsPackableCopy Condition="'$(IsPackable)' == 'false'">false</IsPackableCopy>
  </PropertyGroup>

  <!--Avoid the weird half dependency build of Visual Studio during pack-->
  <PropertyGroup >
        <IsPackable>false</IsPackable>
  </PropertyGroup>

  <Target Name="CustomPack" AfterTargets="Pack" >
    <PropertyGroup>
      <CustomPackBuildProperties>
        GeneratePackageOnBuild=true;
        NoBuild=false;
        BuildingProject=true;
        <!--BuildDependsOn=$(BuildDependsOn_Copy);-->
        <!--IsPackable=true;-->
        BuildingInsideVisualStudio=false;
        IsLocalBuild=$(IsLocalBuild);
      </CustomPackBuildProperties>
    </PropertyGroup>
    <Message Text="IsPackableCopy: $(IsPackableCopy)"/>
    <MSBuild
       Targets="Restore;Build"
      Condition="$(IsPackableCopy)"
             Projects="$(MSBuildProjectFullPath)"
             Properties="$(CustomPackBuildProperties)"/>
    
  </Target>


@benvillalobos
Copy link
Member

Team Triage: Out of curiosity, does this repro when you pass /graph as a parameter for your build?

@benvillalobos
Copy link
Member

@Forgind See if this repros.

@Forgind
Copy link
Member

Forgind commented Dec 10, 2020

The problem here appears to be the intertwined dependencies of Pack and Build. I don't fully understand why, but it seems that in certain scenarios, Build depends on Pack, so there can't be an explicit dependency of Pack on Build because that would be a circular dependency in those cases. In this case, Pack is trying to execute the targets it depends on—which doesn't include Build—before Build executes. Specifically, it tries to execute GenerateNuspec, which expected Build to have executed already, but it hadn't, so this fails.

The easiest fix I found was to run with /t:Build;Pack. I'm still confused as to the logic here, but perhaps there's a solution buried there somewhere.

@TFTomSun
Copy link
Author

TFTomSun commented Dec 11, 2020

@Forgind there's a build flag "GeneratePackageOnBuild". That might be the reason why build depends on pack.

@Forgind but your fix won't work within visual studio, right? At least I don't know how I could configure VS to call not just the pack target on the project on which I click pack.

@Forgind
Copy link
Member

Forgind commented Dec 28, 2020

Maybe it makes sense to have Build sometimes depend on Pack from GeneratePackageOnBuild but Pack depend on Build's dependencies?

@TFTomSun
Copy link
Author

TFTomSun commented Dec 29, 2020

@Forgind When I make some changes on the source code, I expect, that the source code is built before it is packed, right?
I've recently created a build package, that fixes the Visual Studio pack behavior to what I'd expect to happen, when I click on the pack context menu entry of a project file in VS:

  • Restore the root project and it's project dependencies to ensure that floating dependencies are up to date
  • (Delta-)Build the root project and it's dependencies
  • Pack the root project and it's dependencies

The package name is AppGates.Net.Build.TransitivePack
The project url is https://gitlab.com/appgates/net/build

@Forgind
Copy link
Member

Forgind commented Dec 30, 2020

Correct. The tricky part is that the Build target doesn't really do anything—it's just something logic can hook into. It's intended to be the last target to actually be executed, after BeforeBuild and also after AfterBuild. That might be more confusing than necessary, but it's helpful in getting the final build result (succeeded, failed) to consider everything and not just the result of half of the total build process.

Your solution (and the workaround) should work, I think, but they both make the Build complete before Pack starts. I think that would mean that if there's a problem with Pack but not with Build, it will report success anyway.

Maybe a simpler solution to what I posed above that still retains the accurate reporting would be to have Pack depend on AfterBuild? Or hook into that some other way? I'll have to look more at build ordering before I know if that makes sense.

@TFTomSun
Copy link
Author

TFTomSun commented Dec 31, 2020

@Forgind I don't think that there's an issue with unexpected the success results. Did you try out the package? The package implementation is different to what I posted above. Actually I turned off the complete default build and pack behavior in case Pack is called inside VisualStudio. There were simply to many weird side effects with the current VS behavior, especially with project dependencies and a mixture of single target and multi target projects.

Instead I call the build and the pack targets on my own in a target that I attached after Pack.

Of course I would appreciate a simpler solution. But I can tell you, there are a lot of corner cases and it took me quite long to make it work for the corner cases that I know up to now. If you try to find a better solution have a look at the single/multi target project mixture. The multi target projects build seems to be completely different (with these InnerBuilds, but the pack needs to be done outside, etc.). That has also an impact on the Targets/hooks that you could use for another pack logic.

@benvillalobos benvillalobos removed the needs-triage Have yet to determine what bucket this goes in. label Apr 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants