diff --git a/cli/create.go b/cli/create.go
index 5384ec094f..49002777cf 100644
--- a/cli/create.go
+++ b/cli/create.go
@@ -22,10 +22,11 @@ import (
func (r *RootCmd) create() *serpent.Command {
var (
- templateName string
- startAt string
- stopAfter time.Duration
- workspaceName string
+ templateName string
+ templateVersion string
+ startAt string
+ stopAfter time.Duration
+ workspaceName string
parameterFlags workspaceParameterFlags
autoUpdates string
@@ -202,6 +203,14 @@ func (r *RootCmd) create() *serpent.Command {
templateVersionID = template.ActiveVersionID
}
+ if len(templateVersion) > 0 {
+ version, err := client.TemplateVersionByName(inv.Context(), template.ID, templateVersion)
+ if err != nil {
+ return xerrors.Errorf("get template version by name: %w", err)
+ }
+ templateVersionID = version.ID
+ }
+
// If the user specified an organization via a flag or env var, the template **must**
// be in that organization. Otherwise, we should throw an error.
orgValue, orgValueSource := orgContext.ValueSource(inv)
@@ -314,6 +323,12 @@ func (r *RootCmd) create() *serpent.Command {
Description: "Specify a template name.",
Value: serpent.StringOf(&templateName),
},
+ serpent.Option{
+ Flag: "template-version",
+ Env: "CODER_TEMPLATE_VERSION",
+ Description: "Specify a template version name.",
+ Value: serpent.StringOf(&templateVersion),
+ },
serpent.Option{
Flag: "start-at",
Env: "CODER_WORKSPACE_START_AT",
diff --git a/cli/create_test.go b/cli/create_test.go
index b6294f50b4..1f505d0523 100644
--- a/cli/create_test.go
+++ b/cli/create_test.go
@@ -133,6 +133,70 @@ func TestCreate(t *testing.T) {
}
})
+ t.Run("CreateWithSpecificTemplateVersion", func(t *testing.T) {
+ t.Parallel()
+ client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
+ owner := coderdtest.CreateFirstUser(t, client)
+ member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
+ version := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, completeWithAgent())
+ coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
+ template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version.ID)
+
+ // Create a new version
+ version2 := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, completeWithAgent(), func(ctvr *codersdk.CreateTemplateVersionRequest) {
+ ctvr.TemplateID = template.ID
+ })
+ coderdtest.AwaitTemplateVersionJobCompleted(t, client, version2.ID)
+
+ args := []string{
+ "create",
+ "my-workspace",
+ "--template", template.Name,
+ "--template-version", version2.Name,
+ "--start-at", "9:30AM Mon-Fri US/Central",
+ "--stop-after", "8h",
+ "--automatic-updates", "always",
+ }
+ inv, root := clitest.New(t, args...)
+ clitest.SetupConfig(t, member, root)
+ doneChan := make(chan struct{})
+ pty := ptytest.New(t).Attach(inv)
+ go func() {
+ defer close(doneChan)
+ err := inv.Run()
+ assert.NoError(t, err)
+ }()
+ matches := []struct {
+ match string
+ write string
+ }{
+ {match: "compute.main"},
+ {match: "smith (linux, i386)"},
+ {match: "Confirm create", write: "yes"},
+ }
+ for _, m := range matches {
+ pty.ExpectMatch(m.match)
+ if len(m.write) > 0 {
+ pty.WriteLine(m.write)
+ }
+ }
+ <-doneChan
+
+ ws, err := member.WorkspaceByOwnerAndName(context.Background(), codersdk.Me, "my-workspace", codersdk.WorkspaceOptions{})
+ if assert.NoError(t, err, "expected workspace to be created") {
+ assert.Equal(t, ws.TemplateName, template.Name)
+ // Check if the workspace is using the new template version
+ assert.Equal(t, ws.LatestBuild.TemplateVersionID, version2.ID, "expected workspace to use the specified template version")
+ if assert.NotNil(t, ws.AutostartSchedule) {
+ assert.Equal(t, *ws.AutostartSchedule, "CRON_TZ=US/Central 30 9 * * Mon-Fri")
+ }
+ if assert.NotNil(t, ws.TTLMillis) {
+ assert.Equal(t, *ws.TTLMillis, 8*time.Hour.Milliseconds())
+ }
+ assert.Equal(t, codersdk.AutomaticUpdatesAlways, ws.AutomaticUpdates)
+ }
+ })
+
t.Run("InheritStopAfterFromTemplate", func(t *testing.T) {
t.Parallel()
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
diff --git a/cli/testdata/coder_create_--help.golden b/cli/testdata/coder_create_--help.golden
index e4949750f2..ab426bcb37 100644
--- a/cli/testdata/coder_create_--help.golden
+++ b/cli/testdata/coder_create_--help.golden
@@ -42,6 +42,9 @@ OPTIONS:
-t, --template string, $CODER_TEMPLATE_NAME
Specify a template name.
+ --template-version string, $CODER_TEMPLATE_VERSION
+ Specify a template version name.
+
-y, --yes bool
Bypass prompts.
diff --git a/docs/reference/cli/create.md b/docs/reference/cli/create.md
index d4003e2f9e..c165b33f4e 100644
--- a/docs/reference/cli/create.md
+++ b/docs/reference/cli/create.md
@@ -29,6 +29,15 @@ coder create [flags] [name]
Specify a template name.
+### --template-version
+
+| | |
+| ----------- | ------------------------------------ |
+| Type | string |
+| Environment | $CODER_TEMPLATE_VERSION |
+
+Specify a template version name.
+
### --start-at
| | |