Skip to content

Bug: ci-nuget-cache-fallback-masks-stale-package-refs #569

Description

@drmoisan
  • Work Mode: full-bug

Summary

The three build and test workflows restore the packages directory from an
actions/cache entry whose restore-keys fallback is a bare
nuget-${{ runner.os }}- prefix. On a cache miss the fallback supplies package
folders from an unrelated earlier commit, so a project referencing a package
version that packages.config no longer declares still compiles. Two real
defects on PR #568 were invisible to CI for exactly this reason and only
appeared on a local cold build.

Environment

  • OS/version: windows-latest GitHub-hosted runner
  • Python version: n/a (GitHub Actions YAML)
  • Command/flags used: nuget restore TaskMaster.sln, then the workflow's msbuild or vstest step
  • Data source or fixture: actions/cache@v4 entry keyed on **/packages.config

Steps to Reproduce

  1. On a branch, change a package version in every packages.config but leave a
    stale ..\packages\<Id>.<OldVersion>\ path in a .csproj or in test code.
  2. Push. The cache key nuget-${{ runner.os }}-${{ hashFiles('**/packages.config') }}
    misses because the config files changed.
  3. The restore-keys: nuget-${{ runner.os }}- fallback restores a prior cache
    that still contains <Id>.<OldVersion>.
  4. nuget restore installs the new versions alongside the stale restored ones.
  5. The build and the tests pass, despite referencing a version no longer
    declared anywhere in the repository.

Expected Behavior

CI reflects what a clean checkout produces. A project or test that references a
package version absent from packages.config fails the build, because that is
what any developer with a cold packages directory experiences.

Actual Behavior

CI run 31890892701 on chore/update-nuget head 8f30fd53 reported
build-analyzers, build-nullable, and mstest-coverage as success. The
same commit built locally against a correctly-restored packages directory
produced:

  • 10 CSC : error CS0006: Metadata file '..\packages\Meziantou.Analyzer.3.0.138\...' could not be found errors (and the matching Roslynator.Analyzers.4.15.0
    errors) across 16 projects, because the upgrade advanced packages.config and
    the analyzer <Import>/<Error> lines to 3.0.156 / 4.16.0 but left the
    <Analyzer Include> item paths behind.
  • 3 test failures in UtilitiesCS.Test.Extensions.AsyncSerialization_Tests
    (InvalidOperationException: The Microsoft.Graph.xml fixture could not be located from the test assembly path), because the fixture hard-coded
    packages\Microsoft.Graph.6.2.0 while the upgrade moved to 6.5.0.

Only the format-check job failed, and it is the one job with no packages
cache dependency.

Logs / Screenshots

  • Attached minimal logs or screenshot
  • Snippet: CI run 31890892701 job list showing three green build/test jobs on the
    commit that fails a cold local build; local msbuild CS0006 output and the TRX
    failure messages quoted above. Both defects were fixed in commit 46ca9210.

Impact / Severity

  • Blocker
  • High
  • Medium
  • Low

High because it is a gate-fidelity defect, not an ordinary bug: it caused three
protected checks to report green on a commit that does not build from a clean
checkout. Any future package-path drift is silently admitted to main the same
way. It also affects the correctness signal of every prior green run whose cache
was populated from an older commit.

Source

From: docs/features/potential/2026-08-15-ci-nuget-cache-fallback-masks-stale-package-refs.md

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions