Repository navigation
219 lines (189 loc) · 7.8 KB
/
Copy pathe2e-android.yml
File metadata and controls
219 lines (189 loc) · 7.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
name: E2E Tests on Android
on:
workflow_call:
inputs:
shard:
required: true
type: string
secrets:
E2E_ACCOUNT:
required: true
CLAUDE_CODE_OAUTH_TOKEN:
required: true
permissions: {}
jobs:
android-test:
name: 'Android Tests'
runs-on: ubuntu-latest
permissions:
contents: read
timeout-minutes: 95
env:
E2E_TELEMETRY_DISABLED: '1'
E2E_STEP_TIMEOUT_MINUTES: '70'
ANDROID_AVD_HOME: /home/runner/.android/avd
steps:
- name: Checkout Repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
- parallel:
- name: Setup Java
uses: actions/setup-java@c1e323688fd81a25caa38c78aa6df2d33d3e20d9 # v4.8.0
with:
distribution: temurin
java-version: 17
- name: Restore Android AVD (seeded on develop; shard 9 builds its own)
if: ${{ inputs.shard != '9' }}
id: avd-cache
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
~/.android/avd/*
~/.android/adb*
key: avd-${{ runner.os }}-api34
- name: Restore Android SDK packages (emulator + system image, seeded on develop)
uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
with:
path: |
/usr/local/lib/android/sdk/emulator
/usr/local/lib/android/sdk/system-images/android-34/google_apis/x86_64
key: android-sdk-emu-${{ runner.os }}-api34
- name: Setup Node
uses: ./.github/actions/setup-node
- name: Download APK
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: Android APK
- name: Pre-install Android SDK packages (updates a stale cache, retried)
uses: ./.github/actions/preinstall-android-sdk
- name: Setup E2E Account
uses: ./.github/actions/e2e-account
with:
E2E_ACCOUNT: ${{ secrets.E2E_ACCOUNT }}
- 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: Disable unnecessary services (improves emulator stability)
run: |
sudo systemctl stop docker || true
sudo systemctl stop snapd || true
- name: Create Keyboard-enabled AVD (shard 9)
if: ${{ inputs.shard == '9' }}
run: |
set -eux
ANDROID_SDK="${ANDROID_HOME:-${ANDROID_SDK_ROOT:-/usr/local/lib/android/sdk}}"
SDKMANAGER="$ANDROID_SDK/cmdline-tools/latest/bin/sdkmanager"
AVDMANAGER="$ANDROID_SDK/cmdline-tools/latest/bin/avdmanager"
AVD_NAME="Pixel_API_34_Keyboard"
IMAGE="system-images;android-34;google_apis;x86_64"
AVD_BASE="$ANDROID_AVD_HOME"
AVD_INI="$AVD_BASE/${AVD_NAME}.ini"
mkdir -p "$AVD_BASE"
rm -rf "$AVD_BASE/${AVD_NAME}.avd" "$AVD_INI"
"$SDKMANAGER" --install emulator "$IMAGE"
yes | "$SDKMANAGER" --licenses > /dev/null || true
echo "no" | "$AVDMANAGER" create avd -n "$AVD_NAME" -d pixel_7_pro --package "$IMAGE" --force
if [ ! -f "$AVD_INI" ]; then
echo "Expected AVD ini not found: $AVD_INI"
echo "--- avdmanager list avd ---"
"$AVDMANAGER" list avd || true
echo "--- ls AVD_BASE ---"
ls -la "$AVD_BASE" || true
exit 1
fi
AVD_PATH="$(sed -n 's/^path=//p' "$AVD_INI")"
if [ -z "$AVD_PATH" ]; then
echo "Could not resolve AVD path from: $AVD_INI"
cat "$AVD_INI"
exit 1
fi
AVD_CONFIG="$AVD_PATH/config.ini"
if [ ! -f "$AVD_CONFIG" ]; then
echo "Expected AVD config not found: $AVD_CONFIG"
ls -la "$AVD_BASE" || true
ls -la "$AVD_PATH" || true
exit 1
fi
{
echo "hw.keyboard=yes"
echo "hw.keyboard.lid=no"
echo "hw.lcd.density=440"
echo "hw.lcd.height=2280"
echo "hw.lcd.width=1080"
} >> "$AVD_CONFIG"
echo "$AVD_NAME created with physical keyboard support"
- name: Set E2E deadline before the test step timeout
run: echo "E2E_DEADLINE=$(( $(date +%s) + (E2E_STEP_TIMEOUT_MINUTES - 7) * 60 ))" >> "$GITHUB_ENV"
- name: Start Android Emulator and Run E2E Tests (keyboard AVD)
if: ${{ inputs.shard == '9' }}
uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a # v2.37.0
timeout-minutes: ${{ fromJSON(env.E2E_STEP_TIMEOUT_MINUTES) }}
env:
E2E_ANDROID_APP_PATH: ${{ github.workspace }}/app-release.apk
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
SHARD: ${{ inputs.shard }}
with:
api-level: 34
disk-size: 4096M
arch: x86_64
target: google_apis
avd-name: Pixel_API_34_Keyboard
cores: 4
ram-size: 6144M
force-avd-creation: false
disable-animations: true
emulator-boot-timeout: 900
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -accel on
script: bash .github/scripts/run-e2e.sh android "$SHARD"
- name: Start Android Emulator and Run E2E Tests (default, snapshot stays restore-only)
if: ${{ inputs.shard != '9' }}
uses: reactivecircus/android-emulator-runner@e89f39f1abbbd05b1113a29cf4db69e7540cae5a # v2.37.0
timeout-minutes: ${{ fromJSON(env.E2E_STEP_TIMEOUT_MINUTES) }}
env:
E2E_ANDROID_APP_PATH: ${{ github.workspace }}/app-release.apk
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
SHARD: ${{ inputs.shard }}
with:
api-level: 34
disk-size: 4096M
arch: x86_64
target: google_apis
profile: pixel_7_pro
cores: 4
ram-size: 6144M
force-avd-creation: false
disable-animations: true
emulator-boot-timeout: 900
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none -accel on
script: bash .github/scripts/run-e2e.sh android "$SHARD"
- name: Redact E2E Report
id: redact
if: always()
env:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
run: bash .github/scripts/redact-e2e-output.sh
- name: Collect Recorded Agent Replays
id: replays
if: always()
env:
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
run: bash .github/scripts/collect-e2e-replays.sh .e2e/replays
- name: Upload Recorded Agent Replays
if: always() && steps.replays.outputs.count != '' && steps.replays.outputs.count != '0'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: e2e-replays-android-${{ inputs.shard }}
path: .e2e/replays
retention-days: 14
overwrite: true
- name: Upload E2E Report
if: always() && steps.redact.outcome == 'success'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: Android E2E Report - Shard ${{ inputs.shard }}
path: |
.e2e/report.json
.e2e/junit.xml
.e2e/artifacts
retention-days: 7