Skip to content

Commit

Permalink
Chore/GitHub hosted detox runners (#2428)
Browse files Browse the repository at this point in the history
* chore: check xcrun presence

* fix: correct yaml syntax

* chore: boot simulator

* chore: run tests

* fix: change node version

* chore: increase timeout

* chore: boot simulator after installing deps

* chore: use node 18.19.0

* fix: use node 18.12.1

* fix: install ci dependencies

* fix: correct bootstrap scope

* fix: scope syntax

* fix: bootstrap syntax

* fix: bootstrap syntax

* fix: force lfs install

* chore: install Detox CLI

* fix: use iOS SDK 17.1

* test: increase init delay

* test: significantly increase initial delay

* chore: dump debug info

* chore: continue on test run error

* chore: skip logs dumping

* fix: correct screenshot cmd

* fix: change simulator uuid

* fix: correct starting metro

* chore: increase timeouts

* chore: try to establish ws conn in intervals

* chore: dynamically set simulator udid

* chore: cleanup

* fix: correct getting udid syntax

* chore: temporarily switch to push trigger

* chore: cleanup

* chore: adjust intervals

* fix: uploading screenshot

* chore: change trigger condition

* chore: debug run condition

* chore: debug trigger condition

* chore: restore previous run conditions

* chore: android pipeline draft

* chore: temporarily skip ios workflow

* chore: list android emulators

* chore: debug sdk home

* chore: list avdmanager

* chore: check docker presence

* chore: check java

* chore: use proper cmdline-tools to list avd

* chore: create and boot avd

* chore: install sdk image

* fix: correct sdkmanager path

* fix: auto accept sdk prompts

* chore: list qemu

* fix: resign qemu binary

* fix: enter qemu loc

* chore: debug entitlements

* chore: change qemu path

* chore: add verbose to qemu signing

* chore: cleanup android workflow

* chore: change ios workflow trigger

* chore: restore self-hosted android detox

* fix: force pull lfs
  • Loading branch information
siepra authored Apr 17, 2024
1 parent c422cee commit 6124233
Show file tree
Hide file tree
Showing 11 changed files with 183 additions and 51 deletions.
44 changes: 44 additions & 0 deletions .github/workflows/e2e-android-self.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Detox E2E Android (self-hosted)

on:
push:
paths:
- packages/mobile/**
- packages/backend/**
- packages/state-manager/**
- .github/workflows/e2e-android-self.yml

jobs:
detox-android-self-hosted:
timeout-minutes: 10
runs-on: [self-hosted, macOS, ARM64, android]

steps:
- uses: actions/checkout@v4

- name: Install dependencies
run: |
npm i
npm run lerna bootstrap --scope @quiet/eslint-config,@quiet/logger,@quiet/common,@quiet/types,@quiet/state-manager,@quiet/backend,@quiet/identity,@quiet/mobile,backend-bundle
- name: Pull binaries
run: |
git lfs install --force
git lfs pull
- name: Pass local config
run : |
cat << EOF >> packages/mobile/android/local.properties
ndk.path=/Users/quiet/Library/Android/sdk/ndk/25.1.8937393
EOF
- name: Build Detox
run: |
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home
cd packages/mobile
detox build -c android.emu.debug.ci
- name: Run basic tests
run: |
cd packages/mobile
detox test starter -c android.emu.debug.ci
82 changes: 63 additions & 19 deletions .github/workflows/e2e-android.yml
Original file line number Diff line number Diff line change
@@ -1,44 +1,88 @@
name: E2E Android
name: Detox E2E Android

on:
push:
paths:
- packages/mobile/**
- packages/backend/**
- packages/state-manager/**
- .github/workflows/e2e-android.yml
on: workflow_dispatch

jobs:
detox-android:
timeout-minutes: 10
runs-on: [self-hosted, macOS, ARM64, android]
timeout-minutes: 25
runs-on: [macos-latest-xlarge]

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@master
with:
node-version: 18.12.1

- name: Install dependencies
run: |
npm i
npm run lerna bootstrap --scope @quiet/eslint-config,@quiet/logger,@quiet/common,@quiet/types,@quiet/state-manager,@quiet/backend,@quiet/identity,@quiet/mobile,backend-bundle
npm ci
npm run lerna bootstrap -- --scope=\'{@quiet/eslint-config,@quiet/logger,@quiet/common,@quiet/types,@quiet/state-manager,@quiet/backend,@quiet/identity,@quiet/mobile,backend-bundle}\'
- name: Pull binaries
run: |
git lfs install
git lfs install --force
git lfs pull
- name: Pass local config
run : |
cat << EOF >> packages/mobile/android/local.properties
ndk.path=/Users/quiet/Library/Android/sdk/ndk/25.1.8937393
EOF
# see: https://stackoverflow.com/questions/67264212/android-emulator-crash-when-start-hvf-error-hv-error
- name: Create qemu entitlements
run: |
{
echo '<?xml version="1.0" encoding="UTF-8"?>'
echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
echo '<plist version="1.0">'
echo '<dict>'
echo ' <key>com.apple.security.hypervisor</key>'
echo ' <true/>'
echo '</dict>'
echo '</plist>'
} >> $ANDROID_HOME/emulator/qemu/darwin-aarch64/entitlements.xml
- name: Re-sign qemu binary
run: |
cd $ANDROID_HOME/emulator/qemu/darwin-aarch64
codesign -s - --entitlements entitlements.xml --force qemu-system-aarch64 --verbose
- name: Install SDK image
run: yes | $ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager --install 'system-images;android-34;google_apis;arm64-v8a'

- name: Create AVD
run: $ANDROID_HOME/cmdline-tools/latest/bin/avdmanager create avd -n emulator_ci -k 'system-images;android-34;google_apis;arm64-v8a' -d 'pixel_7'

- name: Boot AVD
run: $ANDROID_HOME/emulator/emulator -avd emulator_ci

- name: Install pm2
run: npm install pm2@latest -g

- name: Start metro
run: |
cd packages/mobile
pm2 --name METRO start npm -- start
- name: Install Detox CLI
run: npm install detox-cli --global

- name: Build Detox
run: |
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home
cd packages/mobile
detox build -c android.emu.debug.ci
- name: Run basic tests
run: |
cd packages/mobile
detox test starter -c android.emu.debug.ci
- name: Stop metro
run: pm2 stop METRO

- name: Take screenshot
if: always()
run: | # TODO
- name: Upload screenshot
if: always()
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
with:
name: screenshot.png
path: screenshot.png
62 changes: 50 additions & 12 deletions .github/workflows/e2e-ios.yml
Original file line number Diff line number Diff line change
@@ -1,35 +1,58 @@
name: E2E iOS
name: Detox E2E iOS

on:
push:
paths:
- packages/mobile/**
- packages/backend/**
- packages/state-manager/**
on: workflow_dispatch

jobs:
detox-ios:
timeout-minutes: 10
runs-on: [self-hosted, macOS, ARM64, iOS]
timeout-minutes: 25
runs-on: [macos-latest-xlarge]

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@master
with:
node-version: 18.12.1

- name: Install dependencies
run: |
npm i
npm run lerna bootstrap --scope @quiet/eslint-config,@quiet/logger,@quiet/common,@quiet/types,@quiet/state-manager,@quiet/backend,@quiet/identity,@quiet/mobile,backend-bundle
npm ci
npm run lerna bootstrap -- --scope=\'{@quiet/eslint-config,@quiet/logger,@quiet/common,@quiet/types,@quiet/state-manager,@quiet/backend,@quiet/identity,@quiet/mobile,backend-bundle}\'
- name: Pull binaries
run: |
git lfs install
git lfs install --force
git lfs pull
- name: Install pods
run: |
cd packages/mobile/ios
pod install
- name: List simulator devices
run: xcrun simctl list devices

- name: Boot simulator
run: |
UDID=$(xcrun simctl list devices | grep 'iPhone 15 (' | awk -F '[()]' '{print $2}' | awk 'NR==2')
xcrun simctl boot "$UDID"
- name: Install pm2
run: npm install pm2@latest -g

- name: Start metro
run: |
cd packages/mobile
pm2 --name METRO start npm -- start
- name: Install Detox CLI
run: npm install detox-cli --global

- name: Install applesimutils
run: |
brew tap wix/brew
brew install applesimutils
- name: Build Detox
run: |
cd packages/mobile
Expand All @@ -39,3 +62,18 @@ jobs:
run: |
cd packages/mobile
detox test starter -c ios.sim.debug.ci
- name: Stop metro
run: pm2 stop METRO

- name: Take screenshot
if: always()
run: |
/usr/bin/xcrun simctl io booted screenshot screenshot.png
- name: Upload screenshot
if: always()
uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
with:
name: screenshot.png
path: screenshot.png
2 changes: 1 addition & 1 deletion packages/mobile/.detoxrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ module.exports = {
emulator_ci: {
type: 'android.emulator',
device: {
avdName: 'Pixel_7_API_31',
avdName: 'emulator_ci',
},
},
},
Expand Down
2 changes: 1 addition & 1 deletion packages/mobile/e2e/utils/consts/timeouts.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
export const BASIC = 5000
export const LONG = 20000
export const STARTUP = 90000
export const STARTUP = 120000
2 changes: 1 addition & 1 deletion packages/mobile/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
require_relative '../node_modules/react-native/scripts/react_native_pods'

platform :ios, '17.4'
platform :ios, '17.1'

target 'Quiet' do
config = use_native_modules!
Expand Down
4 changes: 2 additions & 2 deletions packages/mobile/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1393,6 +1393,6 @@ SPEC CHECKSUMS:
Tor: 39dc71bf048312e202608eb499ca5c74e841b503
Yoga: 13c8ef87792450193e117976337b8527b49e8c03

PODFILE CHECKSUM: 811e75c5d23ebd5b5f3e16c6dd4bae230db730d0
PODFILE CHECKSUM: eed49772dde039b0723324c813c83dd4c1af35f7

COCOAPODS: 1.14.3
COCOAPODS: 1.15.2
4 changes: 2 additions & 2 deletions packages/mobile/ios/Quiet.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -5300,7 +5300,7 @@
INFOPLIST_FILE = Quiet/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Quiet;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
IPHONEOS_DEPLOYMENT_TARGET = 17.4;
IPHONEOS_DEPLOYMENT_TARGET = 17.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down Expand Up @@ -5396,7 +5396,7 @@
INFOPLIST_FILE = Quiet/Info.plist;
INFOPLIST_KEY_CFBundleDisplayName = Quiet;
INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.social-networking";
IPHONEOS_DEPLOYMENT_TARGET = 17.4;
IPHONEOS_DEPLOYMENT_TARGET = 17.1;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
Expand Down
13 changes: 8 additions & 5 deletions packages/mobile/ios/Quiet/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,14 @@ - (void) initWebsocketConnection {
* Delay used below can't cause any race condition as websocket won't connect until data server starts listening anyway.
*/
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
NSTimeInterval delayInSeconds = 5;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
[[self.bridge moduleForName:@"CommunicationModule"] sendDataPortWithPort:self.dataPort socketIOSecret:self.socketIOSecret];
});
NSArray *intervals = @[@5, @15, @30, @60, @90];
for (NSNumber *interval in intervals) {
NSTimeInterval delayInSeconds = [interval doubleValue];
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
[[self.bridge moduleForName:@"CommunicationModule"] sendDataPortWithPort:self.dataPort socketIOSecret:self.socketIOSecret];
});
}
});
}

