Skip to content

chore: update script to create android emulator#7006

Open
Rohit3523 wants to merge 7 commits intodevelopfrom
android-script-fix
Open

chore: update script to create android emulator#7006
Rohit3523 wants to merge 7 commits intodevelopfrom
android-script-fix

Conversation

@Rohit3523
Copy link
Contributor

@Rohit3523 Rohit3523 commented Feb 22, 2026

Proposed changes

After the Maestro migration, we changed the Android emulator configuration but didn’t update the local script to create an emulator with the same configuration when running E2E tests.

This PR fixes the script and applies the same configuration.

The only difference is that this script uses arm64-v8a, while the GitHub Action uses x86_64 architecture.

Issue(s)

https://rocketchat.atlassian.net/browse/CORE-1861

How to test or reproduce

Screenshots

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • Improvement (non-breaking change which improves a current function)
  • New feature (non-breaking change which adds functionality)
  • Documentation update (if none of the other choices apply)

Checklist

  • I have read the CONTRIBUTING doc
  • I have signed the CLA
  • Lint and unit tests pass locally with my changes
  • I have added tests that prove my fix is effective or that my feature works (if applicable)
  • I have added necessary documentation (if applicable)
  • Any dependent changes have been merged and published in downstream modules

Further comments

Summary by CodeRabbit

  • Chores
    • Improved Android Virtual Device setup for greater reliability and idempotence.
    • Parameterized AVD configuration (API level, ABI, target, profile) with host-architecture-aware ABI selection.
    • CI-aware behavior: optional skip/storage of environment values and earlier emulator preparation in CI workflows.
    • Automated installation, non-interactive license acceptance, consistent hardware config, and clearer progress/status messaging.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 22, 2026

Walkthrough

Replaces the static AVD creation with a parameterized, strict shell script (scripts/create-avd.sh) that detects SDK paths/host architecture, installs required SDK components non-interactively, creates/removes AVDs by name, writes detailed config, and updates GitHub Actions workflow to invoke the script and use dynamic emulator parameters.

Changes

Cohort / File(s) Summary
AVD creation script
scripts/create-avd.sh
Converted to strict shell (set -e), normalizes ANDROID_HOME from ANDROID_SDK_ROOT or default, augments PATH, parameterizes API_LEVEL, PROFILE, TARGET, ABI, derives AVD_NAME, detects host arch to choose ABI, installs emulator/system-image/platform-tools non-interactively (accepts licenses), removes existing AVD if present, creates AVD and writes/overwrites detailed config.ini, and emits verbose progress/status messages (including GitHub Actions env export).
CI workflow
.github/workflows/maestro-android.yml
Adds/setup Android SDK step and runs scripts/create-avd.sh before APK download; replaces hard-coded emulator params with dynamic env variables (API_LEVEL, ABI, TARGET, PROFILE, disk-size), and reduces emulator timeout from 120 to 60 minutes.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant GH as GitHub Actions / CI
    participant Shell as scripts/create-avd.sh
    participant SDK as sdkmanager (Android SDK)
    participant AVD as avdmanager / emulator
    participant FS as Filesystem (.android/avd)

    GH->>Shell: invoke script (env: API_LEVEL, TARGET, PROFILE, ABI)
    Shell->>SDK: verify SDK_BIN/sdkmanager exists
    Shell->>SDK: install emulator, platform-tools, platforms, system-image (accept licenses)
    SDK-->>Shell: installation result
    Shell->>FS: check for existing AVD `AVD_NAME`
    FS-->>Shell: exists? (yes/no)
    alt exists
      Shell->>AVD: delete existing AVD
      AVD-->>FS: remove AVD files
    end
    Shell->>AVD: create AVD with system-image and params
    AVD-->>FS: write AVD files
    Shell->>FS: write/append `<AVD_NAME>.avd/config.ini`
    Shell-->>GH: export AVD env (GITHUB_ENV) and log status
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested labels

