mirror of
https://github.com/priyanshujain/sanderling.git
synced 2026-10-02 11:07:10 +00:00
checkout v4->v7, setup-go v5->v7, setup-node v4->v7, setup-java v4->v5, upload-artifact v4->v7, cache v4->v6, upload-pages-artifact v3->v5, deploy-pages v4->v5, setup-chrome v1->v2, setup-android v3->v4, goreleaser-action v6->v7. setup-bun and android-emulator-runner are already node24; buf-setup-action stays on its deliberate SHA pin. setup-chrome v2 resolves stable from Chrome for Testing rather than the official installer, so the ci.yml comment about the action's default no longer held.
279 lines
9.0 KiB
YAML
279 lines
9.0 KiB
YAML
name: folio
|
|
|
|
# One spec, three platforms. Dispatch-only: each job boots a device or a
|
|
# browser, builds the folio app for that platform, and runs
|
|
# examples/folio/sanderling/spec.ts against it.
|
|
#
|
|
# web and ios are expect-the-bug jobs: folio double-submits a transaction on a
|
|
# double tap, so the run is supposed to end with exit 2. Exit 0 means the fuzzer
|
|
# stopped finding a bug that is still there; exit 1 means the harness broke. The
|
|
# two are worth telling apart, which is why --exit-on-violation exits 2 and not
|
|
# 1.
|
|
#
|
|
# android is a health gate. It convicts in four runs out of five, which is real
|
|
# evidence but not a gate: the fifth would report a regression it had not found.
|
|
# The budget is set so the conviction it usually gets is reported as a bonus.
|
|
|
|
on:
|
|
workflow_dispatch:
|
|
inputs:
|
|
platforms:
|
|
description: which legs to run
|
|
type: choice
|
|
options: [all, android, ios, web]
|
|
default: all
|
|
seed:
|
|
description: seed override (0 = each job's calibrated seed)
|
|
default: "0"
|
|
duration:
|
|
description: wall-clock budget per run
|
|
default: 20m
|
|
max-steps:
|
|
description: step budget override (0 = each job's calibrated budget)
|
|
default: "0"
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
android:
|
|
timeout-minutes: 90
|
|
if: ${{ inputs.platforms == 'all' || inputs.platforms == 'android' }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v7
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: true
|
|
|
|
- name: Set up the JDKs
|
|
uses: actions/setup-java@v5
|
|
with:
|
|
distribution: temurin
|
|
# The metro gradle plugin folio builds with needs a 21 runtime; the
|
|
# sidecar toolchain pins 17. Both are installed so gradle can pick.
|
|
java-version: |
|
|
17
|
|
21
|
|
|
|
- name: Set up Android SDK
|
|
uses: android-actions/setup-android@v4
|
|
|
|
- name: Set up bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: "1.3.13"
|
|
|
|
- name: Cache Gradle
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: |
|
|
~/.gradle/caches
|
|
~/.gradle/wrapper
|
|
key: folio-gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
|
restore-keys: |
|
|
folio-gradle-${{ runner.os }}-
|
|
|
|
# Without this the emulator falls back to software rendering and every
|
|
# step costs several seconds.
|
|
- name: Enable KVM
|
|
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: Build the folio APK
|
|
run: ./gradlew :app:androidApp:assembleDebug
|
|
working-directory: examples/folio
|
|
|
|
- name: Build sanderling
|
|
run: make sanderling-android
|
|
|
|
- name: Fuzz folio on an emulator
|
|
uses: reactivecircus/android-emulator-runner@v2
|
|
with:
|
|
api-level: 34
|
|
target: google_apis
|
|
arch: x86_64
|
|
emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim
|
|
disable-animations: true
|
|
script: .github/scripts/folio-run.sh android
|
|
env:
|
|
SEED: ${{ inputs.seed != '0' && inputs.seed || '9' }}
|
|
MAX_STEPS: ${{ inputs.max-steps != '0' && inputs.max-steps || '200' }}
|
|
DURATION: ${{ inputs.duration }}
|
|
|
|
- name: Upload the run
|
|
if: always()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: folio-android
|
|
path: runs/
|
|
retention-days: 14
|
|
|
|
ios:
|
|
timeout-minutes: 90
|
|
if: ${{ inputs.platforms == 'all' || inputs.platforms == 'ios' }}
|
|
runs-on: macos-15
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v7
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: true
|
|
|
|
- name: Set up bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: "1.3.13"
|
|
|
|
# idb-companion is not in homebrew-core, only in facebook/homebrew-fb, so
|
|
# it has to be named by its full tap path. xcodegen and just are core.
|
|
- name: Install idb-companion, xcodegen and just
|
|
run: brew install facebook/fb/idb-companion xcodegen just
|
|
|
|
- name: Set up the JDKs
|
|
uses: actions/setup-java@v5
|
|
with:
|
|
distribution: temurin
|
|
# The metro gradle plugin folio builds with needs a 21 runtime; the
|
|
# sidecar toolchain pins 17. Both are installed so gradle can pick.
|
|
java-version: |
|
|
17
|
|
21
|
|
|
|
# The iOS app builds its Kotlin framework through the folio gradle
|
|
# project, which configures :app:androidApp and so needs an Android SDK
|
|
# even on this leg.
|
|
- name: Set up Android SDK
|
|
uses: android-actions/setup-android@v4
|
|
|
|
# Both asset tarballs are built by the prepare scripts, and the runner
|
|
# bundle is an xcodebuild of companion/Sources. Keyed on the scripts and
|
|
# the versions the Makefile embeds, so a later run reuses them.
|
|
- name: Cache the companion and runner bundles
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: |
|
|
internal/driver/ioscompanion/companionassets/assets
|
|
internal/driver/ioscompanion/runnerassets/assets
|
|
key: ios-assets-${{ runner.os }}-${{ hashFiles('internal/driver/ioscompanion/companionassets/prepare.sh', 'companion/prepare.sh', 'companion/project.yml', 'companion/Sources/**') }}
|
|
|
|
- name: Build sanderling
|
|
run: make sanderling-ios
|
|
|
|
- name: Boot a simulator
|
|
run: |
|
|
xcrun simctl boot "$IOS_DEVICE" || true
|
|
xcrun simctl bootstatus "$IOS_DEVICE" -b
|
|
env:
|
|
IOS_DEVICE: iPhone 16 Pro
|
|
|
|
- name: Build and install folio
|
|
run: just ios
|
|
working-directory: examples/folio
|
|
env:
|
|
IOS_DEVICE: iPhone 16 Pro
|
|
|
|
# `just ios` leaves the app running, and the run's own clear-data
|
|
# reinstall on top of a live app has raced FrontBoard into refusing the
|
|
# launch ("app.folio is unknown to FrontBoard") with the run then hanging.
|
|
- name: Stop the app before the run
|
|
run: xcrun simctl terminate booted app.folio || true
|
|
|
|
- name: Fuzz folio on the simulator
|
|
run: .github/scripts/folio-run.sh ios
|
|
env:
|
|
SEED: ${{ inputs.seed != '0' && inputs.seed || '7' }}
|
|
MAX_STEPS: ${{ inputs.max-steps != '0' && inputs.max-steps || '240' }}
|
|
DURATION: ${{ inputs.duration }}
|
|
IOS_DEVICE: iPhone 16 Pro
|
|
|
|
- name: Upload the run
|
|
if: always()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: folio-ios
|
|
path: runs/
|
|
retention-days: 14
|
|
|
|
web:
|
|
timeout-minutes: 60
|
|
if: ${{ inputs.platforms == 'all' || inputs.platforms == 'web' }}
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@v7
|
|
|
|
- name: Set up Go
|
|
uses: actions/setup-go@v7
|
|
with:
|
|
go-version-file: go.mod
|
|
cache: true
|
|
|
|
- name: Set up the JDKs
|
|
uses: actions/setup-java@v5
|
|
with:
|
|
distribution: temurin
|
|
# The metro gradle plugin folio builds with needs a 21 runtime; the
|
|
# sidecar toolchain pins 17. Both are installed so gradle can pick.
|
|
java-version: |
|
|
17
|
|
21
|
|
|
|
- name: Set up bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: "1.3.13"
|
|
|
|
- name: Cache Gradle
|
|
uses: actions/cache@v6
|
|
with:
|
|
path: |
|
|
~/.gradle/caches
|
|
~/.gradle/wrapper
|
|
key: folio-gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
|
restore-keys: |
|
|
folio-gradle-${{ runner.os }}-
|
|
|
|
- name: Set up Chrome
|
|
uses: browser-actions/setup-chrome@v2
|
|
with:
|
|
chrome-version: stable
|
|
|
|
- name: Allow Chrome under unprivileged user namespaces
|
|
run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0
|
|
|
|
- name: Verify headless Chrome starts
|
|
run: |
|
|
chrome --version
|
|
chrome --headless --no-sandbox --disable-gpu --disable-dev-shm-usage \
|
|
--dump-dom 'data:text/html,<title>ok</title>'
|
|
|
|
- name: Build the folio wasmJs app
|
|
run: ./gradlew :app:webApp:wasmJsBrowserDevelopmentExecutableDistribution
|
|
working-directory: examples/folio
|
|
|
|
- name: Build sanderling
|
|
run: make sanderling-web
|
|
|
|
- name: Fuzz folio in the browser
|
|
run: .github/scripts/folio-run.sh web
|
|
env:
|
|
SEED: ${{ inputs.seed != '0' && inputs.seed || '3' }}
|
|
MAX_STEPS: ${{ inputs.max-steps != '0' && inputs.max-steps || '240' }}
|
|
DURATION: ${{ inputs.duration }}
|
|
|
|
- name: Upload the run
|
|
if: always()
|
|
uses: actions/upload-artifact@v7
|
|
with:
|
|
name: folio-web
|
|
path: runs/
|
|
retention-days: 14
|