-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Create prebuilt React Native artifacts #59738
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Create prebuilt React Native artifacts #59738
Conversation
|
|
|
|
|
@roryabraham PR in the current form should be ready, feel free to review it. I tested it on my forked I have a few things to mention/discuss:
|
COMMIT_HASH: ${{ github.event.after }} | ||
PATCHES_HASH: ${{ env.PATCHES_HASH }} | ||
|
||
buildAndPublishRNArtifactsForHybridApp: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is almost the same as buildAndPublishRNArtifactsForStandaloneNewDot
. Maybe I’ll manage to create a composite action.
fi | ||
|
||
IFS=' ' read -ra PATCH_DIRS <<< "$PATCHES_PATHS" | ||
find "${PATCH_DIRS[@]}" -type f -name "react-native+${VERSION}*.patch" -exec sha256sum {} + | sort | sha256sum | awk '{print $1}' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we have to add VERSION
here? 🤔 Couldn't we go with react-native+*.patch
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmmm good point, I assumed that it's just safer to take react-native+${VERSION}*.patch
into consideration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about related packages such as @react-native/gradle-plugin
or @react-native/virtualized-lists
?
I see patches such as @react-native+gradle-plugin+{version}.patch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this is something we should definitely add. I wasn’t sure about it at first, but it could be critical. @react-native
includes a codegen subpackage that generates C++ code, and I bet other packages like gradle-plugin
could also affect the final form of the prebuilt artifacts. I’ll take care of it today.
VERSIONS_FROM_MAVEN_REPOSITORY=$(curl -s -H "Authorization: Bearer ${GITHUB_TOKEN}" \ | ||
"$MAVEN_METADATA_URL" | \ | ||
grep -o "<version>${VERSION}-[0-9]\+</version>" | \ | ||
grep -o "${VERSION}-[0-9]" | \ | ||
sort -t'-' -k2 -n) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd appreciate comments on what's going on here 🙏
paths: | ||
- package.json | ||
- patches/react-native+*.patch | ||
- Mobile-Expensify |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's going to be triggered very often :/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, but there's not much we can do about it.
We could potentially move HybridApp artifacts job to Mobile-Expenisfy
repository and there add path patches/react-native+*.patch
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's wait for the others to discuss 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's ok. package.json
changes just as frequently as Mobile-Expensify
(with every version bump)
echo "Detected changes in HybridApp patches:" | ||
git -C Mobile-Expensify diff --name-only $PREVIOUS_SUBMODULE_COMMIT..$CURRENT_SUBMODULE_COMMIT -- "patches/react-native+*.patch" | ||
env: | ||
PATCHES_PATHS: "Mobile-Expensify/patches" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PATCHES_PATHS: "Mobile-Expensify/patches" | |
PATCHES_PATH: "Mobile-Expensify/patches" |
? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can pass many paths separated by space. It is used to compute patches in HybridApp scenario where we need to consider both patches
directories.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking that maybe we could move all patches to App repository and slightly refactor them to work on both standalone and HybridApp.
This would allow us to build only one react-android
package, but it's a significant amount of work, so it could be a separate issue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd rather keep HybridApp-related patches in Mobile-Expensify as we do now
buildAndPublishRNArtifactsForStandaloneNewDot: | ||
runs-on: ubuntu-latest | ||
if: ${{ always() && needs.verifyNewDotPatchesAndReactNativeVersion.result == 'success'}} | ||
needs: verifyNewDotPatchesAndReactNativeVersion |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's move it above if
🙏
|
||
buildAndPublishRNArtifactsForStandaloneNewDot: | ||
runs-on: ubuntu-latest | ||
if: ${{ always() && needs.verifyNewDotPatchesAndReactNativeVersion.result == 'success'}} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need always
here? And what does it do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, maybe it's not needed here 🤔 always ensures that the job runs even if any of the required jobs have failed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the other hand, buildAndPublishRNArtifactsForHybridApp
needs to use always()
because we need to ensure it runs as long as at least one required job hasn't failed.
echo "Version: ${{ env.NEW_PATCHED_VERSION }}" | ||
echo "Commit hash: ${{ env.COMMIT_HASH }}" | ||
echo "Patches hash: ${{ env.PATCHES_HASH }}" | ||
export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where do those versions come from?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From previous step
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh sorry, I meant the architectures 😅
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Full diff of my requested changes:
full diff
diff --git a/.github/scripts/computePatchesHash.sh b/.github/scripts/computePatchesHash.sh
deleted file mode 100755
index 196f49bcf21..00000000000
--- a/.github/scripts/computePatchesHash.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/bin/bash
-
-if [ -z "$VERSION" ]; then
- echo "VERSION env variable is not set"
- exit 1
-fi
-
-if [ -z "$PATCHES_PATHS" ]; then
- echo "PATCHES_PATHS env variable is not set"
- exit 1
-fi
-
-IFS=' ' read -ra PATCH_DIRS <<< "$PATCHES_PATHS"
-find "${PATCH_DIRS[@]}" -type f -name "react-native+${VERSION}*.patch" -exec sha256sum {} + | sort | sha256sum | awk '{print $1}'
diff --git a/.github/scripts/getNewPatchedRNVersion.sh b/.github/scripts/getNewPatchedRNVersion.sh
index 8b84b8cd5e8..736249e5769 100755
--- a/.github/scripts/getNewPatchedRNVersion.sh
+++ b/.github/scripts/getNewPatchedRNVersion.sh
@@ -1,9 +1,6 @@
#!/bin/bash
-if [ -z "$VERSION" ]; then
- echo "VERSION env variable is not set"
- exit 1
-fi
+VERSION="$(jq -r '.dependencies["react-native"]' package.json)"
if [[ "$IS_HYBRID_BUILD" == "true" ]]; then
PACKAGE="react-hybrid"
diff --git a/.github/workflows/buildAndPublishReactNativeArtifacts.yml b/.github/workflows/buildAndPublishReactNativeArtifacts.yml
index b39aeaca0d6..5ea26af58d0 100644
--- a/.github/workflows/buildAndPublishReactNativeArtifacts.yml
+++ b/.github/workflows/buildAndPublishReactNativeArtifacts.yml
@@ -10,204 +10,112 @@ on:
- Mobile-Expensify
jobs:
- verifyNewDotPatchesAndReactNativeVersion:
- runs-on: ubuntu-latest
+ publish:
+ runs-on: ${{ github.repository_owner == 'Expensify' && 'ubuntu-latest-xl' || 'ubuntu-latest' }}
+ strategy:
+ matrix:
+ is_hybrid: [true, false]
+ env:
+ PATCHES_PATHS: ${{ matrix.is_hybrid && 'Mobile-Expensify/patches' || 'patches' }}
steps:
+ # v4
- name: Checkout
- # v4
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
-
- - name: Check if NewDot patches or react-native version have changed
- run: |
- VERSION=$(jq -r '.dependencies["react-native"]' package.json)
- HASH=$(VERSION=$VERSION ./.github/scripts/computePatchesHash.sh)
-
- git fetch origin ${{ github.event.before }}
- git checkout ${{ github.event.before }}
-
- OLD_VERSION=$(jq -r '.dependencies["react-native"]' package.json)
- # If version has changed and we want to find differences in patches, we need to consider pattern that involves previous react-native version
- OLD_HASH=$(VERSION=$OLD_VERSION ./.github/scripts/computePatchesHash.sh)
-
- if [ "$HASH" == "$OLD_HASH" ] && [ "$VERSION" == "$OLD_VERSION" ]; then
- echo "No relevant changes"
- exit 1
- fi
-
- if [ "$VERSION" != "$OLD_VERSION" ]; then
- echo "Detected react-native version bump ($OLD_VERSION -> $VERSION)"
- exit 0
- fi
-
- if [ "$HASH" != "$OLD_HASH" ]; then
- echo "Detected changes in NewDot patches:"
- git diff --name-only ${{ github.event.before }}..${{ github.event.after }} -- "patches/react-native+*.patch"
- fi
- env:
- PATCHES_PATHS: "patches"
-
- verifyHybridAppPatches:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- # v4
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
with:
- submodules: true
- fetch-depth: 0
- - name: Get react-native version
- run: |
- echo "VERSION=$(jq -r '.dependencies["react-native"]' package.json)" >> $GITHUB_ENV
+ submodules: ${{ matrix.is_hybrid }}
+ ref: ${{ github.event.before }}
- - name: Check if HybridApp patches have changed
- run: |
- CURRENT_SUBMODULE_COMMIT=$(git rev-parse :Mobile-Expensify)
- CURRENT_PATCHES_HASH=$(./.github/scripts/computePatchesHash.sh)
-
- git fetch origin ${{ github.event.before }}
- git checkout ${{ github.event.before }}
+ - name: Get previous commit hash
+ id: getOldHash
+ run: echo "HASH=$(git rev-parse ${{ matrix.is_hybrid == 'true' && ':Mobile-Expensify' || 'HEAD' }})" >> "$GITHUB_OUTPUT"
- git submodule update
-
- PREVIOUS_SUBMODULE_COMMIT=$(git rev-parse :Mobile-Expensify)
-
- if [ "$CURRENT_SUBMODULE_COMMIT" == "$PREVIOUS_SUBMODULE_COMMIT" ]; then
- echo "Submodule commit is the same as the previous one, skipping patch check"
- exit 1
- fi
-
- PREVIOUS_PATCHES_HASH=$(./.github/scripts/computePatchesHash.sh)
-
- if [ "$CURRENT_PATCHES_HASH" == "$PREVIOUS_PATCHES_HASH" ]; then
- echo "No changes in HybridApp patches"
- exit 1
- fi
-
- echo "Detected changes in HybridApp patches:"
- git -C Mobile-Expensify diff --name-only $PREVIOUS_SUBMODULE_COMMIT..$CURRENT_SUBMODULE_COMMIT -- "patches/react-native+*.patch"
- env:
- PATCHES_PATHS: "Mobile-Expensify/patches"
- VERSION: ${{ env.VERSION }}
+ - name: Get previous react-native version
+ id: getOldVersion
+ run: echo "VERSION=$(jq -r '.dependencies["react-native"]' package.json)" >> "$GITHUB_OUTPUT"
- buildAndPublishRNArtifactsForStandaloneNewDot:
- runs-on: ubuntu-latest
- if: ${{ always() && needs.verifyNewDotPatchesAndReactNativeVersion.result == 'success'}}
- needs: verifyNewDotPatchesAndReactNativeVersion
- steps:
- - name: Checkout
- # v4
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
-
- - name: Get react-native version
+ - name: Checkout new ref
run: |
- echo "VERSION=$(jq -r '.dependencies["react-native"]' package.json)" >> $GITHUB_ENV
-
- - name: Setup Node
- uses: ./.github/actions/composite/setupNode
-
- - name: Setup Java
- # v4
- uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12
- with:
- distribution: oracle
- java-version: 17
+ git fetch origin ${{ github.event.after }} --depth=1
+ git checkout ${{ github.event.after }}
+ git submodule update
- - name: Setup Gradle
- # v4
- uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244
+ - name: Get new commit hash
+ id: getNewHash
+ run: echo "HASH=$(git rev-parse ${{ matrix.is_hybrid == 'true' && ':Mobile-Expensify' || 'HEAD' }})" >> "$GITHUB_OUTPUT"
- - name: Save patches hash
- run: |
- echo "PATCHES_HASH=$(./.github/scripts/computePatchesHash.sh)" >> $GITHUB_ENV
- env:
- VERSION: ${{ env.VERSION }}
- PATCHES_PATHS: "patches"
+ - name: Get new react-native version
+ id: getNewVersion
+ run: echo "VERSION=$(jq -r '.dependencies["react-native"]' package.json)" >> "$GITHUB_OUTPUT"
- - name: Determine new patched RN version
+ - name: Check if version changed
+ id: didVersionChange
run: |
- echo "NEW_PATCHED_VERSION=$(./.github/scripts/getNewPatchedRNVersion.sh)" >> $GITHUB_ENV
- env:
- VERSION: ${{ env.VERSION }}
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- IS_HYBRID_BUILD: "false"
+ readonly DID_VERSION_CHANGE=${{ steps.getOldVersion.outputs.VERSION != steps.getNewVersion.outputs.VERSION && 'true' || 'false' }}
+ echo "DID_VERSION_CHANGE=$DID_VERSION_CHANGE" >> "$GITHUB_OUTPUT"
+ if [[ "$DID_VERSION_CHANGE" == 'true' ]]; then
+ echo "::notice::Detected react-native version bump (${{ steps.getOldVersion.outputs.VERSION }} -> ${{ steps.getNewVersion.outputs.VERSION }})"
+ fi
- - name: Build and publish RN artifacts
+ - name: Check if patches changed
+ id: didPatchesChange
run: |
- cd android
- echo "Starting artifacts build for standalone NewDot"
- echo "Version: ${{ env.NEW_PATCHED_VERSION }}"
- echo "Commit hash: ${{ env.COMMIT_HASH }}"
- echo "Patches hash: ${{ env.PATCHES_HASH }}"
- export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64"
- ./gradlew buildReactNativeArtifacts -x lint -x test -x check
- ./gradlew publishReactNativeArtifacts
- env:
- GH_PUBLISH_ACTOR: ${{ github.actor }}
- GH_PUBLISH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- IS_HYBRID_BUILD: "false"
- PATCHED_VERSION: ${{ env.NEW_PATCHED_VERSION }}
- COMMIT_HASH: ${{ github.event.after }}
- PATCHES_HASH: ${{ env.PATCHES_HASH }}
-
- buildAndPublishRNArtifactsForHybridApp:
- runs-on: ubuntu-latest
- if: ${{ always() && (needs.verifyNewDotPatchesAndReactNativeVersion.result == 'success' || needs.verifyHybridAppPatches.result == 'success')}}
- needs: [verifyNewDotPatchesAndReactNativeVersion, verifyHybridAppPatches]
- steps:
- - name: Checkout
- # v4
- uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
- with:
- submodules: true
+ if git ${{ matrix.is_hybrid == 'true' && '-C Mobile-Expensify' }} diff --exit-code --name-only ${{ steps.getOldHash.outputs.HASH }}..${{ steps.getNewHash.outputs.HASH }} -- patches/react-native+*.patch; then
+ echo "::notice::Detected changes in NewDot patches"
+ echo "DID_PATCHES_CHANGE=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "DID_PATCHES_CHANGE=false" >> "$GITHUB_OUTPUT"
+ fi
- - name: Get react-native version
+ - name: Check if we should build and publish the package
+ id: shouldPublish
run: |
- echo "VERSION=$(jq -r '.dependencies["react-native"]' package.json)" >> $GITHUB_ENV
+ if [[ '${{ steps.didVersionChange.outputs.DID_VERSION_CHANGE }}' == 'true' || '${{ steps.didPatchesChange.outputs.DID_PATCHES_CHANGE }}' == 'true ]]; then
+ echo "SHOULD_PUBLISH=true" >> "$GITHUB_OUTPUT"
+ else
+ echo "::notice::No relevant changes, skipping publishing a new React Native build"
+ echo "SHOULD_PUBLISH=false" >> "$GITHUB_OUTPUT"
+ fi
- name: Setup Node
+ if: ${{ steps.shouldPublish.outputs.SHOULD_PUBLISH == 'true' }}
uses: ./.github/actions/composite/setupNode
with:
- IS_HYBRID_BUILD: "true"
+ IS_HYBRID_BUILD: ${{ matrix.is_hybrid }}
+ # v4
- name: Setup Java
- # v4
+ if: ${{ steps.shouldPublish.outputs.SHOULD_PUBLISH == 'true' }}
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12
with:
distribution: oracle
java-version: 17
+ # v4
- name: Setup Gradle
- # v4
+ if: ${{ steps.shouldPublish.outputs.SHOULD_PUBLISH == 'true' }}
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244
- - name: Save patches hash
- run: |
- echo "PATCHES_HASH=$(./.github/scripts/computePatchesHash.sh)" >> $GITHUB_ENV
- env:
- VERSION: ${{ env.VERSION }}
- PATCHES_PATHS: "patches Mobile-Expensify/patches"
-
- name: Determine new patched RN version
- run: |
- echo "NEW_PATCHED_VERSION=$(./.github/scripts/getNewPatchedRNVersion.sh)" >> $GITHUB_ENV
+ if: ${{ steps.shouldPublish.outputs.SHOULD_PUBLISH == 'true' }}
+ id: getNewPatchedVersion
+ run: echo "NEW_PATCHED_VERSION=$(./.github/scripts/getNewPatchedRNVersion.sh)" >> $GITHUB_OUTPUT
env:
- VERSION: ${{ env.VERSION }}
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- IS_HYBRID_BUILD: "true"
+ GITHUB_TOKEN: ${{ github.token }}
+ IS_HYBRID_BUILD: ${{ matrix.is_hybrid }}
+
- name: Build and publish RN artifacts
+ if: ${{ steps.shouldPublish.outputs.SHOULD_PUBLISH == 'true' }}
+ working-directory: ${{ matrix.is_hybrid == 'true' && 'Mobile-Expensify/Android' || 'android' }}
run: |
- cd Mobile-Expensify/Android
- echo "Starting artifacts build for HybridApp"
- echo "Version: ${{ env.NEW_PATCHED_VERSION }}"
+ echo "Starting artifacts build for ${{ matrix.is_hybrid == 'true' && 'HybridApp' || 'NewDot Standalone' }}"
+ echo "Version: ${{ env.PATCHED_VERSION }}"
echo "Commit hash: ${{ env.COMMIT_HASH }}"
- echo "Patches hash: ${{ env.PATCHES_HASH }}"
export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64"
./gradlew buildReactNativeArtifacts -x lint -x test -x check
./gradlew publishReactNativeArtifacts
env:
GH_PUBLISH_ACTOR: ${{ github.actor }}
- GH_PUBLISH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- IS_HYBRID_BUILD: "true"
- PATCHED_VERSION: ${{ env.NEW_PATCHED_VERSION }}
+ GH_PUBLISH_TOKEN: ${{ github.token }}
+ IS_HYBRID_BUILD: ${{ matrix.is_hybrid }}
+ PATCHED_VERSION: ${{ steps.getNewPatchedVersion.outputs.NEW_PATCHED_VERSION }}
COMMIT_HASH: ${{ github.event.after }}
- PATCHES_HASH: ${{ env.PATCHES_HASH }}
diff --git a/patches/react-native+0.77.1+024+publish-gradle.patch b/patches/react-native+0.77.1+024+publish-gradle.patch
index 415b83af56e..e7e7877be6d 100644
--- a/patches/react-native+0.77.1+024+publish-gradle.patch
+++ b/patches/react-native+0.77.1+024+publish-gradle.patch
@@ -4,7 +4,7 @@ index 32287a7..68c9284 100644
+++ b/node_modules/react-native/ReactAndroid/publish.gradle
@@ -13,7 +13,11 @@ def signingKey = findProperty("SIGNING_KEY")
def signingPwd = findProperty("SIGNING_PWD")
-
+
def reactAndroidProjectDir = project(':packages:react-native:ReactAndroid').projectDir
-def mavenTempLocalUrl = "file:///tmp/maven-local"
+def mavenURL = "https://maven.pkg.github.com/Expensify/App"
@@ -12,13 +12,13 @@ index 32287a7..68c9284 100644
+def patchedVersion = System.getenv("PATCHED_VERSION")
+def isHybridBuild = System.getenv("IS_HYBRID_BUILD")?.toBoolean()
+def publishingGroupId = isHybridBuild ? "com.expensify.react-standalone" : "com.expensify.react-hybrid"
-
+
publishing {
publications {
@@ -26,12 +30,14 @@ publishing {
}
}
-
+
+ groupId = publishingGroupId
+
// We populate the publishing version using the project version,
@@ -30,14 +30,13 @@ index 32287a7..68c9284 100644
- version = this.version
+ version = patchedVersion
}
-
+
pom {
@@ -39,10 +45,15 @@ publishing {
description = "A framework for building native apps with React"
url = "https://github.com/facebook/react-native"
-
+
+ properties = [
-+ "patchesHash": System.getenv("PATCHES_HASH"),
+ "commitHash": System.getenv("COMMIT_HASH"),
+ ]
+
@@ -49,9 +48,9 @@ index 32287a7..68c9284 100644
+ name = "Expensify"
}
}
-
+
@@ -65,8 +76,11 @@ publishing {
-
+
repositories {
maven {
- name = "mavenTempLocal"
Just the workflow, because the diff is hard to read
name: Build and publish React Native artifacts
on:
push:
branches:
- main
paths:
- package.json
- patches/react-native+*.patch
- Mobile-Expensify
jobs:
publish:
runs-on: ${{ github.repository_owner == 'Expensify' && 'ubuntu-latest-xl' || 'ubuntu-latest' }}
strategy:
matrix:
is_hybrid: [true, false]
env:
PATCHES_PATHS: ${{ matrix.is_hybrid && 'Mobile-Expensify/patches' || 'patches' }}
steps:
# v4
- name: Checkout
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608
with:
submodules: ${{ matrix.is_hybrid }}
ref: ${{ github.event.before }}
- name: Get previous commit hash
id: getOldHash
run: echo "HASH=$(git rev-parse ${{ matrix.is_hybrid == 'true' && ':Mobile-Expensify' || 'HEAD' }})" >> "$GITHUB_OUTPUT"
- name: Get previous react-native version
id: getOldVersion
run: echo "VERSION=$(jq -r '.dependencies["react-native"]' package.json)" >> "$GITHUB_OUTPUT"
- name: Checkout new ref
run: |
git fetch origin ${{ github.event.after }} --depth=1
git checkout ${{ github.event.after }}
git submodule update
- name: Get new commit hash
id: getNewHash
run: echo "HASH=$(git rev-parse ${{ matrix.is_hybrid == 'true' && ':Mobile-Expensify' || 'HEAD' }})" >> "$GITHUB_OUTPUT"
- name: Get new react-native version
id: getNewVersion
run: echo "VERSION=$(jq -r '.dependencies["react-native"]' package.json)" >> "$GITHUB_OUTPUT"
- name: Check if version changed
id: didVersionChange
run: |
readonly DID_VERSION_CHANGE=${{ steps.getOldVersion.outputs.VERSION != steps.getNewVersion.outputs.VERSION && 'true' || 'false' }}
echo "DID_VERSION_CHANGE=$DID_VERSION_CHANGE" >> "$GITHUB_OUTPUT"
if [[ "$DID_VERSION_CHANGE" == 'true' ]]; then
echo "::notice::Detected react-native version bump (${{ steps.getOldVersion.outputs.VERSION }} -> ${{ steps.getNewVersion.outputs.VERSION }})"
fi
- name: Check if patches changed
id: didPatchesChange
run: |
if git ${{ matrix.is_hybrid == 'true' && '-C Mobile-Expensify' }} diff --exit-code --name-only ${{ steps.getOldHash.outputs.HASH }}..${{ steps.getNewHash.outputs.HASH }} -- patches/react-native+*.patch; then
echo "::notice::Detected changes in NewDot patches"
echo "DID_PATCHES_CHANGE=true" >> "$GITHUB_OUTPUT"
else
echo "DID_PATCHES_CHANGE=false" >> "$GITHUB_OUTPUT"
fi
- name: Check if we should build and publish the package
id: shouldPublish
run: |
if [[ '${{ steps.didVersionChange.outputs.DID_VERSION_CHANGE }}' == 'true' || '${{ steps.didPatchesChange.outputs.DID_PATCHES_CHANGE }}' == 'true ]]; then
echo "SHOULD_PUBLISH=true" >> "$GITHUB_OUTPUT"
else
echo "::notice::No relevant changes, skipping publishing a new React Native build"
echo "SHOULD_PUBLISH=false" >> "$GITHUB_OUTPUT"
fi
- name: Setup Node
if: ${{ steps.shouldPublish.outputs.SHOULD_PUBLISH == 'true' }}
uses: ./.github/actions/composite/setupNode
with:
IS_HYBRID_BUILD: ${{ matrix.is_hybrid }}
# v4
- name: Setup Java
if: ${{ steps.shouldPublish.outputs.SHOULD_PUBLISH == 'true' }}
uses: actions/setup-java@3a4f6e1af504cf6a31855fa899c6aa5355ba6c12
with:
distribution: oracle
java-version: 17
# v4
- name: Setup Gradle
if: ${{ steps.shouldPublish.outputs.SHOULD_PUBLISH == 'true' }}
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244
- name: Determine new patched RN version
if: ${{ steps.shouldPublish.outputs.SHOULD_PUBLISH == 'true' }}
id: getNewPatchedVersion
run: echo "NEW_PATCHED_VERSION=$(./.github/scripts/getNewPatchedRNVersion.sh)" >> $GITHUB_OUTPUT
env:
GITHUB_TOKEN: ${{ github.token }}
IS_HYBRID_BUILD: ${{ matrix.is_hybrid }}
- name: Build and publish RN artifacts
if: ${{ steps.shouldPublish.outputs.SHOULD_PUBLISH == 'true' }}
working-directory: ${{ matrix.is_hybrid == 'true' && 'Mobile-Expensify/Android' || 'android' }}
run: |
echo "Starting artifacts build for ${{ matrix.is_hybrid == 'true' && 'HybridApp' || 'NewDot Standalone' }}"
echo "Version: ${{ env.PATCHED_VERSION }}"
echo "Commit hash: ${{ env.COMMIT_HASH }}"
export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64"
./gradlew buildReactNativeArtifacts -x lint -x test -x check
./gradlew publishReactNativeArtifacts
env:
GH_PUBLISH_ACTOR: ${{ github.actor }}
GH_PUBLISH_TOKEN: ${{ github.token }}
IS_HYBRID_BUILD: ${{ matrix.is_hybrid }}
PATCHED_VERSION: ${{ steps.getNewPatchedVersion.outputs.NEW_PATCHED_VERSION }}
COMMIT_HASH: ${{ github.event.after }}
@@ -0,0 +1,14 @@ | |||
#!/bin/bash | |||
|
|||
if [ -z "$VERSION" ]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per our bash style guide (which is currently not living in a public repo), prefer [[
if [ -z "$VERSION" ]; then | |
if [[ -z "$VERSION" ]]; then |
exit 1 | ||
fi | ||
|
||
if [ -z "$PATCHES_PATHS" ]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if [ -z "$PATCHES_PATHS" ]; then | |
if [[ -z "$PATCHES_PATHS" ]]; then |
#!/bin/bash | ||
|
||
if [ -z "$VERSION" ]; then | ||
echo "VERSION env variable is not set" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NAB but you could source shellUtils.sh
and then use info
, warning
, error
for colored output
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you do this, the preferred way to get the script dir is:
SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)"
readonly SCRIPT_DIR
fi | ||
|
||
IFS=' ' read -ra PATCH_DIRS <<< "$PATCHES_PATHS" | ||
find "${PATCH_DIRS[@]}" -type f -name "react-native+${VERSION}*.patch" -exec sha256sum {} + | sort | sha256sum | awk '{print $1}' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about related packages such as @react-native/gradle-plugin
or @react-native/virtualized-lists
?
I see patches such as @react-native+gradle-plugin+{version}.patch
@@ -0,0 +1,30 @@ | |||
#!/bin/bash | |||
|
|||
if [ -z "$VERSION" ]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if [ -z "$VERSION" ]; then | |
if [[ -z "$VERSION" ]]; then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, can we just simplify this by doing this inside the script rather than having to set an environment variable?
VERSION="$(jq -r '.dependencies["react-native"]' package.json)"
readonly VERSION;
env: | ||
PATCHES_PATHS: "patches" | ||
|
||
verifyHybridAppPatches: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can DRY this workflow up a lot using a matrix strategy.
|
||
if [ "$HASH" != "$OLD_HASH" ]; then | ||
echo "Detected changes in NewDot patches:" | ||
git diff --name-only ${{ github.event.before }}..${{ github.event.after }} -- "patches/react-native+*.patch" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at this, I've just realized that we don't actually need computePatchesHash
at all ... we can just use git diff
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NAB but I'd call this workflow publishReactNativeAndroidArtifacts
paths: | ||
- package.json | ||
- patches/react-native+*.patch | ||
- Mobile-Expensify |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's ok. package.json
changes just as frequently as Mobile-Expensify
(with every version bump)
VERSION: ${{ env.VERSION }} | ||
|
||
buildAndPublishRNArtifactsForStandaloneNewDot: | ||
runs-on: ubuntu-latest |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can use large runners for the build, but only on Expensify org. Otherwise GitHub will start billing anyone for large runner minutes if they push code to main in their fork:
runs-on: ubuntu-latest | |
runs-on: ${{ github.repository_owner == 'Expensify' && 'ubuntu-latest-xl' || 'ubuntu-latest' }} |
I'm not sure what you mean by this.
Looks like So we should be good with the standard token rather than another bot token |
Sorry, I meant that this PR only added mechanism that builds I thought it would be nice to implement this second part in another PR as it gives us better control and minimizes the risk of breaking local or CI builds if something goes wrong. |
Cool, that makes sense to me - create the artifacts in one PR and consume them in another |
Explanation of Change
TO DO:
react-native
patches)Fixed Issues
$ #57120
PROPOSAL:
Tests
Offline tests
QA Steps
// TODO: These must be filled out, or the issue title must include "[No QA]."
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)src/languages/*
files and using the translation methodSTYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)Design
label and/or tagged@Expensify/design
so the design team can review the changes.ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Android: Native
Android: mWeb Chrome
iOS: Native
iOS: mWeb Safari
MacOS: Chrome / Safari
MacOS: Desktop