Skip to content

Pin the bundled .NET runtime so it is a deliberate choice - #2092

Draft
NickJosevski wants to merge 1 commit into
mainfrom
nj/pin-runtime
Draft

Pin the bundled .NET runtime so it is a deliberate choice#2092
NickJosevski wants to merge 1 commit into
mainfrom
nj/pin-runtime

Conversation

@NickJosevski

@NickJosevski NickJosevski commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

Background

Calamari publishes self-contained. Every artifact carries its own copy of the .NET runtime. Customer vulnerability scanners report against that bundled runtime.

Nothing in the repo chose the runtime version. The version came from whichever runtime pack the build agent's SDK happened to ship. Two builds of the same commit on differently patched agents would ship different runtimes.

Results

The bundled runtime version is now a single constant in build/BundledRuntime.cs. The constant applies at both self-contained publish sites and at restore.

Restore needs the property too. Publish runs with --no-restore. Without the pinned pack downloaded during restore, publish fails with NETSDK1112 on any agent that has not cached the pack. --no-restore is kept. A comment there records that it prevents project.assets.json contention across parallel per-RID publishes.

Reducing risk

  • Verified on a cold cache in both directions. The NETSDK1112 failure was reproduced before the fix was confirmed.
  • Verified the pin overrides the SDK default. SDK 8.0.421 defaults to runtime 8.0.27. Published output carries 8.0.29.
  • 82 extraction tests pass on a machine whose newest installed runtime is 8.0.27.

How to review this PR

The constant needs bumping whenever .NET ships a security patch. A stale value silently ships a vulnerable runtime. Worth a Renovate rule after Renovate is re-enabled.

⚠️ Does this change require a corresponding Server Change?
⚠️ If so - please add a "Requires Server Change" label to this PR!

Calamari publishes self-contained. Every artifact carries its own copy of the .NET
runtime. Customer vulnerability scanners report against that bundled runtime.

Nothing in the repo chose the runtime version. The version came from whichever
runtime pack the build agent's SDK happened to ship. Two builds of the same commit
on differently patched agents would ship different runtimes.

build/BundledRuntime.cs holds a single constant. The constant applies at both
self-contained publish sites and at restore.

Restore needs the property too. Publish runs with --no-restore. Without the pinned
pack downloaded during restore, publish fails with NETSDK1112 on any agent that has
not cached the pack. --no-restore is kept. A comment there records that it prevents
project.assets.json contention across parallel per-RID publishes.

Verified on a cold cache in both directions. The NETSDK1112 failure was reproduced
before the fix was confirmed. On SDK 8.0.421, whose default pack is 8.0.27, the
published output carries 8.0.29. 82 extraction tests pass on a machine whose newest
installed runtime is 8.0.27.

The constant needs bumping whenever .NET ships a security patch. A stale value
silently ships a vulnerable runtime. .NET 8 reaches end of support on 10 November
2026, after which this must move to a supported major.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

1 participant