Commit Graph
16 Commits
Author SHA1 Message Date
randy 4982f04258 Verify the deploy actually came up, not just that it was launched
systemctl restart (Type=simple, no readiness protocol) returns as
soon as podman compose up --build forks, before the build or the
container start have actually finished - a build failure or crash
loop would still show as a green deploy job. Poll /api/health for up
to 5 minutes (comfortably above the ~3.5min worst-case cold rebuild)
and fail the job if it never answers.
2026-09-08 21:16:41 +02:00
randy a908cd7abc Fix the real cause of slow podman deploys: add --build, drop podman rmi
CI / check (push) Successful in 44s
CI / deploy (push) Successful in 3s
podman-compose@.service was missing the --build flag that
docker-compose@.service already has (added on cube.local:
/etc/systemd/system/podman-compose@.service), so removing
maptool:latest before every restart (my own earlier fix, meant to
force a rebuild) also destroyed the build cache along with it - every
deploy was redoing apt-get/bundle install from scratch (~3 min
measured, vs ~20s before). --build lets a plain systemctl restart
rebuild while still reusing unchanged layers, same as docker did, so
the ci.yml deploy step collapses back to one line.
2026-09-08 21:12:54 +02:00
randy 049d54e44e Use the short maptool:latest image name in the deploy job
CI / check (push) Successful in 43s
CI / deploy (push) Successful in 4s
docker.io/library/maptool:latest and maptool:latest resolve to the
same local image (verified on cube.local) - the docker.io/library
prefix is just podman's normalization of the unqualified name, not an
actual registry reference. Short form matches what docker-compose.yaml
itself uses and avoids implying a Docker Hub push/pull that never
happens.
2026-09-08 20:38:14 +02:00
randy e4764c64e4 Drive maptool's deploy through the podman-compose@ systemd service
The service's own ExecStart deliberately runs a plain podman compose
up (no --build) since ExecStartPre already tears down the previous
containers/networks/volumes on every start — but that leaves the
built image alone, so the deploy job now removes it directly first
(what forces a fresh build) and drives start/stop through systemctl
rather than calling podman/docker compose by hand. Also switches
/srv/docker/maptool to /srv/podman/maptool per the symlink now in
place, and updates deployment.adoc to match.
2026-09-08 20:33:03 +02:00
randy 61ba86c6e6 Add a GNSS simulator for dev without gpsd running
bin/gnss_simulator.rb speaks gpsd's own JSON wire protocol directly
on its default port -- GpsdClient connects to it exactly as it would
to real gpsd, no app changes needed, and no gpsd install/daemon
required either (unlike the existing fake-NMEA-source approach in
docs/development.adoc, which still needs gpsd itself in front of it).
Drives a loop around a center point at a driving-ish pace rather than
sitting still, since a fixed position isn't much of a "GNSS position"
to look at.

Verified end to end: started it, pointed a dev server at it, and
confirmed /api/gnss/position reports a moving fix across two polls.
2026-09-08 00:28:34 +02:00
randy 37bc14f3ba Show the deployed commit as a hover tooltip on the topbar brand
CI / check (push) Successful in 47s
CI / deploy (push) Successful in 27s
ASSET_VERSION only proves *a* deploy happened recently, not *which*
commit -- not enough to answer "did my push actually deploy, or am I
looking at a stale browser cache" (today's actual answer: neither --
deploy was current, a GeoJSON cache predating a code change was just
never invalidated, since it only checks the source .gpx's mtime).

The CI deploy job now writes REVISION (short SHA) before dropping
.git; app.rb reads it at boot, falling back to "dev" locally/in CI's
own check job where the file never exists.
2026-09-07 23:54:24 +02:00
randy cd4eef342b Add a persisted test suite
CI / check (push) Successful in 1m56s
CI / deploy (push) Successful in 2m56s
`bundle exec rake test` (minitest, a default gem but pinned in
Gemfile for reproducibility) now covers what ad-hoc scripts kept
re-verifying by hand during development: Gpx/Fit/TrackStats parsing,
GpxStore/LiveTrackStore file/TTL logic, LiveTrackClient's payload
parsing, and app.rb's routes end to end via Rack::MockRequest.

