Commit graph

105 commits

Author SHA1 Message Date
Breadway
7286b49457 test: stop emitting reserved bread.reload.* from the reload-storm test
Some checks failed
check / check (push) Failing after 3m23s
`daemon_survives_repeated_reloads_and_pipeline_resumes` manually emitted
`bread.reload.before` / `.after`. Since "Allow well-formed bread.command
events on the emit bus" tightened the normalizer, a manual emit of an
adapter-owned domain (`reload`) is rejected, so this test — and every
push to main since — failed at the test step, blocking the dev-track
publish.

The event names are incidental here; the test only checks that events
flow through the pipeline before and after a reload storm. Renamed to
`bread.reloadtest.*` (a non-reserved domain).
2026-08-31 19:55:31 +08:00
Breadway
c97029f654 Document bread init: api-schema, README CLI reference, hooks_shell note
Some checks failed
dev release / build (push) Failing after 1m47s
Registers 'init' as a cli_command in api-schema.toml and adds its
lines to README.md's CLI reference, keeping xtask check-docs clean.
Also adds a note to hooks_shell.rs's module header explaining why the
compositor case earns a consent-gated config edit that the shell-hook
module deliberately avoids, so the two don't read as contradicting
each other.
2026-08-26 19:31:58 +08:00
Breadway
1fce1979c3 Add bread init: Hyprland compositor layer-rule integration
Installs the layerrule blur/ignore_alpha/animation integration that
breadbar's translucency depends on into a user's hyprland.lua, with a
consent-gated single marked block, timestamped backup, dry-run/--yes,
and --undo. Generates a self-contained ~/.config/hypr/bread.lua that
reads layerrules.json (bread-theme layerrules) and emits hl.layer_rule
calls, appearance fields only. Falls back to printing a snippet
(translated to hyprlang .conf syntax when relevant) rather than
writing when the config isn't a Lua hyprland.lua bread recognizes, and
refuses to install when an existing breadbar layer rule (e.g. BOS's
own dotfiles) is already found under ~/.config/hypr.

bread doctor now reports compositor integration status via a pure
filesystem check, independent of the daemon; it never installs
anything itself.

Wired as a top-level Commands::Init (not a HooksCommand variant) since
it needs diff/consent/backup/undo machinery the hooks family has no
use for.
2026-08-26 19:31:18 +08:00
Breadway
72afe790fd Fix clippy warnings across workspace
Some checks failed
dev release / build (push) Failing after 7s
- io.rs: factor the pending-RPC-replies map into a PendingReplies
  type alias (type_complexity)
- lua_env.rs: drop a redundant i64->i64 cast and an unneeded borrow
  before create_string (unnecessary_cast, needless_borrows_for_generic_args)
- state_engine.rs: iterate watches.values() instead of discarding the
  key from watches.iter() (for_kv_map)
- module_host_sandbox.rs: collapse nested if into a single condition
  (collapsible_if)

