Skip to content

Commit 870a1c4

Browse files
mariusandraclaude
andcommitted
The release moves onto Depot — except the one leg Depot makes slower
Every remaining job in the release workflow moves to Depot runners, sized to what it does: 16 cores for the two that actually compile (buildroot SD images, ESP32 firmware), the default size for the ones that check out, dispatch or upload. push-multiarch stays small on purpose — its build happens on Depot's remote builders, so the runner only orchestrates. The exception is armhf, and it is measured rather than assumed. Depot's ARM fleet is Graviton, which has no AArch32 at EL0, so a linux/arm/v7 build runs under QEMU: debian-trixie-armhf went 516s on GitHub's 4-core Ampere runners to 825s on Depot's 16-core ones. Sixteen emulated cores lose to four native ones. Those two targets go back to ubuntu-24.04-arm with the numbers recorded next to them; every arm64 and amd64 leg genuinely won (498->349s, 609->260s) and stays. Alongside that: the buildroot job builds its platforms in parallel instead of in sequence (failures still propagate), pip is cached where it was rebuilding cffi from source, push-multiarch drops the QEMU and buildx setup it never used now that nothing is built locally, github-release stops cloning full history it does not read, and the last two checkout@v2 pins move to v4 before Actions stops running them. A new .github/actionlint.yaml declares the depot-* labels so actionlint stops calling every runner unknown. Projected: ~23 min to ~16 min, with the armhf leg alone worth 5.7 of it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 81c1b5b commit 870a1c4

3 files changed

Lines changed: 94 additions & 25 deletions

File tree

