Ctrl K
ComunidadGuías…

Makefile

Rama master · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
.PHONY: docs

# Load configuration from .env (production settings, ports, etc.)
-include .env

# Function to strip single/double quotes using Make functions
define strip_quotes
$(subst ",,$(subst ',,$($(1))))
endef

# Disable printing directory traversal on task start/end
MAKEFLAGS += --no-print-directory

# Constants
IMAGE_NAME=sdvd/server
TEST_CLIENT_IMAGE_NAME=sdvd/test-client
IMAGE_VERSION ?= local
DOCKERFILE_PATH=docker/Dockerfile
TEST_CLIENT_DOCKERFILE_PATH=docker/Dockerfile.test-client

# Build configuration (Debug for local, Release for CI/production)
BUILD_CONFIGURATION ?= Debug

# Docker build progress output (plain, tty, auto, quiet)
DOCKER_PROGRESS ?= plain

# Dev overlay adds the sidecar build contexts; explicit -f drops the automatic override merge, so re-add it.
COMPOSE := docker compose -f docker-compose.yml -f docker-compose.dev.yml $(if $(wildcard docker-compose.override.yml),-f docker-compose.override.yml)

# Export IMAGE_VERSION for usage in docker compose commands
export IMAGE_VERSION

# Steam build credentials for Docker image builds (game download).
# By default these come from .env (loaded above). When the test harness
# calls `make build`, it overrides these via command-line variables
# (e.g. `make build STEAM_USERNAME=x`), which take precedence over
# -include .env values in GNU Make.
export STEAM_USERNAME := $(call strip_quotes,STEAM_USERNAME)
export STEAM_PASSWORD := $(call strip_quotes,STEAM_PASSWORD)
export STEAM_REFRESH_TOKEN := $(call strip_quotes,STEAM_REFRESH_TOKEN)

# Cross-platform ISO 8601 UTC timestamp (safe for use with filenames etc.)
ifeq ($(OS),Windows_NT)
    TIMESTAMP := $(shell powershell -NoProfile -Command "(Get-Date).ToUniversalTime().ToString('yyyy-MM-ddTHH-mm-ss')")Z
else
    TIMESTAMP := $(shell date -u '+%Y-%m-%dT%H-%M-%S')Z
endif

# Short git commit ("-dirty" when the tree is modified), baked in as SDVD_GIT_SHA so the diagnostics
# tool can identify a local build. `--match=` matches no tag, leaving --always to yield the bare
# commit; unquoted because cmd.exe would pass the quotes through to git. Empty outside a git checkout,
# where build-server omits the --build-arg so the Dockerfile default applies (passing it empty would
# set the ARG to ""). CI builds via docker/build-push-action and passes its own github.sha.
GIT_SHA := $(shell git describe --always --dirty --match=)

# Install development dependencies
install:
	@echo Installing development dependencies...
	@npm ci
	@dotnet tool restore
	@echo Setup complete. Git hooks are now active.

# Build all production docker images (server + steam-service)
build: build-server build-steam-service

# Build server docker image (downloads game during build for mod compilation)
build-server:
	@echo Building image `$(IMAGE_NAME):$(IMAGE_VERSION)` with BUILD_CONFIGURATION=$(BUILD_CONFIGURATION)...
	@docker buildx build \
		--platform=linux/amd64 \
		--build-arg BUILD_CONFIGURATION=$(BUILD_CONFIGURATION) \
		$(if $(GIT_SHA),--build-arg SDVD_GIT_SHA=$(GIT_SHA)) \
		-t $(IMAGE_NAME):$(IMAGE_VERSION) \
		$(if $(filter-out local,$(IMAGE_VERSION)),-t $(IMAGE_NAME):latest) \
		--secret id=steam_username,env=STEAM_USERNAME \
		--secret id=steam_password,env=STEAM_PASSWORD \
		--secret id=steam_refresh_token,env=STEAM_REFRESH_TOKEN \
		-f $(DOCKERFILE_PATH) \
		--load \
		--progress=$(DOCKER_PROGRESS) \
		.
	@echo Server build complete.

# Build steam-service docker image
build-steam-service:
	@echo Building steam-service image...
	@$(COMPOSE) build steam-auth
	@echo Steam-service build complete.

# Build test client docker image (for containerized E2E tests)
build-test-client:
	@echo Building test client image `$(TEST_CLIENT_IMAGE_NAME):$(IMAGE_VERSION)`...
	@docker buildx build \
		--platform=linux/amd64 \
		-t $(TEST_CLIENT_IMAGE_NAME):$(IMAGE_VERSION) \
		--secret id=steam_username,env=STEAM_USERNAME \
		--secret id=steam_password,env=STEAM_PASSWORD \
		--secret id=steam_refresh_token,env=STEAM_REFRESH_TOKEN \
		-f $(TEST_CLIENT_DOCKERFILE_PATH) \
		--load \
		--progress=$(DOCKER_PROGRESS) \
		.
	@echo Test client build complete.

# Build and run everything
up: build
	@echo Starting server `$(IMAGE_NAME):$(IMAGE_VERSION)`...
	@$(COMPOSE) up -d --build
	@echo Server is now running. Use `make cli` or `make logs` to view output.

# Authenticate Steam accounts and download game files (interactive).
# Passes .env.test (if present) so steam-service sees both production
# credentials (STEAM_USERNAME/PASSWORD from .env via compose) and test
# accounts (STEAM_ACCOUNTS JSON from .env.test). Accounts with saved
# sessions are skipped; only new accounts prompt for Steam Guard.
setup: build-steam-service
	@$(COMPOSE) run --rm -it \
		$(if $(wildcard .env.test),--env-from-file .env.test) \
		steam-auth setup
	@echo Setup complete. Saved sessions are stored in the steam-session volume.

restart:
	@echo Restarting server `$(IMAGE_NAME):$(IMAGE_VERSION)`...
	@$(COMPOSE) restart
	@echo Server restarted. Use `make cli` or `make logs` to view output.

# Stop the server
down:
	@echo Stopping server...
	@$(COMPOSE) down --remove-orphans

# Attach to interactive split-pane server CLI
cli:
	@$(COMPOSE) exec server attach-cli

# Collect a server-state diagnostics bundle (wizard + zip on the host under ./diagnostics)
diagnostics:
	@$(COMPOSE) exec -it server diagnostics

# View server logs (escape sequence to reset colors)
logs:
	@$(COMPOSE) logs -f
	-@bun -e "process.stdout.write('\x1b[0m')"

dumplogs:
	@echo "Writing logs to logs_$(TIMESTAMP).txt"
	@$(COMPOSE) logs > "logs_$(TIMESTAMP).txt"

# Start docs dev server (extracts OpenAPI spec from Docker image first)
docs:
	@echo Extracting OpenAPI spec from $(IMAGE_NAME):$(IMAGE_VERSION) image...
	@bun -e "require('fs').mkdirSync('docs/assets', { recursive: true })"
	-@bun -e "try{require('child_process').execSync('docker rm -f openapi-extract',{stdio:'ignore'})}catch(e){}"
	@docker create --name openapi-extract $(IMAGE_NAME):$(IMAGE_VERSION)
	@docker cp openapi-extract:/data/openapi.json docs/assets/openapi.json
	@docker rm openapi-extract
	@echo OpenAPI spec ready.
	@bun --cwd=./docs run dev

# Regenerate the documentation page-relationship graph (docs/.output/page-graph.html)
docs-graph:
	@bun --cwd=./docs run graph
	@echo "Open docs/.output/page-graph.html in a browser."

# Clean up everything, including all volumes
clean:
	@echo Cleaning up...
	@IMAGE_VERSION=$(IMAGE_VERSION) $(COMPOSE) down -v
	-@docker rmi $(IMAGE_NAME):$(IMAGE_VERSION) $(IMAGE_NAME):latest

# Test project paths
TEST_PROJECT := ./tests/JunimoServer.Tests
RUNNER_PROJECT := ./tests/JunimoServer.TestRunner

# Test filtering. Use FILTER to run specific tests (case-insensitive substring of the
# class FullName or {Class}.{Method} display name). Separate alternatives with '|':
#   make test FILTER=PasswordProtection
#   make test FILTER="Login_WithCorrectPassword"
#   make test FILTER="CabinStrategyNoneTests|CabinPositionPersistenceTests"
#   make test (runs all tests)
# Note: '|' works only for direct `make test`. The !run-tests-e2e PR-comment trigger
# rejects '|' (it would break the sticky-comment markdown table); use one pattern there.
FILTER ?=

# Verbose output. Use VERBOSE=1 for detailed setup steps and diagnostic logs:
#   make test VERBOSE=1
VERBOSE ?=

export COLUMNS=160

# Run tests with custom runner (CI mode - streaming output)
test:
	@dotnet run --project $(RUNNER_PROJECT) -- $(if $(VERBOSE),--verbose) $(if $(FILTER),--filter "$(FILTER)")

# Run unit tests (no Docker, no Steam)
test-unit:
	@dotnet test tests/SteamService.Tests/SteamService.Tests.csproj
	@dotnet test tests/JunimoServer.UnitTests/JunimoServer.UnitTests.csproj

# Run tests with verbose output (detailed setup steps, diagnostics inline)
test-verbose:
	@dotnet run --project $(RUNNER_PROJECT) -- --verbose $(if $(FILTER),--filter "$(FILTER)")

# Run tests with structured JSONL output (for LLM/AI agents)
# Sets SDVD_TEST_TRACING=full for the AI-debug context (respBody capture,
# X-Request-Id on reads, wait_started). An SDVD_TEST_TRACING line in .env.test
# overrides it: TestEnvLoader clobbers process env.
test-llm: export SDVD_TEST_TRACING=full
test-llm:
	@dotnet run --project $(RUNNER_PROJECT) -- --llm $(if $(FILTER),--filter "$(FILTER)")

# Build the test UI frontend (required for --web mode)
build-test-ui:
ifeq ($(OS),Windows_NT)
	@where bun >NUL 2>&1 || (echo "Error: bun is required for test-ui. Install: https://bun.sh" && exit 1)
else
	@command -v bun >/dev/null || (echo "Error: bun is required for test-ui. Install: https://bun.sh" && exit 1)
endif
	@cd tests/test-ui && bun install && bun run build

# Run tests with web UI (opens browser with live results)
test-web: build-test-ui
	@dotnet run --project $(RUNNER_PROJECT) -- --web $(if $(VERBOSE),--verbose) $(if $(FILTER),--filter "$(FILTER)")

# Run tests with web UI and generate static report
test-web-report: build-test-ui
	@dotnet run --project $(RUNNER_PROJECT) -- --web --report $(if $(VERBOSE),--verbose) $(if $(FILTER),--filter "$(FILTER)")

# Render OG (social link-preview) card mockups to .output/og-preview/ for design review
og-preview:
	@dotnet run --project $(RUNNER_PROJECT) -- preview-og

# --- Test Observability Targets ---
# All run via tools/test-observability.ts so they work from any shell (PowerShell,
# cmd, bash) with no jq/python/awk/column dependency. Latest-run resolution and
# all queries live in the script; these targets just pass args through.

# Show test run summary (failures, timing, classification)
test-summary:
	@bun tools/test-observability.ts summary

# Show per-test event log (Usage: make test-events TEST=ClassName.MethodName[(arg=...)])
# Filters infrastructure.jsonl by test displayName; matches both fact and theory tests.
test-events:
	@bun tools/test-observability.ts events TEST="$(TEST)"

# Show infrastructure lifecycle log (server/client creation, capacity, sessions)
test-infra-log:
	@bun tools/test-observability.ts infra-log

# Show full lifecycle log for a container (Usage: make test-container-log CONTAINER=server-0)
test-container-log:
	@bun tools/test-observability.ts container-log CONTAINER="$(CONTAINER)"

# Show run metadata (git, env, runtime info)
test-metadata:
	@bun tools/test-observability.ts metadata

# Show flakiness data across recent runs
test-flaky:
	@bun tools/test-observability.ts flaky

# Rank tests by runtime across recent runs to find suite-shortening targets.
# Reads the per-test timing already in flakiness.jsonl (same file as test-flaky).
# Default sort is total observed slot-time (sum of sampled durations) — the best
# proxy for "improving this shortens the whole suite", since tests run in parallel
# and a frequently-run or theory-multiplied test consumes more wall-clock than a
# slow-but-rare singleton.
# Usage: make test-slowest [N=15] [SORT=total|p50|p90|max] [FIELD=durationMs|testBodyMs] [LASTRUNS=20] [MINRUNS=3]
N ?= 15
SORT ?= total
FIELD ?= durationMs
LASTRUNS ?= 20
MINRUNS ?= 3
test-slowest:
	@bun tools/test-observability.ts slowest N=$(N) SORT=$(SORT) FIELD=$(FIELD) LASTRUNS=$(LASTRUNS) MINRUNS=$(MINRUNS)

# Dump the last few failure_context events from the latest run for quick triage.
test-diagnose:
	@bun tools/test-observability.ts diagnose

# Verify analyzer style rules and formatting without writing (builds the solution).
# Biome covers the JS/TS projects scoped in biome.jsonc.
lint-check:
	@dotnet format style JunimoServer.slnx --severity error --verify-no-changes
	@dotnet csharpier check .
	@npx @biomejs/biome check .

# Auto-fix analyzer style violations (braces, namespaces, usings), then re-format.
lint-fix:
	@dotnet format style JunimoServer.slnx --severity error
	@dotnet csharpier format .
	@npx @biomejs/biome check --write --unsafe .

# Show help
help:
	@echo Stardew Valley Dedicated Server
	@echo ""
	@echo Targets:
	@echo "  make install  - Install development dependencies (commitlint, git hooks)"
	@echo "  make setup    - Run first-time Steam authentication and game download"
	@echo "  make up       - Build and start server"
	@echo "  make build    - Build all production images (server + steam-service)"
	@echo "  make logs     - View server logs"
	@echo "  make dumplogs - Dump server logs to file on host"
	@echo "  make cli      - Attach to interactive server console (tmux-based)"
	@echo "  make diagnostics - Collect a server-state diagnostics zip (host ./diagnostics/)"
	@echo "  make down     - Stop the server"
	@echo "  make restart  - Restart the server (preserves volumes)"
	@echo "  make docs     - Start docs dev server (requires built image)"
	@echo "  make docs-graph - Regenerate the docs page-relationship graph (HTML)"
	@echo "  make clean    - Remove ALL containers, volumes and images"
	@echo ""
	@echo Testing:
	@echo "  make test         - Run E2E tests (CI mode, streaming output)"
	@echo "  make test-verbose - Run tests with detailed setup/diagnostic output"
	@echo "  make test-llm     - Run tests with structured JSONL output (for AI agents)"
	@echo "  make test-web     - Run tests with web UI (opens browser with live results)"
	@echo "  make test-web-report - Run tests with web UI + static report generation"
	@echo "  make test-unit    - Run unit tests (no Docker, no Steam)"
	@echo "  make og-preview   - Render OG link-preview card mockups for design review"
	@echo "  FILTER=X          - Filter tests, e.g. FILTER=PasswordProtection"
	@echo "  VERBOSE=1         - Show detailed setup steps, e.g. make test VERBOSE=1"
	@echo ""
	@echo "  make build-test-client - Build test client container image (for E2E tests)"
	@echo ""
	@echo Formatting:
	@echo "  make lint-check - Verify C# + JS/TS style rules + formatting (slow, builds)"
	@echo "  make lint-fix   - Auto-fix C# + JS/TS style violations + re-format (slow, builds)"
	@echo ""
	@echo Test Observability:
	@echo "  make test-summary  - Show test run summary (failures, timing)"
	@echo "  make test-events   - Show per-test events (TEST=Class.Method)"
	@echo "  make test-infra-log - Show infrastructure lifecycle log"
	@echo "  make test-metadata - Show run metadata (git, env, runtime)"
	@echo "  make test-flaky    - Show flakiness data across recent runs"
	@echo "  make test-slowest  - Rank tests by runtime (SORT=total|p50|p90|max) to find suite-shortening targets"
	@echo "  make test-diagnose - Show last failure_context events for triage"
	@echo "  make test-container-log - Show full container log (Usage: CONTAINER=server-0)"
	@echo ""
	@echo Note: Use GitHub Actions for building and pushing release images

.DEFAULT_GOAL := help