diff --git a/CLAUDE.md b/CLAUDE.md index 5fbf13e..0017382 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -7,9 +7,13 @@ Keep it concise — the agent needs signal, not essays. ## Project overview -Go 1.25 template / PoC starter. Demonstrates: structured logging (slog), -config (flag), consumer-defined interfaces + manual fakes, result type (happy-path error handling), -linting (golangci-lint), security scanning (gosec, govulncheck), git hooks, devcontainer, VSCode tasks. +Go 1.25 template for PoC, hobby projects, and small publishable packages. +Demonstrates: structured logging (slog), config (flag), consumer-defined interfaces + manual fakes, +result type (happy-path error handling), linting (golangci-lint), security scanning (gosec, govulncheck), +git hooks, devcontainer, VSCode tasks. + +Key constraint: `go.mod` stays free of dev tool deps (tools are pinned in `tools.versions` and run via +`go run tool@version`) so packages published from this repo have a clean module graph for consumers. Module: `gitea.djmil.dev/djmil/go-template` — update this when you fork. @@ -22,6 +26,7 @@ cmd/app/main.go composition root — wires deps, no logic here internal/config/ flag-based config loader (config.Load) internal/logger/ slog wrapper with WithField / WithFields internal/greeter/ Example domain package (delete or repurpose) +pkg/result/ Example publishable package (Result/Expect types) tools.versions Pinned tool versions (sourced by Makefile and pre-push hook) .golangci.yml Linter rules .githooks/pre-push Runs gofmt + go vet + golangci-lint + gosec before push @@ -76,6 +81,7 @@ make test-race # tests + race detector make lint # go vet + golangci-lint make lint-fix # go fix + golangci-lint auto-fix make security # gosec + govulncheck +make release # list releases, or tag+push after full checks (make release VERSION=v0.1.0) make clean # remove bin/ ``` @@ -113,3 +119,4 @@ Debug: use launch config "Debug: app" (F5). - 2026-03-29 — Pre-commit hook moved to pre-push; go vet + go fix added to lint pipeline. - 2026-03-29 — Fixed stale docs and .golangci.yml local-prefixes; .vscode launch configs use CLI flags. - 2026-04-01 — Replaced tools.go/go.mod pinning with tools.versions + go run tool@version; go.mod is now free of dev tool deps. +- 2026-04-01 — Added make release: lists tags with no args; validates semver, runs test-race+lint+security, then tags+pushes. diff --git a/Makefile b/Makefile index 517b8aa..d1255f8 100644 --- a/Makefile +++ b/Makefile @@ -64,6 +64,25 @@ security: ## Run gosec + govulncheck @echo "--- govulncheck ---" go run golang.org/x/vuln/cmd/govulncheck@$(GOVULNCHECK_VERSION) ./... +# ── Release ──────────────────────────────────────────────────────────────────── +release: ## List releases, or tag+push a new one (usage: make release VERSION=v0.1.0) +ifdef VERSION + @echo "$(VERSION)" | grep -Eq '^v[0-9]+\.[0-9]+\.[0-9]+$$' || \ + (echo "VERSION must be semver: v0.1.0"; exit 1) + @git diff --quiet && git diff --cached --quiet || \ + (echo "Uncommitted changes — commit first"; exit 1) + @git tag -l | grep -q "^$(VERSION)$$" && \ + (echo "Tag $(VERSION) already exists"; exit 1) || true + $(MAKE) test-race + $(MAKE) lint + $(MAKE) security + git tag $(VERSION) + git push origin $(VERSION) +else + @echo "Released versions:" + @git tag -l --sort=-version:refname | grep -E '^v[0-9]' || echo " (none yet)" +endif + # ── Cleanup ──────────────────────────────────────────────────────────────────── clean: ## Remove build artifacts rm -rf ./bin diff --git a/README.md b/README.md index 369e276..00919a9 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,12 @@ # go-template -A batteries-included Go project template optimised for **PoC and hobby projects**. +A Go project template for **PoC, hobby projects, and small publishable packages**. Clone it, rename the module, run `make init`, and you're coding. +Demonstrates idiomatic Go patterns: stdlib-only dependencies, consumer-defined interfaces, +manual fakes for testing, and a clean `go.mod` that stays free of dev tool noise — +so packages extracted from this template can be published without module graph pollution. + --- ## Features @@ -44,7 +48,8 @@ cd my-project ### 2. Init (run once) ```bash -make init # fetches deps, installs tools, configures git hooks +make init # fetches deps, configures git hooks +make tools # (optional) install tool binaries to GOPATH/bin for IDE integration ``` ### 3. Build and run @@ -64,6 +69,7 @@ make test-race # … with race detector make lint # go vet + golangci-lint make lint-fix # go fix + golangci-lint auto-fix make security # gosec + govulncheck +make release # list tags, or run full checks then tag+push (make release VERSION=v0.1.0) ``` > **Keyboard shortcut (VSCode):** `Ctrl+Shift+B` → build, `Ctrl+Shift+T` → test. @@ -84,6 +90,8 @@ make security # gosec + govulncheck ├── .devcontainer/ # VSCode / Codespaces container definition ├── .githooks/ # pre-push hook (installed by `make setup`) ├── .vscode/ # launch, tasks, editor settings +├── pkg/ +│ └── result/ # Example publishable package (Result/Expect types) ├── tools.versions # Pinned tool versions (Makefile + hook source this) ├── .golangci.yml # Linter configuration └── Makefile # All development commands @@ -99,7 +107,7 @@ All configuration is via CLI flags with sensible defaults: ./bin/app -help -env string environment: dev | staging | prod (default "dev") -log-level string log level: debug | info | warn | error (default "info") - -name string application name (default "go-template") + -name string greeter name (default "Gopher") -port int listen port (default 8080) ``` @@ -211,11 +219,24 @@ Run `make tools` if you also want the updated binary installed to `GOPATH/bin` --- +## Releasing + +```bash +make release # list all existing tags +make release VERSION=v0.1.0 # run full checks, then tag and push +``` + +The release target validates the version format (semver `vX.Y.Z`), ensures the +working tree is clean, and runs `make test-race lint security` before tagging. +The tag is only created and pushed if every check passes. + +--- + ## Devcontainer Open this repo in VSCode and choose **"Reopen in Container"** — the Go -toolchain and all tools (golangci-lint, gosec, govulncheck) are installed -automatically via `make init`. +toolchain is installed automatically. Run `make init` to configure git hooks, +then `make tools` to install linter/scanner binaries to `GOPATH/bin`. Works with GitHub Codespaces out of the box. @@ -225,6 +246,6 @@ Works with GitHub Codespaces out of the box. - **HTTP server** — add [chi](https://github.com/go-chi/chi) or [gin](https://github.com/gin-gonic/gin) - **Database** — add [sqlx](https://github.com/jmoiron/sqlx) or [ent](https://entgo.io/) -- **CI** — add `.github/workflows/ci.yml` running `make lint test security` +- **CI** — add a Gitea Actions / CI pipeline running `make lint test security` - **Docker** — add a multi-stage `Dockerfile` for the binary - **OpenTelemetry** — add tracing with `go.opentelemetry.io/otel`