Shim make dev and make build, format backend/ markdown (closes #28)
check / check (push) Successful in 3m13s
check / check (push) Successful in 3m13s
make dev ran yarn dev inline and there was no make build. Both are now shims, over script/dev and the new script/build. .prettierignore stops leaving out backend/, so backend/README.md is formatted and checked; backend/.golangci.yml is left out by name instead: it is the org standard file whose sha256 backend/script/lint checks, and prettier would reindent it. .claude/ stays in .prettierignore, as git does not ignore it. script/install-precommit and the date on bootstrap's pins go back to the org model; bootstrap, fmt and fmt-check keep what the Go backend and eslint need, each with a comment saying so. Model: opus-5-5
This commit is contained in:
+2
-1
@@ -1,6 +1,7 @@
|
||||
backend/
|
||||
dist/
|
||||
node_modules/
|
||||
tmp/
|
||||
yarn.lock
|
||||
.claude/
|
||||
# The org standard file, copied verbatim; backend/script/lint checks its sha256.
|
||||
backend/.golangci.yml
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.PHONY: bootstrap setup dev test lint fmt fmt-check check frontend-check \
|
||||
frontend-viewport-test docker hooks
|
||||
.PHONY: bootstrap setup dev build test lint fmt fmt-check check \
|
||||
frontend-check frontend-viewport-test docker hooks
|
||||
|
||||
# Standard targets are thin shims; the implementations live in script/
|
||||
# per the scripts-to-rule-them-all pattern (see the Entrypoints section
|
||||
@@ -13,7 +13,11 @@ setup:
|
||||
@script/setup
|
||||
|
||||
dev:
|
||||
yarn dev
|
||||
@script/dev
|
||||
|
||||
# The frontend only; backend/Makefile's build target builds the Go server.
|
||||
build:
|
||||
@script/build
|
||||
|
||||
test:
|
||||
@script/test
|
||||
|
||||
@@ -46,6 +46,10 @@ halves, so the root `make check` fails if either one is broken. We provide:
|
||||
both linters in Docker
|
||||
- `script/setup` — make a fresh clone ready for development: bootstrap plus the
|
||||
git pre-commit hook
|
||||
- `script/dev` — run the Vite dev server, which proxies `/api` to a locally
|
||||
running `netwatch-server`
|
||||
- `script/build` — build the frontend for production into `dist/`;
|
||||
`backend/script/build` builds the Go server
|
||||
- `script/projectname` — print the project name (used for the Docker image tag)
|
||||
- `script/test` — run `script/frontend-test`, then `backend/script/test`, the
|
||||
backend's Go tests with the race detector and coverage
|
||||
@@ -61,7 +65,8 @@ halves, so the root `make check` fails if either one is broken. We provide:
|
||||
- `script/frontend-lint` — run eslint with the rules in `eslint.config.js`; it
|
||||
runs inside the `frontend-lint` stage of `Dockerfile`, which `make lint`
|
||||
builds
|
||||
- `script/frontend-fmt` — format everything prettier understands (writes)
|
||||
- `script/frontend-fmt` — format everything prettier understands (writes), the
|
||||
markdown in `backend/` included
|
||||
- `script/frontend-fmt-check` — check prettier formatting (read-only)
|
||||
- `script/frontend-check` — run `script/frontend-test` and
|
||||
`script/frontend-fmt-check`, for the frontend stage of `Dockerfile`, which has
|
||||
|
||||
@@ -23,6 +23,16 @@ latest run passes.
|
||||
|
||||
# Completed Steps
|
||||
|
||||
- 2026-10-04: `script/` and `Makefile` follow the org models (issue #28):
|
||||
`make dev` shims to the new `script/dev`, the Vite dev server, and the new
|
||||
`make build` to `script/build`, the frontend production build.
|
||||
`.prettierignore` no longer leaves out `backend/`, so `make fmt` and
|
||||
`make fmt-check` cover `backend/README.md`; it leaves out
|
||||
`backend/.golangci.yml` by name, the org standard file whose sha256
|
||||
`backend/script/lint` checks. `script/install-precommit` and the date on
|
||||
`script/bootstrap`'s pins are the org model again; `script/bootstrap`,
|
||||
`script/fmt` and `script/fmt-check` each say in a comment why they differ from
|
||||
it
|
||||
- 2026-10-04: a frontend build on Node 26 or newer, such as `make test` on a
|
||||
host with Node 26, no longer prints Node's warning that `module.register()` is
|
||||
deprecated (issue #32); the build in `Dockerfile` runs on Node 22, which never
|
||||
|
||||
+18
-18
@@ -32,17 +32,16 @@ pattern as the repo root: the targets in `backend/Makefile` are thin shims over
|
||||
`test`, `fmt` and `fmt-check`:
|
||||
|
||||
- `script/build` — compile the static `netwatch-server` binary with its version
|
||||
stamped in. The version is `VERSION` from the environment;
|
||||
when that is unset or empty, it falls back to `git describe` inside a git
|
||||
checkout, then to `dev`
|
||||
stamped in. The version is `VERSION` from the environment; when that is unset
|
||||
or empty, it falls back to `git describe` inside a git checkout, then to `dev`
|
||||
- `script/test` — run the Go tests with the race detector and coverage. Go's
|
||||
`-timeout 30s` bounds the tests, not their compile. If they fail, they run
|
||||
again with `-v` for the details, and the script fails. The race detector needs
|
||||
a C compiler
|
||||
- `script/lint` — check `.golangci.yml` against its pinned sha256, then run
|
||||
golangci-lint. It runs inside the golangci-lint image of the lint stage of
|
||||
the root `Dockerfile`; from a checkout, run `make lint` at the repo root,
|
||||
which builds that stage
|
||||
golangci-lint. It runs inside the golangci-lint image of the lint stage of the
|
||||
root `Dockerfile`; from a checkout, run `make lint` at the repo root, which
|
||||
builds that stage
|
||||
- `script/fmt` — format the Go sources (writes)
|
||||
- `script/fmt-check` — check Go formatting (read-only)
|
||||
- `script/run` — build and run the server locally
|
||||
@@ -61,8 +60,9 @@ flushes them to compressed files on disk for later analysis.
|
||||
|
||||
## Design
|
||||
|
||||
The server is structured as an `fx`-wired Go application under `cmd/netwatch-server/`.
|
||||
Internal packages in `internal/` follow standard Go project layout:
|
||||
The server is structured as an `fx`-wired Go application under
|
||||
`cmd/netwatch-server/`. Internal packages in `internal/` follow standard Go
|
||||
project layout:
|
||||
|
||||
- **`config`**: Loads configuration from environment variables and config files
|
||||
via Viper.
|
||||
@@ -89,11 +89,12 @@ Internal packages in `internal/` follow standard Go project layout:
|
||||
| `REPORTS_PER_MINUTE` | `60` | Reports each client address may send a minute; see [Report limits](#report-limits) |
|
||||
| `CORS_ALLOWED_ORIGINS` | empty | Comma-separated origins whose pages may call the API; see [CORS](#cors) |
|
||||
|
||||
`TRUSTED_PROXIES` defaults to `127.0.0.1/32,::1/128,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16`.
|
||||
The loopback entries cover a reverse proxy on the same host. A request whose
|
||||
direct peer is outside this set has its forwarded headers ignored, and the
|
||||
direct peer is logged and rate-limited instead. The container image does not use
|
||||
this default; see [Container image](#container-image).
|
||||
`TRUSTED_PROXIES` defaults to
|
||||
`127.0.0.1/32,::1/128,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16`. The loopback
|
||||
entries cover a reverse proxy on the same host. A request whose direct peer is
|
||||
outside this set has its forwarded headers ignored, and the direct peer is
|
||||
logged and rate-limited instead. The container image does not use this default;
|
||||
see [Container image](#container-image).
|
||||
|
||||
A variable set to a value the server cannot use, such as `PORT=abc`,
|
||||
`DEBUG=maybe` or a `BIND_ADDRESS` that is not an IP address, stops it from
|
||||
@@ -109,9 +110,9 @@ only nginx reaches it, and with `TRUSTED_PROXIES=127.0.0.1/32`, so it takes the
|
||||
client address nginx passes on and no other. `DATA_DIR` is `/data/reports`, on
|
||||
the `/data` volume; before starting the server, the entrypoint creates it and
|
||||
gives it and `/data` to `netwatch` with `netwatch-server prepare-data-dir`,
|
||||
which acts on nothing outside `/data`. nginx replaces the security headers
|
||||
this server sets with those in the root `security-headers.conf`, so those are
|
||||
what clients of the image see.
|
||||
which acts on nothing outside `/data`. nginx replaces the security headers this
|
||||
server sets with those in the root `security-headers.conf`, so those are what
|
||||
clients of the image see.
|
||||
|
||||
The container's own `TRUSTED_PROXIES` goes to nginx instead: IP addresses or
|
||||
CIDRs, separated by commas, of the reverse proxies in front of the container.
|
||||
@@ -162,8 +163,7 @@ credentials, so it is bounded instead. Both refusals below answer with the same
|
||||
to be written fill the cap on their own, and then no file is deleted. At
|
||||
start, report files past the cap, as after lowering it, are deleted the same
|
||||
way. So the cap is how much of the newest reports is kept: the default of 1
|
||||
GiB is small enough for any host; set it to the space you can give
|
||||
`DATA_DIR`.
|
||||
GiB is small enough for any host; set it to the space you can give `DATA_DIR`.
|
||||
|
||||
### CORS
|
||||
|
||||
|
||||
+3
-1
@@ -17,11 +17,13 @@
|
||||
#
|
||||
# golangci-lint is not installed: make lint runs it in Docker, which
|
||||
# this script does not install either.
|
||||
#
|
||||
# Unlike the org model: Go and gcc for backend/, a newer node for eslint.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
# Pinned versions, 2026-07-07
|
||||
# Pinned versions, 2026-07-06
|
||||
NODE_VERSION="22.17.0"
|
||||
# The oldest node the frontend's dependencies accept: the "engines"
|
||||
# field of eslint 10.12.0, the most demanding of them, asks for 22.13.0
|
||||
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
# script/build: build the frontend for production into dist/. The Go
|
||||
# backend is built by backend/script/build.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
yarn build
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Executable
+13
@@ -0,0 +1,13 @@
|
||||
#!/bin/sh
|
||||
# script/dev: run the frontend's Vite dev server. It proxies /api to a
|
||||
# netwatch-server running locally (see vite.config.js).
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
yarn dev
|
||||
}
|
||||
|
||||
main "$@"
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/bin/sh
|
||||
# script/fmt: format the whole repo (writes): prettier over everything
|
||||
# it understands, then gofmt over the Go backend.
|
||||
# The org model formats only markdown; this repo also has JS and Go.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/bin/sh
|
||||
# script/fmt-check: check formatting across the whole repo (read-only).
|
||||
# Same scope as script/fmt, but fails instead of writing.
|
||||
# The org model checks only markdown; this repo also has JS and Go.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
#!/bin/sh
|
||||
# script/frontend-fmt: format the frontend and every other file prettier
|
||||
# understands, repo-wide (writes). backend/ is in .prettierignore; Go
|
||||
# sources are formatted by backend/script/fmt.
|
||||
# understands, repo-wide (writes), the markdown in backend/ included.
|
||||
# Prettier does not read Go; backend/script/fmt formats the Go sources.
|
||||
set -eu
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
|
||||
@@ -8,8 +8,8 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
|
||||
main() {
|
||||
cd "$ROOT"
|
||||
hook=".git/hooks/pre-commit"
|
||||
printf '#!/bin/sh\nset -e\nscript/precommit\n' > "$hook"
|
||||
chmod +x "$hook"
|
||||
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"
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user