Release/CI pipeline updates + feed warm-up - #16359
Release/CI pipeline updates + feed warm-up#16359Vladimir Morozov (vmoroz) wants to merge 4 commits into
Conversation
There was a problem hiding this comment.
Pull request overview
Updates Azure DevOps CI/release pipelines and introduces scheduled dependency-feed warming.
Changes:
- Updates CI/release triggers, identity, service connection, and network isolation.
- Adds scheduled npm/NuGet feed warming.
- Documents the revised pipeline architecture.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
.ado/ci-pipeline.yml |
Adds branch triggers and heartbeat schedule. |
.ado/release-pipeline.yml |
Updates branches, feed connection, and isolation mode. |
.ado/templates/publish-nuget-to-ado-feed.yml |
Changes the default publishing identity. |
.ado/warm-feed-cache-pipeline.yml |
Defines scheduled authenticated feed warming. |
.ado/README.md |
Documents pipeline and feed changes. |
vnext/Scripts/Warm-RnwFeedCache.ps1 |
Implements npm and NuGet cache warming. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (3)
vnext/Scripts/Warm-RnwFeedCache.ps1:308
- With
-KeepWorkDir, this retains the work directory's.npmrc, which contains the live PAT or AAD token written above. Keeping generated projects for debugging should not leave credentials on disk; remove$npmrcunconditionally before deciding whether to delete the rest of the directory.
if (-not $KeepWorkDir) { Remove-Item -Recurse -Force $WorkDir -ErrorAction SilentlyContinue }
else { Write-Host "`nKept work dir: $WorkDir" -ForegroundColor Yellow }
vnext/Scripts/Warm-RnwFeedCache.ps1:262
Invoke-WebRequesttreats HTTP 202 as a successful response, so thecatchblock's explicit 202 retry path is never reached. The function deletes the response body and reports the package as saved even while Azure Artifacts is still processing it. Capture the response status and retry 202 before returning success.
Invoke-WebRequest -Uri $url -Headers $Headers -OutFile $tmp -ErrorAction Stop | Out-Null
Remove-Item $tmp -Force -ErrorAction SilentlyContinue
return
.ado/warm-feed-cache-pipeline.yml:21
- This schedule only checks out and warms
main, but the public PR pipeline explicitly accepts every*-stabletarget (.ado/pr-pipeline.yml:10-13) and CI now supports 0.81–0.87. Generated projects on those branches have different RN/CLI versions and floating transitive closures, so stable-target PRs can still hit the anonymous-feed failures this pipeline is meant to prevent. Schedule/backport the warmer for each supported branch, or have the main run explicitly warm each supported ref.
branches:
include:
- main
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (4)
.ado/warm-feed-cache-pipeline.yml:58
- This job calls
yarn install, but it only selects Node and never provisions Yarn. The repository's managed-image paths still explicitly install pinned Yarn 1.22.22 because it is not yet guaranteed by the image (.ado/templates/yarn-install.yml:12-19and.ado/build-template.yml:171-176). The scheduled job can therefore fail before warming either npm closure or use an arbitrary agent-installed version. Install the pinned Yarn version after feed authentication, or make the script invoke a pinned Yarn package.
- task: UseNode@1
displayName: Use Node.js 24.x
inputs:
version: '24.x'
vnext/Scripts/Warm-RnwFeedCache.ps1:74
- These defaults duplicate the exact generator/template versions used by
vnext/Scripts/creaternwlib.cmd:122-123andvnext/Scripts/creaternwapp.cmd:118-127. Since this job must reproduce those CLI-init closures, a future version bump in either existing script can silently leave this warmer caching a stale closure. Move these values into shared configuration or a shared generation helper consumed by both paths.
[string]$CreateLibraryVersion = '0.48.9',
[string]$TemplateVersion = '@react-native-community/template@0.84.1',
vnext/Scripts/Warm-RnwFeedCache.ps1:308
- This cleanup is ordinary tail code rather than a
finallyblock, so cancellation, Ctrl+C, or any uncaught terminating error after the.npmrcis written skips it. That can leave a PAT/AAD token in the temporary.npmrc(and local environment overrides in place), despite the “Always remove” claim. Wrap the credential/environment lifetime in an outertry/finallyand perform token-file, environment, and work-directory cleanup infinally.
# Always remove the token-bearing .npmrc so -KeepWorkDir never leaves a credential on disk.
Remove-Item -LiteralPath $npmrc -Force -ErrorAction SilentlyContinue
if (-not $KeepWorkDir) { Remove-Item -Recurse -Force $WorkDir -ErrorAction SilentlyContinue }
vnext/Scripts/Warm-RnwFeedCache.ps1:261
Invoke-WebRequesttreats every 2xx response as success, so an HTTP 202 never reaches the retry condition below; this branch deletes the response file and reports the package saved immediately. Since 202 means the upstream save is still pending, capture the response (using-PassThru) and turn 202 into a retryable failure before returning.
Invoke-WebRequest -Uri $url -Headers $Headers -OutFile $tmp -ErrorAction Stop | Out-Null
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.
Suppressed comments (1)
.ado/ci-pipeline.yml:12
- Azure DevOps evaluates CI triggers from the YAML in the branch being pushed. The existing
0.81-stablebranch still hastrigger: none, so after the documented reviewer action clears the UI override, pushes to that branch will not run CI despite this include. Propagate the YAML trigger change to each supported stable branch before clearing the override, or retain a centrally configured trigger for those branches.
- '0.81-stable'
Description
Type of Change
Why
We must move our CI and Release pipelines to the new
office/ISSADO project and address a number of new safe supply chain related policies.What
1. Release pipeline
.ado/release-pipeline.yml,.ado/templates/publish-nuget-to-ado-feed.ymlsettings.networkIsolationMode: Audit. Release jobs run 1ES Network Isolationin
Enforceby default, which blocksapi.nuget.organd fails the nuget.orgpush.
Auditruns the isolation checks in report-only mode so the pushsucceeds — the same effective behavior as the hermes-windows and
node-api-dotnet release pipelines. The per-domain allow-list is not available
to release jobs, so mode is the only in-pipeline lever (see Follow-ups).
endpointId(
00000000-…) for thems/react-nativefeed with the provisioned ISS serviceconnection
Nuget - ms/react-native(cfe2ce40-…).publish-nuget-to-ado-feed.ymlnow defaultsazureSubscriptiontoOffice-Hermes-Windows-Bot(interim identity; seeFollow-ups).
main+0.81–0.87-stable(dropped end-of-life0.74, added0.86/0.87),matching the CI pipeline.
Validation: a full Release run in
office/ISSpublished all five targets — npm(npmjs.com), the private and public ADO NuGet feeds, nuget.org, and PDB symbols.
The Network Isolation step reported nuget.org under the
CFSCleanpolicy inreport-only mode with no connections blocked.
2. CI pipeline
.ado/ci-pipeline.ymltrigger: none(trigger was configured inthe pipeline UI) with an in-YAML
triggercoveringmain+0.81–0.87-stable. Keeping the trigger in source makes it reviewable andversioned.
(
always: true). Azure DevOps disables long-inactive pipelines; a low-costweekly run keeps the definition enabled.
Reviewer action after merge: clear "Override the YAML continuous integration
trigger from here" in the CI pipeline's Triggers UI so the YAML trigger takes
effect.
3. Feed warm-up pipeline (new)
.ado/warm-feed-cache-pipeline.yml,vnext/Scripts/Warm-RnwFeedCache.ps1Public PR builds run under network isolation and read the
ms/react-native-publicAzure Artifacts feed anonymously. Anonymous readsonly return versions an authenticated identity has already saved, so first-time
transitive dependencies (for example, the
create-react-native-librarytoolchain closure) fail PR restores with 404/500. This pipeline pre-populates the
feed:
Warm-RnwFeedCache.ps1— self-contained script. Warms npm by generating thecRNL library and app projects and running real installs against the
authenticated feed (following the package manager's own resolution); warms
NuGet by downloading every resolved package from the repo's
packages.lock.jsonfiles through the feed's flat2 endpoint. Has skip/overrideswitches and returns non-zero on any failed pass.
warm-feed-cache-pipeline.yml—office/ISSOffice.Unofficialscheduledpipeline (every 6 hours) that runs the script under an authenticated managed
identity (interim
Office-Hermes-Windows-Bot).Validation: local runs against the live feed completed both npm passes and the
NuGet pass, and packages that previously failed anonymous restore resolved
afterward.
Follow-ups
Enforce(compliance).Auditleaves theCFSCleanisolationpolicy reporting nuget.org as non-compliant. Request that
api.nuget.organdwww.nuget.orgbe added to theCFSCleanallow-list for this pipeline, thenremove
settings.networkIsolationMode: Audit.Office-Hermes-Windows-Botwith
Office-React-Native-Windows-Botinpublish-nuget-to-ado-feed.ymlandwarm-feed-cache-pipeline.ymlonce provisioned with feed-push rights.office/ISS, confirm a PR rerun no longerhits anonymous feed 404/500, and revisit the 6-hour cadence after observing
cost.
Changelog
Should this change be included in the release notes: yes
Release/CI pipeline updates + feed warm-up
Microsoft Reviewers: Open in CodeFlow