Repository navigation
fix(input): keep the keyboard dismissed after a drag that starts on the input #3080
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
| name: CI | |
| on: | |
| push: | |
| branches: | |
| - main | |
| pull_request: | |
| branches: | |
| - main | |
| # The block renderers stack (#1026 → #1027 → #1028): its upper PRs target | |
| # these branches until the one below merges. Drop once the stack is in. | |
| - 'feat/block-renderers-*' | |
| merge_group: | |
| types: | |
| - checks_requested | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| changes: | |
| runs-on: ubuntu-latest | |
| outputs: | |
| react-native: ${{ steps.filter.outputs.react-native }} | |
| android: ${{ steps.filter.outputs.android }} | |
| ios: ${{ steps.filter.outputs.ios }} | |
| core: ${{ steps.filter.outputs.core }} | |
| core-cpp: ${{ steps.filter.outputs.core-cpp }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| with: | |
| fetch-depth: 0 | |
| - name: Detect changes | |
| uses: dorny/paths-filter@d1c1ffe0248fe513906c8e24db8ea791d46f8590 # v3.0.3 | |
| id: filter | |
| with: | |
| filters: | | |
| core: | |
| - 'packages/core/**' | |
| - 'package.json' | |
| - '.github/**' | |
| react-native: | |
| - 'packages/react-native-enriched-markdown/**' | |
| - 'packages/core/**' | |
| - 'apps/react-native-example/**' | |
| - 'apps/react-native-web-example/**' | |
| - 'package.json' | |
| - 'yarn.lock' | |
| - '.nvmrc' | |
| - '.yarnrc.yml' | |
| - '.github/**' | |
| android: | |
| - 'packages/enriched-markdown-android/**' | |
| - 'packages/core/**' | |
| - 'vendor/vendor-grammars.mjs' | |
| - 'vendor/gen-registry.mjs' | |
| - 'vendor/grammar-versions.json' | |
| - 'apps/android-example/**' | |
| - 'package.json' | |
| - 'yarn.lock' | |
| - '.nvmrc' | |
| - '.yarnrc.yml' | |
| - '.github/**' | |
| ios: | |
| - 'packages/enriched-markdown-ios/**' | |
| - 'packages/core/**' | |
| - 'apps/ios-example/**' | |
| - 'package.json' | |
| - 'yarn.lock' | |
| - '.nvmrc' | |
| - '.yarnrc.yml' | |
| - '.github/**' | |
| core-cpp: | |
| - 'packages/core/cpp/**' | |
| - 'packages/react-native-enriched-markdown/src/web/wasm/**' | |
| - 'scripts/fetch-md4c.sh' | |
| - 'scripts/test-core-parser.sh' | |
| - 'scripts/test-web-bundle.mjs' | |
| - '.github/**' | |
| # The parser is vendored from software-mansion-labs/md4c, so a sync can change | |
| # how documents parse and can reintroduce a global symbol that collides with | |
| # another embedded MD4C copy. Neither shows up in a native build. | |
| core-parser: | |
| needs: changes | |
| if: needs.changes.outputs.core-cpp == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Check the vendored parser and the AST it produces | |
| run: ./scripts/test-core-parser.sh | |
| # The web bundle is a committed build artifact that nothing rebuilds on | |
| # install, so it silently falls behind packages/core/cpp. | |
| - name: Check the committed WASM bundle against the same AST | |
| run: node scripts/test-web-bundle.mjs | |
| # Nothing else gates these sources: the clang-format hook is local and | |
| # can be bypassed, and no other job formats packages/core/cpp. | |
| - name: Check formatting | |
| run: yarn lint-clang:core-parser | |
| core-tests: | |
| needs: changes | |
| if: needs.changes.outputs.core == 'true' | |
| runs-on: ubuntu-latest | |
| strategy: | |
| matrix: | |
| include: | |
| - build_type: RelWithDebInfo | |
| sanitize: '' | |
| - build_type: Debug | |
| sanitize: '' | |
| - build_type: Debug | |
| sanitize: address,undefined | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Lint C++ core formatting | |
| if: matrix.build_type == 'RelWithDebInfo' | |
| run: yarn workspace @enriched-markdown/core lint-clang | |
| - name: Build and run C++ core tests (${{ matrix.build_type }}${{ matrix.sanitize && ', sanitized' || '' }}) | |
| env: | |
| CORE_CMAKE_ARGS: -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCORE_SANITIZE=${{ matrix.sanitize }} | |
| run: yarn core:test | |
| rn-lint: | |
| needs: changes | |
| if: needs.changes.outputs.react-native == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Lint files | |
| run: yarn lint | |
| - name: Typecheck files | |
| run: yarn typecheck | |
| # The web example resolves the library's `.web` files (moduleSuffixes), | |
| # which the library's own typecheck never sees. | |
| - name: Typecheck the web example | |
| run: yarn workspace react-native-enriched-markdown-web-example typecheck | |
| - name: Run unit tests | |
| run: yarn test | |
| rn-build-library: | |
| needs: changes | |
| if: needs.changes.outputs.react-native == 'true' | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Build package | |
| run: yarn prepare | |
| rn-build-android: | |
| needs: changes | |
| if: needs.changes.outputs.react-native == 'true' | |
| runs-on: ubuntu-latest | |
| env: | |
| ANDROID_HOME: /usr/local/lib/android/sdk | |
| ANDROID_SDK_ROOT: /usr/local/lib/android/sdk | |
| TURBO_CACHE_DIR: .turbo/android | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Build library and generate codegen | |
| run: yarn prepare | |
| - name: Cache turborepo for Android | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: ${{ env.TURBO_CACHE_DIR }} | |
| key: ${{ runner.os }}-turborepo-android-${{ hashFiles('yarn.lock', 'packages/react-native-enriched-markdown/android/**', 'packages/react-native-enriched-markdown/src/**', 'packages/core/cpp/**', 'apps/react-native-example/android/**') }} | |
| restore-keys: | | |
| ${{ runner.os }}-turborepo-android- | |
| - name: Check turborepo cache for Android | |
| run: | | |
| TURBO_CACHE_STATUS=$(yarn turbo run build:android \ | |
| --filter=react-native-enriched-markdown-example \ | |
| --cache-dir="${{ env.TURBO_CACHE_DIR }}" \ | |
| --dry=json | jq -r '.tasks[0].cache.status') | |
| if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then | |
| echo "turbo_cache_hit=1" >> $GITHUB_ENV | |
| fi | |
| - name: Setup Android | |
| if: env.turbo_cache_hit != 1 | |
| uses: ./.github/actions/setup-android | |
| with: | |
| gradle-wrapper-properties: apps/react-native-example/android/gradle/wrapper/gradle-wrapper.properties | |
| - name: Build example for Android | |
| env: | |
| JAVA_OPTS: '-XX:MaxHeapSize=6g' | |
| run: yarn turbo run build:android --cache-dir="${{ env.TURBO_CACHE_DIR }}" | |
| rn-build-ios: | |
| needs: changes | |
| if: needs.changes.outputs.react-native == 'true' | |
| runs-on: macos-latest-xlarge | |
| env: | |
| TURBO_CACHE_DIR: .turbo/ios | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Build library | |
| run: yarn prepare | |
| - name: Set up Xcode | |
| uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0 | |
| with: | |
| xcode-version: '26.3' | |
| - name: Reset build folder and pods | |
| run: rm -rf apps/react-native-example/build apps/react-native-example/ios/Pods apps/react-native-example/ios/Podfile.lock | |
| - name: Cache turborepo for iOS | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: ${{ env.TURBO_CACHE_DIR }} | |
| key: ${{ runner.os }}-turborepo-ios-${{ hashFiles('yarn.lock', 'packages/react-native-enriched-markdown/ios/**', 'packages/react-native-enriched-markdown/src/**', 'packages/core/cpp/**', 'apps/react-native-example/ios/**') }} | |
| restore-keys: | | |
| ${{ runner.os }}-turborepo-ios- | |
| - name: Check turborepo cache for iOS | |
| run: | | |
| TURBO_CACHE_STATUS=$(yarn turbo run build:ios \ | |
| --filter=react-native-enriched-markdown-example \ | |
| --cache-dir="${{ env.TURBO_CACHE_DIR }}" \ | |
| --dry=json | jq -r '.tasks[0].cache.status') | |
| if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then | |
| echo "turbo_cache_hit=1" >> $GITHUB_ENV | |
| fi | |
| - name: Restore cocoapods | |
| if: env.turbo_cache_hit != 1 | |
| id: cocoapods-cache | |
| uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: | | |
| **/ios/Pods | |
| key: ${{ runner.os }}-cocoapods-${{ hashFiles('apps/react-native-example/ios/Podfile.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cocoapods- | |
| - name: Install cocoapods | |
| if: env.turbo_cache_hit != 1 | |
| run: | | |
| cd apps/react-native-example/ios | |
| pod install | |
| env: | |
| NO_FLIPPER: 1 | |
| - name: Cache cocoapods | |
| if: env.turbo_cache_hit != 1 && steps.cocoapods-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: | | |
| **/ios/Pods | |
| key: ${{ steps.cocoapods-cache.outputs.cache-primary-key }} | |
| - name: Build example for iOS | |
| run: yarn turbo run build:ios --cache-dir="${{ env.TURBO_CACHE_DIR }}" | |
| rn-android-unit-tests: | |
| needs: changes | |
| if: needs.changes.outputs.react-native == 'true' | |
| runs-on: ubuntu-latest | |
| env: | |
| ANDROID_HOME: /usr/local/lib/android/sdk | |
| ANDROID_SDK_ROOT: /usr/local/lib/android/sdk | |
| TURBO_CACHE_DIR: .turbo/rn-android-test | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Build library and generate codegen | |
| run: yarn prepare | |
| - name: Cache turborepo for RN Android unit tests | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: ${{ env.TURBO_CACHE_DIR }} | |
| key: ${{ runner.os }}-turborepo-rn-android-test-${{ hashFiles('yarn.lock', 'packages/react-native-enriched-markdown/android/**', 'packages/react-native-enriched-markdown/src/**', 'packages/core/cpp/**', 'apps/react-native-example/android/**') }} | |
| restore-keys: | | |
| ${{ runner.os }}-turborepo-rn-android-test- | |
| - name: Check turborepo cache for RN Android unit tests | |
| run: | | |
| TURBO_CACHE_STATUS=$(yarn test:android \ | |
| --cache-dir="${{ env.TURBO_CACHE_DIR }}" \ | |
| --dry=json | jq -r '.tasks[0].cache.status') | |
| if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then | |
| echo "turbo_cache_hit=1" >> $GITHUB_ENV | |
| fi | |
| - name: Setup Android | |
| if: env.turbo_cache_hit != 1 | |
| uses: ./.github/actions/setup-android | |
| with: | |
| gradle-wrapper-properties: apps/react-native-example/android/gradle/wrapper/gradle-wrapper.properties | |
| - name: Run RN Android unit tests | |
| env: | |
| JAVA_OPTS: '-XX:MaxHeapSize=6g' | |
| run: yarn test:android --cache-dir="${{ env.TURBO_CACHE_DIR }}" | |
| rn-ios-unit-tests: | |
| needs: changes | |
| if: needs.changes.outputs.react-native == 'true' | |
| runs-on: macos-latest-xlarge | |
| env: | |
| TURBO_CACHE_DIR: .turbo/rn-ios-test | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Build library | |
| run: yarn prepare | |
| - name: Set up Xcode | |
| uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0 | |
| with: | |
| xcode-version: '26.3' | |
| - name: Reset build folder and pods | |
| run: rm -rf apps/react-native-example/build apps/react-native-example/ios/Pods apps/react-native-example/ios/Podfile.lock | |
| - name: Cache turborepo for RN iOS unit tests | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: ${{ env.TURBO_CACHE_DIR }} | |
| key: ${{ runner.os }}-turborepo-rn-ios-test-${{ hashFiles('yarn.lock', 'packages/react-native-enriched-markdown/ios/**', 'packages/react-native-enriched-markdown/src/**', 'packages/react-native-enriched-markdown/__tests__/ios/**', 'packages/core/cpp/**', 'apps/react-native-example/ios/**') }} | |
| restore-keys: | | |
| ${{ runner.os }}-turborepo-rn-ios-test- | |
| - name: Check turborepo cache for RN iOS unit tests | |
| run: | | |
| TURBO_CACHE_STATUS=$(yarn test:ios \ | |
| --cache-dir="${{ env.TURBO_CACHE_DIR }}" \ | |
| --dry=json | jq -r '.tasks[0].cache.status') | |
| if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then | |
| echo "turbo_cache_hit=1" >> $GITHUB_ENV | |
| fi | |
| - name: Restore cocoapods | |
| if: env.turbo_cache_hit != 1 | |
| id: cocoapods-cache | |
| uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: | | |
| **/ios/Pods | |
| key: ${{ runner.os }}-cocoapods-${{ hashFiles('apps/react-native-example/ios/Podfile.lock') }} | |
| restore-keys: | | |
| ${{ runner.os }}-cocoapods- | |
| - name: Install cocoapods | |
| if: env.turbo_cache_hit != 1 | |
| run: | | |
| cd apps/react-native-example/ios | |
| pod install | |
| env: | |
| NO_FLIPPER: 1 | |
| - name: Cache cocoapods | |
| if: env.turbo_cache_hit != 1 && steps.cocoapods-cache.outputs.cache-hit != 'true' | |
| uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: | | |
| **/ios/Pods | |
| key: ${{ steps.cocoapods-cache.outputs.cache-primary-key }} | |
| - name: Select iOS simulator | |
| if: env.turbo_cache_hit != 1 | |
| run: | | |
| UDID=$(xcrun simctl list devices available --json \ | |
| | jq -r '[.devices[] | .[] | select(.isAvailable and (.name | startswith("iPhone")))][0].udid') | |
| if [[ -z "$UDID" || "$UDID" == "null" ]]; then | |
| echo "No available iPhone simulator found" | |
| xcrun simctl list devices | |
| exit 1 | |
| fi | |
| echo "IOS_SIMULATOR_UDID=$UDID" >> $GITHUB_ENV | |
| - name: Run RN iOS unit tests | |
| run: yarn test:ios --cache-dir="${{ env.TURBO_CACHE_DIR }}" | |
| android-build: | |
| needs: changes | |
| if: needs.changes.outputs.android == 'true' | |
| runs-on: ubuntu-latest | |
| env: | |
| ANDROID_HOME: /usr/local/lib/android/sdk | |
| ANDROID_SDK_ROOT: /usr/local/lib/android/sdk | |
| TURBO_CACHE_DIR: .turbo/android-native | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Restore Android vendor files | |
| uses: ./.github/actions/restore-android-vendor | |
| - name: Cache turborepo for Android native | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: ${{ env.TURBO_CACHE_DIR }} | |
| key: ${{ runner.os }}-turborepo-android-native-build-${{ hashFiles('yarn.lock', 'packages/enriched-markdown-android/**', 'apps/android-example/**', 'packages/core/cpp/**', 'vendor/vendor-grammars.mjs', 'vendor/gen-registry.mjs', 'vendor/grammar-versions.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-turborepo-android-native-build- | |
| - name: Check turborepo cache for Android native build | |
| run: | | |
| TURBO_CACHE_STATUS=$(yarn turbo run build:android-native \ | |
| --filter=enriched-markdown-android-example \ | |
| --cache-dir="${{ env.TURBO_CACHE_DIR }}" \ | |
| --dry=json | jq -r '.tasks[0].cache.status') | |
| if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then | |
| echo "turbo_cache_hit=1" >> $GITHUB_ENV | |
| fi | |
| - name: Setup Android | |
| if: env.turbo_cache_hit != 1 | |
| uses: ./.github/actions/setup-android | |
| with: | |
| gradle-wrapper-properties: apps/android-example/gradle/wrapper/gradle-wrapper.properties | |
| - name: Build Android example | |
| env: | |
| JAVA_OPTS: '-XX:MaxHeapSize=6g' | |
| run: yarn turbo run build:android-native --filter=enriched-markdown-android-example --cache-dir="${{ env.TURBO_CACHE_DIR }}" | |
| android-unit-tests: | |
| needs: changes | |
| if: needs.changes.outputs.android == 'true' | |
| runs-on: ubuntu-latest | |
| env: | |
| ANDROID_HOME: /usr/local/lib/android/sdk | |
| ANDROID_SDK_ROOT: /usr/local/lib/android/sdk | |
| TURBO_CACHE_DIR: .turbo/android-native | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Restore Android vendor files | |
| uses: ./.github/actions/restore-android-vendor | |
| - name: Cache turborepo for Android native tests | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: ${{ env.TURBO_CACHE_DIR }} | |
| key: ${{ runner.os }}-turborepo-android-native-test-${{ hashFiles('yarn.lock', 'packages/enriched-markdown-android/**', 'packages/core/cpp/**', 'vendor/vendor-grammars.mjs', 'vendor/gen-registry.mjs', 'vendor/grammar-versions.json') }} | |
| restore-keys: | | |
| ${{ runner.os }}-turborepo-android-native-test- | |
| - name: Check turborepo cache for Android native tests | |
| run: | | |
| TURBO_CACHE_STATUS=$(yarn test:android-native \ | |
| --cache-dir="${{ env.TURBO_CACHE_DIR }}" \ | |
| --dry=json | jq -r '.tasks[0].cache.status') | |
| if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then | |
| echo "turbo_cache_hit=1" >> $GITHUB_ENV | |
| fi | |
| - name: Setup Android | |
| if: env.turbo_cache_hit != 1 | |
| uses: ./.github/actions/setup-android | |
| with: | |
| gradle-wrapper-properties: packages/enriched-markdown-android/gradle/wrapper/gradle-wrapper.properties | |
| - name: Run Android unit tests | |
| env: | |
| JAVA_OPTS: '-XX:MaxHeapSize=6g' | |
| run: yarn test:android-native --cache-dir="${{ env.TURBO_CACHE_DIR }}" | |
| android-kotlin-lint: | |
| needs: changes | |
| if: needs.changes.outputs.android == 'true' | |
| runs-on: ubuntu-latest | |
| env: | |
| ANDROID_HOME: /usr/local/lib/android/sdk | |
| ANDROID_SDK_ROOT: /usr/local/lib/android/sdk | |
| TURBO_CACHE_DIR: .turbo/android-native | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Restore Android vendor files | |
| uses: ./.github/actions/restore-android-vendor | |
| - name: Cache turborepo for Android native lint | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: ${{ env.TURBO_CACHE_DIR }} | |
| key: ${{ runner.os }}-turborepo-android-native-lint-${{ hashFiles('yarn.lock', 'packages/enriched-markdown-android/**') }} | |
| restore-keys: | | |
| ${{ runner.os }}-turborepo-android-native-lint- | |
| - name: Check turborepo cache for Android native lint | |
| run: | | |
| TURBO_CACHE_STATUS=$(yarn turbo run lint:android-native \ | |
| --filter=@enriched-markdown/android \ | |
| --cache-dir="${{ env.TURBO_CACHE_DIR }}" \ | |
| --dry=json | jq -r '.tasks[0].cache.status') | |
| if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then | |
| echo "turbo_cache_hit=1" >> $GITHUB_ENV | |
| fi | |
| - name: Setup Android | |
| if: env.turbo_cache_hit != 1 | |
| uses: ./.github/actions/setup-android | |
| with: | |
| gradle-wrapper-properties: packages/enriched-markdown-android/gradle/wrapper/gradle-wrapper.properties | |
| - name: Run ktlint and Android Lint | |
| run: yarn turbo run lint:android-native --filter=@enriched-markdown/android --cache-dir="${{ env.TURBO_CACHE_DIR }}" | |
| ios-build: | |
| needs: changes | |
| if: needs.changes.outputs.ios == 'true' | |
| runs-on: macos-latest-xlarge | |
| env: | |
| TURBO_CACHE_DIR: .turbo/ios-native | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Restore iOS vendor files | |
| uses: ./.github/actions/restore-ios-vendor | |
| - name: Cache turborepo for iOS native build | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: ${{ env.TURBO_CACHE_DIR }} | |
| key: ${{ runner.os }}-turborepo-ios-native-build-${{ hashFiles('yarn.lock', 'packages/enriched-markdown-ios/**', 'apps/ios-example/**', 'packages/core/cpp/**') }} | |
| restore-keys: | | |
| ${{ runner.os }}-turborepo-ios-native-build- | |
| - name: Check turborepo cache for iOS native build | |
| run: | | |
| TURBO_CACHE_STATUS=$(yarn turbo run build:ios-native \ | |
| --filter=enriched-markdown-ios-example \ | |
| --cache-dir="${{ env.TURBO_CACHE_DIR }}" \ | |
| --dry=json | jq -r '.tasks[0].cache.status') | |
| if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then | |
| echo "turbo_cache_hit=1" >> $GITHUB_ENV | |
| fi | |
| - name: Set up Xcode | |
| if: env.turbo_cache_hit != 1 | |
| uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0 | |
| with: | |
| xcode-version: '26.3' | |
| - name: Select iOS simulator | |
| if: env.turbo_cache_hit != 1 | |
| run: | | |
| UDID=$(xcrun simctl list devices available --json \ | |
| | jq -r '[.devices[] | .[] | select(.isAvailable and (.name | startswith("iPhone")))][0].udid') | |
| if [[ -z "$UDID" || "$UDID" == "null" ]]; then | |
| echo "No available iPhone simulator found" | |
| xcrun simctl list devices | |
| exit 1 | |
| fi | |
| echo "IOS_SIMULATOR_UDID=$UDID" >> $GITHUB_ENV | |
| - name: Build iOS example | |
| run: yarn turbo run build:ios-native --filter=enriched-markdown-ios-example --cache-dir="${{ env.TURBO_CACHE_DIR }}" | |
| ios-unit-tests: | |
| needs: changes | |
| if: needs.changes.outputs.ios == 'true' | |
| runs-on: macos-latest | |
| env: | |
| TURBO_CACHE_DIR: .turbo/ios-native | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Restore iOS vendor files | |
| uses: ./.github/actions/restore-ios-vendor | |
| - name: Cache turborepo for iOS native tests | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: ${{ env.TURBO_CACHE_DIR }} | |
| key: ${{ runner.os }}-turborepo-ios-native-test-${{ hashFiles('yarn.lock', 'packages/enriched-markdown-ios/**', 'packages/core/cpp/**') }} | |
| restore-keys: | | |
| ${{ runner.os }}-turborepo-ios-native-test- | |
| - name: Check turborepo cache for iOS native tests | |
| run: | | |
| TURBO_CACHE_STATUS=$(yarn test:ios-native \ | |
| --cache-dir="${{ env.TURBO_CACHE_DIR }}" \ | |
| --dry=json | jq -r '.tasks[0].cache.status') | |
| if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then | |
| echo "turbo_cache_hit=1" >> $GITHUB_ENV | |
| fi | |
| - name: Set up Xcode | |
| if: env.turbo_cache_hit != 1 | |
| uses: maxim-lobanov/setup-xcode@ed7a3b1fda3918c0306d1b724322adc0b8cc0a90 # v1.7.0 | |
| with: | |
| xcode-version: '26.3' | |
| - name: Select iOS simulator | |
| if: env.turbo_cache_hit != 1 | |
| run: | | |
| UDID=$(xcrun simctl list devices available --json \ | |
| | jq -r '[.devices[] | .[] | select(.isAvailable and (.name | startswith("iPhone")))][0].udid') | |
| if [[ -z "$UDID" || "$UDID" == "null" ]]; then | |
| echo "No available iPhone simulator found" | |
| xcrun simctl list devices | |
| exit 1 | |
| fi | |
| echo "IOS_SIMULATOR_UDID=$UDID" >> $GITHUB_ENV | |
| - name: Run iOS unit tests | |
| run: yarn test:ios-native --cache-dir="${{ env.TURBO_CACHE_DIR }}" | |
| ios-swift-lint: | |
| needs: changes | |
| if: needs.changes.outputs.ios == 'true' | |
| runs-on: macos-latest | |
| env: | |
| TURBO_CACHE_DIR: .turbo/ios-native | |
| SWIFTLINT_VERSION: 0.65.0 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1 | |
| - name: Setup | |
| uses: ./.github/actions/setup | |
| - name: Restore iOS vendor files | |
| uses: ./.github/actions/restore-ios-vendor | |
| - name: Cache turborepo for iOS native lint | |
| uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0 | |
| with: | |
| path: ${{ env.TURBO_CACHE_DIR }} | |
| key: ${{ runner.os }}-turborepo-ios-native-lint-${{ hashFiles('yarn.lock', 'packages/enriched-markdown-ios/**') }} | |
| restore-keys: | | |
| ${{ runner.os }}-turborepo-ios-native-lint- | |
| - name: Check turborepo cache for iOS native lint | |
| run: | | |
| TURBO_CACHE_STATUS=$(yarn turbo run lint:ios-native \ | |
| --filter=@enriched-markdown/ios \ | |
| --cache-dir="${{ env.TURBO_CACHE_DIR }}" \ | |
| --dry=json | jq -r '.tasks[0].cache.status') | |
| if [[ $TURBO_CACHE_STATUS == "HIT" ]]; then | |
| echo "turbo_cache_hit=1" >> $GITHUB_ENV | |
| fi | |
| - name: Install SwiftLint | |
| if: env.turbo_cache_hit != 1 | |
| run: | | |
| curl -fsSL -o "$RUNNER_TEMP/swiftlint.zip" \ | |
| "https://github.com/realm/SwiftLint/releases/download/${SWIFTLINT_VERSION}/portable_swiftlint.zip" | |
| mkdir -p "$RUNNER_TEMP/swiftlint" | |
| unzip -oq "$RUNNER_TEMP/swiftlint.zip" -d "$RUNNER_TEMP/swiftlint" | |
| echo "$RUNNER_TEMP/swiftlint" >> $GITHUB_PATH | |
| - name: Run Swift lint | |
| run: yarn turbo run lint:ios-native --filter=@enriched-markdown/ios --cache-dir="${{ env.TURBO_CACHE_DIR }}" | |
| ci-success: | |
| needs: | |
| - changes | |
| - core-parser | |
| - core-tests | |
| - rn-lint | |
| - rn-build-library | |
| - rn-build-android | |
| - rn-build-ios | |
| - rn-android-unit-tests | |
| - rn-ios-unit-tests | |
| - android-build | |
| - android-unit-tests | |
| - android-kotlin-lint | |
| - ios-build | |
| - ios-unit-tests | |
| - ios-swift-lint | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Verify required checks | |
| env: | |
| REACT_NATIVE: ${{ needs.changes.outputs.react-native }} | |
| ANDROID: ${{ needs.changes.outputs.android }} | |
| IOS: ${{ needs.changes.outputs.ios }} | |
| CORE_CPP: ${{ needs.changes.outputs.core-cpp }} | |
| CORE_PARSER: ${{ needs.core-parser.result }} | |
| CORE: ${{ needs.changes.outputs.core }} | |
| CORE_TESTS: ${{ needs.core-tests.result }} | |
| RN_LINT: ${{ needs.rn-lint.result }} | |
| RN_BUILD_LIBRARY: ${{ needs.rn-build-library.result }} | |
| RN_BUILD_ANDROID: ${{ needs.rn-build-android.result }} | |
| RN_BUILD_IOS: ${{ needs.rn-build-ios.result }} | |
| RN_ANDROID_UNIT_TESTS: ${{ needs.rn-android-unit-tests.result }} | |
| RN_IOS_UNIT_TESTS: ${{ needs.rn-ios-unit-tests.result }} | |
| ANDROID_BUILD: ${{ needs.android-build.result }} | |
| ANDROID_UNIT_TESTS: ${{ needs.android-unit-tests.result }} | |
| ANDROID_KOTLIN_LINT: ${{ needs.android-kotlin-lint.result }} | |
| IOS_BUILD: ${{ needs.ios-build.result }} | |
| IOS_UNIT_TESTS: ${{ needs.ios-unit-tests.result }} | |
| IOS_SWIFT_LINT: ${{ needs.ios-swift-lint.result }} | |
| CHANGES: ${{ needs.changes.result }} | |
| run: | | |
| if [[ "$CHANGES" != "success" ]]; then | |
| echo "changes job failed" | |
| exit 1 | |
| fi | |
| check_required() { | |
| local flag=$1 | |
| local result=$2 | |
| local name=$3 | |
| if [[ "$flag" == "true" && "$result" != "success" ]]; then | |
| echo "Required job $name has result $result (expected success)" | |
| exit 1 | |
| fi | |
| } | |
| if [[ "$REACT_NATIVE" != "true" && "$ANDROID" != "true" && "$IOS" != "true" && "$CORE_CPP" != "true" && "$CORE" != "true" ]]; then | |
| echo "No relevant changes detected - CI passed" | |
| exit 0 | |
| fi | |
| check_required "$CORE_CPP" "$CORE_PARSER" "core-parser" | |
| check_required "$CORE" "$CORE_TESTS" "core-tests" | |
| check_required "$REACT_NATIVE" "$RN_LINT" "rn-lint" | |
| check_required "$REACT_NATIVE" "$RN_BUILD_LIBRARY" "rn-build-library" | |
| check_required "$REACT_NATIVE" "$RN_BUILD_ANDROID" "rn-build-android" | |
| check_required "$REACT_NATIVE" "$RN_BUILD_IOS" "rn-build-ios" | |
| check_required "$REACT_NATIVE" "$RN_ANDROID_UNIT_TESTS" "rn-android-unit-tests" | |
| check_required "$REACT_NATIVE" "$RN_IOS_UNIT_TESTS" "rn-ios-unit-tests" | |
| check_required "$ANDROID" "$ANDROID_BUILD" "android-build" | |
| check_required "$ANDROID" "$ANDROID_UNIT_TESTS" "android-unit-tests" | |
| check_required "$ANDROID" "$ANDROID_KOTLIN_LINT" "android-kotlin-lint" | |
| check_required "$IOS" "$IOS_BUILD" "ios-build" | |
| check_required "$IOS" "$IOS_UNIT_TESTS" "ios-unit-tests" | |
| check_required "$IOS" "$IOS_SWIFT_LINT" "ios-swift-lint" | |
| echo "All required checks passed" |