Repository navigation
Conversation
…ket.props stale Step 2a's per-project skip optimisation in Paket.Restore.targets only invalidates on paket.references content change. When a merge bumps a transitive package version, paket.lock and paket.resolved change but paket.references does not, and (with BaseIntermediateOutputPath redirected per-platform) the per-project paket.props stays at the pre-merge content. NuGet then resolves to the previous version indefinitely. This test reproduces that path: full restore, mutate paket.lock content, expect the next restore to invalidate the per-project skip. With the unfixed targets file the skip stays in effect and the test fails. Companion fix to follow.
Add Step 2 a-bis to Paket.Restore.targets that hashes paket.lock and compares to a per-project hash cache file written after each successful per-project restore. If the cached hash differs from the current hash, the per-project skip is invalidated and a paket restore runs. A fall-through case fires once on first encounter for legacy checkouts that pre-date the cache file, so installations upgrading to this version self-correct on the next restore. This complements Step 2a (which hashes paket.references content) so that pure-transitive package version changes — where paket.lock and paket.resolved change but paket.references does not — also invalidate the per-project skip. The hash is computed locally rather than reusing $(PaketRestoreLockFileHash) from Step 1 because Step 1 may be disabled via PaketDisableGlobalRestore. A new file $(PaketIntermediateOutputPath)\<proj>.fsproj.paket.lock.hash records the lock hash at the time of the last successful per-project restore. Greens the integration test added in the previous commit.
|
Would really like to see this reviewed and commented on. I think it possibly resolves an issue I've had forever. My only solution was just manually purging bin/obj dirs between any paket.lock changes (or even more mundane things like switching branches with different paket.locks). |
There was a problem hiding this comment.
Pull request overview
This PR fixes Paket’s MSBuild “skip per-project restore” optimization so it also invalidates when paket.lock content changes (not just when paket.references changes). This prevents stale per-project paket.props / *.paket.resolved under redirected BaseIntermediateOutputPath, which can otherwise cause NuGet to keep resolving old transitive versions indefinitely.
Changes:
- Extend
Paket.Restore.targetsStep 2 with a per-project cached SHA256 ofpaket.lockto force per-project restore when lock content changes (and a one-time fallback when the cache file is missing). - Stamp the per-project lock hash cache after successful per-project restore.
- Add a new integration scenario plus an integration test asserting that a lock-content change triggers per-project restore (via
PAKET_ERROR_ON_MSBUILD_EXEC=true).
Show a summary per file
| File | Description |
|---|---|
| src/Paket.Core/embedded/Paket.Restore.targets | Adds per-project paket.lock hash invalidation and writes the hash cache after per-project restore. |
| integrationtests/Paket.IntegrationTests/RestoreSpecs.fs | Adds a regression test for lock-content invalidation of the per-project restore skip. |
| integrationtests/scenarios/i4333-lock-content-invalidates-project-props/before/Directory.Build.props | New scenario that redirects BaseIntermediateOutputPath and disables global restore (to reproduce the original bug). |
| integrationtests/scenarios/i4333-lock-content-invalidates-project-props/before/paket.dependencies | New scenario dependencies file for the repro project. |
| integrationtests/scenarios/i4333-lock-content-invalidates-project-props/before/paket.lock | New scenario lockfile used to establish and then mutate lock content. |
| integrationtests/scenarios/i4333-lock-content-invalidates-project-props/before/project/paket.references | New scenario references file that remains unchanged while the lock is mutated. |
| integrationtests/scenarios/i4333-lock-content-invalidates-project-props/before/project/project.fsproj | New SDK-style repro project importing Paket.Restore.targets. |
| integrationtests/scenarios/i4333-lock-content-invalidates-project-props/before/project/Program.fs | Minimal program for the new repro project. |
Review details
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
- Files reviewed: 7/8 changed files
- Comments generated: 1
- Review effort level: Lite
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
|
/repo-assist Check if the test added is actually running as part of the CI or is it in the integration tests we haven't fully enabled yet |
|
✓ Repo Assist completed successfully, see workflow run.
|
|
🤖 This is an automated response from Repo Assist. Checked how the new test (
No code changes proposed here since this reflects an existing, intentional-looking trim of Linux integration-test coverage (not something introduced by this PR). Flagging for the maintainer's awareness in case Linux integration coverage should be restored.
Add this agentic workflow to your repoTo install this agentic workflow, run |
This is to fix #4333 — Step 2a's skip in
Paket.Restore.targetspreviously only watchedpaket.references, so transitive changes inpaket.lockleft the per-projectpaket.propsstale. The fix adds apaket.lockcontent-hash check (Step 2 a-bis) and a one-line write of that hash after each successful per-project restore (Step 3 a-bis), plus a fall-through that fires once on first encounter for legacy checkouts that pre-date the cache file.Test in
RestoreSpecs.fsfollows the existing#2684/#3527patterns: full restore, mutatepaket.lockcontent, assert that the nextdotnet restorerequests a per-project restore (viaPAKET_ERROR_ON_MSBUILD_EXEC=true).