Skip to content

Add ASP.NET Core perf-build pipeline#5243

Open
LoopedBard3 wants to merge 12 commits into
dotnet:mainfrom
LoopedBard3:loopedbard3/aspnetcore-perf-build
Open

Add ASP.NET Core perf-build pipeline#5243
LoopedBard3 wants to merge 12 commits into
dotnet:mainfrom
LoopedBard3:loopedbard3/aspnetcore-perf-build

Conversation

@LoopedBard3

@LoopedBard3 LoopedBard3 commented Jun 19, 2026

Copy link
Copy Markdown
Member

DRAFT — do not merge / not ready for review. Posted for Parker's first-pass review.

What this does

Stands up a new Azure DevOps perf-build pipeline hosted in dotnet/performance that builds every commit on dotnet/aspnetcore main from source, stages each per-RID Microsoft.AspNetCore.App.Runtime runtime-pack nupkg, and uploads it to the Build Cache Service (BCS @ pvscmdupload) so dotnet/crank can resolve ASP.NET Core runtime binaries by commit SHA for performance-regression bisection.

This moves work that currently lives in dotnet/aspnetcore (a perf-build.yml to be retired there) into dotnet/performance.

Why move it here

Team merge control. Hosting the pipeline in dotnet/performance gives the perf team full ownership of the build/upload contract instead of it living in aspnetcore.

What's in the change

New

  • eng/pipelines/aspnetcore-perf-build.yml — root pipeline: 5 per-config boolean params, the aspnetcore repo-resource trigger, and the 3 stages (RegisterBuild / Build / UploadArtifacts).
  • eng/pipelines/aspnetcore-perf-build-jobs.ymlauthored build jobs, one self-sufficient job per config (Windows x64; Windows x86; Windows arm64; Linux x64; Linux arm64).
  • eng/pipelines/tools/stage-bcs-nupkg-aspnetcore.ps1 — the canonical "find the one runtime-pack nupkg → copy it to the fixed BCS artifact name BuildArtifacts_{os}_{arch}_Release_aspnetcore.nupkg" recipe. The BCS stores the runtime-pack nupkg verbatim (no extract/repack): a nupkg is a zip on every OS, so crank extracts it with the same code path and gets the nupkg's own runtimes/{rid}/... layout. Storing the raw nupkg keeps the full shipped artifact — crank filters managed/native at consume time — instead of a lossy archive projection that can't be re-derived for historical bisection. (Supersedes the earlier extract/validate/repack pack-bcs-archives-aspnetcore.ps1 moved from aspnetcore.)

