Skip to content
Merged
15 changes: 15 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,21 @@ on:
branches:
- main

permissions:
contents: read

jobs:
verify-generation:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: "go.mod"
check-latest: true
cache: false
- name: Add Go bin to PATH
run: echo "$HOME/go/bin" >> $GITHUB_PATH
- name: Run commands generation command
Expand All @@ -34,5 +43,11 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v5
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: "go.mod"
check-latest: true
cache: false
- name: Build the cli binary
run: make build
7 changes: 7 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ jobs:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Go
uses: actions/setup-go@v6
with:
go-version-file: "go.mod"
check-latest: true
cache: false

- name: Setup mise
uses: jdx/mise-action@v2
with:
Expand Down
4 changes: 3 additions & 1 deletion temporalcloudcli/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ func (b *CloudOptionsBuilder) Build(ctx context.Context) (*CloudOptions, error)
}
}

cloudOpts := &CloudOptions{}
cloudOpts := &CloudOptions{
CommonOptions: common,
}

// Set logger if provided.
if b.Logger != nil {
Expand Down
20 changes: 18 additions & 2 deletions temporalcloudcli/commands.gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ func (v *ClientOptions) BuildFlags(f *pflag.FlagSet) {
_ = f.MarkHidden("server")
}

type DiffOptions struct {
VerboseDiff bool
FlagSet *pflag.FlagSet
}

func (v *DiffOptions) BuildFlags(f *pflag.FlagSet) {
v.FlagSet = f
f.BoolVar(&v.VerboseDiff, "verbose-diff", false, "Show detailed differences between the current and desired namespace configurations when changes are detected.")
}

type CloudCommand struct {
Command cobra.Command
ClientOptions
Expand Down Expand Up @@ -153,11 +163,11 @@ type CloudNamespaceApplyCommand struct {
Parent *CloudNamespaceCommand
Command cobra.Command
ClientOptions
DiffOptions
Spec string
AsyncOperationId string
Idempotent bool
Async bool
VerboseDiff bool
ResourceVersion string
}

Expand All @@ -178,9 +188,9 @@ func NewCloudNamespaceApplyCommand(cctx *CommandContext, parent *CloudNamespaceC
s.Command.Flags().StringVar(&s.AsyncOperationId, "async-operation-id", "", "Custom identifier for tracking this async operation. If not provided, a unique ID is generated automatically.")
s.Command.Flags().BoolVar(&s.Idempotent, "idempotent", false, "Succeed silently if the namespace already matches the specification. Without this flag, the command errors when no changes are needed.")
s.Command.Flags().BoolVar(&s.Async, "async", false, "Return immediately after initiating the operation instead of waiting for completion. Use the returned operation ID to check status later.")
s.Command.Flags().BoolVar(&s.VerboseDiff, "verbose-diff", false, "Show detailed differences between the current and desired namespace configurations when changes are detected.")
s.Command.Flags().StringVarP(&s.ResourceVersion, "resource-version", "v", "", "Resource version for optimistic concurrency control. If not provided, the current version is fetched automatically.")
s.ClientOptions.BuildFlags(s.Command.Flags())
s.DiffOptions.BuildFlags(s.Command.Flags())
s.Command.Run = func(c *cobra.Command, args []string) {
if err := s.run(cctx, args); err != nil {
cctx.Options.Fail(err)
Expand Down Expand Up @@ -231,6 +241,7 @@ type CloudNamespaceEditCommand struct {
Parent *CloudNamespaceCommand
Command cobra.Command
ClientOptions
DiffOptions
Namespace string
AsyncOperationId string
Idempotent bool
Expand All @@ -257,6 +268,7 @@ func NewCloudNamespaceEditCommand(cctx *CommandContext, parent *CloudNamespaceCo
s.Command.Flags().BoolVar(&s.Async, "async", false, "Return immediately after initiating the operation instead of waiting for completion. Use the returned operation ID to check status later.")
s.Command.Flags().StringVarP(&s.ResourceVersion, "resource-version", "v", "", "Resource version for optimistic concurrency control. If not provided, the current version is fetched automatically.")
s.ClientOptions.BuildFlags(s.Command.Flags())
s.DiffOptions.BuildFlags(s.Command.Flags())
s.Command.Run = func(c *cobra.Command, args []string) {
if err := s.run(cctx, args); err != nil {
cctx.Options.Fail(err)
Expand Down Expand Up @@ -348,6 +360,7 @@ type CloudNamespaceLifecycleSetCommand struct {
Parent *CloudNamespaceLifecycleCommand
Command cobra.Command
ClientOptions
DiffOptions
Namespace string
EnableDeleteProtection bool
AsyncOperationId string
Expand Down Expand Up @@ -377,6 +390,7 @@ func NewCloudNamespaceLifecycleSetCommand(cctx *CommandContext, parent *CloudNam
s.Command.Flags().BoolVar(&s.Idempotent, "idempotent", false, "Succeed silently if the lifecycle configuration is already set to the specified value. Without this flag, the command errors when no change is needed.")
s.Command.Flags().StringVar(&s.ResourceVersion, "resource-version", "", "Resource version for optimistic concurrency control. If not provided, the current version is fetched automatically.")
s.ClientOptions.BuildFlags(s.Command.Flags())
s.DiffOptions.BuildFlags(s.Command.Flags())
s.Command.Run = func(c *cobra.Command, args []string) {
if err := s.run(cctx, args); err != nil {
cctx.Options.Fail(err)
Expand Down Expand Up @@ -469,6 +483,7 @@ type CloudNamespaceRetentionSetCommand struct {
Parent *CloudNamespaceRetentionCommand
Command cobra.Command
ClientOptions
DiffOptions
Namespace string
AsyncOperationId string
Async bool
Expand Down Expand Up @@ -498,6 +513,7 @@ func NewCloudNamespaceRetentionSetCommand(cctx *CommandContext, parent *CloudNam
_ = cobra.MarkFlagRequired(s.Command.Flags(), "retention-days")
s.Command.Flags().StringVar(&s.ResourceVersion, "resource-version", "", "Resource version for optimistic concurrency control. If not provided, the current version is fetched automatically.")
s.ClientOptions.BuildFlags(s.Command.Flags())
s.DiffOptions.BuildFlags(s.Command.Flags())
s.Command.Run = func(c *cobra.Command, args []string) {
if err := s.run(cctx, args); err != nil {
cctx.Options.Fail(err)
Expand Down
69 changes: 0 additions & 69 deletions temporalcloudcli/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"bufio"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"log/slog"
Expand All @@ -21,17 +20,13 @@ import (
"github.com/spf13/pflag"
"github.com/temporalio/cloud-cli/temporalcloudcli/internal/printer"
"go.temporal.io/api/common/v1"
commonpb "go.temporal.io/api/common/v1"
"go.temporal.io/api/failure/v1"
"go.temporal.io/api/temporalproto"
"go.temporal.io/cloud-sdk/cloudclient"
"go.temporal.io/sdk/contrib/envconfig"
"go.temporal.io/sdk/converter"
"go.temporal.io/sdk/temporal"
"golang.org/x/term"
"google.golang.org/grpc"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/types/known/timestamppb"
)

// Version is the value put as the default command version. This is often
Expand Down Expand Up @@ -546,15 +541,6 @@ func (c *CloudCommand) preRun(cctx *CommandContext) error {
return nil
}

func aliasNormalizer(aliases map[string]string) func(f *pflag.FlagSet, name string) pflag.NormalizedName {
return func(f *pflag.FlagSet, name string) pflag.NormalizedName {
if actual := aliases[name]; actual != "" {
name = actual
}
return pflag.NormalizedName(name)
}
}

func newNopLogger() *slog.Logger { return slog.New(discardLogHandler{}) }

type discardLogHandler struct{}
Expand All @@ -564,61 +550,6 @@ func (discardLogHandler) Handle(context.Context, slog.Record) error { return nil
func (d discardLogHandler) WithAttrs([]slog.Attr) slog.Handler { return d }
func (d discardLogHandler) WithGroup(string) slog.Handler { return d }

func timestampToTime(t *timestamppb.Timestamp) time.Time {
if t == nil {
return time.Time{}
}
return t.AsTime()
}

type nopWriter struct{}

func (nopWriter) Write(b []byte) (int, error) { return len(b), nil }

type structuredError struct {
Message string `json:"message"`
Type string `json:"type,omitempty"`
Details any `json:"details,omitempty"`
}

func fromApplicationError(err *temporal.ApplicationError) (*structuredError, error) {
var deets any
if err := err.Details(&deets); err != nil && !errors.Is(err, temporal.ErrNoData) {
return nil, err
}
return &structuredError{
Message: err.Error(),
Type: err.Type(),
Details: deets,
}, nil
}

func encodeMapToPayloads(in map[string]any) (map[string]*commonpb.Payload, error) {
if len(in) == 0 {
return nil, nil
}
// search attributes always use default dataconverter
dc := converter.GetDefaultDataConverter()
out := make(map[string]*commonpb.Payload, len(in))
for key, val := range in {
payload, err := dc.ToPayload(val)
if err != nil {
return nil, err
}
out[key] = payload
}
return out, nil
}

type overrideDisplayTypeFlagValue struct {
pflag.Value
displayType string
}

func (o *overrideDisplayTypeFlagValue) Type() string {
return o.displayType
}

func overrideFlagDisplayType(flag *pflag.Flag, displayType string) {
flag.Value = &overrideDisplayTypeFlagValue{Value: flag.Value, displayType: displayType}
}
2 changes: 2 additions & 0 deletions temporalcloudcli/commands.login.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ func (c *CloudLoginCommand) run(cctx *CommandContext, _ []string) error {
return fmt.Errorf("failed to load profile: %w", err)
}
if loadClientOauthRes.OAuth != nil &&
loadClientOauthRes.OAuth.Token != nil &&
Comment thread
cursor[bot] marked this conversation as resolved.
loadClientOauthRes.OAuth.ClientConfig != nil &&
!reflect.DeepEqual(*loadClientOauthRes.OAuth, cliext.OAuthConfig{}) &&
!reflect.DeepEqual(*loadClientOauthRes.OAuth.ClientConfig, oauth2.Config{}) &&
!c.Reset {
Expand Down
Loading