Files
OpenShell/tasks/go.toml
Roland HussandDrew Newberry 8dc55e21ee feat(sdk/go): complete Go SDK with domain clients, auth, and hardening (#2702)
* feat(sdk/go): complete Go SDK with domain clients, auth, and hardening

Add the Go SDK implementation covering all gateway RPC services with
domain-typed clients, comprehensive OIDC authentication flows, fake
test doubles, and proto converters.

Domain clients: Sandbox, Provider, Exec, File, TCP, SSH, Policy,
Profile, Health, Service, Config, Workspace, Inference, Refresh.
Each client validates inputs, resolves sandboxes by name, and converts
between domain types and proto at the boundary.

Auth: OIDC authorization code (PKCE), device code (RFC 8628), and
client credentials (RFC 6749 Section 4.4) flows with gateway config
auto-resolution. Token refresh with singleflight deduplication and
exponential backoff. Edge tunnel proxy for gRPC-over-WebSocket.

Gateway: On-disk gateway discovery with user/system directory
precedence, lazy token loading, and auth mode mapping.

Testing: In-memory fake client with deep-copy isolation, watch
broadcasting with filtering, and workspace-scoped object stores.
Bufconn-based gRPC tests for all domain clients.

Ref: #2044

Signed-off-by: Roland Huß <rhuss@redhat.com>

* feat(sdk/go): add gateway client options for logger, timeout, and retry

Add WithLogger, WithTimeout, and WithRetryPolicy options to the gateway
package's NewClient function. These forward the corresponding Config
fields (Logger, Timeout, RetryPolicy) through to the underlying SDK
client, giving callers full control over observability, connection
timeouts, and retry behavior when constructing clients from on-disk
gateway configurations.

Also adds RetryPolicy type to types package and extends Config with the
three new fields.

* fix(mise): sync sccache lock entry

Signed-off-by: Drew Newberry <anewberry@nvidia.com>

---------

Signed-off-by: Roland Huß <rhuss@redhat.com>
Signed-off-by: Drew Newberry <anewberry@nvidia.com>
Co-authored-by: Drew Newberry <anewberry@nvidia.com>
2026-08-13 19:15:21 +00:00

181 lines
4.6 KiB
TOML

# 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 = "go test -coverprofile=coverage.out -coverpkg=./openshell/... -race ./..."
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/<pkg>.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
# 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 "$SDK_ROOT/buf.gen.yaml")
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
CHECK_TEMPLATE=$(sed 's|out: sdk/go|out: '"$WORK_DIR"'|' buf.gen.yaml)
(cd "$REPO_ROOT" && buf generate --template "$CHECK_TEMPLATE")
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