type: chore

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: updating the script that creates the Android emulator with new configuration to align with the GitHub Action setup.
Linked Issues check ✅ Passed The PR fully addresses CORE-1861 by updating scripts/create-avd.sh and .github/workflows/maestro-android.yml to align local Android emulator creation with GitHub Action configuration.
Out of Scope Changes check ✅ Passed All changes are directly related to the linked issue objective of aligning the Android emulator creation script with GitHub Action configuration. No out-of-scope changes detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Rohit3523 Rohit3523 self-assigned this Feb 24, 2026
@Rohit3523 Rohit3523 marked this pull request as ready for review February 24, 2026 18:00
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
scripts/create-avd.sh (1)

3-10: Harden strict mode and guard SDK path.
Consider adding -u/pipefail and an explicit ANDROID_HOME/ANDROID_SDK_ROOT check so failures are clearer when the SDK isn’t configured.

✅ Suggested tweak
-set -e
+set -euo pipefail
+
+: "${ANDROID_HOME:=${ANDROID_SDK_ROOT:-}}"
+: "${ANDROID_HOME:?Set ANDROID_HOME or ANDROID_SDK_ROOT}"
 
 AVD_NAME="pixel_7_pro"
 API_LEVEL="34"
 TARGET="google_apis"
 ARCH="arm64-v8a"
 
 SDK_BIN="$ANDROID_HOME/cmdline-tools/latest/bin"
+[[ -x "$SDK_BIN/sdkmanager" ]] || { echo "sdkmanager not found at $SDK_BIN" >&2; exit 1; }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/create-avd.sh` around lines 3 - 10, The script currently uses set -e
but doesn't enable strict mode or validate the Android SDK path; update the top
of scripts/create-avd.sh to enable strict error handling (add -u and set -o
pipefail) and validate that either ANDROID_HOME or ANDROID_SDK_ROOT is set
before computing SDK_BIN; if neither is set, print a clear error and exit
non-zero, and compute SDK_BIN from the validated variable so subsequent uses of
AVD_NAME, API_LEVEL, TARGET, ARCH, and SDK_BIN are safe.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@scripts/create-avd.sh`:
- Around line 3-10: The script currently uses set -e but doesn't enable strict
mode or validate the Android SDK path; update the top of scripts/create-avd.sh
to enable strict error handling (add -u and set -o pipefail) and validate that
either ANDROID_HOME or ANDROID_SDK_ROOT is set before computing SDK_BIN; if
neither is set, print a clear error and exit non-zero, and compute SDK_BIN from
the validated variable so subsequent uses of AVD_NAME, API_LEVEL, TARGET, ARCH,
and SDK_BIN are safe.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 566e100 and e0bc963.

📒 Files selected for processing (1)
  • scripts/create-avd.sh
📜 Review details
🔇 Additional comments (3)
scripts/create-avd.sh (3)

12-19: Package installation + license acceptance is solid.
Nice to see a fully non-interactive install path for CI/local parity.


21-34: Idempotent AVD cleanup + explicit device creation looks good.
This should keep local setups aligned with CI.


