Skip to content

@Mobile E2E • Manual • iOS Only • support/tahoe-testing • lewisd5 #3891

@Mobile E2E • Manual • iOS Only • support/tahoe-testing • lewisd5

@Mobile E2E • Manual • iOS Only • support/tahoe-testing • lewisd5 #3891

name: "[Mobile] E2E Only - Scheduled/Manual"
run-name: >
@Mobile E2E • ${{ github.event_name == 'workflow_dispatch' && 'Manual' || github.event_name == 'schedule' && 'Scheduled' || github.event_name }} • ${{ inputs.tests_type || 'All' }} • ${{ inputs.ref || github.ref_name }} • ${{ github.actor }}
on:
schedule:
- cron: "0 3 * * 1-5"
workflow_dispatch:
inputs:
ref:
description: "The branch which triggered this workflow"
required: false
test_filter:
description: Filter to execute only test suite spec files according to pattern(s) (e.g. to execute nftGallery.spec.ts and deeplinks.spec.ts files "addAccount deeplinks")"
required: false
type: string
tests_type:
description: "Which tests to run"
required: true
type: choice
default: "iOS & Android"
options:
- "Android Only"
- "iOS Only"
- "iOS & Android"
speculos_device:
description: Speculos device to use
required: true
type: choice
options:
- nanoS
- nanoSP
- nanoX
- stax
- flex
- nanoGen5
default: nanoX
production_firebase:
description: "Target Firebase Production env"
required: false
type: boolean
default: false
enable_broadcast:
description: "Enable transaction broadcast"
required: false
type: boolean
default: false
export_to_xray:
description: "Send results to Xray"
required: false
type: boolean
default: false
test_execution_android:
description: "Xray execution key for Android (optional)"
required: false
type: string
test_execution_ios:
description: "Xray execution key for iOS (optional)"
required: false
type: string
workflow_call:
inputs:
ref:
description: "The branch which triggered this workflow"
required: false
type: string
test_filter:
description: "Filter to execute only test suite spec files according to pattern(s)"
required: false
type: string
tests_type:
description: "Which tests to run"
required: true
type: string
default: "iOS & Android"
speculos_device:
description: "Speculos device to use"
required: true
type: string
production_firebase:
description: "Target Firebase Production env"
required: false
type: boolean
default: false
enable_broadcast:
description: "Enable transaction broadcast"
required: false
type: boolean
default: false
permissions:
id-token: write
contents: read
env:
cache-bucket: ll-gha-s3-cache
ANDROID_APK_PATH: apps/ledger-live-mobile/android/app/build/outputs/apk/detox${{ inputs.production_firebase == true && 'PreRelease' || '' }}/app-x86_64-detox${{ inputs.production_firebase == true && 'PreRelease' || '' }}.apk
ANDROID_JSBUNDLE_PATH: apps/ledger-live-mobile/main.jsbundle
ANDROID_TESTBINARY_PATH: apps/ledger-live-mobile/android/app/build/outputs/apk/androidTest/detox${{ inputs.production_firebase == true && 'PreRelease' || '' }}/app-detox${{ inputs.production_firebase == true && 'PreRelease' || '' }}-androidTest.apk
IOS_JSBUNDLE_PATH: apps/ledger-live-mobile/ios/build/Build/Products/Release-iphonesimulator/ledgerlivemobile.app/main.jsbundle
IOS_NATIVE_PATH: apps/ledger-live-mobile/ios/build/Build/Products/Release-iphonesimulator
SPECULOS_IMAGE_TAG: ghcr.io/ledgerhq/speculos:${{ inputs.speculos_device == 'nanoS' && '1be65b91a8e0691866f880fd437ac05fce78af9d' || 'master' }}
COINAPPS: ${{ github.workspace }}/coin-apps
SPECULOS_DEVICE: ${{ inputs.speculos_device || 'nanoX' }}
# Android AVD configuration
AVD_API: 35
AVD_ARCH: x86_64
AVD_PROFILE: pixel_7_pro
AVD_TARGET: google_apis
AVD_NAME: "Android_Emulator"
AVD_CORES: 4
AVD_RAM_SIZE: 5120M
AVD_HEAP_SIZE: 1023M
AVD_OPTIONS: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
jobs:
determine-builds:
name: "Determine Builds & Generate Shards"
runs-on: ledger-live-medium
outputs:
matrix_ios: ${{ steps.generate-shards.outputs.matrix_ios }}
matrix_android: ${{ steps.generate-shards.outputs.matrix_android }}
test_files_for_sharding: ${{ steps.generate-shards.outputs.test_files_for_sharding }}
ios_timeout: ${{ steps.generate-shards.outputs.ios_timeout }}
android_timeout: ${{ steps.generate-shards.outputs.android_timeout }}
ios_native_exists: ${{ steps.check-ios-native.outputs.cache-hit }}
ios_js_exists: ${{ steps.check-ios-js.outputs.cache-hit }}
android_native_exists: ${{ steps.check-android-native.outputs.cache-hit }}
android_js_exists: ${{ steps.check-android-js.outputs.cache-hit }}
ios_native_key: ${{ steps.cache-keys.outputs.ios_native_key }}
ios_js_key: ${{ steps.cache-keys.outputs.ios_js_key }}
android_native_key: ${{ steps.cache-keys.outputs.android_native_key }}
android_js_key: ${{ steps.cache-keys.outputs.android_js_key }}
android_timing_cache_key: ${{ steps.cache-keys.outputs.android_timing_cache_key }}
ios_timing_cache_key: ${{ steps.cache-keys.outputs.ios_timing_cache_key }}
avd_cache_key: ${{ steps.cache-keys.outputs.avd_cache_key }}
avd_exists: ${{ steps.check-avd.outputs.cache-hit }}
steps:
- name: generate token
id: generate-token
uses: tibdex/github-app-token@v1
with:
app_id: ${{ secrets.GH_BOT_APP_ID }}
private_key: ${{ secrets.GH_BOT_PRIVATE_KEY }}
- uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.sha }}
repository: LedgerHQ/ledger-live
persist-credentials: false
sparse-checkout: |
apps/ledger-live-mobile
e2e/mobile
token: ${{ steps.generate-token.outputs.token }}
- name: Write summary
run: |
FILTER_PATTERN="${{ inputs.test_filter || '' }}"
DEVICE="${{ inputs.speculos_device || 'nanoX' }}"
BUILD_TYPE="${{ inputs.production_firebase && 'production' || 'testing' }}"
BROADCAST_ENABLED="${{ inputs.enable_broadcast }}"
TEST_EXECUTION_ANDROID="${{ inputs.test_execution_android || '(not provided)' }}"
TEST_EXECUTION_IOS="${{ inputs.test_execution_ios || '(not provided)' }}"
if [ -z "$FILTER_PATTERN" ]; then
FILTER_PATTERN="(none)"
fi
{
echo "## Workflow Context"
echo ""
echo "- **Workflow source branch:** ${{ github.ref_name }}"
echo "- **Triggered branch:** ${{ inputs.ref || github.ref_name }}"
echo "- **Commit SHA:** ${{ github.sha }}"
echo "- **Device selected:** $DEVICE"
echo "- **Filtered pattern:** $FILTER_PATTERN"
echo "- **Test Execution ticket ID (Android):** $TEST_EXECUTION_ANDROID"
echo "- **Test Execution ticket ID (iOS):** $TEST_EXECUTION_IOS"
echo "- **Firebase env to target:** $BUILD_TYPE"
echo "- **Broadcast enabled:** $BROADCAST_ENABLED"
} >> $GITHUB_STEP_SUMMARY
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
id: aws
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID_PROD }}:role/${{ secrets.AWS_CACHE_ROLE_NAME }}
aws-region: ${{ secrets.AWS_CACHE_REGION }}
- name: Determine cache keys
id: cache-keys
run: |
echo "ios_native_key=longterm-${{ hashFiles('apps/ledger-live-mobile/ios') }}-detox-native-ios-${{ inputs.production_firebase == true && 'prod-2' || '3' }}" >> $GITHUB_OUTPUT
echo "android_native_key=longterm-${{ hashFiles('apps/ledger-live-mobile/android') }}-detox-native-android-${{ inputs.production_firebase == true && 'prod-2' || '3' }}" >> $GITHUB_OUTPUT
echo "ios_js_key=${{ inputs.ref || github.sha }}-detox-js-ios" >> $GITHUB_OUTPUT
echo "android_js_key=${{ inputs.ref || github.sha }}-detox-js-android" >> $GITHUB_OUTPUT
echo "android_timing_cache_key=android-e2e-timing-${{ hashFiles('e2e/mobile/specs') }}-2" >> $GITHUB_OUTPUT
echo "ios_timing_cache_key=ios-e2e-timing-${{ hashFiles('e2e/mobile/specs') }}-2" >> $GITHUB_OUTPUT
echo "avd_cache_key=${{ runner.os }}-detox-avd-${{ env.AVD_NAME }}_4-${{ env.AVD_PROFILE }}-${{ env.AVD_TARGET }}-${{ env.AVD_API }}-${{ env.AVD_ARCH }}-${{ env.AVD_CORES }}-${{ env.AVD_RAM_SIZE }}-${{ env.AVD_HEAP_SIZE }}-r2-v8" >> $GITHUB_OUTPUT
- name: Generate shards matrix and test files
id: generate-shards
uses: LedgerHQ/ledger-live/tools/actions/composites/generate-shards-matrix@develop
with:
test_directory: e2e/mobile
test_filter: ${{ inputs.test_filter || '' }}
event_name: ${{ github.event_name }}
ref: ${{ inputs.ref || github.ref_name }}
ios_timing_cache_key: ${{ steps.cache-keys.outputs.ios_timing_cache_key }}
android_timing_cache_key: ${{ steps.cache-keys.outputs.android_timing_cache_key }}
aws_access_key_id: ${{ env.AWS_ACCESS_KEY_ID }}
aws_secret_access_key: ${{ env.AWS_SECRET_ACCESS_KEY }}
aws_session_token: ${{ env.AWS_SESSION_TOKEN }}
cache_bucket: ${{ env.cache-bucket }}
aws_region: ${{ secrets.AWS_CACHE_REGION }}
- name: Check if iOS Native Build exists already
id: check-ios-native
uses: tespkg/actions-cache/restore@v1.9.0
with:
path: apps/ledger-live-mobile/ios/build/Build/Products/Release-iphonesimulator
key: ${{ steps.cache-keys.outputs.ios_native_key }}
accessKey: ${{ env.AWS_ACCESS_KEY_ID }}
secretKey: ${{ env.AWS_SECRET_ACCESS_KEY }}
sessionToken: ${{ env.AWS_SESSION_TOKEN}}
bucket: ${{ env.cache-bucket }}
region: ${{ secrets.AWS_CACHE_REGION }}
use-fallback: false
lookup-only: true
- name: Check if Android Native Build exists already
id: check-android-native
uses: tespkg/actions-cache/restore@v1.9.0
with:
path: apps/ledger-live-mobile/android/app/build/outputs/apk/detox/app-x86_64-detox.apk
key: ${{ steps.cache-keys.outputs.android_native_key }}
accessKey: ${{ env.AWS_ACCESS_KEY_ID }}
secretKey: ${{ env.AWS_SECRET_ACCESS_KEY }}
sessionToken: ${{ env.AWS_SESSION_TOKEN}}
bucket: ${{ env.cache-bucket }}
region: ${{ secrets.AWS_CACHE_REGION }}
use-fallback: false
lookup-only: true
- name: Check if iOS JS Build exists already
id: check-ios-js
uses: tespkg/actions-cache/restore@v1.9.0
with:
path: apps/ledger-live-mobile/main.jsbundle
key: ${{ steps.cache-keys.outputs.ios_js_key }}
accessKey: ${{ env.AWS_ACCESS_KEY_ID }}
secretKey: ${{ env.AWS_SECRET_ACCESS_KEY }}
sessionToken: ${{ env.AWS_SESSION_TOKEN}}
bucket: ${{ env.cache-bucket }}
region: ${{ secrets.AWS_CACHE_REGION }}
use-fallback: false
lookup-only: true
- name: Check if Android JS Build exists already
id: check-android-js
uses: tespkg/actions-cache/restore@v1.9.0
with:
path: apps/ledger-live-mobile/main.jsbundle
key: ${{ steps.cache-keys.outputs.android_js_key }}
accessKey: ${{ env.AWS_ACCESS_KEY_ID }}
secretKey: ${{ env.AWS_SECRET_ACCESS_KEY }}
sessionToken: ${{ env.AWS_SESSION_TOKEN}}
bucket: ${{ env.cache-bucket }}
region: ${{ secrets.AWS_CACHE_REGION }}
use-fallback: false
lookup-only: true
- name: Check if Android AVD cache exists
id: check-avd
if: ${{ inputs.tests_type != 'iOS Only' }}
uses: LedgerHQ/ledger-live/tools/actions/composites/cache/exists@develop
with:
key: ${{ steps.cache-keys.outputs.avd_cache_key }}
accessKey: ${{ secrets.R2_ACCESS_KEY_ID }}
secretKey: ${{ secrets.R2_SECRET_ACCESS_KEY }}
bucket: ledger-live-cache
endpoint: ${{ secrets.R2_ENDPOINT }}
region: auto
build-ios:
name: "iOS Build"
needs: [determine-builds]
if: ${{ inputs.tests_type != 'Android Only' && needs.determine-builds.outputs.test_files_for_sharding != '' }}
uses: LedgerHQ/ledger-live/.github/workflows/test-mobile-build-ios-reusable.yml@develop
with:
ref: ${{ inputs.ref || github.sha }}
macos-specificity-runner-label: "general-pool"
disable-turbo-cache: false
build-ios-js: ${{ needs.determine-builds.outputs.ios_js_exists == 'false' }}
build-ios-native: ${{ needs.determine-builds.outputs.ios_native_exists == 'false' }}
ios-native-cache-key: ${{ needs.determine-builds.outputs.ios_native_key }}
ios-js-cache-key: ${{ needs.determine-builds.outputs.ios_js_key }}
production_firebase: ${{ inputs.production_firebase || false }}
secrets: inherit
# build-android:
# name: "Android Build"
# needs: [determine-builds]
# if: ${{ inputs.tests_type != 'iOS Only' && needs.determine-builds.outputs.test_files_for_sharding != '' }}
# uses: LedgerHQ/ledger-live/.github/workflows/test-mobile-build-android-reusable.yml@develop
# with:
# ref: ${{ inputs.ref || github.sha }}
# disable-turbo-cache: false
# build-android-js: ${{ needs.determine-builds.outputs.android_js_exists == 'false' }}
# build-android-native: ${{ needs.determine-builds.outputs.android_native_exists == 'false' }}
# android-native-cache-key: ${{ needs.determine-builds.outputs.android_native_key }}
# android-js-cache-key: ${{ needs.determine-builds.outputs.android_js_key }}
# production_firebase: ${{ inputs.production_firebase || false }}
# secrets: inherit
# setup-android-avd:
# name: "Setup Android AVD"
# needs: [determine-builds]
# if: ${{ inputs.tests_type != 'iOS Only' && needs.determine-builds.outputs.test_files_for_sharding != '' && needs.determine-builds.outputs.avd_exists != 'true' }}
# runs-on: [ledger-live-linux-e2e-8CPU-32RAM]
# steps:
# - name: Setup Android AVDs
# uses: LedgerHQ/ledger-live/tools/actions/composites/setup-android-avd@develop
# with:
# ref: ${{ inputs.ref || github.sha }}
# avd_api: ${{ env.AVD_API }}
# avd_arch: ${{ env.AVD_ARCH }}
# avd_profile: ${{ env.AVD_PROFILE }}
# avd_target: ${{ env.AVD_TARGET }}
# avd_name: ${{ env.AVD_NAME }}
# avd_cores: ${{ env.AVD_CORES }}
# avd_ram_size: ${{ env.AVD_RAM_SIZE }}
# avd_heap_size: ${{ env.AVD_HEAP_SIZE }}
# avd_options: ${{ env.AVD_OPTIONS }}
# cache_key: ${{ needs.determine-builds.outputs.avd_cache_key }}
# r2_access_key: ${{ secrets.R2_ACCESS_KEY_ID }}
# r2_secret_key: ${{ secrets.R2_SECRET_ACCESS_KEY }}
# r2_endpoint: ${{ secrets.R2_ENDPOINT }}
detox-tests-ios:
name: iOS E2E Tests (${{ matrix.shard }}, ${{ matrix.total }})
needs: [build-ios, determine-builds]
if: ${{ inputs.tests_type != 'Android Only' && needs.determine-builds.outputs.test_files_for_sharding != '' }}
runs-on: [project-portugal]
env:
NODE_OPTIONS: "--max-old-space-size=8192"
LANG: en_US.UTF-8
LANGUAGE: en_US.UTF-8
LC_ALL: en_US.UTF-8
outputs:
status: ${{ steps.run-ios.outcome }}
artifact: ${{ steps.test-artifacts.outputs.artifact-id }}
status_1: ${{ steps.set-output.outputs.status_1 }}
status_2: ${{ steps.set-output.outputs.status_2 }}
status_3: ${{ steps.set-output.outputs.status_3 }}
status_4: ${{ steps.set-output.outputs.status_4 }}
status_5: ${{ steps.set-output.outputs.status_5 }}
status_6: ${{ steps.set-output.outputs.status_6 }}
status_7: ${{ steps.set-output.outputs.status_7 }}
status_8: ${{ steps.set-output.outputs.status_8 }}
status_9: ${{ steps.set-output.outputs.status_9 }}
status_10: ${{ steps.set-output.outputs.status_10 }}
status_11: ${{ steps.set-output.outputs.status_11 }}
status_12: ${{ steps.set-output.outputs.status_12 }}
strategy:
fail-fast: false
matrix:
include: ${{ fromJSON(needs.determine-builds.outputs.matrix_ios) }}
steps:
- uses: actions/checkout@v4
with:
ref: ${{ inputs.ref || github.sha }}
repository: LedgerHQ/ledger-live
persist-credentials: false
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
id: aws
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID_PROD }}:role/${{ secrets.AWS_CACHE_ROLE_NAME }}
aws-region: ${{ secrets.AWS_CACHE_REGION }}
- name: Set shard test files from pre-computed matrix
run: |
echo "SHARD_TEST_FILES<<EOF" >> $GITHUB_ENV
echo "${{ matrix.files }}" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV
echo "Using pre-computed shard ${{ matrix.shard }}/${{ matrix.total }} with $(echo '${{ matrix.files }}' | wc -w) test files"
- name: Boot iOS Simulator in Background
run: |
LOG_FILE="e2e/mobile/artifacts/simulator-boot.log"
mkdir -p e2e/mobile/artifacts
nohup bash -c '
echo "🛫 Booting simulator..."
xcrun simctl boot "iOS Simulator" || true
xcrun simctl bootstatus "iOS Simulator"
' > "$LOG_FILE" 2>&1 &
echo "ℹ️ Simulator boot started in background."
shell: bash
- name: setup caches
id: setup-caches
uses: LedgerHQ/ledger-live/tools/actions/composites/setup-caches@develop
with:
skip-pod-cache: "false"
skip-turbo-cache: "false"
skip-pnpm-cache: "true"
accountId: ${{ secrets.AWS_ACCOUNT_ID_PROD }}
roleName: ${{ secrets.AWS_CACHE_ROLE_NAME }}
region: ${{ secrets.AWS_CACHE_REGION }}
turbo-server-token: ${{ secrets.TURBOREPO_SERVER_TOKEN }}
- uses: nick-fields/retry@v3
name: install dependencies
id: install-dependencies
with:
max_attempts: 2
timeout_minutes: 15
command: pnpm i --filter="live-mobile..." --filter="ledger-live" --filter="ledger-live-mobile-e2e-tests" --filter="@ledgerhq/dummy-*-app..." --filter="live-cli*..." --no-frozen-lockfile --unsafe-perm --ignore-scripts
new_command_on_retry: rm -rf ~/.cocoapods/ && pnpm clean && pnpm i --filter="live-mobile..." --filter="ledger-live" --filter="ledger-live-mobile-e2e-tests" --filter="@ledgerhq/dummy-*-app..." --filter="live-cli*..." --no-frozen-lockfile --unsafe-perm
- name: Detox Post Install
run: node apps/ledger-live-mobile/node_modules/detox/scripts/postinstall.js
- name: Download Native Build
uses: LedgerHQ/ledger-live/tools/actions/composites/cache/download@develop
with:
endpoint: ${{ secrets.S3_DIRECTCONNECT_ENDPOINT }}
key: ${{ needs.determine-builds.outputs.ios_native_key }}
accessKey: ${{ env.AWS_ACCESS_KEY_ID }}
secretKey: ${{ env.AWS_SECRET_ACCESS_KEY }}
sessionToken: ${{ env.AWS_SESSION_TOKEN}}
bucket: ${{ env.cache-bucket }}
region: ${{ secrets.AWS_CACHE_REGION }}
- name: Download JS Build
uses: LedgerHQ/ledger-live/tools/actions/composites/cache/download@develop
with:
endpoint: ${{ secrets.S3_DIRECTCONNECT_ENDPOINT }}
key: ${{ needs.determine-builds.outputs.ios_js_key }}
accessKey: ${{ env.AWS_ACCESS_KEY_ID }}
secretKey: ${{ env.AWS_SECRET_ACCESS_KEY }}
sessionToken: ${{ env.AWS_SESSION_TOKEN}}
bucket: ${{ env.cache-bucket }}
region: ${{ secrets.AWS_CACHE_REGION }}
- name: Copy JS build
run: |
cp apps/ledger-live-mobile/main.jsbundle ${{ env.IOS_JSBUNDLE_PATH }}
cp apps/ledger-live-mobile/main.jsbundle ${{ env.IOS_NATIVE_PATH }}/main.jsbundle
- name: Build dependencies
uses: LedgerHQ/ledger-live/tools/actions/composites/turbo-step@develop
with:
command: pnpm build:llm:deps
turbo_server_token: ${{ secrets.TURBOREPO_SERVER_TOKEN }}
turbo_port: ${{ steps.setup-caches.outputs.port }}
disable_cache: false
- name: Build CLI
uses: LedgerHQ/ledger-live/tools/actions/composites/turbo-step@develop
with:
command: pnpm build:cli
turbo_server_token: ${{ secrets.TURBOREPO_SERVER_TOKEN }}
turbo_port: ${{ steps.setup-caches.outputs.port }}
disable_cache: false
- name: Setup Speculos image and Coin Apps
id: setup-speculos
uses: LedgerHQ/ledger-live/tools/actions/composites/setup-speculos_image@develop
with:
coinapps_path: ${{ env.COINAPPS }}
bot_id: ${{ secrets.GH_BOT_APP_ID }}
bot_key: ${{ secrets.GH_BOT_PRIVATE_KEY }}
- name: Set DISABLE_TRANSACTION_BROADCAST
uses: LedgerHQ/ledger-live/tools/actions/composites/setup-e2e-env@develop
with:
enable_broadcast: ${{ inputs.enable_broadcast }}
build_type: ${{ inputs.production_firebase == 'true' && 'js' || 'testing' }}
- name: Run iOS Detox shard ${{ matrix.shard }}/${{ matrix.total }}
id: run-ios
timeout-minutes: ${{ fromJSON(needs.determine-builds.outputs.ios_timeout) }}
run: |
pnpm mobile e2e:ci -p ios -t \
--e2e \
$([[ "$PRODUCTION" == "true" ]] && printf %s '--production') \
$SHARD_TEST_FILES \
--outputFile=artifacts/e2e-test-results-ios-shard-${{ matrix.shard }}.json
env:
SEED: ${{ secrets.SEED_QAA_B2C }}
GITHUB_TOKEN: ${{ secrets.LL_SPECULOS_CI }}
INPUT_E2E: "true"
REMOTE_SPECULOS: "true"
PRODUCTION: ${{ inputs.production_firebase }}
INPUTS_TEST_FILTER: ${{ inputs.test_filter }}
SWAP_API_BASE: ${{ env.SWAP_API_BASE }}
SHARD_INDEX: ${{ matrix.shard }}
- name: Upload iOS artifacts
if: (!cancelled() || steps.run-ios.outcome == 'cancelled')
uses: actions/upload-artifact@v4
id: "test-artifacts"
with:
name: ios-test-artifacts-${{ matrix.shard }}
path: e2e/mobile/artifacts
- name: Setup iOS Shard timing artifacts
if: (!cancelled() || steps.run-ios.outcome == 'cancelled')
uses: actions/upload-artifact@v4
with:
path: e2e/mobile/artifacts/e2e-test-results-ios-shard-${{ matrix.shard }}.json
name: "${{ needs.determine-builds.outputs.ios_timing_cache_key }}-${{ matrix.shard }}"
- name: Set job output based on detox result
id: set-output
if: ${{ !cancelled() }}
run: |
echo "status_${{ matrix.shard }}=${{ steps.run-ios.outcome }}" >> $GITHUB_OUTPUT
# detox-tests-android:
# name: Android E2E Tests (${{ matrix.shard }}, ${{ matrix.total }})
# needs: [build-android, determine-builds]
# if: ${{ inputs.tests_type != 'iOS Only' && needs.determine-builds.outputs.test_files_for_sharding != '' }}
# runs-on: [ledger-live-linux-e2e-8CPU-32RAM]
# env:
# NODE_OPTIONS: "--max-old-space-size=7168"
# LANG: en_US.UTF-8
# LANGUAGE: en_US.UTF-8
# LC_ALL: en_US.UTF-8
# outputs:
# status: ${{ steps.run-android.outcome }}
# artifact: ${{ steps.test-artifacts.outputs.artifact-id }}
# status_1: ${{ steps.set-output.outputs.status_1 }}
# status_2: ${{ steps.set-output.outputs.status_2 }}
# status_3: ${{ steps.set-output.outputs.status_3 }}
# status_4: ${{ steps.set-output.outputs.status_4 }}
# status_5: ${{ steps.set-output.outputs.status_5 }}
# status_6: ${{ steps.set-output.outputs.status_6 }}
# status_7: ${{ steps.set-output.outputs.status_7 }}
# status_8: ${{ steps.set-output.outputs.status_8 }}
# status_9: ${{ steps.set-output.outputs.status_9 }}
# status_10: ${{ steps.set-output.outputs.status_10 }}
# status_11: ${{ steps.set-output.outputs.status_11 }}
# status_12: ${{ steps.set-output.outputs.status_12 }}
# strategy:
# fail-fast: false
# matrix:
# include: ${{ fromJSON(needs.determine-builds.outputs.matrix_android) }}
# steps:
# - uses: actions/checkout@v4
# with:
# ref: ${{ inputs.ref || github.sha }}
# repository: LedgerHQ/ledger-live
# persist-credentials: false
#
# - name: Configure AWS credentials
# uses: aws-actions/configure-aws-credentials@v4
# id: aws
# with:
# role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID_PROD }}:role/${{ secrets.AWS_CACHE_ROLE_NAME }}
# aws-region: ${{ secrets.AWS_CACHE_REGION }}
#
# - name: Set shard test files from pre-computed matrix
# run: |
# echo "SHARD_TEST_FILES<<EOF" >> $GITHUB_ENV
# echo "${{ matrix.files }}" >> $GITHUB_ENV
# echo "EOF" >> $GITHUB_ENV
# echo "Using pre-computed shard ${{ matrix.shard }}/${{ matrix.total }} with $(echo '${{ matrix.files }}' | wc -w) test files"
#
# - name: Setup Android Environment
# uses: LedgerHQ/ledger-live/tools/actions/composites/setup-android-env@develop
#
# - name: Download Native Build
# uses: LedgerHQ/ledger-live/tools/actions/composites/cache/download@develop
# with:
# key: ${{ needs.determine-builds.outputs.android_native_key }}
# accessKey: ${{ env.AWS_ACCESS_KEY_ID }}
# secretKey: ${{ env.AWS_SECRET_ACCESS_KEY }}
# sessionToken: ${{ env.AWS_SESSION_TOKEN}}
# bucket: ${{ env.cache-bucket }}
# region: ${{ secrets.AWS_CACHE_REGION }}
#
# - name: Download JS Bundle
# uses: LedgerHQ/ledger-live/tools/actions/composites/cache/download@develop
# with:
# key: ${{ needs.determine-builds.outputs.android_js_key }}
# accessKey: ${{ env.AWS_ACCESS_KEY_ID }}
# secretKey: ${{ env.AWS_SECRET_ACCESS_KEY }}
# sessionToken: ${{ env.AWS_SESSION_TOKEN}}
# bucket: ${{ env.cache-bucket }}
# region: ${{ secrets.AWS_CACHE_REGION }}
#
# - name: Prepare APK
# run: |
# mkdir -p /tmp/apk/assets
# mkdir /home/runner/.android/
# mv ${{ env.ANDROID_JSBUNDLE_PATH }} /tmp/apk/assets/index.android.bundle
# mv ${{ env.ANDROID_APK_PATH }} /tmp/apk/tmp.apk
# (cd /tmp/apk/; zip -r tmp.apk assets/index.android.bundle)
# /usr/local/lib/android/sdk/build-tools/34.0.0/zipalign -p 4 /tmp/apk/tmp.apk ${{ env.ANDROID_APK_PATH }}
# /usr/local/lib/android/sdk/build-tools/34.0.0/apksigner sign --ks ${{ secrets.ANDROID_KEYSTORE_PATH }} --ks-pass ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} --ks-key-alias staging --key-pass ${{ secrets.ANDROID_KEYSTORE_PASSWORD }} ${{ env.ANDROID_APK_PATH }}
#
# - name: Setup the caches
# uses: LedgerHQ/ledger-live/tools/actions/composites/setup-caches@develop
# id: setup-caches
# with:
# install-proto: true
# skip-pnpm-cache: "true"
# skip-turbo-cache: "false"
# accountId: ${{ secrets.AWS_ACCOUNT_ID_PROD }}
# roleName: ${{ secrets.AWS_CACHE_ROLE_NAME }}
# region: ${{ secrets.AWS_CACHE_REGION }}
# turbo-server-token: ${{ secrets.TURBOREPO_SERVER_TOKEN }}
#
# - name: Install dependencies
# run: |
# pnpm i --filter="live-mobile..." --filter="ledger-live" --filter="ledger-live-mobile-e2e-tests" --filter="live-cli*..." --filter="@ledgerhq/dummy-*-app..." --no-frozen-lockfile --unsafe-perm --ignore-scripts
#
# - name: Detox Post Install
# run: node apps/ledger-live-mobile/node_modules/detox/scripts/postinstall.js
#
# - name: Build dependencies
# uses: LedgerHQ/ledger-live/tools/actions/composites/turbo-step@develop
# with:
# command: pnpm build:llm:deps
# turbo_server_token: ${{ secrets.TURBOREPO_SERVER_TOKEN }}
# turbo_port: ${{ steps.setup-caches.outputs.port }}
# disable_cache: false
#
# - name: Download android emulator
# timeout-minutes: 10
# uses: LedgerHQ/ledger-live/tools/actions/composites/cache/download@develop
# id: detox-avd
# with:
# key: ${{ needs.determine-builds.outputs.avd_cache_key }}
# accessKey: "${{ secrets.R2_ACCESS_KEY_ID }}"
# secretKey: "${{ secrets.R2_SECRET_ACCESS_KEY }}"
# bucket: ledger-live-cache
# endpoint: ${{ secrets.R2_ENDPOINT }}
# region: auto
# destination: /
#
# - name: Duplicate AVDs for parallel testing
# uses: LedgerHQ/ledger-live/tools/actions/composites/duplicate-avd@develop
# with:
# source_avd_name: ${{ env.AVD_NAME }}
# target_suffixes: "_2,_3"
# avd_api: ${{ env.AVD_API }}
#
# - name: Boot Android Emulators in Background
# run: |
# LOG_FILE="e2e/mobile/artifacts/emulator-boot.log"
# mkdir -p e2e/mobile/artifacts
# nohup bash -c '
# log() { echo "[$(date +%H:%M:%S)] $1"; }
# ts() { while IFS= read -r line; do echo "[$(date +%H:%M:%S)] [$1] $line"; done; }
#
# log "🛫 Starting emulators..."
# $ANDROID_HOME/emulator/emulator -avd ${{ env.AVD_NAME }} ${{ env.AVD_OPTIONS }} 2>&1 | ts "EMU1" &
# $ANDROID_HOME/emulator/emulator -avd ${{ env.AVD_NAME }}_2 ${{ env.AVD_OPTIONS }} 2>&1 | ts "EMU2" &
# $ANDROID_HOME/emulator/emulator -avd ${{ env.AVD_NAME }}_3 ${{ env.AVD_OPTIONS }} 2>&1 | ts "EMU3" &
#
# log "⏳ Waiting for 3 emulators to connect..."
# while [ "$(adb devices | grep -c emulator)" -lt 3 ]; do sleep 2; done
# log "✅ 3 emulators connected"
# log "⏳ Waiting for all emulators to finish booting..."
# adb -s emulator-5554 wait-for-device shell "while [ \"\$(getprop sys.boot_completed)\" != 1 ]; do sleep 1; done"
# log "✅ emulator-5554 booted"
# adb -s emulator-5556 wait-for-device shell "while [ \"\$(getprop sys.boot_completed)\" != 1 ]; do sleep 1; done"
# log "✅ emulator-5556 booted"
# adb -s emulator-5558 wait-for-device shell "while [ \"\$(getprop sys.boot_completed)\" != 1 ]; do sleep 1; done"
# log "✅ emulator-5558 booted"
#
# log "✅ All 3 emulators are fully booted"
# ' > "$LOG_FILE" 2>&1 &
# echo "ℹ️ Android emulators boot started in background."
# shell: bash
#
# - name: Setup Speculos image and Coin Apps
# id: setup-speculos
# uses: LedgerHQ/ledger-live/tools/actions/composites/setup-speculos_image@develop
# with:
# coinapps_path: ${{ env.COINAPPS }}
# bot_id: ${{ secrets.GH_BOT_APP_ID }}
# bot_key: ${{ secrets.GH_BOT_PRIVATE_KEY }}
#
# - name: Build CLI
# uses: LedgerHQ/ledger-live/tools/actions/composites/turbo-step@develop
# with:
# command: pnpm build:cli
# turbo_server_token: ${{ secrets.TURBOREPO_SERVER_TOKEN }}
# turbo_port: ${{ steps.setup-caches.outputs.port }}
# disable_cache: false
#
# - name: Set DISABLE_TRANSACTION_BROADCAST
# uses: LedgerHQ/ledger-live/tools/actions/composites/setup-e2e-env@develop
# with:
# enable_broadcast: ${{ inputs.enable_broadcast }}
# build_type: ${{ inputs.production_firebase == 'true' && 'js' || 'testing' }}
#
# - name: Run Android Detox shard ${{ matrix.shard }}/${{ matrix.total }}
# id: run-android
# timeout-minutes: ${{ fromJSON(needs.determine-builds.outputs.android_timeout) }}
# run: |
# pnpm mobile e2e:ci -p android -t \
# --e2e \
# $([[ "$PRODUCTION" == "true" ]] && printf %s '--production') \
# $SHARD_TEST_FILES \
# --outputFile=artifacts/e2e-test-results-android-shard-${{ matrix.shard }}.json
#
# env:
# DETOX_INSTALL_TIMEOUT: 120000
# SEED: ${{ secrets.SEED_QAA_B2C }}
# INPUT_E2E: "true"
# PRODUCTION: ${{ inputs.production_firebase }}
# INPUTS_TEST_FILTER: ${{ inputs.test_filter }}
# SWAP_API_BASE: ${{ env.SWAP_API_BASE }}
# SHARD_INDEX: ${{ matrix.shard }}
#
# - name: Upload Android artifacts
# if: (!cancelled() || steps.run-android.outcome == 'cancelled')
# uses: actions/upload-artifact@v4
# id: "test-artifacts"
# with:
# name: android-test-artifacts-${{ matrix.shard }}
# path: e2e/mobile/artifacts
#
# - name: Setup Android Shard timing artifacts
# if: (!cancelled() || steps.run-android.outcome == 'cancelled')
# uses: actions/upload-artifact@v4
# with:
# path: e2e/mobile/artifacts/e2e-test-results-android-shard-${{ matrix.shard }}.json
# name: "${{ needs.determine-builds.outputs.android_timing_cache_key }}-${{ matrix.shard }}"
#
# - name: Set job output based on detox result
# id: set-output
# if: ${{ !cancelled() }}
# run: |
# echo "status_${{ matrix.shard }}=${{ steps.run-android.outcome }}" >> $GITHUB_OUTPUT
allure-report-ios:
name: Allure Report iOS
runs-on: [ledger-live-medium]
if: ${{ !cancelled() && needs.detox-tests-ios.outputs.artifact && inputs.tests_type != 'Android Only' }}
needs: [determine-builds, detox-tests-ios]
outputs:
report-url: ${{ steps.upload.outputs.report-url }}
result: ${{ steps.summary.outputs.test_result }}
finalStatus: ${{ steps.aggregate.outputs.finalStatus }}
missingShards: ${{ steps.aggregate.outputs.missingShards }}
steps:
- name: Download Allure Report
uses: actions/download-artifact@v4
with:
path: ios-test-artifacts
pattern: ios-test-artifacts*
merge-multiple: true
- uses: LedgerHQ/ledger-live/tools/actions/composites/upload-allure-report@develop
if: ${{ !cancelled() }}
id: upload
with:
platform: ios-e2e
login: ${{ vars.ALLURE_USERNAME }}
password: ${{ secrets.ALLURE_LEDGER_LIVE_PASSWORD }}
path: ios-test-artifacts
report_path_suffix: ${{ github.event_name != 'schedule' && 'manual' || '' }}
- name: Get summary
id: summary
if: ${{ !cancelled() }}
uses: LedgerHQ/ledger-live/tools/actions/composites/get-allure-summary@develop
with:
allure-results-path: ios-test-artifacts
platform: iOS
- name: Aggregate test results
id: aggregate
uses: LedgerHQ/ledger-live/tools/actions/composites/aggregate-shard-results@develop
with:
total_shards: ${{ fromJSON(needs.determine-builds.outputs.matrix_ios)[0].total }}
status_1: ${{ needs.detox-tests-ios.outputs.status_1 }}
status_2: ${{ needs.detox-tests-ios.outputs.status_2 }}
status_3: ${{ needs.detox-tests-ios.outputs.status_3 }}
status_4: ${{ needs.detox-tests-ios.outputs.status_4 }}
status_5: ${{ needs.detox-tests-ios.outputs.status_5 }}
status_6: ${{ needs.detox-tests-ios.outputs.status_6 }}
status_7: ${{ needs.detox-tests-ios.outputs.status_7 }}
status_8: ${{ needs.detox-tests-ios.outputs.status_8 }}
status_9: ${{ needs.detox-tests-ios.outputs.status_9 }}
status_10: ${{ needs.detox-tests-ios.outputs.status_10 }}
status_11: ${{ needs.detox-tests-ios.outputs.status_11 }}
status_12: ${{ needs.detox-tests-ios.outputs.status_12 }}
# allure-report-android:
# name: Allure Report Android
# runs-on: [ledger-live-medium]
# if: ${{ !cancelled() && needs.detox-tests-android.outputs.artifact && inputs.tests_type != 'iOS Only' }}
# outputs:
# report-url: ${{ steps.upload.outputs.report-url }}
# result: ${{ steps.summary.outputs.test_result }}
# finalStatus: ${{ steps.aggregate.outputs.finalStatus }}
# missingShards: ${{ steps.aggregate.outputs.missingShards }}
# needs: [determine-builds, detox-tests-android]
# steps:
# - name: Download Allure Report
# uses: actions/download-artifact@v4
# with:
# path: android-test-artifacts
# pattern: android-test-artifacts*
# merge-multiple: true
# - uses: LedgerHQ/ledger-live/tools/actions/composites/upload-allure-report@develop
# id: upload
# if: ${{ !cancelled() }}
# with:
# platform: android-e2e
# login: ${{ vars.ALLURE_USERNAME }}
# password: ${{ secrets.ALLURE_LEDGER_LIVE_PASSWORD }}
# path: android-test-artifacts
# report_path_suffix: ${{ github.event_name == 'schedule' && '' || 'manual' }}
# - name: Get summary
# id: summary
# if: ${{ !cancelled() }}
# uses: LedgerHQ/ledger-live/tools/actions/composites/get-allure-summary@develop
# with:
# allure-results-path: android-test-artifacts
# platform: android
# - name: Aggregate test results
# id: aggregate
# uses: LedgerHQ/ledger-live/tools/actions/composites/aggregate-shard-results@develop
# with:
# total_shards: ${{ fromJSON(needs.determine-builds.outputs.matrix_android)[0].total }}
# status_1: ${{ needs.detox-tests-android.outputs.status_1 }}
# status_2: ${{ needs.detox-tests-android.outputs.status_2 }}
# status_3: ${{ needs.detox-tests-android.outputs.status_3 }}
# status_4: ${{ needs.detox-tests-android.outputs.status_4 }}
# status_5: ${{ needs.detox-tests-android.outputs.status_5 }}
# status_6: ${{ needs.detox-tests-android.outputs.status_6 }}
# status_7: ${{ needs.detox-tests-android.outputs.status_7 }}
# status_8: ${{ needs.detox-tests-android.outputs.status_8 }}
# status_9: ${{ needs.detox-tests-android.outputs.status_9 }}
# status_10: ${{ needs.detox-tests-android.outputs.status_10 }}
# status_11: ${{ needs.detox-tests-android.outputs.status_11 }}
# status_12: ${{ needs.detox-tests-android.outputs.status_12 }}
# upload-to-xray:
# name: "Test Mobile E2E > XRAY Report"
# runs-on: [ledger-live-medium]
# strategy:
# matrix:
# platform:
# - android
# - ios
# exclude:
# - platform: ${{ github.event.inputs.tests_type == 'Android Only' && 'ios' }}
#
# fail-fast: false
# env:
# XRAY_CLIENT_ID: ${{ secrets.XRAY_CLIENT_ID }}
# XRAY_CLIENT_SECRET: ${{ secrets.XRAY_CLIENT_SECRET }}
# XRAY_API_URL: https://xray.cloud.getxray.app/api/v2
# JIRA_URL: https://ledgerhq.atlassian.net/browse
# TEST_EXECUTION: ${{ matrix.platform == 'android' && inputs.test_execution_android || inputs.test_execution_ios }}
# needs: [detox-tests-android, detox-tests-ios]
# if: ${{ !cancelled() && inputs.export_to_xray }}
# steps:
# - uses: actions/checkout@v4
# with:
# ref: ${{ inputs.ref || github.sha }}
# repository: LedgerHQ/ledger-live
#
# - name: Download Allure Results
# uses: actions/download-artifact@v4
# with:
# path: "artifacts-${{ matrix.platform }}"
# pattern: ${{ matrix.platform }}-test-artifacts-*
# merge-multiple: true
#
# - name: Format Xray results
# run: e2e/mobile/xray.formater.sh artifacts-${{ matrix.platform }} ${{ matrix.platform }} ${{ env.TEST_EXECUTION}}
#
# - name: Upload aggregated xray results
# uses: actions/upload-artifact@v4
# with:
# retention-days: 1
# name: xray-reports-${{ matrix.platform }}
# path: "artifacts-${{ matrix.platform }}/xray_report.json"
#
# - name: Authenticate to Xray
# id: authenticate
# run: |
# response=$(curl -H "Content-Type: application/json" -X POST \
# --data '{"client_id": "${{ env.XRAY_CLIENT_ID }}", "client_secret": "${{ env.XRAY_CLIENT_SECRET }}"}' \
# ${{ env.XRAY_API_URL }}/authenticate)
# echo "Xray Authentication Response: $response"
# echo "xray_token=$response" >> $GITHUB_OUTPUT
# - name: Publish report on Xray
# id: publish-xray
# run: |
# response=$(curl -H "Content-Type: application/json" \
# -H "Authorization: Bearer ${{ steps.authenticate.outputs.xray_token }}" \
# -X POST \
# --data @artifacts-${{ matrix.platform }}/xray_report.json \
# ${{ env.XRAY_API_URL }}/import/execution)
# echo "Xray Report Response: $response"
# key=$(echo $response | jq -r '.key')
# echo "xray_key=$key" >> $GITHUB_OUTPUT
# - name: Write Xray report link in summary
# shell: bash
# run: echo "::notice title=${{ matrix.platform }} Xray report URL::${{ env.JIRA_URL }}/${{ steps.publish-xray.outputs.xray_key }}"
# report-on-slack:
# name: "Test Mobile E2E > Slack Report"
# runs-on: ubuntu-22.04
# needs: [allure-report-android, allure-report-ios]
# if: ${{ !cancelled() && (needs.allure-report-ios.outputs.report-url || needs.allure-report-android.outputs.report-url) }}
# env:
# IOS_STATUS: ${{ needs.allure-report-ios.outputs.finalStatus }}
# IOS_REPORT_URL: ${{ needs.allure-report-ios.outputs.report-url }}
# IOS_MISSING_SHARDS: ${{ needs.allure-report-ios.outputs.missingShards }}
# ANDROID_STATUS: ${{ needs.allure-report-android.outputs.finalStatus }}
# ANDROID_REPORT_URL: ${{ needs.allure-report-android.outputs.report-url }}
# ANDROID_MISSING_SHARDS: ${{ needs.allure-report-android.outputs.missingShards }}
# TESTS_TYPE: ${{ inputs.tests_type }}
# steps:
# - name: format message
# uses: actions/github-script@v7
# id: message
# with:
# script: |
# const fs = require("fs");
# const text = "Ledger Live Mobile E2E tests finished";
# const header = [
# {
# "type": "header",
# "text": {
# "type": "plain_text",
# "text": ":ledger-logo: Ledger Live Mobile E2E tests results on ${{ inputs.ref || github.ref_name }} - ${{ inputs.speculos_device || 'nanoX' }}",
# "emoji": true
# }
# },
# {
# "type": "divider"
# }
# ];
#
# const iOSResult = [
# {
# "type": "section",
# "text": {
# "type": "mrkdwn",
# "text": `- 🍏 iOS - ${{ inputs.speculos_device }}: ${process.env.IOS_STATUS !== 'success' ? '❌' : '✅'} ${{ needs.allure-report-ios.outputs.result || 'No test results' }}`
# }
# }
# ];
#
# const androidResult = [
# {
# "type": "section",
# "text": {
# "type": "mrkdwn",
# "text": `- 🤖 Android - ${{ inputs.speculos_device }}: ${process.env.ANDROID_STATUS !== 'success' ? '❌' : '✅'} ${{ needs.allure-report-android.outputs.result || 'No test results' }}`
# }
# }
# ];
#
# const iOSInfo = [
# {
# "type": "mrkdwn",
# "text": process.env.IOS_REPORT_URL ? `*Allure Report iOS*\n<${process.env.IOS_REPORT_URL}|Allure Report iOS>` : '*Allure Report iOS*\nNo Allure Report'
# }
# ];
#
# const androidInfo = [
# {
# "type": "mrkdwn",
# "text": process.env.ANDROID_REPORT_URL ? `*Allure Report Android*\n<${process.env.ANDROID_REPORT_URL}|Allure Report Android>` : '*Allure Report Android*\nNo Allure Report'
# }
# ];
#
# const infoFields = []
# .concat(${{ env.TESTS_TYPE == 'Android Only' }} ? [] : iOSInfo)
# .concat(${{ env.TESTS_TYPE == 'iOS Only' }} ? [] : androidInfo)
# .concat([
# {
# "type": "mrkdwn",
# "text": `*Workflow*\n<${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|Workflow run>`
# }
# ]);
#
# const infoBlock = [
# {
# "type": "divider"
# },
# {
# "type": "section",
# "fields": infoFields
# }
# ];
#
# // Warning block for failed shards
# const warningBlocks = [];
# if (process.env.IOS_MISSING_SHARDS) {
# warningBlocks.push({
# "type": "section",
# "text": {
# "type": "mrkdwn",
# "text": `⚠️ *Warning*: iOS - Missing results for shard(s): ${process.env.IOS_MISSING_SHARDS}.`
# }
# });
# }
# if (process.env.ANDROID_MISSING_SHARDS) {
# warningBlocks.push({
# "type": "section",
# "text": {
# "type": "mrkdwn",
# "text": `⚠️ *Warning*: Android - Missing results for shard(s): ${process.env.ANDROID_MISSING_SHARDS}.`
# }
# });
# }
#
# const blocks = []
# .concat(header)
# .concat(${{ env.TESTS_TYPE == 'Android Only' }} ? [] : iOSResult)
# .concat(${{ env.TESTS_TYPE == 'iOS Only' }} ? [] : androidResult)
# .concat(warningBlocks.length > 0 ? warningBlocks : [])
# .concat(infoBlock);
#
# const result = {
# attachments: [
# {
# color: process.env.ANDROID_STATUS !== 'success' || (process.env.IOS_STATUS !== 'success' && process.env.ANDROID_ONLY == 'false')
# ? "#FF333C"
# : "#33FF39",
# blocks,
# },
# ],
# };
#
# fs.writeFileSync(`./payload-slack-content.json`, JSON.stringify(result, null, 2));
# - name: post to a Slack channel
# id: slack
# uses: slackapi/slack-github-action@v1.23.0
# with:
# channel-id: "CTMQ0S5SB"
# payload-file-path: "./payload-slack-content.json"
# env:
# SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_USER_OAUTH_ACCESS_TOKEN }}
# - name: post to a Slack channel
# if: ${{ contains(fromJson('["release"]'), github.ref_name) || contains(fromJson('["release, develop"]'), inputs.ref) || github.event_name == 'schedule' }}
# uses: slackapi/slack-github-action@v1.23.0
# with:
# channel-id: "C05FKJ7DFAP"
# payload-file-path: "./payload-slack-content.json"
# env:
# SLACK_BOT_TOKEN: ${{ secrets.SLACK_BOT_USER_OAUTH_ACCESS_TOKEN }}
merge-ios-timings:
name: Merge iOS Timing Files
needs: [determine-builds, detox-tests-ios]
runs-on: ubuntu-24.04
if: ${{ !cancelled() && (needs.detox-tests-ios.result == 'success' || needs.detox-tests-ios.result == 'failure') }}
steps:
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
id: aws
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID_PROD }}:role/${{ secrets.AWS_CACHE_ROLE_NAME }}
aws-region: ${{ secrets.AWS_CACHE_REGION }}
- uses: LedgerHQ/ledger-live/tools/actions/composites/merge-e2e-detox-timings@develop
with:
platform: ios
artifacts_dir: e2e/mobile/artifacts
key: ${{ needs.determine-builds.outputs.ios_timing_cache_key }}
aws_access_key_id: ${{ env.AWS_ACCESS_KEY_ID }}
aws_secret_access_key: ${{ env.AWS_SECRET_ACCESS_KEY }}
aws_session_token: ${{ env.AWS_SESSION_TOKEN }}
aws_region: ${{ secrets.AWS_CACHE_REGION }}
cache_bucket: ${{ env.cache-bucket }}
github_ref: ${{ github.ref }}
github_run_id: ${{ github.run_id }}
roleName: ${{ secrets.AWS_CACHE_ROLE_NAME }}
accountId: ${{ secrets.AWS_ACCOUNT_ID_PROD }}
# merge-android-timings:
# name: Merge Android Timing Files
# needs: [determine-builds, detox-tests-android]
# runs-on: ubuntu-24.04
# if: ${{ !cancelled() && (needs.detox-tests-android.result == 'success' || needs.detox-tests-android.result == 'failure') }}
# steps:
# - name: Configure AWS credentials
# uses: aws-actions/configure-aws-credentials@v4
# id: aws
# with:
# role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID_PROD }}:role/${{ secrets.AWS_CACHE_ROLE_NAME }}
# aws-region: ${{ secrets.AWS_CACHE_REGION }}
# - uses: LedgerHQ/ledger-live/tools/actions/composites/merge-e2e-detox-timings@develop
# with:
# platform: android
# artifacts_dir: e2e/mobile/artifacts
# key: ${{ needs.determine-builds.outputs.android_timing_cache_key }}
# aws_access_key_id: ${{ env.AWS_ACCESS_KEY_ID }}
# aws_secret_access_key: ${{ env.AWS_SECRET_ACCESS_KEY }}
# aws_session_token: ${{ env.AWS_SESSION_TOKEN }}
# aws_region: ${{ secrets.AWS_CACHE_REGION }}
# cache_bucket: ${{ env.cache-bucket }}
# github_ref: ${{ github.ref }}
# github_run_id: ${{ github.run_id }}
# roleName: ${{ secrets.AWS_CACHE_ROLE_NAME }}
# accountId: ${{ secrets.AWS_ACCOUNT_ID_PROD }}