- Add github.com/google/uuid to dependencies list - Fix version bumping: both main.go and flake.nix need updates - Add section on updating vendorHash when dependencies change - Use nix run .#default instead of nix build for verification Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
131 lines
4.5 KiB
Markdown
131 lines
4.5 KiB
Markdown
# CLAUDE.md
|
|
|
|
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
|
|
## Project Overview
|
|
|
|
homelab-deploy is a message-based deployment system for NixOS configurations using NATS for messaging. The binary operates in three modes:
|
|
|
|
1. **Listener mode** - Runs on NixOS hosts as a systemd service, subscribes to NATS subjects, executes `nixos-rebuild` on deployment requests
|
|
2. **MCP mode** - MCP server exposing deployment tools for AI assistants
|
|
3. **CLI mode** - Manual deployment commands for administrators
|
|
|
|
## Architecture
|
|
|
|
### NATS Subject Structure
|
|
|
|
Default subjects follow `deploy.<tier>.<target>`, but are configurable via template variables:
|
|
- `deploy.<tier>.<hostname>` - Deploy to specific host
|
|
- `deploy.<tier>.all` - Deploy to all hosts in tier
|
|
- `deploy.<tier>.role.<role>` - Deploy to hosts with role in tier
|
|
- `deploy.responses.<uuid>` - Response subject for request/reply
|
|
- `deploy.discover` - Host discovery subject
|
|
|
|
Template variables: `<hostname>`, `<tier>`, `<role>` - expanded at listener startup.
|
|
|
|
### Package Structure
|
|
|
|
```
|
|
cmd/homelab-deploy/main.go # CLI entrypoint with urfave/cli/v3 subcommands
|
|
internal/messages/ # Shared message types (request, response, enums)
|
|
internal/nats/ # NATS client wrapper with NKey auth
|
|
internal/deploy/ # Deployment execution logic (nixos-rebuild, lock)
|
|
internal/listener/ # Listener mode (NATS subscription, request handling)
|
|
internal/cli/ # CLI deploy command logic and subject aliases
|
|
internal/mcp/ # MCP server mode
|
|
nixos/module.nix # NixOS module for listener service
|
|
```
|
|
|
|
### Key Design Patterns
|
|
|
|
- **Request/Reply over NATS**: Deployer sends request with unique `reply_to` subject, listener responds with status updates
|
|
- **NKey authentication**: All NATS connections use ed25519 NKey authentication
|
|
- **Concurrency control**: Only one deployment per host at a time (in-memory lock)
|
|
- **Tiered access**: MCP has separate credentials for test-tier vs admin (all tiers) access
|
|
|
|
### Message Formats
|
|
|
|
Request: `{"action": "switch|boot|test|dry-activate", "revision": "<branch-or-commit>", "reply_to": "<subject>"}`
|
|
|
|
Response: `{"hostname": "<name>", "status": "accepted|rejected|started|completed|failed", "error": "<code>|null", "message": "<details>"}`
|
|
|
|
## Dependencies
|
|
|
|
Key Go libraries:
|
|
- `github.com/urfave/cli/v3` - CLI framework
|
|
- `github.com/nats-io/nats.go` - NATS client
|
|
- `github.com/nats-io/nkeys` - NKey authentication
|
|
- `github.com/mark3labs/mcp-go` - MCP server implementation
|
|
- `github.com/google/uuid` - UUID generation for reply subjects
|
|
|
|
## Build Commands
|
|
|
|
Run commands through the Nix development shell using `nix develop -c`:
|
|
|
|
```bash
|
|
# Build (for quick syntax checking)
|
|
nix develop -c go build ./...
|
|
|
|
# Run tests
|
|
nix develop -c go test ./...
|
|
|
|
# Run single test
|
|
nix develop -c go test -run TestName ./path/to/package
|
|
|
|
# Lint
|
|
nix develop -c golangci-lint run
|
|
|
|
# Vulnerability check
|
|
nix develop -c govulncheck ./...
|
|
|
|
# Run the binary (preferred method - builds and runs via Nix)
|
|
# To pass arguments, use -- before them: nix run .#default -- --help
|
|
nix run .#default
|
|
```
|
|
|
|
## Testing Procedures
|
|
|
|
Before committing, run the following checks:
|
|
|
|
1. `nix develop -c go test ./...` - Unit tests
|
|
2. `nix develop -c golangci-lint run` - Linting
|
|
3. `nix develop -c govulncheck ./...` - Vulnerability scanning
|
|
4. `nix run .#default -- --version` - Verify nix build works
|
|
|
|
## Commit Message Format
|
|
|
|
Use conventional commit format:
|
|
|
|
```
|
|
feat: add new feature
|
|
fix: fix a bug
|
|
docs: update documentation
|
|
refactor: refactor code without changing behavior
|
|
test: add or update tests
|
|
chore: maintenance tasks
|
|
```
|
|
|
|
## Version Bumping
|
|
|
|
Follow semantic versioning:
|
|
|
|
- **Patch** (0.0.x): Bugfixes
|
|
- **Minor** (0.x.0): Non-breaking changes adding features
|
|
- **Major** (x.0.0): Breaking changes
|
|
|
|
Update the version in **both** locations:
|
|
1. `const version` in `cmd/homelab-deploy/main.go`
|
|
2. `version` field in `flake.nix`
|
|
|
|
**When to bump**: If any Go code has changed, bump the version before committing. Do this automatically when asked to commit. On feature branches, only bump once per branch (check if version has already been bumped compared to master).
|
|
|
|
## Updating Dependencies
|
|
|
|
When adding or updating Go dependencies:
|
|
|
|
1. Run `go get <package>` or `go mod tidy`
|
|
2. Update `vendorHash` in `flake.nix`:
|
|
- Set to a fake hash: `vendorHash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=";`
|
|
- Run `nix run .#default -- --version` - the error will show the correct hash
|
|
- Replace with the correct hash from the error message
|