Edited (shared runtime templates — back-compat preserved)

  • register-build-jobs.yml, templates/register-build-job.yml, upload-build-artifacts-jobs.yml, templates/upload-build-artifacts-job.yml — added a sha parameter (default $(Build.SourceVersion)), threaded through to the BCS blob path. The 5 aspnetcore_* upload branches (added in Generalize BCS upload + register-build templates with repoName parameter #5241) now thread sha too, and their artifact file lists are .nupkg.

Key design decisions / things to scrutinize

  1. Can't reuse aspnetcore's default-build.yml cross-repo. That template has hard @self references, and @self always resolves to the root pipeline repo (= performance), which doesn't carry aspnetcore's eng/common contract. So the build jobs are rebuilt from source here as plain - job: blocks that invoke aspnetcore's own eng/build.cmd/eng/build.sh.

    One job per arch (Windows split). Unlike aspnetcore's ci-public.yml, which builds Windows x64→x86→arm64 sequentially in one job (x86/arm64 reuse the x64 step's managed build + on-machine native toolchain), each config here is its own self-sufficient job gated by its boolean — uniform with the Linux jobs. This makes per-config gating exact (e.g. queue only aspnetcore_arm64_windows → only Windows_arm64_build runs; x64 isn't built just to host arm64) and runs the three Windows arches in parallel instead of back-to-back. The tradeoff: each Windows arch carries its own -all (full managed build) and -nativeToolsOnMachine (the toolchain the shared x64 step used to provide); x86/arm64 keep -noBuildNative (faithful to ci-public's per-arch args — native runtime bits restore from packages rather than cross-building on the x64 host). Scrutinize: standalone Windows-arch builds are not locally provable; the first real queued run validates that x86/arm64 restore native correctly without the preceding x64 step.

  2. SHA inversion (load-bearing). Because the pipeline is hosted in performance, Build.SourceVersion is the performance commit, not the aspnetcore one. The correct BCS {sha} is the triggering aspnetcore commit = $(resources.repositories.aspnetcore.version). The root pipeline passes that as sha: to the register/upload templates. The shared templates default sha to $(Build.SourceVersion) so the existing dotnet/runtime perf-build is unaffected.

    Build↔commit correlation (Option B). The build record's sourceVersion is performance's commit, so the dotnet-performance-infra indexer does not rely on sourceVersion. Instead it derives the aspnetcore commit directly from the build's resources.repositories.aspnetcore.version via the runs API — intrinsic to every build that carries the aspnetcore repo resource, so no pipeline-side run tagging is needed. This avoids the silent-empty-latestBuilds failure mode a forgotten or hand-edited build tag could otherwise introduce.

  3. Repo-resource CI trigger for per-commit firing. The aspnetcore AzDO mirror internal/dotnet-aspnetcore is a type: git repository resource with trigger on main (batch: false → eager, per-commit). A push to aspnetcore main fires this pipeline (Build.Reason == ResourceTrigger); jobs check out that resource at the triggering commit. (Note: stage gating uses ResourceTrigger, not IndividualCI — another consequence of the host inversion vs. the aspnetcore reference.) All three stages carry the internal + (ResourceTrigger | Manual) gate: RegisterBuild/UploadArtifacts via ${{ if }} (compile-time removed in public), Build via a runtime condition: so it skips rather than fails in a public/manual misqueue (a fully ${{ if }}-gated pipeline would expand to zero stages, which AzDO rejects).

  4. Build from PUBLIC feeds. No internal runtime download, no enable-internal-runtimes / get-delegation-sas step, no dotnetbuilds-internal-read connection. Proof: aspnetcore's own ci-public.yml builds every public PR with _InternalRuntimeDownloadArgs empty. Only the BCS upload uses the proven .NET Performance connection.

    • Caveat: a rare pre-mirror window where aspnetcore main pins an internal-only runtime would also break aspnetcore's own public CI, so it's not a risk we uniquely take — we simply skip already-broken SHAs.
  5. Per-config booleans for forward-compat indexing. 5 boolean params (default true) gate their build jobs and feed the register/upload buildType arrays, so the dotnet-performance-infra MissingBuildsTrigger PerConfiguration indexer can count exactly these keys. In v1's eager mode all 5 are always built; the booleans let a future Function queue a subset.

  6. No 1ES. Per-commit perf artifacts go to a private BCS cache (unsigned, not redistributed), so we don't extend 1ES.Official — matching dotnet/runtime's perf-build.

  7. Atomicity. continueOnError: false everywhere; any failure sinks the build to Failed and the indexer skips that SHA. UploadArtifacts dependsOn: [Build, RegisterBuild], condition: succeeded().

The 5 configs / RIDs (locked)

configKey rid artifact build job
aspnetcore_x64_linux linux-x64 .nupkg Linux_x64_build
aspnetcore_arm64_linux linux-arm64 .nupkg Linux_arm64_build
aspnetcore_x64_windows win-x64 .nupkg Windows_x64_build
aspnetcore_arm64_windows win-arm64 .nupkg Windows_arm64_build
aspnetcore_x86_windows win-x86 .nupkg Windows_x86_build

BCS layout: builds/aspnetcore/buildArtifacts/{sha}/{configKey}/{buildInfo.json,nupkg}.

Validation status

The full pipeline can't be run locally. All 7 YAML files parse; job-name ↔ dependencyJobName, artifact names, and the staging-script output filename were cross-checked for consistency. Real validation = a manual queued run after merge (pool image availability, aspnetcore from-source build on the dnceng internal pool, end-to-end BCS upload). The aspnetcore-hosted version will be retired once this is validated.

Stand up an Azure DevOps perf-build pipeline hosted in dotnet/performance that builds every commit on dotnet/aspnetcore main from source, packs per-RID Microsoft.AspNetCore.App.Runtime archives, and uploads them to the Build Cache Service for dotnet/crank bisection.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 19, 2026 18:31

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Azure DevOps perf-build pipeline in dotnet/performance to build dotnet/aspnetcore main commits from source, pack per-RID Microsoft.AspNetCore.App.Runtime archives, and upload/register them in BCS using the existing shared templates (extended to support a caller-supplied SHA).

