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

Restore PackageReferences in temporary assembly projects to import build extensions #1056

Closed
wants to merge 2 commits into from

Conversation

ryalanms
Copy link
Member

The temporary project is not getting props and targets files (build extension files) from PackageReferences defined in their parent project. This is causing failures in referenced packages that rely on build extensions (e.g., Google Protocol Buffers) to perform pre-compile tasks, such as code generation.

Several options were considered, including consuming the generated props and targets that include the PackageReferences props/targets from the outer parent project, as the parent project Restore has already run and includes identical PackageReferences. However, we opted to run Restore directly on the temporary project instead, which allowed a fix without changes to external build files (other than a minor change to the Arcade SDK). There are now two Restore operations: one for the parent project and one for the temporary project. Note that Restore will not re-download packages but will generate the assets file, targets file, and props file. These files include imports for build extensions in the PackageReferences.

These tasks could easily be condensed in to a single parameterized task, but breaking the steps in to three made a logs easier to read and improved debugging. There are now three tasks:

  1. CreateTemporaryTargetAssemblyProject
  2. RestoreTemporaryTargetAssemblyProject (which calls RunProjectBuildTarget with Restore)
  3. GenerateTemporaryTargetAssembly

The first task creates a temporary project with random component in the name from the outer parent project. RestoreTemporaryTargetAssemblyProject consumes the temporary project and runs Restore, generating assets, .props, and .targets files that include imports to any build extensions inside PackageReferences. These files are then consumed in GenerateTemporaryTargetAssembly as part of the
normal build process for the temporary project.

Note that there is an Arcade SDK targets file change that needs to be coordinated with this change. Workaround.props needs to be modified to remove a temporary workaround for the lack of PackageReference support to prevent duplicate import errors. dotnet/arcade#3127

(APICompat was re-baselined to account for the public API surface changes in PresentationBuildTasks.)

@ghost ghost requested review from vatsan-madhavan, rladuca and stevenbrix June 21, 2019 21:29
@ghost ghost added the PR metadata: Label to tag PRs, to facilitate with triage label Jun 21, 2019
@walterlv
Copy link
Contributor

@ryalanms Thanks for fixing this issue.
I have some NuGet packages which extend the building so should I have to check target building SDK version to determine whether should I hack to fix or use your fix?

Copy link
Contributor

@walterlv walterlv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is some debug-only code in the three related building tasks.

I use this method to debug my custom building tasks, too. But I think it shouldn't be merged into the release-version code.

@ryalanms
Copy link
Member Author

Thanks for reviewing, @walterlv. After this fix is in, there shouldn't be any need to use custom code to get the build extensions in PackageReferences to work in user code.

@ryalanms ryalanms force-pushed the dev/ryalanms/pbt_packageref_proto branch from 69adf43 to 1e974a0 Compare June 22, 2019 02:14
@ryalanms
Copy link
Member Author

Note that this will fail to build with duplicate imports until the Arcade SDK change is merged and picked up.

Copy link
Member

@rladuca rladuca left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks good, I like 3 tasks better than pivoting on params.

@rladuca
Copy link
Member

rladuca commented Jun 24, 2019

Note that this will fail to build with duplicate imports until the Arcade SDK change is merged and picked up.

Arcade just merged the change.

@@ -1,3 +1,13 @@
Compat issues with assembly PresentationBuildTasks:
MembersMustExist : Member 'Microsoft.Build.Tasks.Windows.GenerateTemporaryTargetAssembly.CompileTypeName.get()' does not exist in the implementation but it does exist in the contract.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a larger unrelated questions we should try to address - namely whether ref-assembly for PresentationBuildTasks needs to be rolled into the ref-pack for .NET Core 3.0.

@nguerrera?

