The nightly release workflow runs on Linux, but the script was written
with BSD-only idioms and had only ever been executed from a Mac. Every
scheduled nightly had been failing; the last successful nightly tag was
cut manually.
- days_since_2026: replace `date -j -f` (BSD) with a python3 one-liner
- sed -i: use the portable `sed -i.bak` + rm pattern; empty-suffix
`sed -i ''` is a BSD-ism that breaks GNU sed's arg parsing
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Now that the release workflow publishes musl binaries, the runtime
image can drop the debian:trixie-slim base for alpine:3.22. The
image shrinks from ~287 MB to ~96 MB (66% smaller) with a smaller
attack surface.
- Dockerfile: alpine:3.22 base, apk packages (ca-certificates git
tini su-exec), BusyBox adduser/addgroup, tini at /sbin/tini.
- entrypoint.sh: replace runuser with su-exec, Alpine's idiomatic
drop-privileges helper.
- release.yml docker job: pull the two linux-musl artifacts instead
of linux-gnu. The docker image and the Alpine install.sh path now
ship the same binary.
- bin/dev/docker-build.sh: compile fabro-cli for the host's musl
target in rust:1-bookworm with musl-tools, the matching CC/LINKER
env vars, and LIBZ_SYS_STATIC=1. Same pattern as CI.
Verified locally on aarch64: Alpine image builds, server binds on
$PORT (default 32276), endpoints return 200, fabro server process
runs as unprivileged UID 1000 under tini.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The host cargo build on macOS produced a Mach-O binary that the
Linux runtime image refused with "Exec format error". Run the
compile in rust:1-bookworm so the output matches the target
platform, and cache the registry plus target dir in named volumes
for incremental rebuilds. Also gitignore docker-context/ since it
is regenerated on every build.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replace the docker/Dockerfile-based api+web compose setup with a
single root Dockerfile that runs the fabro server with the embedded
web UI on port 80, persists state under /storage, and drops to a
non-root fabro user with CAP_NET_BIND_SERVICE.
The release workflow stages the prebuilt Linux binaries from the
compile job into a buildx context and publishes multi-arch images
to ghcr.io/fabro-sh/fabro as :<version> (always), :latest (stable
tags only), and :nightly (nightly tags only).
Also address zizmor findings in nightly.yml (pinned
create-github-app-token, persist-credentials: false with explicit
remote URL setup) and release.yml (no-cache on tag-triggered
setup-bun to close the cache-poisoning path).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops `alpha` / `beta` / `rc` as accepted pre-release labels in
bin/dev/release.sh. `nightly` is now the only pre-release descriptor,
in preparation for automated nightly tags.
Renames the Homebrew tap formula from `fabro-beta` to `fabro-nightly`:
- installer/fabro-beta.rb.template -> installer/fabro-nightly.rb.template
(class renamed FabroBeta -> FabroNightly, desc updated).
- `update-homebrew-beta` job in release.yml is now
`update-homebrew-nightly` with matching file paths and commit message.
Breaking for existing `brew install fabro-sh/tap/fabro-beta` users: the
old formula file stays in the tap for now (removed in a follow-up once
fabro-nightly is populated) and stops receiving updates. Users should
switch to `brew install fabro-sh/tap/fabro-nightly` once the new
formula is published by the next pre-release tag.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a verify_release_tests step to bin/dev/release.sh that runs the
same nextest invocation the CI release workflow uses -- workspace,
--release, --profile ci -- with SEGMENT_WRITE_KEY baked in so
telemetry-active code paths are actually exercised. Runs before the
version bump/tag, so regressions that only show up under --release
plus a compiled-in write key (e.g. telemetry recreating ~/.fabro,
sender tests that assume no key) fail locally in ~5 min instead of
~60 min on a tagged release run.
`--skip-tests` for when you've already run it yourself.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add a verify-spa job to the release workflow that rebuilds the SPA
and fails if committed assets are stale, and add the same check to
bin/dev/release.sh so tagging fails before anything is pushed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add prerelease-aware release automation and keep default install and upgrade
paths pinned to the latest stable tag unless an explicit prerelease version is
requested.