diff --git a/.github/workflows/branch-checks.yml b/.github/workflows/branch-checks.yml index 7713febb6f..c5081b550d 100644 --- a/.github/workflows/branch-checks.yml +++ b/.github/workflows/branch-checks.yml @@ -190,3 +190,31 @@ jobs: - name: Lint run: mise run markdown:lint + + go: + name: Go + needs: pr_metadata + if: needs.pr_metadata.outputs.should_run == 'true' + runs-on: linux-amd64-cpu8 + container: + image: ghcr.io/nvidia/openshell/ci:latest + credentials: + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + + - name: Install tools + run: mise install --locked + + - name: Lint + run: mise run go:lint + + - name: Build + run: mise run go:build + + - name: Test + run: mise run go:test + + - name: Proto check + run: mise run go:proto:check diff --git a/docs/index.yml b/docs/index.yml index b2443e4afd..fe0d935e17 100644 --- a/docs/index.yml +++ b/docs/index.yml @@ -23,6 +23,20 @@ navigation: title: "Observability" - folder: kubernetes title: "Kubernetes" +- section: "SDKs" + slug: sdks + contents: + - section: "Go SDK" + slug: go + contents: + - page: "Getting Started" + path: sdks/go/getting-started.mdx + - page: "Architecture" + path: sdks/go/architecture.mdx + - page: "Error Handling" + path: sdks/go/error-handling.mdx + - page: "Authentication" + path: sdks/go/authentication.mdx - folder: reference title: "Reference" - folder: security diff --git a/docs/sdks/go/architecture.mdx b/docs/sdks/go/architecture.mdx new file mode 100644 index 0000000000..818b3651bd --- /dev/null +++ b/docs/sdks/go/architecture.mdx @@ -0,0 +1,105 @@ +--- +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +title: "Architecture" +description: "Module structure, gRPC transport layer, and proto isolation pattern in the Go SDK." +keywords: "Go SDK, Architecture, gRPC, Protobuf, Module Structure, Transport" +--- + +The Go SDK follows a layered architecture that keeps protocol details +internal while exposing idiomatic Go types to consumers. + +## Module Structure + +``` +sdk/go/ +├── openshell/v1/ # Public API surface +│ ├── client.go # Top-level Client with sub-clients +│ ├── gateway/ # Gateway client factory (reads CLI config) +│ ├── edge/ # Edge API client +│ ├── fake/ # In-memory fakes for testing +│ ├── types/ # Domain types (Config, errors, options) +│ ├── oidc/ # OIDC authentication +│ └── internal/ # Internal helpers (not importable) +│ ├── converter/ # Proto-to-SDK type conversion +│ └── grpc/ # gRPC connection management +└── proto/ # Proto definitions + generated code + ├── openshellv1/ # Generated .pb.go files + ├── datamodelv1/ + └── sandboxv1/ +``` + +## Transport Layer + +The SDK communicates with the OpenShell gateway over gRPC. The transport +is fully internal, and consumers interact only with Go types. + +``` +Consumer Code + │ + ▼ +openshell/v1.Client ← Public API (Go types) + │ + ▼ +internal/converter ← Proto ↔ SDK type conversion + │ + ▼ +internal/grpc ← Connection management, TLS, auth + │ + ▼ +gRPC transport ← Wire protocol +``` + +## Proto Isolation + +Generated protobuf types live in `proto/` packages and are never exposed +through the public API. The `internal/converter` package handles all +translation between proto messages and SDK domain types. + +This means: + +- Consumers never import `proto/` packages directly. +- Proto schema changes do not break the public API. +- Deep copies happen at the boundary, so returned values are safe to mutate. + +## Sub-Clients + +The top-level `Client` provides access to domain-specific sub-clients: + +| Method | Returns | Purpose | +|--------|---------|---------| +| `Sandboxes()` | `SandboxInterface` | Create, list, get, delete sandboxes | +| `Providers()` | `ProviderInterface` | List and inspect compute providers | +| `Services()` | `ServiceInterface` | Manage sandbox services | +| `Exec()` | `ExecInterface` | Execute commands in sandboxes | +| `Files()` | `FileInterface` | Upload and download files | +| `Health()` | `HealthInterface` | Gateway health checks | +| `SSH()` | `SSHInterface` | SSH tunnel management | +| `TCP()` | `TCPInterface` | TCP port forwarding | +| `Config()` | `ConfigInterface` | Sandbox configuration management | +| `Policy()` | `PolicyInterface` | Network policy management | + +## Client Construction + +There are two ways to create a client: + +**From gateway configuration** (reads `~/.config/openshell/`): + +```go +client, err := gateway.NewClient("my-gateway") +``` + +**From explicit configuration**: + +```go +client, err := v1.NewClient(types.Config{ + Address: "localhost:8080", + Auth: myAuthProvider, +}) +``` + +## Concurrency + +All client methods are safe for concurrent use. The underlying gRPC +connection handles multiplexing. Call `client.Close()` when done to +release resources. diff --git a/docs/sdks/go/authentication.mdx b/docs/sdks/go/authentication.mdx new file mode 100644 index 0000000000..1440cbf5ab --- /dev/null +++ b/docs/sdks/go/authentication.mdx @@ -0,0 +1,97 @@ +--- +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +title: "Authentication" +description: "OIDC authentication, token refresh, and gateway auth configuration for the Go SDK." +keywords: "Go SDK, Authentication, OIDC, Token Refresh, TLS, Security" +--- + +The Go SDK supports multiple authentication modes depending on how the +gateway is configured. The gateway client reads auth settings from the +CLI configuration automatically. + +## Authentication Modes + +| Mode | When to Use | Configuration | +|------|-------------|---------------| +| **OIDC** | Production gateways with identity provider | `openshell gateway auth` configures tokens | +| **API Key** | Simple deployments, development | Set via gateway config or `WithAuth` option | +| **None** | Local development, insecure gateways | Default when no auth is configured | + +## Automatic Auth (Recommended) + +When using `gateway.NewClient()`, authentication is resolved automatically +from the CLI configuration: + +```go +// Auth is read from ~/.config/openshell//config.yaml +client, err := gateway.NewClient("my-gateway") +``` + +The CLI stores OIDC tokens after `openshell gateway auth`. The SDK reads +these tokens from disk and wraps them with `RefreshableToken` for +automatic re-reading when the token file is updated. + +## Token Refresh + +You can wrap any auth provider with `NewTokenRefresher` to add +token-expiry-aware refresh logic with configurable leeway: + +```go +import v1 "github.com/NVIDIA/OpenShell/sdk/go/openshell/v1" + +refresher := v1.NewTokenRefresher(baseAuth, + v1.WithLeeway(30 * time.Second), + v1.WithLogger(myLogger), +) + +client, err := gateway.NewClient("my-gateway", + gateway.WithAuth(refresher), +) +``` + +## Custom Auth Provider + +For programmatic authentication, implement the `AuthProvider` interface +or use the built-in providers: + +```go +// Static API key +client, err := gateway.NewClient("my-gateway", + gateway.WithAuth(v1.StaticToken("my-api-key")), +) +``` + +The `AuthProvider` interface provides gRPC per-RPC credentials. Each +call attaches the token to the request metadata automatically. + +## TLS Configuration + +Control TLS settings when connecting to gateways: + +```go +client, err := gateway.NewClient("my-gateway", + gateway.WithTLS(&types.TLSConfig{ + Insecure: false, + CAFile: "/path/to/ca.crt", + }), +) +``` + +For local development with self-signed certificates, you can skip +verification, but this should never be used in production. + +## Testing with Fakes + +The fake client does not require authentication. Use it in tests to +avoid gateway dependencies: + +```go +import "github.com/NVIDIA/OpenShell/sdk/go/openshell/v1/fake" + +func TestMyFeature(t *testing.T) { + client := fake.NewClient() + // Use client.Sandboxes(), client.Exec(), etc. + // No gateway connection or auth needed. +} +``` diff --git a/docs/sdks/go/error-handling.mdx b/docs/sdks/go/error-handling.mdx new file mode 100644 index 0000000000..603e1f7bf3 --- /dev/null +++ b/docs/sdks/go/error-handling.mdx @@ -0,0 +1,96 @@ +--- +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +title: "Error Handling" +description: "SDK error types, gRPC status code mapping, and retry patterns." +keywords: "Go SDK, Errors, gRPC, Status Codes, Retry, Error Handling" +--- + +The SDK translates gRPC status codes into typed Go errors. All errors +returned by client methods can be inspected with `errors.As` to extract +structured details. + +## StatusError + +The primary error type is `types.StatusError`: + +```go +import "github.com/NVIDIA/OpenShell/sdk/go/openshell/v1/types" + +sandbox, err := client.Sandboxes().Get(ctx, "missing") +if err != nil { + var se *types.StatusError + if errors.As(err, &se) { + fmt.Printf("Code: %d, Message: %s\n", se.Code, se.Message) + } +} +``` + +## Error Codes + +The SDK defines error codes that map to gRPC status codes: + +| SDK Error Code | gRPC Status | Meaning | +|----------------|-------------|---------| +| `ErrorNotFound` | `NOT_FOUND` | Resource does not exist | +| `ErrorAlreadyExists` | `ALREADY_EXISTS` | Resource name conflict | +| `ErrorInvalidArgument` | `INVALID_ARGUMENT` | Bad request parameters | +| `ErrorPermissionDenied` | `PERMISSION_DENIED` | Insufficient credentials | +| `ErrorUnavailable` | `UNAVAILABLE` | Gateway is unreachable | +| `ErrorDeadlineExceeded` | `DEADLINE_EXCEEDED` | Request timed out | +| `ErrorCancelled` | `CANCELLED` | Request was cancelled | +| `ErrorInternal` | `INTERNAL` | Server-side failure | +| `ErrorUnimplemented` | `UNIMPLEMENTED` | Operation not supported | +| `ErrorConflict` | `ABORTED` / `FAILED_PRECONDITION` | Conflicting operation | + +## Checking Error Types + +Use helper functions or direct comparison: + +```go +if err != nil { + var se *types.StatusError + if errors.As(err, &se) { + switch se.Code { + case types.ErrorNotFound: + // Handle missing resource + case types.ErrorUnavailable: + // Retry or fail over + default: + // Log and return + } + } +} +``` + +## Retry Configuration + +Configure automatic retries for transient failures: + +```go +client, err := gateway.NewClient("my-gateway", + gateway.WithRetryPolicy(&types.RetryPolicy{ + MaxRetries: 3, + InitialWait: 100 * time.Millisecond, + }), +) +``` + +The retry policy applies to `Unavailable` and `DeadlineExceeded` errors. +Other error codes are returned immediately without retrying. + +## Context Cancellation + +All client methods accept a `context.Context`. Cancelled or timed-out +contexts produce standard Go `context.Canceled` or +`context.DeadlineExceeded` errors: + +```go +ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) +defer cancel() + +sandboxes, err := client.Sandboxes().List(ctx) +if errors.Is(err, context.DeadlineExceeded) { + // Request timed out +} +``` diff --git a/docs/sdks/go/getting-started.mdx b/docs/sdks/go/getting-started.mdx new file mode 100644 index 0000000000..90f3794304 --- /dev/null +++ b/docs/sdks/go/getting-started.mdx @@ -0,0 +1,101 @@ +--- +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +title: "Getting Started" +description: "Install the OpenShell Go SDK, connect to a gateway, and make your first API call." +keywords: "Go SDK, Installation, Quickstart, Gateway, gRPC, Sandbox" +--- + +The Go SDK provides typed clients for the OpenShell gateway and edge APIs. +It wraps gRPC transport and exposes idiomatic Go types with functional option +configuration. + +## Installation + +```shell +go get github.com/NVIDIA/OpenShell/sdk/go@latest +``` + +Requires Go 1.24 or later. + +## Connect to a Gateway + +The gateway client reads connection details from the CLI configuration +(`~/.config/openshell/`). Pass the gateway name or leave it empty to use +the active gateway. + +```go +package main + +import ( + "context" + "fmt" + "log" + + "github.com/NVIDIA/OpenShell/sdk/go/openshell/v1/gateway" +) + +func main() { + // Connect to the active gateway (configured via `openshell gateway use`). + client, err := gateway.NewClient("") + if err != nil { + log.Fatal(err) + } + defer client.Close() + + // List sandboxes. + ctx := context.Background() + sandboxes, err := client.Sandboxes().List(ctx) + if err != nil { + log.Fatal(err) + } + for _, sb := range sandboxes { + fmt.Printf("Sandbox: %s (phase: %s)\n", sb.Name, sb.Status.Phase) + } +} +``` + +## Create a Sandbox + +```go +sandbox, err := client.Sandboxes().Create(ctx, "my-sandbox", &types.SandboxSpec{ + Template: types.SandboxTemplate{ + Image: "ubuntu:24.04", + }, +}, nil) +if err != nil { + log.Fatal(err) +} +fmt.Printf("Created sandbox %s\n", sandbox.Name) +``` + +## Run a Command + +```go +result, err := client.Exec().Run(ctx, "my-sandbox", []string{"echo", "hello"}) +if err != nil { + log.Fatal(err) +} +fmt.Println(string(result.Stdout)) +``` + +## Client Options + +Configure the client with functional options: + +```go +client, err := gateway.NewClient("my-gateway", + gateway.WithTimeout(30 * time.Second), + gateway.WithLogger(myLogger), + gateway.WithRetryPolicy(&types.RetryPolicy{ + MaxRetries: 3, + InitialWait: 100 * time.Millisecond, + }), +) +``` + +## Next Steps + +- [Architecture](/sdks/go/architecture) for module structure and transport details +- [Error Handling](/sdks/go/error-handling) for SDK error types and retry patterns +- [Authentication](/sdks/go/authentication) for OIDC and token configuration diff --git a/sdk/go/go.mod b/sdk/go/go.mod index 26298aebc8..dec3ef3fc9 100644 --- a/sdk/go/go.mod +++ b/sdk/go/go.mod @@ -1,21 +1,21 @@ module github.com/NVIDIA/OpenShell/sdk/go -go 1.25.0 +go 1.24.0 require ( github.com/coder/websocket v1.8.15 github.com/stretchr/testify v1.11.1 - golang.org/x/oauth2 v0.36.0 - google.golang.org/grpc v1.81.1 + golang.org/x/oauth2 v0.35.0 + google.golang.org/grpc v1.80.0 google.golang.org/protobuf v1.36.11 ) require ( github.com/davecgh/go-spew v1.1.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - golang.org/x/net v0.51.0 // indirect - golang.org/x/sys v0.42.0 // indirect - golang.org/x/text v0.34.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect + golang.org/x/net v0.49.0 // indirect + golang.org/x/sys v0.41.0 // indirect + golang.org/x/text v0.33.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/sdk/go/go.sum b/sdk/go/go.sum index dc14bb3d80..0a382a0291 100644 --- a/sdk/go/go.sum +++ b/sdk/go/go.sum @@ -20,30 +20,30 @@ github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= -go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= -go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= -go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= -go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= -go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= -go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= -go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= -go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= -go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= -golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo= -golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y= -golang.org/x/oauth2 v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs= -golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q= -golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= -golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= +golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o= +golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8= +golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= +golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k= +golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= +golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 h1:ggcbiqK8WWh6l1dnltU4BgWGIGo+EVYxCaAPih/zQXQ= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ= -google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 h1:sNrWoksmOyF5bvJUcnmbeAmQi8baNhqg5IWaI3llQqU= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/tasks/go.toml b/tasks/go.toml new file mode 100644 index 0000000000..b92155cfc0 --- /dev/null +++ b/tasks/go.toml @@ -0,0 +1,27 @@ +# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +[tasks."go:proto"] +description = "Regenerate Go protobuf bindings" +dir = "sdk/go" +run = "mise run proto:gen" + +[tasks."go:proto:check"] +description = "Verify generated Go protobuf files are up to date" +dir = "sdk/go" +run = "mise run proto:check" + +[tasks."go:lint"] +description = "Run Go linter" +dir = "sdk/go" +run = "mise run lint" + +[tasks."go:build"] +description = "Build Go SDK packages" +dir = "sdk/go" +run = "mise run build" + +[tasks."go:test"] +description = "Run Go SDK tests" +dir = "sdk/go" +run = "mise run test"