-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Use PackageDownload in torn builds #41951
Conversation
31d49bb
to
1286ed0
Compare
<Target Name="_AddMicrosoftNetCompilerToolsetFrameworkPackage" Condition="'$(MSBuildRuntimeType)' == 'Full'" BeforeTargets="CollectPackageReferences"> | ||
<PropertyGroup Condition="'$(MSBuildRuntimeType)' == 'Full'"> | ||
<!-- Automatically opt users into using the toolset package if they are running an MSBuild other than what this SDK was built against. | ||
This is to reduce 'tearing'/depdendency mismatch, but as always users can override this behavior by disabling the hosted compiler flag. --> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to reduce 'tearing'/depdendency mismatch, but as always users can override this behavior by disabling the hosted compiler flag. --> | |
This is to reduce 'tearing'/dependency mismatch, but as always users can override this behavior by disabling the hosted compiler flag. --> |
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Net.Compilers.Toolset.Framework" ExcludeAssets="All" GeneratePathProperty="true" Condition="'$(DotNetBuildSourceOnly)' != 'true'" /> | ||
<Content Include="$(PkgMicrosoft_Net_Compilers_Toolset_Framework)\tasks\net472\**\*" PackagePath="%(RecursiveDir)" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two follow up items:
- Can you also make a change to roslyn which adds some documentation to this package outlining how it is now consumed in the .NET SDK? Essentially a marker that will alert anyone that is trying to change the code in roslyn to what it means in the .NET SDK?
- Can you file an issue in roslyn that tracks changing the bootstrap framework CI leg to more closely follow what the .NET SDK is now doing? Essentially set
/p:RoslynTargetsPath=...\net472
. That will help ensure our test coverage catches any authoring mistakes we make in roslyn.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<NETSdkWarning ResourceName="CannotDirectlyReferenceMicrosoftNetCompilersToolsetFramework" | ||
Condition="'@(PackageReference->AnyHaveMetadataValue('Identity', 'Microsoft.Net.Compilers.Toolset.Framework'))' == 'true'" /> | ||
<PropertyGroup Condition="'$(BuildWithNetFrameworkHostedCompiler)' == 'true' and '$(OS)' == 'Windows_NT'"> | ||
<RoslynTargetsPath>$(NuGetPackageRoot)\Microsoft.Net.Sdk.Compilers.Toolset\$(NETCoreSdkVersion)</RoslynTargetsPath> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way this is written means that if a customer both
- Sets
BuildWitHNetFrameworkHostedCompiler
or builds in a torn SDK - Sets
RoslynTargetsPath
Then we will simply ignore (2).
Is that the behavior that we want here? To me that seems reasonable but I also worry about confusing users if they set both and we are silently overwriting one of them. Should we issue a diagnostic here if both are set?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds reasonable, I've tried adding this warning, but I don't know how to reliably detect whether RoslynTargetsPath is set by the user or it has the default value set by msbuild.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm ... that is a good point. That would probably need a msbuild analyzer. Let's skip this for now, can revisit if it becomes a real problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is RoslynTargetsPath
meant to be set by customers? I see a few hundred times across all of GH. This seems like something that should have been a private variable originally.
This is to reduce 'tearing'/depdendency mismatch, but as always users can override this behavior by disabling the hosted compiler flag. --> | ||
<BuildWithNetFrameworkHostedCompiler Condition="'$(BuildWithNetFrameworkHostedCompiler)' == '' and '$(_IsDisjointMSBuildVersion)' == 'true'">true</BuildWithNetFrameworkHostedCompiler> | ||
</PropertyGroup> | ||
<UsingTask TaskName="Microsoft.CodeAnalysis.BuildTasks.CopyRefAssembly" AssemblyFile="$(RoslynTargetsPath)\Microsoft.Build.Tasks.CodeAnalysis.dll" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@rainersigwald should we change common.tasks in msbuild to have a comment that says more less "if you change this lest, you also need to change this file in the .NET SDK"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added a note here and to msbuild: dotnet/msbuild#10351
@@ -24,17 +24,15 @@ public void It_restores_Microsoft_Net_Compilers_Toolset_Framework_when_requested | |||
var testAsset = _testAssetsManager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't comment on it but then we should change the name of this test now to It_downloads...
@@ -53,28 +51,19 @@ public void It_restores_Microsoft_Net_Compilers_Toolset_Framework_when_MSBuild_i | |||
var testAsset = _testAssetsManager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same comment about name change
<data name="CannotDirectlyReferenceMicrosoftNetCompilersToolsetFramework" xml:space="preserve"> | ||
<value>NETSDK1205: The Microsoft.Net.Compilers.Toolset.Framework package should not be set directly. Set the property 'BuildWithNetFrameworkHostedCompiler' to 'true' instead if you need it.</value> | ||
<comment>{StrBegin="NETSDK1205: "}{Locked="Microsoft.Net.Compilers.Toolset.Framework"}{Locked="BuildWithNetFrameworkHostedCompiler"}</comment> | ||
</data> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@marcpopMSFT had a comment in a Teams thread about this - instead of removing this warning, should that be changed to warn customers if they reference the new Microsoft.Net.Sdk.Compilers.Toolset package?
We could do that, but nothing happens when customers reference the new package as it has a non-standard layout. So, a warning seems unnecessary to me.
A related question is what happens when a customer references the Microsoft.Net.Compilers.Toolset.Framework package (which we used to warn about). From local testing, it looks like the compiler from the explicit PackageReference takes precedence over the built-in disjoint detection and the PackageDownload.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can always remove a warning but adding one is a compat break, so I think I lean toward changing it rather than removing it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If referencing the old package takes precedents over the packagedownload, do we want to keep the original warning in place? I'm less worried now about the sdk package if referencing it doesn't do anything. CC @baronfel as this is one of those situations where a customer could do bad things to themselves but how much do we want to prevent/warn.
Are there any tests where there is a full end to end test of the system that includes a build? Basically want to exercise the entire code path include executing the compiler. Looking through the PR I didn't see you modify any, but it's possible that they could've been added by our earlier work in torn sdks. |
I don't think there are existing end-to-end tests, I can look into adding one, but perhaps as a follow up PR, I don't know how complicated that will be. |
Fine with it being a follow up PR. I'm not 100% sure if we can do an end-to-end test here or if we have to move that to installer. @baronfel can you help with some guidance here? |
<data name="CannotDirectlyReferenceMicrosoftNetCompilersToolsetFramework" xml:space="preserve"> | ||
<value>NETSDK1205: The Microsoft.Net.Compilers.Toolset.Framework package should not be set directly. Set the property 'BuildWithNetFrameworkHostedCompiler' to 'true' instead if you need it.</value> | ||
<comment>{StrBegin="NETSDK1205: "}{Locked="Microsoft.Net.Compilers.Toolset.Framework"}{Locked="BuildWithNetFrameworkHostedCompiler"}</comment> | ||
</data> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can always remove a warning but adding one is a compat break, so I think I lean toward changing it rather than removing it.
<NETSdkWarning ResourceName="CannotDirectlyReferenceMicrosoftNetCompilersToolsetFramework" | ||
Condition="'@(PackageReference->AnyHaveMetadataValue('Identity', 'Microsoft.Net.Compilers.Toolset.Framework'))' == 'true'" /> | ||
<PropertyGroup Condition="'$(BuildWithNetFrameworkHostedCompiler)' == 'true' and '$(OS)' == 'Windows_NT'"> | ||
<RoslynTargetsPath>$(NuGetPackageRoot)\Microsoft.Net.Sdk.Compilers.Toolset\$(NETCoreSdkVersion)</RoslynTargetsPath> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't NuGet lower-case the package name by default? I guess it won't matter since the only case we care about here is Windows but I'd still do
<RoslynTargetsPath>$(NuGetPackageRoot)\Microsoft.Net.Sdk.Compilers.Toolset\$(NETCoreSdkVersion)</RoslynTargetsPath> | |
<RoslynTargetsPath>$(NuGetPackageRoot)\microsoft.net.sdk.compilers.toolset\$(NETCoreSdkVersion)</RoslynTargetsPath> |
|
||
<ItemGroup Condition="'$(BuildWithNetFrameworkHostedCompiler)' == 'true' and '$(OS)' == 'Windows_NT' "> | ||
<PackageReference Include="Microsoft.Net.Compilers.Toolset.Framework" PrivateAssets="all" Version="$(_NetFrameworkHostedCompilersVersion)" IsImplicitlyDefined="true" /> | ||
<Target Name="_DownloadMicrosoftNetSdkCompilersToolsetPackage" Condition="'$(_NeedToDownloadMicrosoftNetSdkCompilersToolsetPackage)' == 'true'" BeforeTargets="CollectPackageReferences"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this need to be in a target? I think it was before so that the warning could be thrown--is that right @Forgind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Right, makes sense, it probably doesn't need to be in a Target. Currently it looks like we will be re-adding the warning based on #41951 (comment) - but I guess the PackageDownload could still be outside the Target.
There's no installer anymore. We do have E2E tests here but @MiYanni is still getting them lined up in the sdk test infrastructure and using the right layout. It might be possible to add a test there but I don't know how you validate as we don't have tight control over the VS version on the images (so you'd be setting the property explicitly but the behavior wouldn't be much different for an E2E test) |
I'm less concerned about the VS version and more concerned about basic functionality concerns. My idea for a test is more / less to do the following: > dotnet new webapp
> msbuild -p:BuildWithNetFrameworkHostedCompiler=true -bl Then ensure the build succeeded and it downloaded + used the compiler from the downloaded package. There is a bit of risk in constructing the components of this solution in multiple repos. This test would guard against silly mistakes in roslyn thta break the layout of the package, or build authoring errors that messed up the data flow to use the |
I think the current tests like |
This is pretty easy to do, something like: new BuildCommand(testAsset)
.Execute("-p:BuildWithNetFrameworkHostedCompiler=true")
.Should()
.Pass();
You can do this too, though most of our tests construct the project themselves or use checked-in assets. It's a question of whether you want to depend on the template and have the test use the latest version of the template (and potentially break because of changes to it). |
That's exactly what we want. This feature is about "can we build latest" so want it to ebb and flow with how the product evolves.
Can that capture the binary log too? |
You can add |
<NETSdkWarning ResourceName="CannotDirectlyReferenceMicrosoftNetCompilersToolsetFramework" | ||
Condition="'@(PackageReference->AnyHaveMetadataValue('Identity', 'Microsoft.Net.Compilers.Toolset.Framework'))' == 'true'" /> | ||
<PropertyGroup Condition="'$(BuildWithNetFrameworkHostedCompiler)' == 'true' and '$(OS)' == 'Windows_NT'"> | ||
<RoslynTargetsPath>$(NuGetPackageRoot)\microsoft.net.sdk.compilers.toolset\$(NETCoreSdkVersion)</RoslynTargetsPath> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for PackageDownload
, GeneratePathProperty
is automatically set to true. Any reason not to use the property NuGet generates for the package?
Also, what happens during the restore phase when the package hasn't been downloaded yet. Is it OK for restore if this points to a non-existent path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think for
PackageDownload
,GeneratePathProperty
is automatically set to true. Any reason not to use the property NuGet generates for the package?
I think the property is not available for PackageDownload: NuGet/Home#8476
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, what happens during the restore phase when the package hasn't been downloaded yet. Is it OK for restore if this points to a non-existent path?
I think yes, the compiler shouldn't be used during or before restore, right?
Also setting the path after restoring doesn't seem to have any effect, I guess the UsingTask is considered sooner and cannot be overwritten?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, what happens during the restore phase when the package hasn't been downloaded yet. Is it OK for restore if this points to a non-existent path?
Looks like you were right, that is a problem in Visual Studio: #42238
May I suggest using -getItem: or -getProperty? That would let you pull values out of the binlog if you needed them if there was something in an item or property you were looking for. |
There are two key items we are looking for:
Those are really easy to get out of the binlog if we have access to it. |
My point is that we don't have CLI libraries for automating binlog consumption. My recommendation is to do a build per Daniel above and check that it passed and then do a build with the getProperty or getItem flag to get the version of the compiler without having to process a binlog at all. |
I don't know what item or property to get to determine the used compiler assembly path. We could get the RoslynTargetsPath property but that doesn't guarantee it ends up being the DLL used. I think I can instead just assert the path is in the standard output which contains the full command line executed. |
Resolves #41791.