diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml new file mode 100644 index 00000000000..5e9fa901ab5 --- /dev/null +++ b/.github/workflows/action.yml @@ -0,0 +1,19 @@ +name: Android CI + +on: + pull_request: + branches: + - '*' + +jobs: + build: + uses: ./.github/workflows/android_experimental_build.yml + secrets: + EXPERIMENTAL_KEYSTORE_BASE64: ${{ secrets.EXPERIMENTAL_KEYSTORE_BASE64 }} + EXPERIMENTAL_KEYSTORE_PASSWORD: ${{ secrets.EXPERIMENTAL_KEYSTORE_PASSWORD }} + EXPERIMENTAL_KEY_ALIAS: ${{ secrets.EXPERIMENTAL_KEY_ALIAS }} + EXPERIMENTAL_KEY_PASSWORD: ${{ secrets.EXPERIMENTAL_KEY_PASSWORD }} + + test: + uses: ./.github/workflows/maestro_android.yml + needs: build diff --git a/.github/workflows/android_experimental_build.yml b/.github/workflows/android_experimental_build.yml new file mode 100644 index 00000000000..800c1ea9423 --- /dev/null +++ b/.github/workflows/android_experimental_build.yml @@ -0,0 +1,111 @@ +name: Build Android Experimental APK + +on: + workflow_call: + secrets: + EXPERIMENTAL_KEYSTORE_BASE64: + required: true + EXPERIMENTAL_KEYSTORE_PASSWORD: + required: true + EXPERIMENTAL_KEY_ALIAS: + required: true + EXPERIMENTAL_KEY_PASSWORD: + required: true + + +jobs: + android-build: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Log the secrets + run: | + if [ -z "${{ secrets.EXPERIMENTAL_KEYSTORE_BASE64 }}" ]; then + echo "❌ EXPERIMENTAL_KEYSTORE_BASE64 is NOT set" + else + echo "✅ EXPERIMENTAL_KEYSTORE_BASE64 is set" + fi + + if [ -z "${{ secrets.EXPERIMENTAL_KEYSTORE_PASSWORD }}" ]; then + echo "❌ EXPERIMENTAL_KEYSTORE_PASSWORD is NOT set" + else + echo "✅ EXPERIMENTAL_KEYSTORE_PASSWORD is set" + fi + + if [ -z "${{ secrets.EXPERIMENTAL_KEY_ALIAS }}" ]; then + echo "❌ EXPERIMENTAL_KEY_ALIAS is NOT set" + else + echo "✅ EXPERIMENTAL_KEY_ALIAS is set" + fi + + if [ -z "${{ secrets.EXPERIMENTAL_KEY_PASSWORD }}" ]; then + echo "❌ EXPERIMENTAL_KEY_PASSWORD is NOT set" + else + echo "✅ EXPERIMENTAL_KEY_PASSWORD is set" + fi + + - name: Set up Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: 'yarn' + + - name: Cache node_modules + id: cache-node-modules + uses: actions/cache@v4 + with: + path: node_modules + key: ${{ runner.os }}-node_modules-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-node_modules- + + - name: Decode Keystore + run: | + echo "${{ secrets.EXPERIMENTAL_KEYSTORE_BASE64 }}" | base64 -d > android/app/release.keystore + + - name: Set gradle.properties + run: | + echo " " >> android/gradle.properties + echo "KEYSTORE=release.keystore" >> android/gradle.properties + echo "KEYSTORE_PASSWORD=${{ secrets.EXPERIMENTAL_KEYSTORE_PASSWORD }}" >> android/gradle.properties + echo "KEY_ALIAS=${{ secrets.EXPERIMENTAL_KEY_ALIAS }}" >> android/gradle.properties + echo "KEY_PASSWORD=${{ secrets.EXPERIMENTAL_KEY_PASSWORD }}" >> android/gradle.properties + + - name: Install Dependencies + run: yarn install + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v4 + + - name: Cache Gradle Caches + uses: actions/cache@v4 + with: + path: | + ~/.gradle/caches + ~/.gradle/wrapper + key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} + restore-keys: | + gradle-${{ runner.os }}- + + - name: Cache Android build output + uses: actions/cache@v4 + with: + path: | + android/app/build + key: build-output-${{ hashFiles('android/app/src/**', '**/*.gradle*') }} + restore-keys: | + build-output- + + - name: Build Android Release APK + run: | + cd android + ./gradlew assembleExperimentalRelease --no-daemon --build-cache --parallel --max-workers=4 + + - name: Upload APK + uses: actions/upload-artifact@v4 + with: + name: Android Experimental APK + path: android/app/build/outputs/apk/experimental/release/app-experimental-release.apk \ No newline at end of file diff --git a/.github/workflows/maestro_android.yml b/.github/workflows/maestro_android.yml new file mode 100644 index 00000000000..42c00dac203 --- /dev/null +++ b/.github/workflows/maestro_android.yml @@ -0,0 +1,54 @@ +name: Maestro Tests on Android + +on: + workflow_call: + +jobs: + android-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Download APK + uses: actions/download-artifact@v4 + with: + name: Android Experimental APK + + - name: Install Maestro + run: | + curl -fsSL "https://get.maestro.mobile.dev" | bash + echo "$HOME/.maestro/bin" >> $GITHUB_PATH + + - name: Enable KVM group permissions + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: Start Android Emulator and Run Maestro Tests + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: 34 + arch: x86_64 + ram-size: 8192M + disk-size: 4096M + target: google_apis + profile: pixel_7_pro + script: | + mkdir recording + adb install app-experimental-release.apk + maestro test .maestro/login.yml --format junit --output maestro-report.xml + + - name: Upload Recordings + uses: actions/upload-artifact@v4 + with: + name: Test Recordings + path: recording/ + + - name: Upload Test Report + uses: actions/upload-artifact@v4 + with: + name: Android Test Report + path: maestro-report.xml \ No newline at end of file diff --git a/.maestro/login.yml b/.maestro/login.yml new file mode 100644 index 00000000000..31fbb7b5d3e --- /dev/null +++ b/.maestro/login.yml @@ -0,0 +1,34 @@ +appId: chat.rocket.reactnative +name: 'Login Test' +--- +- startRecording: + path: './recording/login_test' + label: 'Begin collecting test evidence' +- launchApp: + label: 'Launch app' + clearState: true + permissions: + all: allow +- extendedWaitUntil: + visible: 'Add Workspace' + timeout: 20000 +- tapOn: + id: new-server-view-input +- inputText: + text: https://mobile.rocket.chat +- tapOn: Connect +- tapOn: Login +- tapOn: + id: login-view-email +- inputText: + text: rohit.bansal@gmail.com +- pressKey: Enter +- inputText: + text: rohit.bansal@gmail.com +- tapOn: + id: login-view +- tapOn: + id: login-view-submit +- assertVisible: + id: 'rooms-list-view-item-general' +- stopRecording