-
-
Notifications
You must be signed in to change notification settings - Fork 35
336 lines (303 loc) · 13.3 KB
/
build-quick.yml
File metadata and controls
336 lines (303 loc) · 13.3 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
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
name: Build quick (each platform)
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
pull_request:
branches:
- "**"
push:
branches:
- main
merge_group:
env:
DEBUG: 1
concurrency:
# if a workflow is run against the same ref, only one at a time...
# ...but allow different triggers to run concurrent (push, manual flake run, scheduled flake run...)
group: ${{ github.workflow }}-${{ github.ref }}-${{ github.event_name }}
cancel-in-progress: true
permissions:
contents: read
jobs:
# We may have a self-hosted runner available for macOS. Use it if so.
determine-macos-runner:
runs-on: ubuntu-latest
concurrency:
group: runner-determination
cancel-in-progress: false
outputs:
runner: ${{ steps.determine-macos-runner.outputs.use-runner }}
steps:
- name: Wait for possible parallel workflow run job startup lag
# After runner choice, the job that will use it has unavoidable job startup lag
# Wait for that job start / runner state change before we choose the runner for this run
run: sleep 30
- name: Use self-hosted runner if online and not busy, otherwise public runner
id: determine-macos-runner
uses: mikehardy/runner-fallback-action@v1
with:
organization: "ankidroid"
# 1- Choices are single labels, emitted array element 0 is used directly below
# 2- self-hosted runner label is configured in Tartelet app on runner host
# It is in format 'macos-*' to work with our label splitter below
primary-runner: "macos-selfhosted"
fallback-runner: "macos-26"
primaries-required: 1
fallback-on-error: true
# Actions secrets and Dependabot secrets are separate, and this is at org level::
# https://github.com/organizations/ankidroid/settings/secrets/dependabot
# https://github.com/organizations/ankidroid/settings/secrets/actions
github-token: ${{ secrets.MIKE_HARDY_ORG_ADMIN_KEY }}
# We want to generate our matrix dynamically
# Initial job generates the matrix as a JSON, and following job will use deserialize and use the result
matrix_prep:
needs: determine-macos-runner
env:
MACOS_RUNNER: ${{ needs.determine-macos-runner.outputs.runner }}
# Do not run the scheduled jobs on forks
if: (github.event_name == 'schedule' && github.repository == 'ankidroid/Anki-Android-Backend') || (github.event_name != 'schedule')
runs-on: ubuntu-latest
outputs:
matrix: ${{ steps.build-matrix.outputs.result }}
steps:
- id: build-matrix
uses: actions/github-script@v9
with:
script: |
// The determine-macos-runner step emits a JSON array of labels, but we need a single label
// We configured it above to emit a single label, for either runner choice, parse it out
const macosRunner = JSON.parse(process.env.MACOS_RUNNER)[0]
// by default, we will include all 3 platforms we test on
// "latest" would be easy everywhere, but "macos-15" isn't "latest" so we are specific there
let osArray = ["ubuntu-latest", "windows-latest", macosRunner]
let includeArray = [];
for(const os of osArray) {
// we do this work to define 'name' so we don't need to update branch protection rules
// if the os changes, the name is used in the expanded workflow run name, which is then
// used as a "required check" on branch protection merge rules, this keeps it stable
// even if "macos-15" changes to "macos-latest" in the future so we just change the list here
// but don't have to go into organization settings / protection rules etc etc
includeArray.push({"os": os, "name": os.split('-')[0]});
}
return {
"os": osArray,
"include": includeArray,
}
- name: Debug Output
run: echo "${{ steps.build-matrix.outputs.result }}"
# This uses the matrix generated from the matrix-prep stage
build:
needs: matrix_prep
# Do not run the scheduled jobs on forks
if: (github.event_name == 'schedule' && github.repository == 'ankidroid/Anki-Android-Backend') || (github.event_name != 'schedule')
strategy:
fail-fast: false
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
runs-on: ${{ matrix.os }}
timeout-minutes: 80
# Stable name so branch protection required checks set is stable regardless of runner version (-latest, -15, etc)
name: build (${{ matrix.name }})
steps:
- name: Liberate disk space (Ubuntu)
uses: jlumbroso/free-disk-space@main
if: contains(matrix.os, 'ubuntu')
with:
tool-cache: false
android: false
dotnet: true
haskell: true
large-packages: false
docker-images: true
swap-storage: false
- uses: actions/checkout@v6
- name: Install windows pre-requisites
# Windows requires git and rsync to build correctly, and specifies them from msys2
# msys2 is already in the windows action runner images, but not in path so add it
# use msys2 to install git and rsync per the README documentation in this repo
#
# note: zstd without absolute path is used in standard github cache restore though,
# and msys2 zstd is 100x slower than default, so remove msys2 zstd
if: contains(matrix.os, 'windows')
run: |
Add-Content $env:GITHUB_PATH "C:\msys64\usr\bin"
c:\msys64\usr\bin\pacman.exe -S --noconfirm git rsync
rm -force c:\msys64\usr\bin\zstd.exe
- name: Install macos self-hosted pre-requisites
# All platforms require cargo to build correctly, but our self-hosted tartelet
# image doesn't have cargo (or rustup) installed by default. Easily fixed
if: contains(runner.environment, 'self-hosted') && contains(runner.os, 'macOS')
run: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain none
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Ubuntu setup
# We get KVM set up on Ubuntu as we run the emulator there (only platform with nested virt)
# We also install some system software needed for the build on ubuntu
if: contains(matrix.os, 'ubuntu')
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
sudo apt update
sudo apt -y install liblzma-dev
- name: Fetch submodules
run: git submodule update --init
- name: Restore Rust Cache (Windows)
id: rust-cache-windows
uses: actions/cache/restore@v5
if: contains(matrix.os, 'windows')
with:
path: |
~/.cargo/registry
~/.cargo/git
target
anki/out/rust
anki/out/download
anki/out/extracted
# no node_modules, as it doesn't unpack properly
key: ${{ runner.os }}-rust-debug-${{ hashFiles('Cargo.lock', 'anki/Cargo.lock', 'anki/yarn.lock') }}
restore-keys: |
${{ runner.os }}-rust-debug
${{ runner.os }}-rust
- name: Restore Rust Cache (Unix)
id: rust-cache-unix
uses: actions/cache/restore@v5
if: contains(matrix.os, 'windows') == false && contains(runner.environment, 'self-hosted') == false
with:
path: |
~/.cargo/registry
~/.cargo/git
target
anki/out/rust
anki/out/download
anki/out/extracted
anki/out/node_modules
key: ${{ runner.os }}-rust-debug-${{ hashFiles('Cargo.lock', 'anki/Cargo.lock', 'anki/yarn.lock') }}
restore-keys: |
${{ runner.os }}-rust-debug
${{ runner.os }}-rust
- name: Read configured NDK version
run: |
cargo install toml-cli
ANDROID_NDK_VERSION=$(toml get gradle/libs.versions.toml versions.ndk --raw)
ANDROID_NDK_MAJOR_VERSION=$(echo $ANDROID_NDK_VERSION | cut -f1 -d.)
ANDROID_NDK_MINOR_VERSION=$(echo $ANDROID_NDK_VERSION | cut -f2 -d.)
ANDROID_NDK_MARKETING_VERSION="r${ANDROID_NDK_MAJOR_VERSION}"
if ! [ "$ANDROID_NDK_MINOR_VERSION" == "0" ]; then
alphabet="abcdefghijklmnopqrstuvwxyz"
ANDROID_NDK_MARKETING_MINOR_VERSION=$(echo ${alphabet:$ANDROID_NDK_MINOR_VERSION:1})
ANDROID_NDK_MARKETING_VERSION="${ANDROID_NDK_MARKETING_VERSION}${ANDROID_NDK_MARKETING_MINOR_VERSION}"
fi
echo "ANDROID_NDK_VERSION=$ANDROID_NDK_VERSION" >> $GITHUB_ENV
echo "ANDROID_NDK_MARKETING_VERSION=$ANDROID_NDK_MARKETING_VERSION" >> $GITHUB_ENV
shell: bash
- name: Setup Android NDK
uses: nttld/setup-ndk@v1
with:
ndk-version: ${{ env.ANDROID_NDK_MARKETING_VERSION }}
add-to-path: false
link-to-sdk: true
- name: Set NDK version (Unix)
if: contains(matrix.os, 'ubuntu') || contains(matrix.os, 'macos')
run: |
export ANDROID_NDK_LATEST_HOME="${ANDROID_SDK_ROOT}/ndk/${ANDROID_NDK_VERSION}"
echo "ANDROID_NDK_HOME=$ANDROID_NDK_LATEST_HOME" >> $GITHUB_ENV
echo "ANDROID_NDK_ROOT=$ANDROID_NDK_LATEST_HOME" >> $GITHUB_ENV
- name: Set NDK version (Windows)
if: contains(matrix.os, 'windows')
run: |
$env:ANDROID_NDK_LATEST_HOME = "$env:ANDROID_SDK_ROOT\ndk\$env:ANDROID_NDK_VERSION"
Add-Content -Path $env:GITHUB_ENV -Value ANDROID_NDK_HOME=$env:ANDROID_NDK_LATEST_HOME
Add-Content -Path $env:GITHUB_ENV -Value ANDROID_NDK_ROOT=$env:ANDROID_NDK_LATEST_HOME
- name: Configure JDK
uses: actions/setup-java@v5
with:
distribution: "temurin"
java-version: "21" # matches Anki-Android
- name: Setup N2
run: bash ./anki/tools/install-n2
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v5
timeout-minutes: 5
with:
# Only write to the cache for builds on the 'main' branches, stops branches evicting main cache
# Builds on other branches will only read from main branch cache writes
# Comment this and the with: above out for performance testing on a branch
cache-read-only: ${{ github.ref != 'refs/heads/main' }}
- name: Build all (current platform)
run: cargo run -p build_rust
- name: Check Rust (Unix)
if: contains(matrix.os, 'windows') == false
run: ./check-rust.sh
- name: Check Rust (Windows)
if: contains(matrix.os, 'windows')
run: ./check-rust.bat
- name: Run tests (Unit)
run: ./gradlew test rsdroid:lint --daemon
- name: Run tests (Emulator)
uses: reactivecircus/android-emulator-runner@v2
if: contains(matrix.os, 'ubuntu')
timeout-minutes: 30
with:
api-level: 23
target: default
arch: x86_64
profile: Nexus 6
script: |
touch adb-log.txt
$ANDROID_HOME/platform-tools/adb logcat '*:D' >> adb-log.txt &
adb emu screenrecord start --time-limit 1800 video.webm
sleep 5
./gradlew rsdroid-instrumented:connectedCheck
- name: Upload rsdroid AAR as artifact
uses: actions/upload-artifact@v6
if: '!cancelled()'
with:
name: rsdroid-aar-${{ matrix.os }}
if-no-files-found: error
path: rsdroid/build/outputs/aar
- name: Upload rsdroid-robo JAR as artifact
uses: actions/upload-artifact@v6
if: '!cancelled()'
with:
name: rsdroid-robo-${{ matrix.os }}
if-no-files-found: error
path: rsdroid-testing/build/libs
- name: Upload Emulator Log
uses: actions/upload-artifact@v6
if: ('!cancelled()' && contains(matrix.os, 'ubuntu'))
with:
name: ${{ matrix.name }}-adb_logs
path: adb-log.txt
- name: Upload Emulator Screen Record
uses: actions/upload-artifact@v6
if: ('!cancelled()' && contains(matrix.os, 'ubuntu'))
with:
name: ${{ matrix.name }}-adb_video
path: video.webm
- name: Save Rust Cache (Windows)
uses: actions/cache/save@v5
if: contains(matrix.os, 'windows') && github.ref == 'refs/heads/main'
with:
path: |
~/.cargo/registry
~/.cargo/git
target
anki/out/rust
anki/out/download
anki/out/extracted
# no node_modules, as it doesn't unpack properly
key: ${{ steps.rust-cache-windows.outputs.cache-primary-key }}
- name: Save Rust Cache (Unix)
uses: actions/cache/save@v5
if: contains(matrix.os, 'windows') == false && github.ref == 'refs/heads/main'
with:
path: |
~/.cargo/registry
~/.cargo/git
target
anki/out/rust
anki/out/download
anki/out/extracted
anki/out/node_modules
key: ${{ steps.rust-cache-unix.outputs.cache-primary-key }}