Skip to content

Commit 6915fe5

Browse files
Merge branch 'main' into refactor/66418-remove-deprecatedReportsTransactions-in-hasNonReimbursableTransactions-p1
# Conflicts: # src/libs/ReportNameUtils.ts # src/libs/ReportUtils.ts # src/pages/inbox/report/SearchActionHeader.tsx # tests/unit/ReportNameUtilsTest.ts # tests/unit/ReportUtilsTest.ts
2 parents 645ad12 + ec619e1 commit 6915fe5

143 files changed

Lines changed: 3879 additions & 940 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/actions/javascript/getPullRequestIncrementalChanges/index.js

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12887,7 +12887,7 @@ exports["default"] = Git;
1288712887
"use strict";
1288812888

1288912889
Object.defineProperty(exports, "__esModule", ({ value: true }));
12890-
exports.bold = exports.formatLink = exports.success = exports.errorDetail = exports.error = exports.note = exports.warn = exports.info = void 0;
12890+
exports.setOutputStream = exports.bold = exports.formatLink = exports.success = exports.errorDetail = exports.error = exports.note = exports.warn = exports.info = void 0;
1289112891
const COLOR_DIM = '\x1b[2m';
1289212892
const COLOR_RESET = '\x1b[0m';
1289312893
const COLOR_YELLOW = '\x1b[33m';
@@ -12902,32 +12902,58 @@ const EMOJIS = {
1290212902
SUCCESS: '✅',
1290312903
ERROR: '🔴',
1290412904
};
12905+
/** Mirrors the console API: informational levels on stdout, warnings and errors on stderr. */
12906+
const outputStreams = {
12907+
info: 'stdout',
12908+
bold: 'stdout',
12909+
success: 'stdout',
12910+
note: 'stdout',
12911+
warn: 'stderr',
12912+
error: 'stderr',
12913+
errorDetail: 'stderr',
12914+
};
12915+
/**
12916+
* Redirects individual levels; levels left out keep whatever they are set to. Call this at startup
12917+
* from a script whose stdout carries machine-readable output (e.g. JSON parsed by another process),
12918+
* where a stray log line would corrupt the payload: `setOutputStream({info: 'stderr'})`.
12919+
*/
12920+
const setOutputStream = (streams) => {
12921+
Object.assign(outputStreams, streams);
12922+
};
12923+
exports.setOutputStream = setOutputStream;
12924+
const write = (level, ...args) => {
12925+
if (outputStreams[level] === 'stderr') {
12926+
console.error(...args);
12927+
return;
12928+
}
12929+
console.log(...args);
12930+
};
1290512931
const info = (...args) => {
12906-
console.log(EMOJIS.INFO, ...args);
12932+
write('info', EMOJIS.INFO, ...args);
1290712933
};
1290812934
exports.info = info;
1290912935
const bold = (...args) => {
12910-
console.log(COLOR_BOLD, ...args, COLOR_RESET);
12936+
write('bold', COLOR_BOLD, ...args, COLOR_RESET);
1291112937
};
1291212938
exports.bold = bold;
1291312939
const success = (...args) => {
12914-
console.log(`${EMOJIS.SUCCESS}${COLOR_GREEN}`, ...args, COLOR_RESET);
12940+
write('success', `${EMOJIS.SUCCESS}${COLOR_GREEN}`, ...args, COLOR_RESET);
1291512941
};
1291612942
exports.success = success;
1291712943
const warn = (...args) => {
12918-
console.warn(`${EMOJIS.WARN}${COLOR_YELLOW}`, ...args, COLOR_RESET);
12944+
write('warn', `${EMOJIS.WARN}${COLOR_YELLOW}`, ...args, COLOR_RESET);
1291912945
};
1292012946
exports.warn = warn;
1292112947
const note = (...args) => {
12922-
console.log(COLOR_DIM, ...args, COLOR_RESET);
12948+
write('note', COLOR_DIM, ...args, COLOR_RESET);
1292312949
};
1292412950
exports.note = note;
1292512951
const error = (...args) => {
12926-
console.error(`${EMOJIS.ERROR}${COLOR_RED}`, ...args, COLOR_RESET);
12952+
write('error', `${EMOJIS.ERROR}${COLOR_RED}`, ...args, COLOR_RESET);
1292712953
};
1292812954
exports.error = error;
1292912955
const errorDetail = (...args) => {
12930-
console.error(` ${COLOR_RED}↳`, ...args, COLOR_RESET);
12956+
write('errorDetail', ` ${COLOR_RED}↳`, ...args, COLOR_RESET);
1293112957
};
1293212958
exports.errorDetail = errorDetail;
1293312959
const formatLink = (name, url) => `\x1b]8;;${url}\x1b\\${name}\x1b]8;;\x1b\\`;

