Skip to content

Release/CI pipeline updates + feed warm-up - #16359

Open
Vladimir Morozov (vmoroz) wants to merge 4 commits into
microsoft:mainfrom
vmoroz:PR/move-release-pipeline
Open

Release/CI pipeline updates + feed warm-up#16359
Vladimir Morozov (vmoroz) wants to merge 4 commits into
microsoft:mainfrom
vmoroz:PR/move-release-pipeline

Conversation

@vmoroz

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

Copy link
Copy Markdown
Member

Description

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • Automation (AI changes or Github Actions to reduce effort of manual tasks)

Why

We must move our CI and Release pipelines to the new office/ISS ADO 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.yml

  • nuget.org egress under network isolation. Added
    settings.networkIsolationMode: Audit. Release jobs run 1ES Network Isolation
    in Enforce by default, which blocks api.nuget.org and fails the nuget.org
    push. Audit runs the isolation checks in report-only mode so the push
    succeeds — 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).
  • Private NuGet feed connection. Replaced the placeholder endpointId
    (00000000-…) for the ms/react-native feed with the provisioned ISS service
    connection Nuget - ms/react-native (cfe2ce40-…).
  • Publish identity. publish-nuget-to-ado-feed.yml now defaults
    azureSubscription to Office-Hermes-Windows-Bot (interim identity; see
    Follow-ups).
  • Trigger branches. CI-completion trigger now covers main +
    0.810.87-stable (dropped end-of-life 0.74, added 0.86/0.87),
    matching the CI pipeline.

Validation: a full Release run in office/ISS published 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 CFSClean policy in
report-only mode with no connections blocked.

2. CI pipeline

.ado/ci-pipeline.yml

  • YAML-driven trigger. Replaced trigger: none (trigger was configured in
    the pipeline UI) with an in-YAML trigger covering main +
    0.810.87-stable. Keeping the trigger in source makes it reviewable and
    versioned.
  • Weekly heartbeat schedule. Added a Monday ~02:00 Pacific run
    (always: true). Azure DevOps disables long-inactive pipelines; a low-cost
    weekly 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.ps1

Public PR builds run under network isolation and read the
ms/react-native-public Azure Artifacts feed anonymously. Anonymous reads
only return versions an authenticated identity has already saved, so first-time
transitive dependencies (for example, the create-react-native-library
toolchain closure) fail PR restores with 404/500. This pipeline pre-populates the
feed:

  • Warm-RnwFeedCache.ps1 — self-contained script. Warms npm by generating the
    cRNL 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.json files through the feed's flat2 endpoint. Has skip/override
    switches and returns non-zero on any failed pass.
  • warm-feed-cache-pipeline.ymloffice/ISS Office.Unofficial scheduled
    pipeline (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

  • Return to Enforce (compliance). Audit leaves the CFSClean isolation
    policy reporting nuget.org as non-compliant. Request that api.nuget.org and
    www.nuget.org be added to the CFSClean allow-list for this pipeline, then
    remove settings.networkIsolationMode: Audit.
  • Dedicated managed identity. Replace the interim Office-Hermes-Windows-Bot
    with Office-React-Native-Windows-Bot in publish-nuget-to-ado-feed.yml and
    warm-feed-cache-pipeline.yml once provisioned with feed-push rights.
  • Register the warm-up pipeline in office/ISS, confirm a PR rerun no longer
    hits 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

@vmoroz
Vladimir Morozov (vmoroz) requested a review from a team as a code owner August 8, 2026 01:21
Copilot AI balanced review requested due to automatic review settings August 8, 2026 01:21
@vmoroz
Vladimir Morozov (vmoroz) requested a review from a team as a code owner August 8, 2026 01:21

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

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.

Comment thread vnext/Scripts/Warm-RnwFeedCache.ps1 Outdated
Comment thread vnext/Scripts/Warm-RnwFeedCache.ps1 Outdated
Comment thread vnext/Scripts/Warm-RnwFeedCache.ps1 Outdated
Copilot AI review requested due to automatic review settings August 8, 2026 01:33

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 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 $npmrc unconditionally 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-WebRequest treats HTTP 202 as a successful response, so the catch block'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 *-stable target (.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

Copilot AI review requested due to automatic review settings August 9, 2026 15:09

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 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-19 and .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-123 and vnext/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 finally block, so cancellation, Ctrl+C, or any uncaught terminating error after the .npmrc is 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 outer try/finally and perform token-file, environment, and work-directory cleanup in finally.
# 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-WebRequest treats 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

Copilot AI review requested due to automatic review settings August 9, 2026 16:37

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 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-stable branch still has trigger: 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'

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