Skip to content

Commit 9a2da80

Browse files
committed
Merge branch 'main' into perf-scan-page/preload-fab-icons
2 parents 0f5df86 + 483e438 commit 9a2da80

471 files changed

Lines changed: 8287 additions & 8701 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/workflows/publishReactNativeAndroidArtifacts.yml

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ jobs:
126126
name: Build and Publish React Native Artifacts
127127
runs-on: ${{ github.repository_owner == 'Expensify' && 'blacksmith-16vcpu-ubuntu-2404' || 'blacksmith-2vcpu-ubuntu-2404' }}
128128
needs: verifyPatches
129-
if: needs.verifyPatches.outputs.build_targets != ''
129+
if: needs.verifyPatches.outputs.build_targets != ''
130130
strategy:
131131
# Disable fail-fast to prevent cancelling both jobs when only one needs to be stopped due to concurrency limits
132132
fail-fast: false
@@ -160,7 +160,7 @@ jobs:
160160

161161
- name: Setup Gradle
162162
uses: gradle/actions/setup-gradle@06832c7b30a0129d7fb559bcc6e43d26f6374244
163-
163+
164164
- name: Determine new patched RN version
165165
id: getNewPatchedVersion
166166
run: echo "NEW_PATCHED_VERSION=$(./.github/scripts/getNewPatchedRNVersion.sh)" >> "$GITHUB_OUTPUT"
@@ -175,14 +175,26 @@ jobs:
175175
echo "Version: ${{ env.PATCHED_VERSION }}"
176176
echo "Patches hash: ${{ env.PATCHES_HASH }}"
177177
export ORG_GRADLE_PROJECT_reactNativeArchitectures="armeabi-v7a,arm64-v8a,x86,x86_64"
178-
./gradlew buildReactNativeArtifacts -PpatchedArtifacts.forceBuildFromSource=true -x lint -x test -x check
178+
179+
# Exclude ktfmt and test tasks from the included react-native build
180+
EXCLUDE_TASKS=(
181+
-x :react-native:packages:react-native:ReactAndroid:ktfmtCheck
182+
-x :react-native:packages:react-native:ReactAndroid:ktfmtCheckMain
183+
-x :react-native:packages:react-native:ReactAndroid:ktfmtCheckScripts
184+
-x :react-native:packages:react-native:ReactAndroid:testDebugOptimizedUnitTest
185+
-x :react-native:packages:react-native:ReactAndroid:testDebugUnitTest
186+
-x :react-native:packages:react-native:ReactAndroid:testReleaseUnitTest
187+
)
188+
189+
./gradlew buildReactNativeArtifacts -PpatchedArtifacts.forceBuildFromSource=true -x lint -x test -x check "${EXCLUDE_TASKS[@]}"
179190
./gradlew publishReactNativeArtifacts -PpatchedArtifacts.forceBuildFromSource=true
180191
env:
181192
GH_PUBLISH_ACTOR: ${{ github.actor }}
182193
GH_PUBLISH_TOKEN: ${{ github.token }}
183194
IS_HYBRID_BUILD: ${{ matrix.is_hybrid }}
184195
PATCHED_VERSION: ${{ steps.getNewPatchedVersion.outputs.NEW_PATCHED_VERSION }}
185196
PATCHES_HASH: ${{ matrix.is_hybrid == 'true' && needs.verifyPatches.outputs.hybrid_app_patches_hash || needs.verifyPatches.outputs.standalone_patches_hash }}
197+
CMAKE_VERSION: 3.31.6
186198

187199
- name: Announce failed workflow in Slack
188200
if: ${{ failure() }}

Mobile-Expensify

android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@ android {
111111
minSdkVersion rootProject.ext.minSdkVersion
112112
targetSdkVersion rootProject.ext.targetSdkVersion
113113
multiDexEnabled rootProject.ext.multiDexEnabled
114-
versionCode 1009034103
115-
versionName "9.3.41-3"
114+
versionCode 1009034203
115+
versionName "9.3.42-3"
116116
// Supported language variants must be declared here to avoid from being removed during the compilation.
117117
// This also helps us to not include unnecessary language variants in the APK.
118118
resConfigs "en", "es"

android/settings.gradle

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,8 @@ if(settings.extensions.patchedArtifacts.buildFromSource) {
3737
}
3838
}
3939

40-
apply from: new File(["node", "--print", "require.resolve('expo/package.json')"].execute(null, rootDir).text.trim(), "../scripts/autolinking.gradle")
41-
useExpoModules()
4240
expoAutolinking {
43-
projectRoot = file(rootDir)
41+
projectRoot = file('../')
42+
searchPaths = ['node_modules']
4443
useExpoModules()
4544
}
Lines changed: 1 addition & 0 deletions
Loading
Lines changed: 1 addition & 0 deletions
Loading

