@Mobile • Test App End-2-End triggered by cng-ledger on ref feat/LIVE-7223 #7115
Workflow file for this run
This file contains 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: "@Mobile • Test App End-2-End" | |
run-name: "@Mobile • Test App End-2-End triggered by ${{ github.event_name == 'workflow_dispatch' && inputs.login || github.actor }} ${{ format('on ref {0}', github.ref_name) }}" | |
on: | |
push: | |
branches: | |
- main | |
- develop | |
- release | |
- hotfix | |
workflow_dispatch: | |
inputs: | |
ref: | |
description: the branch which triggered this workflow | |
required: false | |
login: | |
description: The GitHub username that triggered the workflow | |
required: true | |
base_ref: | |
description: The base branch to merge the head into when checking out the code | |
required: false | |
# Uncomment to have log-level: trace on detox run and build | |
# (cf: apps/ledger-live-mobile/detox.config.js) | |
# env: | |
# DEBUG_DETOX: true | |
concurrency: | |
group: ${{ github.workflow }}-${{ github.ref_name != 'develop' && github.ref || github.run_id }} | |
cancel-in-progress: true | |
jobs: | |
detox-tests-ios: | |
name: "Ledger Live Mobile - iOS Detox Tests" | |
runs-on: [m1, ARM64] | |
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.detox.outcome }} | |
steps: | |
- uses: LedgerHQ/ledger-live/tools/actions/composites/checkout-merge@develop | |
with: | |
ref: ${{ (github.event_name == 'workflow_dispatch' && (inputs.ref || github.ref_name)) || github.sha }} | |
base: ${{ inputs.base_ref }} | |
- name: Setup the toolchain | |
uses: ./tools/actions/composites/setup-toolchain | |
with: | |
pnpm_dest: ${{ runner.temp }}/setup-pnpm | |
- name: Install applesimutils | |
run: | | |
brew update | |
brew tap wix/brew | |
brew install applesimutils | |
- name: Cache LLM pods | |
uses: actions/cache@v3 | |
with: | |
path: | | |
apps/ledger-live-mobile/ios/Pods | |
~/Library/Caches/CocoaPods | |
~/.cocoapods | |
key: ${{ runner.os }}-pods-${{ hashFiles('apps/ledger-live-mobile/ios/Podfile.lock') }} | |
- name: TurboRepo local caching server | |
id: turborepo-cache-server | |
uses: ./tools/actions/turborepo-s3-cache | |
with: | |
server-token: "yolo" | |
cleanup-cache-folder: "true" | |
aws-access-key: ${{ secrets.ACCESS_KEY_BUCKET }} | |
aws-secret-key: ${{ secrets.SECRET_KEY_BUCKET }} | |
- name: install dependencies | |
run: | | |
pnpm i --filter="live-mobile..." --filter="ledger-live" --filter="dummy-*" --no-frozen-lockfile --unsafe-perm | |
- name: Build dependencies | |
run: | | |
pnpm build:llm:deps --api="http://127.0.0.1:${{ steps.turborepo-cache-server.outputs.port }}" --token="yolo" --team="foo" | |
- name: Build Dummy Live SDK and Dummy Wallet API apps for testing | |
run: | | |
pnpm test-utils dummy-apps:build | |
shell: bash | |
- name: Create iOS simulator | |
id: simulator | |
run: | | |
ID=$(xcrun simctl create "iPhone 13" "iPhone 13") | |
echo "id=$ID" >> $GITHUB_OUTPUT | |
- name: Build iOS app for Detox test run | |
run: | | |
pnpm mobile e2e:build -c ios.sim.release | |
- name: Test iOS app | |
id: detox | |
run: | | |
pnpm mobile e2e:test -c ios.sim.release --loglevel error --record-logs all --take-screenshots all --detectOpenHandles --cleanup --headless | |
- name: Delete iOS simulator | |
if: always() | |
run: | | |
xcrun simctl delete ${{ steps.simulator.outputs.id }} | |
- name: Upload test artifacts | |
uses: actions/upload-artifact@v2 | |
if: always() | |
with: | |
name: test-ios-artifacts | |
path: apps/ledger-live-mobile/artifacts | |
- name: Upload Allure report | |
uses: actions/upload-artifact@v2 | |
if: always() | |
with: | |
name: "allure-ios-reports" | |
path: apps/ledger-live-mobile/allure-results | |
allure-report-ios: | |
name: "Allure Reports Export on Server" | |
runs-on: [ledger-live-medium-linux] | |
if: ${{ always() && !cancelled() && github.ref_name == 'develop' }} | |
needs: [detox-tests-ios] | |
steps: | |
- uses: actions/checkout@v3 | |
with: | |
ref: ${{ (github.event_name == 'workflow_dispatch' && (inputs.ref || github.ref_name)) || github.sha }} | |
- uses: ./tools/actions/composites/upload-allure-report | |
with: | |
platform: ios | |
login: ${{ secrets.ALLURE_LOGIN }} | |
password: ${{ secrets.ALLURE_PASSWORD }} | |
path: allure-ios-reports | |
detox-tests-android: | |
name: "Ledger Live Mobile - Android Detox Tests" | |
runs-on: [ledger-live-linux-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.detox.outcome }} | |
steps: | |
- uses: LedgerHQ/ledger-live/tools/actions/composites/checkout-merge@develop | |
with: | |
ref: ${{ (github.event_name == 'workflow_dispatch' && (inputs.ref || github.ref_name)) || github.sha }} | |
- name: Setup the toolchain | |
uses: LedgerHQ/ledger-live/tools/actions/composites/setup-toolchain@develop | |
- name: setup JDK 11 | |
uses: actions/setup-java@v3 | |
with: | |
distribution: "zulu" | |
java-version: "11" | |
cache: "gradle" | |
- name: setup Android SDK | |
uses: android-actions/setup-android@v2.0.8 | |
- name: Gradle cache | |
uses: gradle/gradle-build-action@v2 | |
# https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/ | |
- name: Enable KVM group perms | |
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: TurboRepo local caching server | |
id: turborepo-cache-server | |
uses: ./tools/actions/turborepo-s3-cache | |
with: | |
server-token: "yolo" | |
cleanup-cache-folder: "true" | |
aws-access-key: ${{ secrets.ACCESS_KEY_BUCKET }} | |
aws-secret-key: ${{ secrets.SECRET_KEY_BUCKET }} | |
- name: Install dependencies | |
run: | | |
pnpm i --filter="live-mobile..." --filter="ledger-live" --filter="dummy-*" --no-frozen-lockfile --unsafe-perm | |
- name: Build dependencies | |
run: | | |
pnpm build:llm:deps --api="http://127.0.0.1:${{ steps.turborepo-cache-server.outputs.port }}" --token="yolo" --team="foo" | |
- name: Build Dummy Live SDK and Dummy Wallet API apps for testing | |
run: | | |
pnpm test-utils dummy-apps:build | |
shell: bash | |
- name: Build Android app for Detox test run | |
run: | | |
pnpm mobile e2e:build -c android.emu.release | |
- name: Start Emulator | |
uses: reactivecircus/android-emulator-runner@v2 | |
timeout-minutes: 60 | |
with: | |
api-level: 31 | |
arch: x86_64 | |
profile: pixel_5 | |
target: google_apis | |
avd-name: "Pixel_5_API_31" | |
force-avd-creation: true | |
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none | |
cores: 4 | |
ram-size: 4096M | |
heap-size: 512M | |
disk-size: 4096M | |
disable-linux-hw-accel: false | |
script: echo "Starting Emulator" | |
- name: Run Android Tests | |
id: detox | |
env: | |
DETOX_INSTALL_TIMEOUT: 120000 | |
run: | | |
pnpm mobile e2e:test -c android.emu.release --loglevel error --record-logs all --take-screenshots all --record-videos failing --forceExit --detectOpenHandles --cleanup --headless | |
- name: Upload test artifacts | |
if: always() | |
uses: actions/upload-artifact@v2 | |
with: | |
name: test-android-artifacts | |
path: apps/ledger-live-mobile/artifacts/ | |
- name: Upload Allure Report | |
uses: actions/upload-artifact@v2 | |
if: always() | |
with: | |
name: "allure-android-reports" | |
path: apps/ledger-live-mobile/allure-results | |
allure-report-android: | |
name: "Allure Reports Export on Server" | |
runs-on: [ledger-live-medium-linux] | |
if: ${{ always() && !cancelled() && github.ref_name == 'develop' }} | |
needs: [detox-tests-android] | |
steps: | |
- name: checkout | |
uses: actions/checkout@v3 | |
with: | |
ref: ${{ (github.event_name == 'workflow_dispatch' && (inputs.ref || github.ref_name)) || github.sha }} | |
- uses: ./tools/actions/composites/upload-allure-report | |
with: | |
platform: android | |
login: ${{ secrets.ALLURE_LOGIN }} | |
password: ${{ secrets.ALLURE_PASSWORD }} | |
path: allure-android-reports | |
report: | |
needs: [detox-tests-android, detox-tests-ios] | |
runs-on: ubuntu-latest | |
if: always() && !cancelled() && github.event_name == 'workflow_dispatch' | |
steps: | |
- uses: LedgerHQ/ledger-live/tools/actions/composites/checkout-merge@develop | |
with: | |
ref: ${{ (github.event_name == 'workflow_dispatch' && (inputs.ref || github.ref_name)) || github.sha }} | |
base: ${{ inputs.base_ref }} | |
- uses: actions/github-script@v6 | |
name: prepare status | |
id: status | |
with: | |
script: | | |
const fs = require("fs"); | |
const [ owner, repo ] = "${{ github.repository }}".split("/"); | |
const jobs = await github.paginate(github.rest.actions.listJobsForWorkflowRunAttempt, { | |
owner, | |
repo, | |
run_id: "${{ github.run_id }}", | |
attempt_number: "${{ github.run_attempt }}", | |
}); | |
const findJobUrl = os => | |
jobs.find(job => job.name == `Ledger Live Mobile - ${os} Detox Tests`)?.html_url; | |
const keys = { | |
ios: { | |
symbol: "🍏", | |
name: "iOS", | |
jobUrl: findJobUrl("iOS") | |
}, | |
android: { | |
symbol: "🤖", | |
name: "Android", | |
jobUrl: findJobUrl("Android") | |
}, | |
}; | |
const report = { | |
ios: { | |
pass: ${{ needs.detox-tests-ios.outputs.status == 'success' }}, | |
status: "${{ needs.detox-tests-ios.outputs.status }}", | |
}, | |
android: { | |
pass: ${{ needs.detox-tests-android.outputs.status == 'success'}}, | |
status: "${{ needs.detox-tests-android.outputs.status }}", | |
}, | |
}; | |
let summary = `### Detox Tests | |
` | |
summary += `|` | |
const reportKeys = Object.keys(report); | |
const detoxSuccess = Object.entries(report).every(([os, values]) => !!values.pass); | |
reportKeys.forEach((k) => { | |
summary += ` [${keys[k].symbol} ${keys[k].name}](${keys[k].jobUrl}) |`; | |
}); | |
summary += ` | |
|`; | |
for (let i = 0; i < reportKeys.length; i++) { | |
summary += ` :--: |`; | |
} | |
summary += ` | |
|`; | |
Object.entries(report).forEach(([os, values]) => { | |
summary += ` ${values.pass ? "✅" : "❌"} (${values.status}) |`; | |
}); | |
const output = { | |
summary | |
}; | |
fs.writeFileSync("summary.json", JSON.stringify(output), "utf-8"); | |
- uses: actions/upload-artifact@v3 | |
name: upload summary | |
with: | |
name: summary.json | |
path: ${{ github.workspace }}/summary.json | |
report-on-slack: | |
runs-on: ubuntu-latest | |
needs: [detox-tests-android, detox-tests-ios] | |
if: ${{ failure() && github.event_name == 'push' }} | |
steps: | |
- name: format message | |
uses: actions/github-script@v6 | |
id: message | |
with: | |
script: | | |
const fs = require("fs"); | |
const text = `❌ 🍏 Detox tests failed ❌`; | |
const iOSResult = [ | |
{ | |
"type": "header", | |
"text": { | |
"type": "plain_text", | |
"text": `❌ iOS Detox tests failed ❌`, | |
"emoji": true | |
} | |
}, | |
{ | |
"type": "divider" | |
}, | |
{ | |
"type": "section", | |
"text": { | |
"type": "mrkdwn", | |
"text": `😵 Build Failed | |
` | |
} | |
} | |
]; | |
const androidResult = [ | |
{ | |
"type": "header", | |
"text": { | |
"type": "plain_text", | |
"text": `❌ Android Detox tests failed ❌`, | |
"emoji": true | |
} | |
}, | |
{ | |
"type": "divider" | |
}, | |
{ | |
"type": "section", | |
"text": { | |
"type": "mrkdwn", | |
"text": `😵 Build Failed | |
` | |
} | |
} | |
]; | |
const infoBlock = [ | |
{ | |
"type": "divider" | |
}, | |
{ | |
"type": "section", | |
"text": { | |
"type": "mrkdwn", | |
"text": `<https://github.com/LedgerHQ/ledger-live/actions/runs/${{ github.run_id }}|Workflow run> for more informations`, | |
} | |
} | |
]; | |
const blocks = [] | |
.concat(${{ needs.detox-tests-ios.outputs.status == 'success' }} ? [] : iOSResult) | |
.concat(${{ needs.detox-tests-android.outputs.status == 'success' }} ? [] : androidResult) | |
.concat(infoBlock); | |
const result = { | |
text, | |
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 }} |