Add scripts-to-rule-them-all scaffold (closes #4)
Adopt the Scripts to Rule Them All standard for this Hugo site: - script/ POSIX-sh entrypoints (bootstrap, setup, projectname, test, lint, fmt, fmt-check, check, docker, cibuild, precommit, install-precommit). The correctness check (test/lint) is a clean `hugo --minify` production build; fmt/fmt-check run prettier over the repo's own top-level markdown only, leaving content/ untouched. - Makefile targets reduced to thin shims that call script/NAME, plus a convenience serve target for `hugo server`. - Dockerfile on a sha256-pinned alpine base that installs deps via script/bootstrap and runs `make check`, so the image build fails on any formatting or Hugo build error; .dockerignore added. - .gitea/workflows/check.yml runs script/cibuild on push. - README Entrypoints section documenting the scripts.
This commit was merged in pull request #5.
This commit is contained in:
4
.dockerignore
Normal file
4
.dockerignore
Normal file
@@ -0,0 +1,4 @@
|
||||
.git
|
||||
public
|
||||
resources
|
||||
.hugo_build.lock
|
||||
9
.gitea/workflows/check.yml
Normal file
9
.gitea/workflows/check.yml
Normal file
@@ -0,0 +1,9 @@
|
||||
name: check
|
||||
on: [push]
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# actions/checkout v4.2.2, 2026-02-28
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
|
||||
- run: script/cibuild
|
||||
18
Dockerfile
Normal file
18
Dockerfile
Normal file
@@ -0,0 +1,18 @@
|
||||
# Hugo static-site build image. The build runs `make check` (the
|
||||
# read-only prettier docs check plus a clean `hugo --minify` production
|
||||
# build), so the image build fails on any formatting or Hugo build
|
||||
# error. This is what CI (script/cibuild) runs on every push.
|
||||
# alpine 3.21, 2026-02-28
|
||||
FROM alpine@sha256:c3f8e73fdb79deaebaa2037150150191b9dcbfba68b4a46d70103204c53f4709
|
||||
|
||||
WORKDIR /src
|
||||
|
||||
# Install build dependencies first so the layer caches until the
|
||||
# scripts change (script/bootstrap installs git, make, hugo, node/npm).
|
||||
COPY script/ script/
|
||||
RUN script/bootstrap
|
||||
|
||||
COPY . .
|
||||
|
||||
# Run all checks - build fails if any check fails.
|
||||
RUN make check
|
||||
31
Makefile
Normal file
31
Makefile
Normal file
@@ -0,0 +1,31 @@
|
||||
.PHONY: bootstrap setup test lint fmt fmt-check check docker hooks serve
|
||||
|
||||
bootstrap:
|
||||
@script/bootstrap
|
||||
|
||||
setup:
|
||||
@script/setup
|
||||
|
||||
test:
|
||||
@script/test
|
||||
|
||||
lint:
|
||||
@script/lint
|
||||
|
||||
fmt:
|
||||
@script/fmt
|
||||
|
||||
fmt-check:
|
||||
@script/fmt-check
|
||||
|
||||
check:
|
||||
@script/check
|
||||
|
||||
docker:
|
||||
@script/docker
|
||||
|
||||
hooks:
|
||||
@script/install-precommit
|
||||
|
||||
serve:
|
||||
@hugo server
|
||||
35
README.md
35
README.md
@@ -4,7 +4,8 @@ Las Vegas Meshtastic and LoRa community website.
|
||||
|
||||
## About
|
||||
|
||||
This site provides information about the Las Vegas mesh networking community, including:
|
||||
This site provides information about the Las Vegas mesh networking community,
|
||||
including:
|
||||
|
||||
- Mesh channel configurations
|
||||
- Community coordination (Discord, Signal)
|
||||
@@ -13,11 +14,13 @@ This site provides information about the Las Vegas mesh networking community, in
|
||||
|
||||
## Contributing
|
||||
|
||||
To contribute to this site, contact **sneak@sneak.berlin** for git repository access.
|
||||
To contribute to this site, contact **sneak@sneak.berlin** for git repository
|
||||
access.
|
||||
|
||||
## Technical Details
|
||||
|
||||
This is a static site built with Hugo. The site is deployed automatically via GitHub Actions.
|
||||
This is a static site built with Hugo. The site is deployed automatically via
|
||||
GitHub Actions.
|
||||
|
||||
### Local Development
|
||||
|
||||
@@ -35,6 +38,32 @@ hugo
|
||||
|
||||
Output will be in the `public/` directory.
|
||||
|
||||
## Entrypoints
|
||||
|
||||
This repository adheres to the
|
||||
[Scripts to Rule Them All](https://github.com/github/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, hugo,
|
||||
node/npm) idempotently
|
||||
- `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
|
||||
- `script/fmt` — format the repo's own top-level markdown docs with prettier
|
||||
- `script/fmt-check` — check that formatting (read-only)
|
||||
- `script/check` — run `script/fmt-check` then `script/test`; modifies nothing
|
||||
- `script/docker` — build the Docker image tagged with the project name
|
||||
- `script/cibuild` — the CI build (`docker build .`); the Dockerfile runs
|
||||
`make check`
|
||||
- `script/install-precommit` — install the git pre-commit hook that runs
|
||||
`script/check`
|
||||
|
||||
A convenience `make serve` target runs `hugo server` for local preview.
|
||||
|
||||
## License
|
||||
|
||||
Content is provided as-is for community use.
|
||||
|
||||
70
TODO.md
70
TODO.md
@@ -1,51 +1,53 @@
|
||||
# Workflow
|
||||
|
||||
* branch (from `main`)
|
||||
* do the work in Next Step
|
||||
* move Next Step to the top of Completed Steps
|
||||
* move the top item of Future Steps into Next Step
|
||||
* commit (`TODO.md` changes in the same commit as the work)
|
||||
* merge to `main` if the branch is not protected, otherwise open a PR
|
||||
* push
|
||||
- branch (from `main`)
|
||||
- do the work in Next Step
|
||||
- move Next Step to the top of Completed Steps
|
||||
- move the top item of Future Steps into Next Step
|
||||
- commit (`TODO.md` changes in the same commit as the work)
|
||||
- merge to `main` if the branch is not protected, otherwise open a PR
|
||||
- push
|
||||
|
||||
# Status
|
||||
|
||||
pre-1.0
|
||||
|
||||
No git tags. The site is live, but the repo lacks the standard scaffold
|
||||
(Makefile, LICENSE, Dockerfile, policy files).
|
||||
No git tags. The site is live and now has the scripts-to-rule-them-all scaffold
|
||||
(`Makefile`, `script/`, `Dockerfile`, `check.yml`); still missing `LICENSE` and
|
||||
policy files.
|
||||
|
||||
# Next Step
|
||||
|
||||
Add the policy scaffold in one commit: Makefile with Hugo-appropriate
|
||||
targets (test builds the site with hugo --minify, lint/fmt/fmt-check via
|
||||
prettier over content and theme, check, hooks), .prettierrc and
|
||||
.prettierignore, LICENSE, REPO_POLICIES.md, .editorconfig, and a
|
||||
Dockerfile plus .dockerignore that builds the site and runs make check,
|
||||
images pinned by sha256. Update README to mention the new workflow.
|
||||
Add the remaining policy scaffold: `LICENSE`, `REPO_POLICIES.md`,
|
||||
`.editorconfig`, and prettier config files (`.prettierrc`, `.prettierignore`).
|
||||
Update `README.md` accordingly.
|
||||
|
||||
# Completed Steps
|
||||
|
||||
* 2026-02-10: design pass: minimal light theme with inline CSS, grey
|
||||
wells for mesh channels and signal groups, horizontal overflow fix,
|
||||
body width tuning, map link update
|
||||
* 2026-02-10: added README and footer contribute link
|
||||
* 2026-02-10: added Gitea workflow that builds the site and deploys to
|
||||
- 2026-07-25: added the scripts-to-rule-them-all scaffold (closes #4): `script/`
|
||||
entrypoints, `Makefile` shims, a Hugo `Dockerfile` (sha256-pinned alpine) plus
|
||||
`.dockerignore` that runs `make check`, `.gitea/workflows/check.yml` running
|
||||
`script/cibuild`, and a README Entrypoints section. `test`/`lint` are a clean
|
||||
`hugo --minify` build; `fmt`/`fmt-check` run prettier over the repo's own
|
||||
top-level markdown only
|
||||
- 2026-02-10: design pass: minimal light theme with inline CSS, grey wells for
|
||||
mesh channels and signal groups, horizontal overflow fix, body width tuning,
|
||||
map link update
|
||||
- 2026-02-10: added README and footer contribute link
|
||||
- 2026-02-10: added Gitea workflow that builds the site and deploys to
|
||||
Cloudflare Pages
|
||||
* 2026-02-08: initial Hugo static site for lora.vegas
|
||||
- 2026-02-08: initial Hugo static site for lora.vegas
|
||||
|
||||
# Future Steps
|
||||
|
||||
* Add .gitea/workflows/check.yml that runs make check; pin the images
|
||||
and actions in deploy.yml by sha256 (klakegg/hugo:ext-alpine,
|
||||
node:20, actions/checkout, upload/download-artifact are all
|
||||
unpinned)
|
||||
* Rework README.md into the standard sections: Description, Getting
|
||||
Started, Rationale, Design, TODO, License, Author (currently About,
|
||||
Contributing, Technical Details, License)
|
||||
* Replace the "content is provided as-is" README note with the text of
|
||||
the committed LICENSE
|
||||
* Expand .gitignore beyond Hugo outputs (OS and editor files)
|
||||
* Verify the Cloudflare Pages deploy still works after the workflow
|
||||
changes
|
||||
* Keep mesh channel and signal group listings current
|
||||
- Pin the images and actions in `deploy.yml` by sha256
|
||||
(`klakegg/hugo:ext-alpine`, `node:20`, `actions/checkout`,
|
||||
`upload`/`download-artifact` are all unpinned)
|
||||
- Rework README.md into the standard sections: Description, Getting Started,
|
||||
Rationale, Design, TODO, License, Author (currently About, Contributing,
|
||||
Technical Details, License)
|
||||
- Replace the "content is provided as-is" README note with the text of the
|
||||
committed LICENSE
|
||||
- Expand .gitignore beyond Hugo outputs (OS and editor files)
|
||||
- Verify the Cloudflare Pages deploy still works after the workflow changes
|
||||
- Keep mesh channel and signal group listings current
|
||||
|
||||
76
script/bootstrap
Executable file
76
script/bootstrap
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/bin/sh
|
||||
# script/bootstrap: install all dependencies needed to build and develop
|
||||
# this Hugo site, idempotently. Base tooling comes from nix, apt, brew,
|
||||
# or apk (detected in that order); assumes NOTHING is present (not git,
|
||||
# make, hugo, or node). Installs hugo (the site build) and node/npm
|
||||
# (prettier, used to format the repo's own markdown docs). Every install
|
||||
# is guarded by a check so already-installed tools are skipped.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
PKGMGR=""
|
||||
SUDO=""
|
||||
|
||||
detect_pkgmgr() {
|
||||
[ -n "$PKGMGR" ] && return 0
|
||||
if command -v nix-env >/dev/null 2>&1; then
|
||||
PKGMGR="nix"
|
||||
elif command -v apt-get >/dev/null 2>&1; then
|
||||
PKGMGR="apt"
|
||||
elif command -v brew >/dev/null 2>&1; then
|
||||
PKGMGR="brew"
|
||||
elif command -v apk >/dev/null 2>&1; then
|
||||
PKGMGR="apk"
|
||||
else
|
||||
echo "bootstrap: no supported package manager (nix, apt, brew, apk)" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [ "$PKGMGR" = "apt" ]; then
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
if [ "$(id -u)" != "0" ]; then
|
||||
SUDO="sudo"
|
||||
fi
|
||||
$SUDO env DEBIAN_FRONTEND=noninteractive apt-get update
|
||||
fi
|
||||
}
|
||||
|
||||
# pkg_install <nix-attr> <apt-pkg> <brew-formula> <apk-pkg>
|
||||
pkg_install() {
|
||||
detect_pkgmgr
|
||||
case "$PKGMGR" in
|
||||
nix) nix-env -iA "nixpkgs.$1" ;;
|
||||
apt) $SUDO env DEBIAN_FRONTEND=noninteractive apt-get install -y "$2" ;;
|
||||
brew) brew install "$3" ;;
|
||||
apk) apk add --no-cache "$4" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
missing() {
|
||||
! command -v "$1" >/dev/null 2>&1
|
||||
}
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
|
||||
# Base tooling.
|
||||
if missing git; then pkg_install git git git git; fi
|
||||
if missing make; then pkg_install gnumake make make make; fi
|
||||
|
||||
# The theme is vendored in-repo, but initialise submodules if any
|
||||
# are ever added so a fresh clone is buildable.
|
||||
if [ -f .gitmodules ]; then
|
||||
git submodule update --init --recursive
|
||||
fi
|
||||
|
||||
# Site build.
|
||||
if missing hugo; then pkg_install hugo hugo hugo hugo; fi
|
||||
|
||||
# node/npm provide prettier (via npx) for formatting the docs.
|
||||
if missing node; then pkg_install nodejs nodejs node nodejs; fi
|
||||
if missing npx; then pkg_install nodejs npm npm npm; fi
|
||||
|
||||
echo "bootstrap complete"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
14
script/check
Executable file
14
script/check
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
# script/check: run all checks. Our own extension to
|
||||
# scripts-to-rule-them-all. Must not modify any files. Runs the
|
||||
# read-only formatting check first, then the clean production build.
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
|
||||
main() {
|
||||
"$SCRIPT_DIR/fmt-check"
|
||||
"$SCRIPT_DIR/test"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
14
script/cibuild
Executable file
14
script/cibuild
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
# script/cibuild: run the CI build. The Dockerfile runs `make check`,
|
||||
# so a successful build implies all checks pass. The Gitea workflow
|
||||
# runs this on push.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
docker build .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
14
script/docker
Executable file
14
script/docker
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
# script/docker: build the Docker image tagged with the project name.
|
||||
# The tag comes from script/projectname.
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
docker build -t "$("$SCRIPT_DIR/projectname")" .
|
||||
}
|
||||
|
||||
main "$@"
|
||||
18
script/fmt
Executable file
18
script/fmt
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/sh
|
||||
# script/fmt: format the repo's own top-level markdown docs (README.md,
|
||||
# TODO.md, ...) with prettier, using our standard settings. Scope is
|
||||
# deliberately limited to top-level docs: site content under content/
|
||||
# is left untouched so rendered output cannot change.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
PRETTIER_VERSION="3.4.2"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
npx --yes "prettier@${PRETTIER_VERSION}" --write \
|
||||
'*.md' --tab-width 4 --prose-wrap always
|
||||
}
|
||||
|
||||
main "$@"
|
||||
17
script/fmt-check
Executable file
17
script/fmt-check
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
# script/fmt-check: check the formatting of the repo's own top-level
|
||||
# markdown docs (read-only). Same scope as script/fmt, but fails
|
||||
# instead of writing.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
PRETTIER_VERSION="3.4.2"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
npx --yes "prettier@${PRETTIER_VERSION}" --check \
|
||||
'*.md' --tab-width 4 --prose-wrap always
|
||||
}
|
||||
|
||||
main "$@"
|
||||
15
script/install-precommit
Executable file
15
script/install-precommit
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
# script/install-precommit: install the git pre-commit hook that runs
|
||||
# script/precommit. Our own extension to scripts-to-rule-them-all.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
printf '#!/bin/sh\nset -e\nscript/precommit\n' > .git/hooks/pre-commit
|
||||
chmod +x .git/hooks/pre-commit
|
||||
echo "pre-commit hook installed: runs script/precommit"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
15
script/lint
Executable file
15
script/lint
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
# script/lint: this Hugo site has no dedicated linter, so the lint gate
|
||||
# is a clean build that surfaces broken internal links and template
|
||||
# path problems. It is a real check: `hugo` fails on build errors, and
|
||||
# --printPathWarnings reports render-target collisions.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
hugo --minify --printPathWarnings
|
||||
}
|
||||
|
||||
main "$@"
|
||||
12
script/precommit
Executable file
12
script/precommit
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
# script/precommit: run by the git pre-commit hook; fails the commit if
|
||||
# checks fail. Our own extension to scripts-to-rule-them-all.
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
|
||||
main() {
|
||||
"$SCRIPT_DIR/check"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
12
script/projectname
Executable file
12
script/projectname
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
# script/projectname: output the name of this project. Our own
|
||||
# extension to scripts-to-rule-them-all. Other scripts that need the
|
||||
# name (e.g. script/docker) call this, so they can stay identical
|
||||
# across all repos.
|
||||
set -eu
|
||||
|
||||
main() {
|
||||
echo "lora.vegas"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
13
script/setup
Executable file
13
script/setup
Executable file
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
# script/setup: set up the repo for development after a fresh clone:
|
||||
# installs dependencies (script/bootstrap) and the git pre-commit hook.
|
||||
set -eu
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)"
|
||||
|
||||
main() {
|
||||
"$SCRIPT_DIR/bootstrap"
|
||||
"$SCRIPT_DIR/install-precommit"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
14
script/test
Executable file
14
script/test
Executable file
@@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
# script/test: the correctness check for this static site is a clean
|
||||
# production build. `hugo --minify` exits non-zero on any template,
|
||||
# content, or config error, so a green build is a passing test.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
hugo --minify
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user