Beta is now a real stabilization branch: publishes on every push to
`beta` (mirroring dev's model, auto-versioned X.Y.Z-beta.<ts>+<sha>,
base version from the latest published tag) instead of a manual
beta-v* tag. Fixes made during the freeze land via fix/<issue> branches
merged into `beta` directly. The gen-index.sh clone for beta pulls
bread-ecosystem's default branch (main) rather than pinning to dev,
since beta is the more stable track and main now carries the
TRACK-aware script.
Cargo.toml can drift stale relative to the actual last release (observed
on breadbox/breadpad/breadcrumbs/breadpaper), which made the auto-bumped
dev version sort as OLDER than what's already installed — bakery's semver
check correctly refused those "updates". Deriving the base version from
git ls-remote --tags instead is self-healing regardless of Cargo.toml
drift, with a Cargo.toml fallback only for a repo with no tags yet.
The fixed /tmp/bread-ecosystem-ci path races when multiple repos' dev/beta
workflows run close together on the same self-hosted runner — one job's
rm -rf/clone can stomp another's in-progress checkout, causing the
regenerate-index step to fail intermittently. Switch to mktemp -d.
Adds dev-release.yml (publishes on every push to dev) and beta-release.yml
(publishes on a beta-v* tag), mirroring the pattern landing in
bread-ecosystem/bread. See bread-ecosystem/docs/release-channels.md for
the three-track policy.
Bug fixes:
- mask() panicked on multi-byte UTF-8 passwords (byte-slicing a char
boundary); now masks by char count and never echoes a real character
- `cd --shell` interpolated the config path into a shell -c string via
Debug formatting, which doesn't neutralize shell metacharacters; now
passed as a positional shell argument instead
- connecting to open (no-password) networks failed because an empty PSK
was always sent to nmcli, which nmcli treats as secured-with-no-password
instead of open; the password arg is now omitted entirely when empty
- five nmcli terse-output parse sites used a raw splitn(2, ':'), which
mis-splits any device/connection name containing a literal ':'; unified
on the existing escape-aware field splitter
- watch's health classifier silently read a config-deleted profile as
"healthy" off a bare internet check instead of surfacing the misconfig
- the nmcli-monitor thread seeded its debounce clock with
`Instant::now() - 10s`, which panics on the monotonic clock near boot —
exactly when the generated systemd unit tends to start the watcher
Architecture:
- extracted src/lib.rs + src/app.rs so command logic can be exercised
in-process by tests instead of only by spawning the compiled binary
- added a Runner trait (src/util.rs) so subprocess calls can be faked in
tests; flow::run and watch::classify are now covered by real in-process
tests of the connect state machine and health transitions, not just
their pure helpers
- Wi-Fi passwords are no longer kept in breadcrumbs' config once
NetworkManager durably holds them: NetworkDef.password is now optional,
and a successful password-based connect clears + persists it
immediately, so it's never sent again on subsequent connects
- saved networks (SSID + optional local password) moved out of
breadcrumbs.toml into a separate networks.toml; old configs with
inline [[networks]] still load and migrate automatically on next save
- corrected a false README claim that passwords are never in nmcli argv
Test count: 20 -> 89 (52 unit, 24 CLI integration, 13 in-process
state-machine tests). Full clean run: cargo build/build --release/
test/clippy --all-targets, verified from a `cargo clean` rebuild.
- packaging/arch/PKGBUILD: builds and publishes breadcrumbs to [breadway] repo
- .forgejo/workflows/mirror.yml: mirrors every push/tag to GitHub
- .forgejo/workflows/package.yml: builds on tag, publishes to Forgejo registry
Requires FORGEJO_TOKEN and GITHUB_MIRROR_TOKEN secrets in Forgejo.
Core WiFi management works without Tailscale. tailscale, sudo, and
xdg-utils are only needed for Tailscale login and URL-open features,
so they become optional (warn, don't block) instead of required.
- bakery.toml: describes breadcrumbs for bakery install
- release.yml: builds on hestia self-hosted runner, publishes binary to
dl.breadway.dev and GitHub Releases on v* tags
- flow.rs/nm.rs: connect_and_verify now returns Result<(), String> with
a descriptive error message instead of a bare bool