Skip to content

Commit 1914490

Browse files
authored
feat: implement feature to support template version while creating workspace using cli (coder#14880)
1 parent 0ef5340 commit 1914490

File tree

4 files changed

+95
-4
lines changed

4 files changed

+95
-4
lines changed

cli/create.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,11 @@ import (
2222

2323
func (r *RootCmd) create() *serpent.Command {
2424
var (
25-
templateName string
26-
startAt string
27-
stopAfter time.Duration
28-
workspaceName string
25+
templateName string
26+
templateVersion string
27+
startAt string
28+
stopAfter time.Duration
29+
workspaceName string
2930

3031
parameterFlags workspaceParameterFlags
3132
autoUpdates string
@@ -202,6 +203,14 @@ func (r *RootCmd) create() *serpent.Command {
202203
templateVersionID = template.ActiveVersionID
203204
}
204205

206+
if len(templateVersion) > 0 {
207+
version, err := client.TemplateVersionByName(inv.Context(), template.ID, templateVersion)
208+
if err != nil {
209+
return xerrors.Errorf("get template version by name: %w", err)
210+
}
211+
templateVersionID = version.ID
212+
}
213+
205214
// If the user specified an organization via a flag or env var, the template **must**
206215
// be in that organization. Otherwise, we should throw an error.
207216
orgValue, orgValueSource := orgContext.ValueSource(inv)
@@ -314,6 +323,12 @@ func (r *RootCmd) create() *serpent.Command {
314323
Description: "Specify a template name.",
315324
Value: serpent.StringOf(&templateName),
316325
},
326+
serpent.Option{
327+
Flag: "template-version",
328+
Env: "CODER_TEMPLATE_VERSION",
329+
Description: "Specify a template version name.",
330+
Value: serpent.StringOf(&templateVersion),
331+
},
317332
serpent.Option{
318333
Flag: "start-at",
319334
Env: "CODER_WORKSPACE_START_AT",

cli/create_test.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,70 @@ func TestCreate(t *testing.T) {
133133
}
134134
})
135135

136+
t.Run("CreateWithSpecificTemplateVersion", func(t *testing.T) {
137+
t.Parallel()
138+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
139+
owner := coderdtest.CreateFirstUser(t, client)
140+
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
141+
version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, completeWithAgent())
142+
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
143+
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
144+
145+
// Create a new version
146+
version2 := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, completeWithAgent(), func(ctvr *codersdk.CreateTemplateVersionRequest) {
147+
ctvr.TemplateID = template.ID
148+
})
149+
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version2.ID)
150+
151+
args := []string{
152+
"create",
153+
"my-workspace",
154+
"--template", template.Name,
155+
"--template-version", version2.Name,
156+
"--start-at", "9:30AM Mon-Fri US/Central",
157+
"--stop-after", "8h",
158+
"--automatic-updates", "always",
159+
}
160+
inv, root := clitest.New(t, args...)
161+
clitest.SetupConfig(t, member, root)
162+
doneChan := make(chan struct{})
163+
pty := ptytest.New(t).Attach(inv)
164+
go func() {
165+
defer close(doneChan)
166+
err := inv.Run()
167+
assert.NoError(t, err)
168+
}()
169+
matches := []struct {
170+
match string
171+
write string
172+
}{
173+
{match: "compute.main"},
174+
{match: "smith (linux, i386)"},
175+
{match: "Confirm create", write: "yes"},
176+
}
177+
for _, m := range matches {
178+
pty.ExpectMatch(m.match)
179+
if len(m.write) > 0 {
180+
pty.WriteLine(m.write)
181+
}
182+
}
183+
<-doneChan
184+
185+
ws, err := member.WorkspaceByOwnerAndName(context.Background(), codersdk.Me, "my-workspace", codersdk.WorkspaceOptions{})
186+
if assert.NoError(t, err, "expected workspace to be created") {
187+
assert.Equal(t, ws.TemplateName, template.Name)
188+
// Check if the workspace is using the new template version
189+
assert.Equal(t, ws.LatestBuild.TemplateVersionID, version2.ID, "expected workspace to use the specified template version")
190+
if assert.NotNil(t, ws.AutostartSchedule) {
191+
assert.Equal(t, *ws.AutostartSchedule, "CRON_TZ=US/Central 30 9 * * Mon-Fri")
192+
}
193+
if assert.NotNil(t, ws.TTLMillis) {
194+
assert.Equal(t, *ws.TTLMillis, 8*time.Hour.Milliseconds())
195+
}
196+
assert.Equal(t, codersdk.AutomaticUpdatesAlways, ws.AutomaticUpdates)
197+
}
198+
})
199+
136200
t.Run("InheritStopAfterFromTemplate", func(t *testing.T) {
137201
t.Parallel()
138202
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})

cli/testdata/coder_create_--help.golden

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ OPTIONS:
4242
-t, --template string, $CODER_TEMPLATE_NAME
4343
Specify a template name.
4444

45+
--template-version string, $CODER_TEMPLATE_VERSION
46+
Specify a template version name.
47+
4548
-y, --yes bool
4649
Bypass prompts.
4750

docs/reference/cli/create.md

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)