Repository navigation
fix(build): stable AssemblyVersion — cures the migration binding crash (#143) - #144
Conversation
#143) Space creation was failing on prod ("sync_behavior column missing", #143) because the memex-migration container CrashLoopBackOff'd on startup: Current DB version: 39 System.IO.FileNotFoundException: Could not load file or assembly 'MeshWeaver.Documentation, Version=3.0.0.280' — the system cannot find the file. Root cause: AssemblyVersion was `$(_VersionNumeric).$(_BuildNumber)` where `_BuildNumber` is seconds-since-midnight/2, evaluated PER PROJECT at MSBuild time. AssemblyVersion is the runtime assembly-BINDING identity, so it must be identical across every assembly in a coherent build — but a time-based value drifts a few seconds between projects built in the same CI run. Memex.Database.Migration was compiled against MeshWeaver.Documentation v3.0.0.280 while the packaged DLL carried a different 3.0.0.<other> → binding fails → the migration crashes before it can apply the v40 (sync_behavior) migration → schema stuck at v39 → #143. Fix: AssemblyVersion is now STABLE (`$(_VersionNumeric).0` = 3.0.0.0). FileVersion keeps the per-build number (that + build timestamps drive MSBuild's CopyToOutputDirectory heuristic; it does not participate in assembly binding). Nothing depends on a time-based AssemblyVersion: the self-updater keys on the image tag (ci.N) and NodeType ABI identity uses the Graph MVID. Note this only ever bit CI: LOCAL builds already set `_BuildNumber=0`, so AssemblyVersion was already 3.0.0.0 locally — the fix simply makes CI match the already-correct local behavior. Validated: `dotnet build Memex.Database.Migration -c Release -p:CIRun=true` succeeds and the generated AssemblyInfo for both the migration and MeshWeaver.Documentation now reads AssemblyVersion("3.0.0.0"). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR fixes a production migration startup crash caused by inconsistent AssemblyVersion values across projects within the same CI build, which broke runtime assembly binding and prevented database migrations from applying (leaving the schema stuck before the sync_behavior column migration).
Changes:
- Makes
AssemblyVersionstable across all assemblies ($(_VersionNumeric).0) to ensure consistent runtime binding identity. - Keeps per-build variability in
FileVersion(and CI-only uniqueness inInformationalVersion) so build outputs still change between CI runs without affecting binding.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Test Results (shard 1) 12 files ± 0 12 suites ±0 6m 15s ⏱️ +40s Results for commit 88306e0. ± Comparison against base commit 6943991. This pull request removes 12 and adds 31 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
Test Results 50 files + 1 50 suites +1 25m 7s ⏱️ + 6m 29s Results for commit 88306e0. ± Comparison against base commit 6943991. This pull request removes 12 and adds 688 tests. Note that renamed tests count towards both.♻️ This comment has been updated with latest results. |
Fixes #143.
Symptom
Space creation fails on prod: "database schema issue on the backend (sync_behavior column missing)". The
memex-migrationcontainer CrashLoopBackOffs on startup:So the schema never advances past v39, the
sync_behaviormigration (PR #119) never applies, and Space creation fails. (The portals on the sameci.122build run fine — only the migration image hit it.)Root cause
Directory.Build.propssetAssemblyVersion = $(_VersionNumeric).$(_BuildNumber), where_BuildNumberis seconds-since-midnight ÷ 2, evaluated per project at MSBuild time.AssemblyVersionis the runtime assembly-binding identity — it must be identical across every assembly in a coherent build. A time-based value drifts a few seconds between projects built in the same CI run, soMemex.Database.Migrationwas compiled againstMeshWeaver.Documentationv3.0.0.280 while the packaged DLL carried a different3.0.0.<other>→ binding fails → crash before applying v40.Fix
AssemblyVersion→ stable$(_VersionNumeric).0(3.0.0.0).FileVersionkeeps the per-build number (drives MSBuild's copy heuristic; does not participate in binding).Safe against everything documented in that file: the self-updater keys on the image tag (
ci.N), NodeType ABI identity uses the Graph MVID — neither usesAssemblyVersion. And it only ever bit CI: local builds already set_BuildNumber=0, soAssemblyVersionwas already3.0.0.0locally — this makes CI match the already-correct local behavior.Validation
dotnet build memex/aspire/Memex.Database.Migration -c Release -p:CIRun=truesucceeds, and the generated AssemblyInfo for both the migration andMeshWeaver.Documentationnow readsAssemblyVersion("3.0.0.0")(previously they drifted). After merge → CD rebuilds → the migration runs → v40 (sync_behavior) applies → Space creation works.🤖 Generated with Claude Code