chore: update script to create android emulator#7006
chore: update script to create android emulator#7006
Conversation
WalkthroughReplaces the static AVD creation with a parameterized, strict shell script ( Changes
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Suggested labels
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ 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. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
scripts/create-avd.sh (1)
3-10: Harden strict mode and guard SDK path.
Consider adding-u/pipefailand an explicitANDROID_HOME/ANDROID_SDK_ROOTcheck 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
📒 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.
…cket.Chat.ReactNative into android-script-fix
There was a problem hiding this comment.
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
📒 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 --licensesonly 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 howsdkmanageroperates.However, piping
yesinto 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.
There was a problem hiding this comment.
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
echolines 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
📒 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.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (2)
.github/workflows/maestro-android.yml (2)
28-32: Remove duplicatecreate-avd.shinvocation.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.shAlso 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 setavd-nameto use the created AVD.The
create-avd.shscript 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 explicitavd-name, causing it to default totest. Whenforce-avd-creation: false, the action will attempt to use an AVD namedtestrather than the one that was just created, creating a mismatch. Addingavd-name: ${{ env.AVD_NAME }}ensures the action uses the correct AVD and properly leverages theforce-avd-creation: falsesetting.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
📒 Files selected for processing (2)
.github/workflows/maestro-android.ymlscripts/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
| echo "no" | avdmanager create avd \ | ||
| -n "$AVD_NAME" \ | ||
| -d "$PROFILE" \ | ||
| --package "$IMAGE" |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n scripts/create-avd.shRepository: RocketChat/Rocket.Chat.ReactNative
Length of output: 2338
🏁 Script executed:
# Check avdmanager documentation/common usage patterns
rg -i 'avdmanager|set -e' scripts/create-avd.shRepository: 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/--forceoverwrites 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/--nameAVD name (required) [1]-k/--packagesystem image package id (required) [1]-c/--sdcard {path|size}set/allocate SD card [1]-p/--pathAVD directory location [1]-f/--forceoverwrite existing AVD [1]- (Also commonly available)
--device,--tag,--abidepending on cmdline-tools version; these show up inavdmanager create avd --helpoutput 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"
fiavdmanager 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 -A2Repository: 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 -30Repository: RocketChat/Rocket.Chat.ReactNative
Length of output: 60
🏁 Script executed:
fd -type f -name '*.sh' | xargs rg -l 'avdmanager' 2>/dev/nullRepository: 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 -5Repository: 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" \
+ --forceAlternatively, 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.
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
Checklist
Further comments
Summary by CodeRabbit