[NT-2885] Create Kotlin SDK for Android #1190
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: Main Pipeline | |
| permissions: | |
| contents: read | |
| on: | |
| pull_request: | |
| push: | |
| branches: | |
| - main | |
| concurrency: | |
| group: main-pipeline-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| changes: | |
| name: 🔎 Detect Changes | |
| runs-on: namespace-profile-linux-8-vcpu-16-gb-ram-optimal | |
| outputs: | |
| build: ${{ steps.filter.outputs.build }} | |
| unit: ${{ steps.filter.outputs.unit }} | |
| e2e_node_sdk: ${{ steps.filter.outputs.e2e_node_sdk }} | |
| e2e_node_sdk_web_sdk: ${{ steps.filter.outputs.e2e_node_sdk_web_sdk }} | |
| e2e_web_sdk: ${{ steps.filter.outputs.e2e_web_sdk }} | |
| e2e_web_sdk_react: ${{ steps.filter.outputs.e2e_web_sdk_react }} | |
| e2e_react_web_sdk: ${{ steps.filter.outputs.e2e_react_web_sdk }} | |
| e2e_react_native_android: ${{ steps.filter.outputs.e2e_react_native_android }} | |
| e2e_android: ${{ steps.filter.outputs.e2e_android }} | |
| e2e_ios: ${{ steps.filter.outputs.e2e_ios }} | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 | |
| id: filter | |
| with: | |
| # Intentional CI policy: | |
| # - Implementation E2E jobs run only for implementations relevant to changed paths. | |
| # - Skipped E2E jobs due to unmatched filters are expected behavior. | |
| # - Keep this mapping aligned with CONTRIBUTING.md ("E2E Coverage and Environment"). | |
| filters: | | |
| build: | |
| - 'lib/**' | |
| - 'packages/**' | |
| - 'package.json' | |
| - 'pnpm-lock.yaml' | |
| - 'pnpm-workspace.yaml' | |
| - 'tsconfig*.json' | |
| - '.github/workflows/main-pipeline.yaml' | |
| unit: | |
| - 'lib/**' | |
| - 'packages/**' | |
| - '**/rstest.config.ts' | |
| - 'package.json' | |
| - 'pnpm-lock.yaml' | |
| - 'pnpm-workspace.yaml' | |
| - '.github/workflows/main-pipeline.yaml' | |
| # Node SSR Only implementation E2E coverage scope. | |
| e2e_node_sdk: | |
| - 'implementations/node-sdk/**' | |
| - 'lib/**' | |
| - 'packages/node/node-sdk/**' | |
| - 'packages/universal/core-sdk/**' | |
| - 'packages/universal/api-client/**' | |
| - 'packages/universal/api-schemas/**' | |
| - 'package.json' | |
| - 'pnpm-lock.yaml' | |
| - '.github/workflows/main-pipeline.yaml' | |
| # Node SSR + Web Vanilla implementation E2E coverage scope. | |
| e2e_node_sdk_web_sdk: | |
| - 'implementations/node-sdk+web-sdk/**' | |
| - 'lib/**' | |
| - 'packages/node/node-sdk/**' | |
| - 'packages/web/web-sdk/**' | |
| - 'packages/web/preview-panel/**' | |
| - 'packages/universal/core-sdk/**' | |
| - 'packages/universal/api-client/**' | |
| - 'packages/universal/api-schemas/**' | |
| - 'package.json' | |
| - 'pnpm-lock.yaml' | |
| - '.github/workflows/main-pipeline.yaml' | |
| # Web Vanilla implementation E2E coverage scope. | |
| e2e_web_sdk: | |
| - 'implementations/web-sdk/**' | |
| - 'lib/**' | |
| - 'packages/web/web-sdk/**' | |
| - 'packages/web/preview-panel/**' | |
| - 'packages/universal/core-sdk/**' | |
| - 'packages/universal/api-client/**' | |
| - 'packages/universal/api-schemas/**' | |
| - 'package.json' | |
| - 'pnpm-lock.yaml' | |
| - '.github/workflows/main-pipeline.yaml' | |
| # React + Web SDK implementation E2E coverage scope. | |
| e2e_web_sdk_react: | |
| - 'implementations/web-sdk_react/**' | |
| - 'lib/**' | |
| - 'packages/web/web-sdk/**' | |
| - 'packages/web/preview-panel/**' | |
| - 'packages/universal/core-sdk/**' | |
| - 'packages/universal/api-client/**' | |
| - 'packages/universal/api-schemas/**' | |
| - 'package.json' | |
| - 'pnpm-lock.yaml' | |
| - '.github/workflows/main-pipeline.yaml' | |
| # React Web SDK (optimization-react-web) implementation E2E coverage scope. | |
| e2e_react_web_sdk: | |
| - 'implementations/react-web-sdk/**' | |
| - 'lib/**' | |
| - 'packages/web/frameworks/react-web-sdk/**' | |
| - 'packages/web/web-sdk/**' | |
| - 'packages/web/preview-panel/**' | |
| - 'packages/universal/core-sdk/**' | |
| - 'packages/universal/api-client/**' | |
| - 'packages/universal/api-schemas/**' | |
| - 'package.json' | |
| - 'pnpm-lock.yaml' | |
| - '.github/workflows/main-pipeline.yaml' | |
| # React Native Android implementation E2E coverage scope. | |
| e2e_react_native_android: | |
| - 'implementations/react-native-sdk/**' | |
| - 'lib/**' | |
| - 'packages/react-native-sdk/**' | |
| - 'packages/universal/core-sdk/**' | |
| - 'packages/universal/api-client/**' | |
| - 'packages/universal/api-schemas/**' | |
| - 'package.json' | |
| - 'pnpm-lock.yaml' | |
| - '.github/workflows/main-pipeline.yaml' | |
| # Android native implementation E2E coverage scope. | |
| e2e_android: | |
| - 'implementations/android-sdk/**' | |
| - 'lib/mocks/**' | |
| - 'packages/android/**' | |
| - 'package.json' | |
| - 'pnpm-lock.yaml' | |
| - '.github/workflows/main-pipeline.yaml' | |
| # iOS native implementation E2E coverage scope. | |
| e2e_ios: | |
| - 'implementations/ios-sdk/**' | |
| - 'lib/mocks/**' | |
| - 'packages/ios/**' | |
| - 'package.json' | |
| - 'pnpm-lock.yaml' | |
| - '.github/workflows/main-pipeline.yaml' | |
| setup: | |
| name: 🛠️ pnpm install | |
| runs-on: namespace-profile-linux-8-vcpu-16-gb-ram-optimal | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - name: Set up pnpm cache (Namespace) | |
| uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: pnpm | |
| - run: pnpm install --prefer-offline --frozen-lockfile | |
| license-check: | |
| name: 📄 License Check | |
| runs-on: namespace-profile-linux-8-vcpu-16-gb-ram-optimal | |
| needs: setup | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1 | |
| id: filter | |
| with: | |
| filters: | | |
| lock: | |
| - 'pnpm-lock.yaml' | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - name: Set up pnpm cache (Namespace) | |
| if: steps.filter.outputs.lock == 'true' | |
| uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: pnpm | |
| - if: steps.filter.outputs.lock == 'true' | |
| run: pnpm install --prefer-offline --frozen-lockfile | |
| - if: steps.filter.outputs.lock == 'true' | |
| run: | | |
| echo "In case of error, please see ./CONTRIBUTING.md" | |
| pnpx license-checker \ | |
| --summary \ | |
| --production \ | |
| --relativeLicensePath \ | |
| --onlyAllow 'MIT;Apache-2.0;ISC;BSD-3-Clause;BSD-2-Clause;MIT*;Apache 2.0;Unlicense;Unlicensed;:CC0-1.0;CC-BY-4.0;WTFPL;0BSD;UNLICENSED;Python-2.0;MPL-2.0;CC-BY-3.0;CC0-1.0' | |
| format: | |
| name: 🎨 Format Check | |
| runs-on: namespace-profile-linux-8-vcpu-16-gb-ram-optimal | |
| needs: setup | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: pnpm | |
| - run: pnpm install --prefer-offline --frozen-lockfile | |
| - run: pnpm format:check | |
| build: | |
| name: 📦 Build | |
| runs-on: namespace-profile-linux-8-vcpu-16-gb-ram-optimal | |
| timeout-minutes: 15 | |
| needs: setup | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: pnpm | |
| - run: pnpm install --prefer-offline --frozen-lockfile | |
| - run: pnpm build:ci | |
| - name: Pack SDK tarballs for implementations | |
| run: | | |
| rm -rf pkgs | |
| mkdir -p pkgs | |
| pnpm run pack:pkgs | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: sdk-package-tarballs | |
| path: pkgs/*.tgz | |
| if-no-files-found: error | |
| retention-days: 1 | |
| type-check: | |
| name: 🔷 Type Check | |
| runs-on: namespace-profile-linux-8-vcpu-16-gb-ram-optimal | |
| needs: setup | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: pnpm | |
| - run: pnpm install --prefer-offline --frozen-lockfile | |
| - run: pnpm typecheck | |
| lint: | |
| name: 🎨 Lint | |
| runs-on: namespace-profile-linux-8-vcpu-16-gb-ram-optimal | |
| needs: [setup, build] | |
| if: >- | |
| always() && needs.setup.result == 'success' && (needs.build.result == 'success' || | |
| needs.build.result == 'skipped') | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: pnpm | |
| - run: pnpm install --prefer-offline --frozen-lockfile | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| if: needs.build.result == 'success' | |
| with: | |
| name: sdk-package-tarballs | |
| path: pkgs | |
| - run: pnpm lint | |
| - if: needs.build.result == 'skipped' | |
| run: pnpm build:pkgs | |
| - run: pnpm store prune | |
| - run: pnpm run implementation:install -- --no-frozen-lockfile | |
| - run: pnpm implementation:lint | |
| test-unit: | |
| name: 🧪 Test (${{ matrix.package }}) | |
| runs-on: namespace-profile-linux-8-vcpu-16-gb-ram-optimal | |
| timeout-minutes: 15 | |
| needs: [setup, changes] | |
| if: needs.changes.outputs.unit == 'true' | |
| strategy: | |
| fail-fast: true | |
| matrix: | |
| include: | |
| - package: '@contentful/optimization-api-schemas' | |
| - package: '@contentful/optimization-api-client' | |
| - package: '@contentful/optimization-core' | |
| - package: '@contentful/optimization-node' | |
| - package: '@contentful/optimization-web' | |
| - package: '@contentful/optimization-web-preview-panel' | |
| - package: '@contentful/optimization-react-native' | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: pnpm | |
| - run: pnpm install --prefer-offline --frozen-lockfile | |
| - run: pnpm --filter ${{ matrix.package }} test:unit | |
| e2e-node-sdk: | |
| name: 🖥️ E2E Node SSR Only | |
| runs-on: namespace-profile-linux-8-vcpu-16-gb-ram-optimal | |
| timeout-minutes: 15 | |
| needs: [setup, changes, build] | |
| if: needs.changes.outputs.e2e_node_sdk == 'true' | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - name: Create .env from .env.example | |
| run: cp implementations/node-sdk/.env.example implementations/node-sdk/.env | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - name: Set up caches (Namespace) | |
| uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: | | |
| pnpm | |
| playwright | |
| apt | |
| - run: pnpm install --prefer-offline --frozen-lockfile | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: sdk-package-tarballs | |
| path: pkgs | |
| - run: pnpm store prune | |
| - run: pnpm run implementation:node-sdk -- implementation:install -- --no-frozen-lockfile | |
| - run: pnpm run implementation:node-sdk -- implementation:playwright:install -- --with-deps | |
| - run: pnpm run implementation:node-sdk -- implementation:test:e2e:run | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| if: ${{ !cancelled() }} | |
| with: | |
| name: ci-results-node-sdk | |
| path: | | |
| ./implementations/node-sdk/playwright-report/ | |
| ./implementations/node-sdk/test-results/ | |
| retention-days: 1 | |
| e2e-node-sdk-web-sdk: | |
| name: 🖥️ E2E Node SSR + Web Vanilla | |
| runs-on: namespace-profile-linux-8-vcpu-16-gb-ram-optimal | |
| timeout-minutes: 15 | |
| needs: [setup, changes, build] | |
| if: needs.changes.outputs.e2e_node_sdk_web_sdk == 'true' | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - name: Create .env from .env.example | |
| run: > | |
| cp implementations/node-sdk+web-sdk/.env.example implementations/node-sdk+web-sdk/.env | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - name: Set up caches (Namespace) | |
| uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: | | |
| pnpm | |
| playwright | |
| apt | |
| - run: pnpm install --prefer-offline --frozen-lockfile | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: sdk-package-tarballs | |
| path: pkgs | |
| - run: pnpm store prune | |
| - run: | |
| pnpm run implementation:node-sdk+web-sdk -- implementation:install -- --no-frozen-lockfile | |
| - run: | |
| pnpm run implementation:node-sdk+web-sdk -- implementation:playwright:install -- | |
| --with-deps | |
| - run: pnpm run implementation:node-sdk+web-sdk -- implementation:test:e2e:run | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| if: ${{ !cancelled() }} | |
| with: | |
| name: ci-results-node-sdk+web-sdk | |
| path: | | |
| ./implementations/node-sdk+web-sdk/playwright-report/ | |
| ./implementations/node-sdk+web-sdk/test-results/ | |
| retention-days: 1 | |
| e2e-web-sdk: | |
| name: 🖥️ E2E Web Vanilla | |
| runs-on: namespace-profile-linux-8-vcpu-16-gb-ram-optimal | |
| timeout-minutes: 15 | |
| needs: [setup, changes, build] | |
| if: needs.changes.outputs.e2e_web_sdk == 'true' | |
| steps: | |
| - uses: docker/setup-compose-action@8cccb8c14b6500aaffebff1aa49c502c34d2e5e6 # v2.1.0 | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - name: Create .env from .env.example | |
| run: cp implementations/web-sdk/.env.example implementations/web-sdk/.env | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - name: Set up caches (Namespace) | |
| uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: | | |
| pnpm | |
| playwright | |
| apt | |
| - run: pnpm install --prefer-offline --frozen-lockfile | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: sdk-package-tarballs | |
| path: pkgs | |
| - run: pnpm store prune | |
| - run: pnpm run implementation:web-sdk -- implementation:install -- --no-frozen-lockfile | |
| - run: pnpm run implementation:web-sdk -- implementation:playwright:install -- --with-deps | |
| - run: pnpm run implementation:web-sdk -- implementation:test:e2e:run | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| if: ${{ !cancelled() }} | |
| with: | |
| name: ci-results-web-sdk | |
| path: | | |
| ./implementations/web-sdk/playwright-report/ | |
| ./implementations/web-sdk/test-results/ | |
| retention-days: 1 | |
| e2e-web-sdk_react: | |
| name: 🖥️ E2E React + Web SDK | |
| runs-on: namespace-profile-linux-8-vcpu-16-gb-ram-optimal | |
| timeout-minutes: 15 | |
| needs: [setup, changes, build] | |
| if: needs.changes.outputs.e2e_web_sdk_react == 'true' | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - name: Create .env from .env.example | |
| run: cp implementations/web-sdk_react/.env.example implementations/web-sdk_react/.env | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - name: Set up caches (Namespace) | |
| uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: | | |
| pnpm | |
| playwright | |
| apt | |
| - run: pnpm install --prefer-offline --frozen-lockfile | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: sdk-package-tarballs | |
| path: pkgs | |
| - run: pnpm store prune | |
| - run: pnpm run implementation:web-sdk_react -- implementation:install -- --no-frozen-lockfile | |
| - run: | |
| pnpm run implementation:web-sdk_react -- implementation:playwright:install -- --with-deps | |
| - run: pnpm run implementation:web-sdk_react -- implementation:test:e2e:run | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| if: ${{ !cancelled() }} | |
| with: | |
| name: ci-results-web-sdk_react | |
| path: | | |
| ./implementations/web-sdk_react/playwright-report/ | |
| ./implementations/web-sdk_react/test-results/ | |
| retention-days: 1 | |
| e2e-react-web-sdk: | |
| name: ⚛️ E2E React Web SDK | |
| runs-on: namespace-profile-linux-8-vcpu-16-gb-ram-optimal | |
| timeout-minutes: 15 | |
| needs: [setup, changes, build] | |
| if: needs.changes.outputs.e2e_react_web_sdk == 'true' | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - name: Create .env from .env.example | |
| run: cp implementations/react-web-sdk/.env.example implementations/react-web-sdk/.env | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - name: Set up caches (Namespace) | |
| uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: | | |
| pnpm | |
| playwright | |
| apt | |
| - run: pnpm install --prefer-offline --frozen-lockfile | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: sdk-package-tarballs | |
| path: pkgs | |
| - run: pnpm store prune | |
| - run: pnpm run implementation:react-web-sdk -- implementation:install -- --no-frozen-lockfile | |
| - run: | |
| pnpm run implementation:react-web-sdk -- implementation:playwright:install -- --with-deps | |
| - run: pnpm run implementation:react-web-sdk -- implementation:test:e2e:run | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| if: ${{ !cancelled() }} | |
| with: | |
| name: ci-results-react-web-sdk | |
| path: | | |
| ./implementations/react-web-sdk/playwright-report/ | |
| ./implementations/react-web-sdk/test-results/ | |
| retention-days: 1 | |
| e2e-react-native-android-build: | |
| name: 📱 Build React Native Android APK | |
| runs-on: namespace-profile-linux-16-vcpu-32-gb-ram-optimal | |
| timeout-minutes: 30 | |
| needs: [setup, changes, build] | |
| if: needs.changes.outputs.e2e_react_native_android == 'true' | |
| env: | |
| CI: 'true' | |
| GRADLE_OPTS: >- | |
| -Dorg.gradle.daemon=false -Dorg.gradle.parallel=true -Dorg.gradle.jvmargs=-Xmx4g | |
| -Dkotlin.daemon.jvm.options=-Xmx2g | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - name: Set Android SDK environment variables | |
| run: | | |
| echo "ANDROID_SDK_ROOT=$HOME/.android/sdk" >> "$GITHUB_ENV" | |
| echo "ANDROID_HOME=$HOME/.android/sdk" >> "$GITHUB_ENV" | |
| - name: Prepare cache directories | |
| run: | | |
| mkdir -p "$HOME/.android/sdk" "$HOME/.android/avd" "$HOME/.android/cache" | |
| - name: Set up caches (Namespace) | |
| uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: | | |
| pnpm | |
| gradle | |
| path: | | |
| ~/.android/sdk | |
| ~/.android/cache | |
| - name: Setup Java | |
| uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '17' | |
| - name: Setup Android SDK | |
| uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4.0.1 | |
| - name: Install JS dependencies | |
| run: pnpm install --prefer-offline --frozen-lockfile | |
| - name: Download SDK package tarballs | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: sdk-package-tarballs | |
| path: pkgs | |
| - name: Prune pnpm store metadata cache | |
| run: pnpm store prune | |
| - name: Install React Native implementation dependencies | |
| run: > | |
| pnpm run implementation:react-native-sdk -- implementation:install -- --no-frozen-lockfile | |
| - name: Create .env from .env.example | |
| run: cp implementations/react-native-sdk/.env.example implementations/react-native-sdk/.env | |
| - name: Build Android app (Detox release) | |
| run: pnpm run implementation:react-native-sdk -- test:e2e:android:build:release | |
| - name: Upload Detox APKs | |
| uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: detox-android-apks | |
| path: implementations/react-native-sdk/android/app/build/outputs/apk/ | |
| if-no-files-found: error | |
| retention-days: 1 | |
| e2e-android-sdk: | |
| name: 🤖 E2E Android Native | |
| runs-on: namespace-profile-linux-16-vcpu-32-gb-ram-optimal | |
| timeout-minutes: 45 | |
| needs: [setup, changes] | |
| if: needs.changes.outputs.e2e_android == 'true' | |
| env: | |
| CI: 'true' | |
| GRADLE_OPTS: >- | |
| -Dorg.gradle.daemon=false -Dorg.gradle.parallel=true -Dorg.gradle.jvmargs=-Xmx4g | |
| -Dkotlin.daemon.jvm.options=-Xmx2g | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - name: Set Android SDK environment variables | |
| run: | | |
| echo "ANDROID_SDK_ROOT=$HOME/.android/sdk" >> "$GITHUB_ENV" | |
| echo "ANDROID_HOME=$HOME/.android/sdk" >> "$GITHUB_ENV" | |
| - name: Prepare cache directories | |
| run: | | |
| mkdir -p "$HOME/.android/sdk" "$HOME/.android/avd" "$HOME/.android/cache" | |
| - name: Set up caches (Namespace) | |
| uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: | | |
| pnpm | |
| gradle | |
| path: | | |
| ~/.android/sdk | |
| ~/.android/avd | |
| ~/.android/cache | |
| - name: Install system dependencies (Android emulator) | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends \ | |
| ca-certificates curl unzip zip git \ | |
| netcat-openbsd cpu-checker \ | |
| libgl1 libnss3 libx11-6 libx11-xcb1 libxcomposite1 libxdamage1 libxrandr2 libxtst6 \ | |
| libxi6 libxrender1 libxkbcommon0 libgbm1 libdbus-1-3 libdrm2 libpulse0 | |
| sudo apt-get install -y --no-install-recommends libasound2 || sudo apt-get install -y --no-install-recommends libasound2t64 | |
| - name: Verify KVM is available | |
| run: | | |
| if [ ! -e /dev/kvm ]; then | |
| echo "/dev/kvm not found; Android hardware acceleration will not work." >&2 | |
| exit 1 | |
| fi | |
| ls -l /dev/kvm | |
| sudo kvm-ok || true | |
| - name: Setup Java | |
| uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '17' | |
| - name: Setup Android SDK | |
| uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4.0.1 | |
| - name: Install JS dependencies | |
| run: pnpm install --prefer-offline --frozen-lockfile | |
| - name: Build Android bridge JS bundle | |
| run: pnpm --filter @contentful/optimization-android-bridge build | |
| - name: Build app and test APKs | |
| working-directory: implementations/android-sdk | |
| run: ./gradlew :app:assembleDebug :uitests:assembleDebug | |
| - name: Start Mock Server | |
| run: | | |
| pnpm --dir lib/mocks serve > /tmp/mock-server.log 2>&1 & | |
| echo $! > /tmp/mock-server.pid | |
| for i in {1..60}; do | |
| if nc -z localhost 8000 2>/dev/null; then | |
| echo "Mock server is ready" | |
| break | |
| fi | |
| echo "Waiting for mock server... ($i/60)" | |
| sleep 1 | |
| done | |
| if ! nc -z localhost 8000 2>/dev/null; then | |
| echo "Mock server failed to start:" | |
| cat /tmp/mock-server.log | |
| exit 1 | |
| fi | |
| - name: Run Android E2E Tests (emulator) | |
| uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a # v2.37.0 | |
| with: | |
| api-level: 35 | |
| arch: x86_64 | |
| target: google_apis | |
| profile: pixel_7 | |
| avd-name: test | |
| force-avd-creation: true | |
| emulator-boot-timeout: 600 | |
| cores: 6 | |
| ram-size: 4096M | |
| disk-size: 8G | |
| disable-animations: true | |
| emulator-options: -no-window -no-audio -no-boot-anim -gpu swiftshader_indirect | |
| script: | | |
| echo "Disabling animations..." | |
| adb shell settings put global window_animation_scale 0 | |
| adb shell settings put global transition_animation_scale 0 | |
| adb shell settings put global animator_duration_scale 0 | |
| echo "Installing APKs..." | |
| adb install -r implementations/android-sdk/app/build/outputs/apk/debug/app-debug.apk | |
| adb install -r implementations/android-sdk/uitests/build/outputs/apk/debug/uitests-debug.apk | |
| echo "Setting up adb reverse port forwarding..." | |
| adb reverse tcp:8000 tcp:8000 | |
| sleep 3 | |
| adb shell "for i in 1 2 3 4 5 6 7 8 9 10; do nc -z localhost 8000 2>/dev/null && echo 'Mock server tunnel verified' && exit 0; sleep 1; done; echo 'WARNING: tunnel verification timed out'" | |
| echo "Running UI Automator 2 E2E tests..." | |
| adb shell am instrument -w com.contentful.optimization.uitests/androidx.test.runner.AndroidJUnitRunner 2>&1 | tee /tmp/test-output.log | |
| grep -q "FAILURES" /tmp/test-output.log && { echo "::error::Android UI tests failed"; exit 1; } || true | |
| grep -q "Process crashed" /tmp/test-output.log && { echo "::error::Test process crashed"; exit 1; } || true | |
| - name: Upload logs on failure | |
| if: failure() | |
| run: | | |
| echo "=== Mock Server Logs ===" | |
| cat /tmp/mock-server.log || echo "No mock server logs found" | |
| - name: Stop Mock Server | |
| if: always() | |
| run: | | |
| kill $(cat /tmp/mock-server.pid) 2>/dev/null || true | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| if: always() | |
| with: | |
| name: ci-results-android-sdk | |
| path: | | |
| implementations/android-sdk/logs/ | |
| /tmp/mock-server.log | |
| /tmp/test-output.log | |
| retention-days: 7 | |
| e2e-ios-sdk-build: | |
| name: 🍎 Build iOS UI Test Bundles | |
| runs-on: namespace-profile-macos-apple-silicon-arm64-6-cpu-14-gb | |
| timeout-minutes: 30 | |
| needs: [setup, changes] | |
| if: needs.changes.outputs.e2e_ios == 'true' | |
| env: | |
| DERIVED_DATA: /tmp/optimization-ios-derived-data | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - name: Install XcodeGen and xcbeautify | |
| run: brew install xcodegen xcbeautify | |
| - name: Set up caches (Namespace) | |
| uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: pnpm | |
| path: | | |
| ~/Library/Caches/org.swift.swiftpm | |
| - name: Show toolchain | |
| run: | | |
| xcodebuild -version | |
| xcrun simctl list runtimes | head | |
| - run: pnpm install --prefer-offline --frozen-lockfile | |
| - name: Build iOS UI test bundles (SwiftUI + UIKit) | |
| run: pnpm run implementation:ios-sdk -- test:e2e:ios:build:release | |
| - name: Stage Build/Products for artifact | |
| run: | | |
| mkdir -p /tmp/ios-artifact | |
| cp -R "$DERIVED_DATA/Build/Products" /tmp/ios-artifact/Products | |
| ls /tmp/ios-artifact/Products/*.xctestrun | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| with: | |
| name: ios-uitest-bundles | |
| path: /tmp/ios-artifact/ | |
| if-no-files-found: error | |
| retention-days: 1 | |
| e2e-react-native-android: | |
| name: 📱 E2E React Native Android (shard ${{ matrix.shard }}/2) | |
| runs-on: namespace-profile-linux-16-vcpu-32-gb-ram-optimal | |
| timeout-minutes: 45 | |
| needs: [setup, changes, e2e-react-native-android-build] | |
| if: needs.changes.outputs.e2e_react_native_android == 'true' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| shard: [1, 2] | |
| env: | |
| DETOX_AVD_NAME: test | |
| CI: 'true' | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - name: Set Android SDK environment variables | |
| run: | | |
| echo "ANDROID_SDK_ROOT=$HOME/.android/sdk" >> "$GITHUB_ENV" | |
| echo "ANDROID_HOME=$HOME/.android/sdk" >> "$GITHUB_ENV" | |
| - name: Prepare cache directories | |
| run: | | |
| mkdir -p "$HOME/.android/sdk" "$HOME/.android/avd" "$HOME/.android/cache" | |
| - name: Set up caches (Namespace) | |
| uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: | | |
| apt | |
| pnpm | |
| path: | | |
| ~/.android/sdk | |
| ~/.android/avd | |
| ~/.android/cache | |
| - name: Install system dependencies (Android emulator + React Native) | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y --no-install-recommends \ | |
| ca-certificates curl unzip zip git \ | |
| python3 python3-pip build-essential \ | |
| netcat-openbsd watchman \ | |
| cpu-checker \ | |
| libgl1 libnss3 libx11-6 libx11-xcb1 libxcomposite1 libxdamage1 libxrandr2 libxtst6 \ | |
| libxi6 libxrender1 libxkbcommon0 libgbm1 libdbus-1-3 libdrm2 libpulse0 | |
| sudo apt-get install -y --no-install-recommends libasound2 || sudo apt-get install -y --no-install-recommends libasound2t64 | |
| - name: Verify KVM is available | |
| run: | | |
| if [ ! -e /dev/kvm ]; then | |
| echo "/dev/kvm not found; Android hardware acceleration will not work." >&2 | |
| exit 1 | |
| fi | |
| ls -l /dev/kvm | |
| sudo kvm-ok || true | |
| - name: Setup Java | |
| uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0 | |
| with: | |
| distribution: 'temurin' | |
| java-version: '17' | |
| - name: Setup Android SDK | |
| uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4.0.1 | |
| - name: Install JS dependencies | |
| run: pnpm install --prefer-offline --frozen-lockfile | |
| - name: Download SDK package tarballs | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: sdk-package-tarballs | |
| path: pkgs | |
| - name: Prune pnpm store metadata cache | |
| run: pnpm store prune | |
| - name: Install React Native implementation dependencies | |
| run: > | |
| pnpm run implementation:react-native-sdk -- implementation:install -- --no-frozen-lockfile | |
| - name: Create .env from .env.example | |
| run: cp implementations/react-native-sdk/.env.example implementations/react-native-sdk/.env | |
| - name: Download pre-built Detox APKs | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: detox-android-apks | |
| path: implementations/react-native-sdk/android/app/build/outputs/apk/ | |
| - name: Start Mock Server | |
| run: | | |
| pnpm --dir lib/mocks serve > /tmp/mock-server.log 2>&1 & | |
| echo $! > /tmp/mock-server.pid | |
| for i in {1..60}; do | |
| if nc -z localhost 8000 2>/dev/null; then | |
| echo "Mock server is ready" | |
| break | |
| fi | |
| echo "Waiting for mock server... ($i/60)" | |
| sleep 1 | |
| done | |
| if ! nc -z localhost 8000 2>/dev/null; then | |
| echo "Mock server failed to start:" | |
| cat /tmp/mock-server.log | |
| exit 1 | |
| fi | |
| - name: Run Android E2E Tests (emulator) | |
| uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a # v2.37.0 | |
| with: | |
| api-level: 36 | |
| arch: x86_64 | |
| target: google_apis | |
| profile: pixel_tablet | |
| avd-name: test | |
| force-avd-creation: true | |
| emulator-boot-timeout: 600 | |
| cores: 6 | |
| ram-size: 4096M | |
| disk-size: 8G | |
| disable-animations: true | |
| emulator-options: -no-window -no-audio -no-boot-anim -gpu swiftshader_indirect | |
| script: | | |
| echo "Verifying JAVA_HOME: $JAVA_HOME" | |
| java -version | |
| echo "Setting up adb reverse port forwarding..." | |
| adb reverse tcp:8000 tcp:8000 | |
| echo "Running E2E tests..." | |
| pnpm run implementation:react-native-sdk -- test:e2e:android:run:release -- --retries 1 --shard=${{ matrix.shard }}/2 | |
| - name: Upload logs on failure | |
| if: failure() | |
| run: | | |
| echo "=== Mock Server Logs ===" | |
| cat /tmp/mock-server.log || echo "No mock server logs found" | |
| - name: Stop Mock Server | |
| if: always() | |
| run: | | |
| kill $(cat /tmp/mock-server.pid) 2>/dev/null || true | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| if: always() | |
| with: | |
| name: ci-results-react-native-android-shard-${{ matrix.shard }} | |
| path: | | |
| implementations/react-native-sdk/.detox/ | |
| /tmp/mock-server.log | |
| retention-days: 7 | |
| e2e-ios-sdk: | |
| name: 🍎 E2E iOS UI (${{ matrix.scheme }}) | |
| runs-on: namespace-profile-macos-apple-silicon-arm64-6-cpu-14-gb | |
| timeout-minutes: 45 | |
| needs: [setup, changes, e2e-ios-sdk-build] | |
| if: needs.changes.outputs.e2e_ios == 'true' | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - scheme: SwiftUI | |
| - scheme: UIKit | |
| env: | |
| DERIVED_DATA: /tmp/optimization-ios-derived-data | |
| IOS_SCHEME: ${{ matrix.scheme }} | |
| IOS_SIM_NAME: 'iPhone 16' | |
| IOS_SIM_OS: 'latest' | |
| # Smoke mode for the first PR — restrict to one test class per scheme. | |
| # Remove this env var in a follow-up PR to enable the full suite. | |
| IOS_ONLY_TESTING: OptimizationAppUITests${{ matrix.scheme }}/PreviewPanelTests | |
| steps: | |
| - uses: namespacelabs/nscloud-checkout-action@938f5d2d403d6224d9a0c0dc559b1dae09c2ede4 # v8.1.1 | |
| - uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0 | |
| with: | |
| node-version-file: '.nvmrc' | |
| package-manager-cache: false | |
| - uses: pnpm/action-setup@903f9c1a6ebcba6cf41d87230be49611ac97822e # v6.0.3 | |
| - name: Install xcbeautify | |
| run: brew install xcbeautify | |
| - uses: namespacelabs/nscloud-cache-action@15799a6b54e5765f85b2aac25b3f0df43ed571c0 # v1.4.3 | |
| with: | |
| cache: pnpm | |
| - run: pnpm install --prefer-offline --frozen-lockfile | |
| - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: ios-uitest-bundles | |
| path: /tmp/ios-artifact/ | |
| - name: Reconstruct DerivedData layout at stable path | |
| run: | | |
| mkdir -p "$DERIVED_DATA/Build" | |
| mv /tmp/ios-artifact/Products "$DERIVED_DATA/Build/Products" | |
| ls "$DERIVED_DATA/Build/Products" | |
| - name: Boot iOS Simulator | |
| run: | | |
| DEVICE_UDID=$(xcrun simctl create "ci-${{ matrix.scheme }}" "$IOS_SIM_NAME") | |
| echo "DEVICE_UDID=$DEVICE_UDID" >> "$GITHUB_ENV" | |
| xcrun simctl boot "$DEVICE_UDID" | |
| xcrun simctl bootstatus "$DEVICE_UDID" -b | |
| - name: Start Mock Server | |
| run: | | |
| pnpm --dir lib/mocks serve > /tmp/mock-server.log 2>&1 & | |
| echo $! > /tmp/mock-server.pid | |
| for i in {1..60}; do | |
| if nc -z localhost 8000 2>/dev/null; then | |
| echo "Mock server is ready" | |
| break | |
| fi | |
| echo "Waiting for mock server... ($i/60)" | |
| sleep 1 | |
| done | |
| if ! nc -z localhost 8000 2>/dev/null; then | |
| echo "Mock server failed to start:" | |
| cat /tmp/mock-server.log | |
| exit 1 | |
| fi | |
| - name: Verify built xctestrun exists for ${{ matrix.scheme }} | |
| shell: 'bash -eo pipefail {0}' | |
| run: | | |
| shopt -s nullglob | |
| matches=("$DERIVED_DATA"/Build/Products/OptimizationApp"$IOS_SCHEME"_*.xctestrun) | |
| if [ ${#matches[@]} -eq 0 ]; then | |
| echo "No xctestrun found for scheme $IOS_SCHEME under $DERIVED_DATA/Build/Products/" >&2 | |
| ls -la "$DERIVED_DATA/Build/Products/" || true | |
| exit 1 | |
| fi | |
| printf 'Found xctestrun: %s\n' "${matches[@]}" | |
| - name: Run iOS UI tests (${{ matrix.scheme }}) | |
| shell: 'bash -eo pipefail {0}' | |
| run: pnpm run implementation:ios-sdk -- test:e2e:ios:run:release | |
| - name: Stop Mock Server | |
| if: always() | |
| run: kill $(cat /tmp/mock-server.pid) 2>/dev/null || true | |
| - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 | |
| if: ${{ !cancelled() }} | |
| with: | |
| name: ci-results-ios-${{ matrix.scheme }} | |
| path: | | |
| /tmp/optimization-ios-derived-data/Test-*.xcresult | |
| /tmp/mock-server.log | |
| retention-days: 7 |