A submission failed with HTTP 403 against a freshly published image. The cause was not Alpine, which carries the current yt-dlp: it was the apk layer being reused from an older build, so the image shipped a yt-dlp two months behind while /healthz reported today's tag. "A rebuild is the update" only holds if the layer is genuinely re-run, so the image target now passes --pull --no-cache. Slower, and the only thing that makes the release honest about what is inside it.
68 lines
2.8 KiB
Makefile
68 lines
2.8 KiB
Makefile
# `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 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
|
|
|
|
fmt:
|
|
@out=$$(gofmt -l .); test -z "$$out" || { echo "not gofmt'd:"; echo "$$out"; exit 1; }
|
|
|
|
vet:
|
|
go 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 $(BIN) ./src
|
|
|
|
# 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
|
|
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
|
|
#
|
|
# --pull --no-cache is the point of the target, not caution. yt-dlp rots against YouTube within
|
|
# weeks, and "a rebuild is the update" is only true if the apk layer is actually re-run — a cached
|
|
# one silently ships whatever yt-dlp was current the day that layer was first built.
|
|
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 --pull --no-cache --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)
|