Put the copy-pasted workflows in the Makefile
fix, image, db, backup and clean were all sitting in README.md or docs/deployment.md as blocks to paste. The image target takes IMAGE from the caller so no registry of mine lands in the repository, and refuses an untagged HEAD — the version reaches the binary only through the build arg, so an untagged build makes /healthz claim something that was never released. run was broken: since seeding landed, starting the bare binary against an empty database fatals on the missing admin credentials. It now passes development defaults and binds loopback. The README's layout section still said the source was flat at the root.
This commit is contained in:
@@ -1,9 +1,13 @@
|
||||
# One command before committing: make
|
||||
# `make` is everything that has to pass before a commit. The rest are the workflows that were
|
||||
# otherwise copy-pasted out of README.md and docs/deployment.md.
|
||||
#
|
||||
# gofmt is first because a formatting failure is the cheapest to fix, and it is the only check that
|
||||
# needs a wrapper — gofmt reports offending files on stdout and still exits 0.
|
||||
.POSIX:
|
||||
.PHONY: check fmt vet test build run
|
||||
# gofmt needs a wrapper because it reports offending files on stdout and still exits 0.
|
||||
.PHONY: check fmt vet test fix build run image db backup clean
|
||||
|
||||
# Overridable, so a target never bakes in one person's environment.
|
||||
BIN ?= levyraati26-go
|
||||
ADDR ?= 127.0.0.1:8080
|
||||
STORAGE ?= ./storage
|
||||
|
||||
check: fmt vet test
|
||||
|
||||
@@ -16,11 +20,44 @@ vet:
|
||||
test:
|
||||
go test ./...
|
||||
|
||||
# Suggestions only. go fix rewrites files in place without -diff, and it is not always right —
|
||||
# read the hunks before applying any of them.
|
||||
fix:
|
||||
@go fix -diff ./... || true
|
||||
|
||||
# -o is required, not stylistic: the package lives in ./src, and without it `go build` would try to
|
||||
# write a binary named "src" over the directory.
|
||||
build:
|
||||
go build -o levyraati26-go ./src
|
||||
go build -o $(BIN) ./src
|
||||
|
||||
# Templates and migrations are embedded, so seeing a change means rebuilding.
|
||||
# Templates, static files and migrations are embedded, so seeing a change means rebuilding.
|
||||
# The admin credentials seed the first account on an empty database and are ignored after that.
|
||||
run: build
|
||||
./levyraati26-go
|
||||
ADMIN_EMAIL=$${ADMIN_EMAIL:[email protected]} \
|
||||
ADMIN_PASSWORD=$${ADMIN_PASSWORD:-dev} \
|
||||
SECURE_COOKIES=false STORAGE_DIR=$(STORAGE) ADDR=$(ADDR) ./$(BIN)
|
||||
|
||||
# A release image. VERSION comes from the tag, because that is the only way it reaches the binary
|
||||
# and /healthz must not claim a version that was never tagged. IMAGE names the registry and stays
|
||||
# out of this file: pass it in, or put it in the .env this reads nothing from.
|
||||
#
|
||||
# make image IMAGE=registry.example.com/owner/levyraati26-go
|
||||
image:
|
||||
@test -n "$(IMAGE)" || { echo "set IMAGE, e.g. make image IMAGE=registry.example.com/owner/levyraati26-go"; exit 1; }
|
||||
@v=$$(git describe --tags --exact-match 2>/dev/null) || { echo "HEAD is not tagged; tag the release first"; exit 1; }; \
|
||||
podman build --build-arg VERSION=$$v -t $(IMAGE):$$v -t $(IMAGE):latest . && \
|
||||
echo "built $(IMAGE):$$v — push with: podman push $(IMAGE):$$v"
|
||||
|
||||
# Operations against the running container, straight out of docs/deployment.md.
|
||||
db:
|
||||
docker compose exec app sqlite3 /storage/levyraati.db
|
||||
|
||||
# Copying the file while the app runs is not a backup: WAL keeps recent writes in a sidecar.
|
||||
backup:
|
||||
docker compose exec app sqlite3 /storage/levyraati.db ".backup '/storage/tmp/backup.db'"
|
||||
gzip -c $(STORAGE)/tmp/backup.db > backup-$$(date +%F).db.gz
|
||||
rm $(STORAGE)/tmp/backup.db
|
||||
@echo "wrote backup-$$(date +%F).db.gz"
|
||||
|
||||
clean:
|
||||
rm -f $(BIN)
|
||||
|
||||
@@ -162,11 +162,23 @@ docker compose exec app sqlite3 /storage/levyraati.db
|
||||
|
||||
## Layout
|
||||
|
||||
Go source is flat at the repository root, one package. Beyond that: `templates/` and `static/` are
|
||||
embedded assets, `migrations/` holds numbered `.sql` files applied in order at startup, and
|
||||
`testdata/` holds the golden JSON files that guard the API contract, plus `ytdlp-noose.json` — a real
|
||||
`yt-dlp -J` dump of an ordinary upload, used to test metadata prefill against a video that has no
|
||||
`track`, `artist` or `album` at all.
|
||||
`src/` is the whole program: one flat `package main`, with the assets it embeds beside it, because
|
||||
`//go:embed` cannot reach outside its own directory. `templates/` and `static/` are those assets,
|
||||
`migrations/` holds numbered `.sql` files applied in order at startup, and `testdata/` holds the
|
||||
golden JSON files that guard the API contract, plus `ytdlp-noose.json` — a real `yt-dlp -J` dump of
|
||||
an ordinary upload, used to test metadata prefill against a video that has no `track`, `artist` or
|
||||
`album` at all.
|
||||
|
||||
The root keeps what is not source: `docs/`, the container and compose files, the `Makefile`, and
|
||||
`storage/` once the app has run.
|
||||
|
||||
| Command | Does |
|
||||
|---|---|
|
||||
| `make` | gofmt, `go vet`, `go test` — everything that must pass before a commit |
|
||||
| `make run` | Build and start on `127.0.0.1:8080` with development defaults |
|
||||
| `make fix` | Show `go fix` modernizer suggestions as a diff, without applying them |
|
||||
| `make image IMAGE=…` | Build a release image tagged from `git describe`; refuses an untagged HEAD |
|
||||
| `make db` / `make backup` | SQLite shell, and a WAL-safe snapshot, against the running container |
|
||||
|
||||
## Notes
|
||||
|
||||
|
||||
Reference in New Issue
Block a user