.github/workflows/publishReactNativeAndroidArtifacts.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ jobs:
5959
id: computePatchesHash
6060
run: |
6161
if [[ '${{ matrix.is_hybrid }}' == 'true' ]]; then
62-
echo "PATCHES_HASH=$(./scripts/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
62+
echo "PATCHES_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
6363
else
64-
echo "PATCHES_HASH=$(./scripts/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
64+
echo "PATCHES_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
6565
fi
6666
6767
- name: Setup Node

.github/workflows/publishReactNativeArtifacts.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ on:
3838
- patches/react-native/react-native+*.patch
3939
- patches/react-native/@react-native+*.patch
4040
- Mobile-Expensify
41-
- scripts/compute-patches-hash.sh
41+
- scripts/artifacts-utils/compute-patches-hash.sh
4242

4343
jobs:
4444
verifyPatches:
@@ -62,8 +62,8 @@ jobs:
6262
if: ${{ github.event.after != '' }}
6363
id: getOldPatchesHash
6464
run: |
65-
echo "HYBRID_APP_HASH=$(./scripts/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
66-
echo "STANDALONE_APP_HASH=$(./scripts/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
65+
echo "HYBRID_APP_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
66+
echo "STANDALONE_APP_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
6767
6868
- name: Get previous react-native version
6969
if: ${{ github.event.after != '' }}
@@ -80,8 +80,8 @@ jobs:
8080
- name: Get new patches hash
8181
id: getNewPatchesHash
8282
run: |
83-
echo "HYBRID_APP_HASH=$(./scripts/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
84-
echo "STANDALONE_APP_HASH=$(./scripts/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
83+
echo "HYBRID_APP_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
84+
echo "STANDALONE_APP_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
8585
8686
- name: Get new react-native version
8787
if: ${{ github.event.after != '' }}

.github/workflows/publishReactNativeiOSArtifacts.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,9 @@ jobs:
211211
id: computePatchesHash
212212
run: |
213213
if [[ '${{ matrix.is_hybrid }}' == 'true' ]]; then
214-
echo "PATCHES_HASH=$(./scripts/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
214+
echo "PATCHES_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches Mobile-Expensify/patches)" >> "$GITHUB_OUTPUT"
215215
else
216-
echo "PATCHES_HASH=$(./scripts/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
216+
echo "PATCHES_HASH=$(./scripts/artifacts-utils/compute-patches-hash.sh patches)" >> "$GITHUB_OUTPUT"
217217
fi
218218
219219
- name: Determine new patched RN version

android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ buildscript {
1616
// "mapbox" indicates the usage of the Mapbox SDK.
1717
RNMapboxMapsImpl = "mapbox"
1818
reactNativeIncludedBuild = gradle.getIncludedBuilds().find { it.name == 'react-native' }
19-
// This is our custom extension that we defined in gradleUtils/PatchedArtifactsSettings.gradle
19+
// This is our custom extension that we defined in scripts/artifacts-utils/android/PatchedArtifactsSettings.gradle
2020
// It enables us to use custom artifacts of patched react-native
2121
patchedArtifactsConfig = project.gradle.settings.extensions.findByName('patchedArtifacts')
2222
}

