diff --git a/.ado/apple-pr.yml b/.ado/apple-pr.yml index 145176e7d30fb8..0cda6c83d4ffed 100644 --- a/.ado/apple-pr.yml +++ b/.ado/apple-pr.yml @@ -32,4 +32,4 @@ stages: dependsOn: [] jobs: - template: /.ado/jobs/test-react-native-macos-init.yml@self - #- template: /.ado/jobs/react-native-test-app-integration.yml@self + - template: /.ado/jobs/react-native-test-app-integration.yml@self diff --git a/.ado/jobs/build-test-rntester.yml b/.ado/jobs/build-test-rntester.yml index 9b3d3d269199cb..8f0a07c679d4f7 100644 --- a/.ado/jobs/build-test-rntester.yml +++ b/.ado/jobs/build-test-rntester.yml @@ -2,7 +2,7 @@ parameters: - name: appleBuildMatrix type: object default: - - name: macos_oldarch_jsc + - name: macos_oldarch_jsc friendly_name: 'macOS, Old Arch, JSC' sdk: macosx scheme: RNTester-macOS @@ -30,7 +30,7 @@ parameters: # packager_platform: 'macos' # new_arch_enabled: '1' # use_hermes: '1' - - name: ios_oldarch_jsc + - name: ios_oldarch_jsc friendly_name: 'iOS, Old Arch, JSC' sdk: iphonesimulator scheme: RNTester @@ -58,7 +58,7 @@ parameters: # packager_platform: 'ios' # new_arch_enabled: '1' # use_hermes: '1' - - name: xros_oldarch_jsc + - name: xros_oldarch_jsc friendly_name: 'xrOS, Old Arch, JSC' sdk: xrsimulator scheme: RNTester-visionOS @@ -89,66 +89,57 @@ parameters: jobs: - ${{ each slice in parameters.appleBuildMatrix }}: - - job: ${{ slice.name }} - displayName: ${{ slice.friendly_name }} - pool: - vmImage: $(vmImageApple) - timeoutInMinutes: 90 - cancelTimeoutInMinutes: 5 - steps: + - job: ${{ slice.name }} + displayName: ${{ slice.friendly_name }} + pool: + vmImage: $(vmImageApple) + timeoutInMinutes: 90 + cancelTimeoutInMinutes: 5 + steps: - template: /.ado/templates/apple-tools-setup.yml@self - ${{ if in(slice.sdk, 'xros', 'xrsimulator') }}: - - task: CmdLine@2 - displayName: Download visionOS SDDK - inputs: - script: | - set -eox pipefail - # https://github.com/actions/runner-images/issues/10559 - sudo xcodebuild -runFirstLaunch - sudo xcrun simctl list - sudo xcodebuild -downloadPlatform visionOS - sudo xcodebuild -runFirstLaunch - - - task: CmdLine@2 - displayName: yarn install - inputs: - script: | + - script: | set -eox pipefail - yarn install --immutable + # https://github.com/actions/runner-images/issues/10559 + sudo xcodebuild -runFirstLaunch + sudo xcrun simctl list + sudo xcodebuild -downloadPlatform visionOS + sudo xcodebuild -runFirstLaunch + displayName: Download visionOS SDK - - task: CmdLine@2 - displayName: pod install - inputs: - script: | - set -eox pipefail - cd packages/rn-tester - bundle install - bundle exec pod install --verbose + - script: | + yarn install + displayName: Install npm dependencies + + - script: | + set -eox pipefail + bundle install + bundle exec pod install --verbose env: RCT_NEW_ARCH_ENABLED: ${{ slice.new_arch_enabled }} USE_HERMES: ${{ slice.use_hermes }} + workingDirectory: packages/rn-tester + displayName: Install Pods - - task: CmdLine@2 - displayName: Build ${{ slice.scheme }} - inputs: - script: | - set -eox pipefail - ./.ado/scripts/xcodebuild.sh packages/rn-tester/RNTesterPods.xcworkspace ${{ slice.sdk }} ${{ slice.scheme }} build + - script: | + set -eox pipefail + .ado/scripts/xcodebuild.sh packages/rn-tester/RNTesterPods.xcworkspace ${{ slice.sdk }} ${{ slice.scheme }} build env: CCACHE_DISABLE: 1 - + displayName: Build ${{ slice.scheme }} + # Skip testing on visionOS via the conditions below - ${{ if ne(slice.scheme, 'RNTester-visionOS') }}: - task: ShellScript@2 - displayName: 'Setup packager and WebSocket test server' + displayName: Setup packager and WebSocket test server inputs: - scriptPath: '.ado/scripts/ado-test-setup.sh' + scriptPath: .ado/scripts/ado-test-setup.sh disableAutoCwd: true cwd: '' - - bash: | + - script: | echo Preparing the packager for platform $PLATFORM curl --retry-connrefused --connect-timeout 5 --max-time 10 --retry 10 --retry-delay 5 --retry-max-time 120 "http://localhost:8081/packages/rn-tester/js/RNTesterApp.${PLATFORM}.bundle?platform=${PLATFORM}&dev=true" -o /dev/null curl --retry-connrefused --connect-timeout 5 --max-time 10 --retry 10 --retry-delay 5 --retry-max-time 120 "http://localhost:8081/packages/rn-tester/js/RNTesterApp.${PLATFORM}.bundle?platform=${PLATFORM}&dev=true&minify=false" -o /dev/null @@ -156,21 +147,19 @@ jobs: curl --retry-connrefused --connect-timeout 5 --max-time 10 --retry 10 --retry-delay 5 --retry-max-time 120 "http://localhost:8081/IntegrationTests/RCTRootViewIntegrationTestApp.bundle?platform=${PLATFORM}&dev=true" -o /dev/null env: PLATFORM: ${{ slice.packager_platform }} - displayName: 'curl the packager' + displayName: Fetch JS bundles from dev server - - task: CmdLine@2 - displayName: Test ${{ slice.scheme }} - inputs: - script: | - set -eox pipefail - ./.ado/scripts/xcodebuild.sh packages/rn-tester/RNTesterPods.xcworkspace ${{ slice.sdk }} ${{ slice.scheme }} test + - script: | + set -eox pipefail + .ado/scripts/xcodebuild.sh packages/rn-tester/RNTesterPods.xcworkspace ${{ slice.sdk }} ${{ slice.scheme }} test env: CCACHE_DISABLE: 1 + displayName: Test ${{ slice.scheme }} - task: ShellScript@2 - displayName: 'Cleanup packager and WebSocket test server' + displayName: Cleanup packager and WebSocket test server inputs: - scriptPath: '.ado/scripts/ado-test-cleanup.sh' + scriptPath: .ado/scripts/ado-test-cleanup.sh disableAutoCwd: true cwd: '' condition: always() diff --git a/.ado/jobs/react-native-test-app-integration.yml b/.ado/jobs/react-native-test-app-integration.yml index 45d8abfba8a89a..fdb8f0226804ff 100644 --- a/.ado/jobs/react-native-test-app-integration.yml +++ b/.ado/jobs/react-native-test-app-integration.yml @@ -9,83 +9,50 @@ jobs: cancelTimeoutInMinutes: 5 steps: - template: /.ado/templates/apple-tools-setup.yml@self - - bash: | - echo "##vso[task.setvariable variable=package_version]$(cat package.json | jq .version | awk '{ print substr($0, 2, length($0) - 2) }')" - echo "##vso[task.setvariable variable=react_version]$(cat package.json | jq .peerDependencies.react)" - echo "##vso[task.setvariable variable=rncli_version]$(cat package.json | jq '.dependencies."@react-native-community/cli"')" - echo "##vso[task.setvariable variable=rncli_android_version]$(cat package.json | jq '.dependencies."@react-native-community/cli-platform-android"')" - echo "##vso[task.setvariable variable=rncli_ios_version]$(cat package.json | jq '.dependencies."@react-native-community/cli-platform-ios"')" - displayName: 'Determine react-native-macos version' - workingDirectory: packages/react-native - - bash: | - npm pack ./packages/react-native - displayName: 'Pack react-native-macos' - - bash: | - git clone --progress https://github.com/microsoft/react-native-test-app.git - displayName: Checkout react-native-test-app - - bash: | - set -eo pipefail - cat package.json | - jq '.devDependencies["react"] = $(react_version)' | - jq '.devDependencies["react-native"] = "^0.71"' | - jq '.devDependencies["react-native-macos"] = "../react-native-macos-$(package_version).tgz"' | - jq 'del(.devDependencies["@react-native-community/cli"])' | - jq 'del(.devDependencies["@react-native-community/cli-platform-android"])' | - jq 'del(.devDependencies["@react-native-community/cli-platform-ios"])' | - jq 'del(.devDependencies["react-native-windows"])' > .package.json - mv .package.json package.json - cat package.json | jq .devDependencies - displayName: Modify react-native-test-app dependencies + + - template: /.ado/templates/verdaccio-publish.yml@self + + - script: | + git clone --filter=blob:none --progress https://github.com/microsoft/react-native-test-app.git + displayName: Clone react-native-test-app + + - script: | + node .ado/scripts/export-versions.mjs + displayName: Determine react-native version + + - script: | + npm run set-react-version $(react_native_version) -- --overrides '{ "react-native-macos": "1000.0.0" }' + displayName: Configure react-native-test-app dependencies workingDirectory: react-native-test-app - - bash: | + + - script: | set -eo pipefail - cat package.json | - jq '.devDependencies["@react-native-community/cli"] = $(rncli_version)' | - jq '.devDependencies["@react-native-community/cli-platform-android"] = $(rncli_android_version)' | - jq '.devDependencies["@react-native-community/cli-platform-ios"] = $(rncli_ios_version)' | - jq '.devDependencies["react"] = $(react_version)' | - jq '.devDependencies["react-native"] = "^0.71"' | - jq '.devDependencies["react-native-macos"] = "../../react-native-macos-$(package_version).tgz"' | - jq 'del(.devDependencies["react-native-windows"])' > .package.json - mv .package.json package.json - cat package.json | jq .devDependencies - displayName: Modify example app dependencies - workingDirectory: react-native-test-app/example - - template: /.ado/templates/verdaccio-init.yml@self - - bash: | - npx beachball publish --branch origin/$(System.PullRequest.TargetBranch) --no-push --registry http://localhost:4873 --yes --access public - displayName: Publish beachball packages to verdaccio - - bash: | - cat .yarnrc.yml | sed 's_^npmRegistryServer: ".*"$_npmRegistryServer: "http://localhost:4873"_' > .yarnrc.yml.copy - rm .yarnrc.yml - mv .yarnrc.yml.copy .yarnrc.yml - echo -e '\nunsafeHttpWhitelist: ["localhost"]' >> .yarnrc.yml - displayName: Point react-native-test-app registry to verdaccio server - workingDirectory: react-native-test-app - - bash: | + $(Build.Repository.LocalPath)/.ado/scripts/verdaccio.sh configure yarn --no-immutable displayName: Install npm dependencies workingDirectory: react-native-test-app - - bash: | + + - script: | yarn build:macos || yarn build:macos displayName: Bundle JavaScript workingDirectory: react-native-test-app/example - - bash: | + + - script: | rm macos/Podfile.lock pod install --project-directory=macos displayName: Install Pods workingDirectory: react-native-test-app/example - - bash: | - set -eo pipefail - ../scripts/xcodebuild.sh macos/Example.xcworkspace build | xcbeautify - displayName: Build Intel + + - script: | + ../scripts/build/xcodebuild.sh macos/Example.xcworkspace build + displayName: Build x86 workingDirectory: react-native-test-app/example env: CCACHE_DISABLE: 1 - - bash: | - set -eo pipefail - ../scripts/xcodebuild.sh macos/Example.xcworkspace clean - ../scripts/xcodebuild.sh macos/Example.xcworkspace build ARCHS=arm64 | xcbeautify + + - script: | + ../scripts/build/xcodebuild.sh macos/Example.xcworkspace clean + ../scripts/build/xcodebuild.sh macos/Example.xcworkspace build ARCHS=arm64 displayName: Build ARM workingDirectory: react-native-test-app/example env: diff --git a/.ado/jobs/test-javascript.yml b/.ado/jobs/test-javascript.yml index df02960074d1be..cf13945d7be4f0 100644 --- a/.ado/jobs/test-javascript.yml +++ b/.ado/jobs/test-javascript.yml @@ -4,23 +4,19 @@ jobs: pool: vmImage: $(VmImageApple) steps: - - template: /.ado/templates/apple-tools-setup.yml@self + - template: /.ado/templates/apple-tools-setup.yml@self - - task: CmdLine@2 - displayName: yarn install - inputs: - script: yarn install --immutable + - script: yarn install + displayName: Install npm dependencies - - task: CmdLine@2 - displayName: yarn test-ci [test] - inputs: - script: 'yarn test-ci' - - - script: 'yarn flow-check' - displayName: 'yarn flow-check' + - script: yarn test-ci + displayName: Test - - script: 'yarn lint' - displayName: 'yarn lint' + - script: yarn flow-check + displayName: Flow type check - - script: 'yarn format-check' - displayName: 'yarn format-check' + - script: yarn lint + displayName: Lint + + - script: yarn format-check + displayName: Format diff --git a/.ado/jobs/test-react-native-macos-init.yml b/.ado/jobs/test-react-native-macos-init.yml index 5200d802e0bff5..430c8076d33078 100644 --- a/.ado/jobs/test-react-native-macos-init.yml +++ b/.ado/jobs/test-react-native-macos-init.yml @@ -13,27 +13,7 @@ jobs: - template: /.ado/templates/apple-tools-setup.yml@self - - script: | - set -eox pipefail - yarn install - displayName: Install npm dependencies - - - script: | - set -eox pipefail - yarn build - displayName: Build @react-native/community-cli-plugin - - - script: | - set -eox pipefail - yarn build - workingDirectory: packages/react-native-macos-init - displayName: Build react-native-macos-init - - - template: /.ado/templates/verdaccio-init.yml@self - - - script: | - .ado/scripts/verdaccio.sh publish --branch origin/$(System.PullRequest.TargetBranch) - displayName: Publish react-native-macos to Verdaccio + - template: /.ado/templates/verdaccio-publish.yml@self - script: | node .ado/scripts/export-versions.mjs diff --git a/.ado/npmAddUser.js b/.ado/npmAddUser.js deleted file mode 100644 index d8e77ee409921a..00000000000000 --- a/.ado/npmAddUser.js +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env node -// @ts-check - -const child_process = require("child_process"); - -const username = process.argv[2]; -const password = process.argv[3]; -const email = process.argv[4]; -const registry = process.argv[5]; - -if (!username) { - console.error("Please specify username"); - process.exit(1); -} - -if (!password) { - console.error("Please specify password"); - process.exit(1); -} - -if (!email) { - console.error("Please specify email"); - process.exit(1); -} - -const child = child_process.exec(`npm adduser${registry? (' --registry ' + registry) :''}` ); - -child.stdout.on("data", d => { - const data = d.toString(); - process.stdout.write(d + "\n"); - if (data.match(/username/i)) { - child.stdin.write(username + "\n"); - } else if (data.match(/password/i)) { - child.stdin.write(password + "\n"); - } else if (data.match(/email/i)) { - child.stdin.write(email + "\n"); - } else if (data.match(/logged in as/i)) { - child.stdin.end(); - } -}); diff --git a/.ado/scripts/npmAddUser.mjs b/.ado/scripts/npmAddUser.mjs new file mode 100644 index 00000000000000..f08793fc3fcabb --- /dev/null +++ b/.ado/scripts/npmAddUser.mjs @@ -0,0 +1,42 @@ +#!/usr/bin/env node +// @ts-check + +import { exec } from "node:child_process"; + +/** + * @template T + * @param {T} arg + * @param {string} message + * @returns {asserts arg is NonNullable} + */ +function assert(arg, message) { + if (!arg) { + throw new Error(message); + } +} + +const { [2]: username, [3]: password, [4]: email, [5]: registry } = process.argv; +assert(username, "Please specify username"); +assert(password, "Please specify password"); +assert(email, "Please specify email"); + +const child = exec(`npm adduser${registry ? ` --registry ${registry}` : ""}`); +assert(child.stdout, "Missing stdout on child process"); + +child.stdout.on("data", d => { + assert(child.stdin, "Missing stdin on child process"); + + process.stdout.write(d); + process.stdout.write("\n"); + + const data = d.toString(); + if (data.match(/username/i)) { + child.stdin.write(username + "\n"); + } else if (data.match(/password/i)) { + child.stdin.write(password + "\n"); + } else if (data.match(/email/i)) { + child.stdin.write(email + "\n"); + } else if (data.match(/logged in as/i)) { + child.stdin.end(); + } +}); diff --git a/.ado/scripts/verdaccio.sh b/.ado/scripts/verdaccio.sh index 70e27ed0f754c4..af36643913c096 100755 --- a/.ado/scripts/verdaccio.sh +++ b/.ado/scripts/verdaccio.sh @@ -2,8 +2,6 @@ NPM_REGISTRY=http://localhost:4873 -project_root=$(cd -P "$(dirname $0)" && pwd) - set -eox pipefail case ${1-} in @@ -14,9 +12,9 @@ case ${1-} in "init") npm set registry $NPM_REGISTRY - npx verdaccio --config $project_root/.ado/verdaccio/config.yaml & - node $project_root/.ado/waitForVerdaccio.js - node $project_root/.ado/npmAddUser.js user pass mail@nomail.com $NPM_REGISTRY + scripts_root=$(cd -P "$(dirname $0)" && pwd) + node $scripts_root/waitForVerdaccio.mjs $NPM_REGISTRY + node $scripts_root/npmAddUser.mjs user pass mail@nomail.com $NPM_REGISTRY ;; "publish") diff --git a/.ado/scripts/waitForVerdaccio.mjs b/.ado/scripts/waitForVerdaccio.mjs new file mode 100644 index 00000000000000..2ceb782c4e3f4a --- /dev/null +++ b/.ado/scripts/waitForVerdaccio.mjs @@ -0,0 +1,31 @@ +#!/usr/bin/env node +// @ts-check + +import * as fs from "node:fs"; +import { get } from "node:http"; + +/** + * @param {string} npmRegistryUrl + */ +function queryForServerStatus(npmRegistryUrl) { + get(npmRegistryUrl, res => { + console.log(`Verdaccio server status: ${res.statusCode}`); + if (res.statusCode != 200) { + setTimeout(queryForServerStatus, 2000); + } + }).on("error", err => { + console.log(err.message); + const logUrl = new URL("../verdaccio/console.log", import.meta.url); + try { + const logFile = fs.readFileSync(logUrl, { encoding: "utf-8" }); + console.log("Verdaccio console output: " + logFile); + } catch (error) { + console.log("No Verdaccio console output yet."); + } + setTimeout(queryForServerStatus, 2000); + }); +} + +console.log("Waiting for Verdaccio instance to respond..."); + +queryForServerStatus(process.argv[2]); diff --git a/.ado/templates/apple-tools-setup.yml b/.ado/templates/apple-tools-setup.yml index c1b840f7ac9460..130f7b5c42051d 100644 --- a/.ado/templates/apple-tools-setup.yml +++ b/.ado/templates/apple-tools-setup.yml @@ -3,11 +3,9 @@ steps: inputs: versionSpec: '18.x' - - task: CmdLine@2 - displayName: 'brew bundle' - inputs: - script: | - brew bundle --file .ado/Brewfile - cat .ado/Brewfile.lock.json + - script: | + brew bundle --file .ado/Brewfile + cat .ado/Brewfile.lock.json + displayName: 'Install Homebrew dependencies' - - template: /.ado/templates/apple-xcode-select.yml@self \ No newline at end of file + - template: /.ado/templates/apple-xcode-select.yml@self diff --git a/.ado/templates/verdaccio-init.yml b/.ado/templates/verdaccio-init.yml deleted file mode 100644 index 5fb76fcebc50d2..00000000000000 --- a/.ado/templates/verdaccio-init.yml +++ /dev/null @@ -1,20 +0,0 @@ -# Initializes a verdaccio server. - -steps: - - task: CmdLine@2 - displayName: Launch test npm server (verdaccio) - inputs: - script: | - npx verdaccio --config ./.ado/verdaccio/config.yaml & - - - script: | - npm set registry http://localhost:4873 - displayName: Modify default npm config to point to local verdaccio server - - - script: | - node .ado/waitForVerdaccio.js - displayName: Wait for verdaccio server to boot - - - script: | - node .ado/npmAddUser.js user pass mail@nomail.com http://localhost:4873 - displayName: Add npm user to verdaccio diff --git a/.ado/templates/verdaccio-publish.yml b/.ado/templates/verdaccio-publish.yml new file mode 100644 index 00000000000000..4ec7d058ccf958 --- /dev/null +++ b/.ado/templates/verdaccio-publish.yml @@ -0,0 +1,25 @@ +steps: + - script: | + yarn install + displayName: Install npm dependencies + + - script: | + yarn build + displayName: Build @react-native/community-cli-plugin + + - script: | + yarn build + workingDirectory: packages/react-native-macos-init + displayName: Build react-native-macos-init + + - script: | + npx verdaccio --config .ado/verdaccio/config.yaml & + displayName: Start Verdaccio server + + - script: | + .ado/scripts/verdaccio.sh init + displayName: Configure npm for Verdaccio server + + - script: | + .ado/scripts/verdaccio.sh publish --branch origin/$(System.PullRequest.TargetBranch) + displayName: Publish react-native-macos to Verdaccio diff --git a/.ado/waitForVerdaccio.js b/.ado/waitForVerdaccio.js deleted file mode 100644 index 62c4e2888a8d28..00000000000000 --- a/.ado/waitForVerdaccio.js +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env node -// @ts-check - -const http = require('http'); -const fs = require('fs'); -const path = require('path'); - -function queryForServerStatus() { - - http.get('http://localhost:4873', res => { - console.log(`Server status: ${res.statusCode}`); - if (res.statusCode != 200) { - setTimeout(queryForServerStatus, 2000); - } - }).on('error', err => { - console.log(err.message); - try { - const logFile = fs.readFileSync(path.resolve(__dirname, 'verdaccio/console.log')).toString('utf8'); - console.log('verdaccio console output: ' + logFile); - } catch (error) { - console.log('no verdaccio console output yet.'); - } - setTimeout(queryForServerStatus, 2000); - }); -} - -console.log('Waiting for verdaccio instance to respond...'); - -queryForServerStatus(); \ No newline at end of file