Releases: yoebuild/yoe
v0.10.5
- Build progress bar. While a build is in flight the feed banner at the top
of the screen swaps out for a live progress bar showing the percentage done,
how many units have finished, and how many are still to build. The bar
disappears and the feed banner returns once the build settles.
To update, run: yoe update
Or download the binary for your architecture and place it in your PATH.
Note: Yoe is in heavy development. We recommend cleaning your build directory and re-creating projects (yoe init) with each new release.
v0.10.4
- Search bar clears with
Ctrl+U. Readline's kill-line shortcut wipes the
query input back to a blank bar in one keystroke — faster than holding
Backspace or pressing\to snap to the saved default. Live-applied like a
backspace, so the unit list updates to "showing all" immediately. - Tab completions show up under the query bar. When the search input can't
be advanced further (multiple equally-good matches), the candidate list now
renders as a vertical column directly under the query bar — closer to the
cursor than the previous horizontal blob at the bottom of the screen, and
easier to scan for the next character to type. Long lists truncate with a "(N
more — type a letter to narrow)" hint. - Fresh projects from
yoe initbuild out of the box. The generated
PROJECT.star now pinsxzto the Alpine module, matching the canonical
e2e-project template. Without this, kmod's depmod failed at image-assembly
time because module-core's xz is static-only and doesn't ship liblzma.so.5. - Switching a unit/module to dev mode transfers far less data. The
depth-limited fetch (last 100 / 1000 commits,last year,last month) now
narrows to the unit's pinned ref instead of fanning out across every branch
the upstream tracks, and adds--filter=blob:noneso file content comes down
on demand instead of all at once. For a Linux-kernel-sized repo that's the
difference between a multi-gigabyte fetch and tens of megabytes;git logand
git blamestill work, and missing blobs are fetched lazily when needed. - TUI
/makes refining an existing query faster. When you press/and
the active query is non-empty, the bar opens with a trailing space so you can
immediately type the next term — no need to press End or space first. A blank
query still opens empty. - Toggle any unit or module between pinned and dev mode from the TUI. A new
SRC column on the units and modules tabs surfaces whether each source dir is
yoe-managed (pin), tracking upstream (dev), has commits beyond upstream
(dev-mod), or has uncommitted edits (dev-dirty). Pressuon a unit's
detail page (or a module row) to switch between pin and dev — yoe asks whether
to rewrite origin to SSH, then how much history to fetch (full / last 1000
commits / last 100 commits) so the Linux kernel's full history doesn't have to
come down every time. A spinner runs while the fetch is in flight so you can
see something is happening. Once you're happy with adev-modHEAD,P
captures it back into the.starpin so other people building the project
pick it up. Adev*unit is left untouched at build time, soyoe build
won't overwrite your working tree or undo in-flight changes. - TUI size column no longer overflows on big artifacts. Sizes like a 1003
KiB kernel image render as1003Kinstead of1003.4K, keeping the column
aligned. The decimal still shows for small values (e.g.9.9K,1.2M) where
it carries useful precision. - Device hostname now matches the machine, not the image. A fleet of
raspberrypi4s flashed withdev-imageno longer all answer to
yoe-dev.local; each board comes up as<machine>.local(e.g.
raspberrypi4.local,qemu-x86_64.local) so they're distinguishable on the
LAN out of the box. Sethostname = "..."on an image to override (e.g. a
branded kiosk image). - TUI help bar reflects the active mode. While typing in the search bar, the
bottom help row swaps to the keys that actually work there (type filter,
tab complete,⌫ delete,enter apply,esc cancel) instead of pretending
b build,q quit, etc. still fire. Out of search-edit it shows the
navigation shortcuts as before. - Tab in the search bar always shows progress. When Tab can't advance the
input (multiple candidates with no common prefix to extend — most visibly when
you've just opened the bar, or typed a single ambiguous letter), the candidate
list now flashes in place of the help bar instead of silently doing nothing.
Single-candidate completions still splice in. Empty pool flashes "no
completions".
To update, run: yoe update
Or download the binary for your architecture and place it in your PATH.
Note: Yoe is in heavy development. We recommend cleaning your build directory and re-creating projects (yoe init) with each new release.
v0.10.3
docker-imagestarts dockerd at boot. Pulls in Alpine'sdocker-openrc
package (which ships/etc/init.d/dockerand the/etc/conf.d/dockerconfig
template upstream maintains) and adds the default-runlevel symlink at
packaging time, sodockerdis supervised on a fresh boot without manual
rc-update add.prefer_modulesonproject()pins a unit to a specific module. Set
prefer_modules = {"xz": "alpine"}inPROJECT.starand thexzunit
registers only frommodule-alpine, regardless of which module wins the
default last-module shadowing. Use it whenmodule-core's source-built
version of a package is broken or under-configured and the Alpine prebuilt is
the right answer; the shadow appears on the Diagnostics tab the same way an
ordinary cross-module shadow does.modprobeworks on the booted system. Image assembly now runsdepmod
inside the rootfs afterapk add, so/lib/modules/<ver>/carries a real
modules.depindex instead of just bare.kofiles. The kernel build still
skips depmod (the toolchain container has no copy of it); the rootfs's own
kmodsupplies it via chroot.- Kernel ships container-runtime CONFIG by default. A
container.cfg
fragment (overlayfs, bridge/veth, the full netfilter chain including
NFT_COMPATso iptables-nft works, IPv4 + IPv6 NAT, namespaces, seccomp,
cgroup BPF, eBPF) is merged into the kernel's defconfig during the linux
unit's build, sodockerdandcontainerdstart cleanly without per-image
kernel customisation. The cost on non-container images is a few hundred KB of
kernel modules that nothing references. - TUI flash remembers the last device. Picking and confirming a flash target
writesflash_device = "/dev/sdX"tolocal.star, and re-entering the flash
view positions the cursor on that device when it shows up in the candidate
list. Reflashing the same SD card or USB stick is nowf→ Enter →y. /etc/os-releasenow reports the project version.VERSION,
VERSION_ID, andPRETTY_NAMEcome fromversion = "..."inPROJECT.star,
so tools that read/etc/os-release(and humans on the device) can tell which
build is running. Templates can reach the value as{{.project_version}}.- Image rows in the TUI show the project version. The
image()class
defaults each image unit'sversiontoPROJECT_VERSION(from
PROJECT.star), so the VERSION column in the units table — which used to be
blank for image rows — now shows the version the resulting.imgrepresents. - OpenRC replaces the old rcS startup script. Services now boot under
Alpine's OpenRC service manager, so they get dependency ordering, supervised
start/stop, and proper status/restart commands (rc-service sshd restart,
rc-status) instead of the silent run-everything-in-/etc/init.d/S*pattern.
Units declareservices = ["sshd"](plain names, noS40prefix) and the
resulting apk drops the script in/etc/init.d/plus a runlevel symlink in
/etc/runlevels/default/. - Source-built libraries auto-declare what they ship. Each
.apkyoe builds
from a destdir now listsprovides = so:<soname>=<ver>-r<rel>for every
shared library in the package, matching Alpine's convention. Alpine prebuilt
packages whose upstream PKGINFO declaresdepend = so:libcrypto.so.3or
similar now resolve cleanly against yoe-source-builtopenssl,zlib, etc. —
no manual SONAME bookkeeping in the.starfile. module-alpinepackages now ship with their upstream metadata intact.
Prebuilt Alpine apks pass through yoe's pipeline verbatim — only the signature
is swapped for the project's key — soreplaces,provides,triggers, and
post-install hooks (busybox applet symlink creation, sshd privsep user adds,
…) reach the on-target system the way Alpine intended. Image assembly drops
--no-scriptsso those hooks actually run; this fixes the no-/sbin/init
kernel panic that hit when relying on Alpine's busybox.- Alpine packages no longer end up with doubled-
-rfilenames.alpine_pkg
splits upstream pkgver like1.2.5-r11into yoe's separate version + release
fields, so the published apk ismusl-1.2.5-r11.apkinstead of
musl-1.2.5-r11-r0.apk. Apk's solver finds the file at the URL it constructs
from the index, fixing "package mentioned in index not found" on every
module-alpine package. - noarch passthrough packages route correctly across the repo. apk-tools
constructs fetch URLs from PKGINFO'sarch =field (always
<base>/noarch/<file>for noarch packages), but its solver only reads one
arch's APKINDEX per repo. Three coordinated fixes:- Passthrough alpine_pkg units with
arch = noarchpublish under
<repo>/noarch/(where apk fetches them from). - Each per-arch
APKINDEXnow scans the siblingnoarch/tree at generation
time, so the solver sees noarch packages from any arch's perspective. - A noarch publish refreshes every per-arch
APKINDEX(since each one
references those noarch entries). - Cache validation also looks under
noarch/for the published apk, so noarch
units don't rebuild on every invocation.
- Passthrough alpine_pkg units with
- base-files ships an Alpine-style runlevel baseline. OpenRC services
cgroups,devfs,dmesg(sysinit),bootmisc,hostname,modules,
sysctl(boot), andmount-ro,killprocs(shutdown) are now wired into the
rootfs via/etc/runlevels/<level>/<svc>symlinks, so a fresh image boots
with the hostname set, kernel modules loaded, the cgroup hierarchy mounted (so
container runtimes don't trip on "Devices cgroup isn't mounted"), and shutdown
that unmounts cleanly. - TUI SIZE column for images shows installed content, not partition size. An
image whose machine reserves a 600 MB rootfs partition now reports the ~50 MB
actually populated byapk add, so you can see what your image contains
rather than how big the partition was sized. - New
docker-image. Builds a dev-image-style rootfs that also ships Docker
(engine, CLI, buildx, containerd, runc) so you can poke at the docker
userspace on a yoe-built system. Kernel and init still need the container
pieces beforedockerdcan actually launch a container — that's the next
step. - Files tab on the unit detail page. Tab into a sortable list of every file
the unit installs and its on-disk size — easy to spot the biggest payloads or
confirm a binary actually landed where you expected without leaving the TUI. - Drop into a shell on the source. Press
$in the units tab or detail page
to open a shell in the unit's checked-out source directory, or in the Modules
tab to open a shell in a module's clone — handy forgit status, spot-edits,
or running an out-of-tree command without leaving the TUI. VERSIONcolumn in the unit table. Each row now shows the unit's declared
version next to its module, sortable from theocycle, and the same version
appears next to the unit name on the detail page — so spotting a stale pin or
confirming what's about to build is a glance, not a file open.- TUI auto-follow no longer yanks the cursor mid-navigation. The units list
scrolls to whatever is actively building only when you're idle — pressing j/k
or typing a query keeps the cursor where you put it, whilebstill hands
control back to the build so you can watch what's compiling.
To update, run: yoe update
Or download the binary for your architecture and place it in your PATH.
Note: Yoe is in heavy development. We recommend cleaning your build directory and re-creating projects (yoe init) with each new release.
v0.10.2
yoe initlists module-core last so it wins shadowing. New projects now
order modules so module-core's source-built units (busybox, openssl, …) take
precedence over Alpine prebuilts and over module-rpi, avoiding image-assembly
path collisions. Existing projects can movemodule-coreto the end of their
modules = [...]list inPROJECT.starto get the same behavior.- Images with
network-configand busybox build again. A path collision on
/usr/share/udhcpc/default.script(busybox ships an example script there;
network-config installs the real one) was abortingapk addat image-assembly
time.
To update, run: yoe update
Or download the binary for your architecture and place it in your PATH.
Note: Yoe is in heavy development. We recommend cleaning your build directory and re-creating projects (yoe init) with each new release.
v0.10.1
- TUI flash offers
sudo chownon permission denied. Previously the flash
view just showed "permission denied" and dead-ended — matching the CLI's
behavior, the TUI now prompts to runsudo chown $USER /dev/...and retries
the write automatically. - TUI home screen has tabs. Press
tabto cycle between Units (the existing
list), Modules (declared modules with git status), and Diagnostics (shadowed
units and duplicateprovides). The diagnostics tab carries a count badge so
issues are visible from any tab. --allow-duplicate-providesis on by default. No more passing the flag on
every yoe invocation while thelinux-firmware-*fan-out keeps tripping the
strict check.- Modules renamed:
units-*→module-*.units-core,units-rpi,
units-alpine, andunits-jetsonare nowmodule-core,module-rpi,
module-alpine, andmodule-jetson. Updatemodule(...)URLs and any
path = "modules/units-..."entries in yourPROJECT.star. helixactually runs on the device. Was previously bundled as a
glibc-linked binary that failed silently withhx: not found; now uses
Alpine's musl build.- Images that include
apk-toolsorlibcurlbuild again. A collision
between the source-builtca-certificatesand Alpine's
ca-certificates-bundlewas abortingapk addat image-assembly time. SIZEcolumn in the TUI updates as each unit finishes. No more waiting
for the whole image to complete before transitive deps show their size, and
partial sizes survive a mid-build failure.- Modules show their declared name. The TUI's
MODULEcolumn and any
diagnostic that names a module now use the name set inMODULE.star's
module_info(name = ...)instead of the path basename — so a module
referenced viapath = "modules/units-core"displays ascoreif that's what
it calls itself. Falls back to the path basename when nomodule_infois
declared. dev-imageshipshelixinstead ofvim. Drops the editor entry that
was unintentionally resolving to Alpine'sgvim(and its X11/GTK runtime
closure), keeping the image lean.- Unit detail shows what uses it and what it pulls in. The detail page now
opens with two new sections above the build log: USED BY traces back
through runtime_deps to show which packages you wrote inimage()pulled this
unit in, e.g.dev-image → yazi → libpango → cairo, so you can answer "why is
this on my device?" at a glance. PULLS IN shows the unit's runtime-deps as
a tree. Drilling into an image starts from exactly the packages you wrote in
image()(plus machine packages), then expands each one to show what it drags
in transitively. - TUI layout overhaul. Title and banners stay put when the list is long, the
help bar is always the last line, status messages flash in its place, and
pressing/turns theQuery:header itself into the search input. Long unit
names get an ellipsis instead of breaking column alignment. - Sort columns from the keyboard. Press
oto cycle the unit table through
NAME → CLASS → MODULE → SIZE → DEPS → STATUS;Oflips direction. The
active column shows↑or↓next to its label. - Help bar highlights shortcut keys. Each shortcut letter renders in amber
matching[yoe], so you can scan keys without reading every word. - Cursor follows the work. The TUI opens with the cursor on the default
image, jumps to whatever unit is currently building, and the cursor's full
unit name is always visible just above the help bar. - Configure the default image per developer.
local.staraccepts
image = "..."to overridedefaults.image. Pick an image from the new
Image entry in Setup (s) and the choice is saved — and the active search
re-anchors toin:<image>. Flows throughyoe run,yoe config show, and
the TUI. - More columns in the unit table. Each row now also shows the module that
owns the unit (after shadow resolution), its install size after build (.img
size for images), and how many units it pulls into a runtime closure — so
bloat is easy to spot before flashing. yoe --helpworks and lists global options.--help,-h, andhelp
all print usage, including--project,--show-shadows, and
--allow-duplicate-provides.
To update, run: yoe update
Or download the binary for your architecture and place it in your PATH.
Note: Yoe is in heavy development. We recommend cleaning your build directory and re-creating projects (yoe init) with each new release.
v0.10.0
Errata: due to an issue in the alpine module, you must currently run with:
yoe --allow-duplicate-provides.
- BREAKING CHANGE This project has been moved to a new Github org:
https://github.com/yoebuild.yoe updatefrom previous versions will not work
and you will need to download and manually install the 0.10.0 binary. - TUI search is now a query language; defaults to your image's working set.
Press/to filter bytype:,module:,status:, orin:(closure of any
unit), in addition to plain substring search.Tabcompletes field names and
values. The TUI starts filtered toin:<your-default-image>, so a project
with thousands of units shows just what your image needs. PressSto save
the current query tolocal.staras the new default; press\to snap back
to it. The header showsQuery: … Units: N/Mso you always know how many of
the project's units the current filter is showing. - Use
apk-toolsfrom alpine layer for now. It is built with docs. yoe repo cleandrops stale.apkfiles. Removes any.apkin the
project's local repo whose name+version no longer matches a current unit (unit
deleted, version bumped, release suffix changed) and re-signs the regenerated
APKINDEX. Without this,apk addhappily picks the highest- versioned
candidate even when that candidate is leftover from a since-deleted unit —
which is how aLUA=no-builtapk-tools("apk has been built without help")
could keep winning over Alpine's prebuilt long after the source unit was
removed.- Source-built
opensslno longer collides with Alpine'slibcrypto3/
libssl3. Theopensslunit inunits-corenow declares
provides = ["libcrypto3", "libssl3"], so any package whoseruntime_deps
reachlibcrypto3orlibssl3(e.g.units-alpine'sapk-tools) routes
back to the source-built openssl instead of pulling Alpine's split libcrypto3
/libssl3 packages alongside. Without this, image-timeapk addaborted with
trying to overwrite usr/lib/libcrypto.so.3 owned by openssl-3.4.1-r0. units-alpinenow lives in its own repo.yoe initand the e2e project
pullunits-alpineandunits-jetsonfromgithub.com/yoebuild/instead of
carrying units-alpine inside this repo. Existing projects with
path = "modules/units-alpine"should switch to a remotemodule(...)ref.- Shadow notices are off by default. Cross-module unit shadowing and
providesoverrides no longer print a stderr notice on every load. Pass
--show-shadowsto see them when you actually want to audit which module won. --allow-duplicate-provideslets multiple units share a virtual. When
set, units in the same module may declare the sameprovides(apk-style "any
of these satisfies"); the first one wins forPROVIDESlookup. Needed for
units-alpine'slinux-firmware-*fan-out, where ~100 packages all provide
linux-firmware-any.patches=resolves relative to the unit's own .star file directory. A
unit can now ship its patches alongside its definition (e.g.
units/bsp/foo/patches/0001-fix.patchnext tounits/bsp/foo.star), and the
samepatches=["patches/foo/0001-fix.patch"]works whether the unit is loaded
from a local module override or a fetched remote module. Previously patches
were resolved against the project root, which meant module-shipped patches
couldn't be found unless every consumer copied them.
To update, run: yoe update
Or download the binary for your architecture and place it in your PATH.
Note: Yoe is in heavy development. We recommend cleaning your build directory and re-creating projects (yoe init) with each new release.
v0.9.1
yoe deploy <unit>now installs the package's runtime deps too.
Previously it only built and published the named unit, so deploying a package
withruntime_depsoutside what the device already had on disk failed with a
crypticapk adderror likesqlite (no such package). Deploy now walks the
full runtime closure (the same expansionimage()does at image-build time),
so every transitive dep ends up in the feed beforeapk addruns.- Deploy refreshes the device's apk index every time. The on-device
apk updatestep now usesapk --no-cache update, forcing a refetch of every
repo'sAPKINDEXinstead of trusting whatever is in/var/cache/apk/.
apk-tools 2.x can otherwise hold onto a stale index across a yoe-dev rebuild
and silently miss packages you just published. - Added sqlite unit
To update, run: yoe update
Or download the binary for your architecture and place it in your PATH.
Note: Yoe-NG is in heavy development. We recommend cleaning your build directory and re-creating projects (yoe init) with each new release.
v0.9.0
- New design doc on libc and init choice.
docs/libc-and-init.mdlays out
why yoe is musl + OpenRC + Alpine today, where that stack works (gateways,
IoT, networking gear), where it doesn't (Jetson, vendor BSPs, Adaptive
AUTOSAR), and the planned rootfs-base abstraction that would let a single yoe
codebase serve both Alpine and Ubuntu/L4T projects. Establishes the invariant
that yoe stays apk-native on every target — Debian-derived bases get a
deb_pkgconversion class, not dpkg/apt on the device. - Pull packages straight from Alpine. A new
units-alpinemodule wraps
prebuilt Alpine.apkfiles as yoe units via thealpine_pkg()class — no
source build, no patches, just fetch + verify + repack.musland
sqlite-libsship today; add more by pinning a version and sha256. muslnow comes from Alpine. The hand-rolled musl unit that copied the
dynamic linker out of the build container is gone;muslis now an Alpine apk
wrapped byalpine_pkg(). Output is byte-identical to the Alpine package
other projects already ship..apkURLs work as a source type. Yoe's source workspace now recognises
.apkextensions and bare-copies them so the unit's install task can extract
the multi-stream gzip with GNU tar. Bare-copied sources also keep their URL
filename, so install steps can reference the file by name instead of by cache
hash.- Override an upstream unit by name. Define a unit with the same name in a
higher-priority module (or in the project itself) and it shadows the upstream
one — noprovidesboilerplate needed. The project root beats every module,
and later modules beat earlier ones. A notice on stderr tells you which one
won. - Deploy from the TUI. Press
Don a non-image unit to deploy it to a
running yoe device — host prompt is pre-filled from the last-used target,
build + ssh + apk add output stream into the view, and the host is saved back
tolocal.staron success. - Deploy actually updates the device's apk index.
yoe deployand
yoe device repo addpreviously wrote to
/etc/apk/repositories.d/yoe-dev.list, which apk-tools 2.x ignores. They now
append a marker block to/etc/apk/repositoriesso the nextapk update
actually fetches the dev feed andapk add <unit>finds the freshly built
package. - TUI starts a feed automatically. When you launch
yoe, it brings up the
project's apk feed (or reuses one already running on the LAN), so devices
configured withyoe device repo addcan pull packages without any extra
setup. Status is shown in the header. - SSH target shorthand.
yoe deployandyoe device repo {add,remove,list}
accept[user@]host[:port]— e.g.yoe device repo add localhost:2222for a
QEMU vm oryoe deploy myapp pi@dev-pi.local:2200. The--ssh-portflag is
gone. - APK live deployment tooling.
yoe deploy <unit> <host>builds and
installs a unit on a running yoe device with full apk dependency resolution.
Pair withyoe serveandyoe device repo addto keep a device pointed at
your dev feed for ad-hocapk addfrom the device. See
docs/feed-server.md.
To update, run: yoe update
Or download the binary for your architecture and place it in your PATH.
Note: Yoe-NG is in heavy development. We recommend cleaning your build directory and re-creating projects (yoe init) with each new release.
v0.8.8
To update, run: yoe update
Or download the binary for your architecture and place it in your PATH.
Note: Yoe-NG is in heavy development. We recommend cleaning your build directory and re-creating projects (yoe init) with each new release.
v0.8.6
- Container runtime build path documented.
docs/containers.md now walks through what it takes to
ship Docker, containerd, and runc on a musl yoe rootfs — why prebuilt "static"
binaries don't work, the per-component build breakdown, and how cgo units like
runc plug into yoe's existing Go toolchain andtoolchain-muslcontainer via
depsinstead of needing a new Go+GCC container image. - Rename
debugunits todev. - Expand roadmap. Reorganized as a pointer index into the
design docs, with new sections for the app-developer build/deploy loop,
hardware access, testing, self-hosting, and distribution variants. - New testing design doc at docs/testing.md covers the
plannedyoe testdriver, build-time package QA, on-device upstream tests
(Yoctoptestanalog), image smoke tests, and CI integration. - Kernel modules now ship in images — the
linux,linux-rpi4, and
linux-rpi5units previously built only the in-tree kernel image, so drivers
compiled as loadable modules (Wi-Fi, USB, sound, many filesystems) were
silently dropped. Modules are now built and installed to
/lib/modules/<kver>/in the rootfs, somodprobefinds them at runtime. - Fix rPI4 builds package arch did not match what apk was expecting.
To update, run: yoe update
Or download the binary for your architecture and place it in your PATH.
Note: Yoe-NG is in heavy development. We recommend cleaning your build directory and re-creating projects (yoe init) with each new release.