Repository navigation
start-vs-VisualFSharpSln.ps1: build against a locally built hive Roslyn from its own packages - #20528
xperiandri wants to merge 3 commits into
Conversation
✅ No release notes required |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
T-Gro
left a comment
There was a problem hiding this comment.
🤖 🕵️ AI review — verify independently.
| # RestoreAdditionalProjectSources has to arrive through the props import rather than on the command | ||
| # line: Microsoft.FSharp.NetSdk.targets declares it TreatAsLocalProperty and appends to it. | ||
| $sources = | ||
| if ($feeds) { "<RestoreAdditionalProjectSources>`$(RestoreAdditionalProjectSources);$($feeds -join ';')</RestoreAdditionalProjectSources>" } |
There was a problem hiding this comment.
🤖 🕵️ [P2] Repacked Roslyn packages ignored when the -dev version is unchanged: restore succeeds with the previous contents from NuGet's global-packages cache, despite the updated local feed.
.\start-vs-VisualFSharpSln.ps1 -RoslynVersion 5.10.0-dev -RoslynRepo 'C:\src\roslyn'
# Change Roslyn APIs, rebuild and repack as the same 5.10.0-dev version.
.\start-vs-VisualFSharpSln.ps1 -RoslynVersion 5.10.0-dev -RoslynRepo 'C:\src\roslyn'
# Still consumes the first build's packages until their cache entries are removed.There was a problem hiding this comment.
Fixed in 1e2c85b: before restore, the script removes the global-packages entry ($env:NUGET_PACKAGES or ~\.nuget\packages) of every package the local feeds hold at that -dev version; -DryRun lists them instead.
| throw "$RootSuffix runs a locally built Roslyn $version, which only its own packages provide, but there is no repository at $repo; pass -RoslynRepo." | ||
| } | ||
|
|
||
| $feeds = 'Shipping', 'NonShipping' | ForEach-Object { Join-Path $repo "artifacts\packages\Release\$_" } |
There was a problem hiding this comment.
🤖 🕵️ [P2] Valid relative repository passes validation but nested projects fail restore with NU1301: NuGet resolves the emitted relative sources against each project directory, not the launcher's working directory.
# From the F# checkout, with packed Roslyn packages in the sibling checkout:
.\start-vs-VisualFSharpSln.ps1 -RoslynVersion 5.12.0-dev -RoslynRepo '..\roslyn'There was a problem hiding this comment.
Fixed in 1e2c85b: -RoslynRepo is resolved to an absolute path against the current location before the feeds are built.
| # RestoreAdditionalProjectSources has to arrive through the props import rather than on the command | ||
| # line: Microsoft.FSharp.NetSdk.targets declares it TreatAsLocalProperty and appends to it. | ||
| $sources = | ||
| if ($feeds) { "<RestoreAdditionalProjectSources>`$(RestoreAdditionalProjectSources);$($feeds -join ';')</RestoreAdditionalProjectSources>" } |
There was a problem hiding this comment.
🤖 🕵️ [P2] & in an existing repository path makes the generated override invalid XML; restore stops with MSB4024 while parsing the unescaped feed path.
.\start-vs-VisualFSharpSln.ps1 -RoslynVersion 5.12.0-dev -RoslynRepo 'C:\src\roslyn&tree'There was a problem hiding this comment.
Fixed in 1e2c85b: the feed paths are XML-escaped (SecurityElement.Escape) when written into the props.
| # less about that than a message here does. | ||
| function Get-RoslynDevFeeds([string]$repo, [string]$version) { | ||
| if (-not $repo) { $repo = Join-Path (Split-Path $PSScriptRoot) 'roslyn' } | ||
| if (-not (Test-Path $repo)) { |
There was a problem hiding this comment.
🤖 🕵️ [P2] Existing roslyn[1] repository rejected as nonexistent: both new Test-Path checks interpret brackets as wildcards instead of literal path characters.
.\start-vs-VisualFSharpSln.ps1 -RoslynVersion 5.12.0-dev -RoslynRepo 'C:\src\roslyn[1]'There was a problem hiding this comment.
Fixed in 1e2c85b: every Test-Path and Get-ChildItem in the script now uses -LiteralPath.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
🔍 Tooling Safety Check — Affects-Build-Infra, Affects-Design-Time, Affects-Restore
|
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
A missing package folder can break restore, and clearing the shared NuGet cache can disrupt other builds.
Review effort: Balanced
Findings: 1
Open (2)
What changed in this PR
This PR lets the Visual Studio launch script build the F# extension against a locally built Roslyn deployed in the target hive, using that Roslyn build’s own packages.
Changes:
- Override flowed Roslyn packages whenever the hive uses a
-devbuild. - Add the local Roslyn package folders as restore sources and clear cached copies before restoring.
| File | Description |
|---|---|
start-vs-VisualFSharpSln.ps1 |
Locates local Roslyn packages and configures the override, restore, and launch. |
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
| Write-Host "Would restore, then open $Solution in $DevEnv; F5 deploys into and launches $RootSuffix" | ||
| return | ||
| } | ||
| $stale | ForEach-Object { Remove-Item -LiteralPath $_ -Recurse -Force } |
There was a problem hiding this comment.
Keeping the shared cache. Only <id>/<version> entries at the -dev version are removed, and only for packages the local Roslyn feeds hold at that version. No published package carries that version, so nothing restored from a real feed is affected. The only other readers are builds against this same local Roslyn pack, and those would pick up the stale copy anyway.
A separate cache per launch would re-download every package the repo restores on each launch, and the launched VS would keep that cache for all its builds. Arcade deliberately keeps dev builds on the global cache to avoid that cost (InitializeNuGetPackageCachePath in eng/common/tools.ps1).
84f3cdc to
c820c98
Compare
A Roslyn built locally and deployed into the hive is there because its API surface differs from the flowed package: it is where an ExternalAccess contract lives before it flows. Matching the minor the repo flows therefore says nothing about whether the flowed packages will do, and refusing the dev version left no way to build against the Roslyn F5 actually runs. A dev version now always overrides, and the override adds the package folders of that Roslyn build to RestoreAdditionalProjectSources, since no feed carries its version. -RoslynRepo names the repository, next to this one by default, and the script checks that it actually holds the package before restore fails halfway with NU1101. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…d drop stale -dev packages Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
c820c98 to
4a165d7
Compare


Description
Depends on #20467, which is the base of this branch. Only the last commit, "Build against a locally built hive Roslyn from its own packages", belongs to this pull request; please review it after #20467 merges.
#20467 teaches the script to read the Roslyn deployed in the target hive. When that Roslyn is a local build (a
-devversion), it either matched the minor the repo flows and wrote no override, or stopped and asked for-RoslynVersion. Neither builds against the Roslyn F5 actually runs.A Roslyn is built locally and deployed into a hive because its API surface differs from the flowed package: it is where an ExternalAccess contract lives before it flows. So a matching minor says nothing about whether the flowed packages will do, and asking for a published version gives up on the one that differs.
With this change:
-devversion always overrides the flowed packages.RestoreAdditionalProjectSources, because no feed carries its version. This has to go through the props import:Microsoft.FSharp.NetSdk.targetsdeclares the propertyTreatAsLocalPropertyand appends to it, so a command-line value would not survive.-RoslynReponames the Roslyn repository, defaulting to aroslynfolder next to this one. The script checks that it holds the package for that version and says so, instead of restore failing halfway with NU1101.Shipped Roslyn versions behave as in #20467.
Checked with
-DryRun:RoslynDevShippingandNonShippingpackage foldersFooRoslynDevwith-RoslynRepo C:\no-such-roslynTooling only; no compiler or IDE code path changes, so no release notes entry.
Checklist
🤖 Generated with Claude Code