From 72417cf84a389fefaf4d02bf4c28b280adf70e31 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 16:59:15 +0300 Subject: [PATCH 01/26] Updated gradle to 9.5.0 --- gradle/wrapper/gradle-wrapper.properties | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c61a118f7..24ac9f37b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,11 @@ +# +# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com +# Contributors: denbond7 +# + distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-9.4.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-9.5.0-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME From 0c7473d61de97183500159d73311987ef1f9eb11 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 17:04:22 +0300 Subject: [PATCH 02/26] Updated CI scripts with --no-daemon, --build-cache, and --max-workers=2 flags --- .semaphore/semaphore.yml | 2 +- script/ci-instrumentation-tests-enterprise.sh | 7 ++++++- script/ci-instrumentation-tests-flaky.sh | 7 ++++++- script/ci-instrumentation-tests-with-mailserver.sh | 7 ++++++- script/ci-instrumentation-tests-without-mailserver.sh | 7 ++++++- script/ci-junit-tests.sh | 7 ++++++- script/ci-lint-checks.sh | 7 ++++++- 7 files changed, 37 insertions(+), 7 deletions(-) diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index f80cd11f2..e7b935f2d 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -79,7 +79,7 @@ blocks: # print Java version - java -version # compile project - - ./gradlew --console=plain assembleConsumerUiTests + - ./gradlew --console=plain --no-daemon --build-cache --max-workers=2 assembleConsumerUiTests epilogue: on_pass: commands: diff --git a/script/ci-instrumentation-tests-enterprise.sh b/script/ci-instrumentation-tests-enterprise.sh index b197fcb09..ca8bcc384 100755 --- a/script/ci-instrumentation-tests-enterprise.sh +++ b/script/ci-instrumentation-tests-enterprise.sh @@ -1,4 +1,9 @@ #!/bin/bash -./gradlew --console=plain :FlowCrypt:connectedEnterpriseUiTestsAndroidTest \ +# +# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com +# Contributors: denbond7 +# + +./gradlew --console=plain --no-daemon --build-cache --max-workers=2 --no-daemon --build-cache --max-workers=2 :FlowCrypt:connectedEnterpriseUiTestsAndroidTest \ -Pandroid.testInstrumentationRunnerArguments.filter=com.flowcrypt.email.junit.filters.EnterpriseTestsFilter diff --git a/script/ci-instrumentation-tests-flaky.sh b/script/ci-instrumentation-tests-flaky.sh index 706d3f24b..9fd35ced3 100755 --- a/script/ci-instrumentation-tests-flaky.sh +++ b/script/ci-instrumentation-tests-flaky.sh @@ -1,4 +1,9 @@ #!/bin/bash -./gradlew --console=plain :FlowCrypt:connectedEnterpriseUiTestsAndroidTest \ +# +# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com +# Contributors: denbond7 +# + +./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:connectedEnterpriseUiTestsAndroidTest \ -Pandroid.testInstrumentationRunnerArguments.filter=com.flowcrypt.email.junit.filters.ReadyForCIAndFlakyFilter diff --git a/script/ci-instrumentation-tests-with-mailserver.sh b/script/ci-instrumentation-tests-with-mailserver.sh index 41da56141..62f0184e0 100755 --- a/script/ci-instrumentation-tests-with-mailserver.sh +++ b/script/ci-instrumentation-tests-with-mailserver.sh @@ -1,10 +1,15 @@ #!/bin/bash +# +# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com +# Contributors: denbond7 +# + #print test names #adb shell am instrument -r -w \ # -e filter com.flowcrypt.email.junit.filters.DependsOnMailServerFilter \ # -e log true \ # com.flowcrypt.email.debug.test/androidx.test.runner.AndroidJUnitRunner -./gradlew --console=plain :FlowCrypt:connectedConsumerUiTestsAndroidTest \ +./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:connectedConsumerUiTestsAndroidTest \ -Pandroid.testInstrumentationRunnerArguments.filter=com.flowcrypt.email.junit.filters.DependsOnMailServerFilter diff --git a/script/ci-instrumentation-tests-without-mailserver.sh b/script/ci-instrumentation-tests-without-mailserver.sh index 778887d21..acdc12b48 100755 --- a/script/ci-instrumentation-tests-without-mailserver.sh +++ b/script/ci-instrumentation-tests-without-mailserver.sh @@ -1,5 +1,10 @@ #!/bin/bash +# +# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com +# Contributors: denbond7 +# + if [[ -z "$1" ]]; then echo "numShards is unset or set to the empty string" @@ -28,7 +33,7 @@ if [[ ${varShardIndex} -ge ${varNumShards} ]] # -e log true \ # com.flowcrypt.email.debug.test/androidx.test.runner.AndroidJUnitRunner - ./gradlew --console=plain :FlowCrypt:connectedConsumerUiTestsAndroidTest \ + ./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:connectedConsumerUiTestsAndroidTest \ -Pandroid.testInstrumentationRunnerArguments.filter=com.flowcrypt.email.junit.filters.DoesNotNeedMailServerFilter \ -Pandroid.testInstrumentationRunnerArguments.numShards="${varNumShards}" \ -Pandroid.testInstrumentationRunnerArguments.shardIndex="${varShardIndex}" diff --git a/script/ci-junit-tests.sh b/script/ci-junit-tests.sh index dfdcb6a2e..eeafac333 100755 --- a/script/ci-junit-tests.sh +++ b/script/ci-junit-tests.sh @@ -1,3 +1,8 @@ #!/bin/bash -./gradlew --console=plain :FlowCrypt:testConsumerUiTestsUnitTest +# +# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com +# Contributors: denbond7 +# + +./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:testConsumerUiTestsUnitTest diff --git a/script/ci-lint-checks.sh b/script/ci-lint-checks.sh index cdd01071a..28d447c36 100755 --- a/script/ci-lint-checks.sh +++ b/script/ci-lint-checks.sh @@ -1,3 +1,8 @@ #!/bin/bash -./gradlew --console=plain :FlowCrypt:lintConsumerUiTests +# +# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com +# Contributors: denbond7 +# + +./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:lintConsumerUiTests From cd861b6cf879043917dff1de557b2f3c325f72d6 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 17:17:42 +0300 Subject: [PATCH 03/26] Refactored Semaphore CI caching strategy and separated checksums --- .semaphore/semaphore.yml | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index e7b935f2d..e5898d748 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -46,21 +46,22 @@ global_job_config: - sudo rm -rf ~/.rbenv ~/.phpbrew - checkout # init environment variables - - export SUM=$(checksum build.gradle.kts)-$(checksum FlowCrypt/build.gradle.kts)-$(checksum ./script/ci-install-android-sdk.sh) - - export APP_GRADLE_CACHE=gradle-cache-$SUM # per conf files hash - - export ANDROID_SDK_CACHE=android-sdk-$SUM # per conf files hash - - export BUILD_CXX_CACHE=build-cxx-cache-$SEMAPHORE_GIT_BRANCH-$SUM # per branch and conf files hash - - export BUILD_NATIVE_CACHE=build-native-cache-$SEMAPHORE_GIT_BRANCH-$SUM # per branch and conf files hash - - export BUILD_CACHE=build-cache-$SEMAPHORE_GIT_BRANCH-$SUM # per branch and conf files hash + - export GRADLE_SUM=$(checksum build.gradle.kts)-$(checksum FlowCrypt/build.gradle.kts) + - export SDK_SUM=$(checksum ./script/ci-install-android-sdk.sh) + - export APP_GRADLE_CACHE=project-gradle-cache-$GRADLE_SUM # project .gradle cache, per Gradle config hash + - export ANDROID_SDK_CACHE=android-sdk-$SDK_SUM # Android SDK cache, per SDK installer hash + - export BUILD_CXX_CACHE=build-cxx-cache-$SEMAPHORE_GIT_BRANCH-$GRADLE_SUM # per branch and Gradle config hash + - export BUILD_NATIVE_CACHE=build-native-cache-$SEMAPHORE_GIT_BRANCH-$GRADLE_SUM # per branch and Gradle config hash # restore app caches - cache restore $APP_GRADLE_CACHE - cache restore $BUILD_CXX_CACHE - cache restore $BUILD_NATIVE_CACHE - - cache restore $BUILD_CACHE # restore global caches - cache restore $ANDROID_SDK_CACHE - cache restore gradle-wrapper + - cache restore gradle-cache-$GRADLE_SUM - cache restore gradle-cache + - cache restore android-build-cache-$GRADLE_SUM - cache restore android-build-cache # Install Android dependencies if needed - ./script/ci-install-android-sdk.sh @@ -88,18 +89,14 @@ blocks: - cache has_key $APP_GRADLE_CACHE || cache store $APP_GRADLE_CACHE .gradle - cache has_key $BUILD_CXX_CACHE || cache store $BUILD_CXX_CACHE FlowCrypt/.cxx - cache has_key $BUILD_NATIVE_CACHE || cache store $BUILD_NATIVE_CACHE FlowCrypt/.externalNativeBuild - - cache has_key $BUILD_CACHE || cache store $BUILD_CACHE FlowCrypt/build # clean and store global cache - echo "Store the global cache" - find ~/.gradle/caches/ -name "*.lock" -type f -delete # https://medium.com/cirruslabs/mastering-gradle-caching-and-incremental-builds-37eb1af7fcde - cache has_key $ANDROID_SDK_CACHE || cache store $ANDROID_SDK_CACHE $ANDROID_HOME - - cache delete gradle-wrapper - - cache delete gradle-cache - - cache delete android-build-cache - - cache store gradle-wrapper ~/.gradle/wrapper - - cache store gradle-cache ~/.gradle/caches - - cache store android-build-cache ~/.android/build-cache + - cache has_key gradle-wrapper || cache store gradle-wrapper ~/.gradle/wrapper + - cache has_key gradle-cache-$GRADLE_SUM || cache store gradle-cache-$GRADLE_SUM ~/.gradle/caches + - cache has_key android-build-cache-$GRADLE_SUM || cache store android-build-cache-$GRADLE_SUM ~/.android/build-cache - name: 'Testing' task: From bae1500baabadbd2571a0c1163b6cd4d8dd2e4a3 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 17:19:00 +0300 Subject: [PATCH 04/26] wip --- .semaphore/semaphore.yml | 58 ---------------------------------------- 1 file changed, 58 deletions(-) diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index e5898d748..48109cb59 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -101,51 +101,6 @@ blocks: - name: 'Testing' task: jobs: - - name: 'Lint(structural quality)' - execution_time_limit: - minutes: 15 - commands: - # run Lint checks - - ./script/ci-lint-checks.sh - - - name: 'JUnit tests' - execution_time_limit: - minutes: 15 - commands: - # run JUnit tests - - ./script/ci-junit-tests.sh - - - name: 'Instrumentation tests(No email server)' - execution_time_limit: - minutes: 60 - matrix: - - env_var: EMULATOR - values: [ "0", "1", "2", "3" ] - commands: - # Setup and run an emulator - - ./script/ci-setup-and-run-emulator.sh - # wait until ready - - ./script/ci-wait-for-emulator.sh - # Run filtered logging for TestRunner - - adb logcat -v color TestRunner:V *:S > ~/logcat_log.txt & - # Run instrumentation tests - - ./script/ci-instrumentation-tests-without-mailserver.sh 4 $EMULATOR - - - name: 'Instrumentation tests(with email server)' - execution_time_limit: - minutes: 60 - commands: - # Run an email server - - cd docker-mailserver && ./run_email_server.sh && cd - - # Setup and run an emulator - - ./script/ci-setup-and-run-emulator.sh - #wait until ready - - ./script/ci-wait-for-emulator.sh - # Run filtered logging for TestRunner - - adb logcat -v color TestRunner:V *:S > ~/logcat_log.txt & - # Run instrumentation tests - - ./script/ci-instrumentation-tests-with-mailserver.sh - - name: 'Instrumentation tests(enterprise)' execution_time_limit: minutes: 60 @@ -159,19 +114,6 @@ blocks: # Run instrumentation tests - ./script/ci-instrumentation-tests-enterprise.sh - - name: 'Instrumentation tests(flaky)' - execution_time_limit: - minutes: 60 - commands: - # Setup and run an emulator - - ./script/ci-setup-and-run-emulator.sh - #wait until ready - - ./script/ci-wait-for-emulator.sh - # Run filtered logging for TestRunner - - adb logcat -v color TestRunner:V *:S > ~/logcat_log.txt & - # Run instrumentation tests - - ./script/ci-instrumentation-tests-flaky.sh - epilogue: always: commands: From 5bcab0e9ebafc186e1a23b3ecbf0aa65f6edfa88 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 17:36:56 +0300 Subject: [PATCH 05/26] Refactored CI scripts for improved robustness and emulator handling - Updated shebangs to `#!/usr/bin/env bash` and added `set -euo pipefail` for better error handling. - Improved emulator setup in `ci-setup-and-run-emulator.sh` by ensuring a fresh AVD state and configuring hardware parameters like RAM and GPU. - Optimized `ci-wait-for-emulator.sh` with more reliable boot completion checks and a retry loop for internet connectivity. - Added existence checks for directories and files in artifact and test result publishing scripts to prevent errors when files are missing. - Cleaned up redundant script headers and refactored argument handling in instrumentation test scripts. --- ...ccess-actions-for-instrumentation-tests.sh | 28 +++++++---- ...-get-and-publish-debug-info-as-artifact.sh | 46 ++++++++++++------ script/ci-instrumentation-tests-enterprise.sh | 6 ++- script/ci-instrumentation-tests-flaky.sh | 4 +- ...i-instrumentation-tests-with-mailserver.sh | 4 +- ...nstrumentation-tests-without-mailserver.sh | 47 +++++++++---------- script/ci-junit-tests.sh | 4 +- script/ci-lint-checks.sh | 4 +- script/ci-publish-test-results.sh | 26 +++++++--- script/ci-setup-and-run-emulator.sh | 42 ++++++++++++++--- script/ci-wait-for-emulator.sh | 39 ++++++++++----- 11 files changed, 173 insertions(+), 77 deletions(-) diff --git a/script/ci-after-success-actions-for-instrumentation-tests.sh b/script/ci-after-success-actions-for-instrumentation-tests.sh index 599b26f38..c1a1552c5 100755 --- a/script/ci-after-success-actions-for-instrumentation-tests.sh +++ b/script/ci-after-success-actions-for-instrumentation-tests.sh @@ -1,18 +1,30 @@ -#!/bin/bash +#!/usr/bin/env bash + +# +# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com +# Contributors: denbond7 +# + +set -euo pipefail if [[ "$SEMAPHORE_JOB_NAME" =~ ^Instrumentation.* ]]; then # print debug info about connected device echo "Print connected devices" adb devices - # store logcat log + if [[ -f "$HOME/logcat_log.txt" ]]; then echo "Store logcat log" - artifact push job ~/logcat_log.txt + artifact push job "$HOME/logcat_log.txt" + else + echo "No logcat_log.txt found, skipping" + fi - # store screenshots - echo "Store screenshots" - adb pull "/sdcard/Pictures" - adb shell ls /sdcard/Pictures + echo "Store screenshots" + if adb shell test -d /sdcard/Pictures; then + rm -rf Pictures + adb pull "/sdcard/Pictures" Pictures artifact push job Pictures + else + echo "No /sdcard/Pictures directory found, skipping" + fi fi - diff --git a/script/ci-get-and-publish-debug-info-as-artifact.sh b/script/ci-get-and-publish-debug-info-as-artifact.sh index bf51181f9..1088399f1 100755 --- a/script/ci-get-and-publish-debug-info-as-artifact.sh +++ b/script/ci-get-and-publish-debug-info-as-artifact.sh @@ -1,23 +1,39 @@ -#!/bin/bash +#!/usr/bin/env bash + +# +# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com +# Contributors: denbond7 +# + +set -euo pipefail if [[ "$SEMAPHORE_JOB_NAME" =~ ^Lint.* ]]; then - # don't do any things for 'Lint(structural quality)' job - exit 0 + # Do nothing for 'Lint(structural quality)' job. + exit 0 fi -echo "Store tests results for $SEMAPHORE_JOB_NAME" -artifact push job FlowCrypt/build/reports/ +reports_dir="FlowCrypt/build/reports/" +if [[ -d "$reports_dir" ]]; then + echo "Store test reports for $SEMAPHORE_JOB_NAME" + artifact push job "$reports_dir" +else + echo "Reports directory does not exist: $reports_dir" +fi if [[ "$SEMAPHORE_JOB_NAME" =~ ^Instrumentation.* ]]; then - # store full logcat log - echo "Collect logcat logs as logcat.txt.gz for $SEMAPHORE_JOB_NAME" - adb logcat -d | gzip > ~/logcat.txt.gz - artifact push job ~/logcat.txt.gz + # store full logcat log + echo "Collect logcat logs as logcat.txt.gz for $SEMAPHORE_JOB_NAME" + adb logcat -d | gzip > "$HOME/logcat.txt.gz" + artifact push job "$HOME/logcat.txt.gz" - # store the device's screenshot. it may help to debug a failure - echo "Store the device's screenshot for $SEMAPHORE_JOB_NAME" - adb shell screencap -p /sdcard/screencap.png - adb pull "/sdcard/screencap.png" - artifact push job screencap.png + echo "Store the device's screenshot for $SEMAPHORE_JOB_NAME" + if adb shell screencap -p /sdcard/screencap.png; then + if adb pull "/sdcard/screencap.png"; then + artifact push job screencap.png + else + echo "Could not pull screencap.png" + fi + else + echo "Could not create screencap.png" + fi fi - diff --git a/script/ci-instrumentation-tests-enterprise.sh b/script/ci-instrumentation-tests-enterprise.sh index ca8bcc384..69b49d314 100755 --- a/script/ci-instrumentation-tests-enterprise.sh +++ b/script/ci-instrumentation-tests-enterprise.sh @@ -1,9 +1,11 @@ -#!/bin/bash +#!/usr/bin/env bash # # © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com # Contributors: denbond7 # -./gradlew --console=plain --no-daemon --build-cache --max-workers=2 --no-daemon --build-cache --max-workers=2 :FlowCrypt:connectedEnterpriseUiTestsAndroidTest \ +set -euo pipefail + +./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:connectedEnterpriseUiTestsAndroidTest \ -Pandroid.testInstrumentationRunnerArguments.filter=com.flowcrypt.email.junit.filters.EnterpriseTestsFilter diff --git a/script/ci-instrumentation-tests-flaky.sh b/script/ci-instrumentation-tests-flaky.sh index 9fd35ced3..13ec29982 100755 --- a/script/ci-instrumentation-tests-flaky.sh +++ b/script/ci-instrumentation-tests-flaky.sh @@ -1,9 +1,11 @@ -#!/bin/bash +#!/usr/bin/env bash # # © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com # Contributors: denbond7 # +set -euo pipefail + ./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:connectedEnterpriseUiTestsAndroidTest \ -Pandroid.testInstrumentationRunnerArguments.filter=com.flowcrypt.email.junit.filters.ReadyForCIAndFlakyFilter diff --git a/script/ci-instrumentation-tests-with-mailserver.sh b/script/ci-instrumentation-tests-with-mailserver.sh index 62f0184e0..b33bfbd0c 100755 --- a/script/ci-instrumentation-tests-with-mailserver.sh +++ b/script/ci-instrumentation-tests-with-mailserver.sh @@ -1,10 +1,12 @@ -#!/bin/bash +#!/usr/bin/env bash # # © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com # Contributors: denbond7 # +set -euo pipefail + #print test names #adb shell am instrument -r -w \ # -e filter com.flowcrypt.email.junit.filters.DependsOnMailServerFilter \ diff --git a/script/ci-instrumentation-tests-without-mailserver.sh b/script/ci-instrumentation-tests-without-mailserver.sh index acdc12b48..a78c53e56 100755 --- a/script/ci-instrumentation-tests-without-mailserver.sh +++ b/script/ci-instrumentation-tests-without-mailserver.sh @@ -1,40 +1,39 @@ -#!/bin/bash +#!/usr/bin/env bash # # © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com # Contributors: denbond7 # -if [[ -z "$1" ]]; - then +set -euo pipefail + +if [[ -z "${1:-}" ]]; then echo "numShards is unset or set to the empty string" exit 1 - else - varNumShards=$1 fi -if [[ -z "$2" ]]; - then +if [[ -z "${2:-}" ]]; then echo "shardIndex is unset or set to the empty string" exit 1 - else - varShardIndex=$2 fi -if [[ ${varShardIndex} -ge ${varNumShards} ]] - then +numShards="$1" +shardIndex="$2" + +if (( shardIndex >= numShards )); then echo "shardIndex should be lower than numShards" - else - #print test names - #adb shell am instrument -w \ - # -e filter com.flowcrypt.email.junit.filters.DoesNotNeedMailServerFilter \ - # -e numShards 3 \ - # -e shardIndex 1 \ - # -e log true \ - # com.flowcrypt.email.debug.test/androidx.test.runner.AndroidJUnitRunner - - ./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:connectedConsumerUiTestsAndroidTest \ - -Pandroid.testInstrumentationRunnerArguments.filter=com.flowcrypt.email.junit.filters.DoesNotNeedMailServerFilter \ - -Pandroid.testInstrumentationRunnerArguments.numShards="${varNumShards}" \ - -Pandroid.testInstrumentationRunnerArguments.shardIndex="${varShardIndex}" + exit 1 fi + +#print test names +#adb shell am instrument -w \ +# -e filter com.flowcrypt.email.junit.filters.DoesNotNeedMailServerFilter \ +# -e numShards 3 \ +# -e shardIndex 1 \ +# -e log true \ +# com.flowcrypt.email.debug.test/androidx.test.runner.AndroidJUnitRunner + +./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:connectedConsumerUiTestsAndroidTest \ + -Pandroid.testInstrumentationRunnerArguments.filter=com.flowcrypt.email.junit.filters.DoesNotNeedMailServerFilter \ + -Pandroid.testInstrumentationRunnerArguments.numShards="${numShards}" \ + -Pandroid.testInstrumentationRunnerArguments.shardIndex="${shardIndex}" diff --git a/script/ci-junit-tests.sh b/script/ci-junit-tests.sh index eeafac333..a07519f3a 100755 --- a/script/ci-junit-tests.sh +++ b/script/ci-junit-tests.sh @@ -1,8 +1,10 @@ -#!/bin/bash +#!/usr/bin/env bash # # © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com # Contributors: denbond7 # +set -euo pipefail + ./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:testConsumerUiTestsUnitTest diff --git a/script/ci-lint-checks.sh b/script/ci-lint-checks.sh index 28d447c36..88c328aee 100755 --- a/script/ci-lint-checks.sh +++ b/script/ci-lint-checks.sh @@ -1,8 +1,10 @@ -#!/bin/bash +#!/usr/bin/env bash # # © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com # Contributors: denbond7 # +set -euo pipefail + ./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:lintConsumerUiTests diff --git a/script/ci-publish-test-results.sh b/script/ci-publish-test-results.sh index 4c6622657..d5c21df8c 100755 --- a/script/ci-publish-test-results.sh +++ b/script/ci-publish-test-results.sh @@ -1,12 +1,26 @@ -#!/bin/bash +#!/usr/bin/env bash + +# +# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com +# Contributors: denbond7 +# + +set -euo pipefail if [[ "$SEMAPHORE_JOB_NAME" =~ ^Instrumentation.* ]]; then - # publish test results for Instrumentation tests - test-results publish ~/git/flowcrypt-android/FlowCrypt/build/outputs/androidTest-results/connected/ --name "$SEMAPHORE_JOB_NAME" + results_dir="$HOME/git/flowcrypt-android/FlowCrypt/build/outputs/androidTest-results/connected/" + if [[ -d "$results_dir" ]]; then + test-results publish "$results_dir" --name "$SEMAPHORE_JOB_NAME" + else + echo "Instrumentation test results directory does not exist: $results_dir" + fi fi if [[ "$SEMAPHORE_JOB_NAME" =~ ^JUnit.* ]]; then - # publish test results for JUnit tests - test-results publish ~/git/flowcrypt-android/FlowCrypt/build/test-results/ --name "$SEMAPHORE_JOB_NAME" + results_dir="$HOME/git/flowcrypt-android/FlowCrypt/build/test-results/" + if [[ -d "$results_dir" ]]; then + test-results publish "$results_dir" --name "$SEMAPHORE_JOB_NAME" + else + echo "JUnit test results directory does not exist: $results_dir" + fi fi - diff --git a/script/ci-setup-and-run-emulator.sh b/script/ci-setup-and-run-emulator.sh index 6df16d71f..368857243 100755 --- a/script/ci-setup-and-run-emulator.sh +++ b/script/ci-setup-and-run-emulator.sh @@ -1,15 +1,45 @@ -#!/bin/bash +#!/usr/bin/env bash # # © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com # Contributors: denbond7 # +set -euo pipefail + +AVD_NAME="ci-emulator" +SYSTEM_IMAGE="system-images;android-36;google_apis;x86_64" +DEVICE_NAME="pixel_9" +ABI="google_apis/x86_64" + "$ANDROID_HOME/emulator/emulator" -accel-check + +# Keep the emulator fresh for every CI job. Do not reuse AVD state. +rm -rf "$HOME/.android/avd/${AVD_NAME}.avd" "$HOME/.android/avd/${AVD_NAME}.ini" + avdmanager list devices #debug -echo -ne '\n' | avdmanager -v create avd --name ci-emulator --package "system-images;android-36;google_apis;x86_64" --device 'pixel_9' --abi 'google_apis/x86_64' -cat ~/.android/avd/ci-emulator.avd/config.ini -# echo "hw.ramSize=3064" >> ~/.android/avd/ci-emulator.avd/config.ini -# cat ~/.android/avd/ci-emulator.avd/config.ini + +echo -ne '\n' | avdmanager -v create avd \ + --name "$AVD_NAME" \ + --package "$SYSTEM_IMAGE" \ + --device "$DEVICE_NAME" \ + --abi "$ABI" + +# Keep RAM modest for e2-standard-2. This file belongs to the fresh AVD created above. +echo "hw.ramSize=2048" >> "$HOME/.android/avd/${AVD_NAME}.avd/config.ini" +cat "$HOME/.android/avd/${AVD_NAME}.avd/config.ini" + "$ANDROID_HOME/emulator/emulator" -list-avds #debug -"$ANDROID_HOME/emulator/emulator" -avd ci-emulator -no-snapshot -no-window -no-boot-anim -no-audio -gpu auto -read-only -no-metrics & + +"$ANDROID_HOME/emulator/emulator" \ + -avd "$AVD_NAME" \ + -no-window \ + -no-boot-anim \ + -no-audio \ + -no-snapshot \ + -no-snapshot-load \ + -no-snapshot-save \ + -wipe-data \ + -gpu swiftshader_indirect \ + -read-only \ + -no-metrics & diff --git a/script/ci-wait-for-emulator.sh b/script/ci-wait-for-emulator.sh index 6e622f643..316c70640 100755 --- a/script/ci-wait-for-emulator.sh +++ b/script/ci-wait-for-emulator.sh @@ -1,35 +1,50 @@ -#!/bin/bash +#!/usr/bin/env bash + # # © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com # Contributors: denbond7 # +set -euo pipefail set -o xtrace -adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done;' -adb shell wm dismiss-keyguard -sleep 1 + +adb wait-for-device +adb shell 'while [[ "$(getprop sys.boot_completed)" != "1" ]]; do sleep 1; done;' +adb shell wm dismiss-keyguard || true + adb shell settings put global window_animation_scale 0 adb shell settings put global transition_animation_scale 0 adb shell settings put global animator_duration_scale 0 ################################################################################################### -# to test WKD we need to route all traffic for localhost:443 to localhost:1212 +# To test WKD we need to route all traffic for localhost:443 to localhost:1212 # as we can't use 443 directly for a mock web server. +################################################################################################### adb root -# Need wait for the root environment -sleep 20 +adb wait-for-device +adb shell 'while [[ "$(getprop sys.boot_completed)" != "1" ]]; do sleep 1; done;' + adb shell "echo 1 > /proc/sys/net/ipv4/ip_forward" adb shell "iptables -t nat -A PREROUTING -s 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to 1212" adb shell "iptables -t nat -A OUTPUT -s 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to 1212" -################################################################################################### # https://developer.android.com/tools/adb#forwardports -# forwards requests on a specific host port to a different port on a device. -# It can be helpful for debugging a mock web server +# Forwards requests on a specific host port to a different port on a device. adb forward tcp:1212 tcp:1212 -#check the emulator has internet connection -adb shell "ping -c 1 www.google.com" +# Check that the emulator has internet connection. +for attempt in {1..5}; do + if adb shell "ping -c 1 www.google.com"; then + break + fi + + if [[ "$attempt" -eq 5 ]]; then + echo "Emulator has no internet connection" + exit 1 + fi + + sleep 2 +done echo "Emulator is ready" set +o xtrace From 3ffc7824bf7d801777d3d12b37b09c07f1dbc45d Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 17:41:16 +0300 Subject: [PATCH 06/26] Removed --max-workers=2 from CI scripts and semaphore configuration --- .semaphore/semaphore.yml | 2 +- script/ci-instrumentation-tests-enterprise.sh | 2 +- script/ci-instrumentation-tests-flaky.sh | 2 +- script/ci-instrumentation-tests-with-mailserver.sh | 2 +- script/ci-instrumentation-tests-without-mailserver.sh | 2 +- script/ci-junit-tests.sh | 2 +- script/ci-lint-checks.sh | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index 48109cb59..43e681f6c 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -80,7 +80,7 @@ blocks: # print Java version - java -version # compile project - - ./gradlew --console=plain --no-daemon --build-cache --max-workers=2 assembleConsumerUiTests + - ./gradlew --console=plain --no-daemon --build-cache assembleConsumerUiTests epilogue: on_pass: commands: diff --git a/script/ci-instrumentation-tests-enterprise.sh b/script/ci-instrumentation-tests-enterprise.sh index 69b49d314..ff179352e 100755 --- a/script/ci-instrumentation-tests-enterprise.sh +++ b/script/ci-instrumentation-tests-enterprise.sh @@ -7,5 +7,5 @@ set -euo pipefail -./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:connectedEnterpriseUiTestsAndroidTest \ +./gradlew --console=plain --no-daemon --build-cache :FlowCrypt:connectedEnterpriseUiTestsAndroidTest \ -Pandroid.testInstrumentationRunnerArguments.filter=com.flowcrypt.email.junit.filters.EnterpriseTestsFilter diff --git a/script/ci-instrumentation-tests-flaky.sh b/script/ci-instrumentation-tests-flaky.sh index 13ec29982..26f122293 100755 --- a/script/ci-instrumentation-tests-flaky.sh +++ b/script/ci-instrumentation-tests-flaky.sh @@ -7,5 +7,5 @@ set -euo pipefail -./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:connectedEnterpriseUiTestsAndroidTest \ +./gradlew --console=plain --no-daemon --build-cache :FlowCrypt:connectedEnterpriseUiTestsAndroidTest \ -Pandroid.testInstrumentationRunnerArguments.filter=com.flowcrypt.email.junit.filters.ReadyForCIAndFlakyFilter diff --git a/script/ci-instrumentation-tests-with-mailserver.sh b/script/ci-instrumentation-tests-with-mailserver.sh index b33bfbd0c..64f0d2998 100755 --- a/script/ci-instrumentation-tests-with-mailserver.sh +++ b/script/ci-instrumentation-tests-with-mailserver.sh @@ -13,5 +13,5 @@ set -euo pipefail # -e log true \ # com.flowcrypt.email.debug.test/androidx.test.runner.AndroidJUnitRunner -./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:connectedConsumerUiTestsAndroidTest \ +./gradlew --console=plain --no-daemon --build-cache :FlowCrypt:connectedConsumerUiTestsAndroidTest \ -Pandroid.testInstrumentationRunnerArguments.filter=com.flowcrypt.email.junit.filters.DependsOnMailServerFilter diff --git a/script/ci-instrumentation-tests-without-mailserver.sh b/script/ci-instrumentation-tests-without-mailserver.sh index a78c53e56..b904c77ac 100755 --- a/script/ci-instrumentation-tests-without-mailserver.sh +++ b/script/ci-instrumentation-tests-without-mailserver.sh @@ -33,7 +33,7 @@ fi # -e log true \ # com.flowcrypt.email.debug.test/androidx.test.runner.AndroidJUnitRunner -./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:connectedConsumerUiTestsAndroidTest \ +./gradlew --console=plain --no-daemon --build-cache :FlowCrypt:connectedConsumerUiTestsAndroidTest \ -Pandroid.testInstrumentationRunnerArguments.filter=com.flowcrypt.email.junit.filters.DoesNotNeedMailServerFilter \ -Pandroid.testInstrumentationRunnerArguments.numShards="${numShards}" \ -Pandroid.testInstrumentationRunnerArguments.shardIndex="${shardIndex}" diff --git a/script/ci-junit-tests.sh b/script/ci-junit-tests.sh index a07519f3a..31b13e0b7 100755 --- a/script/ci-junit-tests.sh +++ b/script/ci-junit-tests.sh @@ -7,4 +7,4 @@ set -euo pipefail -./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:testConsumerUiTestsUnitTest +./gradlew --console=plain --no-daemon --build-cache :FlowCrypt:testConsumerUiTestsUnitTest diff --git a/script/ci-lint-checks.sh b/script/ci-lint-checks.sh index 88c328aee..dab6d43eb 100755 --- a/script/ci-lint-checks.sh +++ b/script/ci-lint-checks.sh @@ -7,4 +7,4 @@ set -euo pipefail -./gradlew --console=plain --no-daemon --build-cache --max-workers=2 :FlowCrypt:lintConsumerUiTests +./gradlew --console=plain --no-daemon --build-cache :FlowCrypt:lintConsumerUiTests From 66a468b35ec96a1cd682a05d1f5abe3ccd40c9cf Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 17:47:57 +0300 Subject: [PATCH 07/26] Removed native and redundant build caches from Semaphore configuration --- .semaphore/semaphore.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index 43e681f6c..012d63274 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -50,19 +50,12 @@ global_job_config: - export SDK_SUM=$(checksum ./script/ci-install-android-sdk.sh) - export APP_GRADLE_CACHE=project-gradle-cache-$GRADLE_SUM # project .gradle cache, per Gradle config hash - export ANDROID_SDK_CACHE=android-sdk-$SDK_SUM # Android SDK cache, per SDK installer hash - - export BUILD_CXX_CACHE=build-cxx-cache-$SEMAPHORE_GIT_BRANCH-$GRADLE_SUM # per branch and Gradle config hash - - export BUILD_NATIVE_CACHE=build-native-cache-$SEMAPHORE_GIT_BRANCH-$GRADLE_SUM # per branch and Gradle config hash # restore app caches - cache restore $APP_GRADLE_CACHE - - cache restore $BUILD_CXX_CACHE - - cache restore $BUILD_NATIVE_CACHE # restore global caches - cache restore $ANDROID_SDK_CACHE - cache restore gradle-wrapper - cache restore gradle-cache-$GRADLE_SUM - - cache restore gradle-cache - - cache restore android-build-cache-$GRADLE_SUM - - cache restore android-build-cache # Install Android dependencies if needed - ./script/ci-install-android-sdk.sh # Install ninja @@ -87,8 +80,6 @@ blocks: # store app cache - echo "Store the app cache" - cache has_key $APP_GRADLE_CACHE || cache store $APP_GRADLE_CACHE .gradle - - cache has_key $BUILD_CXX_CACHE || cache store $BUILD_CXX_CACHE FlowCrypt/.cxx - - cache has_key $BUILD_NATIVE_CACHE || cache store $BUILD_NATIVE_CACHE FlowCrypt/.externalNativeBuild # clean and store global cache - echo "Store the global cache" @@ -96,7 +87,6 @@ blocks: - cache has_key $ANDROID_SDK_CACHE || cache store $ANDROID_SDK_CACHE $ANDROID_HOME - cache has_key gradle-wrapper || cache store gradle-wrapper ~/.gradle/wrapper - cache has_key gradle-cache-$GRADLE_SUM || cache store gradle-cache-$GRADLE_SUM ~/.gradle/caches - - cache has_key android-build-cache-$GRADLE_SUM || cache store android-build-cache-$GRADLE_SUM ~/.android/build-cache - name: 'Testing' task: From c3a92ab2a47d42c4a6e86e365130bf6ca00d5a45 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 18:09:44 +0300 Subject: [PATCH 08/26] Removed ninja-build installation from semaphore.yml --- .semaphore/semaphore.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index 012d63274..62c0ecb62 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -58,8 +58,6 @@ global_job_config: - cache restore gradle-cache-$GRADLE_SUM # Install Android dependencies if needed - ./script/ci-install-android-sdk.sh - # Install ninja - - sudo apt install -y ninja-build blocks: - name: 'Build' execution_time_limit: From 7b7ae48f0f1ea46b76cf44610e7e845a07e9693c Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 18:32:09 +0300 Subject: [PATCH 09/26] Configured emulator DNS server and added resolution checks in CI scripts --- script/ci-setup-and-run-emulator.sh | 3 ++- script/ci-wait-for-emulator.sh | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/script/ci-setup-and-run-emulator.sh b/script/ci-setup-and-run-emulator.sh index 368857243..59ace1392 100755 --- a/script/ci-setup-and-run-emulator.sh +++ b/script/ci-setup-and-run-emulator.sh @@ -42,4 +42,5 @@ cat "$HOME/.android/avd/${AVD_NAME}.avd/config.ini" -wipe-data \ -gpu swiftshader_indirect \ -read-only \ - -no-metrics & + -no-metrics \ + -dns-server 10.0.2.2 & diff --git a/script/ci-wait-for-emulator.sh b/script/ci-wait-for-emulator.sh index 316c70640..8c058edd5 100755 --- a/script/ci-wait-for-emulator.sh +++ b/script/ci-wait-for-emulator.sh @@ -32,6 +32,10 @@ adb shell "iptables -t nat -A OUTPUT -s 127.0.0.1 -p tcp --dport 443 -j REDIRECT # Forwards requests on a specific host port to a different port on a device. adb forward tcp:1212 tcp:1212 +# Print DNS configuration for easier CI debugging. +adb shell getprop net.dns1 || true +adb shell getprop net.dns2 || true + # Check that the emulator has internet connection. for attempt in {1..5}; do if adb shell "ping -c 1 www.google.com"; then @@ -46,5 +50,21 @@ for attempt in {1..5}; do sleep 2 done +# Check that Android emulator can resolve FlowCrypt test domains. +# Host-side dnsmasq resolving is not enough: the emulator has its own DNS configuration. +for attempt in {1..5}; do + if adb shell "ping -c 1 fes.flowcrypt.test"; then + break + fi + + if [[ "$attempt" -eq 5 ]]; then + echo "Emulator can't resolve fes.flowcrypt.test" + echo "Make sure ci-setup-and-run-emulator.sh starts emulator with: -dns-server 10.0.2.2" + exit 1 + fi + + sleep 2 +done + echo "Emulator is ready" -set +o xtrace +set +o xtrace \ No newline at end of file From b7704e1ee86246d50a3ac16da18db31f9f87f95b Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 18:40:25 +0300 Subject: [PATCH 10/26] Replaced -dns-server flag with /etc/hosts entries in emulator CI scripts --- script/ci-setup-and-run-emulator.sh | 3 +-- script/ci-wait-for-emulator.sh | 8 +++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/script/ci-setup-and-run-emulator.sh b/script/ci-setup-and-run-emulator.sh index 59ace1392..368857243 100755 --- a/script/ci-setup-and-run-emulator.sh +++ b/script/ci-setup-and-run-emulator.sh @@ -42,5 +42,4 @@ cat "$HOME/.android/avd/${AVD_NAME}.avd/config.ini" -wipe-data \ -gpu swiftshader_indirect \ -read-only \ - -no-metrics \ - -dns-server 10.0.2.2 & + -no-metrics & diff --git a/script/ci-wait-for-emulator.sh b/script/ci-wait-for-emulator.sh index 8c058edd5..66b8f8544 100755 --- a/script/ci-wait-for-emulator.sh +++ b/script/ci-wait-for-emulator.sh @@ -21,6 +21,13 @@ adb shell settings put global animator_duration_scale 0 # as we can't use 443 directly for a mock web server. ################################################################################################### adb root + +adb remount + +adb shell 'echo "10.0.2.2 fes.flowcrypt.test" >> /system/etc/hosts' +adb shell 'echo "10.0.2.2 fel.flowcrypt.test" >> /system/etc/hosts' +adb shell 'echo "10.0.2.2 fel.localhost" >> /system/etc/hosts' + adb wait-for-device adb shell 'while [[ "$(getprop sys.boot_completed)" != "1" ]]; do sleep 1; done;' @@ -59,7 +66,6 @@ for attempt in {1..5}; do if [[ "$attempt" -eq 5 ]]; then echo "Emulator can't resolve fes.flowcrypt.test" - echo "Make sure ci-setup-and-run-emulator.sh starts emulator with: -dns-server 10.0.2.2" exit 1 fi From b1fbe04025e4d28e1896502dcffd3198373fb03d Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 18:46:32 +0300 Subject: [PATCH 11/26] Removed hosts file modifications and adb remount from ci-wait-for-emulator.sh --- script/ci-wait-for-emulator.sh | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/script/ci-wait-for-emulator.sh b/script/ci-wait-for-emulator.sh index 66b8f8544..0d94995d4 100755 --- a/script/ci-wait-for-emulator.sh +++ b/script/ci-wait-for-emulator.sh @@ -9,6 +9,7 @@ set -euo pipefail set -o xtrace adb wait-for-device +# shellcheck disable=SC2016 adb shell 'while [[ "$(getprop sys.boot_completed)" != "1" ]]; do sleep 1; done;' adb shell wm dismiss-keyguard || true @@ -21,14 +22,8 @@ adb shell settings put global animator_duration_scale 0 # as we can't use 443 directly for a mock web server. ################################################################################################### adb root - -adb remount - -adb shell 'echo "10.0.2.2 fes.flowcrypt.test" >> /system/etc/hosts' -adb shell 'echo "10.0.2.2 fel.flowcrypt.test" >> /system/etc/hosts' -adb shell 'echo "10.0.2.2 fel.localhost" >> /system/etc/hosts' - adb wait-for-device +# shellcheck disable=SC2016 adb shell 'while [[ "$(getprop sys.boot_completed)" != "1" ]]; do sleep 1; done;' adb shell "echo 1 > /proc/sys/net/ipv4/ip_forward" From 50a6484bf624a952104a40fcf491e75aba69011b Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 18:56:33 +0300 Subject: [PATCH 12/26] Updated ci-wait-for-emulator.sh to restart adb if root fails --- script/ci-wait-for-emulator.sh | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/script/ci-wait-for-emulator.sh b/script/ci-wait-for-emulator.sh index 0d94995d4..ee2cf5949 100755 --- a/script/ci-wait-for-emulator.sh +++ b/script/ci-wait-for-emulator.sh @@ -21,7 +21,21 @@ adb shell settings put global animator_duration_scale 0 # To test WKD we need to route all traffic for localhost:443 to localhost:1212 # as we can't use 443 directly for a mock web server. ################################################################################################### -adb root + +adb root || { + echo "adb root failed, restarting adb and waiting for emulator..." + + adb kill-server || true + adb start-server + + adb wait-for-device + + # shellcheck disable=SC2016 + adb shell 'while [[ "$(getprop sys.boot_completed)" != "1" ]]; do sleep 1; done;' +} + +sleep 2 + adb wait-for-device # shellcheck disable=SC2016 adb shell 'while [[ "$(getprop sys.boot_completed)" != "1" ]]; do sleep 1; done;' From affd17ddc550368828dde01f114873dad8eac0a3 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 19:02:47 +0300 Subject: [PATCH 13/26] Updated ci-setup-and-run-emulator.sh to use avdmanager for AVD deletion --- script/ci-setup-and-run-emulator.sh | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/script/ci-setup-and-run-emulator.sh b/script/ci-setup-and-run-emulator.sh index 368857243..ad6d0c819 100755 --- a/script/ci-setup-and-run-emulator.sh +++ b/script/ci-setup-and-run-emulator.sh @@ -14,10 +14,19 @@ ABI="google_apis/x86_64" "$ANDROID_HOME/emulator/emulator" -accel-check -# Keep the emulator fresh for every CI job. Do not reuse AVD state. -rm -rf "$HOME/.android/avd/${AVD_NAME}.avd" "$HOME/.android/avd/${AVD_NAME}.ini" +# Keep the emulator fresh for every CI job. +# Remove existing AVD completely before creating a new one. +if avdmanager list avd | grep -q "Name: ${AVD_NAME}"; then + echo "Removing existing AVD: ${AVD_NAME}" -avdmanager list devices #debug + avdmanager delete avd --name "$AVD_NAME" || true +fi + +rm -rf \ + "$HOME/.android/avd/${AVD_NAME}.avd" \ + "$HOME/.android/avd/${AVD_NAME}.ini" + +#avdmanager list devices # debug echo -ne '\n' | avdmanager -v create avd \ --name "$AVD_NAME" \ @@ -25,11 +34,13 @@ echo -ne '\n' | avdmanager -v create avd \ --device "$DEVICE_NAME" \ --abi "$ABI" -# Keep RAM modest for e2-standard-2. This file belongs to the fresh AVD created above. +# Keep RAM modest for e2-standard-2. +# This file belongs to the fresh AVD created above. echo "hw.ramSize=2048" >> "$HOME/.android/avd/${AVD_NAME}.avd/config.ini" + cat "$HOME/.android/avd/${AVD_NAME}.avd/config.ini" -"$ANDROID_HOME/emulator/emulator" -list-avds #debug +#"$ANDROID_HOME/emulator/emulator" -list-avds # debug "$ANDROID_HOME/emulator/emulator" \ -avd "$AVD_NAME" \ From f60401a4f2fd713af05025664ec995a98a880904 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 19:05:15 +0300 Subject: [PATCH 14/26] Commented out debug logging in ci-setup-and-run-emulator.sh --- script/ci-setup-and-run-emulator.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/ci-setup-and-run-emulator.sh b/script/ci-setup-and-run-emulator.sh index ad6d0c819..710858b7a 100755 --- a/script/ci-setup-and-run-emulator.sh +++ b/script/ci-setup-and-run-emulator.sh @@ -38,7 +38,7 @@ echo -ne '\n' | avdmanager -v create avd \ # This file belongs to the fresh AVD created above. echo "hw.ramSize=2048" >> "$HOME/.android/avd/${AVD_NAME}.avd/config.ini" -cat "$HOME/.android/avd/${AVD_NAME}.avd/config.ini" +#cat "$HOME/.android/avd/${AVD_NAME}.avd/config.ini"# debug #"$ANDROID_HOME/emulator/emulator" -list-avds # debug From 2de6140b445ba6fc87092b08133bac9cf3a3dfc5 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 19:14:02 +0300 Subject: [PATCH 15/26] Added DNS initialization check to ci-wait-for-emulator.sh --- script/ci-wait-for-emulator.sh | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/script/ci-wait-for-emulator.sh b/script/ci-wait-for-emulator.sh index ee2cf5949..820a48868 100755 --- a/script/ci-wait-for-emulator.sh +++ b/script/ci-wait-for-emulator.sh @@ -40,6 +40,26 @@ adb wait-for-device # shellcheck disable=SC2016 adb shell 'while [[ "$(getprop sys.boot_completed)" != "1" ]]; do sleep 1; done;' +# Give Android connectivity service time to restore DNS after adb root/adbd restart. +for attempt in {1..30}; do + DNS1="$(adb shell getprop net.dns1 | tr -d '\r' || true)" + DNS2="$(adb shell getprop net.dns2 | tr -d '\r' || true)" + + echo "DNS attempt ${attempt}: net.dns1=${DNS1}, net.dns2=${DNS2}" + + if [[ -n "$DNS1" || -n "$DNS2" ]]; then + break + fi + + if [[ "$attempt" -eq 30 ]]; then + echo "Emulator DNS was not initialized after adb root" + adb shell dumpsys connectivity || true + exit 1 + fi + + sleep 2 +done + adb shell "echo 1 > /proc/sys/net/ipv4/ip_forward" adb shell "iptables -t nat -A PREROUTING -s 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to 1212" adb shell "iptables -t nat -A OUTPUT -s 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to 1212" From 3b48b9db1514c7300ab6f15e30f8516e2c9a8302 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 19:18:12 +0300 Subject: [PATCH 16/26] Updated ci-wait-for-emulator.sh to increase ping attempts and remove DNS property checks --- script/ci-wait-for-emulator.sh | 28 ++++------------------------ 1 file changed, 4 insertions(+), 24 deletions(-) diff --git a/script/ci-wait-for-emulator.sh b/script/ci-wait-for-emulator.sh index 820a48868..1b1835fca 100755 --- a/script/ci-wait-for-emulator.sh +++ b/script/ci-wait-for-emulator.sh @@ -40,26 +40,6 @@ adb wait-for-device # shellcheck disable=SC2016 adb shell 'while [[ "$(getprop sys.boot_completed)" != "1" ]]; do sleep 1; done;' -# Give Android connectivity service time to restore DNS after adb root/adbd restart. -for attempt in {1..30}; do - DNS1="$(adb shell getprop net.dns1 | tr -d '\r' || true)" - DNS2="$(adb shell getprop net.dns2 | tr -d '\r' || true)" - - echo "DNS attempt ${attempt}: net.dns1=${DNS1}, net.dns2=${DNS2}" - - if [[ -n "$DNS1" || -n "$DNS2" ]]; then - break - fi - - if [[ "$attempt" -eq 30 ]]; then - echo "Emulator DNS was not initialized after adb root" - adb shell dumpsys connectivity || true - exit 1 - fi - - sleep 2 -done - adb shell "echo 1 > /proc/sys/net/ipv4/ip_forward" adb shell "iptables -t nat -A PREROUTING -s 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to 1212" adb shell "iptables -t nat -A OUTPUT -s 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to 1212" @@ -73,12 +53,12 @@ adb shell getprop net.dns1 || true adb shell getprop net.dns2 || true # Check that the emulator has internet connection. -for attempt in {1..5}; do +for attempt in {1..30}; do if adb shell "ping -c 1 www.google.com"; then break fi - if [[ "$attempt" -eq 5 ]]; then + if [[ "$attempt" -eq 30 ]]; then echo "Emulator has no internet connection" exit 1 fi @@ -88,12 +68,12 @@ done # Check that Android emulator can resolve FlowCrypt test domains. # Host-side dnsmasq resolving is not enough: the emulator has its own DNS configuration. -for attempt in {1..5}; do +for attempt in {1..30}; do if adb shell "ping -c 1 fes.flowcrypt.test"; then break fi - if [[ "$attempt" -eq 5 ]]; then + if [[ "$attempt" -eq 30 ]]; then echo "Emulator can't resolve fes.flowcrypt.test" exit 1 fi From 0352bb8bd1e645b8348b476e680e74f95a9a530c Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 20:01:39 +0300 Subject: [PATCH 17/26] Added network diagnostic logging and improved ping verification in ci-wait-for-emulator.sh --- script/ci-wait-for-emulator.sh | 99 +++++++++++++++++++--------------- 1 file changed, 57 insertions(+), 42 deletions(-) diff --git a/script/ci-wait-for-emulator.sh b/script/ci-wait-for-emulator.sh index 1b1835fca..ea2c22626 100755 --- a/script/ci-wait-for-emulator.sh +++ b/script/ci-wait-for-emulator.sh @@ -8,15 +8,60 @@ set -euo pipefail set -o xtrace -adb wait-for-device -# shellcheck disable=SC2016 -adb shell 'while [[ "$(getprop sys.boot_completed)" != "1" ]]; do sleep 1; done;' +wait_for_boot_completed() { + adb wait-for-device + + # shellcheck disable=SC2016 + adb shell 'while [[ "$(getprop sys.boot_completed)" != "1" ]]; do sleep 1; done;' +} + +print_network_debug() { + local label="$1" + + echo "========== Network debug: ${label} ==========" + + adb devices || true + adb shell getprop net.dns1 || true + adb shell getprop net.dns2 || true + adb shell ip route || true + adb shell ip addr || true + adb shell iptables -t nat -S || true + adb forward --list || true + + echo "========== End network debug: ${label} ==========" +} + +check_ping_or_fail() { + local host="$1" + local label="$2" + + for attempt in {1..30}; do + if adb shell "ping -c 1 ${host}"; then + return 0 + fi + + if [[ "$attempt" -eq 30 ]]; then + echo "Failed to ping ${host}: ${label}" + print_network_debug "ping failed: ${host}" + exit 1 + fi + + sleep 2 + done +} + +wait_for_boot_completed + adb shell wm dismiss-keyguard || true adb shell settings put global window_animation_scale 0 adb shell settings put global transition_animation_scale 0 adb shell settings put global animator_duration_scale 0 +print_network_debug "before adb root" +check_ping_or_fail "www.google.com" "internet before adb root" +check_ping_or_fail "fes.flowcrypt.test" "flowcrypt.test before adb root" + ################################################################################################### # To test WKD we need to route all traffic for localhost:443 to localhost:1212 # as we can't use 443 directly for a mock web server. @@ -28,19 +73,18 @@ adb root || { adb kill-server || true adb start-server - adb wait-for-device - - # shellcheck disable=SC2016 - adb shell 'while [[ "$(getprop sys.boot_completed)" != "1" ]]; do sleep 1; done;' + wait_for_boot_completed } sleep 2 +wait_for_boot_completed -adb wait-for-device -# shellcheck disable=SC2016 -adb shell 'while [[ "$(getprop sys.boot_completed)" != "1" ]]; do sleep 1; done;' +print_network_debug "after adb root" +check_ping_or_fail "www.google.com" "internet after adb root" +check_ping_or_fail "fes.flowcrypt.test" "flowcrypt.test after adb root" adb shell "echo 1 > /proc/sys/net/ipv4/ip_forward" + adb shell "iptables -t nat -A PREROUTING -s 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to 1212" adb shell "iptables -t nat -A OUTPUT -s 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to 1212" @@ -48,38 +92,9 @@ adb shell "iptables -t nat -A OUTPUT -s 127.0.0.1 -p tcp --dport 443 -j REDIRECT # Forwards requests on a specific host port to a different port on a device. adb forward tcp:1212 tcp:1212 -# Print DNS configuration for easier CI debugging. -adb shell getprop net.dns1 || true -adb shell getprop net.dns2 || true - -# Check that the emulator has internet connection. -for attempt in {1..30}; do - if adb shell "ping -c 1 www.google.com"; then - break - fi - - if [[ "$attempt" -eq 30 ]]; then - echo "Emulator has no internet connection" - exit 1 - fi - - sleep 2 -done - -# Check that Android emulator can resolve FlowCrypt test domains. -# Host-side dnsmasq resolving is not enough: the emulator has its own DNS configuration. -for attempt in {1..30}; do - if adb shell "ping -c 1 fes.flowcrypt.test"; then - break - fi - - if [[ "$attempt" -eq 30 ]]; then - echo "Emulator can't resolve fes.flowcrypt.test" - exit 1 - fi - - sleep 2 -done +print_network_debug "after iptables and adb forward" +check_ping_or_fail "www.google.com" "internet after iptables" +check_ping_or_fail "fes.flowcrypt.test" "flowcrypt.test after iptables" echo "Emulator is ready" set +o xtrace \ No newline at end of file From 5117b2fa3ae276f5ce5d65e60a85534bbeba98c3 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 21:34:57 +0300 Subject: [PATCH 18/26] Enabled HTTP logging and updated CI configuration to run debug instrumentation tests --- .semaphore/semaphore.yml | 4 ++-- FlowCrypt/build.gradle.kts | 10 ++++------ .../ui/gmailapi/SearchMessagesGmailApiFlowTest.kt | 2 ++ script/ci-instrumentation-tests-flaky.sh | 2 +- script/ci-wait-for-emulator.sh | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index 62c0ecb62..b446e55f1 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -89,7 +89,7 @@ blocks: - name: 'Testing' task: jobs: - - name: 'Instrumentation tests(enterprise)' + - name: 'Instrumentation tests(debug)' execution_time_limit: minutes: 60 commands: @@ -100,7 +100,7 @@ blocks: # Run filtered logging for TestRunner - adb logcat -v color TestRunner:V *:S > ~/logcat_log.txt & # Run instrumentation tests - - ./script/ci-instrumentation-tests-enterprise.sh + - ./script/ci-instrumentation-tests-flaky.sh epilogue: always: diff --git a/FlowCrypt/build.gradle.kts b/FlowCrypt/build.gradle.kts index e8179f29a..6f37c4d0f 100644 --- a/FlowCrypt/build.gradle.kts +++ b/FlowCrypt/build.gradle.kts @@ -6,8 +6,6 @@ import com.android.build.api.artifact.SingleArtifact import com.android.build.api.variant.ResValue -import org.gradle.api.GradleException -import java.io.File import com.android.ddmlib.DdmPreferences import java.io.FileInputStream import java.text.SimpleDateFormat @@ -127,10 +125,10 @@ android { "SHARED_TENANT_FES_URL", "\"https://flowcrypt.test/shared-tenant-fes/\"" ) - buildConfigField("boolean", "IS_HTTP_LOG_ENABLED", "false") - buildConfigField("String", "HTTP_LOG_LEVEL", "\"NONE\"") - resValue("string", "gradle_is_http_log_enabled", "false") - resValue("string", "gradle_http_log_level", "NONE") + buildConfigField("boolean", "IS_HTTP_LOG_ENABLED", "true") + buildConfigField("String", "HTTP_LOG_LEVEL", "\"BODY\"") + resValue("string", "gradle_is_http_log_enabled", "true") + resValue("string", "gradle_http_log_level", "BODY") } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/gmailapi/SearchMessagesGmailApiFlowTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/gmailapi/SearchMessagesGmailApiFlowTest.kt index cc7ff3377..9b3cd5895 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/gmailapi/SearchMessagesGmailApiFlowTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/gmailapi/SearchMessagesGmailApiFlowTest.kt @@ -20,6 +20,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.MediumTest import com.flowcrypt.email.R import com.flowcrypt.email.TestConstants +import com.flowcrypt.email.junit.annotations.DebugTest import com.flowcrypt.email.junit.annotations.FlowCryptTestSettings import com.flowcrypt.email.matchers.CustomMatchers.Companion.withRecyclerViewItemCount import com.flowcrypt.email.rules.ClearAppSettingsRule @@ -49,6 +50,7 @@ import java.util.concurrent.TimeUnit @MediumTest @RunWith(AndroidJUnit4::class) @FlowCryptTestSettings(useCommonIdling = false) +@DebugTest class SearchMessagesGmailApiFlowTest : BaseGmailApiTest() { override val mockWebServerRule = diff --git a/script/ci-instrumentation-tests-flaky.sh b/script/ci-instrumentation-tests-flaky.sh index 26f122293..328a437db 100755 --- a/script/ci-instrumentation-tests-flaky.sh +++ b/script/ci-instrumentation-tests-flaky.sh @@ -8,4 +8,4 @@ set -euo pipefail ./gradlew --console=plain --no-daemon --build-cache :FlowCrypt:connectedEnterpriseUiTestsAndroidTest \ - -Pandroid.testInstrumentationRunnerArguments.filter=com.flowcrypt.email.junit.filters.ReadyForCIAndFlakyFilter + -Pandroid.testInstrumentationRunnerArguments.filter=com.flowcrypt.email.junit.filters.DebugTestsFilter diff --git a/script/ci-wait-for-emulator.sh b/script/ci-wait-for-emulator.sh index ea2c22626..be807eb02 100755 --- a/script/ci-wait-for-emulator.sh +++ b/script/ci-wait-for-emulator.sh @@ -35,7 +35,7 @@ check_ping_or_fail() { local host="$1" local label="$2" - for attempt in {1..30}; do + for attempt in {1..10}; do if adb shell "ping -c 1 ${host}"; then return 0 fi @@ -43,7 +43,7 @@ check_ping_or_fail() { if [[ "$attempt" -eq 30 ]]; then echo "Failed to ping ${host}: ${label}" print_network_debug "ping failed: ${host}" - exit 1 + #exit 1 fi sleep 2 From 6c80d2e0dd1c0edd3501b4f9ada75f22ad1eb09a Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sun, 10 May 2026 22:26:55 +0300 Subject: [PATCH 19/26] Refactored ci-wait-for-emulator.sh to improve network setup and verification --- script/ci-wait-for-emulator.sh | 78 +++++++++++++++++----------------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/script/ci-wait-for-emulator.sh b/script/ci-wait-for-emulator.sh index be807eb02..ae06bea29 100755 --- a/script/ci-wait-for-emulator.sh +++ b/script/ci-wait-for-emulator.sh @@ -15,41 +15,35 @@ wait_for_boot_completed() { adb shell 'while [[ "$(getprop sys.boot_completed)" != "1" ]]; do sleep 1; done;' } -print_network_debug() { - local label="$1" - - echo "========== Network debug: ${label} ==========" - - adb devices || true - adb shell getprop net.dns1 || true - adb shell getprop net.dns2 || true - adb shell ip route || true - adb shell ip addr || true - adb shell iptables -t nat -S || true - adb forward --list || true - - echo "========== End network debug: ${label} ==========" -} - check_ping_or_fail() { local host="$1" local label="$2" - for attempt in {1..10}; do + for attempt in {1..30}; do if adb shell "ping -c 1 ${host}"; then return 0 fi if [[ "$attempt" -eq 30 ]]; then echo "Failed to ping ${host}: ${label}" - print_network_debug "ping failed: ${host}" - #exit 1 + exit 1 fi sleep 2 done } +check_iptables_rule_or_fail() { + local chain="$1" + local expected_rule="$2" + + if ! adb shell "iptables -t nat -S ${chain}" | grep -F -- "${expected_rule}"; then + echo "iptables rule was not applied:" + echo "${expected_rule}" + exit 1 + fi +} + wait_for_boot_completed adb shell wm dismiss-keyguard || true @@ -58,43 +52,51 @@ adb shell settings put global window_animation_scale 0 adb shell settings put global transition_animation_scale 0 adb shell settings put global animator_duration_scale 0 -print_network_debug "before adb root" -check_ping_or_fail "www.google.com" "internet before adb root" -check_ping_or_fail "fes.flowcrypt.test" "flowcrypt.test before adb root" - ################################################################################################### # To test WKD we need to route all traffic for localhost:443 to localhost:1212 # as we can't use 443 directly for a mock web server. ################################################################################################### - -adb root || { +if adb root; then + echo "adb root succeeded" +else echo "adb root failed, restarting adb and waiting for emulator..." adb kill-server || true adb start-server +fi - wait_for_boot_completed -} - -sleep 2 wait_for_boot_completed -print_network_debug "after adb root" -check_ping_or_fail "www.google.com" "internet after adb root" -check_ping_or_fail "fes.flowcrypt.test" "flowcrypt.test after adb root" - adb shell "echo 1 > /proc/sys/net/ipv4/ip_forward" -adb shell "iptables -t nat -A PREROUTING -s 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to 1212" -adb shell "iptables -t nat -A OUTPUT -s 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to 1212" +adb shell "iptables -t nat -D OUTPUT -s 127.0.0.1/32 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 1212" || true +adb shell "iptables -t nat -D PREROUTING -s 127.0.0.1/32 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 1212" || true + +adb shell "iptables -t nat -A PREROUTING -s 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to-ports 1212" +adb shell "iptables -t nat -A OUTPUT -s 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to-ports 1212" + +check_iptables_rule_or_fail \ + "PREROUTING" \ + "-A PREROUTING -s 127.0.0.1/32 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 1212" + +check_iptables_rule_or_fail \ + "OUTPUT" \ + "-A OUTPUT -s 127.0.0.1/32 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 1212" +################################################################################################### # https://developer.android.com/tools/adb#forwardports # Forwards requests on a specific host port to a different port on a device. +# It can be helpful for debugging a mock web server +adb forward --remove tcp:1212 || true adb forward tcp:1212 tcp:1212 +if ! adb forward --list | grep -F -- "tcp:1212 tcp:1212"; then + echo "adb forward was not applied: tcp:1212 tcp:1212" + exit 1 +fi -print_network_debug "after iptables and adb forward" -check_ping_or_fail "www.google.com" "internet after iptables" -check_ping_or_fail "fes.flowcrypt.test" "flowcrypt.test after iptables" +################################################################################################### +check_ping_or_fail "www.google.com" "internet connection" +check_ping_or_fail "fes.flowcrypt.test" "flowcrypt.test after iptables and adb forward" echo "Emulator is ready" set +o xtrace \ No newline at end of file From a2f4c8165332cadad054398767b67a5c29fde499 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Mon, 11 May 2026 08:32:35 +0300 Subject: [PATCH 20/26] Added CI failure debug script and updated Semaphore configuration --- .semaphore/semaphore.yml | 2 ++ script/ci-after-fail-debug.sh | 33 +++++++++++++++++++++++++++++++++ script/ci-wait-for-emulator.sh | 1 - 3 files changed, 35 insertions(+), 1 deletion(-) create mode 100755 script/ci-after-fail-debug.sh diff --git a/.semaphore/semaphore.yml b/.semaphore/semaphore.yml index b446e55f1..ec0b65446 100644 --- a/.semaphore/semaphore.yml +++ b/.semaphore/semaphore.yml @@ -115,6 +115,8 @@ blocks: commands: # collect and store debug info as artifacts - ./script/ci-get-and-publish-debug-info-as-artifact.sh + # print debug info + - ./script/ci-after-fail-debug.sh after_pipeline: task: diff --git a/script/ci-after-fail-debug.sh b/script/ci-after-fail-debug.sh new file mode 100755 index 000000000..5d6b49676 --- /dev/null +++ b/script/ci-after-fail-debug.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +# +# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com +# Contributors: denbond7 +# + +set -euo pipefail +set -o xtrace + +check_ping_or_fail() { + local host="$1" + local label="$2" + + for attempt in {1..30}; do + if adb shell "ping -c 1 ${host}"; then + return 0 + fi + + if [[ "$attempt" -eq 30 ]]; then + echo "Failed to ping ${host}: ${label}" + exit 1 + fi + + sleep 2 + done +} + +################################################################################################### +check_ping_or_fail "www.google.com" "internet connection" +check_ping_or_fail "fes.flowcrypt.test" "flowcrypt.test forwarding" + +set +o xtrace \ No newline at end of file diff --git a/script/ci-wait-for-emulator.sh b/script/ci-wait-for-emulator.sh index ae06bea29..69fbdf567 100755 --- a/script/ci-wait-for-emulator.sh +++ b/script/ci-wait-for-emulator.sh @@ -96,7 +96,6 @@ fi ################################################################################################### check_ping_or_fail "www.google.com" "internet connection" -check_ping_or_fail "fes.flowcrypt.test" "flowcrypt.test after iptables and adb forward" echo "Emulator is ready" set +o xtrace \ No newline at end of file From 0d1b07f872cbc34dd298eaae6fb53d193412adf1 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sat, 16 May 2026 13:00:06 +0300 Subject: [PATCH 21/26] Add Ubuntu 24.04 Docker image for Android emulator SDK environment --- docker/TestEnvironment/Dockerfile | 66 ++++++++++++++++++++++++++++ docker/TestEnvironment/README.md | 49 +++++++++++++++++++++ docker/TestEnvironment/create-avd.sh | 33 ++++++++++++++ script/ci-install-android-sdk.sh | 23 +++++++--- 4 files changed, 164 insertions(+), 7 deletions(-) create mode 100644 docker/TestEnvironment/Dockerfile create mode 100644 docker/TestEnvironment/README.md create mode 100644 docker/TestEnvironment/create-avd.sh diff --git a/docker/TestEnvironment/Dockerfile b/docker/TestEnvironment/Dockerfile new file mode 100644 index 000000000..22414e131 --- /dev/null +++ b/docker/TestEnvironment/Dockerfile @@ -0,0 +1,66 @@ +FROM ubuntu:24.04 + +ARG DEBIAN_FRONTEND=noninteractive +ARG ANDROID_PLATFORM=android-36 +ARG ANDROID_SYSTEM_IMAGE=system-images;android-36;google_apis;x86_64 +ARG ANDROID_BUILD_TOOLS=36.0.0 + +ENV JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64 +ENV ANDROID_HOME=/opt/android-sdk +ENV ANDROID_SDK_ROOT=/opt/android-sdk +ENV ANDROID_AVD_HOME=/opt/android-avd +ENV PATH=/opt/android-sdk/emulator:/opt/android-sdk/platform-tools:/opt/android-sdk/cmdline-tools/latest/bin:/usr/lib/jvm/java-21-openjdk-amd64/bin:${PATH} + +RUN apt-get update && apt-get install -y --no-install-recommends \ + bash \ + ca-certificates \ + curl \ + dnsutils \ + git \ + libasound2t64 \ + libc6 \ + libc6-dev \ + libdbus-1-3 \ + libfontconfig1 \ + libgcc-s1 \ + libgl1 \ + libglu1-mesa \ + libnspr4 \ + libnss3 \ + libpulse0 \ + libstdc++6 \ + libu2f-udev \ + libx11-6 \ + libx11-xcb1 \ + libxcb1 \ + libxcursor1 \ + libxdamage1 \ + libxext6 \ + libxi6 \ + libxkbcommon0 \ + libxrandr2 \ + libxrender1 \ + libxtst6 \ + openjdk-21-jdk \ + sudo \ + unzip \ + wget \ + && rm -rf /var/lib/apt/lists/* + +COPY script/ci-install-android-sdk.sh /tmp/ci-install-android-sdk.sh +RUN chmod +x /tmp/ci-install-android-sdk.sh \ + && mkdir -p "${ANDROID_AVD_HOME}" \ + && ANDROID_PLATFORM="${ANDROID_PLATFORM}" \ + ANDROID_SYSTEM_IMAGE="${ANDROID_SYSTEM_IMAGE}" \ + ANDROID_BUILD_TOOLS="${ANDROID_BUILD_TOOLS}" \ + RUN_KVM_CHECK=0 \ + /tmp/ci-install-android-sdk.sh \ + && sdkmanager --list_installed \ + && rm -f /tmp/ci-install-android-sdk.sh + +COPY docker/TestEnvironment/create-avd.sh /usr/local/bin/create-avd.sh +RUN chmod +x /usr/local/bin/create-avd.sh + +WORKDIR /workspace + +CMD ["/bin/bash"] diff --git a/docker/TestEnvironment/README.md b/docker/TestEnvironment/README.md new file mode 100644 index 000000000..e8ab049f7 --- /dev/null +++ b/docker/TestEnvironment/README.md @@ -0,0 +1,49 @@ +# Test Environment Docker Image + +This directory contains a Docker context for a headless Android test environment based on +`ubuntu:24.04`. + +The image installs: + +- OpenJDK 21 +- Android SDK command-line tools +- `platform-tools` +- Android Emulator +- Android platform `android-36` +- Build tools `36.0.0` +- System image `system-images;android-36;google_apis;x86_64` + +## Build + +```bash +docker build -t flowcrypt-android-test-env -f docker/TestEnvironment/Dockerfile . +``` + +## Create an AVD inside the container + +```bash +docker run --rm -it flowcrypt-android-test-env create-avd.sh +``` + +## Run the emulator inside the container + +The container includes the emulator binaries, but actual emulator launch usually needs: + +- `/dev/kvm` passed through to the container +- additional Docker flags such as `--device /dev/kvm` + +Example: + +```bash +docker run --rm -it \ + --device /dev/kvm \ + flowcrypt-android-test-env \ + bash +``` + +Then inside the container: + +```bash +create-avd.sh +emulator -avd ci-emulator -no-window -no-boot-anim -no-audio -gpu swiftshader_indirect +``` diff --git a/docker/TestEnvironment/create-avd.sh b/docker/TestEnvironment/create-avd.sh new file mode 100644 index 000000000..0fcc57554 --- /dev/null +++ b/docker/TestEnvironment/create-avd.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +# +# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com +# Contributors: denbond7 +# + +set -euo pipefail + +AVD_NAME="${AVD_NAME:-ci-emulator}" +SYSTEM_IMAGE="${SYSTEM_IMAGE:-system-images;android-36;google_apis;x86_64}" +DEVICE_NAME="${DEVICE_NAME:-pixel_9}" +ABI="${ABI:-google_apis/x86_64}" + +mkdir -p "${ANDROID_AVD_HOME:-$HOME/.android/avd}" "$HOME/.android" +touch "$HOME/.android/repositories.cfg" + +if avdmanager list avd | grep -q "Name: ${AVD_NAME}"; then + avdmanager delete avd --name "${AVD_NAME}" || true +fi + +rm -rf \ + "${ANDROID_AVD_HOME:-$HOME/.android/avd}/${AVD_NAME}.avd" \ + "${ANDROID_AVD_HOME:-$HOME/.android/avd}/${AVD_NAME}.ini" + +echo "no" | avdmanager create avd \ + --force \ + --name "${AVD_NAME}" \ + --package "${SYSTEM_IMAGE}" \ + --device "${DEVICE_NAME}" \ + --abi "${ABI}" + +echo "Created AVD ${AVD_NAME}" diff --git a/script/ci-install-android-sdk.sh b/script/ci-install-android-sdk.sh index 084866507..123fec611 100755 --- a/script/ci-install-android-sdk.sh +++ b/script/ci-install-android-sdk.sh @@ -22,11 +22,15 @@ fi # ----------------------------- export ANDROID_HOME="${ANDROID_HOME:-$HOME/Android/Sdk}" export ANDROID_SDK_ROOT="${ANDROID_SDK_ROOT:-$ANDROID_HOME}" +RUN_KVM_CHECK="${RUN_KVM_CHECK:-1}" +ANDROID_PLATFORM="${ANDROID_PLATFORM:-android-36}" +ANDROID_SYSTEM_IMAGE="${ANDROID_SYSTEM_IMAGE:-system-images;android-36;google_apis;x86_64}" +ANDROID_BUILD_TOOLS="${ANDROID_BUILD_TOOLS:-}" # ----------------------------- # Pin cmdline-tools archive here # ----------------------------- -SDK_ARCHIVE="commandlinetools-linux-14742923_latest.zip" +SDK_ARCHIVE="${SDK_ARCHIVE:-commandlinetools-linux-14742923_latest.zip}" # ------------------------------------------------------------ # Check that SDK_ARCHIVE is the latest Android cmdline-tools @@ -87,15 +91,17 @@ check_cmdline_tools_latest_or_fail # KVM deps (as in your script) # ----------------------------- sudo apt-get -qq install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils > /dev/null -sudo kvm-ok +if [[ "$RUN_KVM_CHECK" == "1" ]]; then + sudo kvm-ok +fi # ----------------------------- # Install SDK if ~/Android doesn't exist (as in your script) # ----------------------------- -if [[ -d "$HOME/Android" ]]; then - echo "$HOME/Android already exists, skipping installation" +if [[ -x "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" ]]; then + echo "$ANDROID_HOME already exists, skipping installation" else - echo "$HOME/Android does not exist, installing" + echo "$ANDROID_HOME does not exist, installing" mkdir -p "$ANDROID_HOME" # download, unpack and remove sdk archive @@ -122,10 +128,13 @@ else # Install Android SDK (echo "yes" | "${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" --licenses > /dev/null | grep -v = || true) - ( sleep 5; echo "y" ) | ("${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "platforms;android-36" > /dev/null | grep -v = || true) + ( sleep 5; echo "y" ) | ("${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "platforms;${ANDROID_PLATFORM}" > /dev/null | grep -v = || true) ("${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "platform-tools" | grep -v = || true) ("${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "emulator" | grep -v = || true) - (echo "y" | "${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "system-images;android-36;google_apis;x86_64" > /dev/null | grep -v = || true) + if [[ -n "$ANDROID_BUILD_TOOLS" ]]; then + ("${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "build-tools;${ANDROID_BUILD_TOOLS}" | grep -v = || true) + fi + (echo "y" | "${ANDROID_HOME}/cmdline-tools/latest/bin/sdkmanager" "${ANDROID_SYSTEM_IMAGE}" > /dev/null | grep -v = || true) fi # Uncomment this for debug From c7ae7df86a686f3b2c61aadfdb223f2ec0ddb1d0 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sat, 16 May 2026 13:08:23 +0300 Subject: [PATCH 22/26] Refactor Android emulator setup into shared scripts --- docker/TestEnvironment/Dockerfile | 6 ++-- docker/TestEnvironment/README.md | 11 ++++-- docker/TestEnvironment/create-avd.sh | 33 ------------------ script/ci-setup-and-run-emulator.sh | 52 +++------------------------- script/create-avd.sh | 40 +++++++++++++++++++++ script/run-emulator.sh | 37 ++++++++++++++++++++ 6 files changed, 94 insertions(+), 85 deletions(-) delete mode 100644 docker/TestEnvironment/create-avd.sh create mode 100755 script/create-avd.sh create mode 100755 script/run-emulator.sh diff --git a/docker/TestEnvironment/Dockerfile b/docker/TestEnvironment/Dockerfile index 22414e131..2ea9f705b 100644 --- a/docker/TestEnvironment/Dockerfile +++ b/docker/TestEnvironment/Dockerfile @@ -58,8 +58,10 @@ RUN chmod +x /tmp/ci-install-android-sdk.sh \ && sdkmanager --list_installed \ && rm -f /tmp/ci-install-android-sdk.sh -COPY docker/TestEnvironment/create-avd.sh /usr/local/bin/create-avd.sh -RUN chmod +x /usr/local/bin/create-avd.sh +RUN mkdir -p /opt/flowcrypt/scripts +COPY script/create-avd.sh /opt/flowcrypt/scripts/create-avd.sh +COPY script/run-emulator.sh /opt/flowcrypt/scripts/run-emulator.sh +RUN chmod +x /opt/flowcrypt/scripts/create-avd.sh /opt/flowcrypt/scripts/run-emulator.sh WORKDIR /workspace diff --git a/docker/TestEnvironment/README.md b/docker/TestEnvironment/README.md index e8ab049f7..f8a6afe87 100644 --- a/docker/TestEnvironment/README.md +++ b/docker/TestEnvironment/README.md @@ -22,11 +22,16 @@ docker build -t flowcrypt-android-test-env -f docker/TestEnvironment/Dockerfile ## Create an AVD inside the container ```bash -docker run --rm -it flowcrypt-android-test-env create-avd.sh +docker run --rm -it flowcrypt-android-test-env /opt/flowcrypt/scripts/create-avd.sh ``` ## Run the emulator inside the container +The container includes reusable helpers: + +- `/opt/flowcrypt/scripts/create-avd.sh` +- `/opt/flowcrypt/scripts/run-emulator.sh` + The container includes the emulator binaries, but actual emulator launch usually needs: - `/dev/kvm` passed through to the container @@ -44,6 +49,6 @@ docker run --rm -it \ Then inside the container: ```bash -create-avd.sh -emulator -avd ci-emulator -no-window -no-boot-anim -no-audio -gpu swiftshader_indirect +/opt/flowcrypt/scripts/create-avd.sh +/opt/flowcrypt/scripts/run-emulator.sh ``` diff --git a/docker/TestEnvironment/create-avd.sh b/docker/TestEnvironment/create-avd.sh deleted file mode 100644 index 0fcc57554..000000000 --- a/docker/TestEnvironment/create-avd.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash - -# -# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com -# Contributors: denbond7 -# - -set -euo pipefail - -AVD_NAME="${AVD_NAME:-ci-emulator}" -SYSTEM_IMAGE="${SYSTEM_IMAGE:-system-images;android-36;google_apis;x86_64}" -DEVICE_NAME="${DEVICE_NAME:-pixel_9}" -ABI="${ABI:-google_apis/x86_64}" - -mkdir -p "${ANDROID_AVD_HOME:-$HOME/.android/avd}" "$HOME/.android" -touch "$HOME/.android/repositories.cfg" - -if avdmanager list avd | grep -q "Name: ${AVD_NAME}"; then - avdmanager delete avd --name "${AVD_NAME}" || true -fi - -rm -rf \ - "${ANDROID_AVD_HOME:-$HOME/.android/avd}/${AVD_NAME}.avd" \ - "${ANDROID_AVD_HOME:-$HOME/.android/avd}/${AVD_NAME}.ini" - -echo "no" | avdmanager create avd \ - --force \ - --name "${AVD_NAME}" \ - --package "${SYSTEM_IMAGE}" \ - --device "${DEVICE_NAME}" \ - --abi "${ABI}" - -echo "Created AVD ${AVD_NAME}" diff --git a/script/ci-setup-and-run-emulator.sh b/script/ci-setup-and-run-emulator.sh index 710858b7a..dbdff025b 100755 --- a/script/ci-setup-and-run-emulator.sh +++ b/script/ci-setup-and-run-emulator.sh @@ -7,50 +7,8 @@ set -euo pipefail -AVD_NAME="ci-emulator" -SYSTEM_IMAGE="system-images;android-36;google_apis;x86_64" -DEVICE_NAME="pixel_9" -ABI="google_apis/x86_64" - -"$ANDROID_HOME/emulator/emulator" -accel-check - -# Keep the emulator fresh for every CI job. -# Remove existing AVD completely before creating a new one. -if avdmanager list avd | grep -q "Name: ${AVD_NAME}"; then - echo "Removing existing AVD: ${AVD_NAME}" - - avdmanager delete avd --name "$AVD_NAME" || true -fi - -rm -rf \ - "$HOME/.android/avd/${AVD_NAME}.avd" \ - "$HOME/.android/avd/${AVD_NAME}.ini" - -#avdmanager list devices # debug - -echo -ne '\n' | avdmanager -v create avd \ - --name "$AVD_NAME" \ - --package "$SYSTEM_IMAGE" \ - --device "$DEVICE_NAME" \ - --abi "$ABI" - -# Keep RAM modest for e2-standard-2. -# This file belongs to the fresh AVD created above. -echo "hw.ramSize=2048" >> "$HOME/.android/avd/${AVD_NAME}.avd/config.ini" - -#cat "$HOME/.android/avd/${AVD_NAME}.avd/config.ini"# debug - -#"$ANDROID_HOME/emulator/emulator" -list-avds # debug - -"$ANDROID_HOME/emulator/emulator" \ - -avd "$AVD_NAME" \ - -no-window \ - -no-boot-anim \ - -no-audio \ - -no-snapshot \ - -no-snapshot-load \ - -no-snapshot-save \ - -wipe-data \ - -gpu swiftshader_indirect \ - -read-only \ - -no-metrics & +AVD_RAM_SIZE=2048 ./script/create-avd.sh +EMULATOR_GPU_MODE=swiftshader_indirect \ +EMULATOR_READ_ONLY=1 \ +EMULATOR_WIPE_DATA=1 \ +./script/run-emulator.sh diff --git a/script/create-avd.sh b/script/create-avd.sh new file mode 100755 index 000000000..a15982cad --- /dev/null +++ b/script/create-avd.sh @@ -0,0 +1,40 @@ +#!/usr/bin/env bash + +# +# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com +# Contributors: denbond7 +# + +set -euo pipefail + +AVD_NAME="${AVD_NAME:-ci-emulator}" +SYSTEM_IMAGE="${SYSTEM_IMAGE:-system-images;android-36;google_apis;x86_64}" +DEVICE_NAME="${DEVICE_NAME:-pixel_9}" +ABI="${ABI:-google_apis/x86_64}" +AVD_DIR="${ANDROID_AVD_HOME:-$HOME/.android/avd}" +AVD_RAM_SIZE="${AVD_RAM_SIZE:-}" + +mkdir -p "$AVD_DIR" "$HOME/.android" +touch "$HOME/.android/repositories.cfg" + +if avdmanager list avd | grep -q "Name: ${AVD_NAME}"; then + echo "Removing existing AVD: ${AVD_NAME}" + avdmanager delete avd --name "$AVD_NAME" || true +fi + +rm -rf \ + "${AVD_DIR}/${AVD_NAME}.avd" \ + "${AVD_DIR}/${AVD_NAME}.ini" + +echo -ne '\n' | avdmanager -v create avd \ + --force \ + --name "$AVD_NAME" \ + --package "$SYSTEM_IMAGE" \ + --device "$DEVICE_NAME" \ + --abi "$ABI" + +if [[ -n "$AVD_RAM_SIZE" ]]; then + echo "hw.ramSize=${AVD_RAM_SIZE}" >> "${AVD_DIR}/${AVD_NAME}.avd/config.ini" +fi + +echo "Created AVD ${AVD_NAME}" diff --git a/script/run-emulator.sh b/script/run-emulator.sh new file mode 100755 index 000000000..7ecb67791 --- /dev/null +++ b/script/run-emulator.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash + +# +# © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com +# Contributors: denbond7 +# + +set -euo pipefail + +AVD_NAME="${AVD_NAME:-ci-emulator}" +EMULATOR_GPU_MODE="${EMULATOR_GPU_MODE:-swiftshader_indirect}" +EMULATOR_READ_ONLY="${EMULATOR_READ_ONLY:-1}" +EMULATOR_WIPE_DATA="${EMULATOR_WIPE_DATA:-1}" + +"$ANDROID_HOME/emulator/emulator" -accel-check + +emulator_args=( + -avd "$AVD_NAME" + -no-window + -no-boot-anim + -no-audio + -no-snapshot + -no-snapshot-load + -no-snapshot-save + -gpu "$EMULATOR_GPU_MODE" + -no-metrics +) + +if [[ "$EMULATOR_WIPE_DATA" == "1" ]]; then + emulator_args+=(-wipe-data) +fi + +if [[ "$EMULATOR_READ_ONLY" == "1" ]]; then + emulator_args+=(-read-only) +fi + +"$ANDROID_HOME/emulator/emulator" "${emulator_args[@]}" & From 758ed1ef1cd1cff1ee78b7cce7d41f16709000c6 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sat, 16 May 2026 13:12:57 +0300 Subject: [PATCH 23/26] Refactoring --- docker/TestEnvironment/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docker/TestEnvironment/README.md b/docker/TestEnvironment/README.md index f8a6afe87..99549f43a 100644 --- a/docker/TestEnvironment/README.md +++ b/docker/TestEnvironment/README.md @@ -16,13 +16,13 @@ The image installs: ## Build ```bash -docker build -t flowcrypt-android-test-env -f docker/TestEnvironment/Dockerfile . +docker build -t flowcrypt/android-test-env -f docker/TestEnvironment/Dockerfile . ``` ## Create an AVD inside the container ```bash -docker run --rm -it flowcrypt-android-test-env /opt/flowcrypt/scripts/create-avd.sh +docker run --rm -it flowcrypt/android-test-env /opt/flowcrypt/scripts/create-avd.sh ``` ## Run the emulator inside the container @@ -42,7 +42,7 @@ Example: ```bash docker run --rm -it \ --device /dev/kvm \ - flowcrypt-android-test-env \ + flowcrypt/android-test-env \ bash ``` From 5be136fce69a99d61c9ce1e0587214c755bc8b54 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sat, 16 May 2026 13:22:21 +0300 Subject: [PATCH 24/26] Slipped KVM for Docker image --- docker/TestEnvironment/Dockerfile | 1 + script/ci-install-android-sdk.sh | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docker/TestEnvironment/Dockerfile b/docker/TestEnvironment/Dockerfile index 2ea9f705b..8a0d2c15d 100644 --- a/docker/TestEnvironment/Dockerfile +++ b/docker/TestEnvironment/Dockerfile @@ -53,6 +53,7 @@ RUN chmod +x /tmp/ci-install-android-sdk.sh \ && ANDROID_PLATFORM="${ANDROID_PLATFORM}" \ ANDROID_SYSTEM_IMAGE="${ANDROID_SYSTEM_IMAGE}" \ ANDROID_BUILD_TOOLS="${ANDROID_BUILD_TOOLS}" \ + INSTALL_KVM_DEPS=0 \ RUN_KVM_CHECK=0 \ /tmp/ci-install-android-sdk.sh \ && sdkmanager --list_installed \ diff --git a/script/ci-install-android-sdk.sh b/script/ci-install-android-sdk.sh index 123fec611..605cbaddc 100755 --- a/script/ci-install-android-sdk.sh +++ b/script/ci-install-android-sdk.sh @@ -22,6 +22,7 @@ fi # ----------------------------- export ANDROID_HOME="${ANDROID_HOME:-$HOME/Android/Sdk}" export ANDROID_SDK_ROOT="${ANDROID_SDK_ROOT:-$ANDROID_HOME}" +INSTALL_KVM_DEPS="${INSTALL_KVM_DEPS:-1}" RUN_KVM_CHECK="${RUN_KVM_CHECK:-1}" ANDROID_PLATFORM="${ANDROID_PLATFORM:-android-36}" ANDROID_SYSTEM_IMAGE="${ANDROID_SYSTEM_IMAGE:-system-images;android-36;google_apis;x86_64}" @@ -90,7 +91,9 @@ check_cmdline_tools_latest_or_fail # ----------------------------- # KVM deps (as in your script) # ----------------------------- -sudo apt-get -qq install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils > /dev/null +if [[ "$INSTALL_KVM_DEPS" == "1" ]]; then + sudo apt-get -qq install qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils > /dev/null +fi if [[ "$RUN_KVM_CHECK" == "1" ]]; then sudo kvm-ok fi From 23de806d1a05bfbf6a717245d6234d844fe835d5 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sat, 16 May 2026 13:32:14 +0300 Subject: [PATCH 25/26] Modified Dockerfile --- docker/TestEnvironment/Dockerfile | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/docker/TestEnvironment/Dockerfile b/docker/TestEnvironment/Dockerfile index 8a0d2c15d..c9ac82d2d 100644 --- a/docker/TestEnvironment/Dockerfile +++ b/docker/TestEnvironment/Dockerfile @@ -15,34 +15,14 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ bash \ ca-certificates \ curl \ - dnsutils \ - git \ - libasound2t64 \ - libc6 \ - libc6-dev \ libdbus-1-3 \ libfontconfig1 \ - libgcc-s1 \ libgl1 \ - libglu1-mesa \ libnspr4 \ libnss3 \ - libpulse0 \ - libstdc++6 \ libu2f-udev \ - libx11-6 \ - libx11-xcb1 \ - libxcb1 \ - libxcursor1 \ - libxdamage1 \ - libxext6 \ - libxi6 \ libxkbcommon0 \ - libxrandr2 \ - libxrender1 \ - libxtst6 \ - openjdk-21-jdk \ - sudo \ + openjdk-21-jre-headless \ unzip \ wget \ && rm -rf /var/lib/apt/lists/* From 725eb51b0e613916b208d3bb31449d1323781867 Mon Sep 17 00:00:00 2001 From: Denys Bondarenko Date: Sat, 16 May 2026 13:41:29 +0300 Subject: [PATCH 26/26] Modified Dockerfile --- docker/TestEnvironment/Dockerfile | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/docker/TestEnvironment/Dockerfile b/docker/TestEnvironment/Dockerfile index c9ac82d2d..a5311736d 100644 --- a/docker/TestEnvironment/Dockerfile +++ b/docker/TestEnvironment/Dockerfile @@ -15,14 +15,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ bash \ ca-certificates \ curl \ - libdbus-1-3 \ - libfontconfig1 \ - libgl1 \ - libnspr4 \ - libnss3 \ - libu2f-udev \ - libxkbcommon0 \ - openjdk-21-jre-headless \ + openjdk-21-jdk \ unzip \ wget \ && rm -rf /var/lib/apt/lists/*