Skip to content

Fix CI pipeline and add warn-feed script - #16379

Merged
Vladimir Morozov (vmoroz) merged 3 commits into
microsoft:mainfrom
vmoroz:PR/fix-CI-pipeline-in-main
Aug 20, 2026
Merged

Fix CI pipeline and add warn-feed script#16379
Vladimir Morozov (vmoroz) merged 3 commits into
microsoft:mainfrom
vmoroz:PR/fix-CI-pipeline-in-main

Conversation

@vmoroz

@vmoroz Vladimir Morozov (vmoroz) commented Aug 20, 2026

Copy link
Copy Markdown
Member

Description

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Automation (CI/pipeline changes)

Why

main already 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-public feed.
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

  • Fix NU1512 by making RestoreLockedMode and RestoreForceEvaluate mutually
    exclusive: CI enforces the committed lock, local/dev builds regenerate it. The
    repo root now decides this in one place instead of several conflicting ones.
  • Bump the Hermes package to 0.0.0-2608.12001-35d34796 and regenerate every
    packages.lock.json.
  • Point the UWP .NET Native framework packages at an empty fallback folder so
    they restore from the feed. Their machine-local Windows SDK copies are signed
    differently per machine, which caused NU1403 lock-hash mismatches in CI.
  • Harden NuGetRestoreForceEvaluateAllSolutions.ps1: check each restore's exit
    code, strip nuget.org from any node_modules NuGet.Config, and fail loudly
    if a committed lock isn't regenerated.

Feed warming

  • Add @rnw-scripts/warm-feed and a scheduled pipeline that keep the shared
    ms/react-native-public feed warm by re-pulling the latest patch of every
    in-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

  • Publish the npm packages to the ms/react-native-public and ms/react-native
    ADO feeds, matching how the NuGet packages are already published (alongside the
    existing publish to npmjs.com).

prepare-release

Network isolation

  • Replace hardcoded facebook.com image URLs in the tester examples with an
    inline data: URI so the tests don't reach the internet.
  • Disable the Visual Studio Installer background auto-update so it stops calling
    the VS CDN during isolated builds.

Tests

  • Make the creaternwapp e2e test resolve npm versions best-effort instead of
    failing the suite when a preview version isn't published — main publishes
    canary, and preview comes from an in-progress *-stable branch.

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

Copilot AI balanced review requested due to automatic review settings August 20, 2026 03:47

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

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"
Copilot AI review requested due to automatic review settings August 20, 2026 04:16

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 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.yml now contains the same schedule and job, and .ado/README.md:16 still 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 srcSet density 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 missing result means the requested package was not warmed, but only failed results make the command return nonzero. For example, a manually queued --packages npm:foo@typo run logs a warning and succeeds even though it did nothing, so the pipeline cannot reliably report whether the requested version was saved. Treat missing as unsuccessful too.
    packages/@rnw-scripts/warm-feed/src/run.ts:233
  • Registry/authentication and server errors from expandPackage are 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 --only value is ignored, which broadens a mutating command from one requested ecosystem to both npm and NuGet. A typo such as --only npn should fail validation instead of warming more than requested.
    .ado/templates/publish-npm-to-ado-feed.yml:43
  • npm publish defaults to the latest dist-tag. Unlike the existing npmjs job, these ADO jobs do not load or pass NpmDistTag, so publishing a canary/preview release will move the feed's latest tag 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-scripts packages such as integrate-rn/src/test/upgradeDependencies.test.ts and stamp-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
@vmoroz
Vladimir Morozov (vmoroz) merged commit 124897f into microsoft:main Aug 20, 2026
32 checks passed
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
* Address Copilot comments for PR #16379

* Address PR feedback
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.

4 participants