react-native-windows 0.81.31 → 0.81.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,7 +15,7 @@
15
15
 
16
16
  <!--
17
17
  SourceLink is disabled by default since customer projects are still building our projects and therefore we don't want to force customers to use this.
18
- The PR (windows-vs-pr.yml) and CI (publish.yml() turn it back on.
18
+ In-repo builds (BuildingInRnwRepo=true) turn it back on below.
19
19
  -->
20
20
  <EnableSourceLink Condition="'$(EnableSourceLink)' == '' AND '$(BuildingInRnwRepo)' == 'true'">true</EnableSourceLink>
21
21
  <EnableSourceLink Condition="'$(EnableSourceLink)' == ''">false</EnableSourceLink>
@@ -97,7 +97,7 @@
97
97
  <ForcedIncludeFiles>pch.h</ForcedIncludeFiles>
98
98
  <WarningLevel>Level4</WarningLevel>
99
99
  <AdditionalOptions>%(AdditionalOptions) /bigobj /ZH:SHA_256</AdditionalOptions>
100
- <AdditionalOptions Condition="$(PlatformToolsetVersion)&lt;145">%(AdditionalOptions) /await</AdditionalOptions>
100
+ <AdditionalOptions Condition="'$(PlatformToolsetVersion)' != '' And $(PlatformToolsetVersion)&lt;145">%(AdditionalOptions) /await</AdditionalOptions>
101
101
  <AdditionalIncludeDirectories>
102
102
  $(FmtDir)\include;
103
103
  $(ReactNativeWindowsDir)Microsoft.ReactNative;
@@ -172,8 +172,8 @@
172
172
  source. Scoped to v145+ (the bug does not reproduce on v143); remove
173
173
  when the compiler bug is fixed.
174
174
  -->
175
- <Optimization Condition="$(PlatformToolsetVersion)&gt;=145">Disabled</Optimization>
176
- <WholeProgramOptimization Condition="$(PlatformToolsetVersion)&gt;=145">false</WholeProgramOptimization>
175
+ <Optimization Condition="'$(PlatformToolsetVersion)' != '' And $(PlatformToolsetVersion)&gt;=145">Disabled</Optimization>
176
+ <WholeProgramOptimization Condition="'$(PlatformToolsetVersion)' != '' And $(PlatformToolsetVersion)&gt;=145">false</WholeProgramOptimization>
177
177
  </ClCompile>
178
178
  </ItemGroup>
179
179
  <ItemGroup Condition="'$(BuildMSRNCxxNodeApiJsiLoader)' != 'false'">
@@ -13,17 +13,23 @@ struct AbiCallInvoker final : facebook::react::CallInvoker {
13
13
  AbiCallInvoker(IReactContext const &context) : m_context(context) {}
14
14
 
15
15
  void invokeAsync(facebook::react::CallFunc &&func) noexcept override {
16
- m_context.CallInvoker().InvokeAsync(
17
- [context = m_context, func = std::move(func)](const winrt::Windows::Foundation::IInspectable &runtimeHandle) {
18
- func(GetOrCreateContextRuntime(context, runtimeHandle));
19
- });
16
+ auto callInvoker = m_context.CallInvoker();
17
+ if (callInvoker) {
18
+ callInvoker.InvokeAsync(
19
+ [context = m_context, func = std::move(func)](const winrt::Windows::Foundation::IInspectable &runtimeHandle) {
20
+ func(GetOrCreateContextRuntime(context, runtimeHandle));
21
+ });
22
+ }
20
23
  }
21
24
 
22
25
  void invokeSync(facebook::react::CallFunc &&func) override {
23
- m_context.CallInvoker().InvokeSync(
24
- [context = m_context, func = std::move(func)](const winrt::Windows::Foundation::IInspectable &runtimeHandle) {
25
- func(GetOrCreateContextRuntime(context, runtimeHandle));
26
- });
26
+ auto callInvoker = m_context.CallInvoker();
27
+ if (callInvoker) {
28
+ callInvoker.InvokeSync(
29
+ [context = m_context, func = std::move(func)](const winrt::Windows::Foundation::IInspectable &runtimeHandle) {
30
+ func(GetOrCreateContextRuntime(context, runtimeHandle));
31
+ });
32
+ }
27
33
  }
28
34
 
29
35
  private:
@@ -42,7 +42,7 @@
42
42
  <BundleCliCommand Condition="'$(BundleCliCommand)' == ''">npx @react-native-community/cli bundle</BundleCliCommand>
43
43
 
44
44
  <!-- This should be the app package root, this is where the bundle command will be run from -->
45
- <BundleCommandWorkingDir Condition="'$(BundleCommandWorkingDir)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(ProjectDir), 'package.json'))</BundleCommandWorkingDir>
45
+ <BundleCommandWorkingDir Condition="'$(BundleCommandWorkingDir)' == '' AND '$(ProjectDir)' != ''">$([MSBuild]::GetDirectoryNameOfFileAbove($(ProjectDir), 'package.json'))</BundleCommandWorkingDir>
46
46
 
47
47
  <!-- This timeout is to catch when the bundler hangs and can be increased for larger apps -->
48
48
  <BundleCommandTimeoutMs Condition="'$(BundleCommandTimeoutMs)' == ''">300000</BundleCommandTimeoutMs>
@@ -51,8 +51,8 @@
51
51
  <BundleEntryFile Condition="'$(BundleEntryFile)' == '' and Exists('$(BundleCommandWorkingDir)\index.windows.js')">index.windows.js</BundleEntryFile>
52
52
  <BundleEntryFile Condition="'$(BundleEntryFile)' == ''">index.js</BundleEntryFile>
53
53
 
54
- <FullOutDir Condition="'$([System.IO.Path]::GetFullPath($(OutDir)))' == '$(OutDir)'">$(OutDir)</FullOutDir>
55
- <FullOutDir Condition="'$([System.IO.Path]::GetFullPath($(OutDir)))' != '$(OutDir)'">$(ProjectDir)$(OutDir)</FullOutDir>
54
+ <FullOutDir Condition="'$(OutDir)' != '' AND '$([System.IO.Path]::GetFullPath($(OutDir)))' == '$(OutDir)'">$(OutDir)</FullOutDir>
55
+ <FullOutDir Condition="'$(OutDir)' != '' AND '$([System.IO.Path]::GetFullPath($(OutDir)))' != '$(OutDir)'">$(ProjectDir)$(OutDir)</FullOutDir>
56
56
 
57
57
  <!-- Location where source map file for the JS bundle will be created -->
58
58
  <BundleSourceMapDir Condition="'$(BundleSourceMapDir)' == ''">$([MSBuild]::NormalizePath('$(FullOutDir)\sourcemaps\react'))</BundleSourceMapDir>
@@ -1,9 +1,9 @@
1
1
  <?xml version="1.0" encoding="utf-8"?>
2
2
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3
3
  <!--
4
- CI-specific C++ build optimizations for the publish pipeline.
4
+ CI-specific C++ build optimizations.
5
5
 
6
- This file is injected via /p:ForceImportAfterCppTargets in .ado/publish.yml.
6
+ This file is injected via /p:ForceImportAfterCppTargets by the Desktop and Universal build jobs.
7
7
  It overrides defaults that are tuned for developer workflows (incremental builds,
8
8
  file tracking) with settings that are better for CI clean builds.
9
9
 
@@ -10,11 +10,11 @@
10
10
  -->
11
11
  <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
12
12
  <PropertyGroup>
13
- <ReactNativeWindowsVersion>0.81.31</ReactNativeWindowsVersion>
13
+ <ReactNativeWindowsVersion>0.81.34</ReactNativeWindowsVersion>
14
14
  <ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
15
15
  <ReactNativeWindowsMinor>81</ReactNativeWindowsMinor>
16
- <ReactNativeWindowsPatch>31</ReactNativeWindowsPatch>
16
+ <ReactNativeWindowsPatch>34</ReactNativeWindowsPatch>
17
17
  <ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
18
- <ReactNativeWindowsCommitId>05739f63c54727e6f87c8b282ad84a06866801ec</ReactNativeWindowsCommitId>
18
+ <ReactNativeWindowsCommitId>35af7762b027b96d59fced454b92f7fd10dee6fe</ReactNativeWindowsCommitId>
19
19
  </PropertyGroup>
20
20
  </Project>
@@ -6,7 +6,7 @@
6
6
  <!-- Enabling this will (1) Include hermes glues in the Microsoft.ReactNative binaries AND (2) Make hermes the default engine -->
7
7
  <UseHermes Condition="'$(UseHermes)' == ''">true</UseHermes>
8
8
  <!-- This will be true if (1) the client want to use hermes by setting UseHermes to true OR (2) We are building for UWP where dynamic switching is enabled -->
9
- <HermesVersion Condition="'$(HermesVersion)' == ''">0.0.0-2604.21001-94aa5e1d</HermesVersion>
9
+ <HermesVersion Condition="'$(HermesVersion)' == ''">0.0.0-2608.12001-35d34796</HermesVersion>
10
10
  <HermesPackageName Condition="'$(HermesPackageName)' == ''">Microsoft.JavaScript.Hermes</HermesPackageName>
11
11
  <HermesPackage Condition="'$(HermesPackage)' == '' And Exists('$(PkgMicrosoft_JavaScript_Hermes)')">$(PkgMicrosoft_JavaScript_Hermes)</HermesPackage>
12
12
  <HermesPackage Condition="'$(HermesPackage)' == ''">$(NuGetPackageRoot)\$(HermesPackageName)\$(HermesVersion)</HermesPackage>
@@ -8,7 +8,8 @@
8
8
  -->
9
9
 
10
10
  <PropertyGroup>
11
- <RestoreLockedMode Condition="'$(RestoreLockedMode)'=='' OR '$(BuildingInRnwRepo)'=='true'">true</RestoreLockedMode>
11
+ <!-- Locked vs. force-evaluate is decided centrally in the repo-root Directory.Build.props (force-evaluate locally, locked in CI); don't force locked mode on here or it conflicts with force-evaluate (NU1512). -->
12
+ <RestoreLockedMode Condition="'$(RestoreLockedMode)'==''">false</RestoreLockedMode>
12
13
 
13
14
  <!-- RnwNewArchOnly is for projects that always build with RnwNewArch so they don't add .newarch to the filename. -->
14
15
  <RnwNewArchOnly Condition="'$(RnwNewArchOnly)'=='' AND '$(SolutionName)'=='ReactWindows-Desktop'">true</RnwNewArchOnly>
@@ -139,7 +139,7 @@
139
139
  <RuntimeTypeInfo>true</RuntimeTypeInfo>
140
140
  <ShowIncludes Condition="'$(ShowIncludes)'=='true'">true</ShowIncludes>
141
141
  <AdditionalOptions>/utf-8 %(AdditionalOptions)</AdditionalOptions>
142
- <AdditionalOptions Condition="$(PlatformToolsetVersion)&lt;145">%(AdditionalOptions) /await</AdditionalOptions>
142
+ <AdditionalOptions Condition="'$(PlatformToolsetVersion)' != '' And $(PlatformToolsetVersion)&lt;145">%(AdditionalOptions) /await</AdditionalOptions>
143
143
  <ControlFlowGuard>Guard</ControlFlowGuard>
144
144
  <SpectreMitigation>Spectre</SpectreMitigation>
145
145
 
@@ -7,7 +7,33 @@ param(
7
7
  $StartingLocation = Get-Location
8
8
  Set-Location -Path $RepoRoot
9
9
 
10
+ $failedRestores = [System.Collections.Generic.List[string]]::new()
11
+
12
+ function Restore-Solution([string] $solution, [string[]] $extraArgs) {
13
+ Write-Host "Restoring $solution $($extraArgs -join ' ')"
14
+ & msbuild /t:Restore /p:RestoreForceEvaluate=true @extraArgs $solution
15
+ if ($LASTEXITCODE -ne 0) {
16
+ $failedRestores.Add(("$solution $($extraArgs -join ' ')").Trim())
17
+ }
18
+ }
19
+
10
20
  try {
21
+ # Some node_modules packages ship a NuGet.Config that re-adds the public nuget.org feed. That
22
+ # breaks the repo's single-ADO-feed compliance and trips corporate network blocks on api.nuget.org.
23
+ # Strip any nuget.org source so restore only uses the repo's ADO feed.
24
+ Get-ChildItem -File -Recurse -Path $RepoRoot -Filter NuGet.Config -ErrorAction SilentlyContinue |
25
+ Where-Object { $_.FullName -match '\\node_modules\\' } | ForEach-Object {
26
+ $configPath = $_.FullName
27
+ try { [xml]$doc = Get-Content -LiteralPath $configPath -Raw } catch { return }
28
+ $sources = $doc.SelectSingleNode('/configuration/packageSources')
29
+ if (-not $sources) { return }
30
+ $badSources = @($sources.SelectNodes('add') | Where-Object { $_.GetAttribute('value') -match 'nuget\.org' })
31
+ if ($badSources.Count -eq 0) { return }
32
+ $badSources | ForEach-Object { [void]$sources.RemoveChild($_) }
33
+ $doc.Save($configPath)
34
+ Write-Host "Removed nuget.org feed from $configPath"
35
+ }
36
+
11
37
  if (-not $SkipLockDeletion) {
12
38
  # Delete existing lock files
13
39
  $existingLockFiles = (Get-ChildItem -File -Recurse -Path $RepoRoot -Filter *.lock.json)
@@ -22,17 +48,46 @@ try {
22
48
 
23
49
  # Run all solutions with their defaults
24
50
  $($packagesSolutions; $vnextSolutions) | Foreach-Object {
25
- Write-Host Restoring $_.FullName with defaults
26
- & msbuild /t:Restore /p:RestoreForceEvaluate=true $_.FullName
51
+ Restore-Solution $_.FullName @()
27
52
  }
28
53
 
29
54
  # Re-run solutions that build with UseExperimentalWinUI3
30
- $experimentalSolutions = @("playground-composition.sln", "Microsoft.ReactNative.NewArch.sln", "ReactWindows-Desktop.sln");
55
+ $experimentalSolutions = @("playground-composition.sln", "Microsoft.ReactNative.sln", "Microsoft.ReactNative.NewArch.sln", "ReactWindows-Desktop.sln");
31
56
  $($packagesSolutions; $vnextSolutions) | Where-Object { $experimentalSolutions -contains $_.Name } | Foreach-Object {
32
- Write-Host Restoring $_.FullName with UseExperimentalWinUI3=true
33
- & msbuild /t:Restore /p:RestoreForceEvaluate=true /p:UseExperimentalWinUI3=true $_.FullName
57
+ Restore-Solution $_.FullName @('/p:UseExperimentalWinUI3=true')
58
+ }
59
+
60
+ # Re-run solutions that build with Chakra (UseHermes=false)
61
+ $chakraSolutions = @("ReactUWPTestApp.sln", "integrationtest.sln");
62
+ $($packagesSolutions; $vnextSolutions) | Where-Object { $chakraSolutions -contains $_.Name } | Foreach-Object {
63
+ Restore-Solution $_.FullName @('/p:UseHermes=false')
34
64
  }
35
65
  }
36
66
  finally {
37
67
  Set-Location -Path "$StartingLocation"
38
- }
68
+ }
69
+
70
+ # Restore failures used to be ignored (msbuild's exit code was never checked), so a broken run
71
+ # looked successful while leaving lock files deleted. Fail loudly on both failure modes.
72
+ if ($failedRestores.Count -gt 0) {
73
+ Write-Host ''
74
+ Write-Host "ERROR: NuGet restore returned a non-zero exit code for $($failedRestores.Count) solution pass(es):" -ForegroundColor Red
75
+ $failedRestores | ForEach-Object { Write-Host " $_" -ForegroundColor Red }
76
+ }
77
+
78
+ # A committed lock that was deleted but never came back means a project failed or was skipped during restore.
79
+ $missingTrackedLocks = @(git -C $RepoRoot ls-files -- '*.lock.json' | Where-Object { -not (Test-Path (Join-Path $RepoRoot $_)) })
80
+ if ($missingTrackedLocks.Count -gt 0) {
81
+ Write-Host ''
82
+ Write-Host "ERROR: $($missingTrackedLocks.Count) committed lock file(s) were deleted but not regenerated:" -ForegroundColor Red
83
+ $missingTrackedLocks | ForEach-Object { Write-Host " $_" -ForegroundColor Red }
84
+ }
85
+
86
+ if ($failedRestores.Count -gt 0 -or $missingTrackedLocks.Count -gt 0) {
87
+ Write-Host ''
88
+ Write-Host 'Lock file regeneration is INCOMPLETE - do not commit. Fix the errors above and re-run.' -ForegroundColor Red
89
+ exit 1
90
+ }
91
+
92
+ Write-Host ''
93
+ Write-Host 'All solutions restored and every committed lock file was regenerated.' -ForegroundColor Green
@@ -0,0 +1,413 @@
1
+ #!/usr/bin/env pwsh
2
+ <#
3
+ .SYNOPSIS
4
+ Warm the ms/react-native-public Azure Artifacts feed with the npm and NuGet
5
+ packages the React Native Windows CI and CLI-init tests need.
6
+
7
+ .DESCRIPTION
8
+ Public PR builds read the feed anonymously, and an Azure Artifacts upstream feed
9
+ only serves a version once it has been *saved* (pulled through by an authenticated
10
+ request). Any not-yet-saved transitive dependency therefore 404s on a PR build,
11
+ e.g. the CLI lib job failing on 'is-unc-path'.
12
+
13
+ The script warms several ways, all with your credentials:
14
+ - repo: it runs an authenticated `yarn install` in this repo, pulling the repo's
15
+ own dev-dependency closure (including package.json resolutions, so freshly bumped
16
+ versions are saved) through the feed. This is the closure an anonymous PR build of
17
+ the repo restores.
18
+ - npm: it reproduces the base project generations the CLI-init tests run (a
19
+ create-react-native-library lib and a community-CLI app) and installs them, which
20
+ pulls the whole toolchain closure into the feed.
21
+ - NuGet: it downloads every package in the repo's packages.lock.json files (the
22
+ full resolved closure, incl. transitives) via the feed's flat2 endpoint.
23
+
24
+ Saving is idempotent, so re-warming is a no-op.
25
+
26
+ Auth (in order): -Pat / $env:ADO_PAT / $env:AZURE_DEVOPS_EXT_PAT, else an AAD token
27
+ from `az account get-access-token` (requires `az login` locally, or an AzureCLI@2
28
+ task with a managed identity in a pipeline). The token reaches npm and Yarn only
29
+ through environment variables and a throwaway work-dir npmrc; your ~/.npmrc and
30
+ ~/.yarnrc.yml are never modified.
31
+
32
+ Run it manually from a clone, or on a schedule from the ADO warm-up pipeline. Only
33
+ the repo pass touches your checkout (it refreshes node_modules and yarn.lock in
34
+ place); every other pass works in a throwaway work dir.
35
+
36
+ .PARAMETER NpmRegistry
37
+ The feed npm registry to warm. Defaults to ms/react-native-public.
38
+
39
+ .PARAMETER NuGetIndex
40
+ The feed NuGet v3 index.json to warm. Defaults to ms/react-native-public.
41
+
42
+ .PARAMETER Pat
43
+ Optional ADO PAT (Packaging: Read on the feed's org). Falls back to env vars, then az.
44
+
45
+ .PARAMETER WorkDir
46
+ Directory for the throwaway generated projects. Defaults to a new temp folder.
47
+
48
+ .PARAMETER ReactNativeVersion
49
+ react-native version to generate against. Defaults to vnext/package.json.
50
+
51
+ .PARAMETER CliVersion
52
+ @react-native-community/cli version. Defaults to vnext/package.json.
53
+
54
+ .PARAMETER SkipRepo
55
+ Skip the repo warm pass (an authenticated `yarn install` in this repo). Unlike the
56
+ other passes it refreshes node_modules and yarn.lock in your checkout.
57
+
58
+ .PARAMETER SkipLib
59
+ Skip the create-react-native-library warm pass.
60
+
61
+ .PARAMETER SkipApp
62
+ Skip the community-CLI app warm pass.
63
+
64
+ .PARAMETER SkipNuGet
65
+ Skip the NuGet warm pass.
66
+
67
+ .PARAMETER SkipRnwPackages
68
+ Skip warming the repo's own already-published workspace packages into the feed.
69
+
70
+ .PARAMETER KeepWorkDir
71
+ Keep the work dir instead of deleting it (for debugging).
72
+
73
+ .EXAMPLE
74
+ ./Warm-RnwFeedCache.ps1
75
+
76
+ .EXAMPLE
77
+ # Warm against explicit versions and keep the generated projects to inspect:
78
+ ./Warm-RnwFeedCache.ps1 -ReactNativeVersion 0.85.0-nightly-20260303-c26dbe286 -KeepWorkDir
79
+ #>
80
+ [CmdletBinding()]
81
+ param(
82
+ [string]$NpmRegistry = 'https://pkgs.dev.azure.com/ms/react-native/_packaging/react-native-public/npm/registry/',
83
+ [string]$Pat,
84
+ [string]$WorkDir,
85
+ [string]$ReactNativeVersion,
86
+ [string]$CliVersion,
87
+ # CODESYNC: keep in step with vnext/Scripts/creaternwlib.cmd and creaternwapp.cmd,
88
+ # so the warm run reproduces the same generator/template versions the CLI-init tests use.
89
+ [string]$CreateLibraryVersion = '0.48.9',
90
+ [string]$TemplateVersion = '@react-native-community/template@0.84.1',
91
+ [string]$NuGetIndex = 'https://pkgs.dev.azure.com/ms/react-native/_packaging/react-native-public/nuget/v3/index.json',
92
+ [switch]$SkipRepo,
93
+ [switch]$SkipLib,
94
+ [switch]$SkipApp,
95
+ [switch]$SkipNuGet,
96
+ [switch]$SkipRnwPackages,
97
+ [switch]$KeepWorkDir
98
+ )
99
+
100
+ Set-StrictMode -Version Latest
101
+ $ErrorActionPreference = 'Stop'
102
+
103
+ # Azure DevOps resource id for AAD access tokens.
104
+ $AdoResourceId = '499b84ac-1321-427f-aa17-267ca6975798'
105
+ $RepoRoot = (Resolve-Path "$PSScriptRoot\..\..").Path
106
+ $UpdateNightly = Join-Path $RepoRoot 'vnext\Scripts\UpdateNightlyDependencies.ps1'
107
+
108
+ function Get-FeedToken {
109
+ param([string]$Pat)
110
+ $token = $Pat
111
+ if (-not $token) { $token = $env:ADO_PAT }
112
+ if (-not $token) { $token = $env:AZURE_DEVOPS_EXT_PAT }
113
+ if ($token) { return [pscustomobject]@{ Token = $token; Kind = 'pat' } }
114
+ $az = Get-Command az -CommandType Application -ErrorAction SilentlyContinue
115
+ if ($az) {
116
+ $aad = & az account get-access-token --resource $AdoResourceId --query accessToken -o tsv 2>$null
117
+ if ($LASTEXITCODE -eq 0 -and $aad) { return [pscustomobject]@{ Token = $aad.Trim(); Kind = 'aad' } }
118
+ }
119
+ throw "No Azure DevOps auth available. Run 'az login', or pass -Pat / set `$env:ADO_PAT."
120
+ }
121
+
122
+ function Get-RepoVersion {
123
+ param([object]$Pkg, [string]$Section, [string]$Name, [string]$Override)
124
+ if ($Override) { return $Override }
125
+ $deps = $Pkg.$Section
126
+ if ($deps) {
127
+ $prop = $deps.PSObject.Properties | Where-Object { $_.Name -eq $Name } | Select-Object -First 1
128
+ if ($prop) { return [string]$prop.Value }
129
+ }
130
+ throw "Could not find '$Name' in vnext/package.json '$Section'. Pass it explicitly."
131
+ }
132
+
133
+ function Invoke-Checked {
134
+ param([scriptblock]$Script, [string]$What)
135
+ & $Script
136
+ if ($LASTEXITCODE -ne 0) { throw "$What failed (exit $LASTEXITCODE)." }
137
+ }
138
+
139
+ # --- auth + versions ----------------------------------------------------------
140
+
141
+ $token = Get-FeedToken -Pat $Pat
142
+ $pkg = Get-Content (Join-Path $RepoRoot 'vnext\package.json') -Raw | ConvertFrom-Json
143
+ $rnVersion = Get-RepoVersion -Pkg $pkg -Section 'devDependencies' -Name 'react-native' -Override $ReactNativeVersion
144
+ $cliVersion = Get-RepoVersion -Pkg $pkg -Section 'dependencies' -Name '@react-native-community/cli' -Override $CliVersion
145
+ $isNightly = $rnVersion -match 'nightly'
146
+
147
+ if (-not $WorkDir) { $WorkDir = Join-Path ([IO.Path]::GetTempPath()) "rnw-warm-$(Get-Random)" }
148
+ # Refuse a pre-existing directory: cleanup deletes $WorkDir recursively, so it must be one we created.
149
+ if (Test-Path -LiteralPath $WorkDir) {
150
+ throw "WorkDir '$WorkDir' already exists. Pass a path that does not exist so cleanup only deletes what this script creates."
151
+ }
152
+ New-Item -ItemType Directory -Path $WorkDir | Out-Null
153
+
154
+ Write-Host "Feed: $NpmRegistry" -ForegroundColor Cyan
155
+ Write-Host "react-native: $rnVersion" -ForegroundColor Cyan
156
+ Write-Host "cli: $cliVersion" -ForegroundColor Cyan
157
+ Write-Host "Work dir: $WorkDir" -ForegroundColor Cyan
158
+
159
+ # Point npm/npx and Yarn (classic + berry) at the feed with our token, via a
160
+ # work-dir-local npm config so the caller's ~/.npmrc is untouched. $npmrc and
161
+ # $savedEnv are declared before the try so the finally can always undo them.
162
+ $npmrc = Join-Path $WorkDir '.npmrc'
163
+ $savedEnv = @{}
164
+ try {
165
+ $registryKey = ($NpmRegistry -replace '^https?:', '')
166
+ Set-Content -LiteralPath $npmrc -Encoding ascii -Value @(
167
+ "registry=$NpmRegistry"
168
+ "${registryKey}:_authToken=$($token.Token)"
169
+ 'always-auth=true'
170
+ )
171
+
172
+ foreach ($kv in @{
173
+ NPM_CONFIG_USERCONFIG = $npmrc
174
+ NPM_CONFIG_REGISTRY = $NpmRegistry
175
+ YARN_NPM_REGISTRY_SERVER = $NpmRegistry
176
+ YARN_NPM_ALWAYS_AUTH = 'true'
177
+ YARN_NPM_AUTH_TOKEN = $token.Token
178
+ YARN_ENABLE_IMMUTABLE_INSTALLS = 'false'
179
+ }.GetEnumerator()) {
180
+ $savedEnv[$kv.Key] = [Environment]::GetEnvironmentVariable($kv.Key)
181
+ Set-Item "env:$($kv.Key)" $kv.Value
182
+ }
183
+
184
+ function Update-NightlyPackageJson {
185
+ param([string]$PackageJsonPath)
186
+ # UpdateNightlyDependencies.ps1 throws on error (ErrorActionPreference=Stop); no exit code to check.
187
+ if (-not $isNightly) { return }
188
+ & $UpdateNightly -PackageJsonPath $PackageJsonPath -ReactNativeVersion $rnVersion -ReactNativeCliVersion $cliVersion
189
+ }
190
+
191
+ # --- warm passes --------------------------------------------------------------
192
+
193
+ function Warm-Repo {
194
+ # Authenticated install of the repo warms its whole dev closure (incl. resolutions)
195
+ # and refreshes yarn.lock; --mode=skip-build avoids the repo's postinstall build.
196
+ Push-Location $RepoRoot
197
+ try {
198
+ Invoke-Checked -What 'yarn install (repo)' -Script { & yarn install --mode=skip-build }
199
+ }
200
+ finally { Pop-Location }
201
+ }
202
+
203
+ function Warm-Lib {
204
+ Push-Location $WorkDir
205
+ try {
206
+ Invoke-Checked -What 'create-react-native-library' -Script {
207
+ & npx --yes "create-react-native-library@$CreateLibraryVersion" `
208
+ --slug warmlib --description warmlib `
209
+ --author-name 'React-Native-Windows Bot' `
210
+ --author-email '53619745+rnbot@users.noreply.github.com' `
211
+ --author-url 'http://example.com' --repo-url 'http://example.com' `
212
+ --languages kotlin-objc --local false --type turbo-module `
213
+ --react-native-version $rnVersion --example vanilla warmlib
214
+ }
215
+ Push-Location (Join-Path $WorkDir 'warmlib')
216
+ try {
217
+ Update-NightlyPackageJson -PackageJsonPath 'package.json'
218
+ if (Test-Path 'example\package.json') { Update-NightlyPackageJson -PackageJsonPath 'example\package.json' }
219
+ Invoke-Checked -What 'yarn install (lib)' -Script { & yarn install }
220
+ }
221
+ finally { Pop-Location }
222
+ }
223
+ finally { Pop-Location }
224
+ }
225
+
226
+ function Warm-App {
227
+ Push-Location $WorkDir
228
+ try {
229
+ Invoke-Checked -What 'react-native init (app)' -Script {
230
+ $templateArgs = if ($isNightly) { @('--template', $TemplateVersion) } else { @() }
231
+ & npx --yes "@react-native-community/cli@$cliVersion" init warmapp `
232
+ --version $rnVersion @templateArgs --skip-install --install-pods false --skip-git-init true
233
+ }
234
+ Push-Location (Join-Path $WorkDir 'warmapp')
235
+ try {
236
+ Update-NightlyPackageJson -PackageJsonPath 'package.json'
237
+ Invoke-Checked -What 'yarn install (app)' -Script { & yarn install }
238
+ }
239
+ finally { Pop-Location }
240
+ }
241
+ finally { Pop-Location }
242
+ }
243
+
244
+ # NuGet warm: save the resolved closure (packages.lock.json, incl. transitives)
245
+ # from upstream into the feed via authenticated flat2 downloads. No VS/msbuild needed.
246
+ function Get-NuGetAuthHeader {
247
+ param([object]$Token)
248
+ if ($Token.Kind -eq 'pat') {
249
+ $basic = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($Token.Token)"))
250
+ return @{ Authorization = "Basic $basic" }
251
+ }
252
+ return @{ Authorization = "Bearer $($Token.Token)" }
253
+ }
254
+
255
+ function Get-Flat2Base {
256
+ param([string]$IndexUrl, [hashtable]$Headers)
257
+ $index = Invoke-RestMethod -Uri $IndexUrl -Headers $Headers
258
+ $res = $index.resources | Where-Object { $_.'@type' -match '^PackageBaseAddress' } | Select-Object -First 1
259
+ if (-not $res) { throw "NuGet index has no PackageBaseAddress (flat2) resource: $IndexUrl" }
260
+ return ($res.'@id').TrimEnd('/')
261
+ }
262
+
263
+ function Get-NuGetRefsFromLockFiles {
264
+ $refs = @{}
265
+ $lockFiles = Get-ChildItem -Recurse -File -Filter packages.lock.json -Path $RepoRoot -ErrorAction SilentlyContinue |
266
+ Where-Object { $_.FullName -notmatch '[\\/]node_modules[\\/]' }
267
+ foreach ($lf in $lockFiles) {
268
+ $json = Get-Content -LiteralPath $lf.FullName -Raw | ConvertFrom-Json
269
+ if (-not $json.PSObject.Properties['dependencies']) { continue }
270
+ foreach ($framework in $json.dependencies.PSObject.Properties) {
271
+ foreach ($dep in $framework.Value.PSObject.Properties) {
272
+ $info = $dep.Value
273
+ if ($info.type -eq 'Project') { continue }
274
+ if (-not $info.PSObject.Properties['resolved']) { continue }
275
+ $refs["$($dep.Name)|$($info.resolved)"] = [pscustomobject]@{ Id = $dep.Name; Version = [string]$info.resolved }
276
+ }
277
+ }
278
+ }
279
+ return @($refs.Values | Sort-Object Id, Version)
280
+ }
281
+
282
+ function Save-UpstreamNupkg {
283
+ param([string]$Id, [string]$Version, [string]$Flat2Base, [hashtable]$Headers, [int]$MaxAttempts = 4)
284
+ $idLower = $Id.ToLowerInvariant(); $verLower = $Version.ToLowerInvariant()
285
+ $url = "$Flat2Base/$idLower/$verLower/$idLower.$verLower.nupkg"
286
+ $tmp = Join-Path $WorkDir "nuget-$idLower.$verLower.nupkg"
287
+ $lastError = 'unknown error'
288
+ for ($attempt = 1; $attempt -le $MaxAttempts; $attempt++) {
289
+ $retryable = $true
290
+ try {
291
+ # -PassThru returns the response even with -OutFile, so a 202 is visible here
292
+ # (a 2xx never throws, so the old catch reported a still-pending 202 as saved).
293
+ $resp = Invoke-WebRequest -Uri $url -Headers $Headers -OutFile $tmp -PassThru -ErrorAction Stop
294
+ Remove-Item $tmp -Force -ErrorAction SilentlyContinue
295
+ # 202 = Azure Artifacts is still saving the upstream package; not available yet, so retry.
296
+ if ([int]$resp.StatusCode -ne 202) { return }
297
+ $lastError = 'HTTP 202 (upstream save still pending)'
298
+ }
299
+ catch {
300
+ $code = $null; try { $code = [int]$_.Exception.Response.StatusCode } catch { }
301
+ $lastError = if ($code) { "HTTP $code" } else { $_.Exception.Message }
302
+ $retryable = ($null -eq $code -or $code -in 404, 408, 429, 500, 502, 503, 504)
303
+ }
304
+ if (-not $retryable) { break }
305
+ if ($attempt -lt $MaxAttempts) { Start-Sleep -Seconds ([Math]::Min(2 * $attempt, 10)) }
306
+ }
307
+ throw "$Id $Version ($lastError)"
308
+ }
309
+
310
+ function Warm-NuGet {
311
+ $refs = Get-NuGetRefsFromLockFiles
312
+ if ($refs.Count -eq 0) { Write-Host 'No packages.lock.json entries found.' -ForegroundColor Yellow; return }
313
+ $headers = Get-NuGetAuthHeader -Token $token
314
+ $flat2 = Get-Flat2Base -IndexUrl $NuGetIndex -Headers $headers
315
+ Write-Host "Saving $($refs.Count) NuGet package(s) via $flat2" -ForegroundColor Cyan
316
+ $failures = @()
317
+ foreach ($r in $refs) {
318
+ try { Save-UpstreamNupkg -Id $r.Id -Version $r.Version -Flat2Base $flat2 -Headers $headers }
319
+ catch { $failures += $_.Exception.Message }
320
+ }
321
+ if ($failures.Count) { throw "$($failures.Count)/$($refs.Count) NuGet package(s) failed: $($failures -join '; ')" }
322
+ Write-Host "Saved $($refs.Count) NuGet package(s)." -ForegroundColor Green
323
+ }
324
+
325
+ # The CLI-init tests install react-native-windows, whose closure pulls the repo's own already-published
326
+ # workspace packages (e.g. @react-native-windows/package-utils). Verdaccio publishes only the *changed*
327
+ # packages locally and proxies the rest to the feed, so anonymous PR reads 404/500 unless those
328
+ # published versions are cached. CODESYNC: enumerates the same workspaces npmPack.js packs; the subset
329
+ # it strips with --check-npm (already on npmjs) is exactly what a PR build must read from the feed.
330
+ function Warm-RnwPackages {
331
+ $dir = Join-Path $WorkDir 'rnwpkgs'
332
+ New-Item -ItemType Directory -Path $dir | Out-Null
333
+
334
+ $rootPkg = Get-Content (Join-Path $RepoRoot 'package.json') -Raw | ConvertFrom-Json
335
+ $seen = [System.Collections.Generic.HashSet[string]]::new()
336
+ $specs = [System.Collections.Generic.List[string]]::new()
337
+ foreach ($pattern in $rootPkg.workspaces.packages) {
338
+ $pkgDirs = @()
339
+ if ($pattern.EndsWith('/*')) {
340
+ $base = Join-Path $RepoRoot ($pattern.Substring(0, $pattern.Length - 2))
341
+ if (Test-Path -LiteralPath $base) { $pkgDirs = @((Get-ChildItem -LiteralPath $base -Directory).FullName) }
342
+ }
343
+ else { $pkgDirs = @(Join-Path $RepoRoot $pattern) }
344
+ foreach ($d in $pkgDirs) {
345
+ $pj = Join-Path $d 'package.json'
346
+ if (-not (Test-Path -LiteralPath $pj)) { continue }
347
+ $p = Get-Content -LiteralPath $pj -Raw | ConvertFrom-Json
348
+ $props = $p.PSObject.Properties
349
+ if (($props['private'] -and $p.private -eq $true) -or -not $props['name'] -or -not $props['version']) { continue }
350
+ $spec = "$($p.name)@$($p.version)"
351
+ if ($seen.Add($spec)) { $specs.Add($spec) }
352
+ }
353
+ }
354
+
355
+ Push-Location $dir
356
+ try {
357
+ # Skip versions not yet on the feed's upstream: the build's freshly bumped packages aren't published
358
+ # and the CLI test gets those from verdaccio locally, so a miss here is expected (not a failure).
359
+ $published = foreach ($spec in $specs) {
360
+ try { & npm view $spec version *> $null; if ($LASTEXITCODE -eq 0) { $spec } } catch { }
361
+ }
362
+ $published = @($published)
363
+ if ($published.Count -eq 0) {
364
+ Write-Host 'No already-published workspace packages to warm.' -ForegroundColor Yellow
365
+ return
366
+ }
367
+ Write-Host "Warming $($published.Count)/$($specs.Count) workspace package(s) into the feed." -ForegroundColor Cyan
368
+ Invoke-Checked -What 'warm RNW packages' -Script {
369
+ & npm install --ignore-scripts @published
370
+ }
371
+ }
372
+ finally { Pop-Location }
373
+ }
374
+
375
+ $passes = [ordered]@{}
376
+ if (-not $SkipRepo) { $passes['repo'] = ${function:Warm-Repo} }
377
+ if (-not $SkipLib) { $passes['lib'] = ${function:Warm-Lib} }
378
+ if (-not $SkipApp) { $passes['app'] = ${function:Warm-App} }
379
+ if (-not $SkipNuGet) { $passes['nuget'] = ${function:Warm-NuGet} }
380
+ if (-not $SkipRnwPackages) { $passes['rnwpackages'] = ${function:Warm-RnwPackages} }
381
+
382
+ # Run each pass "bare" (no pipe/capture) so npm/yarn inherits the console: real TTY -> live progress, UTF-8 -> no mojibake.
383
+ $results = [System.Collections.Generic.List[object]]::new()
384
+ foreach ($name in $passes.Keys) {
385
+ Write-Host "`n=== Warming '$name' ===" -ForegroundColor Green
386
+ try { & $passes[$name]; $results.Add([pscustomobject]@{ Pass = $name; Status = 'OK' }) }
387
+ catch { Write-Host "##[error]$($_.Exception.Message)" -ForegroundColor Red; $results.Add([pscustomobject]@{ Pass = $name; Status = "FAILED: $($_.Exception.Message)" }) }
388
+ }
389
+
390
+ # --- cleanup + summary --------------------------------------------------------
391
+ }
392
+ finally {
393
+ # Runs even on Ctrl+C or an uncaught error, so the token file and env overrides never linger.
394
+ foreach ($k in $savedEnv.Keys) {
395
+ if ($null -eq $savedEnv[$k]) { Remove-Item "env:$k" -ErrorAction SilentlyContinue }
396
+ else { Set-Item "env:$k" $savedEnv[$k] }
397
+ }
398
+ Remove-Item -LiteralPath $npmrc -Force -ErrorAction SilentlyContinue
399
+ if (-not $KeepWorkDir) { Remove-Item -Recurse -Force $WorkDir -ErrorAction SilentlyContinue }
400
+ else { Write-Host "`nKept work dir: $WorkDir" -ForegroundColor Yellow }
401
+ }
402
+
403
+ $results = @($results)
404
+ Write-Host ''
405
+ if ($results.Count -eq 0) { Write-Host 'Nothing warmed (all passes skipped).' -ForegroundColor Yellow; exit 0 }
406
+ $results | Format-Table -AutoSize Pass, Status | Out-Host
407
+
408
+ $failed = @($results | Where-Object { $_.Status -ne 'OK' })
409
+ if ($failed.Count) {
410
+ Write-Host "$($failed.Count) of $($results.Count) warm pass(es) failed. A failed authenticated install usually means a package is missing upstream or the feed is unhealthy." -ForegroundColor Red
411
+ exit 1
412
+ }
413
+ Write-Host "Feed warmed. Anonymous PR builds should now restore these closures." -ForegroundColor Green
@@ -72,6 +72,9 @@ if not "%part%"=="" (
72
72
 
73
73
  if %USE_VERDACCIO% equ 1 (
74
74
  @echo creaternwapp.cmd: Setting npm to use verdaccio at http://localhost:4873
75
+ set NPM_CONFIG_REGISTRY=http://localhost:4873
76
+ set YARN_NPM_REGISTRY_SERVER=http://localhost:4873
77
+ set YARN_UNSAFE_HTTP_WHITELIST=localhost
75
78
  call npm config set registry http://localhost:4873
76
79
  )
77
80
 
@@ -143,12 +146,13 @@ call yarn install
143
146
 
144
147
  @echo creaternwapp.cmd: Creating commit to save current state
145
148
  if not exist ".git\" call git init .
149
+ call git config user.name "React-Native-Windows Bot"
150
+ call git config user.email "53619745+rnbot@users.noreply.github.com"
146
151
  call git add .
147
152
  call git commit -m "npx --yes @react-native-community/cli@%RNCLI_VERSION% init %APP_NAME% --version %RN_VERSION% %RNCLI_TEMPLATE% --verbose --skip-install --install-pods false --skip-git-init true"
148
153
 
149
154
  if %USE_VERDACCIO% equ 1 (
150
155
  @echo creaternwapp.cmd: Setting yarn to use verdaccio at http://localhost:4873
151
- call yarn config set registry http://localhost:4873
152
156
  call yarn config set npmRegistryServer http://localhost:4873
153
157
  call yarn config set unsafeHttpWhitelist --json "[\"localhost\"]"
154
158
  )
@@ -77,6 +77,9 @@ if not "%part%"=="" (
77
77
 
78
78
  if %USE_VERDACCIO% equ 1 (
79
79
  @echo creaternwlib.cmd: Setting npm to use verdaccio at http://localhost:4873
80
+ set NPM_CONFIG_REGISTRY=http://localhost:4873
81
+ set YARN_NPM_REGISTRY_SERVER=http://localhost:4873
82
+ set YARN_UNSAFE_HTTP_WHITELIST=localhost
80
83
  call npm config set registry http://localhost:4873
81
84
  )
82
85
 
@@ -141,9 +144,11 @@ if not "x%RN_VERSION:nightly=%"=="x%RN_VERSION%" (
141
144
  @echo creaternwlib.cmd: Calling yarn install
142
145
  call yarn install
143
146
 
147
+ call git config user.name "React-Native-Windows Bot"
148
+ call git config user.email "53619745+rnbot@users.noreply.github.com"
149
+
144
150
  if %USE_VERDACCIO% equ 1 (
145
151
  @echo creaternwlib.cmd: Setting yarn to use verdaccio at http://localhost:4873
146
- call yarn config set registry http://localhost:4873
147
152
  call yarn config set npmRegistryServer http://localhost:4873
148
153
  call yarn config set unsafeHttpWhitelist --json "[\"localhost\"]"
149
154
  )
@@ -162,7 +167,8 @@ call yarn install
162
167
 
163
168
  @echo creaternwlib.cmd Creating commit to save current state
164
169
  call git add .
165
- call git commit -m "chore: add rnw dependency"
170
+ rem --no-verify skips the generated project's lefthook hooks (run via bash, absent on Windows agents)
171
+ call git commit --no-verify -m "chore: add rnw dependency"
166
172
 
167
173
  @echo creaternwlib.cmd Running init-windows with: yarn react-native init-windows --template %RNW_TEMPLATE_TYPE% --overwrite --logging
168
174
  call yarn react-native init-windows --template %RNW_TEMPLATE_TYPE% --overwrite --logging
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-windows",
3
- "version": "0.81.31",
3
+ "version": "0.81.34",
4
4
  "license": "MIT",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,7 +26,7 @@
26
26
  "@react-native-community/cli": "17.0.0",
27
27
  "@react-native-community/cli-platform-android": "17.0.0",
28
28
  "@react-native-community/cli-platform-ios": "17.0.0",
29
- "@react-native-windows/cli": "0.81.6",
29
+ "@react-native-windows/cli": "0.81.8",
30
30
  "@react-native/assets": "1.0.0",
31
31
  "@react-native/assets-registry": "0.81.6",
32
32
  "@react-native/codegen": "0.81.6",
@@ -68,10 +68,10 @@
68
68
  "yargs": "^17.6.2"
69
69
  },
70
70
  "devDependencies": {
71
- "@react-native-windows/codegen": "0.81.6",
71
+ "@react-native-windows/codegen": "0.81.7",
72
72
  "@react-native/metro-config": "0.81.6",
73
73
  "@rnw-scripts/babel-react-native-config": "0.0.0",
74
- "@rnw-scripts/eslint-config": "1.2.37",
74
+ "@rnw-scripts/eslint-config": "1.2.38",
75
75
  "@rnw-scripts/jest-out-of-tree-snapshot-resolver": "^1.1.41",
76
76
  "@rnw-scripts/just-task": "2.3.56",
77
77
  "@rnw-scripts/metro-dev-config": "0.0.0",
@@ -85,7 +85,7 @@
85
85
  "prettier": "2.8.8",
86
86
  "react": "19.1.4",
87
87
  "react-native": "0.81.6",
88
- "react-native-platform-override": "0.81.2",
88
+ "react-native-platform-override": "0.81.3",
89
89
  "react-refresh": "^0.14.0",
90
90
  "typescript": "5.0.4"
91
91
  },