Files
Esa Kataja 522827879b Build release images without the layer cache
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.
2026-09-05 15:02:35 +03:00

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)