Skip to content

perf(module-pack): build inside the platform container, prebuilt siblings, per-digest tester cache - #2922

Merged
rbuergi merged 1 commit into
mainfrom
ci/build-inside-the-platform-container
Aug 31, 2026
Merged

rbuergi merged 1 commit into
mainfrom
ci/build-inside-the-platform-container

Conversation

@rbuergi

@rbuergi rbuergi commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

The container lane's wall-time, fixed at the three measured sinks (Plugins#1032 attempt 3, Mcp job: 681 s in the build step):

sink before after
image pulls portal + tester, every job portal only (the build runs INSIDE it); tester = per-digest actions-cache of extracted files
extraction docker cp 331 assemblies + shared frameworks, every job none — /app and the frameworks are the container's own
sibling rebuilds MeshWeaver.AI (168 sources, ~3 min) recompiled by every dependent --prebuilt: consumers take the floor's module-dll-* artifact (bounded wait, loud same-compiler fallback). Measured: Mcp 2.2 s vs ~3 min

New lane input prebuilt-modules (callers set it to their always-modules); each container job publishes its DLL artifact right after building, before its tests. Prebuilt references never ride the consumer's bundle and stay under the binding-identity check. 282/282 tester tests including the consumed-not-rebuilt pin.

Expected end state per job: ~30–60 s portal pull + seconds of compile — decisively under the SDK path's 10–18 min.

🤖 Generated with Claude Code

…ings ride prebuilt, the tester is a per-digest cache

Measured on Plugins#1032 attempt 3 (MeshWeaver.Mcp): 681 s in the build
step — two multi-GB pulls, docker cp of 331 assemblies plus the shared
frameworks, and a full re-compile of MeshWeaver.AI that the same run's
floor job had already built. Three changes, one doctrine (the image IS
the room):

- ONE container: the build executes inside the platform image itself —
  its /app is the reference set and its runtime is the shared-framework
  surface, so the extraction and the --app/--shared-frameworks flags
  disappear along with the tester-image pull.
- The BUILDER travels as files: the tester's /app (builder + generators
  + module-libs) extracted once per DIGEST into the actions cache and
  mounted read-only at /tester.
- --prebuilt: an in-root ProjectReference whose assembly a prebuilt
  directory supplies resolves to that DLL and is not rebuilt ("we don't
  need to rebuild the mesh", maintainer 2026-08-31). Each container job
  uploads module-dll-<name> right after its build; a consumer listed in
  the new prebuilt-modules input waits bounded for the artifact and
  falls back to source WITH A LOUD LINE — same compiler, same
  verification, only slower. Measured: MeshWeaver.Mcp 2.2 s end-to-end
  with a prebuilt MeshWeaver.AI, vs ~3 min rebuilding it.

Prebuilt assemblies never ride the consumer's bundle (they ship as their
own) and are covered by the platform binding-identity check like every
reference. 282/282 tests, incl. the consumed-not-rebuilt pin and the
missing-directory refusal.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI lite review requested due to automatic review settings August 31, 2026 20:36
@rbuergi
rbuergi enabled auto-merge August 31, 2026 20:36

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR optimizes the node-repo module-pack “container” lane by running mw-plugin-test build-project inside the pinned platform image, adding a --prebuilt seam to avoid rebuilding in-root sibling modules, and introducing a per-digest cache for the tester image’s extracted /app payload.

Changes:

  • Add --prebuilt support to mw-plugin-test build-project and wire prebuilt sibling DLLs into the project-graph compilation reference set.
  • Extend the CLI argv handling to accept repeated --prebuilt <dir> inputs.
  • Update node-repo-module-pack.yml to build inside the platform container, cache the tester /app by digest, and publish built module DLLs for other matrix entries to consume.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