(cherry picked from commit 49063cb98ddfeae35d842a6cf439123cfda763d9)
2026-08-23 14:57:43 +08:00
Breadway
e073a17353 ci: package bread-emit and bread-module-host on all tracks
Some checks failed
check / check (push) Failing after 33s
dev release / build (push) Failing after 1m7s
bakery.toml already lists all four binaries; copy, hash, and GitHub
Release upload them. release.yml clones bread-ecosystem via mktemp like
dev/rc so concurrent runner jobs do not race on /tmp/bread-ecosystem-ci.
2026-08-23 14:38:52 +08:00
Breadway
3865327c66 fix(module-host): canonicalize path grants and exec without a shell
RPC-side path_allowed now canonicalizes (parent+filename for new files)
and uses Path::starts_with so ../.ssh and /Wallpapers-evil cannot ride a
Wallpapers grant. exec/exec_capture parse argv, reject shell
metacharacters, and spawn Command::new instead of sh -c. Reserve the
daemon-synthesized module/state/widget/reload event families.
2026-08-23 14:38:52 +08:00
Breadway
670cf22f2c can't be bothered writing a commit message
Some checks failed
dev release / build (push) Failing after 5m30s
2026-08-16 14:23:42 +08:00
Breadway
cdd5de8f58 CI: migrate to bread-ecosystem's shared Arch build image
All checks were successful
dev release / build (push) Successful in 3m7s
beta (rc) release / build (push) Has been skipped
release / build (push) Successful in 2m24s
Routes the release build/test steps and a new fast pre-release
check.yml through ci/build.sh, which delegates to bread-ecosystem's
pinned shared Containerfile/build.sh instead of building against
whatever the bare hestia runner happens to have installed. Follows
the pattern already proven in breadpad. No extra ci/deps.txt: bread's
system_deps (systemd-libs, openssl, zlib) are all already pulled in
transitively by the shared image's base + git packages.
2026-08-15 22:33:23 +08:00
Breadway
6063eb901c State engine applies bread.hyprland.* and snapshots compositor topology
All checks were successful
dev release / build (push) Successful in 1m29s
Match both legacy and namespaced Hyprland events so flipping
legacy_hyprland_event_names no longer freezes monitors/workspace/window.
On event-socket connect, query socket1 and emit bread.hyprland.snapshot
to populate RuntimeState (including workspaces). API 1.7.1.
Track AGENTS.md instead of gitignored CLAUDE.md.
2026-08-15 22:03:30 +08:00
Breadway
d3517d1433 Allow well-formed bread.command events on the emit bus
Docs already said any module or app could publish bread.command.<app>.<verb>,
but command is reserved so both unsourced bread-emit and sourced App emit
rejected the whole namespace. Keep command unclaimable as an app id; accept
bread.command.<known-app>.<verb> (and let an app command another known app).
Also ship bread-emit and bread-module-host, and give udev enumerate the same
classification fields as a live add so boot-time devices are not all unknown.
2026-08-15 21:41:40 +08:00
Breadway
a6973360bd Complete Workstream F: extend check-docs to cover CLI commands, wire into CI
All checks were successful
dev release / build (push) Successful in 1m6s
Two remaining pieces from the original report, both explicitly signed
off on:

1. Wire cargo run -p xtask -- check-docs into dev-release.yml as a
   fail-fast step ahead of the release build/test, so drift between
   api-schema.toml and the real API surface now fails CI instead of
   relying on local discipline.

2. Extend api-schema.toml and check-docs to cover the bread CLI's
   command surface (bread-cli/src/main.rs's Commands/ModulesCommand/
   HooksCommand enums) against README.md's "CLI reference" section,
   not just Lua bindings/IPC methods against Documentation.md. This
   was the specific blind spot that let modules audit, hooks
   install-shell/install-git, and events --tree drift out of README
   in the first place -- check-docs would not have caught that fix
   without this extension, since its prior scope never touched the
   CLI-vs-README relationship at all.

Extraction reuses the same deliberate-textual-scanning approach as
the existing Lua/IPC extractors: depth-tracked enum variant scanning,
clap's PascalCase->kebab-case rename convention, and a hardcoded
(TABLE_VARS-style) map of which top-level Commands variants delegate
to a nested subcommand enum (Modules->ModulesCommand,
Hooks->HooksCommand), producing dotted names like modules.audit.
CLI commands are versioned against the package version (Cargo.toml),
not API_VERSION, since the CLI was never part of that versioned
contract -- documented in api-schema.toml's header.

Verified check-docs actually catches CLI/README drift, not just
passes: temporarily deleted the "bread modules audit" line from
README.md, confirmed check-docs failed with the exact right message,
restored it. 4 new unit tests cover the extraction and cross-check
logic (11 total in xtask, up from 7).
2026-08-05 13:49:57 +08:00
Breadway
da889d6f6a fix(module_host): grant Landlock access to IPC socket path
All checks were successful
dev release / build (push) Successful in 1m2s
Out-of-process modules timed out with "did not report ready within 45s"
because apply_sandbox never allowed the child to reach breadd's Unix
socket. Path-based AF_UNIX connect is mediated as filesystem access, so
without a rule for the socket (and its parent) UnixStream::connect failed
with EACCES and the hello handshake never completed.

Pass socket_path into apply_sandbox and add baseline ReadDir/ReadFile
rules for the socket directory and path, matching the existing module-
directory grant. Update unit-test call sites accordingly.
2026-08-05 10:01:58 +08:00
Breadway
81fbc46e4f Fix README CLI reference drift, correct stale module-sandboxing claim, document check-docs' current gaps
README's CLI reference had drifted from Documentation.md exactly the
way Workstream F exists to prevent: bread modules audit (Workstream D),
bread hooks install-shell/install-git, and bread events --tree
(Workstream B) were all documented in Documentation.md but missing
here, since this section is hand-copied rather than generated or
linked out.

