Skip to content

Commit 28b77bc

Browse files
artus9033thymikeehurali97
authored
feat: expo config plugin (#223)
* chore: bootstrapped demo Expo app * chore: use expo config plugin in expo demo app * chore: reset Expo project * chore: use workspace specifier for monorepo deps * fix: do not toss up source sets in Gradle plugin * feat: base implementation for brownfield Expo config plugin * chore: update lock files * chore: update app.json in ExpoApp * chore: enable debug logging in app.json in ExpoApp * feat: use new logging system in the plugin * feat: templates engine for project modifications * feat: patch for Expo SDK pre v55, fix source file paths * feat: implemented Android brownfield plugin * chore: update ExpoApp scripts * fix: dedent gradle script insertion * fix: depend on Material in AndroidApp; fix typo in gradle scripting comments * fix: package name in ExpoApp * chore: use debug signing config for AndroidApp release variant - for testing purposes * chore: missing indent in gradleHelpers insertion * fix: add missing expo modifications to template build.gradle.kts * chore: use the Expo classes in template ReactNativeHostManager.kt * fix: iOS xcode project processing of target UUID * fix: make Android Expo config explicitly specify versions of RN Android deps to be properly resolved by Gradle when consumed * fix: running package:ios again * chore: udpate rock to 0.12.8 * chore: make nodemon watch template files in dev script for brownfield package * chore: reformat files, extract capitalized string helper, suppress unchecked cast compilation warnings * chore: deintegrate isExpo gradle plugin prop in favor of auto-detection * chore: typo in Android native demo app theme name * feat: config Maven publishing for part of the core expo modules * fix: correct artifact, group and version discovery for manually whitelisted publishable projects * feat: inject transitive dependencies into POM publication files * feat: instead of publishing, inject proper POM and Gradle Module JSON metadata with Expo transitive deps * feat: functional Expo demo in AndroidApp * chore: re-enable signing of gradle plugin * chore: use 0.0.1-snapshot by default in Expo plugin on Android * fix: filter out remaining expo transitive dependencies, add version mediation mechanisms * feat: seamless integration of Expo features into the brownfield CLI * refactor: restructure RNApp sources * feat: reuse RNApp sources in ExpoApp * feat: set up flavors for AndroidApp to consume expo or vanilla artifacts * ci: update CI to account for AndroidApp flavors * chore: remove obsolete comment * fix: monorepo-prone expo detection in CLI * feat: proper code sharing for RN demo apps * fix: make ReactNativeHostManager singatures match across flavors, properly initialize React Native * fix: restore .brownie.ts files in each project for codegen to work properly * feat: added an image view to the demo app * chore: strip obsolete comment * fix: proper module name in ios script * fix: brownie not to crash on Android * fix: handle brownie no stores in project in the CLI * feat: demo apps reorganized, pulled in clean template for expo app * feat: integrate brownie store with Expo demo app * docs: update docs * feat: temporarily deintegrate brownie from expo demo before android is implemented in brownie * chore: rename expo app project * chore: re-enable signing of the gradle plugin * chore: add changesets * refactor: format files * fix(ci): path to RN project in androidapp-road-test * refactor: format files to comply with detekt * chore: revert changes to brownie * fix: paths in packageIos in RN projects * ci: update workflow for Apple apps * feat: demo iOS app supporting interchanging brownfield artifacts * fix: patchExpoPre55.sh * fix: reorder build phases in iOS to first run patching after expo configure * wip: reorder build script phases PoC for Expo config plugin * chore: reorder code properly * chore: use SNAPSHOT for CI and local * chore: add plugin publish and patch scripts for local maven * chore: fix appleapp-road-test ci * chore: use macos runner for appleapp CI * fix(ci): update maven path for expo flavor * fix(ci): expo android * feat: ensure build phase correct order using post_integrate * feat: add ReactNativeHostManager to source files * fix: use the bundleURL in loadView * feat: present Expo RN UI in Apple App * chore: use latest version for brownfield-gradle-plugin * feat: add source files to PBXSourcesBuildPhase * feat: allow entry points other than main * feat: add configuration for vanilla and expo to AppleApp * fix: add info.plist to AppleApp * fix: bundle reference * fix(ci): add guard to only run pods for vanilla * docs: update ExpoApp usages * feat: remove coil dependency from plugin to the lib * refactor: remove TODO comments * feat: guard script reordering against expo version * feat: separate brownie usage by platform * chore: build android app with release variant * docs: add Expo Integration section * chore: bump versions * fix: remove color prop * Update docs/docs/docs/getting-started/expo.mdx Co-authored-by: Michał Pierzchała <thymikee@gmail.com> * Update docs/docs/docs/getting-started/expo.mdx Co-authored-by: Michał Pierzchała <thymikee@gmail.com> * docs: remove images * refactor: fix indentation * chore: remove changeset bump * chore(bump): react-native-brownfield and brownfield-cli for manual RC * feat: set default names * feat: use the default plugin config * docs: add plugin options * Update docs/docs/docs/getting-started/introduction.mdx Co-authored-by: Michał Pierzchała <thymikee@gmail.com> --------- Co-authored-by: Michał Pierzchała <thymikee@gmail.com> Co-authored-by: Hur Ali <hurali97@gmail.com>
1 parent 41c8105 commit 28b77bc

File tree

164 files changed

+8483
-727
lines changed

Some content is hidden

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

164 files changed

+8483
-727
lines changed

.changeset/config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"@callstack/brownfield-example-android-app",
1515
"@callstack/brownfield-example-ios-app",
1616
"@callstack/brownfield-example-rn-app",
17+
"@callstack/brownfield-example-expo-app",
1718
"@callstack/react-native-brownfield-tester-integrated",
1819
"@callstack/brownfield-gradle-plugin-react"
1920
],
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
name: Android road test (selected RN app & AndroidApp)
2+
description: Package the given RN app as AAR, publish to Maven Local, and build the corresponding AndroidApp flavor
3+
4+
inputs:
5+
flavor:
6+
description: 'AndroidApp flavor to build (expo or vanilla)'
7+
required: true
8+
9+
rn-project-path:
10+
description: 'Path to the RN project to build'
11+
required: true
12+
13+
rn-project-maven-path:
14+
description: 'Maven path to the RN project, e.g. com/rnapp/brownfieldlib'
15+
required: true
16+
17+
runs:
18+
using: composite
19+
steps:
20+
- name: Setup
21+
uses: ./.github/actions/setup
22+
23+
- name: Prepare Android environment
24+
uses: ./.github/actions/prepare-android
25+
26+
- name: Restore Gradle cache
27+
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5
28+
with:
29+
path: |
30+
~/.gradle/caches
31+
~/.gradle/wrapper
32+
key: ${{ runner.os }}-android-androidapp-${{ inputs.flavor }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
33+
restore-keys: |
34+
${{ runner.os }}-android-androidapp-${{ inputs.flavor }}-gradle-
35+
${{ runner.os }}-android-androidapp-gradle-
36+
37+
# == Brownfield Gradle Plugin ==
38+
- name: Publish Brownfield Gradle Plugin to Maven Local
39+
run: |
40+
yarn run brownfield:plugin:publish:local
41+
shell: bash
42+
43+
# == RN app ==
44+
- name: Prebuild Expo app
45+
if: ${{ inputs.flavor == 'expo' }}
46+
run: |
47+
cd ${{ inputs.rn-project-path }}
48+
yarn run expo prebuild --platform android
49+
shell: bash
50+
51+
- name: Patch ExpoApp Android build.gradle for CI
52+
if: ${{ inputs.flavor == 'expo' }}
53+
run: |
54+
cd ${{ inputs.rn-project-path }}
55+
yarn run brownfield:prepare:android:ci
56+
shell: bash
57+
58+
- name: Package AAR with the Brownfield CLI
59+
run: |
60+
cd ${{ inputs.rn-project-path }}
61+
yarn run brownfield:package:android
62+
shell: bash
63+
64+
- name: Publish AAR artifact to Maven Local
65+
run: |
66+
cd ${{ inputs.rn-project-path }}
67+
yarn run brownfield:publish:android
68+
shell: bash
69+
70+
- name: Verify debug AAR exists in Maven Local
71+
run: stat ~/.m2/repository/${{ inputs.rn-project-maven-path }}/0.0.1-SNAPSHOT/brownfieldlib-0.0.1-SNAPSHOT-debug.aar
72+
shell: bash
73+
74+
- name: Verify release AAR exists in Maven Local
75+
run: stat ~/.m2/repository/${{ inputs.rn-project-maven-path }}/0.0.1-SNAPSHOT/brownfieldlib-0.0.1-SNAPSHOT-release.aar
76+
shell: bash
77+
78+
# == AndroidApp ==
79+
80+
- name: Build native Android Brownfield app
81+
run: yarn run build:example:android-consumer:${{ inputs.flavor }}
82+
shell: bash
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
name: Apple road test (selected RN app & AppleApp)
2+
description: Package the given RN app as XCFramework, and build the corresponding AppleApp variant
3+
4+
inputs:
5+
variant:
6+
description: 'AppleApp yarn command variant to run (expo or vanilla)'
7+
required: true
8+
9+
rn-project-path:
10+
description: 'Path to the RN project to build'
11+
required: true
12+
13+
runs:
14+
using: composite
15+
steps:
16+
- name: Checkout
17+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
18+
19+
- name: Setup
20+
uses: ./.github/actions/setup
21+
22+
- name: Prepare iOS environment
23+
uses: ./.github/actions/prepare-ios
24+
25+
- name: Configure ccache environment
26+
run: |
27+
echo "USE_CCACHE=1" >> "$GITHUB_ENV"
28+
echo "CCACHE_DIR=${{ github.workspace }}/.ios_ccache" >> "$GITHUB_ENV"
29+
echo "CCACHE_BASEDIR=${{ github.workspace }}" >> "$GITHUB_ENV"
30+
echo "CCACHE_COMPRESS=1" >> "$GITHUB_ENV"
31+
shell: bash
32+
33+
- name: Install ccache
34+
run: brew install ccache
35+
shell: bash
36+
37+
- name: Enable ccache
38+
run: echo "$(brew --prefix)/opt/ccache/libexec" >> $GITHUB_PATH
39+
shell: bash
40+
41+
- name: Restore RNApp & AppleApp ccache
42+
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5
43+
with:
44+
path: |
45+
.ios_ccache
46+
key: ${{ runner.os }}-rnapp-appleapp-${{ inputs.variant }}-ios-ccache-${{ hashFiles(format('{0}/ios/Podfile.lock', inputs.rn-project-path), format('{0}/ios/*.xcodeproj/project.pbxproj', inputs.rn-project-path), 'apps/AppleApp/Brownfield Apple App.xcodeproj/project.pbxproj') }}
47+
restore-keys: |
48+
${{ runner.os }}-rnapp-appleapp-${{ inputs.variant }}-ios-ccache-
49+
50+
# == RN app ==
51+
52+
- name: Restore Pods cache (RN ${{ inputs.variant }} app)
53+
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5
54+
with:
55+
path: |
56+
${{ inputs.rn-project-path }}/ios/Pods
57+
key: ${{ runner.os }}-rnapp-${{ inputs.variant }}-ios-pods-${{ hashFiles(format('{0}/ios/Podfile.lock', inputs.rn-project-path)) }}
58+
restore-keys: |
59+
${{ runner.os }}-rnapp-${{ inputs.variant }}-ios-pods-
60+
61+
- name: Install pods (RN ${{ inputs.variant }} app)
62+
if: inputs.variant == 'vanilla'
63+
run: |
64+
cd ${{ inputs.rn-project-path }}/ios
65+
pod install
66+
shell: bash
67+
68+
- name: Restore DerivedData cache (RN ${{ inputs.variant }} app)
69+
uses: actions/cache@v5
70+
with:
71+
path: ${{ inputs.rn-project-path }}/ios/build
72+
key: ${{ runner.os }}-ios-rnapp-${{ inputs.variant }}-derived-data-${{ hashFiles(format('{0}/ios/Podfile.lock', inputs.rn-project-path), format('{0}/ios/*.xcodeproj/project.pbxproj', inputs.rn-project-path)) }}
73+
restore-keys: |
74+
${{ runner.os }}-ios-rnapp-${{ inputs.variant }}-derived-data-
75+
76+
- name: Package iOS framework with the Brownfield CLI
77+
run: |
78+
cd ${{ inputs.rn-project-path }}
79+
yarn run brownfield:package:ios
80+
shell: bash
81+
82+
# == AppleApp ==
83+
84+
- name: Build Brownfield iOS native app (${{ inputs.variant }})
85+
run: |
86+
yarn run build:example:ios-consumer:${{ inputs.variant }}
87+
shell: bash
88+
89+
# ==============
90+
91+
- name: Log ccache stats
92+
uses: ./.github/actions/ccache-summary
93+
with:
94+
name: RN ${{ inputs.variant }} app & AppleApp

.github/workflows/ci.yml

Lines changed: 38 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -83,61 +83,44 @@ jobs:
8383
- name: Build integrated Android tester app
8484
run: yarn run build:tester-integrated:android
8585

86-
android-rnapp-androidapp:
87-
name: Android road test (RNApp & AndroidApp)
86+
android-androidapp-expo:
87+
name: Android road test (RNApp & AndroidApp - Expo)
8888
runs-on: ubuntu-latest
8989
needs: build-lint
9090

9191
steps:
9292
- name: Checkout
9393
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
9494

95-
- name: Setup
96-
uses: ./.github/actions/setup
97-
98-
- name: Prepare Android environment
99-
uses: ./.github/actions/prepare-android
100-
101-
- name: Restore Gradle cache
102-
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5
95+
- name: Run RNApp -> AndroidApp road test (Expo)
96+
uses: ./.github/actions/androidapp-road-test
10397
with:
104-
path: |
105-
~/.gradle/caches
106-
~/.gradle/wrapper
107-
key: ${{ runner.os }}-android-rnapp-androidapp-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
108-
restore-keys: |
109-
${{ runner.os }}-android-rnapp-androidapp-gradle-
110-
111-
# == RNApp ==
112-
113-
- name: Package AAR with the Brownfield CLI
114-
run: |
115-
cd apps/RNApp
116-
yarn run brownfield:package:android
117-
118-
- name: Publish AAR artifact to Maven Local
119-
run: |
120-
cd apps/RNApp
121-
yarn run brownfield:publish:android
98+
flavor: expo
99+
rn-project-path: apps/ExpoApp
100+
rn-project-maven-path: com/callstack/rnbrownfield/demo/expoapp/brownfieldlib
122101

123-
- name: Verify debug AAR exists in Maven Local
124-
run: stat ~/.m2/repository/com/rnapp/brownfieldlib/0.0.1-local/brownfieldlib-0.0.1-local-debug.aar
125-
126-
- name: Verify release AAR exists in Maven Local
127-
run: stat ~/.m2/repository/com/rnapp/brownfieldlib/0.0.1-local/brownfieldlib-0.0.1-local-release.aar
102+
android-androidapp-vanilla:
103+
name: Android road test (RNApp & AndroidApp - Vanilla)
104+
runs-on: ubuntu-latest
105+
needs: build-lint
128106

129-
# == AndroidApp ==
107+
steps:
108+
- name: Checkout
109+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
130110

131-
- name: Build native Android Brownfield app
132-
run: |
133-
yarn run build:example:android-consumer
111+
- name: Run RNApp -> AndroidApp road test (Vanilla)
112+
uses: ./.github/actions/androidapp-road-test
113+
with:
114+
flavor: vanilla
115+
rn-project-path: apps/RNApp
116+
rn-project-maven-path: com/rnapp/brownfieldlib
134117

135118
ios-tester-integrated:
136119
name: iOS road test (TesterIntegrated)
137120
runs-on: macos-26
138121
needs: build-lint
139122

140-
env: &ios_env
123+
env:
141124
USE_CCACHE: 1
142125
CCACHE_DIR: ${{ github.workspace }}/.ios_ccache
143126
CCACHE_BASEDIR: ${{ github.workspace }}
@@ -203,76 +186,32 @@ jobs:
203186
with:
204187
name: TesterIntegrated
205188

206-
ios-rnapp-appleapp:
207-
name: iOS road test (RNApp & AppleApp)
189+
ios-appleapp-vanilla:
190+
name: iOS road test (RNApp & AppleApp - Vanilla)
208191
runs-on: macos-26
209192
needs: build-lint
210193

211-
env: *ios_env
212-
213194
steps:
214195
- name: Checkout
215196
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
216197

217-
- name: Setup
218-
uses: ./.github/actions/setup
219-
220-
- name: Prepare iOS environment
221-
uses: ./.github/actions/prepare-ios
222-
223-
- name: Install ccache
224-
run: brew install ccache
225-
226-
- name: Enable ccache
227-
run: echo "$(brew --prefix)/opt/ccache/libexec" >> $GITHUB_PATH
228-
229-
- name: Restore RNApp & AppleApp ccache
230-
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5
198+
- name: Run RNApp -> AppleApp road test (Vanilla)
199+
uses: ./.github/actions/appleapp-road-test
231200
with:
232-
path: |
233-
.ios_ccache
234-
key: ${{ runner.os }}-rnapp-appleapp-ios-ccache-${{ hashFiles('apps/RNApp/ios/Podfile.lock', 'apps/RNApp/ios/RNApp.xcodeproj/project.pbxproj', 'apps/AppleApp/Brownfield Apple App.xcodeproj/project.pbxproj') }}
235-
restore-keys: |
236-
${{ runner.os }}-rnapp-appleapp-ios-ccache-
237-
238-
# == RNApp ==
239-
240-
- name: Restore Pods cache (RNApp)
241-
uses: actions/cache@9255dc7a253b0ccc959486e2bca901246202afeb # v5
242-
with:
243-
path: |
244-
apps/RNApp/ios/Pods
245-
key: ${{ runner.os }}-rnapp-ios-pods-${{ hashFiles('apps/RNApp/ios/Podfile.lock') }}
246-
restore-keys: |
247-
${{ runner.os }}-rnapp-ios-pods-
248-
249-
- name: Install pods (RNApp)
250-
run: |
251-
cd apps/RNApp/ios
252-
pod install
201+
variant: vanilla
202+
rn-project-path: apps/RNApp
253203

254-
- name: Restore DerivedData cache (RNApp)
255-
uses: actions/cache@v5
256-
with:
257-
path: apps/RNApp/ios/build
258-
key: ${{ runner.os }}-ios-rnapp-derived-data-${{ hashFiles('apps/RNApp/ios/Podfile.lock', 'apps/RNApp/ios/RNApp.xcodeproj/project.pbxproj') }}
259-
restore-keys: |
260-
${{ runner.os }}-ios-rnapp-derived-data-
261-
262-
- name: Package iOS framework with the Brownfield CLI
263-
run: |
264-
cd apps/RNApp
265-
yarn run brownfield:package:ios
266-
267-
# == AppleApp ==
268-
269-
- name: Build Brownfield iOS native app
270-
run: |
271-
yarn run build:example:ios-consumer
204+
ios-appleapp-expo:
205+
name: iOS road test (RNApp & AppleApp - Expo)
206+
runs-on: macos-26
207+
needs: build-lint
272208

273-
# ==============
209+
steps:
210+
- name: Checkout
211+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6
274212

275-
- name: Log ccache stats
276-
uses: ./.github/actions/ccache-summary
213+
- name: Run ExpoApp -> AppleApp road test (Expo)
214+
uses: ./.github/actions/appleapp-road-test
277215
with:
278-
name: RNApp & AppleApp
216+
variant: expo
217+
rn-project-path: apps/ExpoApp

CONTRIBUTING.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
Run `yarn` in the root of the repository to install all dependencies.
66

77
Depending on your needs, you may need to install CocoaPods in a subset of the below directories:
8+
89
- example React Native iOS app: `cd apps/RNApp/ios && pod install`
910
- integrated iOS tester app: `cd apps/TesterIntegrated/swift && pod install`
1011

@@ -18,17 +19,18 @@ We use [changesets](https://github.com/changesets/changesets) to make it easier
1819

1920
## Scripts
2021

21-
- `lint` - runs linting on all JS/TS source files in the monorepo *[Turbo]*
22+
- `lint` - runs linting on all JS/TS source files in the monorepo _[Turbo]_
2223
- `gradle-plugin:lint` - runs linting on the Brownfield Gradle plugin source code
23-
- `typecheck` - runs TypeScript type checking on all TS source files in the monorepo *[Turbo]*
24-
- `build` - runs all `build*` tasks in the Turbo repo - see below for more details *[Turbo]*
24+
- `typecheck` - runs TypeScript type checking on all TS source files in the monorepo _[Turbo]_
25+
- `build` - runs all `build*` tasks in the Turbo repo - see below for more details _[Turbo]_
2526
- `dev` - runs all `dev` tasks in all workspaces
2627
- `brownfield:plugin:publish:local` - publishes the Brownfield Gradle plugin to your local Maven repository for testing purposes
27-
- `build:brownfield` - builds the React Native Brownfield package (`packages/react-native-brownfield`) *[Turbo]*
28-
- `build:docs` - builds the documentation site (`docs/`) *[Turbo]*
28+
- `build:brownfield` - builds the React Native Brownfield package (`packages/react-native-brownfield`) _[Turbo]_
29+
- `build:docs` - builds the documentation site (`docs/`) _[Turbo]_
2930
- `build:tester-integrated:android` - builds the Android integrated tester app (`apps/TesterIntegrated/android`)
3031
- `build:tester-integrated:ios` - builds the iOS integrated tester app (`apps/TesterIntegrated/swift`)
3132
- `build:example:android-rn` - builds the example React Native app for Android (`apps/RNApp/android`)
3233
- `build:example:ios-rn` - builds the example React Native app for iOS (`apps/RNApp/ios`)
33-
- `build:example:android-consumer` - builds the example native Android consumer app (`apps/AndroidApp`)
34-
- `build:example:ios-consumer` - builds the example native Apple consumer app (`apps/AppleApp`)
34+
- `build:example:android-consumer:expo` - builds the example native Android consumer (`apps/AndroidApp`) app's flavor consuming the Expo RN app (`apps/ExpoApp`) artifact
35+
- - `build:example:android-consumer:vanilla` - builds the example native Android consumer (`apps/AndroidApp`) app's flavor consuming the vanilla RN app (`apps/RNApp`) artifact
36+
- `build:example:ios-consumer` - builds the example native Apple consumer app (`apps/AppleApp`)

0 commit comments

Comments
 (0)