pipeline { agent any environment { ANDROID_HOME = '/Users/xuqinmin/Library/Android/sdk' NEXUS_USER = credentials('nexus-android-user') NEXUS_PASS = credentials('nexus-android-pass') AVD_1 = 'Pixel_9_Pro' AVD_2 = 'Pixel_9_Pro_2' EMULATOR_BIN = "${ANDROID_HOME}/emulator/emulator" ADB = "${ANDROID_HOME}/platform-tools/adb" TEST_PKG = 'com.xuqm.demo.test' RUNNER = 'androidx.test.runner.AndroidJUnitRunner' } options { timeout(time: 60, unit: 'MINUTES') buildDiscarder(logRotator(numToKeepStr: '10')) } stages { stage('Build') { steps { sh './gradlew :sample-app:assembleDebug :sample-app:assembleDebugAndroidTest --no-daemon' } } stage('Start Emulators') { steps { sh """ ${EMULATOR_BIN} -avd ${AVD_1} -no-audio -no-boot-anim -no-snapshot-save -no-window & ${EMULATOR_BIN} -avd ${AVD_2} -no-audio -no-boot-anim -no-snapshot-save -no-window & ${ADB} wait-for-device sleep 20 ${ADB} devices """ } } stage('Install APKs') { steps { sh """ APK=sample-app/build/outputs/apk/debug/sample-app-debug.apk TEST_APK=sample-app/build/outputs/apk/androidTest/debug/sample-app-debug-androidTest.apk for DEV in emulator-5554 emulator-5556; do ${ADB} -s \$DEV install -r "\$APK" ${ADB} -s \$DEV install -r "\$TEST_APK" done """ } } stage('Single-Device Tests') { steps { sh """ ALL_SINGLE="com.xuqm.sdk.sample.SdkIntegrationTest,\ com.xuqm.sdk.sample.PushSdkTest,\ com.xuqm.sdk.sample.NetworkResilienceTest" ${ADB} -s emulator-5554 shell am instrument -w -r \\ -e class "\${ALL_SINGLE}" \\ "${TEST_PKG}/${RUNNER}" | tee test-results-5554.txt grep -q "FAILURES" test-results-5554.txt && exit 1 || true """ } } stage('Cross-Device Tests') { parallel { stage('Sender (5554)') { steps { sh """ ${ADB} -s emulator-5554 shell am instrument -w -r \\ -e class "com.xuqm.sdk.sample.CrossDeviceSenderTest" \\ "${TEST_PKG}/${RUNNER}" | tee cross-sender.txt grep -q "FAILURES" cross-sender.txt && exit 1 || true """ } } stage('Receiver (5556)') { steps { sh """ ${ADB} -s emulator-5556 shell am instrument -w -r \\ -e class "com.xuqm.sdk.sample.CrossDeviceReceiverTest" \\ "${TEST_PKG}/${RUNNER}" | tee cross-receiver.txt grep -q "FAILURES" cross-receiver.txt && exit 1 || true """ } } } } stage('Publish to Nexus') { when { branch 'main' } steps { sh """ ./gradlew publish --no-daemon \\ -PNEXUS_USER=\${NEXUS_USER} \\ -PNEXUS_PASSWORD=\${NEXUS_PASS} """ } } } post { always { sh "${ADB} emu kill || true" archiveArtifacts artifacts: 'test-results-*.txt, cross-*.txt', allowEmptyArchive: true } failure { sh """ ${ADB} -s emulator-5554 logcat -d -s XuqmImSDK:D XuqmPushSDK:W XuqmUpdateSDK:D > logcat-5554.txt || true ${ADB} -s emulator-5556 logcat -d -s XuqmImSDK:D XuqmPushSDK:W XuqmUpdateSDK:D > logcat-5556.txt || true """ archiveArtifacts artifacts: 'logcat-*.txt', allowEmptyArchive: true } } }