chore: test change
This commit is contained in:
parent
8143ba02b0
commit
0955919a69
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,7 +1,7 @@
|
||||
node_modules/
|
||||
dist/
|
||||
coverage/
|
||||
backend/bin/
|
||||
server/bin/
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
29
.gitlab-ci.yml
Normal file
29
.gitlab-ci.yml
Normal file
@ -0,0 +1,29 @@
|
||||
workflow:
|
||||
rules:
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS'
|
||||
when: never
|
||||
- if: '$CI_PIPELINE_SOURCE == "push"'
|
||||
|
||||
stages:
|
||||
- test
|
||||
|
||||
server:
|
||||
stage: test
|
||||
# The Debian image includes the C compiler needed by Go's race detector.
|
||||
image: golang:1.27.2
|
||||
script:
|
||||
- cd server
|
||||
- go vet ./...
|
||||
- go test -race ./...
|
||||
|
||||
webapp:
|
||||
stage: test
|
||||
image: node:24
|
||||
before_script:
|
||||
- npm install --global pnpm@10.28.2
|
||||
- cd webapp
|
||||
- pnpm install --frozen-lockfile
|
||||
script:
|
||||
- pnpm check
|
||||
- pnpm test
|
||||
47
README.md
47
README.md
@ -1,6 +1,6 @@
|
||||
# Subalineado
|
||||
|
||||
Go API and SolidJS + TypeScript frontend in one repository. No database is required.
|
||||
Go API and SolidJS + TypeScript webapp in one repository. No database is required.
|
||||
|
||||
## Start in development
|
||||
|
||||
@ -19,7 +19,7 @@ Ctrl+C stops both services; remove their containers with:
|
||||
task dev:down
|
||||
```
|
||||
|
||||
Compose Watch syncs frontend source into Vite for hot reload and rebuilds the Go service on changes. Dependency and Vite configuration changes rebuild the frontend. Go module and compilation caches persist through BuildKit cache mounts. After a broken Go build, fix and save the source to trigger another build. Dockerfile changes require restarting with `--build`.
|
||||
Compose Watch syncs webapp source into Vite for hot reload and rebuilds the Go service on changes. Dependency and Vite configuration changes rebuild the webapp. Go module and compilation caches persist through BuildKit cache mounts. After a broken Go build, fix and save the source to trigger another build. Dockerfile changes require restarting with `--build`.
|
||||
|
||||
## Discover and extend commands
|
||||
|
||||
@ -29,21 +29,21 @@ task --list # Same list, explicitly
|
||||
task --summary dev # Read usage details for development
|
||||
task dev:status # See running services
|
||||
task dev:logs # Follow their logs
|
||||
task install # Install native Go and frontend dependencies
|
||||
task install # Install native Go and webapp dependencies
|
||||
task check # Go vet, Biome and TypeScript checks
|
||||
task test # Go race tests and Vitest tests
|
||||
task format # Go formatting and safe Biome fixes
|
||||
task build # Build both production Docker images
|
||||
```
|
||||
|
||||
`install`, `check`, `test`, and `format` use your native Go/Node/pnpm tools. `dev`, `dev:*`, and `build` use Docker. Individual commands such as `task backend:test` and `task frontend:check` are also listed. Tasks stop when a command fails.
|
||||
`install`, `check`, `test`, and `format` use your native Go/Node/pnpm tools. `dev`, `dev:*`, and `build` use Docker. Individual commands such as `task server:test` and `task webapp:check` are also listed. Tasks stop when a command fails.
|
||||
|
||||
All commands live in the root `Taskfile.yml`. Add a named task with `desc` and `cmds`; use `dir` for commands in a service directory and `summary` for detailed usage. Task finds the file from repository subdirectories too.
|
||||
|
||||
```yaml
|
||||
frontend:build:
|
||||
desc: Build the frontend locally
|
||||
dir: frontend
|
||||
webapp:build:
|
||||
desc: Build the webapp locally
|
||||
dir: webapp
|
||||
cmds:
|
||||
- pnpm build
|
||||
```
|
||||
@ -60,7 +60,7 @@ docker compose -f compose.yaml -f compose.dev.yaml up --build --watch
|
||||
docker compose up --build -d --wait
|
||||
```
|
||||
|
||||
Open http://localhost:3000. Nginx serves the compiled frontend and proxies `/api/*` and `/health` to Go. Both runtime containers run as non-root users and expose health checks. Ports bind to loopback for local use.
|
||||
Open http://localhost:3000. Nginx serves the compiled webapp and proxies `/api/*` and `/health` to Go. Both runtime containers run as non-root users and expose health checks. Ports bind to loopback for local use.
|
||||
|
||||
```sh
|
||||
docker compose down
|
||||
@ -73,7 +73,7 @@ Use Node **24**, pnpm **10.28.2**, and Go **1.27.2**. `.tool-versions` pins the
|
||||
In one terminal:
|
||||
|
||||
```sh
|
||||
cd backend
|
||||
cd server
|
||||
go mod download
|
||||
go run ./cmd/api
|
||||
```
|
||||
@ -81,26 +81,26 @@ go run ./cmd/api
|
||||
In another:
|
||||
|
||||
```sh
|
||||
cd frontend
|
||||
cd webapp
|
||||
pnpm install --frozen-lockfile
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
Native Go development requires restarting `go run` after edits; Compose Watch automates this in the container workflow.
|
||||
|
||||
Backend checks:
|
||||
Server checks:
|
||||
|
||||
```sh
|
||||
cd backend
|
||||
cd server
|
||||
go test -race ./...
|
||||
go vet ./...
|
||||
go build -o bin/api ./cmd/api
|
||||
```
|
||||
|
||||
Frontend checks:
|
||||
Webapp checks:
|
||||
|
||||
```sh
|
||||
cd frontend
|
||||
cd webapp
|
||||
pnpm check
|
||||
pnpm test
|
||||
pnpm build
|
||||
@ -108,11 +108,20 @@ pnpm build
|
||||
|
||||
`pnpm format` applies Biome formatting and safe fixes; `pnpm test:watch` runs Vitest interactively.
|
||||
|
||||
## Continuous integration
|
||||
|
||||
`.gitlab-ci.yml` runs two jobs in parallel on every push and merge request:
|
||||
|
||||
- Server: `go vet ./...` and `go test -race ./...` with Go 1.27.2.
|
||||
- Webapp: `pnpm check` (Biome and TypeScript) and `pnpm test` (Vitest) with Node 24 and pnpm 10.28.2. Dependencies use the frozen lockfile.
|
||||
|
||||
When a branch has an open merge request, its pushes run the merge request pipeline instead of a duplicate branch pipeline. All checks run even for documentation-only changes. A GitLab runner supporting container images (Docker or Kubernetes executor) must be available to the project; no deployment credentials are needed.
|
||||
|
||||
## Structure and API
|
||||
|
||||
- `backend/cmd/api`: process startup, HTTP timeouts, signal handling and graceful shutdown.
|
||||
- `backend/internal/httpapi`: router, HTTP handlers and endpoint tests.
|
||||
- `frontend/src`: page, typed API client and component tests.
|
||||
- `server/cmd/api`: process startup, HTTP timeouts, signal handling and graceful shutdown.
|
||||
- `server/internal/httpapi`: router, HTTP handlers and endpoint tests.
|
||||
- `webapp/src`: page, typed API client and component tests.
|
||||
- `Taskfile.yml`: discoverable development, dependency, formatting and verification commands.
|
||||
- `compose.yaml`: production images and service dependencies.
|
||||
- `compose.dev.yaml`: development overrides and file-watch rules.
|
||||
@ -122,7 +131,9 @@ pnpm build
|
||||
| `GET /health` | `200 {"status":"ok"}` |
|
||||
| `GET /api/test` | `200 {"message":"API connection successful"}` |
|
||||
|
||||
Responses use `application/json`. Other methods return 405; unknown routes return 404. `HTTP_ADDR` configures the API listener (default `:8080`). Vite reads `API_PROXY_TARGET` (default `http://localhost:8080`); Compose sets it to the backend service. This is a server-side proxy setting, not a browser URL.
|
||||
Responses use `application/json`. Other methods return 405; unknown routes return 404. `HTTP_ADDR` configures the API listener (default `:8080`). Vite reads `API_PROXY_TARGET` (default `http://localhost:8080`); Compose sets it to the server service. This is a server-side proxy setting, not a browser URL.
|
||||
|
||||
|
||||
|
||||
## Tooling choices
|
||||
|
||||
|
||||
62
Taskfile.yml
62
Taskfile.yml
@ -14,8 +14,8 @@ tasks:
|
||||
dev:
|
||||
desc: Start both services with hot reload
|
||||
summary: |
|
||||
Build and start the API and frontend with Compose Watch.
|
||||
Frontend: http://localhost:5173; API: http://localhost:8080.
|
||||
Build and start the API and webapp with Compose Watch.
|
||||
Webapp: http://localhost:5173; API: http://localhost:8080.
|
||||
Ctrl+C stops the services. Run task dev:down to remove containers.
|
||||
Override occupied ports with API_PORT=18080 DEV_WEB_PORT=15173 task dev.
|
||||
Requires Docker Compose 2.32+; native Go, Node and pnpm are unnecessary.
|
||||
@ -38,22 +38,22 @@ tasks:
|
||||
- '{{.DEV_COMPOSE}} ps'
|
||||
|
||||
install:
|
||||
desc: Download native backend and frontend dependencies
|
||||
desc: Download native server and webapp dependencies
|
||||
cmds:
|
||||
- task: backend:install
|
||||
- task: frontend:install
|
||||
- task: server:install
|
||||
- task: webapp:install
|
||||
|
||||
check:
|
||||
desc: Check Go code, frontend linting and TypeScript types
|
||||
desc: Check Go code, webapp linting and TypeScript types
|
||||
cmds:
|
||||
- task: backend:check
|
||||
- task: frontend:check
|
||||
- task: server:check
|
||||
- task: webapp:check
|
||||
|
||||
test:
|
||||
desc: Run backend race tests and frontend component tests
|
||||
desc: Run server race tests and webapp component tests
|
||||
cmds:
|
||||
- task: backend:test
|
||||
- task: frontend:test
|
||||
- task: server:test
|
||||
- task: webapp:test
|
||||
|
||||
build:
|
||||
desc: Build both production Docker images
|
||||
@ -63,53 +63,53 @@ tasks:
|
||||
format:
|
||||
desc: Format Go code and apply safe Biome fixes
|
||||
cmds:
|
||||
- task: backend:format
|
||||
- task: frontend:format
|
||||
- task: server:format
|
||||
- task: webapp:format
|
||||
|
||||
backend:install:
|
||||
server:install:
|
||||
desc: Download Go modules
|
||||
dir: backend
|
||||
dir: server
|
||||
cmds:
|
||||
- go mod download
|
||||
|
||||
backend:check:
|
||||
server:check:
|
||||
desc: Run Go vet
|
||||
dir: backend
|
||||
dir: server
|
||||
cmds:
|
||||
- go vet ./...
|
||||
|
||||
backend:test:
|
||||
server:test:
|
||||
desc: Run Go tests with race detection
|
||||
dir: backend
|
||||
dir: server
|
||||
cmds:
|
||||
- go test -race ./...
|
||||
|
||||
backend:format:
|
||||
desc: Format backend Go source
|
||||
dir: backend
|
||||
server:format:
|
||||
desc: Format server Go source
|
||||
dir: server
|
||||
cmds:
|
||||
- go fmt ./...
|
||||
|
||||
frontend:install:
|
||||
desc: Install frontend dependencies from the lockfile
|
||||
dir: frontend
|
||||
webapp:install:
|
||||
desc: Install webapp dependencies from the lockfile
|
||||
dir: webapp
|
||||
cmds:
|
||||
- pnpm install --frozen-lockfile
|
||||
|
||||
frontend:check:
|
||||
webapp:check:
|
||||
desc: Run Biome and TypeScript checks
|
||||
dir: frontend
|
||||
dir: webapp
|
||||
cmds:
|
||||
- pnpm check
|
||||
|
||||
frontend:test:
|
||||
webapp:test:
|
||||
desc: Run Vitest component tests
|
||||
dir: frontend
|
||||
dir: webapp
|
||||
cmds:
|
||||
- pnpm test
|
||||
|
||||
frontend:format:
|
||||
webapp:format:
|
||||
desc: Apply Biome formatting and safe fixes
|
||||
dir: frontend
|
||||
dir: webapp
|
||||
cmds:
|
||||
- pnpm format
|
||||
|
||||
@ -1,36 +1,36 @@
|
||||
services:
|
||||
backend:
|
||||
server:
|
||||
develop:
|
||||
watch:
|
||||
- action: rebuild
|
||||
path: ./backend
|
||||
path: ./server
|
||||
ignore:
|
||||
- bin/
|
||||
- "**/*_test.go"
|
||||
frontend:
|
||||
webapp:
|
||||
build:
|
||||
target: dev
|
||||
ports: !override
|
||||
- "127.0.0.1:${DEV_WEB_PORT:-5173}:5173"
|
||||
environment:
|
||||
API_PROXY_TARGET: http://backend:8080
|
||||
API_PROXY_TARGET: http://server:8080
|
||||
healthcheck:
|
||||
test: ["CMD", "node", "-e", "fetch('http://127.0.0.1:5173').then(r=>process.exit(r.ok?0:1)).catch(()=>process.exit(1))"]
|
||||
develop:
|
||||
watch:
|
||||
- action: sync
|
||||
path: ./frontend/src
|
||||
path: ./webapp/src
|
||||
target: /app/src
|
||||
initial_sync: true
|
||||
- action: sync
|
||||
path: ./frontend/index.html
|
||||
path: ./webapp/index.html
|
||||
target: /app/index.html
|
||||
initial_sync: true
|
||||
- action: rebuild
|
||||
path: ./frontend/package.json
|
||||
path: ./webapp/package.json
|
||||
- action: rebuild
|
||||
path: ./frontend/pnpm-lock.yaml
|
||||
path: ./webapp/pnpm-lock.yaml
|
||||
- action: rebuild
|
||||
path: ./frontend/vite.config.ts
|
||||
path: ./webapp/vite.config.ts
|
||||
- action: rebuild
|
||||
path: ./frontend/tsconfig.json
|
||||
path: ./webapp/tsconfig.json
|
||||
|
||||
10
compose.yaml
10
compose.yaml
@ -1,8 +1,8 @@
|
||||
name: subalineado
|
||||
services:
|
||||
backend:
|
||||
server:
|
||||
build:
|
||||
context: ./backend
|
||||
context: ./server
|
||||
target: runtime
|
||||
ports:
|
||||
- "127.0.0.1:${API_PORT:-8080}:8080"
|
||||
@ -10,13 +10,13 @@ services:
|
||||
HTTP_ADDR: ":8080"
|
||||
init: true
|
||||
stop_grace_period: 15s
|
||||
frontend:
|
||||
webapp:
|
||||
build:
|
||||
context: ./frontend
|
||||
context: ./webapp
|
||||
target: runtime
|
||||
ports:
|
||||
- "127.0.0.1:${WEB_PORT:-3000}:8080"
|
||||
depends_on:
|
||||
backend:
|
||||
server:
|
||||
condition: service_healthy
|
||||
init: true
|
||||
|
||||
@ -7,7 +7,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"subalineado/backend/internal/httpapi"
|
||||
"subalineado/server/internal/httpapi"
|
||||
"syscall"
|
||||
"time"
|
||||
)
|
||||
@ -1,4 +1,4 @@
|
||||
module subalineado/backend
|
||||
module subalineado/server
|
||||
|
||||
go 1.27.2
|
||||
|
||||
@ -5,12 +5,12 @@ server {
|
||||
index index.html;
|
||||
|
||||
location /api/ {
|
||||
proxy_pass http://backend:8080;
|
||||
proxy_pass http://server:8080;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
location = /health {
|
||||
proxy_pass http://backend:8080;
|
||||
proxy_pass http://server:8080;
|
||||
}
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "subalineado-frontend",
|
||||
"name": "subalineado-webapp",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
Loading…
x
Reference in New Issue
Block a user