CI: runs are too slow; investigate the build cache #74
Closed
opened 2026-10-06 23:37:33 +00:00 by twisla
·
1 comment
No Branch/Tag Specified
main
badges
ci-speed
keys-tables
help-key
devlog-console
console-setting
site-dev
site-howto
site-devlog
site-guide
site-security-txt
site
fix-release-polish
gitea-updates
coverage
ci
notes
f1
s1
m3
g1
m2
ota
v0.13.0
v0.12.0
v0.11.0
v0.10.0
v0.9.0
v0.8.1
v0.8.0
v0.7.0
v0.6.1
v0.6.0
v0.5.0
v0.4.0
v0.3.0
v0.2.1
v0.2.0
v0.1.0
Labels
Clear labels
area/apps
area/audio
area/build
area/cluster
area/gemini
area/gitea
area/gnss
area/ir
area/irc
area/lora
area/ota-debug
area/power
area/scripting
area/ssh
area/storage
area/ui
area/vpn
area/website
area/wifi
concern/memory
concern/security
Launcher and the apps in src/apps
Microphone, speaker, the codec, recording and playback
PlatformIO, Docker, scripts, partitions, sdkconfig
AtomS3 co-processors on Grove and the link protocol
GeminiService, the Gemini App, Saved Pages
The Gitea client: issues, releases, its TLS and its token
GnssService, the GNSS App, Tracks
The infrared LED and the IR Remote
IrcService and the IRC App
The Cap LoRa-1262 radio and the mesh
Updates, Probation, Safe Mode, Debug Console, crash reports
Battery, PowerService, sleep
Lua Apps from the SD card and their API
The SSH client and its terminal
StorageService, the SD card, Storage page
Canvas, widgets, dialogs, Toasts, fonts, keyboard
The WireGuard tunnel
The project website and its docs
WifiService, Wi-Fi Settings, Wi-Fi Tools
May push the heap towards its floors; measure on the device
TLS, signing, the debug token, trust on first use
kind
bug
Something that doesn't work as it should
kind
chore
Refactors, tooling, CI, scripts
kind
docs
README, CONTEXT, milestones, ADRs
kind
feature
Something new the device can do
priority
high
Next up
priority
low
Some day
priority
medium
Soon
status
blocked
Waiting on something else
status
needs-design
Needs a question round (Qnn) before code
status
ready
Designed; can be started
Milestone
No items
No Milestone
R1 Releases
Assignees
twisla (Clément Martin)
Clear assignees
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: twisla/roro9stack#74
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
CI runs take too long. Measured so far (docs/milestones/R1.md and this week's runs):
main(host tests and coverage only)For comparison, on the development machine an incremental firmware build takes 77 seconds, and the same build from a fresh checkout takes 6 minutes (362 s, measured on 2026-10-06 from an exported copy of
main).The likely cause is that difference: the framework is rebuilt with our own SDK settings (
custom_sdkconfig, ADR 0006, pioarduino's "hybrid compile"), and the result lives in the checkout's.pio/build folder. Every CI run starts from a fresh checkout, so it pays the framework rebuild every time. The Docker volumeroro9stack-piokeeps the toolchains and packages, but not that.To investigate, in this order:
platformio.inihasn't changed? If not, can it be (a build folder in the volume, keyed by a hash ofplatformio.iniand the SDK settings, so a changed setting still rebuilds)?mainrather than on every pull request, or tests and the firmware as two jobs in parallel if the runner has the cores (4).Constraints: a release must still be reproducible from its tag (a stale cache must never end up in a published file: the key has to cover everything that changes the output, or releases build clean and only pull requests use the cache); and the runner executes jobs on its own host with access to the signing secret (ADR 0008), so nothing from a fork's pull request may write to a cache a release reads.
Done when (to be refined): a pull request's run takes under 3 minutes when
platformio.inihasn't changed, the tag run's time is known step by step, and R1.md says what is cached, where, and what invalidates it.Done in pull request #76, merged into
main. The investigation and every measurement are indocs/milestones/R1.md.The cause: the firmware step took 358 s, of which 260 s rebuilt the framework that was already in the volume. The platform decides whether it matches by
sdkconfig.defaultsin the project folder, which is generated and not in git: no fresh checkout had it, so every run reinstalled and rebuilt the framework.What changed: that file is kept in the volume, inside the libraries it describes; the version is out of the compiler flags (one generated header); PlatformIO's build cache for pull requests' firmware; ccache for the host tests; a tag builds its firmware once.
On the runner:
src/or followed a framework rebuildThe target was a build under 60 seconds: 18 to 51.
Left as it is, on purpose: a release compiles its own sources from nothing (it reuses the rebuilt framework, not the build cache), so a tag's build stays around 90 seconds. Not measured: a tag's run, expected around 2.5 minutes instead of 13.5.
Not looked into: why the objects of
src/made by a run that rebuilds the framework can't be reused by the next one (it costs one 51-second run, rarely); and the tests' 36 seconds, most of it PlatformIO starting 51 test programs one by one.