tools/MeshWeaver.PluginTester/ProjectBuild.cs Implements prebuilt sibling discovery and adds prebuilt DLLs to Roslyn reference resolution.
tools/MeshWeaver.PluginTester/Program.cs Adds --prebuilt CLI parsing and usage text for build-project.
test/MeshWeaver.PluginTester.Test/PrebuiltSiblingTest.cs Adds regression coverage for consuming prebuilt siblings and refusing missing prebuilt directories.
.github/workflows/node-repo-module-pack.yml Switches container builds to run inside the platform image, adds tester-app cache restore, downloads sibling DLL artifacts, and uploads module DLL artifacts for reuse.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +503 to +510
var referenceAssembly = Path.GetFileNameWithoutExtension(reference);
if (prebuilt.TryGetValue(referenceAssembly, out var prebuiltDll))
{
prebuiltReferences[referenceAssembly] = prebuiltDll;
sink.Info(
$"{Path.GetFileNameWithoutExtension(current)}: ProjectReference {referenceAssembly} "
+ "→ PREBUILT (this run already built it; not rebuilding the mesh)");
continue;
Comment on lines +693 to 701
# The tester's extracted /app, cached by DIGEST — one extraction per digest per repo,
# every later job restores it in seconds instead of pulling the tester image at all.
- name: Restore the tester app (per-digest cache)
if: ${{ inputs.tester-image-digest != '' }}
uses: actions/cache@v4
with:
path: ${{ runner.temp }}/tester-app
key: tester-app-${{ inputs.tester-image-digest }}
- name: Build the module — and say which compiler produced it
@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 0)

793 tests  ±0   789 ✅ ±0   4m 26s ⏱️ -7s
  7 suites ±0     4 💤 ±0 
  7 files   ±0     0 ❌ ±0 

Results for commit d0d1593. ± Comparison against base commit 159a667.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 1)

1 135 tests  +2   1 135 ✅ +2   3m 48s ⏱️ +8s
    7 suites ±0       0 💤 ±0 
    7 files   ±0       0 ❌ ±0 

Results for commit d0d1593. ± Comparison against base commit 159a667.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 5)

    8 files  ±0      8 suites  ±0   4m 12s ⏱️ +10s
1 491 tests ±0  1 490 ✅ ±0  1 💤 ±0  0 ❌ ±0 
2 194 runs  ±0  2 193 ✅ ±0  1 💤 ±0  0 ❌ ±0 

Results for commit d0d1593. ± Comparison against base commit 159a667.

@github-actions

github-actions Bot commented Aug 31, 2026 •

Copy link
Copy Markdown
Contributor

Test Results (shard 4)

1 165 tests  ±0   1 165 ✅ ±0   4m 57s ⏱️ +21s
    7 suites ±0       0 💤 ±0 
    7 files   ±0       0 ❌ ±0 

Results for commit d0d1593. ± Comparison against base commit 159a667.

♻️ This comment has been updated with latest results.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 2)

3 059 tests  ±0   2 867 ✅ ±0   6m 35s ⏱️ -14s
    8 suites ±0     192 💤 ±0 
    8 files   ±0       0 ❌ ±0 

Results for commit d0d1593. ± Comparison against base commit 159a667.

@github-actions

Copy link
Copy Markdown
Contributor

Test Results (shard 3)

1 152 tests  ±0   1 152 ✅ ±0   7m 30s ⏱️ -13s
    7 suites ±0       0 💤 ±0 
    7 files   ±0       0 ❌ ±0 

Results for commit d0d1593. ± Comparison against base commit 159a667.

@github-actions

github-actions Bot commented Aug 31, 2026 •

Copy link
Copy Markdown
Contributor

Test Results

   44 files  ±0     44 suites  ±0   31m 30s ⏱️ +5s
8 795 tests +2  8 598 ✅ +2  197 💤 ±0  0 ❌ ±0 
9 498 runs  +2  9 301 ✅ +2  197 💤 ±0  0 ❌ ±0 

Results for commit d0d1593. ± Comparison against base commit 159a667.

♻️ This comment has been updated with latest results.

@rbuergi
rbuergi added this pull request to the merge queue Aug 31, 2026
Merged via the queue into main with commit 98195f9 Aug 31, 2026
39 of 41 checks passed
rbuergi added a commit that referenced this pull request Sep 1, 2026
…e closure — no module waits for an artifact it does not reference

The first run that ever ACTIVATED prebuilt-modules (Plugins 33451338438) measured the #2922
wait indiscriminate: every container job — consumers and non-consumers alike — sat the bounded
wait for every wanted module, and with the producers' uploads broken by the path: split that
was a uniform ~680s of pure idling per job, poisoning the whole benchmark. The wait now runs
only for modules in THIS entry's transitive ProjectReference closure (computed by a 12-line
stdlib walk over csproj ProjectReferences — verified: Northwind's closure carries
MeshWeaver.Import; OgCard's carries neither AI nor Import and skips every wait). The rendered
bash and the embedded heredoc were proven by extraction + execution, not by eyeballing YAML
dedent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@rbuergi
rbuergi deleted the ci/build-inside-the-platform-container branch October 24, 2026 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants