Skip to content

The UpdateXlfOnBuild on build property is making resource DLL builds non-reproducable #15296

@jaredpar

Description

@jaredpar

When running the C# determinism suite on my machine it was failing saying that our resource DLLs were not reproducable. The difference came down to the manifest resource names in the resource assembly.

  • Building Locally: Microsoft.CodeAnalysis.C_.Users.jaredpar.code.roslyn.src.Dependencies.Collections.Internal.Strings.cs.resources
  • Building in CI: ManifestResourceName = Microsoft.CodeAnalysis.Internal.Strings.cs

Notice that when building locally it is including file paths from my local machine. That is true even though this build occurs with -p:DeterministicSourcePaths. Even with that though, it's strange that a resource name includes a file path.

The manifest resource name is generated by the CreateManifestResourceName target. It will use EmbeddedResources->Link as the basis for the name if it's set, otherwise it will fall back to looking at the file path. In CI it's using Link but locally it's using the file path.

In a typical build the Link metadata is set inside AssignLinkMetadata. Later on there GatherXlfSources maps @(EmbeddedResources) to @(XlfSource) and TranslateSourceFromXlf maps @(XlfSource) back to @(EmbeddedResources). Then CreateManifestResourceName reads this final value of @(EmbeddedResources). This is how it works in CI.

In a build where UpdateXlfOnBuild is set to true though this does not happen. The outer build will run a MSBuild task on the individual TFMS with a target of UpdateXlf. This causes GatherXlfSources to be executed. That inner build finishes, the normal build proceeds and leads to another inner build on the project. That re-uses the evaluation from the UpdateXlf build, it has already run GatherXlfSources hence the cached data is used on the second build. Effectively it causes GatherXlfSources to be evaluated out of order, the Link metadata is not set and manifest resource names end up having file paths in them.

This is problematic because arcade defaults to UpdateXlfOnBuild being true for local builds. Basically local builds are not reflective of our final product.

To fix this I think that either:

  1. We should change the MSBuild with the UpdateXlf target to have a new global property. That way it will not share an evaluation with the later build
  2. Change the model here to have a check mode where it issues a diagnostic when XLF files are out of date. That can be the new arcade default. This could run safely as a part of the normal build and users could then explicitly invoke dotnet build -t:UpdateXlf to resolve.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions