Commit graph

35 commits

Author SHA1 Message Date
db6d231887 ci: add postgres health-check options, remove fragile /dev/tcp wait
Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 18m2s
2026-07-28 08:31:28 -05:00
9242c58a5a feat(ci): add mix test step with postgres before build-and-push
Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 2m36s
Adds a postgres:17-alpine service, a wait-for-postgres step, and a
Run tests step that runs mix ecto.create/migrate/test in the same
docker-run pattern. If tests fail, the Build and push step is
automatically skipped.
2026-07-28 08:05:32 -05:00
486c1e5c66 fix(ci): install build-essential in verify step for bcrypt_elixir NIF compilation
Some checks failed
Build and Push / Build and Push Docker Image (push) Has been cancelled
2026-07-28 08:03:41 -05:00
cfa2b06617 fix(ci): install git+curl in verify-compilation container
Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 30s
The hexpm/elixir slim image lacks git (needed for heroicons git dep)
and curl (needed for esbuild/tailwind binary downloads).
2026-07-28 08:02:26 -05:00
31f7db8cb1 fix(ci): replace broken volume mount with tar pipe in verify-compilation step
Some checks failed
Build and Push / Build and Push Docker Image (push) Failing after 10s
The runner is containerised so the host Docker daemon cannot see its
filesystem. Replace `-v ${{ github.workspace }}:/app` with a
`tar | docker run -i ... tar xf -` pipeline to stream the workspace
into the verification container.
2026-07-28 07:35:54 -05:00
0c3be97abb
fix: resolve 27 security, architecture, test, and performance audit findings
Some checks failed
Build base image / Build and push base image (push) Successful in 3m10s
Build and Push / Build and Push Docker Image (push) Failing after 14s
Build prop-grid-rs / Test, build, push (push) Successful in 12m52s
P0 (security-critical):
- Gate CSV/ADIF upload tabs behind authentication, add 30s cooldown to all upload handlers
- Cap CSV/ADIF imports at 2,000 rows server-side in both parsers
- Add submitter_verified boolean to contacts (client-cannot-set, anonymous=false)
- Create k8s/secret.example.yaml with placeholders, add LIVE_VIEW_SIGNING_SALT

P1 (high-priority):
- Add Mox.verify_on_exit!() to valkey_test.exs
- Replace DateTime.utc_now() truncation with static ~U literals in map_live_test.exs
- Replace Process.sleep with render_async in pskr_spots_live_test.exs (6 occurrences)
- Add MonitorLive.Show test coverage (4 tests: owner view, non-owner redirect, config success/error)
- Extract duct-detection and mechanism-classification logic from ContactLive.Show into Propagation.PathAnalysis
- Split ContactLive.Show render into 12 function components
- Update CLAUDE.md: remove stale ML model, mark HRDPS active, add backtest/pskr dirs
- Batch CSV import enrichment jobs via new enqueue_for_contacts/1

P2 (medium-priority):
- Set secure:true on session and remember-me cookies in production
- Change SMTP TLS from verify_none to verify_peer with public_key cacerts
- Make /metrics fail-closed in production when PROMETHEUS_AUTH_TOKEN unset
- Add RateLimiter (anon_limit:10, auth_limit:60) to /api/contacts/map
- Add content-security-policy-report-only header
- Add comment noting String.to_atom is compile-time safe in hrdps_client.ex
- Delegate duplicated haversine_km to canonical Microwaveprop.Geo.haversine_km/4
- Consolidate score-tier/color/verdict formatting into Microwaveprop.Format
- Update CLAUDE.md testing section to match actual raw-string-matching practice
- Batch HrrrPointEnqueuer Repo.insert_all calls to single round-trip
- Split weather.ex (1696→216 lines) and radio.ex (1285→54 lines) into purpose-based sub-facades

P3 (low-priority):
- Add LIVE_VIEW_SIGNING_SALT warning comment, extend filter_parameters
- Add host/community validation to snmp_client.ex
- Add raw/1 safety comment in algo_live.ex
- Add hex-audit and cargo-audit Makefile targets
- Add privacy_live smoke test
- Replace notify_listener busy-poll loop with Process.monitor/1 + assert_receive
- Add ContactCommonVolumeRadar changeset validation tests (5 tests)
2026-07-27 18:19:37 -05:00
7bda38260d
fix: use full forgejo URL for kaniko-build action instead of github resolution
Some checks failed
Build base image / Build and push base image (push) Failing after 6s
Build and Push / Build and Push Docker Image (push) Failing after 7s
Build prop-grid-rs / Test, build, push (push) Failing after 6m38s
2026-07-27 14:22:14 -05:00
f753de6ff8
fix: use Forgejo checkout mirror instead of bare actions/checkout ref
Some checks failed
Build base image / Build and push base image (push) Failing after 2s
Build prop-grid-rs / Test, build, push (push) Failing after 2s
Build and Push / Build and Push Docker Image (push) Failing after 2s
2026-07-27 12:12:06 -05:00
31b2516d0e
fix: use bare action refs
Some checks failed
Build base image / Build and push base image (push) Failing after 1s
Build prop-grid-rs / Test, build, push (push) Failing after 2s
Build and Push / Build and Push Docker Image (push) Failing after 2s
2026-07-27 10:19:36 -05:00
39f899ce2e
fix: use forgejo action mirrors, add pre-build compile and clippy checks
Some checks failed
Build base image / Build and push base image (push) Failing after 3s
Build prop-grid-rs / Test, build, push (push) Failing after 2s
Build and Push / Build and Push Docker Image (push) Failing after 2s
2026-07-27 08:55:38 -05:00
0643ff76c8 Use Kaniko for Docker builds
Some checks failed
Build prop-grid-rs / Test, build, push (push) Failing after 2s
Build and Push / Build and Push Docker Image (push) Failing after 1s
2026-07-24 14:36:27 -05:00
8597b721c5 Use Kaniko for Docker builds
Some checks are pending
Build base image / Build and push base image (push) Waiting to run
Build and Push / Build and Push Docker Image (push) Waiting to run
2026-07-24 14:36:27 -05:00
6197c649b3 Use Kaniko for Docker builds
Some checks failed
Build prop-grid-rs / Test, build, push (push) Waiting to run
Build and Push / Build and Push Docker Image (push) Waiting to run
Build base image / Build and push base image (push) Failing after 2s
2026-07-24 14:36:26 -05:00
2a177676e5 Migrate from codeberg.org to git.mcintire.me
All checks were successful
Build and Push / Build and Push Docker Image (push) Successful in 3m21s
2026-07-24 14:23:22 -05:00
56b4116f6f Migrate from codeberg.org to git.mcintire.me
Some checks are pending
Build and Push / Build and Push Docker Image (push) Waiting to run
Build prop-grid-rs / Test, build, push (push) Successful in 6m44s
2026-07-24 14:23:21 -05:00
26e1163107 Migrate from codeberg.org to git.mcintire.me
Some checks are pending
Build prop-grid-rs / Test, build, push (push) Waiting to run
Build and Push / Build and Push Docker Image (push) Waiting to run
Build base image / Build and push base image (push) Successful in 4m35s
2026-07-24 14:23:20 -05:00
1650744e89
chore(ci): source registry host from secrets.REGISTRY_URL
All three image build workflows previously hardcoded REGISTRY=codeberg.org
and only pulled USER/PASSWORD from secrets. Switching the URL to come from
the same secrets bag means a registry rotation only needs the
REGISTRY_URL / REGISTRY_USER / REGISTRY_PASSWORD secrets updated, not a
commit to every workflow file.
2026-05-05 14:31:50 -05:00
8a9c0ba67f
chore(ci): move prop and prop-grid-rs images to codeberg
Both build workflows now push to codeberg.org/gmcintire/<image>
alongside the runtime base. Login URL is the hardcoded env.REGISTRY
rather than secrets.REGISTRY_URL so a stale/wrong URL secret can't
silently push to the wrong registry.

k8s deployment manifests still reference git.mcintire.me images and
need a follow-up bump to codeberg-side tags after the next CI build
lands an image at codeberg.org.
2026-05-05 10:29:26 -05:00
4f4d9e44fc
chore(ci): host prop-base on codeberg.org
Move the runtime base image from git.mcintire.me/graham/prop-base
to codeberg.org/gmcintire/prop-base. The shared REGISTRY_USER /
REGISTRY_PASSWORD secrets are pointed at Codeberg credentials;
the build-base workflow hardcodes env.REGISTRY=codeberg.org so it
can't accidentally push to a different registry if the URL secret
drifts.

The main app + prop-grid-rs builds still pull this base via the
BASE_IMAGE arg in Dockerfile, now codeberg.org/gmcintire/prop-base:latest.
2026-05-05 10:22:31 -05:00
0711d9af11
ci: rebuild prop-base weekly to pull Debian security patches
Adds a Sunday 06:00 UTC schedule trigger to build-base.yaml plus a
CACHE_BUST=<ISO year+week> build-arg keyed off `date -u +%G-W%V`. The
apt RUN steps in Dockerfile.base reference the arg in their command
line so BuildKit's layer hash changes when the week rolls over,
forcing apt-get update + install to re-execute and pull fresh
security updates.

The wgrib2-builder stage doesn't see CACHE_BUST so the ~5-min wgrib2
compile keeps hitting layer cache across weeks; only the apt layers
rebuild. Effective cost of the weekly job: ~2 min for the cdo /
gdal-bin reinstall.
2026-05-03 11:51:08 -05:00
8ea31e4317
ci: add prop-base image build pipeline
Pre-builds the runtime base (wgrib2 + g2c + cdo + gdal-bin + locale +
runtime apt deps) into git.mcintire.me/graham/prop-base. The base
workflow is path-filtered to fire only on Dockerfile.base /
build-base.yaml changes, so version bumps stay deterministic and
explicit.

Tag convention: `wgrib2-<v>-g2c-<v>-<unixts>` for traceability +
rollback, plus `:latest` for everyday consumption.

