gliff 0.3.0 compiles natively on aarch64 and its workspace tests pass;
its x86 SIMD paths have scalar fallbacks. openh264 only invokes nasm for
x86 targets, so nasm becomes an x86_64-only makedepend.
Buzz (https://github.com/block/buzz, Apache-2.0) is a Tauri desktop app
on a Nostr relay. Upstream ships Linux builds for x86_64 only, so this
builds the desktop-v0.5.28 tag from source for x86_64 and aarch64,
following upstream's release-linux job: the six sidecar binaries from
the root workspace, then the app with --features mesh-llm. The updater
stays compiled out (its key and endpoint are unset), so pacman owns
updates. On the fast ring; the watch follows desktop-v* releases.
On aarch64, -march gains +crypto so sha2-asm can assemble its SHA
instructions; sha2 still detects them at runtime.
Built natively for aarch64 with bin/build and launched with isolated
HOME/XDG dirs: the window opens and renders the bundled frontend.
MediaPipe 1.1.0 links its SQLite memory and vector stores from prebuilt
archives built with Google's internal toolchain. They have no archive symbol
table, and once indexed they still need Google's libc++ (std::__u) and
internal symbols (__alloc_token_*__Znwm, sqlite_helpers, sqlite3_vector_init),
so the link of libmediapipe.so fails. Drop the semantic retriever's C API from
the library; mediapipe and its other tasks import and work as before.
sync-upstream.yml, sync-rebuilds.yml and track-branches.yml each opened one
batch PR, so one package with a failing build held back every other update
in it (#788, #837). All three now group their changes with
package-pr-groups.sh and hand them to package-prs.yml, which opens a PR per
package and arms auto-merge. Packages pinned from the same upstream branch
still share one. Green packages land on their own and only the failures stay
open; a red PR conflicting with master, and each lane's old batch PR, get
closed.
sync-upstream.yml loses its human-merged lane: it now pushes with the PAT
like the other two, so its builds start without an approval hold and its PRs
auto-merge when green. min_release_age still quarantines fresh releases. Its
approve job, approve-sync-push.cjs, and auto-merge-pr.cjs's exception for
auto/sync-upstream go with it.
The branch tracker stalled omarchy-dev and omarchy-settings-dev twice in a
week:
- All ~50 auto_merge packages rode one PR, so omasnap-git's failing smoke
suite kept the quattro pins unmerged from Oct 4 to Oct 8 (#788). Each
package now gets its own PR on auto/track-branches-<package>; packages
pinned from the same branch share one, since they move in lockstep. A run
closes tracker PRs that master has moved past, and the old single PR.
- A branch tip younger than min_release_age held the whole branch, so a
run that landed shortly after a quattro commit pinned nothing. The watch
now falls back along first-parent history to the newest commit that has
cleared the window, measured from clone time so siblings agree.
- The every-2-hours schedule fired every 6 to 9 hours in practice; run it
hourly.
The tracker opens its PR and then labels it, so a new tracker PR starts
two build runs at once. The second cancelled the first, whose always-run
`result` job then failed and left a red required check on the PR (#901)
until the surviving run finished. The tracker also force-pushes every two
hours, which would cancel long builds the same way the sync branches did.
Treat auto/track-branches like auto/sync-*: the newer run waits and
reuses the finished build's artifacts.
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
The controller created every builder without a DigitalOcean account key, so
DigitalOcean set a root password, emailed it to the token's owner, and turned
password logins on: one email and one password-reachable box per builder,
146 of them on Oct 8.
DO_SSH_KEYS lists account key IDs attached at creation (Ryan, DHH and Emir
in the template). It needs ssh_key:read on the controller's token; without it
every create is refused with 403, so it stays empty until the token has it.
Builders also turn password SSH off in cloud-init, which holds even while no
account key is attached, and Emir joins the operators whose GitHub keys reach
root.
Omarchy 4 no longer uses Elephant or the omarchy-walker meta package, and
omarchy-upgrade-to-quattro removes them; every channel serves Omarchy 4.0.4.
Nothing else here depends on them. walker itself stays.
Deleting a recipe stops it building but leaves it in the channel databases,
and the only removal tool worked on the old repository host's local tree.
Add bin/unpublish-packages, publish-artifact's counterpart: pull the channel
database, repo-remove every entry built from the named pkgbases, upload it.
Package files stay in the bucket. unpublish.yml runs it per channel and
architecture under the publish lock, for packages with no recipe on master.
The split in #869 sent every tree without an artifact to the rebuild job,
so a dispatch whose x86 halves were already published waited eight minutes
for eleven droplets that each found nothing to build in five seconds. Make
the publish job's plan check in the changes job, on its hosted runner,
before a builder is requested.
A one-package merge took 9 to 15 minutes to publish for about 15 seconds of
signing and upload. The run-wide concurrency group made each merge wait for
every earlier run, builds included (#854 waited 13 minutes behind an aarch64
batch), and the publish job waited about 3 minutes for a builder droplet
even when every package had a PR artifact and nothing needed building.
Build x86_64 trees that have no artifact in the rebuild job, one droplet per
entry, as aarch64 already builds there on arm64 runners: in parallel, with
no secrets, and outside any lock. The publish job now only collects
artifacts, signs and uploads, on ubuntu-latest with the GHCR builder image
(#850), and only it holds the publish group.
#867 auto-merged only PRs changing nothing outside pkgbuilds/, so it would
have left #854 open too: like voxtype-bin and the IPU7 camera before it,
Superwhisper added tests/superwhisper-bin-install.sh and one test.yml line
running it.
Count those as package changes: a new file under tests/, and a test.yml
change whose every line adds a ./tests/*.sh call. test.yml runs on PRs only.
Editing an existing test still needs a maintainer, since builder-images.yml
runs tests/build-isolation.sh on master with packages: write.
A package PR approved to build, by its author being trusted or by the
build-approved label, sat open after going green until someone merged it by
hand, so nothing it built was published. Enable GitHub's auto-merge on it
with PKGS_BOT_TOKEN, so the merge lands once the required checks pass and
starts publish.yml.
The trust rule is build-pr.yml's. Only PRs changing nothing outside
pkgbuilds/ qualify: a PR's own tooling never runs in its build, and after
merge it runs with the publish secrets. The upstream sync, which labels its
own PRs, stays on the reviewed lane. Removing build-approved withdraws the
auto-merge.
tobi/omatrack no longer exists on GitHub, so the pinned commit's archive is
404 and 1.8.6 cannot be rebuilt; the old repository host's sync deleted the
published 1.8.6-1 from R2, leaving edge at 1.2.0. A public copy serves the
same commit with an archive matching the pinned sha256 byte for byte.
pkgrel 2 gives the rebuild a new filename, so no cache can serve the
deleted 1.8.6-1 bytes for it.
A droplet DigitalOcean still reports as "new" never registers a runner, but
the controller counted it as one booting and created no replacement until
MAX_AGE_MINUTES. A publish job sat queued for minutes behind one in mkc1.
Delete droplets still provisioning after MAX_BOOT_MINUTES (10) and leave them
out of the live count, so the same tick creates a replacement.
sync-rebuilds now runs on the unattended lane like track-branches: it
opens the pkgrel bump PR with PKGS_BOT_TOKEN and enables auto-merge, so a
Qt (or any rebuild_on) update reaches users without a maintainer merge.
Branch protection still requires result, self-tests and build-isolation
to pass; a failed rebuild stays an open red PR.
The PAT is required because a GITHUB_TOKEN merge does not start
publish.yml. PAT pushes are not held for approval, so the approve job,
the build-approved label and the review request go away.
Co-authored-by: David Heinemeier Hansson <david@hey.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Keep builders coming when DigitalOcean sells out a droplet size
ric1 sold out of g5-32vcpu-64gb-50gb, and every create came back 422. curl -f
dropped the reason and set -e ended the tick, so builders only appeared when
capacity happened to free up, and the journal showed nothing but "curl: (22)".
Try each of SIZES in turn, logging DigitalOcean's refusal message, and fail
the tick only when every size is refused. Builders now power off however
start.sh exits, so a failed registration is reaped instead of counting as a
booting runner until MAX_AGE_MINUTES. The controller unit pulls the checkout
before each tick, so merged controller fixes reach the box.
* Create builders in any region that has the size in stock
ric1 sold out of g5-32vcpu-128gb-50gb within minutes of the box switching to
it. Builders need nothing from a particular region, so read DigitalOcean's
size catalog once per tick and try each of SIZES in every region it lists in
stock, REGIONS first if set. A refused pair is dropped for the rest of the
tick.
The native Hyprland plugin behind Omarchy's floating workspaces: themed
titlebars and edge snapping, built from a hyprbars fork. It is rebuilt
with every Hyprland change, since a plugin only loads into the exact
build it was compiled against.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Arch ships steam for x86_64 only, so on AArch64 `omarchy-pkg-add steam`
found nothing. This aarch64 build installs the same Valve launcher files
(desktop entry, icons, steam-devices udev rules) but replaces the x86
bootstrap with Valve's native arm64 client, which then updates itself from
the stable steam_client_linuxarm64 channel.
The bootstrap is just the client binary, which links only glibc, taken
from the manifest's bins_linuxarm64_linuxarm64 zip and pinned to the sha2
the manifest publishes. /usr/bin/steam unpacks it on first launch, keeps
the ~/.steam links the client requires, and restarts the client when it
exits with 42 after updating. Valve's bin_steam.sh cannot do this: it only
knows the ubuntu12_32 bootstrap.
Beyond Arch's dependencies the client needs gtk2 and libibus for its UI,
and lsof, which it runs to find its own IPC ports.
Valve's native arm64 Steam client loads GTK 2 from the host, and Arch
Linux ARM no longer ships it. Imported from the AUR recipe unchanged
apart from the architecture: x86_64 Steam brings its own copy in its
runtime, so gtk2 builds for aarch64 only.
Dropbox publishes its Linux client for x86_64 only, so on AArch64 the
dropbox package installs that same client and runs it under box64. Only
dropboxd changes: it execs the client through box64, and /usr/bin/dropbox
points at it, so the systemd units and `dropbox-cli start` both go through
the emulator. The x86_64 package is unchanged.
dropbox-cli is a Python script and becomes arch=any.
Dropbox publishes its Linux client for x86_64 only. box64 lets the aarch64
dropbox package run that client, and it has to be published before dropbox
can build for aarch64.
Pinned past v0.4.5-1 because that release crashes in its glib wrapper when
Dropbox starts its tray icon. It ships without a binfmt handler so it does
not compete with qemu-user-static-binfmt.
The upstream and rebuild syncs push with GITHUB_TOKEN, so GitHub holds
their build and test runs for approval. Their approve job only released
those runs once a maintainer had applied build-approved, and never ran
for the push that opened the PR, so every sync PR sat waiting.
The sync now labels its own PR build-approved, and the approve job runs
for created PRs as well as updated ones.
Ship Slack's own x86_64 build unchanged so Omarchy controls the package
on both architectures instead of relying on the AUR recipe for x86_64.
The Electron swap and native module replacements stay AArch64-only.
Slack only publishes an x86_64 Linux build, so the AUR recipe produces an
aarch64 package full of x86_64 binaries that cannot start. Run Slack's
application code on the AArch64 build of the Electron release it ships
with, replace the three native addons Slack requires at boot with
JavaScript equivalents, and drop the x86_64 addons it can do without.
The planner took 'git diff base.sha head.sha', a two-dot diff between
the current master tip and the PR head. For a PR that branched before
later merges, that counts every package master has changed since, so
the PR plans those too and builds its own stale copies of them: wasted
builds, and 'already up to date' Pack failures that turn the PR red for
packages it never touched. #397 (lazyjournal) planned 22 packages for a
one-package change. The checkout is shallow, so ask GitHub for the PR's
files, which are listed against the merge base.
'git status --short | head' under set -o pipefail: once the PR's
pkgbuilds/ differs from base in more than ten files, head exits, git
takes SIGPIPE and the step fails with 141 before anything builds. Every
PR branched far enough behind master hit it (omadev #423, llmman-bin
#428 and others on 2026-09-28). sed -n '1,10p' prints the same preview
and drains the stream.
Moving the whole module broke the rest of it: Writer::create needs a
runtime directory on a different filesystem from the copy, and with the
test root on /dev/shm none qualifies. Only
a_garbage_stream_falls_back_with_the_tree_untouched opens its manifest
in its own test dir, which the builder's /tmp refuses (EOPNOTSUPP).
0.3.5's copymanifest::tests::a_garbage_stream_falls_back_... opens its
anonymous (O_TMPFILE) manifest directly in its /tmp test dir, which the
x86_64 builder's /tmp refuses with EOPNOTSUPP. The sibling tests pass
because Writer::create falls back across directories. Same reason the
other filesystem_tests already run on /dev/shm; none of these spawn.
The upstream hook refused v0.3.5 as missing a required security fix. It
was not missing: copy_file_at now opens through
open_if_regular_with_meta(src.at, O_NOFOLLOW), which open_if_regular
wraps, and the gate's regex wanted '(' right after open_if_regular.
The gate dates from 0.1.x, when Omarchy carried four upstream security
patches and needed releases to prove they had absorbed them. Every
release since 0.1.5 has, and matching literal source lines has since
caught only renames (#488 and this one), never a regression. Keep the
real checks -- SHASUMS256.txt match, tarball root, minimum release age
-- and drop the greps.
Update written by bin/sync-upstream; the checksum matches upstream's
SHASUMS256.txt.
The first pins (quattro ee8ebf6, omasnap eb22bfe) date from 2026-09-21.
Edge has since published omarchy-dev from quattro 7b336b1 through a
manual rebuild, so merging the old pin would ship older code under a
higher version. Moved with the tracker's own code:
bin/sync-upstream --lane auto-merge (BYPASS_MIN_RELEASE_AGE=1)