35-49: Hardware config alignment is clear and explicit.
The settings map cleanly to the expected emulator spec.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/create-avd.sh`:
- Around line 27-29: The current existence check uses grep -q "$AVD_NAME" which
can match substrings and delete the wrong AVD; change the check to match the
name exactly by anchoring the pattern (e.g., use grep -x or ^...$ and -- to
handle names starting with -) against the output of "$SDK_BIN/avdmanager list
avd" before running "$SDK_BIN/avdmanager delete avd -n \"$AVD_NAME\"". Update
the conditional that calls avdmanager list avd and grep (referencing AVD_NAME
and SDK_BIN/avdmanager) to use an exact-match grep invocation so only the exact
AVD_NAME triggers deletion.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e0bc963 and 7a0a16e.

📒 Files selected for processing (1)
  • scripts/create-avd.sh
📜 Review details
🔇 Additional comments (3)
scripts/create-avd.sh (3)

3-6: Good hardening with strict mode + ANDROID_HOME validation.
This makes failures deterministic and avoids silent misconfigurations.


39-53: Hardware config alignment looks good.
The applied settings match the CI-aligned intent and keep local/CI parity.


16-23: The review comment suggests an incorrect approach to license handling.

sdkmanager --licenses only accepts licenses for packages that are already installed or downloaded—you cannot accept licenses before installing packages because the licenses don't exist for uninstalled packages. The current code's order (install packages first, accept licenses second) is actually more aligned with how sdkmanager operates.

However, piping yes into the install commands (yes | $SDK_BIN/sdkmanager --install emulator) could still be beneficial to suppress any interactive prompts during installation, though this should be verified against your target Android SDK version and environment.

Likely an incorrect or invalid review comment.

@Rohit3523 Rohit3523 temporarily deployed to approve_e2e_testing February 24, 2026 18:21 — with GitHub Actions Inactive
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
scripts/create-avd.sh (1)

25-30: Duplicate “Checking existing AVD…” log line.

One of the two identical echo lines can be removed to avoid noisy output.

🧹 Proposed cleanup
-echo "Checking existing AVD..."
-
 EMU_BIN="$ANDROID_HOME/emulator/emulator"
-
-echo "Checking existing AVD..."
+echo "Checking existing AVD..."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/create-avd.sh` around lines 25 - 30, Remove the duplicate "Checking
existing AVD..." echo: in the create-avd.sh section where EMU_BIN is set you
currently print the same message twice; delete one of the two echo "Checking
existing AVD..." lines (keep a single instance either before or after the
EMU_BIN assignment) so output is not duplicated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/create-avd.sh`:
- Around line 16-23: The license acceptance step currently uses "< /dev/null"
which doesn't accept prompts; replace the line that calls "$SDK_BIN/sdkmanager
--licenses < /dev/null || true" with a command that pipes affirmative responses
into the sdkmanager (e.g., "yes | $SDK_BIN/sdkmanager --licenses") and remove
the "|| true" so failures are not suppressed; ensure this change is made
alongside the existing "$SDK_BIN/sdkmanager" installer calls (emulator,
platform-tools, platforms;android-$API_LEVEL,
system-images;android-$API_LEVEL;$TARGET;$ARCH) so license acceptance runs
correctly in headless CI.

---

Nitpick comments:
In `@scripts/create-avd.sh`:
- Around line 25-30: Remove the duplicate "Checking existing AVD..." echo: in
the create-avd.sh section where EMU_BIN is set you currently print the same
message twice; delete one of the two echo "Checking existing AVD..." lines (keep
a single instance either before or after the EMU_BIN assignment) so output is
not duplicated.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7a0a16e and 700bf4d.

📒 Files selected for processing (1)
  • scripts/create-avd.sh
📜 Review details
🔇 Additional comments (2)
scripts/create-avd.sh (2)

3-15: Good hardening and parameterization.

Strict mode, ANDROID_HOME validation, and a clear SDK_BIN check make the script safer and easier to troubleshoot.


38-59: AVD creation + CI-aligned config look good.

The AVD creation flow and appended hardware settings align with the stated objectives.

@Rohit3523 Rohit3523 had a problem deploying to experimental_android_build February 24, 2026 18:29 — with GitHub Actions Error
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
.github/workflows/maestro-android.yml (2)

28-32: Remove duplicate create-avd.sh invocation.

Line 28 and Line 57 execute the same script in the same job. Keeping one step is enough and makes intent clearer.

♻️ Proposed cleanup
-      - name: Create AVD
-        run: |
-          chmod +x scripts/create-avd.sh
-          scripts/create-avd.sh
...
       - name: Prepare Emulator Config
         run: |
           chmod +x scripts/create-avd.sh
           scripts/create-avd.sh

Also applies to: 57-61

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/maestro-android.yml around lines 28 - 32, Remove the
duplicate invocation of scripts/create-avd.sh so the workflow only runs the AVD
creation once; locate the two "Create AVD" steps that call chmod +x
scripts/create-avd.sh followed by scripts/create-avd.sh and delete one of them
(or merge the chmod into a single existing step), keeping a single step that
sets executable permission and runs scripts/create-avd.sh to preserve behavior.

63-73: Explicitly set avd-name to use the created AVD.

The create-avd.sh script creates an AVD named ${{ env.AVD_NAME }} (constructed as ${PROFILE}-api-${API_LEVEL}-${TARGET}-${ABI}), and this environment variable is exported at line 39 of the script. However, the emulator runner action is called without an explicit avd-name, causing it to default to test. When force-avd-creation: false, the action will attempt to use an AVD named test rather than the one that was just created, creating a mismatch. Adding avd-name: ${{ env.AVD_NAME }} ensures the action uses the correct AVD and properly leverages the force-avd-creation: false setting.

Proposed change
       - name: Start Android Emulator and Run Maestro Tests
         uses: reactivecircus/android-emulator-runner@v2
         timeout-minutes: 60
         with:
+          avd-name: ${{ env.AVD_NAME }}
           api-level: ${{ env.API_LEVEL }}
           arch: ${{ env.ABI }}
           target: ${{ env.TARGET }}
           profile: ${{ env.PROFILE }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/maestro-android.yml around lines 63 - 73, The emulator
runner is missing an explicit avd-name so it defaults to "test" instead of the
AVD created by create-avd.sh; update the reactivecircus/android-emulator-runner
step to include avd-name: ${{ env.AVD_NAME }} so the action uses the AVD
exported by the script (AVD_NAME, constructed as
${PROFILE}-api-${API_LEVEL}-${TARGET}-${ABI}) and respects force-avd-creation:
false.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@scripts/create-avd.sh`:
- Around line 62-65: The avd creation step using avdmanager create avd -n
"$AVD_NAME" will fail on reruns and appends duplicate settings to config.ini;
make it idempotent by either adding the --force flag to the avdmanager create
avd invocation (to overwrite existing AVD) or by checking for and removing an
existing AVD name (parse avdmanager list avd output carefully—look for lines
like "Name:" that may have leading whitespace—then call avdmanager delete avd
before creating). Also replace the append-to-config.ini logic with a safe
write/replace approach (overwrite or filter existing keys) so repeated runs do
not duplicate entries in config.ini. Ensure you reference AVD_NAME, avdmanager
create avd, avdmanager list avd, avdmanager delete avd, and the config.ini write
block when implementing the fix.

