build: intermittent CS0006 on the ubuntu CI leg (App.Shared ref assembly), root cause unproven
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 5/5
- Tempo stimato
- Più di una settimana
- Idoneità per principianti
- 25/100
- Tipo di issue
- Bug
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Attiva
- Stack tecnologico
- android, csharp
- Ambito
- build-system, ci-cd
Direzione di ricerca
Start with the Ubuntu Build step in the CI workflow and the Android multi-RID build settings; the issue identifies _AndroidBuildRuntimeIdentifiersInParallel as an untested candidate. First capture a failing binlog using repeated builds with fresh obj/ and bin/ directories, uploading the log on failure. Done means the intermittent CS0006 root cause is established and a fix is supported by evidence; the issue notes that no failing binlog has yet been captured.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Summary
The ubuntu-latest CI leg intermittently fails its Build step with:
CSC : error CS0006: Metadata file
'/home/runner/work/lagebuch/lagebuch/src/LageBuch.App.Shared/obj/Release/net10.0/ref/LageBuch.App.Shared.dll'
could not be found [/home/runner/work/lagebuch/lagebuch/src/LageBuch.App/LageBuch.App.csproj]
Seen once in ~25 runs surveyed (≈4%, single observation so the real rate could be ~1–10%): run 34987088319, attempt 1, the ubuntu leg of #327. A plain re-run cleared it with no code change.
Surfaced while fixing #326. Deliberately not fixed — see "Impact" for why this is filed rather than patched.
Impact (why this is low priority)
| context | builds App + App.Android in one MSBuild invocation? |
exposed |
|---|---|---|
ubuntu CI leg (dotnet build LageBuch.sln) |
yes | only here |
| windows CI leg | no (Desktop.slnf excludes the Android head) |
no |
release.yml windows/linux/macos jobs |
no (dotnet publish src/LageBuch.App/…, own runner) |
no |
release.yml android job |
no (dotnet publish src/LageBuch.App.Android/…, own runner) |
no |
make build / make ci |
no (desktop projects only) | no |
make build-all / make test-all |
yes | yes (needs JDK ≤ 21) |
Releases are structurally safe: each platform publishes a single project in its own job on its own runner, so LageBuch.App's csc and the Android inner build never run in the same invocation.
The failure is fail-stop, not corruption — the build dies, Test is skipped, no artifact is produced. It cannot ship a bad binary. The real cost is signal erosion: an intermittent red that is always "just re-run it" trains people to re-run reds without reading them.
Evidence gathered
Two MSBuild binlogs captured by temporarily adding -bl: plus a pinned actions/upload-artifact to the ubuntu leg, then replayed headlessly:
dotnet msbuild build.binlog -noconlog -flp:"logfile=diag.txt;verbosity=diagnostic"
- baseline (
main@ 9a0de65, no fix): run 35018637663 - attempted fix (
Directory.Build.targets): run 35017414253
❌ Hypothesis DISPROVEN — do not redo this
"
Microsoft.Android.Sdk.AssemblyResolution.targets→_ResolveAssembliesre-invokes the Android head per RID with extra global properties; those flow downProjectReferenceedges, givingLageBuch.App.Sharedtwo MSBuild configurations writing the sameobj/."
The SDK part is real — _ResolveAssemblies does inject _ComputeFilesToPublishForRuntimeIdentifiers, SkipCompilerExecution, _OuterOutputPath etc., once per RID (android-arm64;android-x64). But the conclusion does not follow. Both binlogs show exactly one configuration id per project:
baseline: App.Shared=11 AppLogic=6 Domain=9 Persistence=2 Sync=8
fixed: App.Shared=10 AppLogic=7 Domain=9 Persistence=2 Sync=11
RuntimeIdentifier/SelfContained are stripped for RID-agnostic references and TargetFramework for single-TFM ones (Microsoft.Common.CurrentVersion.targets, _GetProjectReferenceTargetFrameworkProperties), so there is no second configuration to race. Leaked global properties are not the differentiator.
✅ What the evidence does support
The two RID inner builds each request the same configuration's default targets, and the scheduler can place them on different nodes — identically with and without the attempted fix:
| project | baseline | attempted fix |
|---|---|---|
App.Shared |
cfg 11:22 node 4, 11:24 node 4 | cfg 10:22 node 4, 10:24 node 1 |
AppLogic |
cfg 6:42 node 3, 6:45 node 3 | cfg 7:42 node 3, 7:44 node 1 |
Domain |
cfg 9:89 node 4, 9:94 node 1 | cfg 9:82 node 2, 9:91 node 1 |
Persistence |
cfg 2:56 / 2:58 node 3 | cfg 2:52 node 4, 2:54 node 1 |
Sync |
cfg 8:56 / 8:58 node 4 | cfg 11:53 / 11:54 node 2 |
So the hazard is two concurrent builds of one configuration against one obj/ directory, not two configurations. Consistent with the error being CS0006 ("could not be found", i.e. a genuine unlink) rather than CS0009 — the only Delete in range is IncrementalClean, which reads and rewrites the shared …csproj.FileListAbsolute.txt. Not confirmed: no failing binlog was captured, only passing ones.
Unexplained residue
The attempted fix measurably halved the duplicated work for the two direct references — App.Shared went from two CopyFilesToOutputDirectory executions (TaskId 396, 792) to one (TaskId 397), AppLogic likewise — while Domain/Persistence/Sync still run twice. Why undefining properties changed anything, given the configuration was already single, is not explained. That is why it was not merged: "it helped and I don't know why" is not a rationale for a build-system change.
Next candidate (untested)
_AndroidBuildRuntimeIdentifiersInParallel=false — serialises the two RID inner builds so their reference-graph requests cannot overlap. An earlier analysis dismissed this on the reasoning that both inner builds collapse onto the same configuration and so serialising removes no contention; given the above, that reasoning looks exactly backwards — the contention is between those two.
Other options, with the caveat that several are symptom-level: build the Android head in its own sequential CI step; -m:1 on the ubuntu build (slow); ProduceReferenceAssembly=false (likely relocates CS0006 to CS0009 — not recommended).
To capture a failing binlog
Frequency is low, so loop the build inside one step with a fresh obj/+bin/ per iteration and upload on failure only. 15 iterations ≈ 46% chance of catching it, 30 ≈ 70%.
Revisit if
- the rate climbs past roughly 1 in 10
- a second project starts referencing the Android head
- the ubuntu leg ever becomes release-blocking
The attempted fix is preserved in #330 (closed, with a correction comment).
- Lingua principale
- C#
- Stelle
- 1
- Fork
- 3
- Merge medio
- 4h 34m
- PR unite (30g)
- 182
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di CodeForFire/lagebuch
-
bug ux
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
CodeForFire/lagebuch#714 ·
I maintainer di solito rispondono entro 1 giorno
-
bug ux
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
CodeForFire/lagebuch#713 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
CodeForFire/lagebuch#405 ·
I maintainer di solito rispondono entro 1 giorno
-
documentation good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
CodeForFire/lagebuch#349 ·
I maintainer di solito rispondono entro 1 giorno
-
documentation good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 88/100
CodeForFire/lagebuch#348 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di CodeForFire/lagebuch
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
KnifeLemon/Filee#363 ·
I maintainer di solito rispondono entro 1 giorno
-
enhancement
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
-
area-Native untriaged
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
dotnet/machinelearning#7837 ·
I maintainer di solito rispondono entro 2 giorni
-
[CI] .trgen-ignore required for several grammars.Forse già presa @kaby76 l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
antlr/grammars-v4#5073 ·
I maintainer di solito rispondono entro 1 giorno
-
[Enhancement]: Add a search box to the Time Zone dropdownForse già presa @idumlupinar l’ha presa oggi. ApertaStatus: New
Difficoltà 2/5 1-3 ore Idoneità per principianti 85/100
dnnsoftware/Dnn.Platform#7579 ·
I maintainer di solito rispondono entro 2 giorni