android/settings.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ plugins {
66
id("com.facebook.react.settings")
77
id("expo-autolinking-settings")
88
}
9-
apply from: "${rootDir}/../gradleUtils/PatchedArtifactsSettings.gradle"
9+
apply from: "${rootDir}/../scripts/artifacts-utils/android/PatchedArtifactsSettings.gradle"
1010

1111
extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand(['npx', 'rock', 'config', '-p', 'android']) }
1212
rootProject.name = 'NewExpensify'
Lines changed: 1 addition & 0 deletions
Loading

config/eslint/eslint.seatbelt.tsv

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@
103103
"../../src/components/AutoCompleteSuggestions/index.tsx" "react-hooks/set-state-in-effect" 1
104104
"../../src/components/AutoSubmitModal.tsx" "@typescript-eslint/no-unsafe-type-assertion" 2
105105
"../../src/components/Avatar.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1
106-
"../../src/components/AvatarButtonWithIcon.tsx" "react-hooks/static-components" 1
107106
"../../src/components/AvatarCropModal/AvatarCropModal.tsx" "no-restricted-imports" 1
108107
"../../src/components/AvatarCropModal/ImageCropView.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1
109108
"../../src/components/AvatarCropModal/Slider.tsx" "@typescript-eslint/no-unsafe-type-assertion" 1
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
# Prebuilt React Native Artifacts
2+
3+
We ship a few [patches](PATCHES.md) on top of `react-native`, so the copy we build against is not the
4+
one published on npm. To avoid every developer compiling it locally, CI builds `react-native` with our
5+
patches applied and publishes it to our private GitHub Packages Maven repository.
6+
7+
At build time a resolver hashes the local patches and looks for a published artifact tagged with the
8+
same hash. On a match the build downloads `react-native` instead of compiling it. If nothing matches —
9+
because you added or edited a patch locally, or because credentials are missing — the build logs a
10+
warning and compiles `react-native` from source, so a miss slows the build down but never fails it.
11+
12+
> [!NOTE]
13+
> These are not the remote builds described in the "Running the mobile application using Rock" sections
14+
> of the [iOS](SETUP_IOS.md) and [Android](SETUP_ANDROID.md) setup guides. Rock downloads a complete
15+
> prebuilt app from S3; the artifacts described here are only the `react-native` core, and the two are
16+
> independent of each other.
17+
18+
## Configuring GitHub CLI
19+
20+
The artifacts live in a private package registry, so a build has to authenticate. Locally the
21+
credentials come from the GitHub CLI:
22+
23+
1. **Install GitHub CLI**
24+
- Install GitHub CLI by following the instructions from [cli.github.com](https://cli.github.com/)
25+
26+
2. **Create a GitHub Personal Access Token**
27+
- Go to [GitHub Settings > Developer Settings > Personal Access Tokens](https://github.com/settings/tokens)
28+
- Click "Generate new token (classic)"
29+
- Select the following scopes:
30+
- `repo`
31+
- `read:org`
32+
- `gist`
33+
- `read:packages`
34+
- Copy the generated token
35+
36+
3. **Login to GitHub CLI**
37+
```bash
38+
echo "YOUR_TOKEN" | gh auth login --with-token
39+
```
40+
41+
4. **Verify Login**
42+
```bash
43+
gh auth status
44+
```
45+
You should see a message confirming you are authenticated with your GitHub account, and
46+
`read:packages` among the token scopes.
47+
48+
Without a usable token the build still works, it just compiles `react-native` from source. The
49+
resolver says which part of the setup is missing, so check the build log if you expected a prebuilt.
50+
51+
In CI there is no GitHub CLI: the credentials are taken from the `GITHUB_TOKEN` and `GITHUB_ACTOR`
52+
environment variables that the workflow provides.
53+
54+
## Disabling prebuilt artifacts on Android
55+
56+
Prebuilt artifacts are enabled by default. To compile `react-native` from source instead:
57+
58+
- Open `android/gradle.properties` (for standalone NewDot) or `Mobile-Expensify/Android/gradle.properties`
59+
(for HybridApp)
60+
- Set `patchedArtifacts.forceBuildFromSource=true`
61+
62+
To force it for a single Gradle invocation, without editing the properties file:
63+
64+
<!-- cspell:ignore Ppatched -- Gradle's -P flag makes `-PpatchedArtifacts` tokenize as Ppatched + Artifacts -->
65+
66+
```bash
67+
./gradlew <task> -PpatchedArtifacts.forceBuildFromSource=true
68+
```
69+
70+
## Disabling prebuilt artifacts on iOS
71+
72+
Prebuilt artifacts are enabled by default for HybridApp. Standalone NewDot always compiles
73+
`react-native` from source: under `use_frameworks! :linkage => :static` (required by Firebase) the
74+
prebuilt React Core cannot expose `React_RCTAppDelegate` as an importable Swift module, which the
75+
standalone Swift `AppDelegate` needs. HybridApp is unaffected, because its `AppDelegate` is written in
76+
Objective-C and imports that header directly.
77+
78+
To compile `react-native` from source in HybridApp, set `BUILD_RN_FROM_SOURCE` when installing pods:
79+
80+
```bash
81+
BUILD_RN_FROM_SOURCE=1 npm run pod-install
82+
```
83+
84+
The flag is read during `pod install`, so switching it requires reinstalling the pods, not just
85+
rebuilding.
86+
87+
To get symbolicated native stack traces from a prebuilt React Core, install the pods with the dSYMs:
88+
89+
```bash
90+
RCT_SYMBOLICATE_PREBUILT_FRAMEWORKS=1 npm run pod-install
91+
```

contributingGuides/SETUP_ANDROID.md

Lines changed: 4 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -76,43 +76,11 @@ If you haven't done any intentional edits outside of `src/` (like adding new dep
7676
- To point the **Development Emulator** at your local VM, follow [these steps](https://stackoverflow.com/c/expensify/questions/7699).
7777
- You must configure the local dev email account; follow [these instructions](https://stackoverflowteams.com/c/expensify/questions/23537/23538#23538).
7878

79-
## Enabling Prebuilt React Native Artifacts
79+
## Prebuilt React Native Artifacts
8080

81-
By default, `react-native` is built from source when building the Android app. However, you can enable prebuilt artifacts to speed up the build process:
82-
83-
### Disabling Build from Source
84-
- Open `android/gradle.properties` (for Standalone NewDot) or `Mobile-Expensify/Android/gradle.properties` (for HybridApp)
85-
- Set `patchedArtifacts.forceBuildFromSource=false`
86-
87-
### Configuring GitHub CLI
88-
89-
To use prebuilt artifacts, you need to have GitHub CLI installed and configured:
90-
91-
1. **Install GitHub CLI**
92-
- Install GitHub CLI by following the instructions from [cli.github.com](https://cli.github.com/)
93-
94-
2. **Create a GitHub Personal Access Token**
95-
- Go to [GitHub Settings > Developer Settings > Personal Access Tokens](https://github.com/settings/tokens)
96-
- Click "Generate new token (classic)"
97-
- Select the following scopes:
98-
- `repo`
99-
- `read:org`
100-
- `gist`
101-
- `read:packages`
102-
- Copy the generated token
103-
104-
3. **Login to GitHub CLI**
105-
```bash
106-
echo "YOUR_TOKEN" | gh auth login --with-token
107-
```
108-
109-
4. **Verify Login**
110-
```bash
111-
gh auth status
112-
```
113-
You should see a message confirming you are authenticated with your GitHub account.
114-
115-
After completing these steps, you should be able to build Android apps with prebuilt `react-native` artifacts.
81+
Android builds download a prebuilt `react-native` from GitHub Packages instead of compiling it, which
82+
requires an authenticated GitHub CLI. See [Prebuilt React Native Artifacts](PREBUILT_REACT_NATIVE_ARTIFACTS.md)
83+
for the setup and for how to compile from source instead.
11684

11785
## Push Notifications Setup
11886

0 commit comments

Comments
 (0)