Changes:

  • Introduces eng/pipelines/aspnetcore-perf-build.yml + eng/pipelines/aspnetcore-perf-build-jobs.yml to build/pack/publish ASP.NET Core runtime-pack artifacts for the locked set of 5 config keys.
  • Adds sha parameter plumbing through the shared register/upload dispatcher + leaf templates so non-self (resource) builds can write BCS blobs under the triggering repo commit.
  • Adds eng/pipelines/tools/pack-bcs-archives.ps1 to produce the BCS archive layout from runtime-pack nupkgs.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
eng/pipelines/aspnetcore-perf-build.yml New root pipeline with aspnetcore repo-resource trigger and Register/Build/Upload stages.
eng/pipelines/aspnetcore-perf-build-jobs.yml New authored build jobs to build aspnetcore from source (Windows multi-arch + Linux x64/arm64) and publish artifacts.
eng/pipelines/tools/pack-bcs-archives.ps1 New packaging script to turn runtime-pack nupkgs into BCS archive layout and validate contents.
eng/pipelines/upload-build-artifacts-jobs.yml Adds sha parameter and threads it through aspnetcore upload branches.
eng/pipelines/templates/upload-build-artifacts-job.yml Adds sha parameter and uses it in the BCS blob path for uploads.
eng/pipelines/register-build-jobs.yml Adds sha parameter and forwards it into per-buildType register jobs.
eng/pipelines/templates/register-build-job.yml Adds sha parameter and uses it in the BCS blob path for buildInfo.json.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread eng/pipelines/aspnetcore-perf-build.yml
Comment thread eng/pipelines/aspnetcore-perf-build-jobs.yml Outdated
Comment thread eng/pipelines/tools/pack-bcs-archives.ps1 Outdated
Comment thread eng/pipelines/tools/pack-bcs-archives.ps1 Outdated
Parker Bibus and others added 2 commits June 19, 2026 12:00
Add an early, unconditional RegisterBuild job that tags the run with aspnetcore-sha:<40-char sha> (the aspnetcore commit from the repo-resource version macro). The build record's sourceVersion is the performance commit, so this tag is the dotnet-performance-infra indexer's sole aspnetcore-sha signal. Additive; the BCS {sha} override and buildInfo.json are unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…version)

The dotnet-performance-infra indexer derives the aspnetcore commit directly from the build's resources.repositories.aspnetcore.version via the runs API, so the dedicated TagBuild job is redundant. The BCS {sha} path override and buildInfo.json are unchanged.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 19, 2026 19:11
@LoopedBard3 LoopedBard3 changed the title Add ASP.NET Core perf-build pipeline (moved from dotnet/aspnetcore) Add ASP.NET Core perf-build pipeline Jun 19, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment thread eng/pipelines/aspnetcore-perf-build-jobs.yml Outdated
Comment thread eng/pipelines/aspnetcore-perf-build-jobs.yml Outdated
Comment thread eng/pipelines/aspnetcore-perf-build-jobs.yml Outdated
Comment thread eng/pipelines/aspnetcore-perf-build-jobs.yml Outdated
Comment thread eng/pipelines/upload-build-artifacts-jobs.yml Outdated
Comment thread eng/pipelines/aspnetcore-perf-build.yml
Comment thread eng/pipelines/aspnetcore-perf-build.yml Outdated
Parker Bibus and others added 2 commits June 22, 2026 14:42
- Convert job-level variables: blocks in aspnetcore-perf-build-jobs.yml from the
  invalid list form (- key: value) to the mapping form so AzDO schema validation
  passes and _AspNetCoreRoot/_PackScript/_ShippingDir/_StagingRoot expand (all 3
  build jobs).
- Clarify pack-bcs-archives.ps1 .DESCRIPTION (explicit pwsh step, not an
  afterBuild hook; reference aspnetcore-perf-build-jobs.yml) and add a local-run
  .EXAMPLE that passes -ShippingDir/-StagingRoot explicitly.
- Clarify the ATOMICITY comment in aspnetcore-perf-build.yml to note the
  always()-guarded log-publish steps are intentionally continueOnError:true.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Thread `sha: ${{ parameters.sha }}` into the 15 runtime upload branches in