config/webpack/ModuleInitTimingPlugin.ts

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import type {Chunk, Compiler} from 'webpack';
1+
import path from 'path';
2+
import type {Chunk, Compiler, NormalModule} from 'webpack';
23
import webpack from 'webpack';
34
// @libs alias is not available in Node.js/Storybook context — use relative path instead
45
// @ts-expect-error -- Can't use .ts extensions without allowImportingTsExtensions in tsconfig
@@ -37,6 +38,9 @@ function createTimingRuntimeModule(): webpack.RuntimeModule {
3738
*/
3839
class ModuleInitTimingPlugin {
3940
apply(compiler: Compiler): void {
41+
if (compiler.isChild()) {
42+
return;
43+
}
4044
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
4145
// Ensure webpack generates the __webpack_require__.i interception
4246
// mechanism for every chunk that has a runtime.
@@ -49,6 +53,29 @@ class ModuleInitTimingPlugin {
4953
compilation.addRuntimeModule(chunk, createTimingRuntimeModule());
5054
});
5155
});
56+
57+
// Emit module-names.json once per build (after all compilations are sealed).
58+
// Using compiler.hooks.emit rather than compilation.hooks.processAssets avoids
59+
// conflicts when multiple compilation rounds run in the same build (e.g. Sentry plugin).
60+
compiler.hooks.emit.tap(PLUGIN_NAME, (compilation) => {
61+
const names: Record<string, string> = {};
62+
for (const module of compilation.modules) {
63+
const id = compilation.chunkGraph.getModuleId(module);
64+
if (id === null) {
65+
continue;
66+
}
67+
const resource = 'resource' in module ? (module as NormalModule).resource : undefined;
68+
if (!resource || resource.includes('node_modules')) {
69+
continue;
70+
}
71+
const relativePath = `./${path.relative(compiler.context, resource).replaceAll('\\', '/')}`;
72+
names[String(id)] = relativePath;
73+
}
74+
if (Object.keys(names).length > 0) {
75+
// eslint-disable-next-line no-param-reassign
76+
compilation.assets['module-names.json'] = new webpack.sources.RawSource(JSON.stringify(names));
77+
}
78+
});
5279
}
5380
}
5481

contributingGuides/NAVIGATION.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,7 @@ Do not use dynamic routes when:
710710
`DYNAMIC_ROUTES` in `src/ROUTES.ts`: each entry has:
711711

712712
- `path`: The URL suffix (e.g. `'verify-account'`).
713-
- `entryScreens`: List of screen names that are allowed to have this suffix appended (access control; see [Entry Screens (Access Control)](#entry-screens-access-control)).
713+
- `entryScreens`: List of screen names that are allowed to have this suffix appended (access control; see [Entry Screens (Access Control)](#entry-screens-access-control)). Use `['*']` to allow all screens.
714714

715715
`createDynamicRoute(suffix)` — [`createDynamicRoute.ts`](src/libs/Navigation/helpers/createDynamicRoute.ts). Accepts a `DynamicRouteSuffix` (from `DYNAMIC_ROUTES`), appends it to the current active route and returns the full route. Use the following when navigating to a dynamic route:
716716

@@ -731,6 +731,24 @@ When parsing a URL, `src/libs/Navigation/helpers/getStateFromPath.ts` resolves t
731731

732732
When adding or extending a dynamic route, list every screen that should be able to open it (e.g. `SCREENS.SETTINGS.WALLET.ROOT` for Verify Account from Wallet).
733733

734+
#### Wildcard access (`'*'`)
735+
736+
Setting `entryScreens` to `['*']` grants access to the dynamic route from any screen. This bypasses per-screen authorization entirely for that route.
737+
738+
```ts
739+
KEYBOARD_SHORTCUTS: {
740+
path: 'keyboard-shortcuts',
741+
entryScreens: ['*'],
742+
},
743+
```
744+
745+
> [!CAUTION]
746+
> **Use `'*'` only when the dynamic route genuinely needs to be reachable from every screen.**
747+
> If only a subset of screens should access the route, list them explicitly.
748+
> Overusing `'*'` weakens the access control that `entryScreens` provides
749+
> and makes it harder to reason about which screens can trigger a given flow.
750+
> When in doubt, prefer an explicit list.
751+
734752
### Current limitations (work in progress)
735753

736754
- **Path parameters:** Suffixes must not include path params (e.g. `a/:reportID`). Query parameters are supported - see [Dynamic routes with query parameters](#dynamic-routes-with-query-parameters).

contributingGuides/SELECTION_LIST.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ This doc explains when and how to use the `SelectionList` and `SelectionListWith
88
There are two main components:
99

1010
- [**`SelectionList`**](../src/components/SelectionList/BaseSelectionList.tsx) - For displaying a single array of data (no sections)
11-
- [**`SelectionListWithSections`**](../src/components/SelectionListWithSections/BaseSelectionListWithSections.tsx) - For displaying data organized into multiple sections
11+
- [**`SelectionListWithSections`**](../src/components/SelectionList/SelectionListWithSections/BaseSelectionListWithSections.tsx) - For displaying data organized into multiple sections
1212

1313
## When to Use Each Component
1414

@@ -59,13 +59,18 @@ There are two main components:
5959
```tsx
6060
<SelectionListWithSections
6161
sections={[
62-
{ title: 'Recent', data: recentContacts },
63-
{ title: 'All Contacts', data: allContacts },
62+
{ title: 'Recent', data: recentContacts, sectionIndex: 0 },
63+
{ title: 'All Contacts', data: allContacts, sectionIndex: 1 },
6464
]}
6565
ListItem={UserListItem}
6666
onSelectRow={handleSelectContact}
6767
shouldShowTextInput
68-
textInputLabel="Search contacts"
68+
textInputOptions={{
69+
label: "Search items",
70+
value: searchText,
71+
onChangeText: setSearchText,
72+
headerMessage
73+
}}
6974
/>
7075
```
7176

cspell.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@
205205
"ecash",
206206
"ecconnrefused",
207207
"econn",
208+
"EDDSA",
208209
"EDIFACT",
209210
"Egencia",
210211
"Electromedical",
@@ -303,6 +304,7 @@
303304
"gradlew",
304305
"Grantmaking",
305306
"groupmonth",
307+
"groupweek",
306308
"gscb",
307309
"gsib",
308310
"gsst",
@@ -597,6 +599,7 @@
597599
"reactnativebackgroundtask",
598600
"reactnativehybridapp",
599601
"reactnativekeycommand",
602+
"reannounce",
600603
"reauthentication",
601604
"Reauthenticator",
602605
"Rebooked",

0 commit comments

Comments
 (0)