diff --git a/internal/cli/api/api.go b/internal/cli/api/api.go index eb8fd5d5dd..b49528b03a 100644 --- a/internal/cli/api/api.go +++ b/internal/cli/api/api.go @@ -107,6 +107,9 @@ func convertAPIToCobraCommand(command api.Command) (*cobra.Command, error) { return errors.Join(ErrFailedToSetUntouchedFlags, err) } + // Remind the user to pin their api command to a specific version to avoid breaking changes + remindUserToPinVersion(cmd) + // Reset version to default if unsupported version was selected // This can happen when the profile contains a default version which is not supported for a specific endpoint ensureVersionIsSupported(command, &version) @@ -329,6 +332,22 @@ func defaultAPIVersion(command api.Command) (string, error) { return lastVersion.Version, nil } +func remindUserToPinVersion(cmd *cobra.Command) { + versionFlag := cmd.Flag(flag.Version) + // if we fail to get the version flag (which should never happen), then quit + if versionFlag == nil { + return + } + + // check if the version flag is still in it's default state: + // - not set by the user + // - not set using api_version on the users profile + // in that case, print a warning + if !versionFlag.Changed { + fmt.Fprintf(os.Stderr, "warning: using default API version '%s'; consider pinning a version to ensure consisentcy when updating the CLI\n", versionFlag.Value.String()) + } +} + func ensureVersionIsSupported(apiCommand api.Command, version *string) { for _, commandVersion := range apiCommand.Versions { if commandVersion.Version == *version { @@ -343,7 +362,7 @@ func ensureVersionIsSupported(apiCommand api.Command, version *string) { return } - fmt.Fprintf(os.Stderr, "warning: version '%s' is not supported for this endpoint, falling back to default version: '%s'", *version, defaultVersion) + fmt.Fprintf(os.Stderr, "warning: version '%s' is not supported for this endpoint, using default API version '%s'; consider pinning a version to ensure consisentcy when updating the CLI\n", *version, defaultVersion) *version = defaultVersion } diff --git a/test/e2e/atlas/autogenerated_commands_test.go b/test/e2e/atlas/autogenerated_commands_test.go index db911903fc..f5ce999bcb 100644 --- a/test/e2e/atlas/autogenerated_commands_test.go +++ b/test/e2e/atlas/autogenerated_commands_test.go @@ -55,26 +55,38 @@ func TestAutogeneratedCommands(t *testing.T) { t.Parallel() cmd := exec.Command(cliPath, "api", "clusters", "getCluster", "--groupId", g.projectID, "--clusterName", g.clusterName) cmd.Env = os.Environ() - resp, err := e2e.RunAndGetStdOut(cmd) + stdOut, stdErr, err := e2e.RunAndGetSeparateStdOutAndErr(cmd) req.NoError(err) var c Cluster - req.NoError(json.Unmarshal(resp, &c)) + req.NoError(json.Unmarshal(stdOut, &c)) req.Equal(g.clusterName, c.Name) req.Equal(g.projectID, c.GroupID) + + // verify that we print the rinder for user to pin versions + // we're checking the first and the second half of the message because we don't want to fix this test every time clusters releases a new version + errorStr := string(stdErr) + req.Contains(errorStr, "warning: using default API version '") + req.Contains(errorStr, "'; consider pinning a version to ensure consisentcy when updating the CLI\n") }) t.Run("getCluster_valid_version_OK", func(t *testing.T) { t.Parallel() cmd := exec.Command(cliPath, "api", "clusters", "getCluster", "--groupId", g.projectID, "--clusterName", g.clusterName, "--version", "2024-08-05") cmd.Env = os.Environ() - resp, err := e2e.RunAndGetStdOut(cmd) + stdOut, stdErr, err := e2e.RunAndGetSeparateStdOutAndErr(cmd) req.NoError(err) var c Cluster - req.NoError(json.Unmarshal(resp, &c)) + req.NoError(json.Unmarshal(stdOut, &c)) req.Equal(g.clusterName, c.Name) req.Equal(g.projectID, c.GroupID) + + // verify that we don't print the reminder for users to pin versions + // we're checking the first and the second half of the message because we don't want to fix this test every time clusters releases a new version + errorStr := string(stdErr) + req.NotContains(errorStr, "warning: using default API version '") + req.NotContains(errorStr, "'; consider pinning a version to ensure consisentcy when updating the CLI\n") }) t.Run("getCluster_invalid_version_warn", func(t *testing.T) { @@ -89,6 +101,7 @@ func TestAutogeneratedCommands(t *testing.T) { req.Equal(g.clusterName, c.Name) req.Equal(g.projectID, c.GroupID) - req.Contains(string(stdErr), "warning: version '2020-01-01' is not supported for this endpoint, falling back to default version:") + req.Contains(string(stdErr), "warning: version '2020-01-01' is not supported for this endpoint, using default API version '") + req.Contains(string(stdErr), "'; consider pinning a version to ensure consisentcy when updating the CLI\n") }) }