- name
- update-roslyn-version
- description
- Guide for updating the Roslyn language server version in the vscode-csharp repository. Use this when asked to update Roslyn, bump the Roslyn version, or upgrade the language server version.
# Update Roslyn Version
This skill describes how to update the Roslyn language server version in the vscode-csharp repository.
## Prerequisites
1. You must have a local clone of the `dotnet/roslyn` repository. Common locations for this include:
- `C:\Users\<username>\source\repos\roslyn`
- Next to the current repo directory, e.g. `<current-repo-root>/../roslyn`
- If unable to find local roslyn repo, ask the user for its location.
2. The `dnx` command must be available. It is included with the .NET 10 SDK and later:
```powershell
dnx --help
```
3. The GitHub CLI must be installed and authenticated so its token can be passed to Roslyn Tools:
```powershell
gh auth status
```
## Input Required
- **New Roslyn Version** (optional): The new version to update to (e.g., `5.5.0-2.26080.10`). If not provided, the version will be auto-discovered from the latest passing `dotnet-roslyn-official` pipeline build on main. See [Version Auto-Discovery](#version-auto-discovery) below.
## Version Auto-Discovery
If the user does not provide a specific Roslyn version, follow these steps to discover the latest version from the official Roslyn build pipeline.
### Prerequisites
1. The Azure Developer CLI (`azd`) must be installed. See https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd for platform-specific instructions.
- If `azd` is missing, don't look for an alternative. Instead, stop and assist the user with installing it.
2. You must be authenticated:
```shell
azd auth login
```
### Discovery Steps
1. **Get an Azure DevOps bearer token:**
```shell
TOKEN=$(azd auth token --scope "499b84ac-1321-427f-aa17-267ca6975798/.default" --output json | jq -r '.token')
```
2. **Find the latest passing main build** (pipeline definition ID `327` = `dotnet-roslyn-official`):
```shell
BUILD_ID=$(curl -s -H "Authorization: Bearer $TOKEN" \
"https://dnceng.visualstudio.com/internal/_apis/build/builds?definitions=327&branchName=refs/heads/main&statusFilter=completed&resultFilter=succeeded&\$top=1&api-version=7.0" \
| jq '.value[0].id')
```
3. **Find the "Publish Assets" task log URL from the build timeline:**
```shell
LOG_URL=$(curl -s -H "Authorization: Bearer $TOKEN" \
"https://dnceng.visualstudio.com/internal/_apis/build/builds/$BUILD_ID/timeline?api-version=7.0" \
| jq -r '.records[] | select(.name == "Publish Assets" and .type == "Task") | .log.url')
```
4. **Fetch the log and extract the NuGet package version:**
```shell
VERSION=$(curl -s -H "Authorization: Bearer $TOKEN" "$LOG_URL" \
| grep -oP 'Microsoft\.CodeAnalysis\.\K\d+\.\d+\.\d+-[\w.]+(?=\.nupkg)' \
| head -1)
echo "Discovered version: $VERSION"
```
The extracted version (e.g., `5.6.0-2.26173.1`) is the value to use as the new Roslyn version for the rest of the process.
## Process
### Step 1: Create a New Branch
Create a new git branch for the update:
```powershell
git checkout -B update/roslyn-<version>
```
Replace `<version>` with the new Roslyn version, using dashes instead of dots for the branch name.
### Step 2: Update package.json
Update the `defaults.roslyn` field in `package.json`:
```json
"defaults": {
"roslyn": "<new-version>",
...
}
```
### Step 3: Run updateRoslynVersion
This step acquires the new Roslyn packages and ensures they are in the proper feeds:
```powershell
npm run updateRoslynVersion
```
This task:
- Downloads all platform-specific Roslyn nuget packages
- Ensures packages are saved to the consumption AzDo artifacts feed
- Runs `installDependencies` to update local dependencies
**Note**: You may need to install the [Azure Artifacts NuGet Credential Provider](https://github.com/microsoft/artifacts-credprovider#installation-on-windows) for interactive authentication.
### Step 4: Get the Previous Roslyn Commit SHA
The commit SHAs are stored in the `.nuspec` files inside the downloaded NuGet packages. After running `npm run updateRoslynVersion`, the new version's package will be cached locally, but you need to explicitly download the old version to get its commit SHA.
**To get the old version's commit SHA:**
1. First, find the old version number from the current `package.json` (before your edit) - look at the `defaults.roslyn` value
2. Download the old version's package to the local cache:
```powershell
dotnet restore "C:\Users\<username>\source\repos\vscode-csharp\msbuild\server" /p:PackageName=roslyn-language-server.osx-arm64 /p:PackageVersion=<old-version> --interactive
```
3. Extract the commit SHA from the nuspec file:
```powershell
Get-Content "C:\Users\<username>\source\repos\vscode-csharp\out\.nuget\roslyn-language-server.osx-arm64\<old-version>\roslyn-language-server.osx-arm64.nuspec" | Select-String -Pattern "commit"
```
This will show output like:
```
<repository type="git" url="https://github.com/dotnet/roslyn" branch="main" commit="0e21a3cb684db6ab02646541a780b3278f53d19e" />
```
### Step 5: Get the New Roslyn Commit SHA
After running `npm run updateRoslynVersion`, the new version's package is already cached. Extract the commit SHA:
```powershell
Get-Content "C:\Users\<username>\source\repos\vscode-csharp\out\.nuget\roslyn-language-server.osx-arm64\<new-version>\roslyn-language-server.osx-arm64.nuspec" | Select-String -Pattern "commit"
```
**Note**: The Azure DevOps artifacts feed web pages require authentication and may not load properly in automated scenarios. Always use the nuspec files from the local package cache.
### Step 6: Generate Changelog Entries Using PR Finder
First, locate the local `dotnet/roslyn` repository. Common locations include:
- `C:\Users\<username>\source\repos\roslyn`
- `C:\repos\roslyn`
Navigate to the roslyn repository, fetch the latest, and run the pr-finder tool:
```powershell
cd <path-to-roslyn-repo>
git fetch origin
dnx Microsoft.RoslynTools --prerelease --source https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json -- pr-finder --github-token "$(gh auth token)" --start <old-commit-sha> --end <new-commit-sha> --format "o#"
```
**Important**: Invoke Roslyn Tools through `dnx` instead of a globally installed `roslyn-tools` executable. Always pass the GitHub token explicitly with `--github-token`.
This will output a list of PRs in the format needed for the changelog:
```
* <PR title> (PR: [#<number>](https://github.com/dotnet/roslyn/pull/<number>))
```
Keep the raw output from `pr-finder`; you'll use it unchanged in the pull request description in Step 10.
### Step 7: Update CHANGELOG.md
Add an entry to `CHANGELOG.md` under the current version section (e.g., `# 2.121.x`):
Copy the results from the previous step (should already be formatted correctly).
```markdown
* Update Roslyn to <new-version> (PR: [#](https://github.com/dotnet/vscode-csharp/pull/))
* <PR title 1> (PR: [#<number>](https://github.com/dotnet/roslyn/pull/<number>))
* <PR title 2> (PR: [#<number>](https://github.com/dotnet/roslyn/pull/<number>))
...
```
Note: Leave the PR number blank initially (just `[#]`) - it will be updated after the PR is created.
### Step 8: Filter Changelog Entries
Treat the changelog as a concise list of user-facing VS Code editor and language server changes, not a list of all production changes in Roslyn. Review the PR title and, when its impact is ambiguous, its changed files or description.
Remove entries that are:
- **Infrastructure/Build changes**: CI/CD pipelines, build scripts, Azure DevOps configurations
- **Visual Studio-only changes**: Features or fixes specific to Visual Studio IDE (not VS Code)
- **Test-only changes**: Test infrastructure, test fixes that don't affect production code
- **Internal tooling**: Changes to internal tools not used by the language server
- **Documentation-only**: README updates, internal docs (unless they document user-facing features)
- **Compiler-only changes**: Language implementation, parsing, lowering, emit, code generation, compiler APIs, or compiler performance changes without direct editor or language server impact
- **Razor compiler internals**: Razor parsing, lowering, code generation, or compiler architecture changes that do not directly change the VS Code editing experience
- **Internal refactoring and dependencies**: Architectural refactors, implementation details, package updates, or internal performance work unless they have a clear user-visible effect in VS Code
Keep entries that are:
- Language server protocol (LSP) changes
- Code analysis or diagnostics improvements visible in the editor
- Completion, navigation, refactoring features
- Performance improvements specifically affecting editor or language server responsiveness
- Bug fixes that affect language server behavior
- Razor changes that directly affect editing features such as formatting, completion, navigation, or code actions
- API changes consumed by the VS Code extension or language server
When uncertain, omit the entry from `CHANGELOG.md`; the complete unfiltered list remains available in the pull request description.
### Step 9: Commit and Push
```powershell
git add package.json CHANGELOG.md
git commit -m "Update Roslyn to <new-version>"
git push -u origin update/roslyn-<version>
```
### Step 10: Create Pull Request
Create a pull request on GitHub:
- Title: `Update roslyn to <new-version>`
- Base: `main`
- Description/body: the raw, unfiltered output from `pr-finder` in Step 6, including the compare link and full PR list exactly as produced by the tool. Do not apply the Step 8 changelog filtering to the PR description.
### Step 11: Update Changelog with PR Number
After the PR is created, note the PR number (e.g., `#8941`), then:
1. Update the CHANGELOG.md entry to include the actual PR number:
```markdown
* Update Roslyn to <new-version> (PR: [#8941](https://github.com/dotnet/vscode-csharp/pull/8941))
```
2. Commit and push the update:
```powershell
git add CHANGELOG.md
git commit -m "Update changelog with PR number"
git push
```
## Example
For updating from `5.4.0-2.26077.7` to `5.5.0-2.26080.10`:
1. Branch: `update/roslyn-5-5-0-2-26080-10`
2. package.json change: `"roslyn": "5.5.0-2.26080.10"`
3. Find old commit from package metadata for version `5.4.0-2.26077.7`
4. Find new commit from package metadata for version `5.5.0-2.26080.10`
5. Run pr-finder in roslyn repo
6. Update CHANGELOG.md with the output
7. Run `npm run updateRoslynVersion`
8. Create PR titled "Update roslyn to 5.5.0-2.26080.10"
9. Update changelog with PR number
## Reference PR
See [PR #8941](https://github.com/dotnet/vscode-csharp/pull/8941) as an example of a Roslyn version update.
## Files Modified
- `package.json` - Update `defaults.roslyn` version
- `CHANGELOG.md` - Add changelog entry with Roslyn PR list
## Troubleshooting
### Authentication Issues with updateRoslynVersion
If you encounter authentication errors:
1. Install Azure Artifacts Credential Provider
2. Run the command again - it should prompt for interactive authentication
### pr-finder Returns Empty Results
Ensure:
1. You have fetched the latest from origin in the roslyn repo: `git fetch origin`
2. Both commit SHAs exist in your local repo
3. `gh auth status` succeeds and `gh auth token` returns a token
4. You are invoking the tool through `dnx` and passing `--github-token "$(gh auth token)"`
### Finding Commit SHAs
The commit SHAs are embedded in the nuspec files inside the downloaded NuGet packages:
1. After running `npm run updateRoslynVersion`, packages are cached in `out/.nuget/`
2. To get the old version's commit, you may need to explicitly download it first:
```powershell
dotnet restore "msbuild\server" /p:PackageName=roslyn-language-server.osx-arm64 /p:PackageVersion=<old-version> --interactive
```
3. Then read the nuspec file:
```powershell
Get-Content "out\.nuget\roslyn-language-server.osx-arm64\<version>\roslyn-language-server.osx-arm64.nuspec" | Select-String -Pattern "commit"
```
**Note**: The Azure DevOps artifacts feed web pages require authentication and often fail to load in automated scenarios. Always use the local nuspec files instead.
GitHub에서 보기