version: '3' vars: GOCMD: go BINARY_NAME: reticulum-go BUILD_DIR: bin MAIN_PACKAGE: ./cmd/reticulum-go tasks: default: desc: Show available tasks cmds: - task --list all: desc: Clean, download dependencies, build and test deps: [clean, deps, build, test] build: desc: Build release binary (no debug symbols, static) env: CGO_ENABLED: '0' cmds: - mkdir -p {{.BUILD_DIR}} - '{{.GOCMD}} build -ldflags="-s -w" -o {{.BUILD_DIR}}/{{.BINARY_NAME}} {{.MAIN_PACKAGE}}' debug: desc: Build debug binary cmds: - mkdir -p {{.BUILD_DIR}} - '{{.GOCMD}} build -o {{.BUILD_DIR}}/{{.BINARY_NAME}} {{.MAIN_PACKAGE}}' build-experimental: desc: Build binary with experimental features (GOEXPERIMENT=greenteagc) env: GOEXPERIMENT: greenteagc cmds: - mkdir -p {{.BUILD_DIR}} - '{{.GOCMD}} build -o {{.BUILD_DIR}}/{{.BINARY_NAME}}-experimental {{.MAIN_PACKAGE}}' experimental: desc: Alias for build-experimental cmds: - task: build-experimental release: desc: Build stripped static binary for release (alias for build) cmds: - task: build fmt: desc: Format Go code cmds: - '{{.GOCMD}} fmt ./...' fmt-check: desc: Check if code is formatted (useful for CI) cmds: - '{{.GOCMD}} fmt -d ./... > fmt.diff 2>&1 || true' - 'test -s fmt.diff && (echo "Code is not formatted. Run ''task fmt'' to fix." && cat fmt.diff && rm -f fmt.diff && exit 1) || (rm -f fmt.diff && exit 0)' vet: desc: Run go vet cmds: - '{{.GOCMD}} vet ./...' lint: desc: Run revive linter cmds: - revive -config revive.toml -formatter friendly ./pkg/* ./cmd/* ./internal/* scan: desc: Run gosec security scanner cmds: - gosec ./... check: desc: Run fmt-check, vet, lint, test-short, and scan deps: [fmt-check, vet, lint, test-short, scan] bench: desc: Run benchmarks with standard GC cmds: - '{{.GOCMD}} test -bench=. -benchmem ./...' bench-experimental: desc: Run benchmarks with experimental GC env: GOEXPERIMENT: greenteagc cmds: - '{{.GOCMD}} test -bench=. -benchmem ./...' bench-compare: desc: Run benchmarks with both GC settings deps: [bench, bench-experimental] clean: desc: Remove build artifacts cmds: - '{{.GOCMD}} clean' - rm -rf {{.BUILD_DIR}} test: desc: Run tests cmds: - '{{.GOCMD}} test -v ./...' test-short: desc: Run short tests cmds: - '{{.GOCMD}} test -short -v ./...' test-race: desc: Run tests with race detector cmds: - '{{.GOCMD}} test -race -v ./...' coverage: desc: Generate test coverage report cmds: - '{{.GOCMD}} test -coverprofile=coverage.out ./...' - '{{.GOCMD}} tool cover -html=coverage.out' deps: desc: Download and verify dependencies env: GOPROXY: '{{.GOPROXY | default "https://proxy.golang.org,direct"}}' cmds: - '{{.GOCMD}} mod download' - '{{.GOCMD}} mod verify' mod-tidy: desc: Tidy go.mod file cmds: - '{{.GOCMD}} mod tidy' mod-verify: desc: Verify dependencies cmds: - '{{.GOCMD}} mod verify' build-linux: desc: Build for Linux (amd64, arm64, arm, riscv64) env: CGO_ENABLED: '0' cmds: - mkdir -p {{.BUILD_DIR}} - 'GOOS=linux GOARCH=amd64 {{.GOCMD}} build -o {{.BUILD_DIR}}/{{.BINARY_NAME}}-linux-amd64 {{.MAIN_PACKAGE}}' - 'GOOS=linux GOARCH=arm64 {{.GOCMD}} build -o {{.BUILD_DIR}}/{{.BINARY_NAME}}-linux-arm64 {{.MAIN_PACKAGE}}' - 'GOOS=linux GOARCH=arm {{.GOCMD}} build -o {{.BUILD_DIR}}/{{.BINARY_NAME}}-linux-arm {{.MAIN_PACKAGE}}' - 'GOOS=linux GOARCH=riscv64 {{.GOCMD}} build -o {{.BUILD_DIR}}/{{.BINARY_NAME}}-linux-riscv64 {{.MAIN_PACKAGE}}' build-all: desc: Build for all Linux architectures deps: [build-linux] run: desc: Run with go run cmds: - '{{.GOCMD}} run {{.MAIN_PACKAGE}}' tinygo-build: desc: Build binary with TinyGo compiler cmds: - mkdir -p {{.BUILD_DIR}} - tinygo build -o {{.BUILD_DIR}}/{{.BINARY_NAME}}-tinygo -size short {{.MAIN_PACKAGE}} tinygo-wasm: desc: Build WebAssembly binary with TinyGo compiler cmds: - mkdir -p {{.BUILD_DIR}} - tinygo build -target wasm -o {{.BUILD_DIR}}/{{.BINARY_NAME}}.wasm ./cmd/reticulum-wasm test-wasm: desc: Run WebAssembly tests using Node.js vars: WASM_BIN_PATH: sh: pwd env: GOOS: js GOARCH: wasm cmds: - PATH="$PATH:{{.WASM_BIN_PATH}}/misc/wasm" {{.GOCMD}} test -v ./pkg/wasm/ ./cmd/reticulum-wasm/ build-wasm: desc: Build WebAssembly binary with standard Go compiler env: CGO_ENABLED: '0' GOOS: js GOARCH: wasm cmds: - mkdir -p {{.BUILD_DIR}} - '{{.GOCMD}} build -ldflags="-s -w" -o {{.BUILD_DIR}}/{{.BINARY_NAME}}.wasm ./cmd/reticulum-wasm' build-wasm-example: desc: Build WebAssembly example env: CGO_ENABLED: '0' cmds: - mkdir -p examples/wasm/public/static - 'cd examples/wasm && GOOS=js GOARCH=wasm {{.GOCMD}} build -o public/static/reticulum-go.wasm .' - | GOROOT=$({{.GOCMD}} env GOROOT) if [ -f "$GOROOT/lib/wasm/wasm_exec.js" ]; then cp "$GOROOT/lib/wasm/wasm_exec.js" examples/wasm/public/js/ echo "wasm_exec.js copied successfully from $GOROOT/lib/wasm/" elif [ -f "$GOROOT/misc/wasm/wasm_exec.js" ]; then cp "$GOROOT/misc/wasm/wasm_exec.js" examples/wasm/public/js/ echo "wasm_exec.js copied successfully from $GOROOT/misc/wasm/" else echo "Warning: wasm_exec.js not found" exit 1 fi install: desc: Install dependencies cmds: - '{{.GOCMD}} mod download' checksum: desc: Generate SHA256 checksum for binary (uses BINARY_PATH env var if set, otherwise defaults to bin/reticulum-go) cmds: - | BINARY_PATH="${BINARY_PATH:-{{.BUILD_DIR}}/{{.BINARY_NAME}}}" if [ -f "$BINARY_PATH" ]; then sha256sum "$BINARY_PATH" > "${BINARY_PATH}.sha256" echo "Generated checksum: ${BINARY_PATH}.sha256" else echo "Error: Binary not found at $BINARY_PATH" exit 1 fi example:announce: desc: Run announce example cmds: - 'cd examples/announce && {{.GOCMD}} run .' example:minimal: desc: Run minimal example cmds: - 'cd examples/minimal && {{.GOCMD}} run .' example:pageserver: desc: Run pageserver example cmds: - 'cd examples/pageserver && {{.GOCMD}} run .' example:echo-listen: desc: Run echo example (waits for incoming connections, P2P peer) cmds: - 'cd examples/echo && {{.GOCMD}} run . --server' example:echo-connect: desc: Run echo example (initiates connection to peer, requires DESTINATION env var) cmds: - | if [ -z "${DESTINATION}" ]; then echo "Error: DESTINATION environment variable required (hexadecimal hash of peer)" echo "Example: DESTINATION=abc123... task example:echo-connect" exit 1 fi cd examples/echo && {{.GOCMD}} run . --destination="${DESTINATION}" example:link-listen: desc: Run link example (waits for incoming link requests, P2P peer) cmds: - 'cd examples/link && {{.GOCMD}} run . --server' example:link-connect: desc: Run link example (initiates link to peer, requires DESTINATION env var) cmds: - | if [ -z "${DESTINATION}" ]; then echo "Error: DESTINATION environment variable required (hexadecimal hash of peer)" echo "Example: DESTINATION=abc123... task example:link-connect" exit 1 fi cd examples/link && {{.GOCMD}} run . --destination="${DESTINATION}" example:filetransfer-share: desc: Run filetransfer example (shares files from directory, P2P peer) cmds: - | if [ -z "${SERVE_PATH}" ]; then echo "Error: SERVE_PATH environment variable required (directory to share)" echo "Example: SERVE_PATH=/path/to/files task example:filetransfer-share" exit 1 fi cd examples/filetransfer && {{.GOCMD}} run . --server --serve="${SERVE_PATH}" example:filetransfer-fetch: desc: Run filetransfer example (fetches files from peer, requires DESTINATION env var) cmds: - | if [ -z "${DESTINATION}" ]; then echo "Error: DESTINATION environment variable required (hexadecimal hash of peer)" echo "Example: DESTINATION=abc123... task example:filetransfer-fetch" exit 1 fi cd examples/filetransfer && {{.GOCMD}} run . --destination="${DESTINATION}" trivy:install: desc: Install Trivy scanner cmds: - | if ! command -v trivy &> /dev/null; then curl -L -o /tmp/trivy.deb https://git.quad4.io/Quad4-Extra/assets/raw/commit/90fdcea1bb71d91df2de6ff2e3897f278413f300/bin/trivy_0.68.2_Linux-64bit.deb sudo dpkg -i /tmp/trivy.deb || sudo apt-get install -f -y else echo "Trivy is already installed: $(trivy --version)" fi trivy:scan: desc: Run Trivy vulnerability scan cmds: - | if ! command -v trivy &> /dev/null; then echo "Error: Trivy not found. Run 'task trivy:install' first." exit 1 fi trivy fs --scanners vuln --severity HIGH,CRITICAL --timeout 90m . trivy:scan-all: desc: Run Trivy full scan (vulnerabilities, secrets, misconfig) cmds: - | if ! command -v trivy &> /dev/null; then echo "Error: Trivy not found. Run 'task trivy:install' first." exit 1 fi trivy fs --scanners vuln,secret,misconfig . sbom: desc: Generate SBOM files (SPDX and CycloneDX formats) cmds: - | if ! command -v trivy &> /dev/null; then echo "Error: Trivy not found. Run 'task trivy:install' first." exit 1 fi mkdir -p sbom trivy fs --format spdx-json --include-dev-deps --output sbom/sbom.spdx.json . trivy fs --format cyclonedx --include-dev-deps --output sbom/sbom.cyclonedx.json . echo "SBOM files generated in sbom/ directory" sbom:spdx: desc: Generate SPDX JSON SBOM cmds: - | if ! command -v trivy &> /dev/null; then echo "Error: Trivy not found. Run 'task trivy:install' first." exit 1 fi mkdir -p sbom trivy fs --format spdx-json --include-dev-deps --output sbom/sbom.spdx.json . echo "SPDX SBOM generated: sbom/sbom.spdx.json" sbom:cyclonedx: desc: Generate CycloneDX SBOM cmds: - | if ! command -v trivy &> /dev/null; then echo "Error: Trivy not found. Run 'task trivy:install' first." exit 1 fi mkdir -p sbom trivy fs --format cyclonedx --include-dev-deps --output sbom/sbom.cyclonedx.json . echo "CycloneDX SBOM generated: sbom/sbom.cyclonedx.json" trivy:scan:json: desc: Run Trivy vulnerability scan with JSON output cmds: - | if ! command -v trivy &> /dev/null; then echo "Error: Trivy not found. Run 'task trivy:install' first." exit 1 fi mkdir -p reports trivy fs --scanners vuln --format json --output reports/trivy-vuln.json --timeout 90m . trivy:scan:sarif: desc: Run Trivy scan with SARIF output (for GitHub/GitLab integration) cmds: - | if ! command -v trivy &> /dev/null; then echo "Error: Trivy not found. Run 'task trivy:install' first." exit 1 fi mkdir -p reports trivy fs --scanners vuln,secret --format sarif --output reports/trivy.sarif --timeout 90m . trivy:scan:secrets: desc: Scan for hardcoded secrets cmds: - | if ! command -v trivy &> /dev/null; then echo "Error: Trivy not found. Run 'task trivy:install' first." exit 1 fi trivy fs --scanners secret . trivy:scan:licenses: desc: Scan for licenses in dependencies cmds: - | if ! command -v trivy &> /dev/null; then echo "Error: Trivy not found. Run 'task trivy:install' first." exit 1 fi trivy fs --scanners license . trivy:scan:misconfig: desc: Scan for misconfigurations in config files cmds: - | if ! command -v trivy &> /dev/null; then echo "Error: Trivy not found. Run 'task trivy:install' first." exit 1 fi trivy fs --scanners misconfig . trivy:db-update: desc: Update Trivy vulnerability database cmds: - | if ! command -v trivy &> /dev/null; then echo "Error: Trivy not found. Run 'task trivy:install' first." exit 1 fi trivy image --download-db-only trivy:cache-clean: desc: Clean Trivy cache cmds: - | if ! command -v trivy &> /dev/null; then echo "Error: Trivy not found. Run 'task trivy:install' first." exit 1 fi trivy clean --cache trivy:compliance: desc: "Generate compliance report (specify COMPLIANCE env var: docker-bench-cis, k8s-nsa, etc.)" cmds: - | if ! command -v trivy &> /dev/null; then echo "Error: Trivy not found. Run 'task trivy:install' first." exit 1 fi if [ -z "${COMPLIANCE}" ]; then echo "Error: COMPLIANCE environment variable required" echo "Example: COMPLIANCE=docker-bench-cis task trivy:compliance" exit 1 fi mkdir -p reports trivy fs --compliance "${COMPLIANCE}" --format json --output "reports/compliance-${COMPLIANCE}.json" . trivy:ci: desc: Run Trivy scan for CI (exits with non-zero code on findings) cmds: - | if ! command -v trivy &> /dev/null; then echo "Error: Trivy not found. Run 'task trivy:install' first." exit 1 fi trivy fs --scanners vuln --severity HIGH,CRITICAL --exit-code 1 --timeout 90m . docker:build: desc: Build Docker image (runtime image) vars: IMAGE_NAME: reticulum-go IMAGE_TAG: latest cmds: - docker build -f docker/Dockerfile -t {{.IMAGE_NAME}}:{{.IMAGE_TAG}} . docker:build:tag: desc: Build Docker image with custom tag (use IMAGE_TAG env var) vars: IMAGE_NAME: reticulum-go IMAGE_TAG: ${IMAGE_TAG:-latest} cmds: - docker build -f docker/Dockerfile -t {{.IMAGE_NAME}}:{{.IMAGE_TAG}} . docker:build:build: desc: Build Docker image for building binaries only vars: IMAGE_NAME: reticulum-go-build IMAGE_TAG: latest cmds: - docker build -f docker/Dockerfile.build -t {{.IMAGE_NAME}}:{{.IMAGE_TAG}} . docker:run: desc: Run Docker container (runtime image) vars: IMAGE_NAME: reticulum-go IMAGE_TAG: latest CONTAINER_NAME: reticulum-go cmds: - | docker run --rm -it \ --name {{.CONTAINER_NAME}} \ -p 4242:4242 \ {{.IMAGE_NAME}}:{{.IMAGE_TAG}} docker:run:detached: desc: Run Docker container in detached mode vars: IMAGE_NAME: reticulum-go IMAGE_TAG: latest CONTAINER_NAME: reticulum-go cmds: - | docker run -d \ --name {{.CONTAINER_NAME}} \ -p 4242:4242 \ {{.IMAGE_NAME}}:{{.IMAGE_TAG}} docker:stop: desc: Stop running Docker container vars: CONTAINER_NAME: reticulum-go cmds: - docker stop {{.CONTAINER_NAME}} || true - docker rm {{.CONTAINER_NAME}} || true docker:extract: desc: Extract binary from build container vars: IMAGE_NAME: reticulum-go-build IMAGE_TAG: latest BINARY_NAME: reticulum-go cmds: - | CONTAINER_ID=$(docker create {{.IMAGE_NAME}}:{{.IMAGE_TAG}}) docker cp $CONTAINER_ID:/dist/{{.BINARY_NAME}} {{.BUILD_DIR}}/{{.BINARY_NAME}} docker rm $CONTAINER_ID echo "Binary extracted to {{.BUILD_DIR}}/{{.BINARY_NAME}}" docker:buildx:setup: desc: Setup Docker buildx for multi-platform builds cmds: - docker buildx create --name reticulum-builder --use || docker buildx use reticulum-builder - docker buildx inspect --bootstrap docker:buildx:build: desc: Build multi-platform Docker image vars: IMAGE_NAME: reticulum-go IMAGE_TAG: latest PLATFORMS: linux/amd64,linux/arm64,linux/arm/v7 cmds: - | docker buildx build \ --platform {{.PLATFORMS}} \ -f docker/Dockerfile \ -t {{.IMAGE_NAME}}:{{.IMAGE_TAG}} \ --load \ . docker:buildx:build:push: desc: Build and push multi-platform Docker image vars: IMAGE_NAME: reticulum-go IMAGE_TAG: latest PLATFORMS: linux/amd64,linux/arm64,linux/arm/v7 cmds: - | if [ -z "${DOCKER_REGISTRY}" ]; then echo "Error: DOCKER_REGISTRY environment variable required" echo "Example: DOCKER_REGISTRY=registry.example.com task docker:buildx:build:push" exit 1 fi docker buildx build \ --platform {{.PLATFORMS}} \ -f docker/Dockerfile \ -t ${DOCKER_REGISTRY}/{{.IMAGE_NAME}}:{{.IMAGE_TAG}} \ --push \ . docker:clean: desc: Clean Docker images and containers cmds: - docker stop reticulum-go || true - docker rm reticulum-go || true - docker rmi reticulum-go:latest || true - docker rmi reticulum-go-build:latest || true