- Go 1.25.1+ (see
go.modfor exact version) - goreleaser (for builds and releases)
- gocover-cobertura (for coverage reports)
Install build dependencies:
make depmain.go # CLI entrypoint (server + client subcommands)
client/ # Client package
server/ # Server package
share/ # Shared libraries
ccrypto/ # Cryptographic utilities (key generation, SSH keys)
cio/ # I/O helpers (logging, pipes, stdio)
cnet/ # Networking (WebSocket connections, HTTP server, metering)
cos/ # OS utilities (signals, pprof)
settings/ # Configuration (remotes, users, environment)
tunnel/ # Tunnel implementation (TCP/UDP proxying)
test/
e2e/ # End-to-end tests (auth, TLS, SOCKS, UDP, proxy)
bench/ # Benchmarks
example/ # Example config files (users.json, deployment configs)
Build for the current platform:
make allCross-compile for a specific OS:
make linux
make darwin
make windows
make freebsdBuild a Docker image:
make dockerUnit tests (excludes the test/ package):
make testThis runs tests with race detection, generates a coverage report in ./build/, and produces a Cobertura XML for CI.
Run all tests directly (including e2e):
go test ./...Run only e2e tests:
go test ./test/e2e/Format and vet the code:
make lintThis runs go fmt and go vet across all packages (excluding test/).
- Standard Go formatting (
go fmt) - No external linting tools beyond
go vet - Tests use the
_testpackage suffix for e2e tests (e.g.,package e2e_test) - Unit tests live alongside their source files (e.g.,
client/client_test.go) - E2e tests use a shared
testLayoutsetup helper intest/e2e/setup_test.go
Releases are handled via goreleaser. The configuration lives in two places:
.github/goreleaser.yml-- upstream multi-platform release configgoreleaser.yml-- OutSystems-specific config (Linux only, with Docker image toghcr.io)
To do a dry-run release:
goreleaser release --config .github/goreleaser.yml --clean --snapshotTo create an actual release:
make releaseThis runs lint, tests, and then goreleaser release.
- Fork or branch from
master - Keep changes focused -- one concern per PR
- Run
make lintandmake testbefore pushing - Ensure your changes compile across platforms (
CGO_ENABLED=0is used for most builds) - Add or update tests for new functionality, especially in
test/e2e/for tunnel behavior changes - Dependabot manages dependency updates on a monthly cycle -- don't batch unrelated dep bumps with feature work