Adopt the scripts-to-rule-them-all layout and the canonical Docker gates
check / check (push) Successful in 1m3s
check / check (push) Successful in 1m3s
script/ holds the entrypoints and the Makefile targets shim to them. Linting and testing are phases of the Dockerfile, built alone by script/lint and script/test with a fresh CACHEBUST value and cache mounts for Go's build cache and golangci-lint's; the build stage depends on both, and the runtime stage ships the binary and the source without .git. Formatting stays on the host in script/fmt and script/fmt-check (gofmt and the prettier pinned in yarn.lock). script/cibuild bootstraps, runs script/check and builds the tagged image, and the Gitea workflow calls it. script/precommit refuses a commit whose go.mod or go.sum is not tidy. cgo stays off, so the test phase runs on the alpine Go image without -race; that is the one departure from the canonical Go Dockerfile. Re-vendored from the prompts repository's next branch: REPO_POLICIES.md (2026-11-04), .golangci.yml (byte-identical, so the local exhaustruct_v5 addition is gone now that canonical carries it), .gitea/workflows/check.yml, .editorconfig, .gitignore and .dockerignore, the last two followed by this repository's own entries. AGENTS.md holds the repository-specific guidance for agents. The README gains the Entrypoints section and describes the new gates.
This commit is contained in:
@@ -1,30 +1,45 @@
|
||||
# sneak.berlin/go/x
|
||||
#
|
||||
# This Makefile is the single source of truth for how this repo is built,
|
||||
# tested, linted, and formatted. Always use these targets rather than
|
||||
# invoking the underlying tools directly.
|
||||
.PHONY: bootstrap setup test lint fmt fmt-check check docker hooks \
|
||||
build install tidy clean
|
||||
|
||||
.PHONY: all build install test lint fmt fmt-go fmt-md fmt-check \
|
||||
fmt-check-go fmt-check-md check docker hooks tidy setup clean
|
||||
# Makefile targets are thin shims; the implementations live in script/
|
||||
# per the scripts-to-rule-them-all pattern (see the Entrypoints section
|
||||
# of README.md). The targets after the shims are this repo's own.
|
||||
|
||||
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
|
||||
|
||||
# This repository's own targets.
|
||||
|
||||
BINARY := sutil
|
||||
VERSION := $(shell git describe --always --dirty 2>/dev/null || echo dev)
|
||||
VERSION := $(shell git describe --tags --always --dirty 2>/dev/null || echo unknown)
|
||||
GOLDFLAGS := -X main.Version=$(VERSION)
|
||||
GO_DIRS := cmd internal pkg
|
||||
|
||||
# golangci/golangci-lint:v2.15.0, 2026-10-16 (keep in sync with Dockerfile)
|
||||
GOLANGCI_LINT_IMAGE := golangci/golangci-lint@sha256:fbfcfd12a6f8d7f1b97b3362ca80fc2a244d46863148c73cb88e7793af96c481
|
||||
|
||||
# flags are repeated here (also in .prettierrc) so this Makefile works
|
||||
# standalone when copied as a template
|
||||
PRETTIER := yarn run --silent prettier
|
||||
PRETTIER_FLAGS := --tab-width 4 --prose-wrap always
|
||||
MARKDOWN_GLOB := '**/*.md'
|
||||
|
||||
all: build
|
||||
|
||||
# cgo stays off everywhere: builds are static and the tests do not use
|
||||
# -race, which would require a C toolchain.
|
||||
# cgo stays off everywhere: builds are static, and the test phase of the
|
||||
# Dockerfile runs without -race, which would need a C toolchain.
|
||||
export CGO_ENABLED := 0
|
||||
|
||||
# Build the sutil binary in the repo root with the git version embedded.
|
||||
@@ -35,81 +50,9 @@ build:
|
||||
install:
|
||||
go install -trimpath -ldflags "$(GOLDFLAGS)" ./cmd/$(BINARY)
|
||||
|
||||
# Run the tests quietly; on failure rerun verbosely for diagnostics and
|
||||
# still fail.
|
||||
test:
|
||||
@go test -timeout 30s -cover ./... || \
|
||||
{ echo "--- Rerunning with -v for details ---"; \
|
||||
go test -timeout 30s -v ./...; exit 1; }
|
||||
|
||||
# Lint with the pinned golangci-lint image when docker is available so local
|
||||
# results match CI exactly. Inside the Docker build (where there is no
|
||||
# docker) the image's own golangci-lint binary is used. The host module
|
||||
# cache is shared read-only; the linter and build caches live in named
|
||||
# volumes so repeated runs are fast.
|
||||
#
|
||||
# .golangci.yml is verified against the linter's schema first: golangci-lint
|
||||
# otherwise ignores keys it does not know and silently runs with defaults.
|
||||
LINT_COMMAND := golangci-lint config verify && golangci-lint run ./...
|
||||
|
||||
lint:
|
||||
@if command -v docker >/dev/null 2>&1; then \
|
||||
docker run --rm \
|
||||
-v "$(CURDIR)":/src \
|
||||
-v "$$(go env GOMODCACHE)":/go/pkg/mod:ro \
|
||||
-v sutil-golangci-lint-cache:/root/.cache/golangci-lint \
|
||||
-v sutil-go-build-cache:/root/.cache/go-build \
|
||||
-w /src $(GOLANGCI_LINT_IMAGE) sh -c '$(LINT_COMMAND)'; \
|
||||
else \
|
||||
$(LINT_COMMAND); \
|
||||
fi
|
||||
|
||||
# Format everything (writes files).
|
||||
fmt: fmt-go fmt-md
|
||||
|
||||
fmt-go:
|
||||
gofmt -w $(GO_DIRS)
|
||||
|
||||
fmt-md:
|
||||
$(PRETTIER) --write $(MARKDOWN_GLOB) $(PRETTIER_FLAGS)
|
||||
|
||||
# Check formatting without writing anything.
|
||||
fmt-check: fmt-check-go fmt-check-md
|
||||
|
||||
fmt-check-go:
|
||||
@unformatted="$$(gofmt -l $(GO_DIRS))"; \
|
||||
if [ -n "$$unformatted" ]; then \
|
||||
echo "gofmt: the following files need formatting:"; \
|
||||
echo "$$unformatted"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
fmt-check-md:
|
||||
$(PRETTIER) --check $(MARKDOWN_GLOB) $(PRETTIER_FLAGS)
|
||||
|
||||
# Everything CI gates on. Must not modify any files.
|
||||
check: test lint fmt-check
|
||||
|
||||
# Build the Docker image; the Dockerfile runs the same checks as `make check`.
|
||||
docker:
|
||||
docker build -t $(BINARY) .
|
||||
|
||||
# Install the pre-commit hook.
|
||||
hooks:
|
||||
@printf '#!/bin/sh\nset -e\n' > .git/hooks/pre-commit
|
||||
@if [ -f go.mod ]; then \
|
||||
printf 'go mod tidy\ngo fmt ./...\ngit diff --exit-code -- go.mod go.sum || { echo "go mod tidy changed files; please stage and retry"; exit 1; }\n' >> .git/hooks/pre-commit; \
|
||||
fi
|
||||
@printf 'make check\n' >> .git/hooks/pre-commit
|
||||
@chmod +x .git/hooks/pre-commit
|
||||
|
||||
# Tidy go.mod and go.sum.
|
||||
# Tidy go.mod and go.sum; script/precommit refuses a commit that needs it.
|
||||
tidy:
|
||||
go mod tidy
|
||||
|
||||
# One-time developer setup: install the pinned prettier for markdown checks.
|
||||
setup:
|
||||
yarn install --frozen-lockfile
|
||||
|
||||
clean:
|
||||
rm -f $(BINARY)
|
||||
|
||||
Reference in New Issue
Block a user