From 570fe16a19513c7c05307cc4f1e4487d293e9d28 Mon Sep 17 00:00:00 2001 From: jdabbech-ledger <145363160+jdabbech-ledger@users.noreply.github.com> Date: Wed, 27 Dec 2023 13:44:07 +0100 Subject: [PATCH] [LIVE-10137] [CI] - [Github Actions] - Improve clarity of run actions (#5642) * chore(ci): mobile e2e build & test script * chore(ci): improve clarity desktop lint action * chore: use of zx instead of bash * fix(mobile): e2e script cache option --- .github/workflows/test-desktop-external.yml | 2 +- .github/workflows/test-desktop.yml | 2 +- .github/workflows/test-mobile-e2e.yml | 18 +-- apps/ledger-live-desktop/package.json | 1 + apps/ledger-live-desktop/scripts/ci-lint.mjs | 59 +++++++++ apps/ledger-live-mobile/package.json | 1 + apps/ledger-live-mobile/scripts/e2e-ci.mjs | 124 +++++++++++++++++++ 7 files changed, 192 insertions(+), 15 deletions(-) create mode 100755 apps/ledger-live-desktop/scripts/ci-lint.mjs create mode 100755 apps/ledger-live-mobile/scripts/e2e-ci.mjs diff --git a/.github/workflows/test-desktop-external.yml b/.github/workflows/test-desktop-external.yml index 138887e1ac23..64d706fb10b1 100644 --- a/.github/workflows/test-desktop-external.yml +++ b/.github/workflows/test-desktop-external.yml @@ -43,7 +43,7 @@ jobs: with: skip_builds: true - name: lint - run: pnpm lint --filter="ledger-live-desktop" -- --format="json" -o="lint.json" + run: pnpm desktop lint:ci - name: prettier run: pnpm desktop prettier:check - name: typecheck diff --git a/.github/workflows/test-desktop.yml b/.github/workflows/test-desktop.yml index 717717ae34d7..0694765cefb5 100644 --- a/.github/workflows/test-desktop.yml +++ b/.github/workflows/test-desktop.yml @@ -56,7 +56,7 @@ jobs: skip_builds: true turborepo-server-port: ${{ steps.toolchain.outputs.port }} - name: lint - run: pnpm lint --filter="ledger-live-desktop" --api="http://127.0.0.1:${{ steps.toolchain.outputs.port }}" --token="${{ secrets.TURBOREPO_SERVER_TOKEN }}" --team="foo" -- --format="json" -o="lint.json" + run: pnpm desktop lint:ci -p ${{ steps.toolchain.outputs.port }} -t "${{ secrets.TURBOREPO_SERVER_TOKEN }}" - name: prettier run: pnpm desktop prettier:check - name: typecheck diff --git a/.github/workflows/test-mobile-e2e.yml b/.github/workflows/test-mobile-e2e.yml index 7d84c2deb05d..da5694113088 100644 --- a/.github/workflows/test-mobile-e2e.yml +++ b/.github/workflows/test-mobile-e2e.yml @@ -104,23 +104,15 @@ jobs: echo "id=$ID" >> $GITHUB_OUTPUT - name: Build iOS app for Detox test run if: steps.detox-build.outputs.cache-hit != 'true' - run: | - pnpm mobile e2e:build -c ios.sim.release + run: pnpm mobile e2e:ci -p ios -b - name: Build JS Bundle app for Detox test run if: steps.detox-build.outputs.cache-hit == 'true' - run: | - pnpm mobile bundle:ios --dev false --minify false - pnpm mobile exec detox clean-framework-cache - pnpm mobile exec detox build-framework-cache - cd apps/ledger-live-mobile - cp main.jsbundle ios/build/Build/Products/Release-iphonesimulator/ledgerlivemobile.app/main.jsbundle - mv main.jsbundle ios/build/Build/Products/Release-iphonesimulator/main.jsbundle + run: pnpm mobile e2e:ci -p ios --bundle - name: Test iOS app id: detox timeout-minutes: 45 - run: | - pnpm mobile e2e:test -c ios.sim.release --loglevel error --record-logs all --take-screenshots all --headless --retries 1 --cleanup --record-performance all + run: pnpm mobile e2e:ci -p ios -t - name: Delete iOS simulator if: always() run: | @@ -207,7 +199,7 @@ jobs: shell: bash - name: Build Android app for Detox test run run: | - pnpm mobile e2e:build -c android.emu.release + pnpm mobile e2e:ci -p android -b - name: cache android emulator uses: tespkg/actions-cache@v1 id: detox-avd @@ -258,7 +250,7 @@ jobs: ram-size: 8192M disable-linux-hw-accel: false emulator-options: -read-only -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none - script: pnpm mobile e2e:test -c android.emu.release --loglevel error --record-logs all --take-screenshots all --forceExit --headless --retries 1 --cleanup + script: pnpm mobile e2e:ci -p android -t - name: Upload test artifacts if: always() uses: actions/upload-artifact@v3 diff --git a/apps/ledger-live-desktop/package.json b/apps/ledger-live-desktop/package.json index a30e45a5c55a..514f4a59d105 100644 --- a/apps/ledger-live-desktop/package.json +++ b/apps/ledger-live-desktop/package.json @@ -21,6 +21,7 @@ "build:js": "cross-env NODE_ENV=production node ./tools/main.js build", "build:testing": "cross-env NODE_ENV=production TESTING=1 node ./tools/main.js build", "lint": "eslint src static tools tests --ext .js,.jsx,.json,.ts,.tsx --cache", + "lint:ci": "zx scripts/ci-lint.mjs", "lint:fix": "eslint src tools static tests --ext .js,.jsx,.json,.ts,.tsx --fix", "prettier": "prettier --write \"{src,tools,tests}/**/*.{js,jsx,json,ts,tsx}\"", "prettier:check": "prettier -c \"{src,tools}/**/*.{js,jsx,json,ts,tsx}\"", diff --git a/apps/ledger-live-desktop/scripts/ci-lint.mjs b/apps/ledger-live-desktop/scripts/ci-lint.mjs new file mode 100755 index 000000000000..921a81bbcf59 --- /dev/null +++ b/apps/ledger-live-desktop/scripts/ci-lint.mjs @@ -0,0 +1,59 @@ +#!/usr/bin/env zx +import { basename } from 'path' +import stylish from "../../../node_modules/eslint/lib/cli-engine/formatters/stylish.js" + +const usage = () => { + console.log(`Usage: ${basename(__filename)} [-h] [-p ] [-t ]`); + process.exit(1) +} + +let port, token; + +for (const arg in argv) { + switch (arg) { + case 'h': + usage(); + break; + case 'p': + port = argv[arg]; + break + case 't': + token = argv[arg]; + break; + case '_': + break; + default: + usage(); + break; + } +} + +if (typeof token !== "string") { + usage(); +} + +const lint = async () => { + cd('../../') + + if (typeof port === 'string') { + await $`pnpm lint \\ + --filter="ledger-live-desktop" \\ + --api="http://127.0.0.1:${port}" \\ + --token=${token} \\ + --team="foo" \\ + -- --format="json" \\ + -o="lint.json"`; + } else { + await $`pnpm lint \\ + --filter="ledger-live-desktop" \\ + --token=${token} \\ + --team="foo" \\ + -- --format="json" \\ + -o="lint.json"`; + } + + const lintJson = require('../lint.json') + stylish(lintJson); +} + +await lint() diff --git a/apps/ledger-live-mobile/package.json b/apps/ledger-live-mobile/package.json index 02a848f5ecc2..b040be04bafe 100644 --- a/apps/ledger-live-mobile/package.json +++ b/apps/ledger-live-mobile/package.json @@ -16,6 +16,7 @@ "android:bundleInDebug": "ANDROID_BUNDLE_IN_DEBUG=true pnpm android", "gen-metafile": "zx ./scripts/gen-metafile.mjs", "e2e:build": "pnpm detox build", + "e2e:ci": "zx ./scripts/e2e-ci.mjs", "e2e:test": "pnpm detox test", "prebeta": "bundle install", "ios:staging": "ENVFILE=.env.ios.staging react-native run-ios --configuration Staging", diff --git a/apps/ledger-live-mobile/scripts/e2e-ci.mjs b/apps/ledger-live-mobile/scripts/e2e-ci.mjs new file mode 100755 index 000000000000..40deeb5e0319 --- /dev/null +++ b/apps/ledger-live-mobile/scripts/e2e-ci.mjs @@ -0,0 +1,124 @@ +#!/usr/bin/env zx +import { basename } from 'path'; + +let platform, test, build, bundle; +let cache = true; + +const usage = (exitCode = 1) => { + console.log(`Usage: ${basename(__filename)} -p --platform [-h --help] [-t --test] [-b --build] [--bundle] [--cache | --no-cache]`); + process.exit(exitCode); +} + +const build_ios = async () => { + await $`pnpm mobile e2e:build -c ios.sim.release`; +} + +const bundle_ios = async () => { + await $`pnpm mobile bundle:ios --dev false --minify false`; +} + +const bundle_ios_with_cache = async () => { + await bundle_ios(); + + await $`pnpm mobile exec detox clean-framework-cache`; + await $`pnpm mobile exec detox build-framework-cache`; + within(async () => { + cd('apps/ledger-live-mobile'); + await $`cp main.jsbundle ios/build/Build/Products/Release-iphonesimulator/ledgerlivemobile.app/main.jsbundle`; + await $`mv main.jsbundle ios/build/Build/Products/Release-iphonesimulator/main.jsbundle`; + }); +} + +const test_ios = async () => { + await $`pnpm mobile e2e:test \ + -c ios.sim.release \ + --loglevel error \ + --record-logs all \ + --take-screenshots all \ + --headless \ + --retries 1 \ + --cleanup \ + --record-performance all`; +} + +const build_android = async () => { + await $`pnpm mobile e2e:build -c android.emu.release`; +} + +const test_android = async () => { + await $`pnpm mobile e2e:test \\ + -c android.emu.release \\ + --loglevel error \\ + --record-logs all \\ + --take-screenshots all \\ + --forceExit \\ + --headless \\ + --retries 1 \\ + --cleanup`; +} + +const getTasksFrom = { + ios: { + build: build_ios, + bundle: async () => cache ? await bundle_ios_with_cache() : await bundle_ios(), + test: test_ios, + }, + android: { + build: build_android, + bundle: () => undefined, + test: test_android + } +} + +for (const argName in argv) { + switch (argName) { + case 'help': + case 'h': + usage(0); + break; + case 'platform': + case 'p': + if (argv[argName] !== 'ios' && argv[argName] !== 'android') { + usage(1); + } else { + platform = argv[argName]; + } + break; + case 'test': + case 't': + test = true; + break; + case 'build': + case 'b': + build = true; + break; + case 'bundle': + bundle = true; + break; + case 'cache': + cache = argv[argName]; + break; + case '_': + break; + default: + usage(42); + break; + } +} + +within(async () => { + if (!platform) { + usage(2) + } + + cd('../../'); + if (build) { + await getTasksFrom[platform].build(); + } + if (bundle) { + await getTasksFrom[platform].bundle(); + } + if (test) { + await getTasksFrom[platform].test(); + } +});