diff --git a/.circleci/config.yml b/.circleci/config.yml index 0fe6c07f777c33..7345fe18dc74e7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -936,9 +936,7 @@ jobs: - run: name: Install iOS dependencies - Configuration << parameters.flavor >>; New Architecture << parameters.architecture >>; JS Engine << parameters.jsengine>>; Flipper << parameters.flipper >> command: | - cd /tmp/$PROJECT_NAME - yarn install - cd ios + cd /tmp/$PROJECT_NAME/ios bundle install diff --git a/scripts/run-ci-e2e-tests.js b/scripts/run-ci-e2e-tests.js index 44e5c96ae286e3..a94e1be4468860 100644 --- a/scripts/run-ci-e2e-tests.js +++ b/scripts/run-ci-e2e-tests.js @@ -36,6 +36,9 @@ const REACT_NATIVE_TEMP_DIR = exec( ).stdout.trim(); const REACT_NATIVE_APP_DIR = `${REACT_NATIVE_TEMP_DIR}/template`; const numberOfRetries = argv.retries || 1; + +const VERDACCIO_CONFIG_PATH = path.join(ROOT, '.circleci/verdaccio.yml'); + let SERVER_PID; let APPIUM_PID; let VERDACCIO_PID; @@ -75,7 +78,7 @@ try { const REACT_NATIVE_PACKAGE = path.join(ROOT, 'react-native-*.tgz'); describe('Set up Verdaccio'); - VERDACCIO_PID = setupVerdaccio(); + VERDACCIO_PID = setupVerdaccio(ROOT, VERDACCIO_CONFIG_PATH); describe('Publish packages'); forEachPackage( diff --git a/scripts/setup-verdaccio.js b/scripts/setup-verdaccio.js index e62e7918540d2a..3dc32a261dbe60 100644 --- a/scripts/setup-verdaccio.js +++ b/scripts/setup-verdaccio.js @@ -9,22 +9,41 @@ 'use strict'; -const {exec} = require('shelljs'); -const spawn = require('child_process').spawn; - -function setupVerdaccio() { - const verdaccioProcess = spawn('npx', [ - 'verdaccio@5.15.3', - '--config', - '.circleci/verdaccio.yml', - ]); +const {execSync, spawn} = require('child_process'); + +function setupVerdaccio( + reactNativeRootPath, // Path to React Native root folder + verdaccioConfigPath, // Path to Verdaccio config file, which you want to use for bootstrapping Verdaccio + verdaccioStoragePath, // Path to Verdaccio storage, where it should keep packages. Optional. Default value will be decided by your Verdaccio config +) { + if (!reactNativeRootPath) { + throw new Error( + 'Path to React Native repo root is not specified. You should provide it as a first argument', + ); + } + + if (!verdaccioConfigPath) { + throw new Error( + 'Path to Verdaccio config is not specified. You should provide it as a second argument', + ); + } + + const verdaccioProcess = spawn( + 'npx', + ['verdaccio@5.16.3', '--config', verdaccioConfigPath], + {env: {...process.env, VERDACCIO_STORAGE_PATH: verdaccioStoragePath}}, + ); + const VERDACCIO_PID = verdaccioProcess.pid; - exec('npx wait-on@6.0.1 http://localhost:4873'); - exec('npm set registry http://localhost:4873'); - exec('echo "//localhost:4873/:_authToken=secretToken" > .npmrc'); + + execSync('npx wait-on@6.0.1 http://localhost:4873'); + + execSync('npm set registry http://localhost:4873'); + execSync('echo "//localhost:4873/:_authToken=secretToken" > .npmrc', { + cwd: reactNativeRootPath, + }); + return VERDACCIO_PID; } -module.exports = { - setupVerdaccio: setupVerdaccio, -}; +module.exports = setupVerdaccio; diff --git a/scripts/template/README.md b/scripts/template/README.md new file mode 100644 index 00000000000000..657b9c39b99f65 --- /dev/null +++ b/scripts/template/README.md @@ -0,0 +1,30 @@ +## Why? + +The main purpose of `install-dependencies.js` is to bootstrap [Verdaccio](https://verdaccio.org/docs/what-is-verdaccio). It will host all the local packages, which are not yet present on npm registry. In the near future this should help us in keep template tests green, because once we move to [monorepo structure](https://github.com/react-native-community/discussions-and-proposals/pull/480), template app may use some versions of dependencies that are not yet present on npm registry. + +## I have migrated some module to package, which is not yet published to npm, how to use it? + +First of all, you need to modify [Verdaccio config](https://github.com/facebook/react-native/tree/main/scripts/template/verdaccio.yml): +```diff + packages: ++ '': ++ access: $all ++ publish: $all + '@*/*': + access: $all + publish: $authenticated + proxy: npmjs + '**': + access: $all + publish: $all + proxy: npmjs +``` + +After that, you should modify [install-dependencies script](https://github.com/facebook/react-native/tree/main/scripts/template/install-dependencies.js) to include your package for publishing + +```diff +const PACKAGES_TO_PUBLISH_PATHS = [ + ... ++ "packages/" +]; +``` diff --git a/scripts/template/install-dependencies.js b/scripts/template/install-dependencies.js new file mode 100644 index 00000000000000..47f4eb492c41e4 --- /dev/null +++ b/scripts/template/install-dependencies.js @@ -0,0 +1,67 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +'use strict'; + +const yargs = require('yargs'); +const {execSync, spawnSync} = require('child_process'); +const setupVerdaccio = require('../setup-verdaccio'); + +const {argv} = yargs + .option('r', { + alias: 'reactNativeRootPath', + describe: 'Path to root folder of react-native', + required: true, + }) + .option('c', { + alias: 'templatePath', + describe: 'Path to template application folder', + required: true, + }) + .strict(); + +const {reactNativeRootPath, templatePath} = argv; + +const VERDACCIO_CONFIG_PATH = `${reactNativeRootPath}/scripts/template/verdaccio.yml`; +const VERDACCIO_STORAGE_PATH = `${templatePath}/node_modules`; + +const PACKAGES_TO_PUBLISH_PATHS = []; + +function install() { + const VERDACCIO_PID = setupVerdaccio( + reactNativeRootPath, + VERDACCIO_CONFIG_PATH, + VERDACCIO_STORAGE_PATH, + ); + process.stdout.write('Bootstrapped Verdaccio \u2705\n'); + + // Publish all necessary packages... + for (const packagePath of PACKAGES_TO_PUBLISH_PATHS) { + execSync('npm publish --registry http://localhost:4873 --access public', { + cwd: `${reactNativeRootPath}/${packagePath}`, + stdio: [process.stdin, process.stdout, process.stderr], + }); + + process.stdout.write(`Published /${packagePath} to proxy \u2705\n`); + } + + spawnSync('yarn', ['install'], { + cwd: templatePath, + stdio: [process.stdin, process.stdout, process.stderr], + }); + process.stdout.write('Installed dependencies via Yarn \u2705\n'); + + process.stdout.write(`Killing verdaccio. PID — ${VERDACCIO_PID}...\n`); + execSync(`kill -9 ${VERDACCIO_PID}`); + process.stdout.write('Killed Verdaccio process \u2705\n'); + + process.exit(); +} + +install(); diff --git a/scripts/template/verdaccio.yml b/scripts/template/verdaccio.yml new file mode 100644 index 00000000000000..03ebcfdc7e1dc0 --- /dev/null +++ b/scripts/template/verdaccio.yml @@ -0,0 +1,27 @@ +storage: ./storage +auth: + htpasswd: + file: ./htpasswd +uplinks: + npmjs: + url: https://registry.npmjs.org/ + max_fails: 40 + maxage: 30m + timeout: 60s + fail_timeout: 10m + cache: false + agent_options: + keepAlive: true + maxSockets: 40 + maxFreeSockets: 10 +packages: + '@*/*': + access: $all + publish: $authenticated + proxy: npmjs + '**': + access: $all + publish: $all + proxy: npmjs +logs: + - {type: file, path: verdaccio.log, format: json, level: warn}