---

Nitpick comments:
In @.github/workflows/maestro-android.yml:
- Around line 28-32: Remove the duplicate invocation of scripts/create-avd.sh so
the workflow only runs the AVD creation once; locate the two "Create AVD" steps
that call chmod +x scripts/create-avd.sh followed by scripts/create-avd.sh and
delete one of them (or merge the chmod into a single existing step), keeping a
single step that sets executable permission and runs scripts/create-avd.sh to
preserve behavior.
- Around line 63-73: The emulator runner is missing an explicit avd-name so it
defaults to "test" instead of the AVD created by create-avd.sh; update the
reactivecircus/android-emulator-runner step to include avd-name: ${{
env.AVD_NAME }} so the action uses the AVD exported by the script (AVD_NAME,
constructed as ${PROFILE}-api-${API_LEVEL}-${TARGET}-${ABI}) and respects
force-avd-creation: false.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 700bf4d and b6c5294.

📒 Files selected for processing (2)
  • .github/workflows/maestro-android.yml
  • scripts/create-avd.sh
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: E2E Build Android / android-build
  • GitHub Check: ESLint and Test / run-eslint-and-test
  • GitHub Check: format

Comment on lines +62 to +65
echo "no" | avdmanager create avd \
-n "$AVD_NAME" \
-d "$PROFILE" \
--package "$IMAGE"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n scripts/create-avd.sh

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 2338


🏁 Script executed:

# Check avdmanager documentation/common usage patterns
rg -i 'avdmanager|set -e' scripts/create-avd.sh

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 120


🌐 Web query:

avdmanager create avd --force idempotent options

💡 Result:

To make avdmanager create avd idempotent in scripts/CI, you basically have two choices:

1) “Ensure this AVD exists (and matches my desired config)” → overwrite deterministically

Use force overwrite plus non-interactive input:

echo "no" | avdmanager create avd \
  --name my_avd \
  --package "system-images;android-34;google_apis;x86_64" \
  --force
  • -f/--force overwrites an existing AVD with the same name (this is the closest built-in “idempotent” behavior). [1]
  • echo "no" | ... avoids the interactive prompt (commonly used in CI). [2]

