Three sources of unbounded growth removed:
- Drop cache-from/cache-to registry: on a persistent self-hosted runner the
local BuildKit layer cache already provides between-run reuse; the registry
cache was redundant and pushed ~2 GB of torch layers on every build
- Switch docker system prune -f → -af so old :SHA-tagged images are removed,
not just dangling ones (-f alone never touched named tags)
- Add docker builder prune --keep-storage 5g to bound the local BuildKit
cache; pip mount cache (torch etc.) is recently-used so survives, stale
intermediate layers are evicted first
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
build-push-action@v7 generates OCI attestation manifests by default.
Forgejo's registry doesn't support OCI image index format with attestations,
causing the push to fail with "unknown". provenance: false disables this.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add `# syntax=docker/dockerfile:1` to enable BuildKit cache mounts
- Replace `--no-cache-dir` pip installs with `--mount=type=cache,target=/root/.cache/pip`
so torch/CUDA wheels are reused across builds instead of re-downloaded every run
- Add `docker system prune -f` step before build to free dangling image/layer space
- Add `cache-from`/`cache-to` pointing to `:cache` tag so unchanged layers
(including the heavy voice-deps layer) are pulled from registry instead of rebuilt
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
All code goes through dev first where CI runs on push. PR runs
(dev→main) were duplicating already-validated checks and causing
queue contention. Build job was already gated to push-only events.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Even mode=min still hits the registry's blob size limit (400 Bad Request).
The local runner's Docker daemon layer cache is sufficient for fast
incremental builds without needing a separate registry cache tag.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
mode=max exports all intermediate layer blobs which exceeded the Forgejo
registry's blob upload size limit (400 Bad Request). mode=min only exports
the final image layers, keeping cache entries small enough for the registry.
The actual image build and push was succeeding; only the cache write failed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Merging to main now runs CI checks only. The release tag (v*) is the
sole trigger for a production :latest image, eliminating the redundant
double-build that previously occurred on every PR merge + tag pair.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Dockerfile: ARG BUILD_VERSION=dev → ENV APP_VERSION baked into image
- ci.yml: BUILD_VERSION passed as build-arg; set to git tag name on v*
tag builds, "dev" on branch builds
- routes/api.py: GET /api/version returns {"version": APP_VERSION}
- SettingsView: fetches /api/version on mount, displays in About section
under General tab
Version source of truth is the git tag (YY.MM.DD.N CalVer).
pyproject.toml / package.json versions are no longer maintained.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Ubuntu 24.04 blocks pip install into the system Python by default.
Add --break-system-packages for the lint job's throwaway container.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The label now explicitly declares the dependency versions it provides
rather than using the opaque ubuntu-latest alias. All runs-on fields
in ci.yml updated to match.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- infra/Dockerfile.runner-base: new Ubuntu 24.04 image with Python 3.12
and Node 22 LTS pre-installed, tagged py3.12-node22. Eliminates the
~3-4 min deadsnakes PPA install that ran on every test job.
- infra/runner-compose.yml: update ubuntu-latest label to use
runner-base:py3.12-node22 instead of node:20-bullseye.
- .forgejo/workflows/ci.yml: remove Python 3.12 install steps (now in
base image), add actions/cache for pip keyed on pyproject.toml hash,
bump node-version 20 → 22.
- Dockerfile: bump frontend build stage node:20-alpine → node:22-alpine.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
deadsnakes python3.12 sees system python3.10's setuptools at
/usr/lib/python3/dist-packages and skips installation, leaving python3.12
without setuptools. A venv gets its own site-packages so pip/setuptools
are properly present for http-ece's legacy setup.py build.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
pip builds legacy setup.py packages in an isolated environment that doesn't
inherit the globally installed setuptools. Pre-building http-ece with
--no-build-isolation bypasses that isolation so setuptools is available.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
http-ece (pulled in by pywebpush) uses setup.py and requires setuptools,
which is not included in the deadsnakes Python 3.12 install.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
python:3.12-slim has no Node, causing actions/checkout@v4's post-step
to fail with 'exec: node not found'. Drop the container: declaration
so jobs run on the ubuntu-latest runner (which has Node). Install
Python 3.12 via deadsnakes PPA for the test job since the runner base
image (Ubuntu 22.04) ships with Python 3.10.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Merged ci.yml and build.yml into a single workflow. The build job now
declares needs: [typecheck, lint, test] so images are only pushed when
all checks are green. PRs run CI only; branch/tag pushes run CI then
build if successful.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
actions/setup-python fails in act_runner because it tries to download
pre-built binaries from GitHub CDN which aren't available in this
environment. Using a Python container image directly is the correct
approach — same pattern as the Flutter jobs in fabled_app.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Prevents workflows from running on changes to docs, README, infra,
summary.md, or other non-code files. Build workflow also skips on
test-only changes since tests don't affect the Docker image.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- .forgejo/workflows/ci.yml: fast checks on every push (TS typecheck,
Python lint via ruff, pytest) — no Docker build, ~30s with cache
- .forgejo/workflows/build.yml: Docker build with registry-side layer
caching + SSH deploy on main branch pushes only
- pyproject.toml: add ruff to dev deps, configure pytest and ruff rules
- tests/: conftest.py + first unit tests for _safe_filename (no DB needed)
- Makefile: add lint, fmt, typecheck, test, check targets for local use
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>