|
|
|
@@ -0,0 +1,68 @@
|
|
|
|
|
<Project>
|
|
|
|
|
|
|
|
|
|
<!--
|
|
|
|
|
◆ THE TRIMMER'S VERSION IS PINNED HERE BECAUSE OTHERWISE THE LOCK FILES ARE NOT LOCKED.
|
|
|
|
|
|
|
|
|
|
Microsoft.NET.ILLink.Tasks is not referenced by anything in this repository. The SDK adds it
|
|
|
|
|
on its own to any project that sets IsTrimmable or IsAotCompatible — DodoSSH.Contracts and
|
|
|
|
|
DodoSSH.Crypto do, and the Android head gets it from trimming being on by default there — and
|
|
|
|
|
the version it asks for is whatever the running SDK happens to bundle. That version lives in
|
|
|
|
|
the SDK's own Microsoft.NETCoreSdk.BundledVersions.props, as a KnownILLinkPack item.
|
|
|
|
|
|
|
|
|
|
Which makes it a dependency whose version is a property of the toolchain rather than of this
|
|
|
|
|
repository, and that is the whole problem: packages.lock.json records it as a Direct reference
|
|
|
|
|
with a requested range, so the lock file silently means "whichever SDK last ran a restore".
|
|
|
|
|
global.json says rollForward: latestMinor, so CI's setup-dotnet installs the newest 10.x SDK
|
|
|
|
|
that exists on the day it runs. The moment .NET ships a servicing release, CI's SDK asks for a
|
|
|
|
|
version the committed lock files do not have, and the locked-mode restore in ci.yml fails with
|
|
|
|
|
NU1004 before a single file is compiled.
|
|
|
|
|
|
|
|
|
|
That is not hypothetical. It closed the whole pipeline: main's run 125 and every open pull
|
|
|
|
|
request went red together, on
|
|
|
|
|
|
|
|
|
|
error NU1004: The package reference Microsoft.NET.ILLink.Tasks version has changed
|
|
|
|
|
from [10.0.10, ) to [10.0.11, ).
|
|
|
|
|
|
|
|
|
|
with nothing in any of those commits touching a package. .NET had shipped SDK 10.0.400, which
|
|
|
|
|
bundles ILLink 10.0.11 where 10.0.302 bundled 10.0.10, and setup-dotnet installed it the next
|
|
|
|
|
time anything ran.
|
|
|
|
|
|
|
|
|
|
Worse than the outage is the shape of the repair without this pin. Regenerating the lock files
|
|
|
|
|
holds only until the next servicing release, and it cannot be done from a machine whose newest
|
|
|
|
|
SDK is older than the runner's: a restore on 10.0.302 writes 10.0.10 straight back and re-breaks
|
|
|
|
|
CI, so the recorded version becomes a fact about whoever ran restore last rather than about this
|
|
|
|
|
repository. That is exactly the state locking exists to prevent, and it is not a hypothetical
|
|
|
|
|
either — every SDK installed on the machine this pin was written on tops out at 10.0.302.
|
|
|
|
|
|
|
|
|
|
Pinning it makes the recorded version a decision this repository made, reviewable in a diff
|
|
|
|
|
like every other version in Directory.Packages.props, and identical on every machine whatever
|
|
|
|
|
SDK it has. Moving it is then a deliberate edit here plus a regenerated lock file, which is the
|
|
|
|
|
same ceremony any other dependency bump gets.
|
|
|
|
|
|
|
|
|
|
It is an Update on the SDK's item rather than a PackageVersion in Directory.Packages.props, and
|
|
|
|
|
it has to be: the reference is implicit, so the SDK supplies the version itself and central
|
|
|
|
|
package management never gets asked. ProcessFrameworkReferences reads @(KnownILLinkPack) when
|
|
|
|
|
it runs, which is why this lives in Directory.Build.targets — the item does not exist yet while
|
|
|
|
|
Directory.Build.props is being evaluated.
|
|
|
|
|
|
|
|
|
|
Keep this within a patch or two of the runtime the SDK ships. It is the trimming analyzer and
|
|
|
|
|
the ILLink task, so a small skew is harmless, but a version far behind the framework being
|
|
|
|
|
analysed is a real way to miss a trim warning.
|
|
|
|
|
-->
|
|
|
|
|
<Target Name="PinTheILLinkPackVersion" BeforeTargets="ProcessFrameworkReferences">
|
|
|
|
|
<!--
|
|
|
|
|
Inside a target, and not for tidiness. The SDK ships one KnownILLinkPack per target framework
|
|
|
|
|
and they all share the identity "Microsoft.NET.ILLink.Tasks", so the TargetFramework metadata
|
|
|
|
|
is the only thing telling net10.0's entry from net8.0's. A condition on %(...) is item
|
|
|
|
|
batching, which MSBuild permits in a target and rejects during evaluation with MSB4191 — so
|
|
|
|
|
an ItemGroup at the top of this file cannot express "only the net10.0 one" at all, and the
|
|
|
|
|
unconditioned Update it would have to become rewrites every framework's entry.
|
|
|
|
|
-->
|
|
|
|
|
<ItemGroup>
|
|
|
|
|
<KnownILLinkPack Update="Microsoft.NET.ILLink.Tasks"
|
|
|
|
|
Condition="'%(TargetFramework)' == 'net10.0'"
|
|
|
|
|
ILLinkPackVersion="10.0.11" />
|
|
|
|
|
</ItemGroup>
|
|
|
|
|
</Target>
|
|
|
|
|
|
|
|
|
|
</Project>
|