From 3b128f7a2af31f2e2a6812ee57aba97f5ea760fc Mon Sep 17 00:00:00 2001 From: Dominik Czupryna Date: Wed, 8 Nov 2023 14:23:57 +0100 Subject: [PATCH] chore: add expo to test matrix --- .github/actions/setup_test_project/action.yml | 24 ++- .github/workflows/ci.yml | 140 ++++++++++-------- package.json | 2 + repoUtils/expoAppExporter.js | 3 + scripts/copyExampleProjectBaseFiles.js | 83 +++++++++++ 5 files changed, 186 insertions(+), 66 deletions(-) create mode 100644 repoUtils/expoAppExporter.js create mode 100644 scripts/copyExampleProjectBaseFiles.js diff --git a/.github/actions/setup_test_project/action.yml b/.github/actions/setup_test_project/action.yml index 209d5601..13201181 100644 --- a/.github/actions/setup_test_project/action.yml +++ b/.github/actions/setup_test_project/action.yml @@ -7,6 +7,10 @@ inputs: NODE_VERSION: description: Node version to use # https://github.com/actions/setup-node#supported-version-syntax required: false + IS_EXPO: + description: Should template use expo + required: false + default: false runs: using: composite @@ -16,10 +20,16 @@ runs: with: node-version: ${{ inputs.NODE_VERSION }} - - name: Initialize project template + - name: Initialize project default template + if: '${{ inputs.IS_EXPO == false }}' run: npx react-native@latest init BlePlxExample --version ${{ inputs.REACT_NATIVE_VERSION }} --directory test_project --skip-install --verbose shell: bash + - name: Initialize project expo template + if: '${{ inputs.IS_EXPO == true }}' + run: npx create-expo-app test_project + shell: bash + - name: Cache dependencies id: yarn-cache uses: actions/cache@v3 @@ -32,8 +42,18 @@ runs: ${{ runner.os }}-${{ inputs.REACT_NATIVE_VERSION }}-yarn- - name: Copy project files - run: REACT_NATIVE_VERSION=${{ inputs.REACT_NATIVE_VERSION }} node ./scripts/copyExampleProjectFiles.js + if: '${{ inputs.IS_EXPO == false }}' + run: node ./scripts/copyExampleProjectFiles.js + shell: bash + env: + REACT_NATIVE_VERSION: ${{ inputs.REACT_NATIVE_VERSION }} + + - name: Copy project files + if: '${{ inputs.IS_EXPO == true }}' + run: node ./scripts/copyExampleProjectBaseFiles.js shell: bash + env: + REACT_NATIVE_VERSION: ${{ inputs.REACT_NATIVE_VERSION }} - name: Install dependencies if: steps.yarn-cache.outputs.cache-hit != 'true' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e0d72998..8991e9eb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,11 +52,11 @@ jobs: strategy: fail-fast: false matrix: - configurations: - [ + configurations: [ { react_native_version: '0.72.6', node_version: 18 }, - { react_native_version: '0.71.14', node_version: 16 }, - { react_native_version: '0.70.13', node_version: 16 } + # { react_native_version: '0.71.14', node_version: 16 }, + # { react_native_version: '0.70.13', node_version: 16 }, + { react_native_version: 'expo', node_version: 18, is_expo: true } ] env: TURBO_CACHE_DIR: .turbo/android @@ -69,6 +69,7 @@ jobs: with: REACT_NATIVE_VERSION: ${{ matrix.configurations.react_native_version }} NODE_VERSION: ${{ matrix.configurations.node_version }} + IS_EXPO: ${{ matrix.configurations.is_expo }} - name: Cache turborepo for Android uses: actions/cache@v3 @@ -110,67 +111,78 @@ jobs: ${{ runner.os }}-${{ matrix.configurations.react_native_version }}-gradle- - name: Build example for Android + if: '${{ matrix.configurations.is_expo == false }}' run: | yarn turbo run test:android --cache-dir="${{ env.TURBO_CACHE_DIR }}" - build-ios: - runs-on: macos-latest - strategy: - fail-fast: false - matrix: - configurations: - [ - { react_native_version: '0.72.6', node_version: 18 }, - { react_native_version: '0.71.14', node_version: 16 }, - { react_native_version: '0.70.13', node_version: 16 } - ] - env: - TURBO_CACHE_DIR: .turbo/ios - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup - uses: ./.github/actions/setup_test_project - with: - REACT_NATIVE_VERSION: ${{ matrix.configurations.react_native_version }} - NODE_VERSION: ${{ matrix.configurations.node_version }} - - - name: Cache turborepo for iOS - uses: actions/cache@v3 - with: - path: ${{ env.TURBO_CACHE_DIR }} - key: ${{ runner.os }}-${{ matrix.configurations.react_native_version }}-turborepo-ios-${{ hashFiles('**/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-${{ matrix.configurations.react_native_version }}-turborepo-ios- - - - name: Check turborepo cache for iOS - run: | - TURBO_CACHE_STATUS=$(node -p "($(yarn --silent turbo run test:ios --cache-dir="${{ env.TURBO_CACHE_DIR }}" --dry=json)).tasks.find(t => t.task === 'test:ios').cache.status") - - if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then - echo "turbo_cache_hit=1" >> $GITHUB_ENV - fi - - - name: Cache cocoapods - if: env.turbo_cache_hit != 1 - id: cocoapods-cache - uses: actions/cache@v3 - with: - path: | - **/ios/Pods - key: ${{ runner.os }}-${{ matrix.configurations.react_native_version }}-cocoapods-${{ hashFiles('test_project/ios/Podfile.lock') }} - restore-keys: | - ${{ runner.os }}-${{ matrix.configurations.react_native_version }}-cocoapods- - - - name: Install cocoapods - if: env.turbo_cache_hit != 1 - run: | - cd test_project/ios - pod install --verbose - env: - NO_FLIPPER: 1 - - - name: Build test_project for iOS + - name: Build example for expo Android + if: '${{ matrix.configurations.is_expo == true }}' run: | - yarn turbo run test:ios --cache-dir="${{ env.TURBO_CACHE_DIR }}" + yarn turbo run test:androidExpo --cache-dir="${{ env.TURBO_CACHE_DIR }}" + + # build-ios: + # runs-on: macos-latest + # strategy: + # fail-fast: false + # matrix: + # configurations: [] + # # { react_native_version: '0.72.6', node_version: 18 }, + # # { react_native_version: '0.71.14', node_version: 16 }, + # # { react_native_version: '0.70.13', node_version: 16 }, + # # { react_native_version: 'expo', node_version: 18, is_expo: true } + # env: + # TURBO_CACHE_DIR: .turbo/ios + # steps: + # - name: Checkout + # uses: actions/checkout@v3 + + # - name: Setup + # uses: ./.github/actions/setup_test_project + # with: + # REACT_NATIVE_VERSION: ${{ matrix.configurations.react_native_version }} + # NODE_VERSION: ${{ matrix.configurations.node_version }} + # IS_EXPO: ${{ matrix.configurations.is_expo }} + + # - name: Cache turborepo for iOS + # uses: actions/cache@v3 + # with: + # path: ${{ env.TURBO_CACHE_DIR }} + # key: ${{ runner.os }}-${{ matrix.configurations.react_native_version }}-turborepo-ios-${{ hashFiles('**/yarn.lock') }} + # restore-keys: | + # ${{ runner.os }}-${{ matrix.configurations.react_native_version }}-turborepo-ios- + + # - name: Check turborepo cache for iOS + # run: | + # TURBO_CACHE_STATUS=$(node -p "($(yarn --silent turbo run test:ios --cache-dir="${{ env.TURBO_CACHE_DIR }}" --dry=json)).tasks.find(t => t.task === 'test:ios').cache.status") + + # if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then + # echo "turbo_cache_hit=1" >> $GITHUB_ENV + # fi + + # - name: Cache cocoapods + # if: env.turbo_cache_hit != 1 + # id: cocoapods-cache + # uses: actions/cache@v3 + # with: + # path: | + # **/ios/Pods + # key: ${{ runner.os }}-${{ matrix.configurations.react_native_version }}-cocoapods-${{ hashFiles('test_project/ios/Podfile.lock') }} + # restore-keys: | + # ${{ runner.os }}-${{ matrix.configurations.react_native_version }}-cocoapods- + + # - name: Install cocoapods + # if: env.turbo_cache_hit != 1 + # run: | + # cd test_project/ios + # pod install --verbose + # env: + # NO_FLIPPER: 1 + + # - name: Build test_project for iOS + # if: env.turbo_cache_hit != 1 && '${{ matrix.configurations.is_expo == false }}' + # run: | + # yarn turbo run test:ios --cache-dir="${{ env.TURBO_CACHE_DIR }}" + + # - name: Build test_project for expo iOS + # if: env.turbo_cache_hit != 1 && '${{ matrix.configurations.is_expo == true }}' + # run: yarn turbo run test:iosExpo --cache-dir="${{ env.TURBO_CACHE_DIR }}" diff --git a/package.json b/package.json index 9a706819..e43b0669 100644 --- a/package.json +++ b/package.json @@ -41,8 +41,10 @@ "example": "yarn --cwd example", "build:android": "cd example/android && ./gradlew assembleDebug --no-daemon --console=plain -PreactNativeArchitectures=arm64-v8a", "test:android": "cd test_project/android && ./gradlew assembleDebug --no-daemon --console=plain -PreactNativeArchitectures=arm64-v8a", + "test:androidExpo": "cd test_project && npx expo run:android", "build:ios": "cd example/ios && xcodebuild -workspace BlePlxExample.xcworkspace -scheme BlePlxExample -configuration Debug -sdk iphonesimulator CC=clang CPLUSPLUS=clang++ LD=clang LDPLUSPLUS=clang++ GCC_OPTIMIZATION_LEVEL=0 GCC_PRECOMPILE_PREFIX_HEADER=YES ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO", "test:ios": "cd test_project/ios && xcodebuild -workspace BlePlxExample.xcworkspace -scheme BlePlxExample -configuration Debug -sdk iphonesimulator ASSETCATALOG_COMPILER_OPTIMIZATION=time DEBUG_INFORMATION_FORMAT=dwarf COMPILER_INDEX_STORE_ENABLE=NO", + "test:iosExpo": "cd test_project && npx expo run:ios", "bootstrap": "yarn example && yarn install && yarn example pods", "clean": "del-cli android/build example/android/build example/android/app/build example/ios/build", "build:plugin": "tsc --build plugin", diff --git a/repoUtils/expoAppExporter.js b/repoUtils/expoAppExporter.js new file mode 100644 index 00000000..85e830e8 --- /dev/null +++ b/repoUtils/expoAppExporter.js @@ -0,0 +1,3 @@ +import App from './src/App' + +export default App diff --git a/scripts/copyExampleProjectBaseFiles.js b/scripts/copyExampleProjectBaseFiles.js new file mode 100644 index 00000000..3a12c4d4 --- /dev/null +++ b/scripts/copyExampleProjectBaseFiles.js @@ -0,0 +1,83 @@ +const path = require('path') +const fs = require('fs') + +const TEST_PROJECT_DIR_NAME = '../test_project' +const EXAMPLE_PROJECT_DIR_NAME = '../example' +const REPO_UTILS_DIR_NAME = '../repoUtils' + +const expoAppEntryPath = path.join(__dirname, REPO_UTILS_DIR_NAME, 'expoAppExporter.js') +const expoAppEntryPathDestinationPath = path.join(__dirname, TEST_PROJECT_DIR_NAME, 'App.js') + +const copyExampleProjectExpoAppEntry = () => { + console.info('Deleting expo App entry from test_project') + fs.unlinkSync(expoAppEntryPathDestinationPath) + console.info('Copying expo App entry from repoUtils to test_project') + fs.copyFileSync(expoAppEntryPath, expoAppEntryPathDestinationPath) +} + +const jsSourceDirectory = path.join(__dirname, EXAMPLE_PROJECT_DIR_NAME, 'src') +const jsSourceDestinationDirectory = path.join(__dirname, TEST_PROJECT_DIR_NAME, 'src') + +const copyExampleProjectJsFiles = () => { + console.info('Copying src from example to test_project') + fs.cpSync(jsSourceDirectory, jsSourceDestinationDirectory, { recursive: true }) +} + +const packageJsonPath = path.join(__dirname, EXAMPLE_PROJECT_DIR_NAME, 'package.json') +const packageJsonDestinationPath = path.join(__dirname, TEST_PROJECT_DIR_NAME, 'package.json') + +const addMissingDependencies = () => { + const sourcePackageJson = require(packageJsonPath) + const editedPackageJson = require(packageJsonDestinationPath) + + console.info('Checking for missing dependencies') + const missingDependencies = Object.keys(sourcePackageJson.dependencies).filter( + dependency => !editedPackageJson.dependencies[dependency] + ) + const missingDevDependencies = Object.keys(sourcePackageJson.devDependencies).filter( + dependency => !editedPackageJson.devDependencies[dependency] + ) + + missingDependencies.forEach(dependency => { + editedPackageJson.dependencies[dependency] = sourcePackageJson.dependencies[dependency] + }) + missingDevDependencies.forEach(dependency => { + editedPackageJson.devDependencies[dependency] = sourcePackageJson.devDependencies[dependency] + }) + + console.info('Writing new package.json to test_project') + fs.writeFileSync(packageJsonDestinationPath, JSON.stringify(editedPackageJson, null, 2) + '\n') +} + +const babelConfigDestinationPath = path.join(__dirname, TEST_PROJECT_DIR_NAME, 'babel.config.js') +const babelConfigSourcePath = path.join(__dirname, EXAMPLE_PROJECT_DIR_NAME, 'babel.config.js') + +const copyBabelConfig = () => { + console.info('Deleting babel.config.js from test_project') + fs.unlinkSync(babelConfigDestinationPath) + console.info('Copying babel.config.js from example to test_project') + fs.copyFileSync(babelConfigSourcePath, babelConfigDestinationPath) +} + +const fixExpoBabelConfig = () => { + const currentData = fs.readFileSync(babelConfigDestinationPath, 'utf-8') + + const updatedData = currentData.replace( + "presets: ['module:metro-react-native-babel-preset']", + "presets: ['babel-preset-expo']" + ) + + fs.writeFileSync(babelConfigDestinationPath, updatedData, 'utf-8') + + console.info('Expo babel update complete') +} + +const copyExampleProjectFiles = () => { + copyExampleProjectExpoAppEntry() + copyExampleProjectJsFiles() + copyBabelConfig() + fixExpoBabelConfig() + addMissingDependencies() +} + +copyExampleProjectFiles()