Also found and fixed while auditing: the Module system section still
said modules "are not sandboxed" -- false since Workstreams D and G
added opt-in capability-scoped, Landlock-sandboxed execution.

Documented in CONTRIBUTING.md that check-docs (Workstream F, scoped
down to a drift detector rather than a generator -- see api-schema.toml's
header) is deliberately not yet wired into CI pending a separate review
pass on the workflow-file change, and that its scope doesn't cover the
CLI-reference-vs-README drift this commit just fixed by hand -- both
previously tracked only in conversation history, not durably in the repo.
2026-08-05 09:28:27 +08:00
Breadway
2485e1af1f Bump workspace crate versions to 0.8.0 ahead of v0.8.0-rc.1
Some checks failed
beta (rc) release / build (push) Successful in 1m5s
release / build (push) Has been skipped
dev release / build (push) Failing after 1m51s
2026-08-05 08:40:03 +08:00
Breadway
50ff425d2a Fix test harness process leak: graceful SIGTERM shutdown + disable podman adapter in test fixtures
All checks were successful
dev release / build (push) Successful in 1m3s
The integration test harness (ipc_integration.rs and
module_host_sandbox.rs) tore down spawned breadd instances via
Child::kill() (SIGKILL). Since breadd's PodmanAdapter is enabled by
default and the test breadd.toml fixtures didn't disable it, every
test-spawned daemon on a machine with podman installed ran a real
`podman events --format json` child. SIGKILL gives breadd zero chance
to run its own graceful shutdown path (wait_for_shutdown -> adapter
tasks dropping -> kill_on_drop firing on that child), so it was
orphaned and reparented to init on every single test run instead.

A day of repeated `cargo test --workspace` runs during today's
workstream development left 1,559 such orphaned processes consuming
76.8GB of RSS system-wide, found and cleaned up separately.

Fix is two-layered: disable the podman adapter in both harnesses'
breadd.toml fixtures (tests don't need real container-lifecycle
watching, matching how hyprland/udev/power/network are already
disabled there), and change TestHarness::drop to send SIGTERM with a
bounded wait before falling back to SIGKILL, so breadd's own cleanup
gets a real chance to run - defense in depth against any future
adapter that spawns a subprocess.

Verified: two full `cargo test --workspace` runs (282 tests) produce
zero new podman events processes and zero leftover breadd/
bread-module-host processes.
2026-08-05 06:45:20 +08:00
Breadway
d26861697c Merge feature/module-host-sandbox (Workstream G) 2026-08-05 04:12:58 +08:00
Breadway
1e2817537b Add Workstream G: out-of-process, Landlock-sandboxed module runtime
Closes the gap Workstream D's in-process capability scoping left open:
build_scoped_env only gated presence of bread.* bindings, but os.execute/
io.open/debug.* remained fully reachable since a module's Lua still ran
inside breadd's own process. A module that declares [[permissions]] in
bread.module.toml (including an explicit empty list) is now spawned as a
separate bread-module-host process instead, restricted by a Landlock
ruleset breadd builds from that module's granted permissions and applies
via Command::pre_exec before the child executes any Lua at all. A module
with no manifest at all keeps today's in-process, ungated behavior for
backward compatibility.

- bread-module-host: new minimal binary (mlua + tokio + serde_json) that
  connects to breadd's existing IPC socket, presents a one-time spawn
  token, and proxies bread.* calls as RPC instead of direct bindings.
- breadd/src/module_host.rs: spawn + token registry + apply_sandbox
  (Landlock ruleset construction), with unit tests that spawn a real
  child and verify denial at the OS level, not a Lua-level check.
- breadd/src/ipc/module_host_bridge.rs: the module_host.* RPC bridge
  (on/once/off/emit/after/every/cancel, fs.read/write, exec/exec_capture,
  state.get, log/warn/error, status) plus the hello handshake. Bumped
  API_VERSION to 1.6.0.
- breadd/tests/module_host_sandbox.rs: end-to-end acceptance tests going
  through a real spawned breadd + bread-module-host + IPC handshake —
  os.execute/io.open denied outside a module's granted fs.read scope, and
  kill -9 on a module-host child leaving breadd and other modules intact
  while breadd reports bread.module.crashed.
