# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. # SPDX-License-Identifier: Apache-2.0 # Go SDK development, build, lint, and format tasks ["go:test"] description = "Run Go SDK unit tests with coverage" dir = "sdk/go" run = """ #!/usr/bin/env bash set -euo pipefail if [ "$(go env GOOS)" = "windows" ] && [ "$(go env GOARCH)" = "arm64" ]; then echo "Go race detection is unsupported on windows/arm64; running without -race." go test -coverprofile=coverage.out -coverpkg=./openshell/... ./... else go test -coverprofile=coverage.out -coverpkg=./openshell/... -race ./... fi """ hide = true ["go:test:integration"] description = "Run Go SDK integration tests" dir = "sdk/go" run = "go test -tags=integration -race ./..." hide = true ["go:lint"] description = "Run Go SDK linter" dir = "sdk/go" run = "golangci-lint run ./..." hide = true ["go:fmt"] description = "Format Go SDK code" dir = "sdk/go" run = "goimports -w . && go fmt ./..." hide = true ["go:build"] description = "Build Go SDK packages" dir = "sdk/go" run = "go build ./..." hide = true ["go:format:check"] description = "Verify Go SDK code is gofmt-formatted" dir = "sdk/go" run = """ #!/usr/bin/env bash set -euo pipefail UNFORMATTED=$(gofmt -l . 2>/dev/null || true) if [ -n "$UNFORMATTED" ]; then echo "ERROR: The following files are not gofmt-formatted:" echo "$UNFORMATTED" exit 1 fi """ hide = true ["go:ci"] description = "Run Go SDK full CI pipeline" depends = ["go:format:check", "go:lint", "go:build", "go:test", "go:proto:check", "go:docs:check"] ["go:docs:check"] description = "Verify every public Go SDK package has a docs page" dir = "sdk/go" run = """ #!/usr/bin/env bash set -euo pipefail DOCS_DIR="docs/src/api" SUMMARY="docs/src/SUMMARY.md" MISSING=0 # Find all public packages with a doc.go (excluding internal, proto, types) for docfile in openshell/v1/*/doc.go; do pkg=$(basename "$(dirname "$docfile")") # Skip internal packages and types (no user-facing docs needed) case "$pkg" in internal|types) continue ;; esac # Check for matching docs page if [ ! -f "$DOCS_DIR/$pkg.md" ]; then echo "MISSING: $DOCS_DIR/$pkg.md (package openshell/v1/$pkg has doc.go but no docs page)" MISSING=$((MISSING + 1)) fi # Check for SUMMARY.md entry if ! grep -q "api/$pkg.md" "$SUMMARY" 2>/dev/null; then echo "MISSING: SUMMARY.md entry for api/$pkg.md" MISSING=$((MISSING + 1)) fi done if [ "$MISSING" -gt 0 ]; then echo "" echo "ERROR: $MISSING documentation gaps found." echo "Every public package with doc.go needs a docs/src/api/.md page" echo "and a SUMMARY.md entry. See Constitution XIII." exit 1 fi echo "Docs check passed: all public packages have documentation." """ hide = true ["go:proto:gen"] description = "Generate Go bindings from proto files using buf" dir = "sdk/go" run = """ #!/usr/bin/env bash set -euo pipefail SDK_ROOT=$(pwd -P) REPO_ROOT=$(cd ../.. && pwd -P) for tool in buf protoc-gen-go protoc-gen-go-grpc; do if ! command -v "$tool" &>/dev/null; then echo "ERROR: $tool not found. Run 'mise install' to install it." exit 1 fi done if find proto -maxdepth 1 -name '*.proto' -print -quit | grep -q .; then echo "ERROR: sdk/go/proto must contain generated bindings only." echo "Proto sources belong in the repository root proto/ directory." exit 1 fi BUF_TEMPLATE="$SDK_ROOT/buf.gen.yaml" if command -v cygpath &>/dev/null; then WORK_DIR=$(mktemp -d) trap 'rm -rf "$WORK_DIR"' EXIT GO_PLUGIN=$(cygpath -m "$(command -v protoc-gen-go)") GRPC_PLUGIN=$(cygpath -m "$(command -v protoc-gen-go-grpc)") GO_PLUGIN=${GO_PLUGIN//&/\\&} GRPC_PLUGIN=${GRPC_PLUGIN//&/\\&} sed \ -e "s|local: protoc-gen-go$|local: $GO_PLUGIN|" \ -e "s|local: protoc-gen-go-grpc$|local: $GRPC_PLUGIN|" \ "$SDK_ROOT/buf.gen.yaml" > "$WORK_DIR/buf.gen.yaml" BUF_TEMPLATE="$WORK_DIR/buf.gen.yaml" fi # Clean previous output before regeneration find proto -name '*.pb.go' -delete 2>/dev/null || true find proto -mindepth 1 -type d -empty -delete 2>/dev/null || true (cd "$REPO_ROOT" && buf generate --template "$BUF_TEMPLATE") echo "Proto generation complete." echo "Generated packages:" for pkg_dir in proto/*/; do count=$(find "$pkg_dir" -maxdepth 1 -name '*.go' | wc -l | tr -d ' ') echo " $pkg_dir: $count files" done """ hide = true ["go:proto:check"] description = "Verify generated Go SDK proto files are up to date" dir = "sdk/go" run = """ #!/usr/bin/env bash set -euo pipefail SDK_ROOT=$(pwd -P) REPO_ROOT=$(cd ../.. && pwd -P) for tool in buf protoc-gen-go protoc-gen-go-grpc; do if ! command -v "$tool" &>/dev/null; then echo "ERROR: $tool not found. Run 'mise install' to install it." exit 1 fi done WORK_DIR=$(mktemp -d) trap 'rm -rf "$WORK_DIR"' EXIT if find proto -maxdepth 1 -name '*.proto' -print -quit | grep -q .; then echo "ERROR: sdk/go/proto contains copied proto sources." echo "Proto sources belong in the repository root proto/ directory." exit 1 fi # Generate to temp directory with adjusted output path BUF_OUTPUT_DIR="$WORK_DIR" if command -v cygpath &>/dev/null; then BUF_OUTPUT_DIR=$(cygpath -m "$WORK_DIR") fi sed "s|out: sdk/go|out: $BUF_OUTPUT_DIR|" "$SDK_ROOT/buf.gen.yaml" > "$WORK_DIR/buf.gen.yaml" if command -v cygpath &>/dev/null; then GO_PLUGIN=$(cygpath -m "$(command -v protoc-gen-go)") GRPC_PLUGIN=$(cygpath -m "$(command -v protoc-gen-go-grpc)") GO_PLUGIN=${GO_PLUGIN//&/\\&} GRPC_PLUGIN=${GRPC_PLUGIN//&/\\&} sed \ -e "s|local: protoc-gen-go$|local: $GO_PLUGIN|" \ -e "s|local: protoc-gen-go-grpc$|local: $GRPC_PLUGIN|" \ "$WORK_DIR/buf.gen.yaml" > "$WORK_DIR/buf.gen.windows.yaml" mv "$WORK_DIR/buf.gen.windows.yaml" "$WORK_DIR/buf.gen.yaml" fi (cd "$REPO_ROOT" && buf generate --template "$WORK_DIR/buf.gen.yaml") DIFF_OUTPUT=$(diff -r "$WORK_DIR/proto" "$SDK_ROOT/proto" 2>&1) || true if [ -n "$DIFF_OUTPUT" ]; then echo "ERROR: Generated proto files are out of date." echo "Run 'mise run go:proto:gen' to regenerate." echo "" echo "$DIFF_OUTPUT" exit 1 fi echo "Proto check passed: generated files are up to date." """ hide = true