upload-build-artifacts-jobs.yml, matching the per-branch `repoName` threading
already present on all branches. Behavior-neutral: sha defaults to
$(Build.SourceVersion) (the leaf template default), so runtime perf-build
uploads resolve to the same BCS path as before; only callers that pass an
explicit sha (e.g. the aspnetcore pipeline's resource version) change the
path. register-build-jobs.yml already forwards sha to every buildType via its
${{ each }} loop, so no change was needed there.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 22, 2026 22:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Comment thread eng/pipelines/upload-build-artifacts-jobs.yml Outdated
Comment thread eng/pipelines/aspnetcore-perf-build-jobs.yml Outdated
Parker Bibus and others added 2 commits June 22, 2026 16:24
Replace the single multi-arch Windows_build job with three independent,
boolean-gated jobs (Windows_x64_build / Windows_x86_build /
Windows_arm64_build), mirroring the Linux job structure. Each job now:
- is gated solely by its own aspnetcore_*_windows boolean (x64 is no longer
  an unconditional base build that runs whenever any Windows arch is
  requested), and
- builds standalone with -all + -nativeToolsOnMachine; x86/arm64 keep
  -noBuildNative so native runtime bits restore from packages.

Repoint the three Windows aspnetcore_*_windows upload branches'
dependencyJobName to the new per-arch job names.

This gives exact per-config gating for the forward-compat indexer (queue
only arm64 -> only Windows_arm64_build runs) and runs the three Windows
arches in parallel instead of sequentially. Standalone Windows-arch native
restore is validated by the first real queued run.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
After U1 (4f41751) every upload branch threads sha: ${{ parameters.sha }},
so the parameter doc claiming runtime branches omit sha and inherit the leaf
default is no longer accurate. Reword to say all branches pass sha explicitly
and it resolves to the $(Build.SourceVersion) default when no caller overrides
it. Comment-only; no behavior change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 23, 2026 17:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Comment thread eng/pipelines/aspnetcore-perf-build.yml
Comment thread eng/pipelines/tools/pack-bcs-archives.ps1 Outdated
Parker Bibus and others added 2 commits June 23, 2026 12:29
…ults

Two follow-up Copilot comments on the latest push (c43515f):

1. aspnetcore-perf-build.yml: the Build stage was the only ungated stage. It
   checks out the internal-only aspnetcore mirror on the internal DncEng pool,
   so a manual queue in a public project would fail confusingly while the
   already-gated RegisterBuild/UploadArtifacts stages are compile-time removed.
   Add a runtime condition: matching the sibling internal + (ResourceTrigger |
   Manual) gate. A runtime condition (not ${{ if }}) keeps the stage
   present-but-skipped in public, avoiding a zero-stage (invalid) pipeline.
   Behavior-neutral in the steady-state internal trigger path.

2. pack-bcs-archives.ps1: $ShippingDir/$StagingRoot defaults called Join-Path on
   BUILD_SOURCESDIRECTORY/BUILD_ARTIFACTSTAGINGDIRECTORY, which throws during
   parameter binding when those env vars are unset (local runs). Fall back to the
   current directory so the documented local-override workflow works off-agent.
   Unchanged on the agent where the BUILD_* vars are always set.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The pack script is aspnetcore-specific: it is hardcoded to find
Microsoft.AspNetCore.App.Runtime.{rid} nupkgs and emit the lowercase
microsoft.aspnetcore.app.runtime.{rid}/Release layout. It shares the
eng/pipelines/tools/ directory with the dotnet/runtime perf-build pipeline, so an
-aspnetcore suffix makes its scope explicit and avoids a future collision with a
runtime-specific pack script. Matches the aspnetcore-* naming of its sibling
pipeline files. Updated the 5 _PackScript references and the header comment in
aspnetcore-perf-build-jobs.yml and the 2 .EXAMPLE self-references in the script.
No contract depends on the filename (only the pipeline references it).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 23, 2026 19:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment thread eng/pipelines/tools/pack-bcs-archives-aspnetcore.ps1 Outdated
…netcore

Copilot review: the pack script selected the runtime-pack nupkg with
`Sort-Object Name | Select-Object -First 1`, which silently picks the
lexicographically-smallest match if multiple versions are present in the Shipping
directory -- packing an unintended version into the BCS archive.

A clean from-source build produces exactly one non-symbols
Microsoft.AspNetCore.App.Runtime.{rid} pack per RID, so collect all non-symbols
matches and assert exactly one: throw a clear error listing the offenders when
more than one is found, instead of guessing. Matches the script's existing
assert-the-contract style (single archive root entry). Renamed the local to
$nupkgMatches to avoid shadowing PowerShell's automatic $Matches variable under
Set-StrictMode. Verified parse + 0/1/2-match behavior off-agent (symbols pack
correctly excluded).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@LoopedBard3 LoopedBard3 self-assigned this Jun 23, 2026
@LoopedBard3 LoopedBard3 marked this pull request as ready for review June 23, 2026 19:53
Copilot AI review requested due to automatic review settings June 23, 2026 19:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment on lines +115 to +131
$pattern = "Microsoft.AspNetCore.App.Runtime.$rid.*.nupkg"
$matches = @(Get-ChildItem -Path $ShippingDir -Filter $pattern -File -ErrorAction SilentlyContinue |
Where-Object { $_.Name -notmatch '\.symbols\.nupkg$' } |
Sort-Object Name)
if ($matches.Count -eq 0) {
throw "Could not find runtime pack nupkg matching '$pattern' under '$ShippingDir'."
}
if ($matches.Count -gt 1) {
# A clean from-source build produces exactly one non-symbols runtime pack
# per RID. More than one means a stale/duplicate version is lingering in
# the Shipping dir; pick-first would silently pack the lexicographically
# smallest (likely wrong) version, so fail loudly instead.
$names = ($matches | ForEach-Object { $_.Name }) -join ', '
throw "Expected exactly one runtime pack nupkg matching '$pattern' under '$ShippingDir', found $($matches.Count): $names."
}
$nupkg = $matches[0]
Write-Host "Found nupkg: $($nupkg.FullName)"

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in c96b8cd. Renamed the local $matches to $nupkgMatches (all 6 references) so it no longer shadows PowerShell's automatic $Matches variable, which matters once Set-StrictMode is in play or regex matching is added later. Pure rename, no behavior change; script still parses and the exactly-one-nupkg assertion is unaffected.

@@ -0,0 +1,206 @@
<#

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does this file even exist? It seems to just unpack the nupkg, then re-pack it. It seems like it would be a lot simpler to just save off the nupkg to the archive.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The main thing is that this transforms the nupkg to match what we already have from dotnet/runtime. Both storing the nupkg or these archives work, each with their own pros and cons. Storing nupkgs leaves us with a simpler pipeline here and having the whole artifact but causes a mismatch between this and dotnet/runtime packs in what is stored and how crank can use each (may be able to share more if both are tar/zip) (still a WIP). While storing the archives makes this pipeline more complex but should allow for more reuse on the crank side as the stored packages with match dotnet/runtime build format.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call — that extract/repack round-trip was pointless, so I cut it. We're now storing the runtime-pack nupkg verbatim in BCS instead of transforming it into an archive. The script (pack-bcs-archives-aspnetcore.ps1 → renamed stage-bcs-nupkg-aspnetcore.ps1) is now just "find the one Microsoft.AspNetCore.App.Runtime.{rid} nupkg and copy it to the fixed BCS artifact name." It still earns its keep for two reasons: it asserts exactly one non-symbols nupkg exists (a stale/dup version should fail loudly, not get silently picked), and it renames the version-stamped filename to the predictable BuildArtifacts_{os}_{arch}_Release_aspnetcore.nupkg that crank resolves from a SHA. crank does the managed/native filtering at consume time, so there's nothing to strip here. The matching crank-side change is in dotnet/crank#878.

Comment thread eng/pipelines/aspnetcore-perf-build-jobs.yml
PowerShell's $Matches is an automatic variable populated by the -match
operator; assigning to the case-insensitive local $matches shadows it and
is risky under Set-StrictMode if regex matching is later added. Rename the
local to $nupkgMatches and update all references. No behavior change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
DrewScoggins
DrewScoggins previously approved these changes Jun 23, 2026
Replace the extract/validate/repack pack-bcs-archives-aspnetcore.ps1 with a thin
stage-bcs-nupkg-aspnetcore.ps1 that copies the single runtime-pack nupkg to the
fixed BCS artifact name. The BCS now stores the verbatim nupkg (crank filters at
consume time) rather than a transformed archive, so there is no produce-time
layout transform to maintain and crank can re-derive whatever it needs.

- New stage-bcs-nupkg-aspnetcore.ps1 (find the one runtime-pack nupkg, copy to
  BuildArtifacts_{os}_{arch}_Release_aspnetcore.nupkg); old pack script removed
- Build jobs drop -Format and invoke the staging script
- Upload dispatcher aspnetcore files -> .nupkg

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 23, 2026 22:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants