Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@ tasks.register("publishAllToMavenTempLocal") {
":packages:react-native:ReactAndroid:hermes-engine:publishAllPublicationsToMavenTempLocalRepository")
}

// Added to allow us to publish patched Android JARs to Gitlab. This is part
// of the "Patching React Native" process at:
// https://www.notion.so/wanderlog/Patching-React-Native-17b4797ed24d481eb2155c9daec1ba98?source=copy_link
tasks.register("publishAllToGitLab") {
description = "Publish all the release artifacts to a GitLab Maven Repository."

val gitlabKey = project.property("gitlabPrivateToken") as? String
if (gitlabKey == null) {
throw IllegalStateException("gitlabPrivateToken property is not set. Set it in your ~/.gradle/gradle.properties file to a full-access token")
}

// The Release pubName is derived by searching for MavenPublication in the codebase
dependsOn(":packages:react-native:ReactAndroid:publishAllPublicationsToGitLabRepository")
dependsOn(":packages:react-native:ReactAndroid:hermes-engine:publishAllPublicationsToGitLabRepository")
}

tasks.register("publishAndroidToSonatype") {
description = "Publish the Android artifacts to Sonatype (Maven Central or Snapshot repository)"
dependsOn(":packages:react-native:ReactAndroid:publishToSonatype")
Expand Down
21 changes: 21 additions & 0 deletions packages/react-native/ReactAndroid/publish.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,27 @@ publishing {
name = "mavenTempLocal"
url = mavenTempLocalUrl
}

// Added to allow us to publish patched Android JARs to Gitlab. This
// is part of the "Patching React Native" process at:
// https://www.notion.so/wanderlog/Patching-React-Native-17b4797ed24d481eb2155c9daec1ba98?source=copy_link
//
// Added based on https://docs.gitlab.com/ee/user/packages/gradle_repository/#authenticate-with-a-personal-access-token-or-deploy-token-in-gradle
// to publish our forked package to Maven
maven {
// URL modified based on https://docs.gitlab.com/ee/api/packages/maven.html#upload-a-package-file
// Project ID is obtained from the itineraries project on Gitlab
url = "https://gitlab.com/api/v4/projects/9347980/packages/maven"
name = "GitLab"
// Modified based on https://stackoverflow.com/a/61339469
credentials(HttpHeaderCredentials) {
name = "Private-Token"
value = project.property("gitlabPrivateToken")
}
authentication {
header(HttpHeaderAuthentication)
}
}
}