Useful create avd options (the ones that matter for reproducibility):

  • -n/--name AVD name (required) [1]
  • -k/--package system image package id (required) [1]
  • -c/--sdcard {path|size} set/allocate SD card [1]
  • -p/--path AVD directory location [1]
  • -f/--force overwrite existing AVD [1]
  • (Also commonly available) --device, --tag, --abi depending on cmdline-tools version; these show up in avdmanager create avd --help output in the field. [2]

2) “Create only if missing” → don’t touch existing AVDs

Do an existence check first, then create without --force:

if ! avdmanager list avd -c | grep -q '^my_avd$'; then
  echo "no" | avdmanager create avd -n my_avd -k "system-images;android-34;google_apis;x86_64"
fi

avdmanager itself doesn’t provide a dedicated “create-if-not-exists” flag; scripting with list avd is the typical approach. [1]


🏁 Script executed:

# Search for avdmanager documentation or common usage patterns
rg 'avdmanager\s+create' --type bash -B2 -A2

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 106


🏁 Script executed:

# Let me search for the actual output format of avdmanager list avd
# to verify if the proposed grep pattern is correct
rg 'list avd|grep' --type sh -B2 -A2 . 2>/dev/null | head -30

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 60


🏁 Script executed:

fd -type f -name '*.sh' | xargs rg -l 'avdmanager' 2>/dev/null

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 287


🏁 Script executed:

# Check if there are any CI/workflow files that might show how avdmanager is used
fd -type f -name '*.yml' -o -name '*.yaml' | xargs rg -l 'create-avd|avdmanager' 2>/dev/null | head -5

Repository: RocketChat/Rocket.Chat.ReactNative

Length of output: 287


🌐 Web query:

avdmanager list avd output format "Name:" example

💡 Result:

avdmanager list avd prints a “pretty” multi-line block per AVD that includes lines like Name: (and usually Device:, Path:, Target:, etc.). Example output:

$ avdmanager list avd
Available Android Virtual Devices:
    Name: Pixel_C_Tablet_API_30
  Device: pixel_c (Google)
    Path: /Users/alleng/.android/avd/Pixel_C_Tablet_API_30.avd
  Target: Google APIs (Google Inc.)
          Based on: Android API 30 Tag/ABI: google_apis/x86
    Skin: pixel_c
  Sdcard: 128 MB

[2]

If you need a script-friendly format, avdmanager supports list ... -c for “compact output suitable for scripts” when listing AVDs. [1]

Sources: [1] https://developer.android.com/tools/avdmanager, [2] https://blog.csdn.net/wizardforcel/article/details/141383947


Add idempotency check or use --force flag to handle existing AVDs on reruns.

Line 62 will fail on subsequent runs if the AVD already exists (set -e aborts the script). Additionally, appending to config.ini (lines 67–74) will duplicate settings on reruns.

Use --force flag for simpler idempotent creation:

Suggested fix (simplest)
 echo "no" | avdmanager create avd \
   -n "$AVD_NAME" \
   -d "$PROFILE" \
   --package "$IMAGE" \
+  --force

Alternatively, check and delete the existing AVD first (note: adjust the grep pattern—avdmanager list avd output has leading whitespace before Name:):

Alternative: delete-then-create approach
+if avdmanager list avd | grep -q "[[:space:]]*Name: ${AVD_NAME}$"; then
+  echo "Deleting existing AVD: $AVD_NAME"
+  avdmanager delete avd -n "$AVD_NAME"
+fi
+
 echo "no" | avdmanager create avd \
   -n "$AVD_NAME" \
   -d "$PROFILE" \
   --package "$IMAGE"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@scripts/create-avd.sh` around lines 62 - 65, The avd creation step using
avdmanager create avd -n "$AVD_NAME" will fail on reruns and appends duplicate
settings to config.ini; make it idempotent by either adding the --force flag to
the avdmanager create avd invocation (to overwrite existing AVD) or by checking
for and removing an existing AVD name (parse avdmanager list avd output
carefully—look for lines like "Name:" that may have leading whitespace—then call
avdmanager delete avd before creating). Also replace the append-to-config.ini
logic with a safe write/replace approach (overwrite or filter existing keys) so
repeated runs do not duplicate entries in config.ini. Ensure you reference
AVD_NAME, avdmanager create avd, avdmanager list avd, avdmanager delete avd, and
the config.ini write block when implementing the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant