Files
lora.vegas/README.md
clawbot fd3cd4c18c
All checks were successful
check / check (push) Successful in 16s
Add Makefile shims for cibuild and precommit (closes #34)
script/cibuild and script/precommit both existed and were already the
documented CI and pre-commit entrypoints, but neither had a Makefile
target, so the standing rule to drive the repo through make targets
rather than the underlying tool could not be followed for either.

It matters most for the build. A bare `docker build .` fails closed on
the CHECK_EPOCH guard by design, so script/cibuild is one of only three
supported ways to build an image here, and it was the only one of the
three without a target while `make docker` had one.

The two targets are thin shims in the same style as every other target
and change nothing about what the scripts do. .PHONY was already
complete for the targets that existed and now lists both new ones.

README.md's Entrypoints section gains the script-to-target mapping so
the two documents agree, including the two names that do not match:
script/install-precommit is `make hooks`, and script/precommit is
`make precommit`. It also notes that `make cibuild` is the slowest
target, because it is the only one that runs two container builds --
while still taking seconds once the shared script/bootstrap layer is
cached, since Dockerfile.lint's first four instructions are
byte-identical to the main Dockerfile's and the pinned-Hugo compile is
therefore paid once per machine rather than twice.

Two accuracy fixes to text the same section already carried. The
script/install-precommit bullet said the installed hook runs
script/check; the script writes script/precommit into
.git/hooks/pre-commit, and its own header comment says so. And the
Makefile is described as listing the operations you are expected to run
rather than as the authoritative list of everything the repo can do,
which is not literally true: script/projectname is an internal helper
that script/docker calls to compute a tag, and it has no target
deliberately -- a target for it would be noise in the `make<tab>`
listing this change exists to make useful.

TODO.md also loses the stale Future Step asking someone to confirm the
static/_headers file took effect in production. That was confirmed live
on both hostnames on 2026-08-10 and recorded at
#14 , so the item is work
already done. The Status paragraph's matching "unverified in production
until the next deploy" clause is corrected for the same reason: a commit
that edits TODO.md should not leave a known-false statement in it.
2026-08-10 13:57:34 +00:00

6.4 KiB

lora.vegas

lora.vegas is the website of the Las Vegas Meshtastic and LoRa community: an MIT-licensed single-page static site, built with Hugo, by @sneak.

It publishes what the local mesh needs in one linkable place:

  • Mesh channel configurations
  • Community coordination links (Discord, Signal)
  • Meetup information
  • Local resources

Getting Started

From a fresh clone, make setup installs every build dependency (git, make, go, the pinned Hugo, node/npm) and the git pre-commit hook, and make serve starts the Hugo development server:

git clone git@git.eeqj.de:sneak/lora.vegas.git
cd lora.vegas
make setup
make serve

Then open http://localhost:1313 to preview the site.

To produce the production build, which writes the rendered site to public/:

make test

Before committing, run the full check suite — the production build, the lint build, and the formatting check:

make check

The lint runs inside Docker, so make check needs a working Docker daemon; there is no host fallback. On a machine that has never built the image, the first run compiles the pinned Hugo from source, which takes minutes; later runs reuse that cached layer.

make fmt rewrites the repo's markdown and CSS to the project's prettier settings; run it if make check fails on formatting.

To contribute to this site, contact sneak@sneak.berlin for git repository access.

Entrypoints

This repository adheres to the Scripts to Rule Them All standard: normalized scripts in script/ are the entrypoints for the development workflow, and the Makefile targets are thin shims that call them. We provide:

  • script/bootstrap — install all build dependencies (git, make, go, hugo, node/npm) idempotently. Hugo is pinned to an exact version and installed with go install, which verifies it against sum.golang.org; the version is the HUGO_VERSION constant at the top of the script
  • script/setup — prepare a fresh clone: run script/bootstrap and install the git pre-commit hook
  • script/test — the correctness check: a clean hugo --minify production build
  • script/lint — a clean build that surfaces broken links and path collisions, run inside Docker: it builds Dockerfile.lint, where the lint is a build step, so a successful build is a clean lint
  • script/fmt — format every markdown and CSS file in the repo with prettier; the exclusions live in .prettierignore with the reason for each
  • script/fmt-check — check that formatting (read-only)
  • script/check — run script/test, script/lint, then script/fmt-check; modifies no tracked files
  • script/docker — build the Docker image tagged with the project name
  • script/cibuild — the CI build: script/lint first, for fail-fast feedback, then the main image, which runs the non-lint checks
  • script/install-precommit — install the git pre-commit hook that runs script/precommit

Each of those has a Makefile shim of the same name — make bootstrap, make setup, make test, make lint, make fmt, make fmt-check, make check, make docker, make cibuild — with one exception: script/install-precommit is make hooks. script/precommit, which is what the installed hook runs, is make precommit. Prefer the make targets; the Makefile lists the operations you are expected to run.

make cibuild is the slowest target: it is the only one that runs two container builds, the lint image first and then the main image. The two share the script/bootstrap layer byte-for-byte, so the pinned-Hugo compile described above is paid once per machine rather than twice, and once that layer is cached a full make cibuild takes seconds. That is the cost of the CI build, not a sign of a problem.

Every lint run for this repo happens inside a container, and only the lint does. script/lint has no host path and no "already inside a container?" branch, so what a developer runs and what CI runs are the same build. script/fmt and script/fmt-check run on the host: a formatting check is not a lint.

That is also why the main Dockerfile runs script/test and script/fmt-check rather than make check. make check calls script/lint, which is itself a docker build, so a make check inside an image would attempt a docker build in a bare Alpine with no docker client and no daemon socket. The lint is not skipped — script/cibuild runs it first, in its own container, before the main image build starts.

Build any image through script/cibuild, script/docker or script/lint only. All three pass a per-invocation CHECK_EPOCH build argument that the Dockerfiles require, so a check layer can never be served from cache — without it Docker returns a green it did not earn. A bare docker build fails closed on the CHECK_EPOCH guard rather than caching its way to a false success.

A convenience make serve target runs hugo server for local preview.

Rationale

The Las Vegas Meshtastic and LoRa community needs one durable, linkable place for its channel configurations and group links. Those details otherwise live inside a Discord or Signal thread, where they scroll away, cannot be linked to from outside, are invisible to anyone who has not already joined, and quietly go stale. A static site at a stable domain is the opposite of that: one URL to hand to a newcomer, and one place to correct when a channel changes.

Design

The site is a single page. All of its content is one Hugo content file, content/_index.md, rendered by a minimal theme vendored in-repo at themes/loravega/ — there is no upstream theme dependency and no submodule.

The theme's layouts/_default/baseof.html inlines themes/loravega/static/css/style.css into a <style> block with Hugo's readFile, so the whole site ships as a single HTML document with no external CSS request and no second round trip.

hugo --minify builds the site into public/. Deployment is automatic: on push to main, the Gitea Actions workflow .gitea/workflows/deploy.yml builds the site and publishes public/ to Cloudflare Pages.

TODO

The live task list is in TODO.md.

License

MIT. See LICENSE. This covers everything in the repository — the Hugo configuration, the script/ entrypoints, the vendored themes/loravega/ templates and CSS, and the site content in content/.

Author

@sneak