if (signingKey && signingPwd) {
Expand Down
132 changes: 132 additions & 0 deletions scripts/build-package.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// @flow
const {
downloadHermesSourceTarball,
expandHermesSourceTarball,
} = require('../packages/react-native/scripts/hermes/hermes-utils');
const { REPO_ROOT } = require('./consts');
const fs = require('fs');
const { rm } = require('fs/promises');
const {cp, exec} = require('shelljs');

/**
* This script is used as a part of Patching React Native. See:
* https://www.notion.so/wanderlog/Patching-React-Native-17b4797ed24d481eb2155c9daec1ba98?source=copy_link
*
* This section goes over how we created it:
* ["How did we figure out the steps for Create scripts for building patched React Native](https://www.notion.so/wanderlog/Patching-React-Native-17b4797ed24d481eb2155c9daec1ba98?source=copy_link#2aef9a6861f68016a0def8edec2d3d5a)
*
* This code is largely copied from other files per the comments below.
*
* If this script fails, we can debug it by running it with `CI=true` to see
* all the intermediate commands the Shell scripts run, since the scripts
* enable `set -x` when `CI` is set.
*/
async function buildPackage() {
const reactNativePackagePath = `${REPO_ROOT}/packages/react-native`;

// This part of the code downloads the Hermes source code and expands it.
// Start copied from scripts/release-testing/utils/testing-utils.js
const hermesCoreSourceFolder = `${reactNativePackagePath}/sdks/hermes`;

if (!fs.existsSync(hermesCoreSourceFolder)) {
console.info('The Hermes source folder is missing. Downloading...');
downloadHermesSourceTarball();
expandHermesSourceTarball();
}

// need to move the scripts inside the local hermes cloned folder
// cp sdks/hermes-engine/utils/*.sh <your_hermes_checkout>/utils/.
cp(
`${reactNativePackagePath}/sdks/hermes-engine/hermes-engine.podspec`,
`${reactNativePackagePath}/sdks/hermes/hermes-engine.podspec`,
);
cp(
`${reactNativePackagePath}/sdks/hermes-engine/hermes-utils.rb`,
`${reactNativePackagePath}/sdks/hermes/hermes-utils.rb`,
);
cp(
`${reactNativePackagePath}/sdks/hermes-engine/utils/*.sh`,
`${reactNativePackagePath}/sdks/hermes/utils/.`,
);
// End copied from scripts/release-testing/utils/testing-utils.js

// Builds the types_generated. We figured this out by asking:
// "What code in this project creates the types_generated directory?"
exec('yarn build-types', {cwd: REPO_ROOT});

// Builds the FBReactNativeSpec. We figured this out by asking:
// "What code in this project creates the FBReactNativeSpec directory?"
exec('yarn install && yarn prepack', {cwd: reactNativePackagePath});
// We don't need the README.md file
await rm(`${reactNativePackagePath}/README.md`);

// build-mac-framework.sh builds hermes and hermesc binaries for MacOS.
// I figured this out by:
//
// 1. Running the code in `buildAllArtifacts` below (uncomment the line)
// below
// 2. Running `find . -name hermes` and seeing that the file was in
// `./packages/react-native/sdks/hermes/build_macosx/bin/hermes`
// 3. Finding references to build_macosx and seeing it was likely created
// by the build_apple_framework function
// 4. Finding callers of the build_apple_framework function

// MAC_DEPLOYMENT_TARGET is used by get_mac_deployment_target in
// build-mac-framework.sh. The value to set is taken from
// publish-release.yml
process.env.MAC_DEPLOYMENT_TARGET = "10.15";
exec(
'bash ./utils/build-mac-framework.sh',
{cwd: `${reactNativePackagePath}/sdks/hermes`},
);

// Uncomment this to build all the artifacts for Hermes, including ones that we
// don't need.
// buildAllArtifacts(hermesCoreSourceFolder);

// We figured out the files to copy by running:
// `find . -name hermesc` and and `find . -name hermes | grep bin`
//
// We figured out the destination directory by looking at the the paths in
// the official React Native NPM package: https://www.npmjs.com/package/react-native/v/0.81.5?activeTab=code
const hermesDir = `${reactNativePackagePath}/sdks/hermes/build_macosx/bin`;
const hermescDir = `${reactNativePackagePath}/sdks/hermes/build_host_hermesc/bin`;
const destinationDir = `${reactNativePackagePath}/sdks/hermesc/osx-bin`;
console.info(`Copying files from ${hermesDir} to ${destinationDir}`);
console.info(`Copying files from ${hermescDir} to ${destinationDir}`);
await fs.promises.mkdir(destinationDir, { recursive: true });
cp('-r', `${hermesDir}/*`, `${destinationDir}/`);
cp('-r', `${hermescDir}/*`, `${destinationDir}/`);
}

/**
* This function builds all the artifacts for Hermes, including ones that we
* don't need. We used it initially to figure out which subtasks built the hermes
* and hermesc binaries.
*/
// eslint-disable-next-line no-unused-vars
function buildAllArtifacts(hermesCoreSourceFolder) {
// These versions were copied from publish-release.yml
process.env.IOS_DEPLOYMENT_TARGET = '15.1';
process.env.MAC_DEPLOYMENT_TARGET = '10.15';
process.env.XROS_DEPLOYMENT_TARGET = '1.0';

// Start copied from scripts/release-testing/utils/testing-utils.js
const jsiFolder = `${reactNativePackagePath}/ReactCommon/jsi`;

const buildTypeiOSArtifacts = 'Debug';

// the android ones get set into /private/tmp/maven-local
const localMavenPath = '/private/tmp/maven-local';

// Generate native files for iOS
generateiOSArtifacts(
jsiFolder,
hermesCoreSourceFolder,
buildTypeiOSArtifacts,
localMavenPath,
);
// End copied from scripts/release-testing/utils/testing-utils.js
}

buildPackage();
138 changes: 138 additions & 0 deletions scripts/move-react-native-package.sh
Comment thread
hsource marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#!/bin/bash

set -e

SAVED_ROOT_FILES_NAME="saved-root-files"

# Parse command line arguments
help_text_and_exit() {
cat <<END
Usage: bash move-react-native-package.sh [--reverse] [--help]
Example:
bash move-react-native-package.sh --reverse
bash move-react-native-package.sh --help

This script is used as a part of Patching React Native. See:
https://www.notion.so/wanderlog/Patching-React-Native-17b4797ed24d481eb2155c9daec1ba98?source=copy_link

We need to do this because the installed NPM package consists of files within
the /packages/react-native directory. Since we install from Github, we need to
create a tag with those files at the root.

This script moves the react-native package to the root directory and updates
the .gitignore. It saves the moved files in a directory called
$SAVED_ROOT_FILES_NAME.

If --reverse is passed, all operations are reversed.

END
exit 1
}

while [ $# -gt 0 ]; do
case $1 in
--reverse) REVERSE=true; shift 1;;
--help) help_text_and_exit;
esac
done

