Skip to content

Commit c80041b

Browse files
authored
feat: add coder_ai_task resource (#413)
1 parent 6570400 commit c80041b

File tree

4 files changed

+175
-0
lines changed

4 files changed

+175
-0
lines changed

docs/resources/ai_task.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "coder_ai_task Resource - terraform-provider-coder"
4+
subcategory: ""
5+
description: |-
6+
Use this resource to define Coder tasks.
7+
---
8+
9+
# coder_ai_task (Resource)
10+
11+
Use this resource to define Coder tasks.
12+
13+
14+
15+
<!-- schema generated by tfplugindocs -->
16+
## Schema
17+
18+
### Required
19+
20+
- `sidebar_app` (Block Set, Min: 1, Max: 1) The coder_app to display in the sidebar. Usually a chat interface with the AI agent running in the workspace, like https://github.com/coder/agentapi. (see [below for nested schema](#nestedblock--sidebar_app))
21+
22+
### Read-Only
23+
24+
- `id` (String) A unique identifier for this resource.
25+
26+
<a id="nestedblock--sidebar_app"></a>
27+
### Nested Schema for `sidebar_app`
28+
29+
Required:
30+
31+
- `id` (String) A reference to an existing `coder_app` resource in your template.

provider/ai_task.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
6+
"github.com/google/uuid"
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
10+
)
11+
12+
type AITask struct {
13+
ID string `mapstructure:"id"`
14+
SidebarApp []AITaskSidebarApp `mapstructure:"sidebar_app"`
15+
}
16+
17+
type AITaskSidebarApp struct {
18+
ID string `mapstructure:"id"`
19+
}
20+
21+
// TaskPromptParameterName is the name of the parameter which is *required* to be defined when a coder_ai_task is used.
22+
const TaskPromptParameterName = "AI Prompt"
23+
24+
func aiTask() *schema.Resource {
25+
return &schema.Resource{
26+
SchemaVersion: 1,
27+
28+
Description: "Use this resource to define Coder tasks.",
29+
CreateContext: func(c context.Context, resourceData *schema.ResourceData, i any) diag.Diagnostics {
30+
resourceData.SetId(uuid.NewString())
31+
return nil
32+
},
33+
ReadContext: schema.NoopContext,
34+
DeleteContext: schema.NoopContext,
35+
Schema: map[string]*schema.Schema{
36+
"id": {
37+
Type: schema.TypeString,
38+
Description: "A unique identifier for this resource.",
39+
Computed: true,
40+
},
41+
"sidebar_app": {
42+
Type: schema.TypeSet,
43+
Description: "The coder_app to display in the sidebar. Usually a chat interface with the AI agent running in the workspace, like https://github.com/coder/agentapi.",
44+
ForceNew: true,
45+
Required: true,
46+
MaxItems: 1,
47+
Elem: &schema.Resource{
48+
Schema: map[string]*schema.Schema{
49+
"id": {
50+
Type: schema.TypeString,
51+
Description: "A reference to an existing `coder_app` resource in your template.",
52+
Required: true,
53+
ForceNew: true,
54+
ValidateFunc: validation.IsUUID,
55+
},
56+
},
57+
},
58+
},
59+
},
60+
}
61+
}

provider/ai_task_test.go

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
package provider_test
2+
3+
import (
4+
"regexp"
5+
"testing"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
func TestAITask(t *testing.T) {
13+
t.Parallel()
14+
15+
t.Run("OK", func(t *testing.T) {
16+
t.Parallel()
17+
18+
resource.Test(t, resource.TestCase{
19+
ProviderFactories: coderFactory(),
20+
IsUnitTest: true,
21+
Steps: []resource.TestStep{{
22+
Config: `
23+
provider "coder" {
24+
}
25+
resource "coder_agent" "dev" {
26+
os = "linux"
27+
arch = "amd64"
28+
}
29+
resource "coder_app" "code-server" {
30+
agent_id = coder_agent.dev.id
31+
slug = "code-server"
32+
display_name = "code-server"
33+
icon = "builtin:vim"
34+
url = "http://localhost:13337"
35+
open_in = "slim-window"
36+
}
37+
resource "coder_ai_task" "test" {
38+
sidebar_app {
39+
id = coder_app.code-server.id
40+
}
41+
}
42+
`,
43+
Check: func(state *terraform.State) error {
44+
require.Len(t, state.Modules, 1)
45+
resource := state.Modules[0].Resources["coder_ai_task.test"]
46+
require.NotNil(t, resource)
47+
for _, key := range []string{
48+
"id",
49+
"sidebar_app.#",
50+
} {
51+
value := resource.Primary.Attributes[key]
52+
require.NotNil(t, value)
53+
require.Greater(t, len(value), 0)
54+
}
55+
require.Equal(t, "1", resource.Primary.Attributes["sidebar_app.#"])
56+
return nil
57+
},
58+
}},
59+
})
60+
})
61+
62+
t.Run("InvalidSidebarAppID", func(t *testing.T) {
63+
t.Parallel()
64+
65+
resource.Test(t, resource.TestCase{
66+
ProviderFactories: coderFactory(),
67+
IsUnitTest: true,
68+
Steps: []resource.TestStep{{
69+
Config: `
70+
provider "coder" {
71+
}
72+
resource "coder_ai_task" "test" {
73+
sidebar_app {
74+
id = "not-a-uuid"
75+
}
76+
}
77+
`,
78+
ExpectError: regexp.MustCompile(`expected "sidebar_app.0.id" to be a valid UUID`),
79+
}},
80+
})
81+
})
82+
}

provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ func New() *schema.Provider {
7272
ResourcesMap: map[string]*schema.Resource{
7373
"coder_agent": agentResource(),
7474
"coder_agent_instance": agentInstanceResource(),
75+
"coder_ai_task": aiTask(),
7576
"coder_app": appResource(),
7677
"coder_metadata": metadataResource(),
7778
"coder_script": scriptResource(),

0 commit comments

Comments
 (0)