Expand Down
16 changes: 8 additions & 8 deletions packages/mobile/ios/Quiet/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -36,26 +36,26 @@
<key>CFBundleVersion</key>
<string>371</string>
<key>ITSAppUsesNonExemptEncryption</key>
<false />
<false/>
<key>LSRequiresIPhoneOS</key>
<true />
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<false />
<false/>
<key>NSAllowsLocalNetworking</key>
<true />
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>localhost</key>
<dict>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true />
<true/>
</dict>
</dict>
</dict>
<key>NSLocationWhenInUseUsageDescription</key>
<string />
<string></string>
<key>UIAppFonts</key>
<array>
<string>Rubik-Black.ttf</string>
Expand All @@ -74,7 +74,7 @@
<string>Rubik-SemiBoldItalic.ttf</string>
</array>
<key>UIBackgroundModes</key>
<array />
<array/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIRequiredDeviceCapabilities</key>
Expand All @@ -88,6 +88,6 @@
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false />
<false/>
</dict>
</plist>
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import { eventChannel } from 'redux-saga'
export function* startConnectionSaga(
action: PayloadAction<ReturnType<typeof initActions.startWebsocketConnection>['payload']>
): Generator {
const isAlreadyConnected = yield* select(initSelectors.isWebsocketConnected)
if (isAlreadyConnected) return

const { dataPort, socketIOSecret } = action.payload

console.log('WEBSOCKET', 'Entered start connection saga', dataPort)
Expand Down

0 comments on commit 6124233

Please sign in to comment.