MAPTOOL_DATA_DIR (new, app.rb) lets the suite point GPX_STORE/
LIVETRACK_STORE at a throwaway directory instead of real data/ —
without it every run would leave uploaded test files behind. Each
lib file's old `if __FILE__ == $0` self-check is now redundant with
real tests covering the same ground, so removed rather than kept as
a second copy of the same assertions. Wired into ci.yml so it isn't
just a local convenience.
2026-09-07 12:46:35 +02:00
randy f9ddf860ea Add Garmin LiveTrack session tracking
CI / check (push) Successful in 6m49s
CI / deploy (push) Successful in 23s
A Gmail-watching Apps Script (documented in docs/deployment.adoc) posts
the session ID from each LiveTrack email to a new webhook, which stores
it in data/livetrack.json; a new sidebar panel lists what's been
received.
2026-09-06 21:05:35 +02:00
randy 60170efda2 Rename deploy runner label to cube-host
CI / check (push) Successful in 6m26s
CI / deploy (push) Successful in 22s
2026-08-28 20:38:16 +02:00
randy 3fbd97a0bd Add a weekly Renovate workflow for dependency updates
CI / check (push) Successful in 7m25s
CI / deploy (push) Successful in 14s
Runs renovate/renovate against this Gitea instance on the native
deploy runner, opening PRs for outdated Bundler dependencies instead
of relying on manually noticing (as happened with puma/mustermann
earlier).
2026-08-27 19:31:24 +02:00
randy e13d1a1e97 Require Gitea login to write GPX data; IPv6-capable bind
CI / check (push) Successful in 6m28s
CI / deploy (push) Successful in 13s
Upload/delete/move/create-folder now require logging in via Gitea
OAuth2 (only MAPTOOL_ALLOWED_GITEA_USER is granted write access);
reading stays public. Deploy secrets (session secret, OAuth2 client
credentials, allowed user) are written to .env from Gitea Actions
repo secrets on every deploy instead of living on the server by hand.

Also switch the container's bind address to "[::]" (dual-stack) so
the app is reachable over IPv6, not just IPv4.
2026-08-27 18:02:37 +02:00
randy ae67cc72c7 Move deploy job to a dedicated native runner
CI / check (push) Successful in 5m43s
CI / deploy (push) Successful in 2m46s
The Docker-based runner's own container is too minimal for host-mode
jobs (no rsync, docker CLI, or Node.js) and has no reliable path to
the host filesystem or systemctl otherwise. Register a separate,
native runner (label deploy:host) just for deployment, and point the
deploy job at it.
2026-08-27 16:12:33 +02:00
randy 71e638b459 Fix CI: host-mode runner has no Node.js for actions/checkout
CI / check (push) Successful in 7m3s
CI / deploy (push) Failing after 1s
Host-mode jobs run directly in the runner container instead of a
spawned per-job container, so JS actions like actions/checkout@v4
have no Node.js runtime to execute with. Replace it with a plain git
fetch/checkout in the deploy job.
2026-08-27 15:39:47 +02:00
randy 3a79c3d6c1 Add Docker deployment via Gitea Actions host-mode runner
CI / check (push) Successful in 5m47s
CI / deploy (push) Failing after 1s
Containerize the app (Dockerfile, docker-compose.yaml) and add a CI
deploy job that syncs the checkout to /srv/docker/maptool and runs
docker compose directly, using the runner's new "host" execution
label to reach the host's Docker daemon and filesystem.
2026-08-27 14:54:21 +02:00
randy f186a3e8ef Fix CI: ruby/setup-ruby doesn't recognize "file" as a version keyword
CI / check (push) Successful in 5m47s
Omitting ruby-version entirely triggers its actual auto-detection from
.ruby-version — "file" was a mistaken guess and failed with "Unknown
engine file".
2026-08-27 14:06:31 +02:00
randy 7f2ad57d1a Add a Gitea Actions CI workflow
CI / check (push) Failing after 1m30s
Ruby syntax check, a require_relative "app" smoke load, and JS syntax
check on every push/PR. No test suite exists yet, so these are cheap
syntax/load checks rather than behavioral tests.
2026-08-27 14:03:37 +02:00