- bread-shared/src/module_host_ipc.rs: shared wire types (hello result,
  tagged event/timer push envelope) so breadd and bread-module-host can't
  drift on the handshake/push shape.

Deferred (documented in Documentation.md's Workstream G section): the
trust="in-process" opt-out, remaining bread.* namespaces over RPC
(hyprland/widget/machine/bluetooth/notify/state.watch), network
sandboxing, and a fully static build that would remove the Execute grant
Landlock's dynamic-linker requirement forces on system library dirs.
2026-08-05 04:02:05 +08:00
Breadway
450454d164 Merge feature/capability-manifest (Workstream D) 2026-08-04 22:40:49 +08:00
Breadway
252f65593c Fix rules.toml integration test after merging Workstream A's manual-emit domain restriction
The test triggered its rules via IPC's no-source emit method with real
adapter-owned event names (bread.device.*, bread.power.*), which
Workstream A now correctly rejects as impersonation. Switched to a
custom non-reserved domain (testrule.*) since what's under test is
rules.toml -> bread.on() -> action wiring, not adapter-specific event
names -- real rules.toml usage is unaffected since it subscribes to
genuine adapter-sourced events, not manually-injected ones.
2026-08-04 22:40:41 +08:00
Breadway
3c70c7a823 Merge feature/rules-toml (Workstream E) 2026-08-04 22:38:05 +08:00
Breadway
3510c3ba90 Merge feature/schema-first-docs (Workstream F) 2026-08-04 22:37:16 +08:00
Breadway
c8f6a72331 Merge feature/hyprland-event-namespace (Workstream C)
# Conflicts:
#	breadd/src/core/normalizer.rs
2026-08-04 22:37:09 +08:00
Breadway
d29466cb1e Fix: AdapterSource::Manual arm missing id/caused_by after A+B merge 2026-08-04 22:35:25 +08:00
Breadway
0384ea1354 Merge feature/event-causality (Workstream B) 2026-08-04 22:33:29 +08:00
Breadway
94be831a21 Merge feature/ipc-connection-auth (Workstream A) 2026-08-04 22:33:23 +08:00
Breadway
6841163620 Add capability-scoped module API (Workstream D)
ModuleManifest gains a structured [[permissions]] field (bread-shared's
new ModulePermission/PermissionKind, shared between bread-cli and breadd
so the two never drift on what a permission "type" string means).

breadd now gives every third-party module's Lua chunk a scoped _ENV
instead of the shared global table: load_scoped_lua_file builds a fresh
`bread` table containing only baseline bindings (event subscription,
timers, json, module/store, logging, and the pure-Lua sugar built on top
of those) plus whatever the manifest's permissions grant, with a
metatable __index falling back to the real globals for everything else
(stdlib, require/package - so require("bread.devices") keeps working,
since builtins load unscoped and their closures capture that environment
lexically regardless of the caller's). _G is explicitly rebound to the
scoped table itself to close the obvious escape hatch. A module with no
manifest, or a manifest with no permissions key, keeps full ambient
access unchanged (today's behavior) but is now tracked as `ungated` in
module status and surfaced by `bread doctor`. An explicit `permissions =
[]` is scoped for real but not flagged, since that's a deliberate
declaration.

Adds `bread modules audit <name>`: a best-effort text scan of a module's
.lua files suggesting a [[permissions]] block to paste into its manifest.

Converts examples/modules/cpu-temp-widget.lua into a directory module
with a worked bread.module.toml (fs.read + widget) as the reference
example. Documentation.md gets a new "Capability-scoped modules" section
covering the taxonomy, the require()/closure mechanism, and an explicit
note that path/bin scoping is recorded but not yet enforced per-call -
that's the out-of-process module sandboxing workstream this manifest
schema is laid down for. API_VERSION bumped 1.4.0 -> 1.5.0.
2026-08-04 22:24:16 +08:00
Breadway
d270ac6ff7 Namespace Hyprland events under bread.hyprland.*, keep legacy names via [compat]
normalize_hyprland() dual-emits each of its 10 flat event names
(bread.workspace.changed, bread.monitor.connected, bread.window.opened,
etc.) alongside a bread.hyprland.<rest> equivalent, so portable automation
can subscribe to bread.hyprland.* and be guaranteed compositor-specific
coverage without also matching genuinely cross-backend events like
bread.power.*. The bread.hyprland.event fallback was already namespaced
and is unaffected.

Gated behind [compat] legacy_hyprland_event_names (default true during
the deprecation window) so the old names keep firing until modules
migrate; set to false to emit only the namespaced names.
EventNormalizer::with_legacy_hyprland_event_names(bool) is a builder on
top of the existing ::new(dedup_window_ms), threaded through from config
in main.rs.

Bumps API_VERSION to 1.5.0 (additive), updates Documentation.md's
Hyprland event reference with Deprecated/Since markers and the new
[compat] option, refreshes the README config example and the
dock-workflow/git-branch-widget examples to the namespaced names, and
adds DEPRECATIONS.md tracking the deferred full removal once the window
closes.
2026-08-04 22:08:44 +08:00
Breadway
45b5aee117 Add rules.toml: declarative event->action automation without Lua
Adds a bread.rules built-in module plus a breadd/src/core/rules.rs
parser/validator so the common "when event X happens, do Y" case
(dock connect script, AC-disconnect notification, keyboard rate on
connect) no longer requires hand-written init.lua.

- rules.toml is optional, XDG_CONFIG_HOME-aware (mirrors breadd.toml's
  config_path() resolution), and purely additive alongside init.lua.
- Each [[rule]] needs `on` (event suffix, "bread." implied, wildcards
  supported) and exactly one of run/exec/notify. `run` names a single
  script (tilde-expanded + shell-quoted so spaces in the path can't be
  word-split); `exec` is a raw shell command line passed through as-is;
  `notify` shows a desktop notification.
- Rule data is threaded into the bread.rules Lua module via globals
  set just before it loads (same technique load_profiles() already
  uses for __profiles_path), avoiding any need to hand-escape values
  into generated Lua source text.
- Parse/validation failures surface through the existing module
  load-error path (Lua error() -> run_on_load -> set_module_status),
  so a bad rules.toml shows up via `bread doctor` exactly like a
  broken hand-written module would, without blocking other valid
  rules in the same file.
- Documentation.md gets a new Getting-started fast path plus a
  Dictionary entry; README's Configuration section gets a short
  pointer. Since: v1.5.
2026-08-04 22:05:26 +08:00
Breadway
c5e871694a Add schema-first API docs drift detector (xtask check-docs)
Documentation.md's Lua API and IPC protocol sections are hand-written
prose and have drifted from the actual bread.* binding / IPC method
surface before. This adds a checked-in registry (api-schema.toml) of
every current Lua binding and IPC method, plus a new xtask crate
(`cargo run -p xtask -- check-docs`) that cross-checks it against
breadd/src/lua/mod.rs, breadd/src/ipc/mod.rs, and Documentation.md
itself, failing loudly on any mismatch. It's a drift detector, not a
doc generator — Documentation.md's prose is untouched except for one
genuine gap the bootstrap surfaced: bread.hyprland.eval had no mention
anywhere in the docs, now given a one-line example alongside its
siblings.

CONTRIBUTING.md documents the resulting contributor workflow.
2026-08-04 18:21:05 +08:00
Breadway
6ff1ee910b Add event causality tracking (id + caused_by chains)
Every BreadEvent now gets a unique id at construction (via
BreadEvent::new/with_timestamp, and the normalizer's struct-literal call
sites, which all now assign one explicitly). A new caused_by field is
populated only when a Lua bread.emit() call runs synchronously inside a
bread.on subscriber's handler: LuaEngine tracks the currently-dispatching
event's id (set/restored around each handle_event invocation, single-
threaded so a plain Mutex-guarded slot suffices) and bread.emit()'s Rust
binding reads it when constructing the outgoing event. This lets chains of
Lua modules that react to each other's events be reconstructed instead of
timestamp-guessed from a live `bread events` log.

Also:
- bread events --tree renders the caused_by chain as an indented,
  live-streaming-friendly tree instead of a flat line-per-event stream.
- API_VERSION bumped 1.4.0 -> 1.5.0 (additive-only change).
- Documentation.md's event envelope, bread.emit, and debugging-tips
  sections updated with Since: v1.5 markers.
- New end-to-end regression test spawning the real daemon with 3 chained
  Lua handlers (A emits X on trigger, B emits Y on X, C emits Z on Y) and
  asserting caused_by threads correctly through all three hops.
2026-08-04 17:55:31 +08:00
Breadway
7bb6fbb20f ipc: close unauthenticated event-spoofing gap in emit's no-source path
The IPC "emit" method's no-source path took a bare event+data and sent it
straight to emit_tx tagged AdapterSource::System with zero validation of
the event name. Any same-UID process on the socket could send e.g.
{"event":"bread.power.ac.connected",...} and have it delivered to every
Lua subscriber indistinguishable from a real adapter event, since System
is the same tag the daemon uses for its own trusted, Rust-originated
sends (bread.system.startup, bread.profile.activated).

Fix, scoped to the actual threat model (same-UID Unix socket trust means
there's no way to cryptographically distinguish "the real bread-cli
binary" from any other local process, so a generic connection-identity
handshake would be theater):

- New AdapterSource::Manual tag for the no-source emit path. System is
  now reserved for daemon-internal, Rust-code-originated sends only and
  can never again be produced from data that arrived over the wire.
- The event name is rejected if its top-level dotted segment is one of
  the reserved, adapter-owned domains (RESERVED_DOMAINS in
  bread-shared/src/apps.rs) -- extended with bluetooth/workspace/window/
  monitor, event families the Hyprland and Bluetooth adapters already
  publish under but that were missing from that list. Freely-named
  custom/test event names are untouched, so `bread emit <name>` and
  bread-emit's fire-and-forget single-line-write design keep working
  exactly as documented.

Bumped API_VERSION to 1.5.0 and updated Documentation.md's IPC emit
section and Namespaces reserved-domains list accordingly.

Also fixed a subscribe/emit race that surfaced while adding regression
tests for this: events.subscribe's ack is written to the client before
the server task actually registers on the broadcast channel, so a test
that emits immediately after reading the ack can race the registration.
Added a settle delay plus an explicit timeout (instead of an unbounded
read loop) so a future regression fails the test instead of hanging the
whole binary.
2026-08-04 17:41:18 +08:00
Breadway
96639516b1 can't be bothered writing a commit message
All checks were successful
dev release / build (push) Successful in 1m33s
2026-08-03 09:37:15 +08:00
Breadway
b9e2530743 CONTRIBUTING.md: document single-trunk + RC-tag release model
All checks were successful
dev release / build (push) Successful in 3m59s
2026-07-31 11:08:41 +08:00
Breadway
b00e145a93 CI: single-trunk model — dev triggers on main, beta becomes RC-tag-triggered
Replaces the dev/beta branch split with one trunk (main): dev-track
builds still publish on every push, but the beta track now publishes
from a vX.Y.Z-rc.N prerelease tag instead of a separately-maintained
beta branch. Removes the branch nobody reliably kept in sync.
2026-07-31 11:05:29 +08:00
Breadway
34854f1471 update deps
All checks were successful
dev release / build (push) Successful in 55s
2026-07-23 11:46:35 +08:00
Breadway
8a794c03bf Will change this commit message to mean something later
All checks were successful
dev release / build (push) Successful in 56s
2026-07-23 11:16:33 +08:00
Breadway
f9a8c4f915 Drop pacman packaging, bakery-only distribution
All checks were successful
dev release / build (push) Successful in 1m17s
bakery already fully covers what the PKGBUILD provided (binary, systemd
--user service where applicable, dependency declarations) except a LICENSE
copy, which bakery.toml's new license_file field now closes. Removes
packaging/arch/ and .forgejo/workflows/package.yml; adds the LICENSE
artifact to each release/dev-release/beta-release workflow's prepare
step. Not pacman-installed inside BOS today (BOS already consumes these
apps exclusively via build-local.sh's skel-staging), so this only removes
the option to `pacman -S` outside of BOS/bakery.
2026-07-23 10:25:12 +08:00
Breadway
8d3f55b607 Will change this commit message to mean something later
Some checks failed
dev release / build (push) Failing after 0s
2026-07-22 19:52:16 +08:00
Breadway
f3905d8114 docs: add CONTRIBUTING.md
Some checks failed
dev release / build (push) Failing after 0s
Documents the dev/beta/main branch and release-track workflow shared
across the bread ecosystem. See bread-ecosystem's docs/release-channels.md
for the full policy this implements.
2026-07-22 19:40:26 +08:00
Breadway
ef035dc687 ci: make beta a branch-triggered freeze track, not a one-off tag
All checks were successful
dev release / build (push) Successful in 1m22s
beta release / build (push) Successful in 1m17s
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.
2026-07-22 18:37:11 +08:00
Breadway
e28b5cedee ci: base dev version on the latest published tag, not Cargo.toml
All checks were successful
dev release / build (push) Successful in 1m12s
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.
2026-07-22 13:51:32 +08:00
Breadway
21131672ab ci: use a unique temp dir for the bread-ecosystem clone in dev/beta CI
All checks were successful
dev release / build (push) Successful in 1m24s
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.
2026-07-22 10:24:08 +08:00
Breadway
d480209ec2 ci: pin gen-index.sh clone to bread-ecosystem's dev branch
All checks were successful
dev release / build (push) Successful in 1m2s
The TRACK-aware gen-index.sh only exists on bread-ecosystem's dev branch
so far (not yet merged to main). Without --branch dev, the remote clone
defaulted to main and silently ran the old track-blind script, which is
why dl.breadway.dev/dev/index.json never actually picked up bread's dev
builds despite the workflow reporting success.
2026-07-22 09:49:43 +08:00
Breadway
00ba49bfe9 ci: fail fast on missing signing key when regenerating index.json
All checks were successful
dev release / build (push) Successful in 55s
The remote gen-index.sh call never had MINISIGN_SEC_KEY wired through, so a
missing/misconfigured secret silently produced an unsigned index.json that
overwrote the previously-signed one instead of failing the job — this is
why bread's dev track never appeared in dl.breadway.dev/dev/index.json
after the first dev-release.yml run despite it reporting success.
2026-07-22 09:44:44 +08:00
Breadway
edb37a28e0 ci: add dev/beta build track workflows
All checks were successful
dev release / build (push) Successful in 1m7s
Mirrors the new stable/beta/dev track feature landing in bread-ecosystem's
bakery. dev-release.yml publishes on every push to dev; beta-release.yml
publishes on a beta-v* tag. Both skip the GitHub Release upload step and
publish to dl.breadway.dev/{dev,beta}/bread/ via gen-index.sh's new TRACK
env var. See bread-ecosystem/docs/release-channels.md for the full policy.
2026-07-22 09:25:24 +08:00
Breadway
d0f9c6c578 ci: remove GitHub push-mirror workflow 2026-07-21 19:16:45 +08:00
Breadway
d563461d7d Remove leftover GitHub Actions CI workflow (Forgejo is now canonical CI; GitHub is a pure mirror target)
All checks were successful
Mirror to GitHub / mirror (push) Successful in 3s
2026-07-19 03:10:41 +08:00
Breadway
22e34e2cf2 Bump version to 0.7.0
All checks were successful
Mirror to GitHub / mirror (push) Successful in 2s
release / build (push) Successful in 1m45s
Build and publish package / package (push) Successful in 2m8s
2026-07-19 03:06:24 +08:00
Breadway
1208c5d1b7 Add filesystem/git/podman/systemd adapters, git/shell hooks, bread-emit CLI, app-detection helpers 2026-07-19 03:05:57 +08:00
Breadway
89c5849539 Fix audit findings: path traversal, exec shell, glob dup, dead bread-sync, version drift
- modules_mgmt.rs: reject module names containing path separators, `..`,
  or absolute paths before joining onto modules_dir (install_from_local,
  remove_module, read_module_manifest); adds canonicalized containment
  check as defense in depth. Manifest-supplied names and CLI args were
  previously joined unsanitized, allowing path traversal on install/remove.
- breadd/src/lua/mod.rs: bread.exec now runs via `sh -c` instead of
  `sh -lc`; no documented reason was found for login-shell semantics.
- Unify the two independently hand-written glob matchers (subscription
  dispatch in breadd/src/core/subscriptions.rs vs. the CLI --filter path
  in breadd/src/ipc/mod.rs) into one implementation in
  bread-shared/src/glob.rs, used by both call sites.
- Remove the dead bread-sync/ tree (already excluded from the workspace
  and fully unreferenced) and its stale PKGBUILD deps (libgit2, git
  optdepend) and packaging docs mention.
- Correct the version-number transposition bug ("6.2.0" instead of
  "0.6.2"/"0.6.6") across bread-shared, breadd, and bread-cli Cargo.toml,
  and fix PKGBUILD's stale pkgver, so Cargo.toml/doctor/PKGBUILD all agree
  with the latest git tag (v0.6.6).
2026-07-17 03:20:14 +08:00