Files
trezor-suite/.github/workflows/test-suite-native-e2e-android.yml
Matej Kriz baa56b265e chore(suite-native): default feature flag values on develop same as on production
- To reduce the risk of errors and simplify testing, the default values of feature flags are the same as in production. Default values can be changed locally for development using environment variables.
2025-03-20 16:41:14 +01:00

276 lines
10 KiB
YAML

name: "[Test] suite-native Android E2E"
permissions:
id-token: write # for fetching the OIDC token (needed for aws s3 actions)
on:
schedule:
- cron: "0 0 * * *"
pull_request:
paths:
- "suite-native/**"
- "suite-common/**"
- "packages/connect/**"
- ".github/workflows/test-suite-native-e2e-android.yml"
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
env:
NODE_ENV: "test"
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
RN_SRC_EXT: "e2e.tsx"
jobs:
prepare_android_test_app:
if: github.repository == 'trezor/trezor-suite'
runs-on: ubuntu-latest
steps:
- name: Checkout project
uses: actions/checkout@v4
with:
submodules: "true"
- name: Free Disk Space
uses: jlumbroso/free-disk-space@main
with:
# The free GH runner has limited disk space, so we need to uninstall some preinstalled tools.
dotnet: true
haskell: true
tool-cache: false
android: false
swap-storage: false
large-packages: false
- name: Install node and yarn
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
cache: yarn
- name: Setup node_modules cache
uses: actions/cache@v4
with:
path: node_modules
key: node_modules/${{ github.ref }}/${{github.run_id}}
- name: Install Yarn dependencies
run: |
echo -e "\nenableScripts: false" >> .yarnrc.yml
echo -e "\nenableHardenedMode: false" >> .yarnrc.yml
yarn install
- name: Setup Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: 17
- name: Prebuild native expo project
working-directory: ./suite-native/app
run: yarn prebuild --platform android --clean
- name: Sign message system config
working-directory: ./suite-common/message-system
run: yarn sign-config
- name: get Expo app fingerprint
id: expo-fingerprint
working-directory: ./suite-native/app
run: npx @expo/fingerprint ./ > expo-fingerprint.json && node -e "console.log('HASH=' + require('./expo-fingerprint.json').hash)" >> $GITHUB_OUTPUT
- name: Configure aws credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::538326561891:role/gh_actions_trezor_suite_dev_deploy
aws-region: eu-central-1
- name: Check if native build exists in AWS bucket
id: s3_build_cache
run: |
if aws s3 ls s3://dev.suite.sldev.cz/suite-mobile/${{ steps.expo-fingerprint.outputs.HASH }} --summarize;
then
echo "hit=true" >> $GITHUB_OUTPUT;
else
echo "hit=false" >> $GITHUB_OUTPUT;
fi
################ CACHE HIT - REPLACE JS BUNDLE ONLY ##############
- name: Setup Android SDK
if: steps.s3_build_cache.outputs.hit == 'true'
uses: android-actions/setup-android@v3
- name: Download Apktool
if: steps.s3_build_cache.outputs.hit == 'true'
run: |
wget https://github.com/iBotPeaches/Apktool/releases/download/v2.8.1/apktool_2.8.1.jar -O apktool.jar
wget https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/linux/apktool -O apktool
chmod +x apktool
sudo mv apktool.jar /usr/local/bin/apktool.jar
sudo mv apktool /usr/local/bin/apktool
- name: Download build from aws bucket
if: steps.s3_build_cache.outputs.hit == 'true'
working-directory: ./suite-native/app
run: aws s3 cp s3://dev.suite.sldev.cz/suite-mobile/${{ steps.expo-fingerprint.outputs.HASH }}/ ./android/app/build/outputs --recursive
- name: decompile .apk build
if: steps.s3_build_cache.outputs.hit == 'true'
working-directory: ./suite-native/app/android/app/build/outputs/apk/release
run: apktool d app-release.apk -o unpacked
- name: replace JS bundle
if: steps.s3_build_cache.outputs.hit == 'true'
working-directory: "./suite-native/app"
env:
JS_BUNDLE_PATH: ./android/app/build/outputs/apk/release/unpacked/assets/index.android.bundle
ASSETS_DEST_PATH: ./android/app/build/outputs/apk/release/unpacked/res/
ENTRY_FILE_PATH: ./suite-native/app/index.js
EXPO_PUBLIC_IS_DETOX_BUILD: true
EXPO_PUBLIC_FF_IS_REGTEST_ENABLED: true
EXPO_PUBLIC_ENVIRONMENT: debug
run: npx react-native bundle --platform android --dev false --entry-file $ENTRY_FILE_PATH --bundle-output $JS_BUNDLE_PATH --assets-dest $ASSETS_DEST_PATH
- name: fix native library bundling (extractNativeLibs=true)
if: steps.s3_build_cache.outputs.hit == 'true'
working-directory: "./suite-native/app/android/app/build/outputs/apk/release/unpacked"
run: sed -i 's/android:extractNativeLibs=\"false\"/android:extractNativeLibs=\"true\"/g' AndroidManifest.xml
- name: compile .apk back
if: steps.s3_build_cache.outputs.hit == 'true'
working-directory: ./suite-native/app/android/app/build/outputs/apk/release
run: apktool b unpacked -o app-release.apk
- name: sign re-bundled .apk
if: steps.s3_build_cache.outputs.hit == 'true'
working-directory: ./suite-native/app/android/app/build/outputs/apk/release
env:
KEYSTORE_PATH: ../../../../debug.keystore
KEYSTORE_PASSWORD: pass:android
run: $ANDROID_HOME/build-tools/35.0.0/apksigner sign --ks $KEYSTORE_PATH --ks-pass $KEYSTORE_PASSWORD --out app-release.apk app-release.apk
############# CACHE MISS - COMPILE A FRESH .APK FILE #############
- name: Build a new Detox test .apk
if: steps.s3_build_cache.outputs.hit == 'false'
working-directory: ./suite-native/app
run: ../../node_modules/.bin/detox build -PreactNativeArchitectures=x86_64 --configuration android.emu.release
- name: save .apk to the aws s3 bucket
if: steps.s3_build_cache.outputs.hit == 'false'
working-directory: ./suite-native/app/android/app/build/outputs
run: aws s3 cp . s3://dev.suite.sldev.cz/suite-mobile/${{ steps.expo-fingerprint.outputs.HASH }}/ --recursive
- name: Save build to cache
uses: actions/cache/save@v4
with:
path: |
suite-native/app/android/app/build/
key: android_test_build/${{ github.ref }}/${{github.run_id}}
###################################################################
run_android_e2e_tests:
if: github.repository == 'trezor/trezor-suite'
runs-on: ubuntu-latest
needs: prepare_android_test_app
steps:
- name: Checkout project
uses: actions/checkout@v4
with:
submodules: "true"
- name: Free Disk Space
uses: jlumbroso/free-disk-space@main
with:
# Combination of android emulator and trezor-user-env is using a too much disk space
# of a free tier GH action runner, some preinstalled packages have to be removed.
dotnet: true
haskell: true
tool-cache: false
android: false
swap-storage: false
large-packages: false
- name: Install node and yarn
uses: actions/setup-node@v4
with:
node-version-file: ".nvmrc"
cache: yarn
- name: Load node modules cache
uses: actions/cache@v4
with:
path: node_modules
key: node_modules/${{ github.ref }}/${{github.run_id}}
- name: Install Yarn dependencies
run: |
echo -e "\nenableScripts: false" >> .yarnrc.yml
echo -e "\nenableHardenedMode: false" >> .yarnrc.yml
yarn install
- name: Get device name from detox config file
id: device
run: node -e "console.log('AVD_NAME=' + require('./suite-native/app/.detoxrc').devices.emulator.device.avdName)" >> $GITHUB_OUTPUT
- name: Run trezor-user-env
env:
COMPOSE_FILE: ./docker/docker-compose.suite-native-ci.yml
run: |
docker compose pull trezor-user-env-unix trezor-user-env-regtest
docker compose up --detach trezor-user-env-unix trezor-user-env-regtest
- name: Read test .apk from cache
uses: actions/cache/restore@v4
with:
path: |
suite-native/app/android/app/build/
key: android_test_build/${{ github.ref }}/${{github.run_id}}
- name: Enable Android emulator KVM optimalization
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm
- name: Run Detox E2E Android tests
uses: reactivecircus/android-emulator-runner@v2
env:
RUNNER_TEMP: /tmp
with:
api-level: 31
profile: pixel_3a
arch: x86_64
working-directory: suite-native/app
ram-size: 4096M
force-avd-creation: true
avd-name: ${{ steps.device.outputs.AVD_NAME }}
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -grpc 8554
script: yarn test:e2e android.emu.release --headless --take-screenshots failing --record-videos failing
- name: Upload results to Currents.dev
if: ${{ ! cancelled() }}
env:
CURRENTS_PROJECT_ID: iUe1Y4
CURRENTS_RECORD_KEY: ${{ secrets.CURRENTS_RECORD_KEY }}
working-directory: ./suite-native/app
run: |
npx currents convert \
--input-format=junit \
--input-file=./reports/junit-report.xml \
--output-dir=./currents \
--framework=postman \
--framework-version=v11.2.0
npx currents upload --project-id=${CURRENTS_PROJECT_ID} --key=${CURRENTS_RECORD_KEY} --report-dir ./currents
- name: "Store failed test screenshot artifacts"
if: ${{failure()}}
uses: actions/upload-artifact@v4
with:
name: failed-android-tests
path: suite-native/app/artifacts