From a3a4c0e896f0469acbb79dfae06fa14fd79512f3 Mon Sep 17 00:00:00 2001 From: Nikolay Tatarinov Date: Wed, 4 Mar 2026 11:39:27 +0300 Subject: [PATCH] Enhance development workflow with Docker integration - Updated CONTRIBUTING.md to clarify the use of Makefile targets for running tasks inside Docker, eliminating the need for local Go or Node installations. - Introduced docker-compose.tools.yml for backend and frontend tools, allowing for streamlined testing, linting, and formatting. - Created Dockerfile.tools to set up a Go environment with necessary tools for testing and linting. - Modified Makefile to include separate targets for backend and frontend tests, improving clarity and usability. - Updated documentation in development.md and testing.md to reflect the new Docker-based workflow for running tests and development tasks. --- .cursor/rules/project-conventions.mdc | 2 +- .cursor/skills/run-tests/SKILL.md | 40 +++---------- CONTRIBUTING.md | 8 +-- Dockerfile.tools | 7 +++ Makefile | 21 ++++--- docker-compose.tools.yml | 21 +++++++ docs/development.md | 86 +++++++++++++++------------ docs/testing.md | 19 +++++- 8 files changed, 120 insertions(+), 84 deletions(-) create mode 100644 Dockerfile.tools create mode 100644 docker-compose.tools.yml diff --git a/.cursor/rules/project-conventions.mdc b/.cursor/rules/project-conventions.mdc index 9ec1a47..55927fa 100644 --- a/.cursor/rules/project-conventions.mdc +++ b/.cursor/rules/project-conventions.mdc @@ -8,7 +8,7 @@ alwaysApply: true - **Monorepo:** Go backend + Nuxt 3 frontend. Backend: `cmd/hnh-map/`, `internal/app/`. Frontend source: `frontend-nuxt/`; production static output: `frontend/` (build artifact from `frontend-nuxt/`, do not edit). - **Changing API:** Update `internal/app/` (e.g. `api.go`, `map.go`) and [docs/api.md](docs/api.md); frontend uses composables in `frontend-nuxt/composables/` (e.g. `useMapApi.ts`). - **Changing config:** Update [.env.example](.env.example) and [docs/configuration.md](docs/configuration.md). -- **Local run / build:** [docs/development.md](docs/development.md), [CONTRIBUTING.md](CONTRIBUTING.md). Dev ports: frontend 3000, backend 3080; prod: 8080. +- **Local run / build:** [docs/development.md](docs/development.md), [CONTRIBUTING.md](CONTRIBUTING.md). Dev ports: frontend 3000, backend 3080; prod: 8080. Build, test, lint, and format run via Docker (Makefile + docker-compose.tools.yml). - **Docs:** [docs/](docs/) (architecture, API, configuration, development, deployment). Some docs are in Russian. - **Coding:** Write tests first before implementing any functionality. - **Running tests:** When the user asks to run tests or to verify changes, use the run-tests skill: [.cursor/skills/run-tests/SKILL.md](.cursor/skills/run-tests/SKILL.md). diff --git a/.cursor/skills/run-tests/SKILL.md b/.cursor/skills/run-tests/SKILL.md index f6477fb..88d27a2 100644 --- a/.cursor/skills/run-tests/SKILL.md +++ b/.cursor/skills/run-tests/SKILL.md @@ -12,42 +12,20 @@ description: Runs backend (Go) and frontend (Vitest) tests for the hnh-map monor ## What to run -This repo has two test suites. Run the one(s) that match the changed code, or both if unsure. +Tests run **in Docker** via the Makefile; no local Go or Node is required. -### Backend (Go) +From the repo root, use: -From repo root: +- **Both backend and frontend:** `make test` (runs backend then frontend tests in Docker). +- **Backend only:** `make test-backend` +- **Frontend only:** `make test-frontend` -```bash -make test -``` - -Or: - -```bash -go test ./... -``` - -Uses temp dirs and in-memory DBs; no external services needed. - -### Frontend (Vitest) - -From repo root: - -```bash -npm --prefix frontend-nuxt run test -``` - -Or from `frontend-nuxt/`: - -```bash -npm test -``` +These use `docker-compose.tools.yml`; the first run may build the backend-tools image. ## Scope -- **Backend-only changes** (e.g. `internal/`, `cmd/`): run `make test`. -- **Frontend-only changes** (e.g. `frontend-nuxt/`): run `npm --prefix frontend-nuxt run test`. -- **Both or unclear**: run backend then frontend. +- **Backend-only changes** (e.g. `internal/`, `cmd/`): run `make test-backend`. +- **Frontend-only changes** (e.g. `frontend-nuxt/`): run `make test-frontend`. +- **Both or unclear**: run `make test`. Report pass/fail and any failing test names or errors. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8261777..4fde7b7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,19 +25,19 @@ The backend follows a layered architecture: **Store → Services → Handlers**. ## Formatting, linting, and tests -Use Makefile targets for common tasks: +Use Makefile targets; they run inside Docker via `docker-compose.tools.yml`, so you do not need Go or Node installed for these tasks: ```bash make fmt # Format all code (Go + frontend) make lint # Run Go linter (golangci-lint) and frontend ESLint -make test # Run Go tests +make test # Run backend and frontend tests ``` -Or run manually: +Or run manually on the host if you have Go and Node: - Go: `go fmt ./...` and `golangci-lint run` - Frontend: `npm --prefix frontend-nuxt run lint` and `npm --prefix frontend-nuxt run format` -- Tests: `go test ./...` +- Tests: `go test ./...` and `npm --prefix frontend-nuxt run test` Always format and lint before committing. Add or update tests if you change behaviour. diff --git a/Dockerfile.tools b/Dockerfile.tools new file mode 100644 index 0000000..99e1575 --- /dev/null +++ b/Dockerfile.tools @@ -0,0 +1,7 @@ +# Backend tools image: Go + golangci-lint for test, fmt, lint. +# Source is mounted at /hnh-map at run time via docker-compose.tools.yml. +FROM golang:1.24-alpine + +RUN go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.61.0 + +WORKDIR /hnh-map diff --git a/Makefile b/Makefile index 09dedbf..6a1ba5b 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ -.PHONY: dev build test lint fmt generate-frontend clean +.PHONY: dev build test test-backend test-frontend lint fmt generate-frontend clean + +TOOLS_COMPOSE = docker compose -f docker-compose.tools.yml dev: docker compose -f docker-compose.dev.yml up @@ -6,16 +8,21 @@ dev: build: docker compose -f docker-compose.prod.yml build -test: - go test ./... +test: test-backend test-frontend + +test-backend: + $(TOOLS_COMPOSE) run --rm backend-tools go test ./... + +test-frontend: + $(TOOLS_COMPOSE) run --rm frontend-tools sh -c "npm ci && npm test" lint: - golangci-lint run - npm --prefix frontend-nuxt run lint + $(TOOLS_COMPOSE) run --rm backend-tools golangci-lint run + $(TOOLS_COMPOSE) run --rm frontend-tools sh -c "npm ci && npm run lint" fmt: - go fmt ./... - npm --prefix frontend-nuxt run format + $(TOOLS_COMPOSE) run --rm backend-tools go fmt ./... + $(TOOLS_COMPOSE) run --rm frontend-tools sh -c "npm ci && npm run format" generate-frontend: npm --prefix frontend-nuxt run generate diff --git a/docker-compose.tools.yml b/docker-compose.tools.yml new file mode 100644 index 0000000..e9e9127 --- /dev/null +++ b/docker-compose.tools.yml @@ -0,0 +1,21 @@ +# One-off tools: test, lint, fmt. Use with: docker compose -f docker-compose.tools.yml run --rm +# Source is mounted so commands run against current code. + +services: + backend-tools: + build: + context: . + dockerfile: Dockerfile.tools + volumes: + - .:/hnh-map + # Default command; override when running (e.g. go test ./..., golangci-lint run). + command: ["go", "test", "./..."] + + frontend-tools: + image: node:20-alpine + working_dir: /app + volumes: + - ./frontend-nuxt:/app + - /app/node_modules + # Default command; override when running (e.g. npm test, npm run lint). + command: ["npm", "test"] diff --git a/docs/development.md b/docs/development.md index 23e34e0..eb5dbf2 100644 --- a/docs/development.md +++ b/docs/development.md @@ -1,34 +1,9 @@ # Development +The recommended way to develop is **Docker-first**: run the app with `make dev`, and run tests, lint, and format with `make test`, `make lint`, and `make fmt`. All of these use Docker (see [Makefile targets](#makefile-targets)); you do not need Go or Node installed for the dev loop. Optionally, you can run backend or frontend locally without Docker (see [Without Docker](#without-docker)). + ## Local setup -### Backend (Go) - -From the repository root: - -```bash -go build -o hnh-map ./cmd/hnh-map -./hnh-map -grids=./grids -port=8080 -``` - -Or without building: - -```bash -go run ./cmd/hnh-map -grids=./grids -port=8080 -``` - -The server serves static files from the `frontend/` directory (you need to build the frontend first, see below). - -### Frontend (Nuxt) - -```bash -cd frontend-nuxt -npm install -npm run dev -``` - -In dev mode the app is available at root (e.g. `http://localhost:3000/`). The backend must be reachable; configure the proxy in `nuxt.config.ts` if needed (e.g. to `http://localhost:8080`). - ### Docker Compose (development) ```bash @@ -53,6 +28,37 @@ Port `3080` is for API and backend endpoints; the root `/` may return `404` in d **Gravatar (avatar by email):** Gravatar URLs are built on the frontend using the `md5` package (client-side MD5 of the user's email). No backend endpoint is used; the frontend composable `useGravatarUrl` (see Phase 5+ of the navbar/avatar plan) will use this dependency. +### Without Docker + +You can run backend and frontend on the host if you have Go and Node installed. + +#### Backend (Go) + +From the repository root: + +```bash +go build -o hnh-map ./cmd/hnh-map +./hnh-map -grids=./grids -port=8080 +``` + +Or without building: + +```bash +go run ./cmd/hnh-map -grids=./grids -port=8080 +``` + +The server serves static files from the `frontend/` directory (you need to build the frontend first, see below). + +#### Frontend (Nuxt) + +```bash +cd frontend-nuxt +npm install +npm run dev +``` + +In dev mode the app is available at root (e.g. `http://localhost:3000/`). The backend must be reachable; configure the proxy in `nuxt.config.ts` if needed (e.g. to `http://localhost:8080`). + ### Building the image and production Compose ```bash @@ -70,33 +76,35 @@ In production the frontend is built into the image and served by the backend fro ## Makefile targets +All of `test`, `lint`, and `fmt` run inside Docker via `docker-compose.tools.yml` (backend and frontend tools containers with source mounted). No local Go or Node is required. + | Target | Description | |--------|-------------| | `make dev` | Start Docker Compose development environment | | `make build` | Build production Docker image | -| `make test` | Run Go tests (`go test ./...`) | -| `make lint` | Run Go and frontend linters | -| `make fmt` | Format all code (Go + frontend) | -| `make generate-frontend` | Build frontend static output into `frontend/` | +| `make test` | Run backend and frontend tests in Docker | +| `make test-backend` | Run Go tests in Docker only | +| `make test-frontend` | Run frontend (Vitest) tests in Docker only | +| `make lint` | Run Go (golangci-lint) and frontend (ESLint) linters in Docker | +| `make fmt` | Format all code (Go + frontend) in Docker | +| `make generate-frontend` | Build frontend static output into `frontend/` (host) | | `make clean` | Remove build artifacts | ## Running tests +From the repo root: + ```bash make test ``` -Or directly: +This runs backend tests and frontend tests in Docker (see `docker-compose.tools.yml`). To run only one side: `make test-backend` or `make test-frontend`. + +If you have Go and Node installed locally, you can instead run: ```bash go test ./... -``` - -For frontend tests (if configured): - -```bash -cd frontend-nuxt -npm test +cd frontend-nuxt && npm test ``` See [docs/testing.md](testing.md) for details on the test suite. diff --git a/docs/testing.md b/docs/testing.md index 92f987d..1991c4b 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -2,13 +2,24 @@ ## Running tests -### Backend (Go) +The canonical way to run tests is via Docker (no local Go or Node required): ```bash make test ``` -Or directly: +This runs both backend and frontend tests in Docker. For one side only: + +```bash +make test-backend # Go tests only +make test-frontend # Vitest only +``` + +### Backend (Go) + +With Docker (recommended): `make test-backend` or `make test`. + +Or directly if you have Go installed: ```bash go test ./... @@ -16,6 +27,10 @@ go test ./... ### Frontend (Vitest) +With Docker (recommended): `make test-frontend` or `make test`. + +Or directly if you have Node installed: + ```bash cd frontend-nuxt npm test