Development
Development
Setup
mise manages every tool (Go, golangci-lint, goreleaser, helm, hugo, …) at pinned versions, every task and the git hooks:
git clone https://git.bitfoo.de/dvonessen/forgemirror.git && cd forgemirror
mise install # tools; also points core.hooksPath at .githooks
mise tasks # list all tasks| Task | Purpose |
|---|---|
mise run check | Full gate: fmt, tidy, vet, lint, tests (race, ≥ 80 % coverage), govulncheck, manifests, chart, docs |
mise run fmt | Format (gofumpt, goimports, golines) |
mise run test -- -run Name | Run selected tests |
mise run run -- <args> | Run the service from source |
mise run build | Build bin/forgemirror |
mise run snapshot | Full goreleaser build without publishing |
mise run docs:serve | Live preview of this documentation |
The pre-push hook validates commit messages and runs mise run check.
CI runs exactly the same tasks, so a green push predicts a green pipeline.
Layout
| Path | Content |
|---|---|
cmd/forgemirror/ | main only: signals and exit code |
internal/app | CLI and wiring |
internal/config | Layered configuration, secrets, validation |
internal/webhook | Signature check, payload parsing, filter decision |
internal/filter | Mirror rules |
internal/dispatch | Background runs: coalescing, fan-out, concurrency limit |
internal/mirror | git clone and push with injected credentials |
internal/server | HTTP routing, health, graceful shutdown |
internal/telemetry | OpenTelemetry metrics and Prometheus exporter |
deploy/, charts/ | kustomize manifests, Helm chart |
docs/ | This site (Hugo + Hextra) |
Conventions
- Go: modern idioms for the pinned Go version. There is no package-level
mutable state,
context.Contextcomes first, and errors are wrapped with%w. - Tests: table-driven and parallel, with fakes instead of real networks
or remotes. Real git is used only in the integration tests of
internal/mirror. - Comments: explain why, not what.
- Commits: Conventional Commits
with gitmoji, for example
feat(webhook): :sparkles: accept organization hooks. This is enforced by thecommit-msghook, thepre-pushhook and CI. Commit types determine the next version; see CI/CD and releases.
Documentation
The site lives in docs/:
- Content:
docs/content/. - Configuration:
docs/hugo.yaml, which also holds the project URLs used across the pages. - Repository files: reference pages embed files such as
forgemirror.example.yamland the chart’svalues.yamlstraight from the repository with therepo-fileshortcode, so they cannot drift.
mise run docs:serve # http://localhost:1313
mise run docs:check # strict build, as in CILast updated on