-
Notifications
You must be signed in to change notification settings - Fork 0
156 lines (143 loc) · 7.38 KB
/
Copy pathandroid-ech.yml
File metadata and controls
156 lines (143 loc) · 7.38 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
name: android-ech
on:
push:
branches:
- main
pull_request:
schedule:
# Daily, in the afternoon UTC — last of the four scheduled workflows, hours after the
# container and network suites, so a regression in the snapshot's ECH or DoH handling
# shows up without anyone pushing to this repo and without several emulators competing
# with the rest of the day's jobs for runners.
- cron: '47 14 * * *'
workflow_dispatch:
inputs:
okhttpVersion:
description: 'OkHttp version under test (e.g. 5.5.0-SNAPSHOT)'
required: false
type: string
permissions:
contents: read
env:
GRADLE_OPTS: "-Dorg.gradle.jvmargs=-Xmx4g -Dorg.gradle.daemon=false -Dkotlin.incremental=false"
# Empty means the version pinned as ech-okhttp in libs.versions.toml, which is the
# snapshot: ECH needs DnsOverHttps.includeServiceMetadata, and no release has it yet.
OKHTTP_VERSION: ${{ inputs.okhttpVersion || '' }}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
android-ech:
name: android-ech (${{ inputs.okhttpVersion || 'pinned snapshot' }}, API ${{ matrix.apiLevel }})
runs-on: ubuntu-latest
timeout-minutes: 45
strategy:
# Each API level reports independently, for the same reason the version matrices do:
# the difference between them is the result we are after, and one emulator failing to
# boot must not take the others' results with it.
fail-fast: false
# The API level is declared once per row and used three times — by the emulator, by the
# artifact name, and by the metadata that tells the status page what the suite ran on.
# Two copies of an API level is how a page ends up confidently reporting the wrong device.
#
# Per-commit runs boot one emulator, API 37.1, because that is where ECH works and those
# runs are about this repository. The daily run also covers the latest 37.2 beta, so an
# upcoming Android quarterly release can expose an ECH regression before it is stable:
#
# 21 the module's minSdk, and OkHttp 5's. Every case skips — the fixture origin is
# TLS 1.3 only — but the run still installs the instrumentation APK and calls
# `OkHttp.initialize`, so a published artifact that stopped loading on the oldest
# supported Android is caught here rather than by whoever still ships to it.
# 30 an older level with TLS 1.3. What it asserts is the fallback: a config list
# OkHttp cannot use must produce an ordinary handshake to the real name, not a
# failed call.
# 35 the same, on a recent release used by devices in the field.
# 36 the same ECH fallback, plus Android 16's explicit Certificate Transparency opt-in.
# 37.1 the current stable image, where Certificate Transparency is enforced by default,
# `android.net.ssl.EchConfigList` exists, and ECH is actually performed.
# 37.2-beta3 the next quarterly release, exercising the same ECH path before release.
#
# Play Store images exist only for the newest level, so the older rows take the plain
# `google_apis` image — and API 21, which predates those, the `default` one.
matrix: >-
${{ fromJSON(
(github.event_name == 'schedule' || github.event_name == 'workflow_dispatch')
&& '{"include":[{"apiLevel":"21","target":"default","arch":"x86_64"},{"apiLevel":"30","target":"google_apis","arch":"x86_64"},{"apiLevel":"35","target":"google_apis","arch":"x86_64"},{"apiLevel":"36","target":"google_apis","arch":"x86_64"},{"apiLevel":"37.1","target":"google_apis_playstore_ps16k","arch":"x86_64"},{"apiLevel":"37.2-beta3","target":"google_apis_playstore_ps16k","arch":"x86_64"}]}'
|| '{"include":[{"apiLevel":"37.1","target":"google_apis_playstore_ps16k","arch":"x86_64"}]}'
) }}
steps:
- name: Checkout
uses: actions/checkout@v7.0.1
- name: Configure JDK
uses: actions/setup-java@v5.7.0
with:
distribution: 'temurin'
java-version: 21
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v6.3.0
- 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
# ECH is applied by OkHttp's Android platform through android.net.ssl.EchConfigList, so
# only the API 37 rows perform it; the rest assert what a device that cannot do ECH must
# do instead. API 36+ also runs the deterministic Certificate Transparency fixture cases.
# See the matrix above, EncryptedClientHelloTest, and CertificateTransparencyTest.
- name: Run the Android TLS suite against the fixture containers
uses: reactivecircus/android-emulator-runner@v2.38.0
with:
api-level: ${{ matrix.apiLevel }}
target: ${{ matrix.target }}
arch: ${{ matrix.arch }}
disable-animations: true
emulator-options: >-
-no-window
-gpu swiftshader_indirect
-noaudio
-no-boot-anim
-camera-back none
-memory 4096
script: android-ech/run-ech-test.sh
# What the XML can't say: which OkHttp version this resolved to, and which run
# produced it. The status page reports both workflows as one picture, keyed by the
# version under test, so each artifact has to identify itself.
#
# Unlike the container suites, this XML is laid out by device rather than by Gradle
# task, so the task is named here instead of being read off the path.
- name: Record Run Metadata
if: always()
run: |
version='${{ inputs.okhttpVersion }}'
if [ -z "$version" ]; then
version=$(sed -n 's/^ech-okhttp = "\(.*\)"$/\1/p' gradle/libs.versions.toml)
fi
mkdir -p android-ech/build
cat > android-ech/build/run-metadata.json <<JSON
{
"workflow": "android-ech",
"label": "${{ inputs.okhttpVersion || 'pinned-snapshot' }}",
"okhttpVersion": "$version",
"platform": "Android emulator API ${{ matrix.apiLevel }} · ${{ matrix.arch }}",
"variant": "API ${{ matrix.apiLevel }}",
"jobStatus": "${{ job.status }}",
"runNumber": ${{ github.run_number }},
"runUrl": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}",
"commit": "${{ github.sha }}",
"event": "${{ github.event_name }}",
"finishedAt": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
"task": "connectedAndroidTest"
}
JSON
# The suite's XML, for the status page, whatever colour the job ended up.
- name: Upload Test Results
if: always()
uses: actions/upload-artifact@v7.0.1
with:
name: android-ech-test-results-${{ inputs.okhttpVersion || 'pinned-snapshot' }}-api${{ matrix.apiLevel }}
path: |
android-ech/build/run-metadata.json
android-ech/build/outputs/androidTest-results/connected*/**/*.xml
android-ech/build/test-results/*.json
android-ech/build/reports/androidTests/connected/
retention-days: 30