Skip to content

Add ASP.NET Core perf-build pipeline#5243

Draft
LoopedBard3 wants to merge 3 commits into
dotnet:mainfrom
LoopedBard3:loopedbard3/aspnetcore-perf-build
Draft

Add ASP.NET Core perf-build pipeline#5243
LoopedBard3 wants to merge 3 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, packs per-RID Microsoft.AspNetCore.App.Runtime archives, and uploads them 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 (Windows x64/x86/arm64 in one job; Linux x64; Linux arm64).
  • eng/pipelines/tools/pack-bcs-archives.ps1moved verbatim from aspnetcore; the canonical "find runtime-pack nupkg → produce the lowercase microsoft.aspnetcore.app.runtime.{rid}/Release/... archive" recipe.

Edited (shared runtime templates — back-compat preserved)

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.

  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.)

  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 archive build job
aspnetcore_x64_linux linux-x64 .tar.gz Linux_x64_build
aspnetcore_arm64_linux linux-arm64 .tar.gz Linux_arm64_build
aspnetcore_x64_windows win-x64 .zip Windows_build
aspnetcore_arm64_windows win-arm64 .zip Windows_build
aspnetcore_x86_windows win-x86 .zip Windows_build

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

Validation status

The full pipeline can't be run locally. All 7 YAML files parse; job-name ↔ dependencyJobName, artifact names, and pack-script output paths 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 on lines +135 to +139
- stage: Build
displayName: Build
dependsOn: []
jobs:
- template: /eng/pipelines/aspnetcore-perf-build-jobs.yml
Comment on lines +121 to +125
-Configuration Release
-arch arm64
-pack
-noBuildJava
-noBuildNative
Comment on lines +6 to +11
.DESCRIPTION
This is the single, canonical "find the runtime-pack nupkg and zip it into
the BCS archive layout" recipe used by every job in perf-build.yml (Windows
x64/x86/arm64, Linux x64, Linux arm64). The build jobs invoke it from their
`afterBuild` hook with the RID(s) they produced and the archive format that
matches their platform convention (.zip on Windows, .tar.gz on Linux).
Comment on lines +42 to +46
.EXAMPLE
./pack-bcs-archives.ps1 -Rids win-x64,win-x86,win-arm64 -Format zip

.EXAMPLE
./pack-bcs-archives.ps1 -Rids linux-x64 -Format targz
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 on lines +60 to +65
variables:
- _AspNetCoreRoot: $(Agent.BuildDirectory)\s\aspnetcore
- _PackScript: $(Agent.BuildDirectory)\s\performance\eng\pipelines\tools\pack-bcs-archives.ps1
- _ShippingDir: $(Agent.BuildDirectory)\s\aspnetcore\artifacts\packages\Release\Shipping
- _StagingRoot: $(Build.ArtifactStagingDirectory)\bcs
- MSBUILDUSESERVER: "1"
Comment on lines +182 to +186
variables:
- _AspNetCoreRoot: $(Agent.BuildDirectory)/s/aspnetcore
- _PackScript: $(Agent.BuildDirectory)/s/performance/eng/pipelines/tools/pack-bcs-archives.ps1
- _ShippingDir: $(Agent.BuildDirectory)/s/aspnetcore/artifacts/packages/Release/Shipping
- _StagingRoot: $(Build.ArtifactStagingDirectory)/bcs
Comment on lines +240 to +244
variables:
- _AspNetCoreRoot: $(Agent.BuildDirectory)/s/aspnetcore
- _PackScript: $(Agent.BuildDirectory)/s/performance/eng/pipelines/tools/pack-bcs-archives.ps1
- _ShippingDir: $(Agent.BuildDirectory)/s/aspnetcore/artifacts/packages/Release/Shipping
- _StagingRoot: $(Build.ArtifactStagingDirectory)/bcs
Comment on lines +121 to +126
-Configuration Release
-arch arm64
-pack
-noBuildJava
-noBuildNative
/p:OnlyPackPlatformSpecificPackages=true
Comment on lines +10 to +14
# sha controls the {sha} segment of the BCS blob path. Defaults to the self
# repo commit ($(Build.SourceVersion)) for back-compat with the runtime
# perf-build pipeline. Resource-built tenants (e.g. aspnetcore, whose source
# is a repository resource rather than self) pass the resource's commit, e.g.
# sha: $(resources.repositories.aspnetcore.version). Runtime config branches
Comment on lines +114 to +118
# The aspnetcore commit this build corresponds to is NOT tagged on the run: the
# dotnet-performance-infra indexer reads it directly from the build's
# `resources.repositories.aspnetcore.version` via the runs API (intrinsic to the
# build carrying the aspnetcore repo resource). The BCS {sha} path override below
# still uses that same value.
Comment on lines +38 to +39
# ATOMICITY: continueOnError:false everywhere; any failure sinks the build to
# Failed and the MissingBuildsTrigger Function skips indexing that SHA.
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.

2 participants