@@ -20,6 +20,8 @@
<UsingTask TaskName="Microsoft.Build.Tasks.Windows.FileClassifier" AssemblyFile="$(_PresentationBuildTasksAssembly)" />
<UsingTask TaskName="Microsoft.Build.Tasks.Windows.MarkupCompilePass2" AssemblyFile="$(_PresentationBuildTasksAssembly)" />
<UsingTask TaskName="Microsoft.Build.Tasks.Windows.GenerateTemporaryTargetAssembly" AssemblyFile="$(_PresentationBuildTasksAssembly)" />
<UsingTask TaskName="Microsoft.Build.Tasks.Windows.CreateTemporaryTargetAssemblyProject" AssemblyFile="$(_PresentationBuildTasksAssembly)" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason you chose CreateTemporaryTargetAssemblyProject, instead of calling the task GenerateTemporaryTargetAssemblyProject and keep naming in line with previous task names?

@@ -380,6 +382,8 @@
<PropertyGroup>

<MarkupCompilePass2ForMainAssemblyDependsOn>
CreateTemporaryTargetAssemblyProject;
RestoreTemporaryTargetAssemblyProject;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend renaming this target as "RunRestoreTargetOnTemporaryTargetAssemblyProject"


<RunProjectBuildTarget
ProjectName="$(_TemporaryTargetAssemblyProjectName)"
BuildTarget="Restore"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use a pattern similar to that in <Target Name="_CompileTemporaryAssembly" DependsOnTargets="BuildOnlySettings;ResolveKeySource;CoreCompile" /> and <_CompileTargetNameForLocalType Condition="'$(_CompileTargetNameForLocalType)' == ''">_CompileTemporaryAssembly</_CompileTargetNameForLocalType> used in GenerateTemporaryTargetAssembly

using MS.Utility;
using MS.Internal.Tasks;

// Since we disable PreSharp warnings in this file, PreSharp warning is unknown to C# compiler.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need this and related suppressions - we don't really use PreSharp any more

//
if (nodeGroup.HasChildNodes)
{
ArrayList itemToRemove = new ArrayList();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use ArrayList - instead use List<object>

//
// Continue the loop for the next ItemGroup.
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

excess blank line

}

} // end of "for i" statement.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

excess blank line

/// </summary>
public sealed class RunProjectBuildTarget : Task
{
#region Constructors
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use regions in new code

using MS.Utility;
using MS.Internal.Tasks;

// Since we disable PreSharp warnings in this file, PreSharp warning is unknown to C# compiler.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use PreSharp - remove comment and related warning suppressions

@vatsan-madhavan
Copy link
Member

The approach and the fix looks good to me overall. Given the overall level of churn, I'm hesitant to merge this so close to Preview 7 (check-ins close at noon tomorrow for WPF).

I don't see clear reasons why this change should cause regressions. The approach is sound and I think the change looks good to me overall. That said, the general complexity of the fix makes me think that it is likely to bring with it a slightly higher possibility of bugs. I'd rather fork off master to preview/3.0 (which happens on in two days on 6/26), and and then merge this into master for Preview 8 (so we would get early feedback on P8 builds).

I've spoken with @ryalanms and he agrees that waiting for 2 days is reasonable.

Marking as NO MERGE for now.

@vatsan-madhavan vatsan-madhavan added * NO MERGE * metadata: The PR is not ready for merge yet (see discussion for detailed reasons) and removed * NO MERGE * metadata: The PR is not ready for merge yet (see discussion for detailed reasons) labels Jun 24, 2019
@vatsan-madhavan
Copy link
Member

Removing NO MERGE since #1100 is completed.

@nguerrera
Copy link

Are you initiating a restore during the build? That is not allowed. It breaks the promise of build --no-restore, and will also mess with VS that handles restore differently than restore target.

@nguerrera
Copy link

cc @davkean

@nguerrera
Copy link

Note that Restore will not re-download packages but will generate the assets file, targets file, and props file.

This seems risky. If there's any evaluation change in generated project that ends up changing a PackageReference it could still hit the network.

@ryalanms
Copy link
Member Author

ryalanms commented Jan 5, 2021

Closing this, since we ended up taking a different implementation. Thanks.

@ryalanms ryalanms closed this Jan 5, 2021
@mmitche mmitche deleted the dev/ryalanms/pbt_packageref_proto branch January 13, 2021 14:46
@ghost ghost locked as resolved and limited conversation to collaborators Apr 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
* NO MERGE * metadata: The PR is not ready for merge yet (see discussion for detailed reasons) PR metadata: Label to tag PRs, to facilitate with triage
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants