dev
yml 487 lines 21.4 KB
Raw
1
2 name: Automated Integration Tests
3
4 # Temporarily disabled - uncomment to re-enable
5 on:
6 # push:
7 # pull_request:
8 # branches: [main]
9 workflow_dispatch: # This is to manually trigger if needed
10 defaults:
11 run:
12 shell: bash
13 jobs:
14 Automated_integration_test:
15 runs-on: linux-amd64
16 timeout-minutes: 90
17 container:
18 image: ghcr.io/cake-tech/cake_wallet:debian12-flutter3.27.0-go1.24.1-ruststablenightly
19 env:
20 STORE_PASS: test@cake_wallet
21 KEY_PASS: test@cake_wallet
22 MONEROC_CACHE_DIR_ROOT: /opt/generic_cache
23 BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
24 ANDROID_AVD_HOME: /root/.android/avd
25 volumes:
26 - /opt/cw_cache_android/root/.cache:/root/.cache
27 - /opt/cw_cache_android/root/.android/avd/:/root/.android/avd
28 - /opt/cw_cache_android/root/.ccache:/root/.ccache
29 - /opt/cw_cache_android/root/.pub-cache/:/root/.pub-cache
30 - /opt/cw_cache_android/root/.gradle/:/root/.gradle
31 - /opt/cw_cache_android/root/.android/:/root/.android
32 - /opt/cw_cache_android/root/go/pkg:/root/go/pkg
33 - /opt/cw_cache_android/opt/generic_cache:/opt/generic_cache
34 - /dev/kvm:/dev/kvm
35 strategy:
36 matrix:
37 api-level: [29]
38
39 steps:
40 - name: Fix github actions messing up $HOME...
41 run: 'echo HOME=/root | sudo tee -a $GITHUB_ENV'
42 - uses: actions/checkout@v4
43 with:
44 ref: ${{ github.event.pull_request.head.sha || github.sha }}
45 - name: configure git
46 run: |
47 git config --global --add safe.directory '*'
48 git config --global user.email "ci@cakewallet.com"
49 git config --global user.name "CakeWallet CI"
50 - name: Get the full commit message
51 run: |
52 FULL_MESSAGE="$(git log -1 --pretty=%B)"
53 echo "message<<EOF" >> $GITHUB_ENV
54 echo "$FULL_MESSAGE" >> $GITHUB_ENV
55 echo "EOF" >> $GITHUB_ENV
56
57 - name: Add secrets
58 run: |
59 touch cw_bitcoin/lib/.secrets.g.dart
60 touch cw_evm/lib/.secrets.g.dart
61 touch cw_solana/lib/.secrets.g.dart
62 touch cw_core/lib/.secrets.g.dart
63 touch cw_nano/lib/.secrets.g.dart
64 touch cw_tron/lib/.secrets.g.dart
65
66 echo "const polygonScanApiKey = '${{ secrets.POLYGON_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
67 echo "const etherScanApiKey = '${{ secrets.ETHER_SCAN_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
68 echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
69 echo "const nowNodesApiKey = '${{ secrets.EVM_NOWNODES_API_KEY }}';" >> cw_evm/lib/.secrets.g.dart
70 echo "const ankrApiKey = '${{ secrets.ANKR_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
71 echo "const chainStackApiKey = '${{ secrets.CHAIN_STACK_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
72 echo "const moralisApiKey = '${{ secrets.MORALIS_API_KEY }}';" >> cw_solana/lib/.secrets.g.dart
73
74 echo "const nano2ApiKey = '${{ secrets.NANO2_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
75 echo "const nanoNowNodesApiKey = '${{ secrets.NANO_NOW_NODES_API_KEY }}';" >> cw_nano/lib/.secrets.g.dart
76
77 echo "const tronGridApiKey = '${{ secrets.TRON_GRID_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
78 echo "const tronNowNodesApiKey = '${{ secrets.TRON_NOW_NODES_API_KEY }}';" >> cw_tron/lib/.secrets.g.dart
79
80 echo "const breezApiKey = '${{ secrets.BREEZ_API_KEY }}';" >> cw_bitcoin/lib/.secrets.g.dart
81
82 echo "${{ secrets.MAIN_SECRETS_FILE }}" | base64 --decode > lib/.secrets.g.dart
83
84 - name: prepare monero_c and cache
85 run: |
86 export MONEROC_HASH=$(cat scripts/prepare_moneroc.sh | grep 'git checkout' | xargs | awk '{ print $3 }')
87 echo MONEROC_HASH=$MONEROC_HASH >> /etc/environment
88 mkdir -p "$MONEROC_CACHE_DIR_ROOT/moneroc-$MONEROC_HASH/monero_c"
89 pushd scripts
90 ln -s "$MONEROC_CACHE_DIR_ROOT/moneroc-$MONEROC_HASH/monero_c"
91 ./prepare_moneroc.sh
92 popd
93 pushd scripts/monero_c
94 mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/built" || true
95 mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/built" || true
96 mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/built" || true
97 mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/sources" || true
98 mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/sources" || true
99 mkdir -p "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/sources" || true
100
101 rm -rf "$PWD/contrib/depends/built" "$PWD/monero/contrib/depends/built" "$PWD/wownero/contrib/depends/built"
102 rm -rf "$PWD/contrib/depends/sources" "$PWD/monero/contrib/depends/sources" "$PWD/wownero/contrib/depends/sources"
103 mkdir -p contrib/depends || true
104 ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/built" "$PWD/contrib/depends/built"
105 ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/built" "$PWD/monero/contrib/depends/built"
106 ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/built" "$PWD/wownero/contrib/depends/built"
107 ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/contrib/depends/sources" "$PWD/contrib/depends/sources"
108 ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/monero/contrib/depends/sources" "$PWD/monero/contrib/depends/sources"
109 ln -sf "$MONEROC_CACHE_DIR_ROOT/_cache/wownero/contrib/depends/sources" "$PWD/wownero/contrib/depends/sources"
110 popd
111
112 - name: Generate KeyStore
113 run: |
114 pushd /opt/generic_cache
115 if [[ ! -f key.jks ]];
116 then
117 keytool -genkey -v -keystore key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias testKey -noprompt -dname "CN=CakeWallet, OU=CakeWallet, O=CakeWallet, L=Florida, S=America, C=USA" -storepass $STORE_PASS -keypass $KEY_PASS
118 else
119 echo "$PWD/key.jks exist, not generating"
120 fi
121 popd
122 cp /opt/generic_cache/key.jks android/app
123
124 - name: Execute Build and Setup Commands
125 run: |
126 pushd scripts/android
127 source ./app_env.sh cakewallet
128 ./app_config.sh
129 popd
130
131 - name: Build monero_c
132 run: |
133 pushd scripts/android/
134 source ./app_env.sh cakewallet
135 ./build_monero_all.sh
136 popd
137
138 - name: Install Flutter dependencies
139 run: |
140 flutter pub get
141
142 - name: Build mwebd
143 run: |
144 set -x -e
145 export MWEBD_HASH=$(cat scripts/android/build_mwebd.sh | grep 'git reset --hard' | xargs | awk '{ print $4 }')
146 echo MWEBD_HASH=$MWEBD_HASH >> /etc/environment
147 pushd scripts/android
148 gomobile init;
149 ./build_mwebd.sh
150 popd
151
152 - name: Build Decred
153 run: |
154 set -x -e
155 pushd scripts/android
156 ./build_decred.sh
157 popd
158
159 - name: Build generated code
160 run: |
161 flutter --version
162 flutter pub get
163 ./model_generator.sh
164
165 - name: Generate key properties
166 run: |
167 dart run tool/generate_android_key_properties.dart keyAlias=testKey storeFile=key.jks storePassword=$STORE_PASS keyPassword=$KEY_PASS
168
169 - name: Generate localization
170 run: |
171 dart run tool/generate_localization.dart
172
173 - name: Rename app
174 run: |
175 sanitized_branch_name=${BRANCH_NAME#origin/} # Remove 'origin/' prefix if it exists
176 sanitized_branch_name=${sanitized_branch_name:0:16} # Take only the first 16 characters
177 sanitized_branch_name=$(echo "$sanitized_branch_name" | tr '[:upper:]' '[:lower:]') # Convert to lowercase
178 sanitized_branch_name=$(echo "$sanitized_branch_name" | sed 's/[^a-z0-9]//g') # Remove all special characters
179
180 echo -e "id=com.cakewallet.test_${sanitized_branch_name}\nname=${BRANCH_NAME}" > android/app.properties
181
182 - name: Build
183 run: |
184 flutter build apk --dart-define=hasDevOptions=true --release --split-per-abi
185
186 - name: Rename apk file
187 run: |
188 sanitized_branch_name=$(grep '^id=' android/app.properties | cut -d'=' -f2 | sed 's/com\.cakewallet\.test_//')
189 cd build/app/outputs/flutter-apk
190 mkdir test-apk
191
192 cp app-arm64-v8a-release.apk test-apk/${sanitized_branch_name}.apk
193 cp app-x86_64-release.apk test-apk/${sanitized_branch_name}_x86.apk
194 echo "APK files created: test-apk/${sanitized_branch_name}.apk and test-apk/${sanitized_branch_name}_x86.apk"
195
196 - name: Find APK file
197 id: find_apk
198 run: |
199 set -x
200 # Read the sanitized branch name from the app.properties file
201 sanitized_branch_name=$(grep '^id=' android/app.properties | cut -d'=' -f2 | sed 's/com\.cakewallet\.test_//')
202
203 echo "Looking for APK file: build/app/outputs/flutter-apk/test-apk/${sanitized_branch_name}.apk"
204 ls -la build/app/outputs/flutter-apk/test-apk/ || echo "test-apk directory not found"
205 apk_file=$(ls build/app/outputs/flutter-apk/test-apk/${sanitized_branch_name}.apk || exit 1)
206 echo "APK_FILE=$apk_file" >> $GITHUB_ENV
207 echo "APK file found: $apk_file"
208 ls -la "$apk_file"
209
210 - name: 🔍 Debug System Environment
211 run: |
212 echo "=== System Information ==="
213 uname -a
214 echo "=== Container Info ==="
215 cat /proc/version || echo "Cannot read /proc/version"
216 echo "=== KVM Device Check ==="
217 ls -la /dev/kvm || echo "KVM device not found"
218 echo "=== udev Status ==="
219 which udevadm || echo "udevadm not found"
220 echo "=== Current User ==="
221 whoami
222 echo "=== Groups ==="
223 groups
224 echo "=== Environment ==="
225 env | grep -E "(HOME|USER|PATH)" | sort
226
227 - name: 🧹 Clean up existing emulators
228 run: |
229 echo "=== Cleaning up existing emulators ==="
230 # Kill any existing emulator processes
231 pkill -f emulator || echo "No emulator processes found"
232 # Kill any existing adb processes
233 pkill -f adb || echo "No adb processes found"
234 # Wait a moment for processes to terminate
235 sleep 2
236 # Start adb server fresh
237 adb start-server || echo "Failed to start adb server"
238 # Kill adb server to ensure clean state
239 adb kill-server || echo "Failed to kill adb server"
240 echo "=== Cleanup complete ==="
241
242 - name: 🔍 Verify AVD Configuration
243 run: |
244 echo "=== AVD Configuration Check ==="
245
246 # Check if AVD directory exists
247 echo "Checking AVD directory..."
248 ls -la ~/.android/avd/ || echo "AVD directory not found"
249
250 # List available AVDs
251 echo "Available AVDs:"
252 emulator -list-avds || echo "Failed to list AVDs"
253
254 # Check Android SDK location
255 echo "Android SDK location:"
256 echo $ANDROID_HOME
257 echo $ANDROID_SDK_ROOT
258
259 # Check emulator binary
260 echo "Emulator binary:"
261 which emulator || echo "Emulator not found in PATH"
262 emulator -version || echo "Failed to get emulator version"
263
264 echo "=== AVD Check Complete ==="
265
266 - name: 🦾 Enable KVM
267 run: |
268 echo "=== KVM Setup and Verification ==="
269
270 # Check if KVM device exists
271 if [ -e /dev/kvm ]; then
272 echo "✅ KVM device found at /dev/kvm"
273
274 # Check current permissions
275 echo "Current KVM permissions:"
276 ls -la /dev/kvm
277
278 # Set proper permissions
279 sudo chmod 666 /dev/kvm || echo "⚠️ Failed to set KVM permissions"
280
281 # Verify permissions were set
282 if [ -r /dev/kvm ] && [ -w /dev/kvm ]; then
283 echo "✅ KVM is readable and writable"
284 else
285 echo "⚠️ KVM permissions may not be optimal"
286 fi
287
288 # Test KVM functionality
289 echo "Testing KVM functionality..."
290 if command -v kvm-ok >/dev/null 2>&1; then
291 if kvm-ok 2>/dev/null; then
292 echo "✅ KVM is working properly"
293 else
294 echo "⚠️ KVM check failed, but continuing..."
295 fi
296 else
297 echo "ℹ️ kvm-ok command not available, testing manually..."
298 # Manual KVM test
299 if [ -r /dev/kvm ] && [ -w /dev/kvm ]; then
300 echo "✅ KVM device is accessible"
301 fi
302 fi
303
304 # Try to create udev rules (may fail in container, that's OK)
305 echo "Setting up udev rules..."
306 sudo mkdir -p /etc/udev/rules.d || echo "⚠️ Could not create udev directory"
307 echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules || echo "⚠️ Could not create udev rule"
308
309 # Try to reload udev rules (will likely fail in container, that's OK)
310 sudo udevadm control --reload-rules || echo "ℹ️ udevadm control failed (expected in container)"
311 sudo udevadm trigger --name-match=kvm || echo "ℹ️ udevadm trigger failed (expected in container)"
312
313 else
314 echo "❌ KVM device not found at /dev/kvm"
315 echo "This will cause the emulator to run in software mode (slower)"
316 fi
317
318 # Check system resources
319 echo "=== System Resources ==="
320 echo "Memory:"
321 free -h
322 echo "Disk space:"
323 df -h
324 echo "CPU cores:"
325 nproc
326 echo "KVM module loaded:"
327 lsmod | grep kvm || echo "KVM module not loaded (may be built-in)"
328
329 echo "=== KVM Setup Complete ==="
330
331 - name: 🦾 Cache gradle
332 uses: gradle/actions/setup-gradle@v3
333
334 - name: 🦾 Cache AVD
335 uses: actions/cache@v4
336 id: avd-cache
337 with:
338 path: |
339 ~/.android/avd/*
340 ~/.android/adb*
341 key: avd-${{ matrix.api-level }}
342
343 - name: 🔧 Prepare emulator utilities
344 run: |
345 # Create a helper script for emulator readiness checks
346 cat > /tmp/emulator_ready.sh << 'EOF'
347 #!/bin/bash
348
349 echo "=== Emulator Readiness Check ==="
350
351 # Wait for boot completion
352 echo "1. Checking boot completion..."
353 timeout 300 bash -c 'until adb shell getprop sys.boot_completed 2>/dev/null | grep -q "1"; do sleep 5; echo " Waiting for boot completion..."; done'
354 if [ $? -eq 0 ]; then
355 echo "✅ Boot completed"
356 else
357 echo "❌ Boot completion timeout"
358 echo "⚠️ Continuing anyway..."
359 fi
360
361 # Wait for input service
362 echo "2. Checking input service..."
363 timeout 60 bash -c 'until adb shell service list 2>/dev/null | grep -q "input"; do sleep 2; echo " Waiting for input service..."; done'
364 if [ $? -eq 0 ]; then
365 echo "✅ Input service ready"
366 else
367 echo "❌ Input service timeout"
368 echo "⚠️ Continuing anyway..."
369 fi
370
371 # Wait for package manager
372 echo "3. Checking package manager..."
373 timeout 60 bash -c 'until adb shell pm list packages 2>/dev/null >/dev/null; do sleep 2; echo " Waiting for package manager..."; done'
374 if [ $? -eq 0 ]; then
375 echo "✅ Package manager ready"
376 else
377 echo "❌ Package manager timeout"
378 echo "⚠️ Continuing anyway..."
379 fi
380
381 # Wait for settings service
382 echo "4. Checking settings service..."
383 timeout 60 bash -c 'until adb shell settings get global window_animation_scale 2>/dev/null >/dev/null; do sleep 2; echo " Waiting for settings service..."; done'
384 if [ $? -eq 0 ]; then
385 echo "✅ Settings service ready"
386 else
387 echo "❌ Settings service timeout"
388 echo "⚠️ Continuing anyway..."
389 fi
390
391 echo "✅ Emulator readiness check completed"
392 EOF
393
394 chmod +x /tmp/emulator_ready.sh
395
396 - name: 🦾 Create AVD and generate snapshot for caching
397 if: steps.avd-cache.outputs.cache-hit != 'true'
398 uses: reactivecircus/android-emulator-runner@v2
399 with:
400 api-level: ${{ matrix.api-level }}
401 force-avd-creation: false
402 # arch: ${{ matrix.arch }}
403 emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -read-only -memory 1024 -no-snapshot-save
404 working-directory: ${{ github.workspace }}
405 disable-animations: false
406 script: |
407 echo "=== AVD Snapshot Generation ==="
408
409 # Use the helper script to ensure emulator is fully ready
410 /tmp/emulator_ready.sh
411
412 # Manually disable animations with error handling
413 echo "Disabling animations manually..."
414 adb shell settings put global window_animation_scale 0.0 || echo "Failed to disable window animations"
415 adb shell settings put global transition_animation_scale 0.0 || echo "Failed to disable transition animations"
416 adb shell settings put global animator_duration_scale 0.0 || echo "Failed to disable animator duration"
417
418 echo "=== Checking emulator status before termination ==="
419 adb devices || echo "ADB devices check failed"
420 echo "=== AVD snapshot generation complete ==="
421
422 - name: 🚀 Integration tests on Android Emulator
423 timeout-minutes: 60
424 uses: reactivecircus/android-emulator-runner@v2
425 with:
426 api-level: ${{ matrix.api-level }}
427 force-avd-creation: false
428 emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -read-only -memory 1024 -no-snapshot-save
429 disable-animations: false
430 working-directory: ${{ github.workspace }}
431 script: |
432 echo "=== Pre-test Environment Check ==="
433 pwd
434 ls -la integration_test_runner.sh || echo "integration_test_runner.sh not found"
435
436 echo "=== Emulator Status Check ==="
437 adb devices
438
439 echo "=== Emulator Info ==="
440 adb shell getprop ro.build.version.release || echo "Failed to get Android version"
441 adb shell getprop ro.product.model || echo "Failed to get device model"
442
443 echo "=== Checking Emulator Performance ==="
444 adb shell cat /proc/cpuinfo | grep -i "model name" | head -1 || echo "Could not check CPU info"
445 adb shell cat /proc/meminfo | grep -i "memtotal" || echo "Could not check memory info"
446
447 echo "=== Checking Emulator Process ==="
448 ps aux | grep emulator | grep -v grep || echo "Emulator process not found in ps output"
449
450 echo "=== Making script executable ==="
451 chmod a+rx integration_test_runner.sh
452
453 echo "=== Running integration tests ==="
454
455 echo "Final emulator readiness check..."
456 /tmp/emulator_ready.sh || echo "Emulator readiness check failed, but continuing..."
457
458 echo "Disabling animations for test performance..."
459 adb shell settings put global window_animation_scale 0.0 || echo "Failed to disable window animations"
460 adb shell settings put global transition_animation_scale 0.0 || echo "Failed to disable transition animations"
461 adb shell settings put global animator_duration_scale 0.0 || echo "Failed to disable animator duration"
462
463 echo "Starting integration test runner..."
464 ./integration_test_runner.sh
465 TEST_EXIT_CODE=$?
466
467 if [ $TEST_EXIT_CODE -eq 0 ]; then
468 echo "Integration tests completed successfully"
469 else
470 echo "Integration tests failed with exit code $TEST_EXIT_CODE"
471 fi
472
473 - name: 🧹 Post-test cleanup
474 if: always()
475 run: |
476 echo "=== Post-test cleanup ==="
477 # Kill any remaining emulator processes
478 pkill -f emulator || echo "No emulator processes to kill"
479 # Kill any remaining adb processes
480 pkill -f adb || echo "No adb processes to kill"
481 # Wait for processes to terminate
482 sleep 2
483 # Check for any remaining processes
484 ps aux | grep -E "(emulator|adb)" | grep -v grep || echo "No remaining emulator/adb processes"
485 echo "=== Cleanup complete ==="
486 - name: cleanup
487 run: rm -rf build/app/outputs/flutter-apk/test-apk/