From 8083d9d5c87fbb7d7d8f018706a8d0769480378a Mon Sep 17 00:00:00 2001 From: Cian Johnston Date: Tue, 26 Aug 2025 19:42:02 +0100 Subject: [PATCH] fix(cli): attach org option to task create (#19554) Attaches the org context options to the exp task create cmd --- cli/exp_taskcreate.go | 4 ++- cli/exp_taskcreate_test.go | 73 ++++++++++++++++++++++++++++---------- 2 files changed, 57 insertions(+), 20 deletions(-) diff --git a/cli/exp_taskcreate.go b/cli/exp_taskcreate.go index 40f45a903c..9125b86329 100644 --- a/cli/exp_taskcreate.go +++ b/cli/exp_taskcreate.go @@ -23,7 +23,7 @@ func (r *RootCmd) taskCreate() *serpent.Command { taskInput string ) - return &serpent.Command{ + cmd := &serpent.Command{ Use: "create [template]", Short: "Create an experimental task", Middleware: serpent.Chain( @@ -123,4 +123,6 @@ func (r *RootCmd) taskCreate() *serpent.Command { return nil }, } + orgContext.AttachOptions(cmd) + return cmd } diff --git a/cli/exp_taskcreate_test.go b/cli/exp_taskcreate_test.go index 520838c53a..121f22eb52 100644 --- a/cli/exp_taskcreate_test.go +++ b/cli/exp_taskcreate_test.go @@ -29,12 +29,13 @@ func TestTaskCreate(t *testing.T) { taskCreatedAt = time.Now() organizationID = uuid.New() + anotherOrganizationID = uuid.New() templateID = uuid.New() templateVersionID = uuid.New() templateVersionPresetID = uuid.New() ) - templateAndVersionFoundHandler := func(t *testing.T, ctx context.Context, templateName, templateVersionName, presetName, prompt string) http.HandlerFunc { + templateAndVersionFoundHandler := func(t *testing.T, ctx context.Context, orgID uuid.UUID, templateName, templateVersionName, presetName, prompt string) http.HandlerFunc { t.Helper() return func(w http.ResponseWriter, r *http.Request) { @@ -42,14 +43,14 @@ func TestTaskCreate(t *testing.T) { case "/api/v2/users/me/organizations": httpapi.Write(ctx, w, http.StatusOK, []codersdk.Organization{ {MinimalOrganization: codersdk.MinimalOrganization{ - ID: organizationID, + ID: orgID, }}, }) - case fmt.Sprintf("/api/v2/organizations/%s/templates/my-template/versions/my-template-version", organizationID): + case fmt.Sprintf("/api/v2/organizations/%s/templates/my-template/versions/my-template-version", orgID): httpapi.Write(ctx, w, http.StatusOK, codersdk.TemplateVersion{ ID: templateVersionID, }) - case fmt.Sprintf("/api/v2/organizations/%s/templates/my-template", organizationID): + case fmt.Sprintf("/api/v2/organizations/%s/templates/my-template", orgID): httpapi.Write(ctx, w, http.StatusOK, codersdk.Template{ ID: templateID, ActiveVersionID: templateVersionID, @@ -94,47 +95,47 @@ func TestTaskCreate(t *testing.T) { handler func(t *testing.T, ctx context.Context) http.HandlerFunc }{ { - args: []string{"my-template@my-template-version", "--input", "my custom prompt"}, + args: []string{"my-template@my-template-version", "--input", "my custom prompt", "--org", organizationID.String()}, expectOutput: fmt.Sprintf("The task %s has been created at %s!", cliui.Keyword("task-wild-goldfish-27"), cliui.Timestamp(taskCreatedAt)), handler: func(t *testing.T, ctx context.Context) http.HandlerFunc { - return templateAndVersionFoundHandler(t, ctx, "my-template", "my-template-version", "", "my custom prompt") + return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "my-template-version", "", "my custom prompt") }, }, { - args: []string{"my-template", "--input", "my custom prompt"}, + args: []string{"my-template", "--input", "my custom prompt", "--org", organizationID.String()}, env: []string{"CODER_TASK_TEMPLATE_VERSION=my-template-version"}, expectOutput: fmt.Sprintf("The task %s has been created at %s!", cliui.Keyword("task-wild-goldfish-27"), cliui.Timestamp(taskCreatedAt)), handler: func(t *testing.T, ctx context.Context) http.HandlerFunc { - return templateAndVersionFoundHandler(t, ctx, "my-template", "my-template-version", "", "my custom prompt") + return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "my-template-version", "", "my custom prompt") }, }, { - args: []string{"--input", "my custom prompt"}, + args: []string{"--input", "my custom prompt", "--org", organizationID.String()}, env: []string{"CODER_TASK_TEMPLATE_NAME=my-template", "CODER_TASK_TEMPLATE_VERSION=my-template-version"}, expectOutput: fmt.Sprintf("The task %s has been created at %s!", cliui.Keyword("task-wild-goldfish-27"), cliui.Timestamp(taskCreatedAt)), handler: func(t *testing.T, ctx context.Context) http.HandlerFunc { - return templateAndVersionFoundHandler(t, ctx, "my-template", "my-template-version", "", "my custom prompt") + return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "my-template-version", "", "my custom prompt") }, }, { - env: []string{"CODER_TASK_TEMPLATE_NAME=my-template", "CODER_TASK_TEMPLATE_VERSION=my-template-version", "CODER_TASK_INPUT=my custom prompt"}, + env: []string{"CODER_TASK_TEMPLATE_NAME=my-template", "CODER_TASK_TEMPLATE_VERSION=my-template-version", "CODER_TASK_INPUT=my custom prompt", "CODER_ORGANIZATION=" + organizationID.String()}, expectOutput: fmt.Sprintf("The task %s has been created at %s!", cliui.Keyword("task-wild-goldfish-27"), cliui.Timestamp(taskCreatedAt)), handler: func(t *testing.T, ctx context.Context) http.HandlerFunc { - return templateAndVersionFoundHandler(t, ctx, "my-template", "my-template-version", "", "my custom prompt") + return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "my-template-version", "", "my custom prompt") }, }, { - args: []string{"my-template", "--input", "my custom prompt"}, + args: []string{"my-template", "--input", "my custom prompt", "--org", organizationID.String()}, expectOutput: fmt.Sprintf("The task %s has been created at %s!", cliui.Keyword("task-wild-goldfish-27"), cliui.Timestamp(taskCreatedAt)), handler: func(t *testing.T, ctx context.Context) http.HandlerFunc { - return templateAndVersionFoundHandler(t, ctx, "my-template", "", "", "my custom prompt") + return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "", "", "my custom prompt") }, }, { - args: []string{"my-template", "--input", "my custom prompt", "--preset", "my-preset"}, + args: []string{"my-template", "--input", "my custom prompt", "--preset", "my-preset", "--org", organizationID.String()}, expectOutput: fmt.Sprintf("The task %s has been created at %s!", cliui.Keyword("task-wild-goldfish-27"), cliui.Timestamp(taskCreatedAt)), handler: func(t *testing.T, ctx context.Context) http.HandlerFunc { - return templateAndVersionFoundHandler(t, ctx, "my-template", "", "my-preset", "my custom prompt") + return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "", "my-preset", "my custom prompt") }, }, { @@ -142,14 +143,14 @@ func TestTaskCreate(t *testing.T) { env: []string{"CODER_TASK_PRESET_NAME=my-preset"}, expectOutput: fmt.Sprintf("The task %s has been created at %s!", cliui.Keyword("task-wild-goldfish-27"), cliui.Timestamp(taskCreatedAt)), handler: func(t *testing.T, ctx context.Context) http.HandlerFunc { - return templateAndVersionFoundHandler(t, ctx, "my-template", "", "my-preset", "my custom prompt") + return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "", "my-preset", "my custom prompt") }, }, { args: []string{"my-template", "--input", "my custom prompt", "--preset", "not-real-preset"}, expectError: `preset "not-real-preset" not found`, handler: func(t *testing.T, ctx context.Context) http.HandlerFunc { - return templateAndVersionFoundHandler(t, ctx, "my-template", "", "my-preset", "my custom prompt") + return templateAndVersionFoundHandler(t, ctx, organizationID, "my-template", "", "my-preset", "my custom prompt") }, }, { @@ -173,7 +174,7 @@ func TestTaskCreate(t *testing.T) { }, }, { - args: []string{"not-real-template", "--input", "my custom prompt"}, + args: []string{"not-real-template", "--input", "my custom prompt", "--org", organizationID.String()}, expectError: httpapi.ResourceNotFoundResponse.Message, handler: func(t *testing.T, ctx context.Context) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { @@ -192,6 +193,40 @@ func TestTaskCreate(t *testing.T) { } }, }, + { + args: []string{"template-in-different-org", "--input", "my-custom-prompt", "--org", anotherOrganizationID.String()}, + expectError: httpapi.ResourceNotFoundResponse.Message, + handler: func(t *testing.T, ctx context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/api/v2/users/me/organizations": + httpapi.Write(ctx, w, http.StatusOK, []codersdk.Organization{ + {MinimalOrganization: codersdk.MinimalOrganization{ + ID: anotherOrganizationID, + }}, + }) + case fmt.Sprintf("/api/v2/organizations/%s/templates/template-in-different-org", anotherOrganizationID): + httpapi.ResourceNotFound(w) + default: + t.Errorf("unexpected path: %s", r.URL.Path) + } + } + }, + }, + { + args: []string{"no-org", "--input", "my-custom-prompt"}, + expectError: "Must select an organization with --org=", + handler: func(t *testing.T, ctx context.Context) http.HandlerFunc { + return func(w http.ResponseWriter, r *http.Request) { + switch r.URL.Path { + case "/api/v2/users/me/organizations": + httpapi.Write(ctx, w, http.StatusOK, []codersdk.Organization{}) + default: + t.Errorf("unexpected path: %s", r.URL.Path) + } + } + }, + }, } for _, tt := range tests {