Files
anchorage/Makefile
William Gill 12bf35caf8 anchorage v1.0 initial tree
Greenfield Go multi-tenant IPFS Pinning Service wire-compatible with the
IPFS Pinning Services API spec. Paired 1:1 with Kubo over localhost RPC,
clustered via embedded NATS JetStream, Postgres source-of-truth with
RLS-enforced tenancy, Fiber + huma v2 for the HTTP surface, Authentik
OIDC for session login with kid-rotated HS256 JWT API tokens.

Feature-complete against the 22-milestone build plan, including the
ship-it v1.0 gap items:

  * admin CLIs: drain/uncordon, maintenance, mint-token, rotate-key,
    prune-denylist, rebalance --dry-run, cache-stats, cluster-presences
  * TTL leader election via NATS KV, fence tokens, JetStream dedup
  * rebalancer (plan/apply split), reconciler, requeue sweeper
  * ristretto caches with NATS-backed cross-node invalidation
    (placements live-nodes + token denylist)
  * maintenance watchdog for stuck cluster-pause flag
  * Prometheus /metrics with CIDR ACL, HTTP/pin/scheduler/cache gauges
  * rate limiting: session (10/min) + anonymous global (120/min)
  * integration tests: rebalance, refcount multi-org, RLS belt
  * goreleaser (tar + deb/rpm/apk + Alpine Docker) targeting Gitea

Stack: Cobra/Viper, Fiber v2 + huma v2, embedded NATS JetStream,
pgx/sqlc/golang-migrate, ristretto, TypeID, prometheus/client_golang,
testcontainers-go.
2026-04-16 18:13:36 -05:00

103 lines
3.2 KiB
Makefile

# anchorage — developer-facing Makefile.
#
# Targets follow the Go standards doc: fmt + vet + lint + test must be
# clean on every PR. `make check` is the local equivalent of CI.
SHELL := /usr/bin/env bash
PKG := anchorage
BIN := anchorage
BIN_DIR := bin
CMD_DIR := ./cmd/anchorage
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo dev)
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo unknown)
DATE ?= $(shell date -u +%Y-%m-%dT%H:%M:%SZ)
LDFLAGS := -s -w \
-X $(PKG)/internal/cmd.version=$(VERSION) \
-X $(PKG)/internal/cmd.commit=$(COMMIT) \
-X $(PKG)/internal/cmd.date=$(DATE)
GO ?= go
GOFMT ?= gofmt
GOIMPORTS ?= goimports
STATICCHK ?= staticcheck
GOVULNCHK ?= govulncheck
GORELEASER ?= goreleaser
.PHONY: help
help: ## Show this help
@awk 'BEGIN{FS=":.*##"} /^[a-zA-Z_-]+:.*##/ {printf " \033[36m%-14s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
.PHONY: build
build: ## Compile the anchorage binary into ./bin
@mkdir -p $(BIN_DIR)
$(GO) build -trimpath -ldflags "$(LDFLAGS)" -o $(BIN_DIR)/$(BIN) $(CMD_DIR)
.PHONY: run
run: ## Run `anchorage version` against the local source tree
$(GO) run $(CMD_DIR) version
.PHONY: fmt
fmt: ## gofmt + goimports across the module
$(GOFMT) -w -s .
@command -v $(GOIMPORTS) >/dev/null && $(GOIMPORTS) -w -local $(PKG) . || echo "goimports not installed; skipping"
.PHONY: vet
vet: ## go vet ./...
$(GO) vet ./...
.PHONY: lint
lint: ## staticcheck ./...
@command -v $(STATICCHK) >/dev/null && $(STATICCHK) ./... || echo "staticcheck not installed; skipping"
.PHONY: test
test: ## go test -race -count=1 ./...
$(GO) test -race -count=1 ./...
.PHONY: vuln
vuln: ## govulncheck ./...
@command -v $(GOVULNCHK) >/dev/null && $(GOVULNCHK) ./... || echo "govulncheck not installed; skipping"
.PHONY: tidy
tidy: ## go mod tidy
$(GO) mod tidy
.PHONY: check
check: fmt vet lint test vuln ## Full pre-PR verification
.PHONY: clean
clean: ## Remove build artifacts
rm -rf $(BIN_DIR) coverage.* dist/
# ---------------------------------------------------------------------------
# Release pipeline — GoReleaser
# ---------------------------------------------------------------------------
.PHONY: snapshot
snapshot: ## Build a local snapshot (tar + deb + rpm + docker) into ./dist
$(GORELEASER) release --snapshot --clean
.PHONY: release-check
release-check: ## Dry-run the release config without building
$(GORELEASER) check
.PHONY: release
release: ## Tagged release (requires GITEA_TOKEN in env; pushes to Gitea + package repo)
$(GORELEASER) release --clean
.PHONY: docker-local
docker-local: build ## Build the container image from the current tree (no GoReleaser)
docker build -f build/package/Dockerfile -t anchorage:dev $(BIN_DIR)
# ---------------------------------------------------------------------------
# Swarm stack helpers
# ---------------------------------------------------------------------------
.PHONY: stack-deploy
stack-deploy: ## Deploy the production Swarm stack (requires docker swarm init + secrets)
docker stack deploy -c deploy/docker-compose.yml anchorage
.PHONY: stack-rm
stack-rm: ## Remove the deployed Swarm stack (volumes retained)
docker stack rm anchorage