Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 31 additions & 15 deletions .github/actions/preview-emulator/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,26 +47,26 @@ runs:
shell: bash
run: |
echo "path=${ANDROID_HOME:-${ANDROID_SDK_ROOT:-/usr/local/lib/android/sdk}}" >> "$GITHUB_OUTPUT"
# actions/cache never re-saves on an exact key hit, so a fixed key would
# freeze the image at whatever revision was current when it was first
# cached: sdkmanager would re-fetch each new revision on every run and
# the cache would never catch up, while CI quietly tested a stale image.
# Rotating weekly bounds that. The restore-keys prefix means a rotation
# restores last week's copy and lets sdkmanager fetch just the delta,
# rather than paying for a full download.
echo "week=$(date -u +%G-W%V)" >> "$GITHUB_OUTPUT"

# The system image is the one large download here (system.img alone is
# ~4.1 GiB, ~2 GiB compressed). The preview emulator package is
# deliberately NOT cached: it moves often and pinning a stale build would
# defeat the purpose of these jobs. sdkmanager still runs after a cache
# hit, so a newer image revision is still picked up.
# defeat the purpose of these jobs.
#
# Restore and save are split so the entry can be keyed on the image
# revision, which is only knowable after sdkmanager has run. A single
# actions/cache with a fixed key never re-saves on a hit, so it would pin
# whatever revision was cached first and re-download every subsequent
# revision on every run, forever. Here: restore whatever copy exists,
# let sdkmanager bring it up to date, then save under the revision that
# actually ended up on disk. A new revision lands in the cache on the
# first run that sees it.
- name: Restore cached system image
id: sysimg-cache
uses: actions/cache@v4
id: sysimg-restore
uses: actions/cache/restore@v4
with:
path: ${{ steps.sdk.outputs.path }}/system-images/android-${{ inputs.api-level }}/${{ inputs.target }}/${{ inputs.abi }}
key: sysimg-v1-android-${{ inputs.api-level }}-${{ inputs.target }}-${{ inputs.abi }}-${{ steps.sdk.outputs.week }}
key: sysimg-v1-android-${{ inputs.api-level }}-${{ inputs.target }}-${{ inputs.abi }}-rev
restore-keys: |
sysimg-v1-android-${{ inputs.api-level }}-${{ inputs.target }}-${{ inputs.abi }}

Expand Down Expand Up @@ -100,6 +100,7 @@ runs:
# The AVD must be created BEFORE emulators;latest is installed: with the
# preview package present, avdmanager create silently no-ops.
- name: Install system image and create AVD
id: sysimg
shell: bash
run: |
set +o pipefail # see "Update SDK cmdline-tools" -- `yes |` vs pipefail
Expand All @@ -108,11 +109,17 @@ runs:
PKG='system-images;android-${{ inputs.api-level }};${{ inputs.target }};${{ inputs.abi }}'
# Timed so the value of caching the image can be read straight off the
# job log rather than inferred.
echo "SYSIMG-CACHE hit=${{ steps.sysimg-cache.outputs.cache-hit || 'false' }}"
echo "SYSIMG-CACHE restored-from='${{ steps.sysimg-restore.outputs.cache-matched-key }}'"
T0=$(date +%s)
yes | "$SDK/cmdline-tools/latest/bin/sdkmanager" --channel=3 --install "$PKG" platform-tools > /dev/null
echo "SYSIMG-INSTALL seconds=$(( $(date +%s) - T0 ))"
du -sh "$SDK/system-images/android-${{ inputs.api-level }}/${{ inputs.target }}/${{ inputs.abi }}" 2>/dev/null | sed 's/^/SYSIMG-SIZE /' || true
IMGDIR="$SDK/system-images/android-${{ inputs.api-level }}/${{ inputs.target }}/${{ inputs.abi }}"
du -sh "$IMGDIR" 2>/dev/null | sed 's/^/SYSIMG-SIZE /' || true
# Key the cache on the revision that actually ended up on disk.
REV="$(sed -n 's/^Pkg\.Revision=//p' "$IMGDIR/source.properties" 2>/dev/null | head -1 | tr -d ' \r')"
[ -n "$REV" ] || REV=unknown
echo "SYSIMG-REVISION $REV"
echo "revision=$REV" >> "$GITHUB_OUTPUT"
# Mimic the emulator-runner action's invocation (--abi and --device
# skip the auto-select/prompt path where bare creates silently no-op).
echo no | "$SDK/cmdline-tools/latest/bin/avdmanager" create avd --force -n "$AVD" \
Expand Down Expand Up @@ -153,6 +160,15 @@ runs:
>> "$HOME/.android/avd/$AVD.avd/config.ini"
echo "===== AVD root ini ====="; cat "$HOME/.android/avd/$AVD.ini"

# Only writes when the restored entry is not already this revision, so a
# steady state costs nothing and a new revision is picked up once.
- name: Save system image to cache
if: steps.sysimg-restore.outputs.cache-matched-key != format('sysimg-v1-android-{0}-{1}-{2}-rev{3}', inputs.api-level, inputs.target, inputs.abi, steps.sysimg.outputs.revision)
uses: actions/cache/save@v4
with:
path: ${{ steps.sdk.outputs.path }}/system-images/android-${{ inputs.api-level }}/${{ inputs.target }}/${{ inputs.abi }}
key: sysimg-v1-android-${{ inputs.api-level }}-${{ inputs.target }}-${{ inputs.abi }}-rev${{ steps.sysimg.outputs.revision }}

- name: Install preview emulator
shell: bash
run: |
Expand Down
Loading