echo "Starting react-native package move script..."


# Get the repository root directory
# We want this directory to be correct even if the script has been moved by
# itself.
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PARENT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
PARENT_BASENAME=$(basename "$PARENT_DIR")

if [ "$PARENT_BASENAME" = "$SAVED_ROOT_FILES_NAME" ]; then
REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
else
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
fi
cd "$REPO_ROOT"

SAVED_ROOT_FILES_PATH="$REPO_ROOT/$SAVED_ROOT_FILES_NAME"

# Forward moves
if [ "$REVERSE" != true ]; then
# Check if we've already moved the package
if [ -d "$SAVED_ROOT_FILES_PATH" ]; then
echo "Error: $SAVED_ROOT_FILES_NAME directory already exists. Nothing to do."
exit 1
fi

mkdir -p "$SAVED_ROOT_FILES_PATH/packages"

echo "Saving existing .gitignore to saved-root-files/.gitignore"
cp -f "$REPO_ROOT/.gitignore" "$SAVED_ROOT_FILES_PATH/.gitignore"

echo "Updating .gitignore to add, modify, and delete lines"
# On macOS, sed -i requires an extension argument (use empty string for in-place)
# Remove /packages/react-native from paths
sed -i '' 's|/packages/react-native/|/|g' "$REPO_ROOT/.gitignore"

# Remove any lines that remove things we want to keep
# We determined these by doing these steps, and then repeating them until we
# didn't miss any files:
#
# 1. Doing `yarn add react-native@^0.81.5`
# 2. Listing the files by doing `find node_modules/react-native > originalFiles.txt`
# 3. Installing our fork of react-native
# 4. Running the same command to list the files again
# 5. Diffing the two files to see what was missed
sed -E -i '' '/^\/?vendor/d' "$REPO_ROOT/.gitignore"
sed -E -i '' '/^\/?sdks\/hermesc/d' "$REPO_ROOT/.gitignore"
sed -i '' '/types_generated/d' "$REPO_ROOT/.gitignore"
sed -i '' '/FBReactNativeSpec/d' "$REPO_ROOT/.gitignore"
echo "/saved-root-files/" >> "$REPO_ROOT/.gitignore"

echo "Moving all files to $SAVED_ROOT_FILES_PATH"
for item in "$REPO_ROOT"/*; do
item_name=$(basename "$item")
# Skip the directory itself
if [ "$item_name" != "$SAVED_ROOT_FILES_NAME" ]; then
echo "- Moving $item_name to $SAVED_ROOT_FILES_PATH"
mv -f "$item" "$SAVED_ROOT_FILES_PATH/"
fi
done

echo "Moving /packages/react-native contents to root..."

mv -f "$SAVED_ROOT_FILES_PATH/packages/react-native"/* "$REPO_ROOT/"

echo "Script completed successfully"

# Reverse moves
else
echo "Reversing operations: moving files from $SAVED_ROOT_FILES_NAME back to root..."

if [ ! -d "$SAVED_ROOT_FILES_PATH" ]; then
echo "Error: $SAVED_ROOT_FILES_NAME directory not found. Nothing to reverse."
exit 1
fi

echo "Moving react-native package contents to within saved-root-files/packages" # Ensure the directory exists
mkdir -p "$SAVED_ROOT_FILES_PATH/packages/react-native"

for item in "$REPO_ROOT"/*; do
item_name=$(basename "$item")
if [ "$item_name" != "$SAVED_ROOT_FILES_NAME" ]; then
echo "- Moving $item_name back to packages/react-native"
mv -f "$item" "$SAVED_ROOT_FILES_NAME/packages/react-native/"
fi
done

echo "Moving .gitignore back to root"
mv -f "$SAVED_ROOT_FILES_PATH/.gitignore" "$REPO_ROOT/.gitignore"

echo "Moving all files back to root"
mv -f "$SAVED_ROOT_FILES_PATH"/* "$REPO_ROOT/"

echo "Deleting $SAVED_ROOT_FILES_NAME"
rm -rf "$SAVED_ROOT_FILES_PATH"

echo "Reverse operation completed successfully"
exit 0
fi
Loading