Fix CI pipeline and add warn-feed script - #16379
Merged
Vladimir Morozov (vmoroz) merged 3 commits intoAug 20, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Improves network-isolated CI, package restoration, release publishing, and feed warming.
Changes:
- Adds automated npm/NuGet feed warming and ADO npm publishing.
- Fixes NuGet lock handling and upgrades Hermes.
- Removes external tester images and updates release/CLI automation.
Reviewed changes
Copilot reviewed 73 out of 74 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
yarn.lock |
Registers warm-feed workspace. |
vnext/Scripts/Warm-RnwFeedCache.ps1 |
Expands legacy feed warming. |
vnext/Scripts/NuGetRestoreForceEvaluateAllSolutions.ps1 |
Hardens lock regeneration. |
vnext/ReactCommon.UnitTests/packages.lock.json |
Updates Hermes lock. |
vnext/ReactCommon.UnitTests/packages.experimentalwinui3.lock.json |
Updates experimental Hermes lock. |
vnext/PropertySheets/NuGet.LockFile.props |
Revises locked-mode defaults. |
vnext/PropertySheets/JSEngine.props |
Bumps Hermes. |
vnext/Microsoft.ReactNative/packages.lock.json |
Updates Hermes lock. |
vnext/Microsoft.ReactNative/packages.experimentalwinui3.lock.json |
Updates experimental lock. |
vnext/Microsoft.ReactNative.IntegrationTests/packages.lock.json |
Updates Hermes lock. |
vnext/Microsoft.ReactNative.IntegrationTests/packages.experimentalwinui3.lock.json |
Updates experimental lock. |
vnext/Microsoft.ReactNative.CsWinRT/packages.lock.json |
Updates Hermes lock. |
vnext/Microsoft.ReactNative.CsWinRT/packages.experimentalwinui3.lock.json |
Updates experimental lock. |
vnext/Desktop/packages.lock.json |
Updates Hermes lock. |
vnext/Desktop/packages.experimentalwinui3.lock.json |
Updates experimental lock. |
vnext/Desktop.UnitTests/packages.lock.json |
Updates Hermes lock. |
vnext/Desktop.UnitTests/packages.experimentalwinui3.lock.json |
Updates experimental lock. |
vnext/Desktop.IntegrationTests/packages.lock.json |
Updates Hermes lock. |
vnext/Desktop.IntegrationTests/packages.experimentalwinui3.lock.json |
Updates experimental lock. |
vnext/Desktop.DLL/packages.lock.json |
Updates Hermes lock. |
vnext/Desktop.DLL/packages.experimentalwinui3.lock.json |
Updates experimental lock. |
packages/sample-custom-component/windows/SampleCustomComponent/packages.lock.json |
Updates Hermes lock. |
packages/sample-custom-component/windows/SampleCustomComponent/packages.experimentalwinui3.lock.json |
Updates experimental lock. |
packages/sample-app-fabric/windows/SampleAppFabric/packages.lock.json |
Updates Hermes lock. |
packages/sample-app-fabric/windows/SampleAppFabric.Package/packages.lock.json |
Updates package lock. |
packages/playground/windows/playground-composition/packages.lock.json |
Updates Hermes lock. |
packages/playground/windows/playground-composition/packages.experimentalwinui3.lock.json |
Updates experimental lock. |
packages/playground/windows/playground-composition.Package/packages.lock.json |
Updates package lock. |
packages/playground/windows/playground-composition.Package/packages.experimentalwinui3.lock.json |
Updates experimental lock. |
packages/e2e-test-app-fabric/windows/RNTesterApp-Fabric/packages.lock.json |
Updates Hermes lock. |
packages/e2e-test-app-fabric/windows/RNTesterApp-Fabric.Package/packages.lock.json |
Updates package lock. |
packages/e2e-test-app-fabric/test/__snapshots__/snapshotPages.test.js.snap |
Updates image snapshot. |
packages/@rnw-scripts/warm-feed/warm-feed.config.json |
Configures feed warming. |
packages/@rnw-scripts/warm-feed/tsconfig.json |
Configures TypeScript. |
packages/@rnw-scripts/warm-feed/src/warmFeed.ts |
Adds CLI entry point. |
packages/@rnw-scripts/warm-feed/src/warmers.ts |
Implements package warming. |
packages/@rnw-scripts/warm-feed/src/versions.ts |
Implements version comparison. |
packages/@rnw-scripts/warm-feed/src/types.ts |
Defines warmer types. |
packages/@rnw-scripts/warm-feed/src/run.ts |
Orchestrates warming. |
packages/@rnw-scripts/warm-feed/src/registries.ts |
Queries package registries. |
packages/@rnw-scripts/warm-feed/src/pool.ts |
Adds bounded concurrency. |
packages/@rnw-scripts/warm-feed/src/logger.ts |
Adds timestamped logging. |
packages/@rnw-scripts/warm-feed/src/http.ts |
Adds retrying HTTP client. |
packages/@rnw-scripts/warm-feed/src/feedPackages.ts |
Enumerates feed packages. |
packages/@rnw-scripts/warm-feed/src/expand.ts |
Selects versions to warm. |
packages/@rnw-scripts/warm-feed/src/config.ts |
Loads warmer configuration. |
packages/@rnw-scripts/warm-feed/src/auth.ts |
Resolves ADO authentication. |
packages/@rnw-scripts/warm-feed/README.md |
Documents feed warming. |
packages/@rnw-scripts/warm-feed/package.json |
Defines warmer package. |
packages/@rnw-scripts/warm-feed/bin.js |
Adds executable shim. |
packages/@rnw-scripts/warm-feed/.gitignore |
Ignores build outputs. |
packages/@rnw-scripts/warm-feed/.eslintrc.js |
Configures linting. |
packages/@rnw-scripts/prepare-release/src/prepareRelease.ts |
Refreshes release lockfile. |
packages/@rnw-scripts/prepare-release/src/beachballBump.ts |
Adds lockfile update helper. |
packages/@react-native/tester/overrides.json |
Marks derived tester files. |
packages/@react-native/tester/js/examples/Touchable/TouchableExample.js |
Embeds offline image. |
packages/@react-native/tester/js/examples/Pressable/PressableExample.js |
Embeds offline image. |
packages/@react-native/tester/js/examples/Layout/LayoutEventsExample.js |
Embeds offline image. |
packages/@react-native/tester/js/examples/Image/ImageExample.js |
Replaces network images. |
packages/@react-native-windows/cli/src/e2etest/createRnwApp.test.ts |
Adds version fallbacks. |
packages/@react-native-windows/automation-channel/windows/AutomationChannel/packages.lock.json |
Updates Hermes lock. |
package.json |
Adds warm-feed command. |
Directory.Build.props |
Centralizes NuGet restore mode. |
change/react-native-windows-067c0855-154d-4ca7-91e8-3a87f41740d8.json |
Adds RNW change entry. |
change/@react-native-windows-cli-d3a95276-0d6a-4882-9ec7-705bee190db3.json |
Adds CLI change entry. |
change/@react-native-windows-automation-channel-1d28e060-e543-46bb-8751-8c27c0c3c0bd.json |
Adds automation change entry. |
.nuget/empty-uwp-fallback/.gitkeep |
Creates empty UWP fallback. |
.ado/warm-feed-pipeline.yml |
Adds scheduled warmer. |
.ado/warm-feed-cache-pipeline.yml |
Migrates existing warmer. |
.ado/templates/run-windows-with-certificates.yml |
Disables force evaluation by default. |
.ado/templates/publish-npm-to-ado-feed.yml |
Adds ADO npm publishing. |
.ado/templates/prepare-build-env.yml |
Removes VS updater mitigation. |
.ado/templates/msbuild-sln.yml |
Removes conflicting restore option. |
.ado/release-pipeline.yml |
Publishes npm packages to ADO. |
Suppressed comments (1)
packages/@rnw-scripts/warm-feed/src/registries.ts:136
- A 5xx response or malformed NuGet version index becomes an empty version list and is cached, so the package is silently omitted while the warming run can remain green. Reject unsuccessful/invalid responses instead.
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+87
to
+100
| - task: AzureCLI@2 | ||
| displayName: Warm ms/react-native-public feed | ||
| inputs: | ||
| azureSubscription: Office-Hermes-Windows-Bot | ||
| scriptType: pscore | ||
| scriptLocation: inlineScript | ||
| inlineScript: | | ||
| $ErrorActionPreference = 'Stop' | ||
| $env:WARM_FEED_TOKEN = az account get-access-token ` | ||
| --resource 499b84ac-1321-427f-aa17-267ca6975798 --query accessToken -o tsv | ||
| $pkgs = '${{ parameters.packages }}'.Trim() | ||
| $warmArgs = @() | ||
| if ($pkgs) { foreach ($p in ($pkgs -split '\s+')) { $warmArgs += @('--packages', $p) } } | ||
| npx warm-feed @warmArgs |
Comment on lines
+87
to
+100
| - task: AzureCLI@2 | ||
| displayName: Warm ms/react-native-public feed | ||
| inputs: | ||
| azureSubscription: Office-Hermes-Windows-Bot | ||
| scriptType: pscore | ||
| scriptLocation: inlineScript | ||
| inlineScript: | | ||
| $ErrorActionPreference = 'Stop' | ||
| $env:WARM_FEED_TOKEN = az account get-access-token ` | ||
| --resource 499b84ac-1321-427f-aa17-267ca6975798 --query accessToken -o tsv | ||
| $pkgs = '${{ parameters.packages }}'.Trim() | ||
| $warmArgs = @() | ||
| if ($pkgs) { foreach ($p in ($pkgs -split '\s+')) { $warmArgs += @('--packages', $p) } } | ||
| npx warm-feed @warmArgs |
Comment on lines
+49
to
+52
| if (status === 401 || status === 403) { | ||
| throw new Error(`Get Packages auth failed (${status}) for ${ecosystem}`); | ||
| } | ||
| const page = body?.value ?? []; |
Comment on lines
+50
to
+57
| if (status === 401 || status === 403) { | ||
| throw new Error(`npm registry auth failed (${status}) for ${id}`); | ||
| } | ||
| if (!body || !body.versions) { | ||
| log.debug(`npm packument ${id} -> ${status}`); | ||
| cache.set(id, null); | ||
| return null; | ||
| } |
Comment on lines
+230
to
+233
| } catch (err) { | ||
| log.warn(`expand ${eco} ${p.id} failed: ${(err as Error).message}`); | ||
| return []; | ||
| } |
Comment on lines
+179
to
+181
| } else if (options.only) { | ||
| log.warn(`ignoring invalid --only '${options.only}'`); | ||
| } |
| Get-Process -Name BackgroundDownload -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue | ||
| displayName: Disable VS Installer background download | ||
|
|
||
| # The commit tag in the nuspec requires that we use at least nuget 5.8 (because things break with nuget versions before and Vs 16.8 or later) |
Comment on lines
25
to
+26
| const IMAGE2 = | ||
| 'https://www.facebook.com/ar_effect/external_textures/648609739826677.png'; | ||
| 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR4nGNgAAIAAAUAAen63NgAAAAASUVORK5CYII='; |
Comment on lines
+22
to
+28
| schedules: | ||
| - cron: '0 0,6,12,18 * * *' | ||
| displayName: Every 6 hours | ||
| branches: | ||
| include: | ||
| - main | ||
| always: true |
Comment on lines
+11
to
+17
| "scripts": { | ||
| "build": "rnw-scripts build", | ||
| "clean": "rnw-scripts clean", | ||
| "lint": "rnw-scripts lint", | ||
| "lint:fix": "rnw-scripts lint:fix", | ||
| "warm-feed": "rnw-scripts build && node bin.js", | ||
| "watch": "rnw-scripts watch" |
Yichen Yao (hansenyy)
approved these changes
Aug 20, 2026
Contributor
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 74 out of 75 changed files in this pull request and generated 2 comments.
Suppressed comments (7)
.ado/warm-feed-pipeline.yml:5
- This adds a second definition of the feed warmer while
.ado/warm-feed-cache-pipeline.ymlnow contains the same schedule and job, and.ado/README.md:16still declares that existing file as the entry point. Keeping two equivalent pipeline YAMLs creates drift and can double feed traffic if both definitions are registered; retain one canonical file and update its references.
# Scheduled feed-warming pipeline (office/ISS).
#
# Enumerates the ms/react-native-public feed and re-pulls, with the pipeline's
# managed identity, the latest patch of every npm/NuGet major.minor line already
# in use, so anonymous network-isolated PR/CI builds can restore them.
packages/@react-native/tester/js/examples/Image/ImageExample.js:26
- These constants are later used by the “Image Loading Events”, prefetch, reload, and “Image Download Progress” examples (for example, lines 989-1034). Replacing their network URLs with inline data URIs guarantees those examples no longer exercise network loading or download progress, and using the same 1×1 image also defeats the
srcSetdensity example. Use a network-isolated local HTTP fixture that preserves distinct image sizes and network behavior.
const IMAGE1 =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR4nGNgAAIAAAUAAen63NgAAAAASUVORK5CYII=';
const IMAGE2 =
'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVR4nGNgAAIAAAUAAen63NgAAAAASUVORK5CYII=';
packages/@rnw-scripts/warm-feed/src/run.ts:153
- A
missingresult means the requested package was not warmed, but onlyfailedresults make the command return nonzero. For example, a manually queued--packages npm:foo@typorun logs a warning and succeeds even though it did nothing, so the pipeline cannot reliably report whether the requested version was saved. Treatmissingas unsuccessful too.
packages/@rnw-scripts/warm-feed/src/run.ts:233 - Registry/authentication and server errors from
expandPackageare swallowed and converted to an empty target list. If registry access is broken for every package, the scheduled run can report “nothing to warm” and exit successfully without checking any versions. Let these errors reject the pool, or collect them and return a nonzero result.
packages/@rnw-scripts/warm-feed/src/run.ts:181 - An invalid
--onlyvalue is ignored, which broadens a mutating command from one requested ecosystem to both npm and NuGet. A typo such as--only npnshould fail validation instead of warming more than requested.
.ado/templates/publish-npm-to-ado-feed.yml:43 npm publishdefaults to thelatestdist-tag. Unlike the existing npmjs job, these ADO jobs do not load or passNpmDistTag, so publishing a canary/preview release will move the feed'slatesttag to that prerelease. Pass the release dist-tag into this template and publish with--tag(including appropriate handling for already-present versions).
$out = & npm publish $tgz.FullName --registry $registry 2>&1 | Out-String
packages/@rnw-scripts/warm-feed/src/expand.ts:143
- The new feed-selection engine has no tests for npm/NuGet parsing, prerelease precedence, in-use-line selection,
includeLatest, or major limiting. These rules decide which package versions are pulled into a shared production feed and contain several boundary cases; add focused unit tests, following the colocated test pattern used by other@rnw-scriptspackages such asintegrate-rn/src/test/upgradeDependencies.test.tsandstamp-version/src/test/renderPropsFile.test.ts.
Comment on lines
+93
to
+100
| inlineScript: | | ||
| $ErrorActionPreference = 'Stop' | ||
| $env:WARM_FEED_TOKEN = az account get-access-token ` | ||
| --resource 499b84ac-1321-427f-aa17-267ca6975798 --query accessToken -o tsv | ||
| $pkgs = '${{ parameters.packages }}'.Trim() | ||
| $warmArgs = @() | ||
| if ($pkgs) { foreach ($p in ($pkgs -split '\s+')) { $warmArgs += @('--packages', $p) } } | ||
| npx warm-feed @warmArgs |
Comment on lines
+93
to
+100
| inlineScript: | | ||
| $ErrorActionPreference = 'Stop' | ||
| $env:WARM_FEED_TOKEN = az account get-access-token ` | ||
| --resource 499b84ac-1321-427f-aa17-267ca6975798 --query accessToken -o tsv | ||
| $pkgs = '${{ parameters.packages }}'.Trim() | ||
| $warmArgs = @() | ||
| if ($pkgs) { foreach ($p in ($pkgs -split '\s+')) { $warmArgs += @('--packages', $p) } } | ||
| npx warm-feed @warmArgs |
Vineeth (vineethkuttan)
approved these changes
Aug 20, 2026
This was referenced Aug 20, 2026
Vladimir Morozov (vmoroz)
added a commit
to vmoroz/microsoft-react-native-windows
that referenced
this pull request
Aug 21, 2026
Vladimir Morozov (vmoroz)
added a commit
that referenced
this pull request
Aug 21, 2026
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Description
Type of Change
Why
mainalready runs CI and Release on the office/ISS Azure DevOps project (from#16350 and #16359). Those builds are network-isolated: no outbound internet at
build time, and packages restore from the internal
ms/react-native-publicfeed.This PR adds the remaining fixes needed to build and go green under those
constraints — most were found while making the same move on
0.81-stable(#16360) — plus new tooling to keep the shared feed warm.
What
NuGet restore and lock files
NU1512by makingRestoreLockedModeandRestoreForceEvaluatemutuallyexclusive: CI enforces the committed lock, local/dev builds regenerate it. The
repo root now decides this in one place instead of several conflicting ones.
0.0.0-2608.12001-35d34796and regenerate everypackages.lock.json..NET Nativeframework packages at an empty fallback folder sothey restore from the feed. Their machine-local Windows SDK copies are signed
differently per machine, which caused
NU1403lock-hash mismatches in CI.NuGetRestoreForceEvaluateAllSolutions.ps1: check each restore's exitcode, strip
nuget.orgfrom anynode_modulesNuGet.Config, and fail loudlyif a committed lock isn't regenerated.
Feed warming
@rnw-scripts/warm-feedand a scheduled pipeline that keep the sharedms/react-native-publicfeed warm by re-pulling the latest patch of everyin-use version line. This lets network-isolated PR/CI builds restore
anonymously. It reads only the feed (no repo lockfiles or checkouts), so one
pipeline serves every repo that consumes the feed. Supersedes the previous
PowerShell warmer.
Release
ms/react-native-publicandms/react-nativeADO feeds, matching how the NuGet packages are already published (alongside the
existing publish to npmjs.com).
prepare-release
yarn.lockafter the beachball version bump so the release commitstays installable under
yarn install --immutable(cherry-pick of Recreate yarn.lock when preparing new release #16375).Network isolation
facebook.comimage URLs in the tester examples with aninline
data:URI so the tests don't reach the internet.the VS CDN during isolated builds.
Tests
creaternwappe2e test resolve npm versions best-effort instead offailing the suite when a
previewversion isn't published —mainpublishescanary, andpreviewcomes from an in-progress*-stablebranch.Testing
Exercised end-to-end through the migrated CI/PR pipelines in the office/ISS
project; the full run is green.
Changelog
Should this change be included in the release notes: no
CI/build-infrastructure and tooling changes (with a Hermes package bump); no
user-facing runtime behavior change.
Microsoft Reviewers: Open in CodeFlow