Summary
The pack job in .github/workflows/igniteui-blazor-lite-release.yml (branch btraykov/release-workflow-refactoring) runs on its own runner and packs with --no-build --no-restore, so no dotnet restore ever runs there. Whether that succeeds depends on an MSBuild cache file that happens to travel inside the artifact, not on anything the workflow controls. When that cache is rejected, the job fails with NETSDK1064. Infragistics.QueryBuilder.Executor, whose release workflow was modelled on this one and has the same shape, hit exactly this in production on 2026-09-01.
Where it is in this repo
The pack job declares needs: sign-assemblies and its own runs-on: windows-latest, then checks out, sets up .NET, downloads the signed-assemblies artifact into src, and runs:
dotnet pack ./src/IgniteUI.Blazor.Lite.csproj
--configuration ${{ env.BUILD_CONFIGURATION }}
--no-build
--no-restore
-p:PackageVersion=${{ env.VERSION }}
-p:RepositoryUrl=${{ env.REPOSITORY_URL }}
-p:RepositoryType=git
-p:RepositoryCommit=${{ github.sha }}
-o "${{ github.workspace }}/artifacts"
The packages restored by the build job live in that runner's global NuGet cache, which is not part of the artifact and does not exist on the pack runner.
Why this usually works anyway
The artifact carries src/bin/** and src/obj/**, and src/obj/<Configuration>/<tfm>/<project>.assets.cache travels with it. When MSBuild's ResolvePackageAssets accepts that cache, it reuses the previously resolved package assets and never looks for the packages on disk, so the missing package cache goes unnoticed. When it rejects the cache, it re-resolves from src/obj/project.assets.json, probes the package folders recorded there (C:\Users\runneradmin\.nuget\packages\), finds nothing, and fails.
So --no-restore on a separate runner is not safe by design — it is safe only while that cache keeps being accepted.
Evidence from the QueryBuilder failure
Failing job: https://github.com/IgniteUI/Infragistics.QueryBuilder.Executor/actions/runs/33509115228/job/99862048354
C:\Program Files\dotnet\sdk\9.0.317\Sdks\Microsoft.NET.Sdk\targets\Microsoft.PackageDependencyResolution.targets(266,5):
error NETSDK1064: Package Microsoft.EntityFrameworkCore.Analyzers, version 9.0.4 was not found.
It might have been deleted since NuGet restore.
Otherwise, NuGet restore might have only partially completed, which might have been due to maximum path length restrictions.
[D:\a\Infragistics.QueryBuilder.Executor\Infragistics.QueryBuilder.Executor\Infragistics.QueryBuilder.Executor.csproj::TargetFramework=net8.0]
The preceding release (https://github.com/IgniteUI/Infragistics.QueryBuilder.Executor/actions/runs/33004665173, 1.0.2-prerelease.36) succeeded on the same workflow shape: same split jobs, same --no-build --no-restore, no restore in pack, identical bin/** + obj/** artifacts with include-hidden-files: true, and identical setup-dotnet steps.
The failure was reproduced from the failing run's own signed-assemblies artifact, replayed at the same workspace path:
| Scenario |
Result |
| Artifact exactly as delivered |
pack succeeds |
Same files, obj/project.assets.json made newer than obj/Release/<tfm>/*.assets.cache |
NETSDK1064, identical message |
| Restore first, then the identical pack command |
pack succeeds |
Ruled out as the cause: the SDK version (9.0.315 and 10.x both fail identically once the cache is rejected, so this repo's global.json pin of 10.0.100 does not protect it), the -p:RepositoryUrl / -p:RepositoryCommit pack arguments — which this workflow also passes — the signing job refreshing DLL timestamps, and any difference in artifact contents between the passing and failing runs.
Why it has not manifested here yet
The split-job release workflow is not merged into master, and no release has been produced from btraykov/release-workflow-refactoring, so this pack job has never executed in a real release run. That is the only reason — not a structural difference from QueryBuilder.
The exposure is the same once it does run: the same split-job handoff, the same --no-restore, and net8.0;net9.0;net10.0 multi-targeting (QueryBuilder failed on its net8.0 inner build).
Why it appeared suddenly in QueryBuilder
Nothing in that release changed the pack path. The necessary and sufficient condition for the failure is that ResolvePackageAssets rejects the transferred cache, and acceptance is decided by a timestamp comparison between obj/project.assets.json and the per-framework assets.cache — both of which are written by actions/download-artifact when it materialises the artifact, not by the build that produced them. Earlier releases landed on the winning side of that comparison; this one did not.
The precise trigger for run 33509115228 is not recoverable from the logs. What is reproducible is that the error appears exactly when the cache is rejected and disappears when a restore runs first.
Suggested fix
Restore on the pack runner before packing. This is not a rebuild, so the Authenticode-signed assemblies downloaded from sign-assemblies are left untouched and every downstream signature and strong-name check still applies:
- name: Restore .NET dependencies
run: dotnet restore ./src/IgniteUI.Blazor.Lite.csproj
placed between Download signed assemblies and Pack NuGet package.
The equivalent alternative is to drop --no-restore from dotnet pack and let it restore implicitly. Either option removes the dependency on cache acceptance; keeping --no-restore without a restore step means release correctness rests on artifact extraction ordering.
One repo-specific note: the Razor SDK reads src/wwwroot when it builds the static web asset manifest, and the build job already depends on the web assets being in place before restore. A restore in the pack job runs after signed-assemblies (which includes src/wwwroot/**) has been downloaded, so the assets are present at that point.
Notes
Filed pre-emptively — there is no failure in this repository to point at yet. The same issue is being filed against IgniteUI/IgniteUI.Blazor.GridLite, and the fix has been applied in the QueryBuilder release-hardening PR where the failure actually occurred.
Summary
The
packjob in.github/workflows/igniteui-blazor-lite-release.yml(branchbtraykov/release-workflow-refactoring) runs on its own runner and packs with--no-build --no-restore, so nodotnet restoreever runs there. Whether that succeeds depends on an MSBuild cache file that happens to travel inside the artifact, not on anything the workflow controls. When that cache is rejected, the job fails withNETSDK1064.Infragistics.QueryBuilder.Executor, whose release workflow was modelled on this one and has the same shape, hit exactly this in production on 2026-09-01.Where it is in this repo
The
packjob declaresneeds: sign-assembliesand its ownruns-on: windows-latest, then checks out, sets up .NET, downloads thesigned-assembliesartifact intosrc, and runs:The packages restored by the
buildjob live in that runner's global NuGet cache, which is not part of the artifact and does not exist on the pack runner.Why this usually works anyway
The artifact carries
src/bin/**andsrc/obj/**, andsrc/obj/<Configuration>/<tfm>/<project>.assets.cachetravels with it. When MSBuild'sResolvePackageAssetsaccepts that cache, it reuses the previously resolved package assets and never looks for the packages on disk, so the missing package cache goes unnoticed. When it rejects the cache, it re-resolves fromsrc/obj/project.assets.json, probes the package folders recorded there (C:\Users\runneradmin\.nuget\packages\), finds nothing, and fails.So
--no-restoreon a separate runner is not safe by design — it is safe only while that cache keeps being accepted.Evidence from the QueryBuilder failure
Failing job: https://github.com/IgniteUI/Infragistics.QueryBuilder.Executor/actions/runs/33509115228/job/99862048354
The preceding release (https://github.com/IgniteUI/Infragistics.QueryBuilder.Executor/actions/runs/33004665173,
1.0.2-prerelease.36) succeeded on the same workflow shape: same split jobs, same--no-build --no-restore, no restore inpack, identicalbin/**+obj/**artifacts withinclude-hidden-files: true, and identicalsetup-dotnetsteps.The failure was reproduced from the failing run's own
signed-assembliesartifact, replayed at the same workspace path:obj/project.assets.jsonmade newer thanobj/Release/<tfm>/*.assets.cacheNETSDK1064, identical messageRuled out as the cause: the SDK version (9.0.315 and 10.x both fail identically once the cache is rejected, so this repo's
global.jsonpin of10.0.100does not protect it), the-p:RepositoryUrl/-p:RepositoryCommitpack arguments — which this workflow also passes — the signing job refreshing DLL timestamps, and any difference in artifact contents between the passing and failing runs.Why it has not manifested here yet
The split-job release workflow is not merged into
master, and no release has been produced frombtraykov/release-workflow-refactoring, so thispackjob has never executed in a real release run. That is the only reason — not a structural difference from QueryBuilder.The exposure is the same once it does run: the same split-job handoff, the same
--no-restore, andnet8.0;net9.0;net10.0multi-targeting (QueryBuilder failed on itsnet8.0inner build).Why it appeared suddenly in QueryBuilder
Nothing in that release changed the pack path. The necessary and sufficient condition for the failure is that
ResolvePackageAssetsrejects the transferred cache, and acceptance is decided by a timestamp comparison betweenobj/project.assets.jsonand the per-frameworkassets.cache— both of which are written byactions/download-artifactwhen it materialises the artifact, not by the build that produced them. Earlier releases landed on the winning side of that comparison; this one did not.The precise trigger for run
33509115228is not recoverable from the logs. What is reproducible is that the error appears exactly when the cache is rejected and disappears when a restore runs first.Suggested fix
Restore on the pack runner before packing. This is not a rebuild, so the Authenticode-signed assemblies downloaded from
sign-assembliesare left untouched and every downstream signature and strong-name check still applies:placed between
Download signed assembliesandPack NuGet package.The equivalent alternative is to drop
--no-restorefromdotnet packand let it restore implicitly. Either option removes the dependency on cache acceptance; keeping--no-restorewithout a restore step means release correctness rests on artifact extraction ordering.One repo-specific note: the Razor SDK reads
src/wwwrootwhen it builds the static web asset manifest, and thebuildjob already depends on the web assets being in place before restore. A restore in thepackjob runs aftersigned-assemblies(which includessrc/wwwroot/**) has been downloaded, so the assets are present at that point.Notes
Filed pre-emptively — there is no failure in this repository to point at yet. The same issue is being filed against
IgniteUI/IgniteUI.Blazor.GridLite, and the fix has been applied in the QueryBuilder release-hardening PR where the failure actually occurred.