Skip to content

Title release PRs with a rocket prefix, add the release label, and detect releases by commit marker - #16551

Merged
Vladimir Morozov (vmoroz) merged 3 commits into
microsoft:mainfrom
vmoroz:PR/release-pr-title
Nov 1, 2026
Merged

Vladimir Morozov (vmoroz) merged 3 commits into
microsoft:mainfrom
vmoroz:PR/release-pr-title

Conversation

@vmoroz

@vmoroz Vladimir Morozov (vmoroz) commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

Description

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Automation (AI changes or Github Actions to reduce effort of manual tasks)

Why

Release PRs opened by the prepare-release bot are titled like
RELEASE: Releasing 10 package(s) (0.85-stable) (for example #16504). They are hard to
pick out from other PRs and carry no label to filter on. Dependabot PRs already use
short emoji prefixes such as 📦 [main] (#16548); this gives release PRs the same
treatment.

CI decides whether a merged commit is a release by its first line (RELEASE:). GitHub
uses the PR title as that line when a PR has more than one commit (for example #16248,
which had a lock-file fix on top) or when the merger edits it. With the new title, such
a release would silently build as a developer build: no publish, no tag. So this PR
also moves release detection to a marker in the commit body, which survives squash
merges.

Backports: #16557 (0.85-stable) and #16558 (0.81-stable). Until they merge, those
branches keep the old RELEASE: detection, while a manual bot run from main that
targets them would already use the new title. Merge them together with this PR.

What

  • New release PR title. 🚀 [<branch>]: Release N packages (1 package when there
    is only one). The branch drops one trailing -stable: [main], [0.85], [0.81].
  • release label. Added on create (gh pr create --label) and on every refresh
    (gh pr edit --add-label); other labels are kept. The label must exist in the repo.
  • Commit marker. The bot's commit keeps the subject
    RELEASE: Releasing N package(s) (<branch>) and gains the body line
    RNW-Release-Branch: <branch>.
  • CI release detection (.ado/scripts/detectReleaseBuild.js, no dependencies).
    Setup reads the full message of the built commit:
    • exactly one well-formed marker naming the built branch means a release;
    • a malformed, duplicate or wrong-branch marker fails Setup visibly (in auto mode);
    • with no marker, the old RELEASE: first-line rule applies and the log says so;
    • PR builds keep the prepare-release/ branch rule; the isReleaseBuild
      auto/true/false parameter still overrides.
  • Source tag step now also requires a release commit, so forcing
    isReleaseBuild=false never tags. The release pipeline is unchanged.
  • Dry run prints the title, label and full commit message.
  • Tests use Node's built-in runner (node:test); no new dependencies. The package
    entry point is now an exported main() that bin.js calls; exit codes are unchanged.

Screenshots

N/A

Testing

  • Unit tests for the title, gh commands, create/refresh/dry-run/bump-only flows, and
    the detector (CRLF/LF, long and squash bodies, co-author trailers, rewritten
    subjects, malformed/duplicate/wrong-branch markers, legacy subject, overrides, PR
    builds, pipeline wiring).
  • Local dry runs on main, 0.85-stable and 0.81-stable show the new title, label and
    marker.
  • Live runs from a test branch:
    • Prepare-release bot with target 0.85-stable and 0.81-stable updated 🚀 [0.85]: Release 10 packages #16504 and
      🚀 [0.81]: Release 13 packages #16545: titles 🚀 [0.85]: Release 10 packages and 🚀 [0.81]: Release 13 packages,
      label release, and each commit gained its RNW-Release-Branch: <branch> line.
    • CI, ordinary commit, auto: RESULT: isReleaseBuild=False; isReleaseCommit=False.
    • CI, marker naming another branch, auto: Setup failed with Invalid release marker.
    • CI, matching marker, false: RESULT: isReleaseBuild=False; isReleaseCommit=True.
    • CI, ordinary commit, true: the tag step was skipped with
      Expanded: and(True, eq('True', 'True'), eq('False', 'True')), so the Setup result
      reaches the NuGet job.

Changelog

Should this change be included in the release notes: no

Release PRs created by the prepare-release bot are titled 🚀 [<branch>]: Release N packages and labeled release; CI detects releases by a commit-body marker.

@vmoroz
Vladimir Morozov (vmoroz) requested a review from a team as a code owner October 30, 2026 21:36
Copilot AI balanced review requested due to automatic review settings October 30, 2026 21:36
@vmoroz
Vladimir Morozov (vmoroz) marked this pull request as draft October 30, 2026 21:38

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.

🟡 Changes recommended

The missing release label must be provisioned or both commands will fail on every bot run after the release branch is pushed.

1 open issue
What changed in this PR

Updates the prepare-release bot to make release PRs easier to identify and filter, while preserving the commit subjects used by release automation.

Changes:

  • Uses a shared rocket-prefixed title formatter with branch aliases and singular/plural package counts.
  • Adds the release label on creation and refresh, and previews titles and labels during dry runs.
  • Exports main() for testing and adds Node-based tests for formatting, commands, and release flows.
File Description
packages/​@rnw-scripts/​prepare-release/​src/​test/​prepareRelease.test.ts Tests titles, release flows, failures, and entry-point behavior.
packages/​@rnw-scripts/​prepare-release/​src/​test/​github.test.ts Tests label flags, command arguments, and temporary-file cleanup.
packages/​@rnw-scripts/​prepare-release/​src/​prepareRelease.ts Shares title formatting, expands dry-run output, and exports main().
packages/​@rnw-scripts/​prepare-release/​src/​github.ts Adds release-label flags to PR creation and refresh.
packages/​@rnw-scripts/​prepare-release/​package.json Adds the Node test-runner command.
packages/​@rnw-scripts/​prepare-release/​bin.js Invokes exported main() and handles rejected promises.

Review effort: Balanced

The prepare-release bot now titles release PRs '🚀 [<branch alias>]: Release N packages' (alias drops one trailing '-stable') and adds the 'release' label on create and refresh without touching other labels. The commit subject still starts with 'RELEASE:'. Dry run prints the title and label. --bump-only is unchanged. Adds unit tests for the package using the built-in Node.js test runner (node:test), with no new dependencies.

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.

🟡 Changes recommended

The test does not cover a PR created despite a failed gh response, so it does not verify that a retry updates the existing PR instead of attempting another creation.

1 open issue
1 resolved since last review

Review effort: Balanced

The prepare-release bot now adds a release-branch marker line to the body of
its RELEASE: commit. CI reads the full commit message of the built commit with
the new .ado/scripts/detectReleaseBuild.js: a single well-formed marker that
names the built branch makes it a release build; a malformed, duplicate, or
mismatched marker fails Setup in auto mode. Commits without a marker still use
the RELEASE: first-line rule. PR builds keep the prepare-release/ branch rule,
and the isReleaseBuild parameter still forces either scenario.

The source tag step now also requires IsReleaseBuild=True and a release commit,
so forcing a developer build no longer tags. The release pipeline is unchanged.
Adds node:test coverage for the detector and wires it into the root test script.
@vmoroz
Vladimir Morozov (vmoroz) marked this pull request as ready for review November 1, 2026 00:16
Copilot AI balanced review requested due to automatic review settings November 1, 2026 00:17
@vmoroz
Vladimir Morozov (vmoroz) requested a review from a team as a code owner November 1, 2026 00:17
@vmoroz Vladimir Morozov (vmoroz) changed the title Title release PRs with a rocket prefix and add the release label Title release PRs with a rocket prefix, add the release label, and detect releases by commit marker Nov 1, 2026

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.

🟡 Changes recommended

The new title can prevent releases from publishing or tagging on stable branches, while subject-only markers can incorrectly trigger release builds.

2 open issues
1 previously missed issue

In code that hasn't changed since last review

High severity Keep legacy release titles until stable branches are upgraded

packages/​@rnw-scripts/​prepare-release/​src/​prepareRelease.ts:360

[P1] Both 0.81-stable and 0.85-stable still detect releases and tag sources using the RELEASE: subject prefix. If the bot targets either branch and the squash merge uses this new PR title, its CI ignores the body marker and runs a developer build without publishing or tagging. Backport the detector and tag changes before emitting the new title for those branches, or retain the legacy title until each target is upgraded.

Review effort: Balanced

Comment thread .ado/scripts/detectReleaseBuild.js Resolved
- Read the `RNW-Release-Branch` marker only from the commit body, so a
  commit whose subject is the marker line is not treated as a release.
- Test that a rerun refreshes a PR that GitHub created before `gh` failed,
  instead of creating a second one.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings November 1, 2026 00:27

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.

🔵 Needs a closer look

Potential release-title compatibility differences across stable branches could affect publishing and tagging, warranting human assessment.

No open issues 🎉

2 resolved since last review

Review effort: Balanced

@vmoroz
Vladimir Morozov (vmoroz) merged commit 1b59811 into microsoft:main Nov 1, 2026
32 checks passed
@vmoroz
Vladimir Morozov (vmoroz) deleted the PR/release-pr-title branch November 1, 2026 17:45
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