11#!/usr/bin/env -S node --experimental-strip-types --no-warnings
22
3+ import { error , info } from "@rnx-kit/console" ;
34import { untar } from "@rnx-kit/tools-shell" ;
45import { markdownTable } from "markdown-table" ;
56import * as fs from "node:fs" ;
@@ -11,6 +12,7 @@ import packageJson from "package-json";
1112import semverCoerce from "semver/functions/coerce.js" ;
1213import semverCompare from "semver/functions/compare.js" ;
1314import type { MetaPackage , Package , Preset } from "../src/types.js" ;
15+ import { createGitHubClient , fetchPullRequests } from "./github.ts" ;
1416
1517type Options = {
1618 targetVersion ?: string ;
@@ -203,6 +205,35 @@ async function fetchPackageInfo(
203205 } ;
204206}
205207
208+ async function fetchReleaseCandidateVersion ( ) {
209+ const [ latest , next ] = await Promise . allSettled ( [
210+ packageJson ( "react-native" , { version : "latest" } ) ,
211+ packageJson ( "react-native" , { version : "next" } ) ,
212+ ] ) ;
213+
214+ assertFulfilled ( latest , "latest" ) ;
215+ assertFulfilled ( next , "next" ) ;
216+
217+ const latestVersion = latest . value . version ;
218+ const nextVersion = next . value . version ;
219+ if ( semverCompare ( latestVersion , nextVersion ) < 0 ) {
220+ return nextVersion ;
221+ }
222+
223+ // If the release candidate was recently promoted to stable, we might still
224+ // have an open pull request
225+ const pullRequest = await fetchPullRequests ( createGitHubClient ( ) ) ;
226+ if ( pullRequest . data . length > 0 ) {
227+ const pr = pullRequest . data [ 0 ] ;
228+ const m = pr . title . match ( / a d d p r o f i l e f o r ( \d + \. \d + ) $ / ) ;
229+ if ( m ) {
230+ return m [ 1 ] ;
231+ }
232+ }
233+
234+ throw new Error ( `No new release candidate available since ${ latestVersion } ` ) ;
235+ }
236+
206237function getPackageVersion (
207238 packageName : string ,
208239 dependencies ? : Record < string , string >
@@ -557,7 +588,7 @@ async function main({
557588 const [ dst , presetFile ] = getProfilePath ( presetName , targetVersion ) ;
558589 fs . writeFile ( dst , newProfile , ( ) => {
559590 if ( ! pullRequest ) {
560- console . log ( `Wrote to '${ dst } '` ) ;
591+ info ( `Wrote to '${ dst } '` ) ;
561592 }
562593
563594 const profiles = fs
@@ -589,7 +620,7 @@ async function main({
589620 ] . join ( "\n" ) ;
590621 fs . writeFileSync ( presetFile , preset ) ;
591622 if ( ! pullRequest ) {
592- console . log ( `Updated '${ presetFile } '` ) ;
623+ info ( `Updated '${ presetFile } '` ) ;
593624 }
594625 } ) ;
595626 }
@@ -634,6 +665,8 @@ async function main({
634665 const collator = new Intl . Collator ( ) ;
635666 table . sort ( ( lhs , rhs ) => collator . compare ( lhs [ 0 ] , rhs [ 0 ] ) ) ;
636667 if ( table . length > 0 ) {
668+ // The following lines are used for the pull request description; do not use
669+ // colors or prefixes
637670 console. log ( ) ;
638671 console . log ( markdownTable ( [ headers , ...table ] ) ) ;
639672 }
@@ -691,30 +724,17 @@ async function parseArgs(): Promise<Options> {
691724 }
692725
693726 if ( options . releaseCandidate ) {
694- const [ latest , next ] = await Promise . allSettled ( [
695- packageJson ( "react-native" , { version : "latest" } ) ,
696- packageJson ( "react-native" , { version : "next" } ) ,
697- ] ) ;
698-
699- assertFulfilled ( latest , "latest" ) ;
700- assertFulfilled ( next , "next" ) ;
701-
702- const latestVersion = latest . value . version ;
703- const nextVersion = next . value . version ;
704- if ( semverCompare ( latestVersion , nextVersion ) >= 0 ) {
705- throw new Error (
706- `No new release candidate available since ${ latestVersion } `
707- ) ;
708- }
709-
727+ const nextVersion = await fetchReleaseCandidateVersion ( ) ;
710728 const { major, minor } = coerceVersion ( nextVersion ) ;
711729 const targetVersion = `${ major } .${ minor } ` ;
712730 options . targetVersion = targetVersion ;
713731
714732 if ( options . pullRequest ) {
733+ // The following line is used for the pull request description; do not use
734+ // colors or prefixes
715735 console . log ( "Add profile for" , targetVersion ) ;
716736 } else {
717- console . log ( "Found release candidate:" , nextVersion ) ;
737+ info ( "Found release candidate:" , nextVersion ) ;
718738 }
719739 }
720740
@@ -725,7 +745,7 @@ if (fileURLToPath(import.meta.url) === path.resolve(process.argv[1])) {
725745 parseArgs ( )
726746 . then ( main )
727747 . catch ( ( e : Error ) => {
728- console . error ( e . message ) ;
748+ error ( e . message ) ;
729749 process . exitCode = 1 ;
730750 } ) ;
731751}
0 commit comments