Race condition when publishing multiple projects can cause missed references
- Dominant language
- C#
- Stars
- 5.5k
- Forks
- 1.5k
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 141
Description
This was reported via a Microsoft discussion group; this is a simplified repro.
The solution in [publish_bad_ordering.zip](https://github.com/dotnet/msbuild/files/9728840/publish_bad_ordering.zip), when built and published with
```sh
dotnet build
dotnet publish --no-build -bl -flp:v=diag -m:1
```
(`7.0.100-rc.1.22431.12`), will produce an incorrect `App3.deps.json` compared to publishing only `App3.csproj`:
```diff
diff --git "a/.\\IndividualPublish-App3.deps.json" "b/.\\SolutionPublish-App3.deps.json"
index 4b28e94..7dd6f87 100644
--- "a/.\\IndividualPublish-App3.deps.json"
+++ "b/.\\SolutionPublish-App3.deps.json"
@@ -20,12 +20,7 @@
"StyleCop.Analyzers.Unstable": "1.2.0.435"
}
},
- "StyleCop.Analyzers.Unstable/1.2.0.435": {},
- "App1/1.0.0": {
- "runtime": {
- "App1.dll": {}
- }
- }
+ "StyleCop.Analyzers.Unstable/1.2.0.435": {}
}
},
"libraries": {
@@ -47,11 +42,6 @@
"sha512": "sha512-ouwPWZxbOV3SmCZxIRqHvljkSzkCyi1tDoMzQtDb/bRP8ctASV/iRJr+A2Gdj0QLaLmWnqTWDrH82/iP+X80Lg==",
"path": "stylecop.analyzers.unstable/1.2.0.435",
"hashPath": "stylecop.analyzers.unstable.1.2.0.435.nupkg.sha512"
- },
- "App1/1.0.0": {
- "type": "project",
- "serviceable": false,
- "sha512": ""
}
}
}
\ No newline at end of file
```
This happens because the reference from App2→App3 causes parts of `ProjectReference` resolution to execute in a bad order:
```sh-session
❯ rg 'Done building target .(_SplitProjectReferencesByFileExistence|BuildOnlySettings|AssignProjectConfiguration|ResolveProjectReferences). in project .App3\.csproj' .\msbuild.log
48393:Done building target "_SplitProjectReferencesByFileExistence" in project "App3.csproj".: (TargetId:147)
51394:Done building target "BuildOnlySettings" in project "App3.csproj".: (TargetId:168)
51501:Done building target "AssignProjectConfiguration" in project "App3.csproj".: (TargetId:176)
51519:Done building target "ResolveProjectReferences" in project "App3.csproj".: (TargetId:178)
```
`_SplitProjectReferencesByFileExistence` depends on `@(ProjectReferenceWithConfiguration)`
https://github.com/dotnet/msbuild/blob/20ce296d6b3f4e63a511321c7e1a2f69a4ee63ef/src/Tasks/Microsoft.Common.CurrentVersion.targets#L1606-L1612
which is populated in `AssignProjectConfiguration`
https://github.com/dotnet/msbuild/blob/20ce296d6b3f4e63a511321c7e1a2f69a4ee63ef/src/Tasks/Microsoft.Common.CurrentVersion.targets#L1564-L1567
So if `_SplitProjectReferencesByFileExistence` runs first, the later `ResolveProjectReferences` will do nothing.
Missing project references at `publish --no-build` time can be somewhat benign, but in this case the project falls into a `$(_UseBuildDependencyFile) != true` case, because `@(_ExcludeFromPublishPackageReference)` is nonempty, because of the `ExcludeAssets="all"` on a `PackageReference` to `StyleCop.Analyzers`. That causes `App3.deps.json` to be recomputed with bad project-reference information, causing the absence of `App1`.
In the build that initially caused this report, this happened intermittently due to sometimes scheduling App3's publish before App2's reference to it, but the repro described above is deterministic because of limiting to a single build node with `-m:1`.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.