Files
sanderling/.github/actions/folio-app/action.yml
T
pj 1d684a98eb ci: let a restored ios bundle survive make's mtime check
The cache restored and the build ran anyway: a restored tarball keeps the
mtime it was archived with while checkout stamps the sources, so make read
every bundle as stale. Both logged Cache hit and rebuilt regardless.

Dating the bundles after their sources fixes the lie where it is told.
Order-only prerequisites would have fixed it in make, but a laptop has no
cache key, so editing prepare.sh would silently embed the previous tarball.

The formula version joins the key because a hit now decides what gets
embedded, and the key was blind to the brew install: the 1.1.8 and 1.5.0.b2
runs shared a key.
2026-08-18 13:04:31 +05:30

114 lines
5.0 KiB
YAML

name: folio app
description: Install the toolchain folio needs on one platform, and build the app there.
inputs:
platform:
description: android, ios or web
required: true
runs:
using: composite
steps:
- name: Set up the JDKs
uses: actions/setup-java@b6effb05e454b25005698d916606bdc6ffcbf961 # v5.7.0
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, so this is needed off Android too.
# `make sanderling-android` wants it as well, for the sidecar JAR.
- name: Set up Android SDK
if: inputs.platform != 'web'
uses: android-actions/setup-android@40fd30fb8d7440372e1316f5d1809ec01dcd3699 # v4.0.1
- name: Cache Gradle
if: inputs.platform != 'ios'
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: folio-gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
folio-gradle-${{ runner.os }}-
# 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.
#
# The tap is checked out at the 1.1.8 formula because companionassets stages
# bin/ and Frameworks/ as siblings and names its output companion-1.1.8. The
# tap moved to 1.5.0, which drops the top-level Frameworks/, so floating on
# it broke the staging and made the embedded version string a lie. Moving to
# 1.5.0 is a companion change, not a CI one.
- name: Install idb-companion, xcodegen and just
id: idb
if: inputs.platform == 'ios'
shell: bash
env:
HOMEBREW_NO_AUTO_UPDATE: 1
run: |
brew install xcodegen just
brew tap facebook/fb
git -C "$(brew --repository facebook/fb)" checkout --quiet c0386793f59da10c619787f2aa18d938ef1d69c9
brew install facebook/fb/idb-companion
echo "companion-version=$(brew list --versions idb-companion | awk '{print $2}')" >> "$GITHUB_OUTPUT"
# 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. This has to
# land before `make sanderling-ios`, which is what consumes them.
#
# The formula version is in the key because it is the companion tarball's
# largest input and it lives outside the repository: prepare.sh copies
# whatever brew installed. Without it, a tap pin bumped on its own would hit
# a cache filled from the old formula and embed it under the new pin.
- name: Cache the companion and runner bundles
id: ios-assets
if: inputs.platform == 'ios'
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
internal/driver/ioscompanion/companionassets/assets
internal/driver/ioscompanion/runnerassets/assets
key: ios-assets-${{ runner.os }}-idb${{ steps.idb.outputs.companion-version }}-${{ hashFiles('internal/driver/ioscompanion/companionassets/prepare.sh', 'companion/prepare.sh', 'companion/project.yml', 'companion/Sources/**') }}
# A restored tarball keeps the mtime it was archived with, while the
# checkout stamps the prepare scripts and companion sources with checkout
# time, so make reads every restored bundle as older than its sources and
# rebuilds it. The key covers all of those sources exactly, so a hit means
# the bundles match them and the timestamps are the only thing lying.
- name: Date the restored bundles after their sources
if: inputs.platform == 'ios' && steps.ios-assets.outputs.cache-hit == 'true'
shell: bash
run: |
touch -c internal/driver/ioscompanion/companionassets/assets/*.tar.gz \
internal/driver/ioscompanion/runnerassets/assets/*.tar.gz
# Without this the emulator falls back to software rendering and every
# step costs several seconds.
- name: Enable KVM
if: inputs.platform == 'android'
shell: bash
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
if: inputs.platform == 'android'
shell: bash
working-directory: examples/folio
run: ./gradlew :app:androidApp:assembleDebug
- name: Build the folio wasmJs app
if: inputs.platform == 'web'
shell: bash
working-directory: examples/folio
run: ./gradlew :app:webApp:wasmJsBrowserDevelopmentExecutableDistribution