This commit only adds the new files — the app Dockerfile + build.yaml
still build wgrib2 from source. A follow-up will swap the app
Dockerfile to FROM prop-base:latest once this image lands in the
registry.
2026-05-03 11:40:50 -05:00
141956b727
ci(grid-rs): surface docker daemon diagnostics on wait-step failure
Mirrors the verbose wait-for-docker block from build.yaml so future "failed
to connect to docker" failures print socket permissions, docker-related
env vars, and full `docker info` output instead of a single unhelpful line.
2026-04-20 08:41:53 -05:00
8774181824
ci: run clippy + cargo test inside Dockerfile builder
The previous approach (`docker run -v $(pwd)/rust/prop_grid_rs:/src`)
fails under act_runner because the runner container's pwd isn't a path
the host docker daemon can see — clippy installed, then cargo couldn't
find Cargo.toml.

Move the lint + test gate into the Dockerfile builder stage so the
build context ships over the socket the normal way. If clippy warns or
a test regresses, the image build fails and nothing is pushed.
2026-04-19 15:55:26 -05:00
339591cedd
ci: install clippy component before running it
`rust:1.94-trixie` ships rustc + cargo but not clippy — `rustup
component add clippy` pulls it in on the fly.
2026-04-19 15:50:19 -05:00
d570452168
ci: add build-grid-rs workflow for the Rust worker image
Runs `cargo clippy --all-targets -- -D warnings` + `cargo test` inside
a rust:1.94-trixie container, then builds `rust/prop_grid_rs/Dockerfile`
and pushes three tags: the timestamped `main-<ts>-<sha>`, `latest`, and
a static `main` tag that `k8s/deployment-grid-rs.yaml` pins to.

Path-filtered to `rust/prop_grid_rs/**` so Elixir-only pushes don't
trigger a redundant Rust build.
2026-04-19 15:48:41 -05:00
fd48263992
Revert "ci: build against a dind sidecar instead of the host socket"
This reverts commit 2a6f14129a.
2026-04-19 12:29:24 -05:00
2a6f14129a
ci: build against a dind sidecar instead of the host socket
The host docker socket wasn't mounted consistently across act_runners,
so which runner picked up the push was the difference between a clean
build and "unable to connect to docker." Switch to a dockerd service
pinned to the same bridge network as the job; the CLI now talks to
it over TCP via DOCKER_HOST=tcp://dockerd:2375. Every runner has a
daemon, every time — no more re-runs for the scheduling lottery.
2026-04-19 12:24:41 -05:00
c5436279ed
ci: dump docker socket diagnostics when the daemon poll times out
The 30s poll is enough to ride out a slow daemon startup, but not a
runner where the socket isn't mounted at all. Print DOCKER_HOST, the
socket stat, and the verbose `docker info` error on timeout so the
next flaky run tells us whether it's a startup race or a missing
mount.
2026-04-19 12:21:39 -05:00
d51f545ab7
ci: ride out docker daemon + registry flakes
Forgejo act_runner mounts the host docker socket into the job
container; the daemon sometimes takes a beat to answer, which has
been surfacing as intermittent "unable to connect to docker" failures
on login. Gate the build on a `docker info` poll (up to 30s) so later
steps don't race the socket, and wrap login + buildx push in a 3-try
exponential-backoff (2s/4s/8s) so a transient registry hiccup doesn't
require a manual workflow re-run.
2026-04-19 12:19:43 -05:00
5a25c6d649
ci: install buildx and use docker buildx build --push
The Dockerfile uses `--mount=type=cache` which requires BuildKit.
The static docker tarball only ships the CLI, so the plugin has to
be installed separately. Also flip the build step to
`docker buildx build --push` so build and push happen in one pass
instead of two (avoids the intermediate local-daemon load).
2026-04-18 15:21:30 -05:00
508834633e
ci: install docker CLI from static tarball, not apt
The runner image's bookworm apt repos have been failing GPG
verification with "At least one invalid signature was encountered"
on every job. Clearing lists and reinstalling debian-archive-keyring
on the host doesn't help because the runner spins up a fresh
container per job. Dodge apt entirely by grabbing the static Docker
27.5.1 client binary from download.docker.com. The binary talks to
the host's /var/run/docker.sock that act_runner mounts into the job
container, which is all we need for build + push.
2026-04-18 15:01:24 -05:00
b6caffea3e
feat(nav): show last-deployed timestamp
Docker final stage bakes BUILD_TIMESTAMP into /app/BUILD_TIMESTAMP via
build-arg (only consumed after mix compile, so earlier layer caching is
preserved). Application.build_timestamp/0 reads the file, falls back to
DEPLOY_TIMESTAMP env, then to compile time. Navbar renders a compact
"Deployed Xm ago" with the full UTC time in the tooltip.
2026-04-17 13:08:51 -05:00
ab819852ae Install Docker CLI in CI runner container 2026-04-11 09:04:22 -05:00
669fe07bcf Replace buildx/login GitHub Actions with plain docker commands
setup-buildx-action downloads from GitHub Releases which is slow
and unreliable from the Forgejo runner. Plain docker build/push
works fine since Docker is already on the runner host.
2026-04-10 17:22:57 -05:00
a11a3ec775 Add k8s manifests and Forgejo CI for cluster deployment 2026-04-06 09:25:24 -05:00