diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 456b816e..2d051a2c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -21,6 +21,8 @@ jobs: uses: actions/setup-go@v5 with: go-version-file: go.mod + cache: true + cache-dependency-path: go.sum - name: Run GoReleaser uses: goreleaser/goreleaser-action@v6 diff --git a/Makefile b/Makefile index 18da511f..43969f04 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: help fmt test install tag release check-clean check-version install-hooks +.PHONY: help fmt test test-race install install-dev build build-dev build-release tag release check-clean check-version install-hooks clean SHELL := /bin/sh @@ -9,27 +9,72 @@ VERSION ?= # A helpful dev version string (used by install-dev) GIT_DESCRIBE := $(shell git describe --tags --always --dirty 2>/dev/null) +# Parallelism for test runs. Defaults to the number of CPUs available. +JOBS ?= $(shell sysctl -n hw.ncpu 2>/dev/null || nproc 2>/dev/null || echo 4) + +# Release link flags strip debug info and symbol tables for smaller, faster-linking binaries. +RELEASE_LDFLAGS := -s -w -X main.Version=$(GIT_DESCRIBE) +DEV_LDFLAGS := -X main.Version=$(GIT_DESCRIBE) + +# -trimpath removes filesystem path prefixes from the binary, making builds reproducible +# and avoiding embedding personal paths. +RELEASE_BUILD_FLAGS := -trimpath -ldflags "$(RELEASE_LDFLAGS)" +DEV_BUILD_FLAGS := -ldflags "$(DEV_LDFLAGS)" + help: @printf "%s\n" \ "Targets:" \ " make fmt # gofmt -w ." \ " make install-hooks # install git pre-commit hook" \ - " make test # go test ./..." \ - " make install # build and install with version from git" \ + " make test # go test ./... (parallel)" \ + " make test-race # go test -race ./..." \ + " make build # release build (-trimpath, stripped)" \ + " make build-dev # dev build (uses Go build cache)" \ + " make install # install release-flavored binary" \ + " make install-dev # install dev-flavored binary" \ + " make clean # remove build artefacts" \ " make tag VERSION=vX.Y.Z # create annotated git tag (requires clean tree)" \ " make release VERSION=vX.Y.Z # tag + push (triggers GoReleaser via GitHub Actions)" fmt: gofmt -w . +# Test target relies on Go's built-in build/test cache for speed. +# -p sets the package compile parallelism, -parallel controls in-package t.Parallel(). test: - go test ./... + go test -p $(JOBS) -parallel $(JOBS) ./... + +test-race: + go test -race -p $(JOBS) -parallel $(JOBS) ./... + +# Release build: stripped, trimpath'd, smaller binary that links faster. +build: build-release + +build-release: + @V="$(GIT_DESCRIBE)"; V=$${V:-dev}; \ + echo "Building td $$V (release)"; \ + go build -trimpath -ldflags "-s -w -X main.Version=$$V" -o td . + +# Dev build: keep symbol table for debuggers, otherwise rely on Go's incremental cache. +build-dev: + @V="$(GIT_DESCRIBE)"; V=$${V:-dev}; \ + echo "Building td $$V (dev)"; \ + go build -ldflags "-X main.Version=$$V" -o td . install: @V="$(GIT_DESCRIBE)"; V=$${V:-dev}; \ - echo "Installing td $$V"; \ + echo "Installing td $$V (release)"; \ + go install -trimpath -ldflags "-s -w -X main.Version=$$V" . + +install-dev: + @V="$(GIT_DESCRIBE)"; V=$${V:-dev}; \ + echo "Installing td $$V (dev)"; \ go install -ldflags "-X main.Version=$$V" . +clean: + rm -f td + go clean + check-clean: @git diff --quiet && git diff --cached --quiet || (echo "Error: working tree is not clean" && exit 1)