VayuPress Development Guide
Goal
A new developer should be able to run make dev in under 10 minutes and make their first change.
Prerequisites
- Go 1.23+ (CI & deploy build with the latest stable Go, currently 1.25.x)
- SQLite3 (
apt install sqlite3) - (Optional) Meilisearch for full-text search testing
Quick Start
git clone https://github.com/johalputt/vayupress.git
cd vayupress
# Set required environment variables
export API_KEY=dev-secret-key
export DB_PATH=/tmp/vayupress-dev.db
export CACHE_DIR=/tmp/vayupress-cache
export DOMAIN=localhost
export PORT=8080
# Create cache directory
mkdir -p /tmp/vayupress-cache
# Run the application (P13: real Go package)
go run ./cmd/vayupress
# or:
make dev
The server starts at http://localhost:8080.
Source Model (P13)
The canonical Go source lives embedded in scripts/deploy-vayupress.sh (the
heredoc between cat > main.go << 'GOEOF' and GOEOF). This keeps the
curl -sSL ... | bash installer self-contained.
That exact source is mirrored to cmd/vayupress/main.go so you get full Go tooling.
The deploy script is canonical — if you change the embedded source, regenerate the
mirror and commit both:
# After editing the heredoc in scripts/deploy-vayupress.sh:
make sync # regenerate cmd/vayupress/main.go
make sync-check # verify parity (this is what CI runs)
CI's P13 · Source Sync job fails the build if the two ever drift. The canonical
source must stay gofmt-clean (CI's go-native job enforces gofmt -l).
See ADR-0044.
Development Workflow
# Run tests
go test ./... -v
# Run tests with race detector (mandatory before PR)
go test -race ./...
# Run linter
golangci-lint run
# Run vulnerability scan
govulncheck ./...
# Build binary
go build -o vayupress main.go
# Check binary size (must be <45 MB compressed)
gzip -c vayupress | wc -c
Environment Variables for Development
export API_KEY=dev-secret-key
export DB_PATH=/tmp/vayupress-dev.db
export CACHE_DIR=/tmp/vayupress-cache
export DOMAIN=localhost
export PORT=8080
export MEILI_HOST=http://localhost:7700 # optional
export VAYU_MAINTENANCE=false
export VAYU_MIGRATE_DRY_RUN=false # set true to preview migrations
Making a Change
- Create a branch:
git checkout -b feat/my-change - Make your change.
- Add/update tests.
- Run
go test -race ./...— must pass. - Run
golangci-lint run— must pass. - Update
CHANGELOG.md. - Update docs if you changed behavior.
- Sign your commit:
git commit -s -m "feat: description" - Open a PR.
Architecture Overview
See ARCHITECTURE.md for diagrams and component descriptions.
Key constraints for development:
- SQLite-first: every feature must work without Meilisearch.
- No heavy frontend: public paths use HTMX + Alpine.js only.
- No new dependencies without RFC approval.
- No breaking API changes without a MAJOR version bump.
Test Requirements
| Test Type | Command | Threshold |
|---|---|---|
| Unit tests | go test ./... |
Coverage ≥ 70% |
| Race detector | go test -race ./... |
Zero races |
| Integration | go test -tags integration ./... |
Must exist |
| Linting | golangci-lint run |
Zero errors |
| Vulnerability | govulncheck ./... |
No High/Critical CVEs |
Debugging
# Inspect write queue
curl -H "Authorization: Bearer $API_KEY" http://localhost:8080/admin/queue
# Check health
curl http://localhost:8080/health/ready
# Prometheus metrics
curl http://localhost:8080/metrics
# pprof (localhost only, rate-limited)
curl http://localhost:6060/debug/pprof/
Common Issues
See TROUBLESHOOTING.md.