Onboarding Integration Tests #54
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: Onboarding Integration Tests | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - "lib/**" | |
| - "priv/templates/**" | |
| - "test/onboarding/**" | |
| - ".github/workflows/onboarding.yml" | |
| pull_request: | |
| paths: | |
| - "lib/**" | |
| - "priv/templates/**" | |
| - "test/onboarding/**" | |
| schedule: | |
| # Nightly at 06:00 UTC — catches regressions from upstream changes | |
| - cron: "0 6 * * *" | |
| workflow_dispatch: | |
| inputs: | |
| scope: | |
| description: "Test scope (generator | pre_device | all)" | |
| required: false | |
| default: "generator" | |
| concurrency: | |
| group: onboarding-${{ github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| # ── Fast gate: generator + pre-device (no simulator required) ──────────────── | |
| pre-device: | |
| name: "Pre-device (${{ matrix.env }} / Elixir ${{ matrix.elixir }})" | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Primary: Nix — highest-risk environment based on user reports | |
| - run: A | |
| env: nix | |
| elixir: "1.18" | |
| otp: "27" | |
| priority: critical | |
| # Latest toolchain via mise | |
| - run: B | |
| env: mise | |
| elixir: "1.19" | |
| otp: "28" | |
| priority: critical | |
| # Minimum versions via mise | |
| - run: C | |
| env: mise | |
| elixir: "1.18" | |
| otp: "27" | |
| priority: standard | |
| # asdf | |
| - run: D | |
| env: asdf | |
| elixir: "1.19" | |
| otp: "28" | |
| priority: standard | |
| runs-on: macos-15 # Apple Silicon; required for arm64 Android images | |
| steps: | |
| - uses: actions/checkout@v4 | |
| # ── Nix setup (Run A) ────────────────────────────────────────────────── | |
| - name: Install Nix | |
| if: matrix.env == 'nix' | |
| uses: cachix/install-nix-action@v26 | |
| with: | |
| nix_path: nixpkgs=channel:nixos-24.05 | |
| - name: Enter Nix dev shell and verify elixir version | |
| if: matrix.env == 'nix' | |
| run: | | |
| nix develop ./test/onboarding/nix#default --command elixir --version | |
| # Ensure Nix elixir is 1.18.x | |
| nix develop ./test/onboarding/nix#default --command \ | |
| elixir -e 'v = System.version(); [maj, min | _] = String.split(v, "."); if String.to_integer(min) < 18, do: exit(1)' | |
| # ── mise setup (Runs B, C) ───────────────────────────────────────────── | |
| - name: Install mise | |
| if: matrix.env == 'mise' | |
| uses: jdx/mise-action@v2 | |
| with: | |
| version: latest | |
| - name: Configure mise versions | |
| if: matrix.env == 'mise' | |
| run: | | |
| mise use --global elixir@${{ matrix.elixir }} | |
| mise use --global erlang@${{ matrix.otp }} | |
| mise install | |
| elixir --version | |
| # ── asdf setup (Run D) ──────────────────────────────────────────────── | |
| - name: Install asdf | |
| if: matrix.env == 'asdf' | |
| uses: asdf-vm/actions/setup@v3 | |
| - name: Configure asdf versions | |
| if: matrix.env == 'asdf' | |
| run: | | |
| asdf plugin add elixir https://github.com/asdf-vm/asdf-elixir.git || true | |
| asdf plugin add erlang https://github.com/asdf-vm/asdf-erlang.git || true | |
| asdf install elixir ${{ matrix.elixir }} | |
| asdf install erlang ${{ matrix.otp }} | |
| echo "elixir ${{ matrix.elixir }}" >> ~/.tool-versions | |
| echo "erlang ${{ matrix.otp }}" >> ~/.tool-versions | |
| # ── Android SDK ─────────────────────────────────────────────────────── | |
| - name: Set up Android SDK | |
| uses: android-actions/setup-android@v3 | |
| - name: Install Android SDK components | |
| run: | | |
| sdkmanager "platform-tools" "emulator" "build-tools;34.0.0" | |
| sdkmanager "system-images;android-28;google_apis;arm64-v8a" | |
| sdkmanager "system-images;android-35;google_apis;arm64-v8a" | |
| sdkmanager "platforms;android-34" "platforms;android-35" | |
| # ── Install Hex and dala archive ─────────────────────────────────────── | |
| - name: Install Hex | |
| run: mix local.hex --force | |
| - name: Cache dala archive | |
| uses: actions/cache@v4 | |
| with: | |
| path: ~/.mix/archives | |
| key: dala-archive-${{ hashFiles('mix.exs') }} | |
| # ── Run tests ───────────────────────────────────────────────────────── | |
| - name: Run generator + pre-device tests | |
| run: | | |
| mix dala.onboarding_test --only generator --env ${{ matrix.env }} | |
| mix dala.onboarding_test --only pre_device --env ${{ matrix.env }} | |
| timeout-minutes: 20 | |
| env: | |
| MIX_ENV: test | |
| # On Nix: ensure system curl is first in PATH to avoid SSL issues | |
| PATH: /usr/bin:/bin:${{ env.PATH }} | |
| # ── Artifacts on failure ────────────────────────────────────────────── | |
| - name: Upload failure logs | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: onboarding-pre-device-run-${{ matrix.run }} | |
| path: /tmp/dala_onboarding_*/logs/ | |
| retention-days: 7 | |
| # ── Full device tests: iOS + Android simulators/emulators ──────────────────── | |
| with-devices: | |
| name: "With devices (${{ matrix.ios }} + ${{ matrix.android }})" | |
| needs: pre-device # Only run after the fast gate passes | |
| # Run on: scheduled runs, manual dispatch with scope=all, or pushes to main. | |
| # On PRs and normal pushes, skip — the fast pre-device gate is sufficient. | |
| if: | | |
| always() && !cancelled() && | |
| needs.pre-device.result == 'success' && | |
| (github.event_name == 'schedule' || | |
| (github.event_name == 'workflow_dispatch' && github.event.inputs.scope == 'all') || | |
| github.ref == 'refs/heads/main') | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| # Minimum versions — most likely to reveal compatibility issues | |
| - run: ios-min | |
| ios: ios_min | |
| android: android_min | |
| # Maximum versions — latest OS features, fresh APIs | |
| - run: ios-max | |
| ios: ios_max | |
| android: android_max | |
| runs-on: macos-15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Install mise + Elixir 1.19 | |
| uses: jdx/mise-action@v2 | |
| with: | |
| version: latest | |
| - name: Install Hex + dala archive | |
| run: mix local.hex --force | |
| - name: Set up Android SDK | |
| uses: android-actions/setup-android@v3 | |
| - name: Install Android system images | |
| run: | | |
| sdkmanager "platform-tools" "emulator" "build-tools;34.0.0" | |
| sdkmanager "system-images;android-28;google_apis;arm64-v8a" | |
| sdkmanager "system-images;android-35;google_apis;arm64-v8a" | |
| sdkmanager "platforms;android-34" "platforms;android-35" | |
| - name: Download iOS 16 runtime (ios-min only) | |
| if: matrix.ios == 'ios_min' | |
| run: | | |
| xcrun simctl runtime add "com.apple.CoreSimulator.SimRuntime.iOS-16-0" || true | |
| timeout-minutes: 15 | |
| - name: Run full onboarding test (ios=${{ matrix.ios }}, android=${{ matrix.android }}) | |
| run: mix dala.onboarding_test --all --env mise | |
| timeout-minutes: 45 | |
| env: | |
| MIX_ENV: test | |
| DALA_TEST_IOS_SLOT: ${{ matrix.ios }} | |
| DALA_TEST_ANDROID_SLOT: ${{ matrix.android }} | |
| - name: Upload failure logs and workspace | |
| if: failure() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: onboarding-device-${{ matrix.run }} | |
| path: | | |
| /tmp/dala_onboarding_*/logs/ | |
| /tmp/dala_onboarding_*/dala_failure_test/ | |
| retention-days: 7 | |
| # ── Summary ─────────────────────────────────────────────────────────────────── | |
| summary: | |
| name: Onboarding gate | |
| needs: [pre-device, with-devices] | |
| if: always() | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Check results | |
| run: | | |
| if [[ "${{ needs.pre-device.result }}" != "success" ]]; then | |
| echo "::error::Pre-device tests failed" | |
| exit 1 | |
| fi | |
| # with-devices may be skipped (not a failure) when not on main/schedule/dispatch-all | |
| if [[ "${{ needs.with-devices.result }}" == "failure" ]]; then | |
| echo "::error::Device tests failed" | |
| exit 1 | |
| fi | |
| if [[ "${{ needs.with-devices.result }}" == "skipped" ]]; then | |
| echo "ℹ Device tests skipped (not on main/schedule/dispatch-all) — pre-device gate passed" | |
| fi | |
| echo "All onboarding tests passed" |