Skip to content

Commit a3d3126

Browse files
authored
fix(cli): do not ask for immutables on update (#9266)
1 parent e6d90bd commit a3d3126

File tree

2 files changed

+132
-1
lines changed

2 files changed

+132
-1
lines changed

cli/parameterresolver.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ func (pr *ParameterResolver) resolveWithInput(resolved []codersdk.WorkspaceBuild
184184
if (tvp.Ephemeral && pr.promptBuildOptions) ||
185185
(action == WorkspaceCreate && tvp.Required) ||
186186
(action == WorkspaceCreate && !tvp.Ephemeral) ||
187-
(action == WorkspaceUpdate && tvp.Required) ||
187+
(action == WorkspaceUpdate && tvp.Mutable && tvp.Required) ||
188188
(action == WorkspaceUpdate && !tvp.Mutable && firstTimeUse) ||
189189
(action == WorkspaceUpdate && tvp.Mutable && !tvp.Ephemeral && pr.promptRichParameters) {
190190
parameterValue, err := cliui.RichParameter(inv, tvp)

cli/update_test.go

+131
Original file line numberDiff line numberDiff line change
@@ -602,4 +602,135 @@ func TestUpdateValidateRichParameters(t *testing.T) {
602602
}
603603
<-doneChan
604604
})
605+
606+
t.Run("ImmutableRequiredParameterExists_MutableRequiredParameterAdded", func(t *testing.T) {
607+
t.Parallel()
608+
609+
// Create template and workspace
610+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
611+
user := coderdtest.CreateFirstUser(t, client)
612+
613+
templateParameters := []*proto.RichParameter{
614+
{Name: stringParameterName, Type: "string", Mutable: false, Required: true, Options: []*proto.RichParameterOption{
615+
{Name: "First option", Description: "This is first option", Value: "1st"},
616+
{Name: "Second option", Description: "This is second option", Value: "2nd"},
617+
{Name: "Third option", Description: "This is third option", Value: "3rd"},
618+
}},
619+
}
620+
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, prepareEchoResponses(templateParameters))
621+
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
622+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
623+
624+
inv, root := clitest.New(t, "create", "my-workspace", "--yes", "--template", template.Name, "--parameter", fmt.Sprintf("%s=%s", stringParameterName, "2nd"))
625+
clitest.SetupConfig(t, client, root)
626+
err := inv.Run()
627+
require.NoError(t, err)
628+
629+
// Update template: add required, mutable parameter
630+
const mutableParameterName = "foobar"
631+
updatedTemplateParameters := []*proto.RichParameter{
632+
templateParameters[0],
633+
{Name: mutableParameterName, Type: "string", Mutable: true, Required: true},
634+
}
635+
636+
updatedVersion := coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, prepareEchoResponses(updatedTemplateParameters), template.ID)
637+
coderdtest.AwaitTemplateVersionJob(t, client, updatedVersion.ID)
638+
err = client.UpdateActiveTemplateVersion(context.Background(), template.ID, codersdk.UpdateActiveTemplateVersion{
639+
ID: updatedVersion.ID,
640+
})
641+
require.NoError(t, err)
642+
643+
// Update the workspace
644+
inv, root = clitest.New(t, "update", "my-workspace")
645+
clitest.SetupConfig(t, client, root)
646+
doneChan := make(chan struct{})
647+
pty := ptytest.New(t).Attach(inv)
648+
go func() {
649+
defer close(doneChan)
650+
err := inv.Run()
651+
assert.NoError(t, err)
652+
}()
653+
654+
matches := []string{
655+
mutableParameterName, "hello",
656+
"Planning workspace...", "",
657+
}
658+
for i := 0; i < len(matches); i += 2 {
659+
match := matches[i]
660+
value := matches[i+1]
661+
pty.ExpectMatch(match)
662+
663+
if value != "" {
664+
pty.WriteLine(value)
665+
}
666+
}
667+
<-doneChan
668+
})
669+
670+
t.Run("MutableRequiredParameterExists_ImmutableRequiredParameterAdded", func(t *testing.T) {
671+
t.Parallel()
672+
673+
// Create template and workspace
674+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
675+
user := coderdtest.CreateFirstUser(t, client)
676+
677+
templateParameters := []*proto.RichParameter{
678+
{Name: stringParameterName, Type: "string", Mutable: true, Required: true, Options: []*proto.RichParameterOption{
679+
{Name: "First option", Description: "This is first option", Value: "1st"},
680+
{Name: "Second option", Description: "This is second option", Value: "2nd"},
681+
{Name: "Third option", Description: "This is third option", Value: "3rd"},
682+
}},
683+
}
684+
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, prepareEchoResponses(templateParameters))
685+
coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
686+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
687+
688+
inv, root := clitest.New(t, "create", "my-workspace", "--yes", "--template", template.Name, "--parameter", fmt.Sprintf("%s=%s", stringParameterName, "2nd"))
689+
clitest.SetupConfig(t, client, root)
690+
err := inv.Run()
691+
require.NoError(t, err)
692+
693+
// Update template: add required, immutable parameter
694+
updatedTemplateParameters := []*proto.RichParameter{
695+
templateParameters[0],
696+
{Name: immutableParameterName, Type: "string", Mutable: false, Required: true, Options: []*proto.RichParameterOption{
697+
{Name: "fir", Description: "This is first option for immutable parameter", Value: "I"},
698+
{Name: "sec", Description: "This is second option for immutable parameter", Value: "II"},
699+
{Name: "thi", Description: "This is third option for immutable parameter", Value: "III"},
700+
}},
701+
}
702+
703+
updatedVersion := coderdtest.UpdateTemplateVersion(t, client, user.OrganizationID, prepareEchoResponses(updatedTemplateParameters), template.ID)
704+
coderdtest.AwaitTemplateVersionJob(t, client, updatedVersion.ID)
705+
err = client.UpdateActiveTemplateVersion(context.Background(), template.ID, codersdk.UpdateActiveTemplateVersion{
706+
ID: updatedVersion.ID,
707+
})
708+
require.NoError(t, err)
709+
710+
// Update the workspace
711+
inv, root = clitest.New(t, "update", "my-workspace")
712+
clitest.SetupConfig(t, client, root)
713+
doneChan := make(chan struct{})
714+
pty := ptytest.New(t).Attach(inv)
715+
go func() {
716+
defer close(doneChan)
717+
err := inv.Run()
718+
assert.NoError(t, err)
719+
}()
720+
721+
matches := []string{
722+
immutableParameterName, "thi",
723+
"Planning workspace...", "",
724+
}
725+
for i := 0; i < len(matches); i += 2 {
726+
match := matches[i]
727+
value := matches[i+1]
728+
pty.ExpectMatch(match)
729+
730+
if value != "" {
731+
pty.WriteLine(value)
732+
}
733+
}
734+
<-doneChan
735+
})
605736
}

0 commit comments

Comments
 (0)