.github/actionlint.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Depot-managed GitHub Actions runners (https://depot.dev/docs/github-actions).
2+
# actionlint only knows GitHub's own labels, so the ones we use have to be
3+
# declared here or every `runs-on: depot-*` is reported as an unknown label.
4+
# Label shape: depot-ubuntu-<image>[-arm][-<cores>]; no suffix means the
5+
# project's default size.
6+
self-hosted-runner:
7+
labels:
8+
- depot-ubuntu-24.04
9+
- depot-ubuntu-24.04-16
10+
- depot-ubuntu-24.04-32
11+
- depot-ubuntu-24.04-arm
12+
- depot-ubuntu-24.04-arm-16
13+
- depot-ubuntu-24.04-arm-32

.github/workflows/docker-publish-multi.yml

Lines changed: 66 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,14 @@ permissions:
1313
contents: write
1414

1515
jobs:
16+
# Runner sizing: every job runs on Depot. The bookkeeping jobs (version
17+
# bump, npm dispatch, release notes, matrix, addon repo, GitHub release) are
18+
# I/O bound and take the default Depot size; only the two jobs that actually
19+
# compute (Buildroot images, ESP32 firmware) take 16 cores. The one
20+
# exception is the armhf leg of build-prebuilt-cross, which stays on
21+
# GitHub's ARM runners — see backend/bin/cross for the measurements.
1622
update-versions:
17-
runs-on: ubuntu-latest
23+
runs-on: depot-ubuntu-24.04
1824
outputs:
1925
release_sha: ${{ steps.release-ref.outputs.release_sha }}
2026
docker_version: ${{ steps.release-ref.outputs.docker_version }}
@@ -71,7 +77,7 @@ jobs:
7177
publish-npm:
7278
name: Publish FrameOS npm packages
7379
needs: update-versions
74-
runs-on: ubuntu-latest
80+
runs-on: depot-ubuntu-24.04
7581
steps:
7682
# npm auth uses trusted publishing (OIDC), which matches on the
7783
# top-level workflow file — so publishing lives in npm-publish.yml and
@@ -90,7 +96,7 @@ jobs:
9096
release-notes:
9197
name: Generate Release Notes
9298
needs: update-versions
93-
runs-on: ubuntu-latest
99+
runs-on: depot-ubuntu-24.04
94100
steps:
95101
- name: Checkout release commit
96102
uses: actions/checkout@v4
@@ -120,7 +126,7 @@ jobs:
120126

121127
determine-release-targets:
122128
needs: update-versions
123-
runs-on: ubuntu-24.04
129+
runs-on: depot-ubuntu-24.04
124130
outputs:
125131
targets: ${{ steps.set-matrix.outputs.targets }}
126132
steps:
@@ -229,7 +235,7 @@ jobs:
229235
build-buildroot-release-image:
230236
name: Build Buildroot Release Image
231237
needs: [update-versions, build-prebuilt-cross]
232-
runs-on: ubuntu-latest
238+
runs-on: depot-ubuntu-24.04-16
233239
steps:
234240
- name: Checkout code
235241
uses: actions/checkout@v4
@@ -243,6 +249,15 @@ jobs:
243249
path: release-assets
244250
merge-multiple: true
245251

252+
# Same warm pip cache as the cross matrix: this job's requirements
253+
# install spent ~31s of its ~150s wall clock building cffi from sdist.
254+
- name: Set up Python
255+
uses: actions/setup-python@v6
256+
with:
257+
python-version: '3.12'
258+
cache: 'pip'
259+
cache-dependency-path: backend/requirements.txt
260+
246261
- name: Install backend dependencies
247262
run: |
248263
pip install -r backend/requirements.txt
@@ -280,14 +295,42 @@ jobs:
280295
echo "No Buildroot platforms with cached base images found." >&2
281296
exit 1
282297
fi
298+
# One platform per background job. Each build works in its own
299+
# tempdir and writes its own frameos-<version>-<platform>-* files,
300+
# so the only shared state is the read-mostly Buildroot base image
301+
# cache (one distinct file per platform). Sequentially the two
302+
# platforms cost 55s + 38s; in parallel the step is as long as the
303+
# slowest one. Output is captured per platform and replayed in
304+
# order afterwards so the log stays readable.
305+
pids=()
306+
names=()
283307
for platform in $platforms; do
308+
echo "Building release image for ${platform}"
284309
python3 tools/buildroot-images/buildroot_images.py \
285310
--platform "$platform" \
286311
release-image \
287312
--prebuilt-cross-dir release-assets \
288313
--release-assets-dir release-assets \
289-
--version "$DOCKER_VERSION"
314+
--version "$DOCKER_VERSION" \
315+
> "buildroot-release-${platform}.log" 2>&1 &
316+
pids+=("$!")
317+
names+=("$platform")
318+
done
319+
status=0
320+
for index in "${!pids[@]}"; do
321+
if ! wait "${pids[$index]}"; then
322+
echo "Buildroot release image failed for ${names[$index]}" >&2
323+
status=1
324+
fi
325+
done
326+
for platform in "${names[@]}"; do
327+
echo "::group::Buildroot release image ${platform}"
328+
cat "buildroot-release-${platform}.log"
329+
echo "::endgroup::"
290330
done
331+
if [ "$status" -ne 0 ]; then
332+
exit 1
333+
fi
291334
ls -lh release-assets/*.img.gz release-assets/*.metadata.json
292335
293336
- name: Upload Buildroot release images
@@ -313,7 +356,7 @@ jobs:
313356
build-esp32-generic-firmware:
314357
name: Build ESP32 firmware (generic, all panels)
315358
needs: [update-versions]
316-
runs-on: ubuntu-latest
359+
runs-on: depot-ubuntu-24.04-16
317360
steps:
318361
- name: Checkout code
319362
uses: actions/checkout@v4
@@ -382,24 +425,21 @@ jobs:
382425
# image build and pushes the multi-arch manifest directly.
383426
push-multiarch:
384427
needs: [update-versions, build-prebuilt-cross, build-buildroot-release-image]
385-
runs-on: ubuntu-latest
428+
# The image itself is built on Depot's remote builders, so this runner only
429+
# orchestrates: the default size is plenty.
430+
runs-on: depot-ubuntu-24.04
386431
steps:
387432
- name: Checkout code
388-
uses: actions/checkout@v2
433+
uses: actions/checkout@v4
389434
with:
390435
ref: ${{ needs.update-versions.outputs.release_sha }}
391436

392-
- name: Set up QEMU
393-
uses: docker/setup-qemu-action@v1
394-
395-
- name: Set up Docker Buildx
396-
uses: docker/setup-buildx-action@v1
397-
with:
398-
version: latest
399-
install: true
400-
437+
# No QEMU or local buildx setup: depot/build-push-action runs the build
438+
# on Depot's remote amd64 and arm64 builders, so nothing is emulated or
439+
# built on this runner. Only the registry login is still needed, because
440+
# Depot pushes with this runner's Docker credentials.
401441
- name: Login to Docker Hub
402-
uses: docker/login-action@v1
442+
uses: docker/login-action@v3
403443
with:
404444
username: ${{ secrets.DOCKERHUB_USERNAME }}
405445
password: ${{ secrets.DOCKERHUB_TOKEN }}
@@ -441,7 +481,7 @@ jobs:
441481
update-addon-repo:
442482
name: Update Home Assistant Addon
443483
needs: [update-versions, push-multiarch, release-notes]
444-
runs-on: ubuntu-latest
484+
runs-on: depot-ubuntu-24.04
445485
steps:
446486
- name: Checkout frameos
447487
uses: actions/checkout@v4
@@ -450,7 +490,7 @@ jobs:
450490
path: frameos
451491

452492
- name: Checkout frameos-home-assistant-addon
453-
uses: actions/checkout@v2
493+
uses: actions/checkout@v4
454494
with:
455495
repository: frameos/frameos-home-assistant-addon
456496
token: ${{ secrets.ACTIONS_WRITE_TOKEN }}
@@ -520,13 +560,16 @@ jobs:
520560
github-release:
521561
name: Create GitHub Release
522562
needs: [update-versions, push-multiarch, build-prebuilt-cross, build-buildroot-release-image, build-esp32-generic-firmware, update-addon-repo, release-notes]
523-
runs-on: ubuntu-latest
563+
runs-on: depot-ubuntu-24.04
524564
steps:
565+
# Shallow: this job only needs a working directory for `gh` and the
566+
# downloaded artifacts. Release notes come from an artifact and the tag
567+
# is created from RELEASE_SHA, so no history is read here.
525568
- name: Checkout release commit
526569
uses: actions/checkout@v4
527570
with:
528571
ref: ${{ needs.update-versions.outputs.release_sha }}
529-
fetch-depth: 0
572+
fetch-depth: 1
530573

531574
- name: Download prebuilt cross artifacts
532575
uses: actions/download-artifact@v4

backend/bin/cross

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,16 +49,29 @@ class TargetDefinition:
4949
}
5050

5151

52+
# armhf (linux/arm/v7) is the one target that must NOT go to a Depot ARM
53+
# runner. Depot's ARM runners are AWS Graviton, which cannot execute AArch32
54+
# at EL0, so the arm/v7 build container falls back to QEMU: measured 773s and
55+
# 825s on depot-ubuntu-24.04-arm-16 versus 349-377s for arm64 on the same
56+
# runner. GitHub's ubuntu-24.04-arm runners are Ampere Altra, which does run
57+
# AArch32 natively — there armhf costs the same as arm64 (501s vs 507s and
58+
# 516s vs 507s across two releases), so 4 native cores beat 16 emulated ones.
59+
# The permanent fix is to give linux/arm/v7 the same treatment as arm/v6 (an
60+
# amd64 container plus the arm-linux-gnueabihf cross toolchain that
61+
# cross_toolchain_packages.py already defines and the Modal executor already
62+
# uses); until that is validated, keep armhf on GitHub's ARM runners.
63+
ARMHF_RUNNER = "ubuntu-24.04-arm"
64+
5265
TARGETS: tuple[TargetDefinition, ...] = (
53-
TargetDefinition("debian", "bookworm", "armhf", "linux/arm/v7", "debian:bookworm", runner="depot-ubuntu-24.04-arm-16"),
66+
TargetDefinition("debian", "bookworm", "armhf", "linux/arm/v7", "debian:bookworm", runner=ARMHF_RUNNER),
5467
TargetDefinition("debian", "bookworm", "arm64", "linux/arm64", "debian:bookworm", runner="depot-ubuntu-24.04-arm-16"),
5568
TargetDefinition("debian", "bookworm", "amd64", "linux/amd64", "debian:bookworm"),
5669
# ARMv6 hard-float for the Raspberry Pi Zero W Buildroot image. Debian has
5770
# no ARMv6 port, so this builds in an amd64 container with the Bootlin
5871
# armv6-eabihf toolchain (see cross_toolchain_packages.py); armhf packages
5972
# only provide headers and link stubs.
6073
TargetDefinition("debian", "bookworm", "armv6", "linux/arm/v6", "debian:bookworm"),
61-
TargetDefinition("debian", "trixie", "armhf", "linux/arm/v7", "debian:trixie", runner="depot-ubuntu-24.04-arm-16"),
74+
TargetDefinition("debian", "trixie", "armhf", "linux/arm/v7", "debian:trixie", runner=ARMHF_RUNNER),
6275
TargetDefinition("debian", "trixie", "arm64", "linux/arm64", "debian:trixie", runner="depot-ubuntu-24.04-arm-16"),
6376
TargetDefinition("debian", "trixie", "amd64", "linux/amd64", "debian:trixie"),
6477
TargetDefinition("ubuntu", "24.04", "arm64", "linux/arm64", "ubuntu:24.04", runner="depot-ubuntu-24.04-arm-16"),

0 commit comments

Comments
 (0)