Pin CI actions to commit hashes and fix the API 37 emulator run
The API 37 job failed after 23 seconds, before an emulator ever started. The CI log names the cause exactly: sdkmanager --install 'build-tools;37.0.0' platform-tools 'platforms;android-37' Warning: Failed to find package 'platforms;android-37' There is no platforms;android-37. The release is published as android-37.0, alongside 37.1 and the 37.2 betas. The earlier attempt to fix this with system-image-api-level was aimed at the wrong package: that input only names the system image, while the platform is installed from api-level directly. Setting api-level to 37.0 resolves all three packages, and build-tools is a hardcoded constant in the action rather than derived from api-level, so it is unaffected. A separate label field keeps the job name reading "API 37". Every action is now pinned to a commit hash with its release in a trailing comment. A tag is mutable: the owner can repoint v4 at new code whenever they like, so a tag reference amounts to running whatever that repository contains tomorrow. Each hash was verified to resolve to the tag its comment claims, because a wrong hash is worse than a tag -- it looks deliberate. Versions moved a long way in the process: checkout v4 -> v7.0.1, setup-java v4 -> v5.7.0, upload-artifact v4 -> v7.0.1. gradle/actions is gone rather than upgraded. Its v6 release moved the caching component closed-source and states that upgrading accepts Gradle's Terms of Use for it. That has no bearing on the project's own licence -- a CI tool is never combined with or distributed alongside the app, unlike the FFmpeg libraries that make the APK GPL -- but it is a component in the build path that cannot be audited or forked. Gradle now runs through the committed wrapper, which verifies its own distribution against distributionSha256Sum, and caching is a handful of lines of actions/cache. The rest of the matrix passed on this run: API 33, 34, 35 and 36 all green, along with the unit tests and the FFmpeg archive check. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,6 +10,15 @@ concurrency:
|
||||
group: status-check-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
# Third-party actions are pinned to a commit rather than a tag. A tag is mutable: the
|
||||
# owner can repoint v4 at new code, so a tag reference is an open invitation to run
|
||||
# whatever that repository contains tomorrow. The trailing comment records which
|
||||
# release each hash corresponds to, since a bare hash is unreadable.
|
||||
env:
|
||||
GRADLE_CACHE_PATHS: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
|
||||
jobs:
|
||||
# ---------------------------------------------------------------------------
|
||||
# Validates the committed FFmpeg archive. It does not build anything: the whole
|
||||
@@ -25,7 +34,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Verify the committed archive
|
||||
run: |
|
||||
@@ -66,19 +75,26 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- uses: actions/setup-java@v4
|
||||
- uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: '17' # AGP 9 will not run on anything older
|
||||
|
||||
- uses: gradle/actions/setup-gradle@v4
|
||||
# Gradle is invoked through the committed wrapper rather than a setup action.
|
||||
# The wrapper verifies its own distribution against distributionSha256Sum, and
|
||||
# caching is a handful of lines, so the action earned little here.
|
||||
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ${{ env.GRADLE_CACHE_PATHS }}
|
||||
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle.kts', 'gradle/libs.versions.toml', 'gradle/wrapper/gradle-wrapper.properties') }}
|
||||
restore-keys: gradle-${{ runner.os }}-
|
||||
|
||||
- name: Unit tests
|
||||
run: ./gradlew :app:testDebugUnitTest
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
if: always()
|
||||
with:
|
||||
name: unit-test-report
|
||||
@@ -89,15 +105,13 @@ jobs:
|
||||
#
|
||||
# The range is the point: minSdk is 33 and targetSdk is 37, and the foreground
|
||||
# service type differs across it -- none below 34, dataSync at 34, mediaProcessing
|
||||
# from 35. Testing a single level would leave two thirds of that branch unexercised,
|
||||
# and running the range locally is what caught a test that had baked in an
|
||||
# assumption about the host's encoders.
|
||||
# from 35. Testing a single level would leave two thirds of that branch unexercised.
|
||||
#
|
||||
# FFmpeg is not built here. The AAR is committed under bin/, so a red run means the
|
||||
# code is broken rather than that a cross-compile hiccuped.
|
||||
# ---------------------------------------------------------------------------
|
||||
e2e:
|
||||
name: E2E API ${{ matrix.api-level }}
|
||||
name: E2E API ${{ matrix.label }}
|
||||
runs-on: ubuntu-latest
|
||||
needs: ffmpeg
|
||||
timeout-minutes: 60
|
||||
@@ -108,27 +122,33 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- api-level: 33
|
||||
system-image-api-level: 33
|
||||
- api-level: 34
|
||||
system-image-api-level: 34
|
||||
- api-level: 35
|
||||
system-image-api-level: 35
|
||||
- api-level: 36
|
||||
system-image-api-level: 36
|
||||
# API 37 is published as android-37.0, not android-37, so the image level has
|
||||
# to be given separately or the download resolves to no package at all.
|
||||
- api-level: 37
|
||||
system-image-api-level: "37.0"
|
||||
- label: "33"
|
||||
api-level: "33"
|
||||
- label: "34"
|
||||
api-level: "34"
|
||||
- label: "35"
|
||||
api-level: "35"
|
||||
- label: "36"
|
||||
api-level: "36"
|
||||
# API 37 ships as android-37.0. The emulator action installs
|
||||
# "platforms;android-${api-level}" and there is no platforms;android-37,
|
||||
# so a bare 37 fails during SDK setup before an emulator ever starts.
|
||||
# system-image-api-level alone does not fix it: that only names the image.
|
||||
- label: "37"
|
||||
api-level: "37.0"
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- uses: actions/setup-java@v4
|
||||
- uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
|
||||
with:
|
||||
distribution: temurin
|
||||
java-version: '17'
|
||||
|
||||
- uses: gradle/actions/setup-gradle@v4
|
||||
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ${{ env.GRADLE_CACHE_PATHS }}
|
||||
key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle.kts', 'gradle/libs.versions.toml', 'gradle/wrapper/gradle-wrapper.properties') }}
|
||||
restore-keys: gradle-${{ runner.os }}-
|
||||
|
||||
# Without this the emulator falls back to software rendering and takes minutes
|
||||
# longer to boot, when it boots at all.
|
||||
@@ -140,10 +160,9 @@ jobs:
|
||||
sudo udevadm trigger --name-match=kvm
|
||||
|
||||
- name: Instrumented tests
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
uses: reactivecircus/android-emulator-runner@a421e43855164a8197daf9d8d40fe71c6996bb0d # v2.38.0
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
system-image-api-level: ${{ matrix.system-image-api-level }}
|
||||
target: google_apis
|
||||
arch: x86_64
|
||||
profile: pixel_6
|
||||
@@ -154,10 +173,10 @@ jobs:
|
||||
disable-animations: true
|
||||
script: ./gradlew :app:connectedDebugAndroidTest
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
if: always()
|
||||
with:
|
||||
name: e2e-report-api${{ matrix.api-level }}
|
||||
name: e2e-report-api${{ matrix.label }}
|
||||
path: |
|
||||
app/build/reports/androidTests/
|
||||
app/build/outputs/androidTest-results/
|
||||
|
||||
Reference in New Issue
Block a user