Repository navigation
ci: test library consumption from packed tarballs - #603
Open
thiagobrez wants to merge 1 commit into
Open
thiagobrez wants to merge 1 commit into
thiagobrez wants to merge 1 commit into
Conversation
Pack the publishable packages with npm pack and install them into fresh consumer apps, so CI resolves the library the way users do instead of through workspace links and src/ aliases. - consumer-expo: app from the packed Expo template, config plugin via prebuild, Release builds on Xcode 26 and AGP 8 - consumer-cli: React Native CLI app on the example's RN version, Release builds on Xcode 27 and AGP 9 with built-in Kotlin Also run yarn test in the lint job and cancel superseded runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Comment on lines
+213
to
+307
| name: consumer-expo (${{ matrix.platform }}) | ||
| needs: build-library | ||
| runs-on: ${{ matrix.runner }} | ||
| timeout-minutes: 60 | ||
|
|
||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| include: | ||
| - platform: ios | ||
| runner: macos-26 | ||
| - platform: android | ||
| runner: ubuntu-latest | ||
|
|
||
| env: | ||
| APP_DIR: ${{ github.workspace }}/../consumer | ||
|
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 | ||
| with: | ||
| node-version-file: .nvmrc | ||
|
|
||
| - name: Download packages | ||
| uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 | ||
| with: | ||
| name: packages | ||
| path: ${{ runner.temp }}/packages | ||
|
|
||
| - name: Create app from the Expo template | ||
| run: | | ||
| npx --yes create-expo-app@latest "$APP_DIR" --template "$RUNNER_TEMP"/packages/bottom-tabs-expo-template-*.tgz --no-install | ||
|
|
||
| # The template pins the published versions; the tarballs replace them. | ||
| - name: Install packages from tarballs | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: | | ||
| npm install "$RUNNER_TEMP"/packages/react-native-bottom-tabs-*.tgz "$RUNNER_TEMP"/packages/bottom-tabs-react-navigation-*.tgz | ||
|
|
||
| - name: Typecheck | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: npx tsc --noEmit | ||
|
|
||
| - name: Bundle JavaScript | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: npx expo export --platform ${{ matrix.platform }} | ||
|
|
||
| - name: Install JDK | ||
| if: matrix.platform == 'android' | ||
| uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0 | ||
| with: | ||
| distribution: 'zulu' | ||
| java-version: '17' | ||
|
|
||
| - name: Setup Gradle | ||
| if: matrix.platform == 'android' | ||
| uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.0 | ||
|
|
||
| - name: Finalize Android SDK | ||
| if: matrix.platform == 'android' | ||
| run: | | ||
| /bin/bash -c "yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses > /dev/null" | ||
|
|
||
| # Runs the library's config plugin from the tarball's app.plugin.js. | ||
| - name: Prebuild | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: npx expo prebuild --platform ${{ matrix.platform }} | ||
|
|
||
| # BottomNavigationView crashes on launch without a Material theme. | ||
| - name: Check the config plugin set the Material 3 theme | ||
| if: matrix.platform == 'android' | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: | | ||
| grep 'parent="Theme.Material3.DayNight.NoActionBar"' android/app/src/main/res/values/styles.xml | ||
|
|
||
| - name: Build for iOS | ||
| if: matrix.platform == 'ios' | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: | | ||
| xcodebuild -workspace ios/consumer.xcworkspace -scheme consumer -configuration Release -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath ios/build ARCHS=arm64 CODE_SIGNING_ALLOWED=NO -quiet | ||
|
|
||
| - name: Build for Android | ||
| if: matrix.platform == 'android' | ||
| working-directory: ${{ env.APP_DIR }}/android | ||
| env: | ||
| JAVA_OPTS: '-XX:MaxHeapSize=6g' | ||
| run: | | ||
| ./gradlew assembleRelease -PreactNativeArchitectures=arm64-v8a --no-daemon --console=plain | ||
|
|
||
| # Installs the packed library into a fresh React Native Community CLI app on | ||
| # the example's React Native version, as bare React Native users do. | ||
| consumer-cli: |
Comment on lines
+308
to
+410
| name: consumer-cli (${{ matrix.platform }}) | ||
| needs: build-library | ||
| runs-on: ${{ matrix.runner }} | ||
| timeout-minutes: 60 | ||
|
|
||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| include: | ||
| # Only Xcode 27 compiles the `#if compiler(>=6.4)` iOS 27 SDK code; | ||
| # consumer-expo builds with Xcode 26. | ||
| - platform: ios | ||
| runner: xcode-27 | ||
| - platform: android | ||
| runner: ubuntu-latest | ||
|
|
||
| env: | ||
| APP_DIR: ${{ github.workspace }}/../consumer | ||
|
|
||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1 | ||
|
|
||
| - name: Setup Node.js | ||
| uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0 | ||
| with: | ||
| node-version-file: .nvmrc | ||
|
|
||
| - name: Download packages | ||
| uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2 | ||
| with: | ||
| name: packages | ||
| path: ${{ runner.temp }}/packages | ||
|
|
||
| - name: Create app on the example's React Native version | ||
| run: | | ||
| version=$(node -p "require('./apps/example/package.json').dependencies['react-native'].replace(/^\D+/, '')") | ||
| npx --yes @react-native-community/cli@latest init Consumer --version "$version" --directory "$APP_DIR" --skip-install --skip-git-init | ||
|
|
||
| - name: Install library from tarball | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: | | ||
| cp "$GITHUB_WORKSPACE/.github/consumer/App.tsx" App.tsx | ||
| npm install "$RUNNER_TEMP"/packages/react-native-bottom-tabs-*.tgz | ||
|
|
||
| - name: Typecheck | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: npx tsc --noEmit | ||
|
|
||
| - name: Bundle JavaScript | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: | | ||
| npx react-native bundle --entry-file index.js --platform ${{ matrix.platform }} --dev false --bundle-output "$RUNNER_TEMP/index.bundle" | ||
|
|
||
| - name: Install pods | ||
| if: matrix.platform == 'ios' | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: | | ||
| bundle install | ||
| cd ios && bundle exec pod install | ||
|
|
||
| - name: Build for iOS | ||
| if: matrix.platform == 'ios' | ||
| working-directory: ${{ env.APP_DIR }} | ||
| run: | | ||
| xcodebuild -workspace ios/Consumer.xcworkspace -scheme Consumer -configuration Release -sdk iphonesimulator -destination 'generic/platform=iOS Simulator' -derivedDataPath ios/build ARCHS=arm64 CODE_SIGNING_ALLOWED=NO -quiet | ||
|
|
||
| - name: Install JDK | ||
| if: matrix.platform == 'android' | ||
| uses: actions/setup-java@f2beeb24e141e01a676f977032f5a29d81c9e27e # v5.1.0 | ||
| with: | ||
| distribution: 'zulu' | ||
| java-version: '17' | ||
|
|
||
| - name: Setup Gradle | ||
| if: matrix.platform == 'android' | ||
| uses: gradle/actions/setup-gradle@3f5f9adaf7d9fecd50b5935e54106014257a94e6 # v6.4.0 | ||
|
|
||
| - name: Finalize Android SDK | ||
| if: matrix.platform == 'android' | ||
| run: | | ||
| /bin/bash -c "yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --licenses > /dev/null" | ||
|
|
||
| # Inherits the Material 3 theme as the Quick Start tells CLI users to, and | ||
| # turns on AGP 9's built-in Kotlin, which the template still opts out of | ||
| # and AGP 10 makes mandatory. consumer-expo (AGP 8) covers the library | ||
| # applying kotlin-android itself. | ||
| - name: Configure Android app | ||
| if: matrix.platform == 'android' | ||
| working-directory: ${{ env.APP_DIR }}/android | ||
| run: | | ||
| sed -i 's/Theme.AppCompat.DayNight.NoActionBar/Theme.Material3.DayNight.NoActionBar/' app/src/main/res/values/styles.xml | ||
| grep 'parent="Theme.Material3.DayNight.NoActionBar"' app/src/main/res/values/styles.xml | ||
| sed -i '/^android.builtInKotlin=false/d; /^android.newDsl=false/d' gradle.properties | ||
| sed -i '/apply plugin: "org.jetbrains.kotlin.android"/d' app/build.gradle | ||
|
|
||
| - name: Build for Android | ||
| if: matrix.platform == 'android' | ||
| working-directory: ${{ env.APP_DIR }}/android | ||
| env: | ||
| JAVA_OPTS: '-XX:MaxHeapSize=6g' | ||
| run: | | ||
| ./gradlew assembleRelease -PreactNativeArchitectures=arm64-v8a --no-daemon --console=plain |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR Description
CI change. Consumers keep hitting bugs that CI can't catch because nothing in CI uses the library the way users do. The example app:
src/through Babel module-resolver aliases and tsconfigpaths, so a brokenlib/output, broken.d.tsfiles, a missingfilesentry or a brokenapp.plugin.js(v 1.0.2 emits an error when using expo #460) still passes.android.builtInKotlin=false). That's how fix(android): skip explicit Kotlin plugin when AGP registers the kotlin extension #568 and fix(android): remove unused kotlin-kapt plugin for AGP 9 built-in Kotlin #600 got through.build:iosonly bundles JS.The Expo template and the config plugin never ran in CI either.
This follows react-native-arrangement-view's CI: pack the packages and install them into freshly created apps.
build-librarynow packsreact-native-bottom-tabs,@bottom-tabs/react-navigationand@bottom-tabs/expo-templateand uploads them as an artifact. It usesnpm packbecausechangeset publishpublishes withnpm publish, so CI tests the same files that ship.consumer-expo(iOS onmacos-26, Android onubuntu-latest) follows the Quick Start'screate-expo-app --template @bottom-tabs/expo-templatepath:tsc,expo export, andexpo prebuild, which runs the plugin from the tarball'sapp.plugin.js.kotlin-androiditself.consumer-cli(iOS onxcode-27, Android onubuntu-latest):@react-native-community/cli initon the example's React Native version (currently 0.87.1, which comes with TypeScript 6), then installs the packed library.TabViewfrom.github/consumer/App.tsx.tsc, a JS bundle, CocoaPods and Release builds.#if compiler(>=6.4)iOS 27 code.Two more changes taken from the reference workflow:
yarn testnow runs in the lint job (CI never ran it), andconcurrencycancels superseded runs.Things for reviewers:
xcode-27is GitHub's public-preview Xcode 27 runner label. actionlint doesn't recognize it yet; react-native-arrangement-view already uses it.consumer-expotests what template users get, not the latest SDK.build-iosjob now overlaps these jobs and still never runsxcodebuildthrough CocoaPods. It could be dropped or fixed in a follow-up.How to test?
Check the four
consumer-*jobs on this PR.Every step was run locally first:
consumer-expo: iOS Release with Xcode 26.6 and Android Release passed.consumer-cli: iOS Release with Xcode 27.1 and Android Release with built-in Kotlin passed.kotlin-kaptline that fix(android): remove unused kotlin-kapt plugin for AGP 9 built-in Kotlin #600 removed makesconsumer-cli (android)fail withThe 'org.jetbrains.kotlin.kapt' plugin is not compatible with built-in Kotlin support, the error users reported.Screenshots
N/A, CI only.
🤖 Generated with Claude Code