64 tests covering: auth/setup and the CSRF gate, the "owner adds their
own data, anyone linked can mute it" permission pattern shared across
calendar-select/tasks-source/whiteboard-source, migration correctness
(fresh install, idempotent re-run, expected columns), battery estimate
outlier rejection, calendar_feed's fetch/merge/partial-failure handling,
webdav_client's fetch/list-directory, the whiteboard force-refresh
throttle bypass and browse endpoint, and render-size invariants across
calendar views/orientations.
No DB/HTTP fixtures need Docker, Node, or a real Immich/CalDAV/WebDAV
server -- a fresh temp SQLite file plus a couple of small local HTTP
servers as test doubles cover it all. Table data is wiped and reseeded
between tests rather than relying on SQLAlchemy's transaction-rollback
isolation pattern, which needs a pysqlite event-listener workaround
app/db.py's engine doesn't have and has no reason to gain just for tests.
Wired into .gitea/workflows/server-docker-build.yml as its own job that
build-and-push now depends on, so a failing suite blocks the image push
rather than just running alongside it for show.
Docker defaults to HTTPS for any non-docker.io registry, and
10.0.0.246:3000 (a bare LAN IP:port) isn't serving valid HTTPS -- the
push kept going out over HTTPS and failing. Adds a buildkitd config
telling BuildKit specifically to use HTTP for that host.
This only fixes the actual build+push step (BuildKit). The "Log in"
step runs a plain `docker login` through the classic Docker CLI/daemon
instead, which doesn't read this config -- that one still needs
10.0.0.246:3000 added to "insecure-registries" in the actual Docker
daemon's /etc/docker/daemon.json on whatever host runs the Gitea
Actions runner, followed by a daemon restart. That's runner-host
infrastructure outside this repo.
Cloudflare (fronting git.thumeit.com) started rejecting image pushes
with 413 Payload Too Large once whiteboard mode's Node runtime + native
resvg bindings made the image significantly bigger than before. Switched
the build/push target to a LAN-local registry (10.0.0.246:3000) that has
nothing in front of it to hit that limit, and updated
docker-compose.yml.example to match.
The build container was pinned to espressif/idf:release-v5.3, but the
firmware is actually developed against v6.0.2 (this machine's
$IDF_PATH). That gap caused real compile failures in CI --
esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown and
ESP_NETIF_CAPTIVEPORTAL_URI are both newer than v5.3 has, plus a
transitive stdbool.h include that changed between versions -- none of
it a real bug in the source.
The runner's job workspace lives in a named Docker volume, not a real
host path, so a nested docker run -v "\$PWD:/workspace" bind-mounted an
empty directory when talking to the host daemon (which has no notion of
paths inside the calling container) -- build_for_board.sh: No such file
or directory. docker create/cp/start streams the checkout into the
build container through the Docker API instead, which works regardless
of what backs either side's workspace.
espressif/idf:release-v5.3 has no Node.js, and actions/checkout (a Node
action) runs inside whatever container: the job specifies -- it failed
immediately with "node: not found" on the first real run. Checkout now
runs on the plain runner; only the two build steps spin up the ESP-IDF
image themselves via docker run, using the runner's already-mounted
docker socket.
New Gitea Actions workflow builds both board variants and publishes
them as release assets whenever firmware/version.txt is bumped. The
server can now poll that repo's releases (next to the existing manual
upload) and either surface an "Update frame" button or, with
"Automatically apply updates" checked, stage the new build itself --
the frame still only updates on its own next wake either way.
The automatic GITHUB_TOKEN doesn't reliably authenticate against Gitea's
Container Registry -- confirmed as a known, still-open limitation across
several Gitea versions (multiple upstream issues, consistent with the
401/unauthorized error hit here). Gitea's own community guidance is to
use a real Personal Access Token instead. Switches docker/login-action to
a REGISTRY_TOKEN repo secret (a PAT with package write scope, created in
Gitea's user settings) with an explicit username rather than the
gitea.actor context, and drops the now-unused permissions: packages:
write block that only applied to the auto token.
Builds server/Dockerfile and pushes to this repo's Gitea Container
Registry (git.thumeit.com/tfaour/espresso-frame-server) on every push to
main that touches server/, tagged both latest and the commit SHA.
docker-compose.yml now sets both image: and build: -- deploy hosts can
docker compose pull to grab the CI-built image without needing this
repo's build context, while local dev can still docker compose build
against Dockerfile changes directly.