-
Notifications
You must be signed in to change notification settings - Fork 729
Add skill for updating the xamlTools version #9532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
JoeRobich
merged 7 commits into
dotnet:main
from
noiseonwires:add-xamltools-update-skill
Jul 15, 2026
+300
−0
Merged
Changes from all commits
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
960eb1f
Add skill for updating xamlTools version
noiseonwires e956daf
Potential fix for pull request finding
noiseonwires 7e07932
Potential fix for pull request finding
noiseonwires 6b3da50
Potential fix for pull request finding
noiseonwires d07cbb6
Potential fix for pull request finding
noiseonwires 08648d8
Fail fast when boundary commit is beyond first page in xamlTools chan…
noiseonwires 64cc788
Potential fix for pull request finding
noiseonwires File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,300 @@ | ||
| --- | ||
| name: update-xamltools-version | ||
| description: Guide for updating the xamlTools (Microsoft.VisualStudio.DesignToolsBase) component version in the vscode-csharp repository. Use this when asked to update xamlTools, bump the xamlTools version, or upgrade the XAML/DesignTools component. | ||
| --- | ||
|
|
||
| # Update xamlTools Version | ||
|
|
||
| This skill describes how to update the `xamlTools` component version in the vscode-csharp repository. | ||
|
|
||
| Unlike Roslyn (which lives on GitHub at `dotnet/roslyn`), `xamlTools` lives entirely in Azure DevOps, in the VS source repository under the `src/Xaml` folder. | ||
|
|
||
| The general mechanism is the same as Roslyn: changes are merged into the VS repo, CI produces a NuGet package (`Microsoft.VisualStudio.DesignToolsBase`) that flows to the upstream feed, and updating vscode-csharp means bumping the version in `package.json`, refreshing the component, and adding a `CHANGELOG.md` entry via a PR. | ||
|
|
||
| Because there is no cross-repo tooling equivalent to `roslyn-tools pr-finder`, the update is generally **simpler** than the Roslyn update, but the changelog still requires a manual review/trim step (even if the raw PR list is generated via the REST API). | ||
|
|
||
| ## Input Required | ||
|
|
||
| - **New xamlTools Version** (required): The `Microsoft.VisualStudio.DesignToolsBase` NuGet package version to update to (e.g., `18.9.11921.35`). Ask the user to provide it. | ||
| - The user is responsible for ensuring that version has been **saved from upstream into the `msft_consumption` feed** (see [Ensure the Package Is Available in the Feed](#optional-ensure-the-package-is-available-in-the-feed)). If a version is not in the feed, restoring it will fail. | ||
| - **Changelog entries** (recommended): A short list of notable XAML/DesignTools changes between the previous and new version, with their AzDO PR numbers. These can be generated **fully automatically** from the VS repo via the Azure DevOps REST API — **no VS source enlistment is required** (see [Step 4](#step-4-gather-changelog-entries)). If you lack `az` access to that AzDO organization, ask the user to provide the list. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| 1. A local clone of `dotnet/vscode-csharp`. | ||
| 2. The .NET SDK installed. | ||
| 3. The [Azure Artifacts NuGet Credential Provider](https://github.com/microsoft/artifacts-credprovider#installation-on-windows) for interactive authentication when restoring packages from the feed. | ||
| 4. For the automated changelog (Step 4): the [Azure CLI](https://learn.microsoft.com/cli/azure/) signed in (`az login`) with access to the Azure DevOps organization that hosts the VS source repo. The concrete org/project/repo coordinates are environment-specific — supply them from your own notes or parse them from a VS repo URL the user provides (see [Step 4](#step-4-gather-changelog-entries)); they are intentionally not hard-coded in this public skill. This is used to call the VS repo REST API — **no VS source enlistment is required**. | ||
|
|
||
| ## (Optional) Ensure the Package Is Available in the Feed | ||
|
|
||
| This is normally the user's responsibility, but here is the full process to locate and save the package. vscode-csharp restores from the `msft_consumption` feed (see `NuGet.config`), which pulls versions from an upstream source. A new version must be present (and saved) in that feed before it can be restored. | ||
|
|
||
| 1. After your changes merge into the VS repo, it may take **up to one day** for a NuGet package build to appear in the upstream feed. | ||
| 1. Find your merge commit's CloudBuild number in the AzDO CI. | ||
| 2. Open the package in Azure Artifacts: [Microsoft.VisualStudio.DesignToolsBase](https://dev.azure.com/azure-public/vside/_artifacts/feed/msft_consumption/NuGet/Microsoft.VisualStudio.DesignToolsBase). Switch to **"Upstream versions"** and search for your version. | ||
| 3. If it is there, click the three dots (`...`) on the right and select **"Save to feed"**. | ||
|
|
||
| **Note**: These Azure DevOps feed web pages require authentication and often fail to load in automated scenarios. If you cannot access them, ask the user to confirm the version has been saved to the feed and to provide the exact version string. Do not attempt to guess or fabricate a version. | ||
|
|
||
| ## Process | ||
|
|
||
| ### Step 1: Create a New Branch | ||
|
|
||
| Create a new git branch for the update: | ||
| ```powershell | ||
| git checkout -B update/xamltools-<version> | ||
| ``` | ||
| Replace `<version>` with the new xamlTools version, using dashes instead of dots for the branch name (e.g., `update/xamltools-18-9-11921-35`). | ||
|
|
||
| ### Step 2: Update package.json | ||
|
|
||
| Update the `defaults.xamlTools` field in `package.json`: | ||
|
|
||
| ```json | ||
| "defaults": { | ||
| ... | ||
| "xamlTools": "<new-version>" | ||
| } | ||
| ``` | ||
|
|
||
| ### Step 3: Acquire the Package | ||
|
|
||
| Refresh the local component and ensure the package is present in the consumption feed: | ||
|
|
||
| ```powershell | ||
| npm run installDependencies | ||
| ``` | ||
|
|
||
| `xamlTools` (`Microsoft.VisualStudio.DesignToolsBase`) is a **non-platform-specific** package, so unlike Roslyn there is no dedicated `updateXamlToolsVersion` task and no per-platform acquisition. Running `installDependencies` downloads and installs xamlTools into `./.xamlTools/`; a successful restore validates that the requested version is available via the `msft_consumption` feed (if it isn’t, follow [Ensure the Package Is Available in the Feed](#optional-ensure-the-package-is-available-in-the-feed)). | ||
|
|
||
| **Note**: You may need the [Azure Artifacts NuGet Credential Provider](https://github.com/microsoft/artifacts-credprovider#installation-on-windows) for interactive authentication. If the restore fails with a "package not found" error, the version is likely not yet saved to the feed — see [Ensure the Package Is Available in the Feed](#optional-ensure-the-package-is-available-in-the-feed). | ||
|
|
||
| ### Step 4: Gather Changelog Entries | ||
|
|
||
| Because xamlTools lives in Azure DevOps, there is no `pr-finder` equivalent. The change list can be generated **fully automatically from the VS repo via the Azure DevOps REST API — no VS source enlistment is required** (Option A). If you lack `az` access to that AzDO organization, fall back to a user-provided list (Option B). Each entry references its AzDO PR number rather than a GitHub PR link. | ||
|
|
||
| #### Option A (preferred): Generate from the VS repo automatically | ||
|
|
||
| The flow is: (1) resolve the exact VS-repo commit that produced each package version, (2) list the `/src/Xaml` commits between them, (3) map those commits to their PRs, (4) trim to user/developer-facing changes. | ||
|
|
||
| All REST calls target the VS source repo and need an Azure DevOps bearer token. | ||
|
|
||
| **Resolve the VS repo coordinates first.** The org/project/repo are intentionally not hard-coded in this public skill, so obtain them, in order of preference: | ||
| 1. From your own private notes/environment if you have them (this is the expected path for maintainers), otherwise | ||
| 2. Ask the user for the VS repo web URL and parse `<org>`/`<project>`/`<repo>` from it. Both AzDO URL shapes work: | ||
| - `https://<org>.visualstudio.com/<project>/_git/<repo>` | ||
| - `https://dev.azure.com/<org>/<project>/_git/<repo>` | ||
|
|
||
| Then set the coordinates (the REST API uses the `https://dev.azure.com/<org>` host form): | ||
| ```powershell | ||
| # AzDO coordinates for the VS source repo. Fill these in from your notes or the URL the user provides. | ||
| $org = '<azdo-org-url>' # e.g. https://dev.azure.com/<org> | ||
| $repo = "$org/<project>/_apis/git/repositories/<vs-repo>" # the repo that hosts src/Xaml | ||
| # 499b84ac-... is the well-known Azure DevOps application ID; `az login` must have access to that org. | ||
| $tok = az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798 --query accessToken -o tsv | ||
| $hdr = @{ Authorization = "Bearer $tok" } | ||
| ``` | ||
|
|
||
| ##### 4.1 Resolve each version's VS-repo commit from the DLL (not from a build) | ||
|
|
||
| The `Microsoft.VisualStudio.DesignToolsBase` **package/nuspec does not embed a commit SHA**, but its **assemblies do**. `Microsoft.VisualStudio.DesignTools.Markup.dll` (stamped by Nerdbank.GitVersioning) carries the commit two ways: | ||
| - `ProductVersion` = `18.x.NNN+<short-10-char-sha>` — the short SHA. | ||
| - internal const `ThisAssembly.GitCommitId` — the **full 40-char SHA**, which is what the REST API requires (short SHAs are rejected with HTTP 400). | ||
|
|
||
| The **new** version's DLL is already in `./.xamlTools/` after Step 3. For the **old** version (the value in `package.json` *before* your Step 2 edit), restore it into a throwaway project first: | ||
| ```powershell | ||
| $old = '<old-version>' | ||
| $probe = Join-Path $env:TEMP 'xamlProbe' | ||
| New-Item -ItemType Directory -Force $probe | Out-Null | ||
| Copy-Item ./NuGet.config $probe -Force | ||
| @" | ||
| <Project Sdk="Microsoft.NET.Sdk"> | ||
| <PropertyGroup><TargetFramework>net8.0</TargetFramework><RestorePackagesPath>packages</RestorePackagesPath></PropertyGroup> | ||
| <ItemGroup><PackageReference Include="Microsoft.VisualStudio.DesignToolsBase" Version="$old" /></ItemGroup> | ||
| </Project> | ||
| "@ | Set-Content (Join-Path $probe 'probe.csproj') | ||
| dotnet restore (Join-Path $probe 'probe.csproj') --interactive | Out-Null | ||
| ``` | ||
| Read the full SHA from either DLL using an **isolated load context** (both DLLs share the same assembly identity, so a plain `Assembly.LoadFrom` of the second would just return the first): | ||
| ```powershell | ||
| function Get-XamlCommit($dll) { | ||
| $alc = [System.Runtime.Loader.AssemblyLoadContext]::new([string][guid]::NewGuid(), $true) | ||
| try { | ||
| $asm = $alc.LoadFromStream([System.IO.MemoryStream]::new([System.IO.File]::ReadAllBytes($dll))) | ||
| $f = $asm.GetType('ThisAssembly').GetField('GitCommitId', [System.Reflection.BindingFlags]'NonPublic,Static,Public') | ||
| [string]$f.GetRawConstantValue() | ||
| } finally { $alc.Unload() } | ||
| } | ||
| $newCommit = Get-XamlCommit './.xamlTools/Microsoft.VisualStudio.DesignTools.Markup.dll' | ||
| $oldCommit = Get-XamlCommit (Get-ChildItem $probe -Recurse -Filter 'Microsoft.VisualStudio.DesignTools.Markup.dll' | Select-Object -First 1).FullName | ||
| ``` | ||
|
|
||
| ##### 4.2 List the `/src/Xaml` commits between the two versions | ||
|
|
||
| Do **not** use the obvious "commits between two commits" query (`searchCriteria.compareVersion` + `itemVersion`): the two build source commits frequently live on **divergent branches**, so that query returns 0. Instead, walk `/src/Xaml` history back from the new commit and stop at the old build's most-recent `/src/Xaml` commit (the "boundary", already shipped in the previous version): | ||
| ```powershell | ||
| function Get-XamlCommits($version, $top) { | ||
| $q = @{ 'searchCriteria.itemPath'='/src/Xaml'; 'searchCriteria.itemVersion.version'=$version; | ||
| 'searchCriteria.itemVersion.versionType'='commit'; 'searchCriteria.$top'="$top"; 'api-version'='7.1' } | ||
| (Invoke-RestMethod -Uri "$repo/commits" -Headers $hdr -Body $q -Method Get).value | ||
| } | ||
| $boundary = (Get-XamlCommits $oldCommit 1)[0].commitId | ||
| $range = New-Object System.Collections.Generic.List[object] | ||
| $foundBoundary = $false | ||
| foreach ($c in (Get-XamlCommits $newCommit 1000)) { if ($c.commitId -eq $boundary) { $foundBoundary = $true; break }; $range.Add($c) } | ||
| if (-not $foundBoundary) { throw "Boundary commit not found in first page of /src/Xaml history. Increase `$top or page results (searchCriteria.`$skip) and retry." } | ||
| "in-range /src/Xaml commits: $($range.Count)" | ||
| ``` | ||
| Use the *list* API as above; the single-commit `GET /commits/{sha}` endpoint is flaky in scripts and best avoided. | ||
|
|
||
| ##### 4.3 Map the in-range commits to PRs — cover **both** completion styles | ||
|
|
||
| Parsing `Merged PR <id>: <title>` out of commit messages only finds **squash-completed** PRs. **Merge-completed** PRs instead contribute their individual dev commits (whose messages are *not* `Merged PR ...`), and their merge commit doesn't change the path so it never shows up in the filtered list. Missing these is the single most common cause of an incomplete changelog — so combine both detections: | ||
| ```powershell | ||
| # (a) squash-completed PRs — from "Merged PR <id>: <title>" commit messages | ||
| $squash = foreach ($c in $range) { | ||
| $m = [regex]::Match($c.comment.Split([char]10)[0], '^Merged PR (\d+): (.*)$') | ||
| if ($m.Success) { [pscustomobject]@{ Id = $m.Groups[1].Value; Title = $m.Groups[2].Value.Trim() } } | ||
| } | ||
| # (b) merge-completed PRs — map the in-range commit ids to their PRs | ||
| $body = @{ queries = @(@{ type = 'commit'; items = @($range.commitId) }) } | ConvertTo-Json -Depth 4 | ||
| $res = Invoke-RestMethod -Uri "$repo/pullRequestQuery?api-version=7.1" -Headers $hdr -Method Post -Body $body -ContentType 'application/json' | ||
| $merged = foreach ($p in $res.results[0].PSObject.Properties) { foreach ($pr in $p.Value) { [pscustomobject]@{ Id = "$($pr.pullRequestId)"; Title = $pr.title } } } | ||
| # union both, de-duplicated | ||
| @($squash + $merged) | Sort-Object Id -Unique | ForEach-Object { " * $($_.Title) (PR: AzDO#$($_.Id))" } | ||
| ``` | ||
|
|
||
| ##### 4.4 Trim to user/developer-facing changes | ||
|
|
||
| Keep features, fixes, telemetry, and Hot Reload behavior. **Drop** infrastructure noise — the `pullRequestQuery` step in particular sweeps in integration PRs that merely carried the commits along: | ||
| - branch-sync / integration PRs: `Merge main into ...`, `Sync vscode -> ...`, `Merge for <build>`; | ||
| - component insertions: `... Roslyn ... Insertion into main`; | ||
| - build/test/pipeline/localization churn and pure refactors. | ||
|
|
||
| #### Option B (fallback): User-provided list | ||
|
|
||
| If you cannot reach the VS repo (no `az` access to that AzDO organization) or cannot resolve the commits, ask the user for the list of notable XAML/DesignTools changes with their AzDO PR numbers. | ||
|
|
||
| #### (Alternative) Local VS enlistment | ||
|
|
||
| With a VS enlistment, `git log` is a convenient cross-check — but it does **not** replace step 4.3, because `--first-parent ... -- src/Xaml` only surfaces merge-commit PRs. Prefer the REST flow above as the source of truth. | ||
| ```powershell | ||
| git log --first-parent "<old-commit>..<new-commit>" --pretty=format:"%s" -- src/Xaml | | ||
| Select-String -Pattern '^Merged PR (\d+): (.*)$' | | ||
| ForEach-Object { " * $($_.Matches.Groups[2].Value) (PR: AzDO#$($_.Matches.Groups[1].Value))" } | ||
| ``` | ||
|
|
||
| #### (Optional) Confirm a specific PR shipped in a version | ||
|
|
||
| To check whether a given AzDO PR is part of a version, compare its **individual commits** against the `/src/Xaml` range (its *merge* commit will not appear in the range): | ||
| ```powershell | ||
| $id = <pr-id> | ||
| $pr = Invoke-RestMethod -Uri "$repo/pullRequests/$id?api-version=7.1" -Headers $hdr # status / targetRefName / closedDate | ||
| $last = (Invoke-RestMethod -Uri "$repo/pullRequests/$id/iterations?api-version=7.1" -Headers $hdr).value[-1].id | ||
| $paths = (Invoke-RestMethod -Uri "$repo/pullRequests/$id/iterations/$last/changes?api-version=7.1" -Headers $hdr).changeEntries.item.path | ||
| $prCommits = (Invoke-RestMethod -Uri "$repo/pullRequests/$id/commits?api-version=7.1" -Headers $hdr).value.commitId | ||
| $inRange = $prCommits | Where-Object { $range.commitId -contains $_ } | ||
| "under /src/Xaml: $(@($paths | Where-Object { $_ -like '/src/Xaml*' }).Count)/$($paths.Count); in-range commits: $($inRange.Count)/$($prCommits.Count)" | ||
| ``` | ||
| It is **included** when at least one of its commits is in `$range` **and** it changed files under `/src/Xaml` (a PR that touches no `/src/Xaml` files is not part of the package build). | ||
|
|
||
| ### Step 5: Update CHANGELOG.md | ||
|
|
||
| Add an entry to `CHANGELOG.md` under the current in-development version section (the top-most `# 2.x.x` header). Use the AzDO reference format for the child entries: | ||
|
noiseonwires marked this conversation as resolved.
|
||
|
|
||
| ~~~markdown | ||
| * Update xamlTools to <new-version> (PR: [#](https://github.com/dotnet/vscode-csharp/pull/)) | ||
| * <change description> (PR: AzDO#<number>) | ||
| * <change description> (PR: AzDO#<number>, AzDO#<number>) | ||
| ~~~ | ||
|
|
||
| Notes: | ||
| - Leave the vscode-csharp PR number blank initially (just `[#]`) — it is filled in after the PR is created (Step 8). | ||
| - Child entries use `AzDO#<number>` (the VS source repo PR/work item number), **not** a GitHub link, because those changes live in Azure DevOps. Multiple references are comma-separated, e.g. `(PR: AzDO#728266, AzDO#730837)`. | ||
|
|
||
| ### Step 6: Commit and Push | ||
|
|
||
| ```powershell | ||
| git add package.json CHANGELOG.md | ||
| git commit -m "Update xamlTools to <new-version>" | ||
| git push -u origin update/xamltools-<version> | ||
| ``` | ||
|
|
||
| ### Step 7: Create Pull Request | ||
|
|
||
| Create a pull request on GitHub: | ||
| - Title: `Update xamlTools to <new-version>` | ||
| - Base: `main` | ||
| - Description: Summarize the bump (from `<old-version>` to `<new-version>`) and note that the `CHANGELOG.md` entry documents the notable XAML/DesignTools changes. | ||
|
|
||
| ### Step 8: Update Changelog with PR Number | ||
|
|
||
| xamlTools update PRs have an "interesting" changelog flow: the vscode-csharp PR number isn't known until the PR exists, so it is backfilled after creation. | ||
|
|
||
| After the PR is created, note the PR number (e.g., `#9461`), then: | ||
|
|
||
| 1. Update the `CHANGELOG.md` entry to include the actual PR number: | ||
| ```markdown | ||
| * Update xamlTools to <new-version> (PR: [#9461](https://github.com/dotnet/vscode-csharp/pull/9461)) | ||
| ``` | ||
| You can also try to guess the number ahead of time by inspecting the latest open/closed PRs and issues on GitHub, but backfilling after creation is the reliable approach. | ||
|
|
||
| 2. Commit and push the update — either a follow-up commit, or amend and force-push: | ||
|
noiseonwires marked this conversation as resolved.
|
||
| ```powershell | ||
| git add CHANGELOG.md | ||
| git commit -m "Update changelog with PR number" | ||
| git push | ||
| ``` | ||
|
|
||
| ## Example | ||
|
|
||
| For updating from `18.9.11909.33` to `18.9.11921.35` (see [PR #9461](https://github.com/dotnet/vscode-csharp/pull/9461)): | ||
|
|
||
| 1. Branch: `update/xamltools-18-9-11921-35` | ||
| 2. `package.json` change: `"xamlTools": "18.9.11921.35"` | ||
| 3. Run `npm run installDependencies` | ||
| 4. Add a `CHANGELOG.md` entry under the current version section: | ||
| ```markdown | ||
| * Update xamlTools to 18.9.11921.35 (PR: [#9461](https://github.com/dotnet/vscode-csharp/pull/9461)) | ||
| * MAUI Hot Reload exceptions reporting (PR: AzDO#749102) | ||
| * C# XAML Expressions (XEXPR) support improvements and fixes (PR: AzDO#748362) | ||
| ``` | ||
| 5. Create PR titled "Update xamlTools to 18.9.11921.35" | ||
| 6. Backfill the PR number in the changelog | ||
|
|
||
| ## Reference PR | ||
|
|
||
| See [PR #9461](https://github.com/dotnet/vscode-csharp/pull/9461) as an example of a xamlTools version update. | ||
|
|
||
| ## Files Modified | ||
|
|
||
| - `package.json` - Update `defaults.xamlTools` version | ||
| - `CHANGELOG.md` - Add changelog entry with the xamlTools AzDO change list | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Restore Fails With "Package Not Found" | ||
|
|
||
| The requested version is likely not yet available/saved in the `msft_consumption` feed. Either: | ||
| 1. Wait (it can take up to a day after the VS repo merge for the upstream package to build), or | ||
| 2. Save it from upstream to the feed (see [Ensure the Package Is Available in the Feed](#optional-ensure-the-package-is-available-in-the-feed)), then re-run `npm run installDependencies`. | ||
|
|
||
| ### Authentication Issues with installDependencies | ||
|
|
||
| If you encounter authentication errors: | ||
| 1. Install the [Azure Artifacts Credential Provider](https://github.com/microsoft/artifacts-credprovider#installation-on-windows). | ||
| 2. Run `npm run installDependencies` again — it should prompt for interactive authentication. | ||
|
|
||
| ### Can't Access the Azure Artifacts Feed Pages | ||
|
|
||
| The Azure DevOps feed web pages require authentication and may not load in automated scenarios. Ask the user to confirm the version has been saved to the feed and to provide the exact `Microsoft.VisualStudio.DesignToolsBase` version string. Do not guess a version. | ||
|
|
||
| ### Commit REST Query Returns HTTP 400 or an Empty Range (Step 4) | ||
|
|
||
| - **HTTP 400 "object ID must be 40 characters"**: you passed a short SHA. The REST API needs the **full 40-char** commit id — take it from `ThisAssembly.GitCommitId` (Step 4.1), not from `ProductVersion` (which only has the short SHA). | ||
| - **`compareVersion`/`itemVersion` range returns 0**: the two build source commits are on **divergent branches**. Don't use the compare query; use the boundary-walk in Step 4.2 instead. | ||
|
|
||
| ### Changelog Is Missing PRs (Step 4) | ||
|
|
||
| Almost always because only squash-completed PRs were detected. Re-run Step 4.3 and make sure you also run the `pullRequestQuery` (`type: commit`) mapping, which catches **merge-completed** PRs whose commits carry ordinary dev messages instead of `Merged PR ...`. | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.