Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3e31c06

Browse files
committed
Merge branch 'main' into clihelp
2 parents 8fecb67 + 19b4323 commit 3e31c06

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1678
-1098
lines changed

.github/CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
site @coder/frontend
2+
site/src/xServices @presleyp

.github/dependabot.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ updates:
4141
timezone: "America/Chicago"
4242
commit-message:
4343
prefix: "chore"
44+
labels:
45+
- "dependencies"
46+
- "typescript/js"
4447
ignore:
4548
# Ignore major updates to Node.js types, because they need to
4649
# correspond to the Node.js engine version

.github/workflows/coder.yaml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
runs-on: ubuntu-latest
3030
steps:
3131
- uses: actions/checkout@v3
32-
- uses: actions/setup-go@v2
32+
- uses: actions/setup-go@v3
3333
with:
3434
go-version: "~1.18"
3535
- name: golangci-lint
@@ -71,7 +71,7 @@ jobs:
7171
uses: arduino/setup-protoc@v1
7272
with:
7373
version: "3.19.4"
74-
- uses: actions/setup-go@v2
74+
- uses: actions/setup-go@v3
7575
with:
7676
go-version: "~1.18"
7777
- run: curl -sSL
@@ -123,7 +123,7 @@ jobs:
123123
steps:
124124
- uses: actions/checkout@v3
125125

126-
- uses: actions/setup-go@v2
126+
- uses: actions/setup-go@v3
127127
with:
128128
go-version: "~1.18"
129129

@@ -191,7 +191,7 @@ jobs:
191191
steps:
192192
- uses: actions/checkout@v3
193193

194-
- uses: actions/setup-go@v2
194+
- uses: actions/setup-go@v3
195195
with:
196196
go-version: "~1.18"
197197

@@ -289,7 +289,7 @@ jobs:
289289
- name: Set up Google Cloud SDK
290290
uses: google-github-actions/setup-gcloud@v0
291291

292-
- uses: actions/setup-go@v2
292+
- uses: actions/setup-go@v3
293293
with:
294294
go-version: "~1.18"
295295

@@ -363,7 +363,7 @@ jobs:
363363
js-${{ runner.os }}-
364364
365365
# Go is required for uploading the test results to datadog
366-
- uses: actions/setup-go@v2
366+
- uses: actions/setup-go@v3
367367
with:
368368
go-version: "~1.18"
369369

@@ -419,7 +419,7 @@ jobs:
419419
js-${{ runner.os }}-
420420
421421
# Go is required for uploading the test results to datadog
422-
- uses: actions/setup-go@v2
422+
- uses: actions/setup-go@v3
423423
with:
424424
go-version: "~1.18"
425425

.github/workflows/release.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ jobs:
1010
- uses: actions/checkout@v3
1111
with:
1212
fetch-depth: 0
13-
- uses: actions/setup-go@v2
13+
- uses: actions/setup-go@v3
1414
with:
1515
go-version: "~1.18"
1616

cli/cliui/prompt.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/bgentry/speakeasy"
1414
"github.com/mattn/go-isatty"
1515
"github.com/spf13/cobra"
16+
"golang.org/x/xerrors"
1617
)
1718

1819
// PromptOptions supply a set of options to the prompt.
@@ -47,7 +48,7 @@ func Prompt(cmd *cobra.Command, opts PromptOptions) (string, error) {
4748
if opts.Secret && isInputFile && isatty.IsTerminal(inFile.Fd()) {
4849
line, err = speakeasy.Ask("")
4950
} else {
50-
if runtime.GOOS == "darwin" && isInputFile {
51+
if !opts.IsConfirm && runtime.GOOS == "darwin" && isInputFile {
5152
var restore func()
5253
restore, err = removeLineLengthLimit(int(inFile.Fd()))
5354
if err != nil {
@@ -113,7 +114,7 @@ func Prompt(cmd *cobra.Command, opts PromptOptions) (string, error) {
113114
return "", err
114115
case line := <-lineCh:
115116
if opts.IsConfirm && line != "yes" && line != "y" {
116-
return line, Canceled
117+
return line, xerrors.Errorf("got %q: %w", line, Canceled)
117118
}
118119
if opts.Validate != nil {
119120
err := opts.Validate(line)

cli/workspaceautostart.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
"time"
6+
7+
"github.com/spf13/cobra"
8+
9+
"github.com/coder/coder/coderd/autostart/schedule"
10+
"github.com/coder/coder/codersdk"
11+
)
12+
13+
const autostartDescriptionLong = `To have your workspace build automatically at a regular time you can enable autostart.
14+
When enabling autostart, provide a schedule. This schedule is in cron format except only
15+
the following fields are allowed:
16+
- minute
17+
- hour
18+
- day of week
19+
20+
For example, to start your workspace every weekday at 9.30 am, provide the schedule '30 9 1-5'.`
21+
22+
func workspaceAutostart() *cobra.Command {
23+
autostartCmd := &cobra.Command{
24+
Use: "autostart enable <workspace> <schedule>",
25+
Short: "schedule a workspace to automatically start at a regular time",
26+
Long: autostartDescriptionLong,
27+
Example: "coder workspaces autostart enable my-workspace '30 9 1-5'",
28+
Hidden: true, // TODO(cian): un-hide when autostart scheduling implemented
29+
}
30+
31+
autostartCmd.AddCommand(workspaceAutostartEnable())
32+
autostartCmd.AddCommand(workspaceAutostartDisable())
33+
34+
return autostartCmd
35+
}
36+
37+
func workspaceAutostartEnable() *cobra.Command {
38+
return &cobra.Command{
39+
Use: "enable <workspace_name> <schedule>",
40+
ValidArgsFunction: validArgsWorkspaceName,
41+
Args: cobra.ExactArgs(2),
42+
RunE: func(cmd *cobra.Command, args []string) error {
43+
client, err := createClient(cmd)
44+
if err != nil {
45+
return err
46+
}
47+
48+
workspace, err := client.WorkspaceByName(cmd.Context(), codersdk.Me, args[0])
49+
if err != nil {
50+
return err
51+
}
52+
53+
validSchedule, err := schedule.Weekly(args[1])
54+
if err != nil {
55+
return err
56+
}
57+
58+
err = client.UpdateWorkspaceAutostart(cmd.Context(), workspace.ID, codersdk.UpdateWorkspaceAutostartRequest{
59+
Schedule: validSchedule.String(),
60+
})
61+
if err != nil {
62+
return err
63+
}
64+
65+
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nThe %s workspace will automatically start at %s.\n\n", workspace.Name, validSchedule.Next(time.Now()))
66+
67+
return nil
68+
},
69+
}
70+
}
71+
72+
func workspaceAutostartDisable() *cobra.Command {
73+
return &cobra.Command{
74+
Use: "disable <workspace_name>",
75+
ValidArgsFunction: validArgsWorkspaceName,
76+
Args: cobra.ExactArgs(1),
77+
RunE: func(cmd *cobra.Command, args []string) error {
78+
client, err := createClient(cmd)
79+
if err != nil {
80+
return err
81+
}
82+
83+
workspace, err := client.WorkspaceByName(cmd.Context(), codersdk.Me, args[0])
84+
if err != nil {
85+
return err
86+
}
87+
88+
err = client.UpdateWorkspaceAutostart(cmd.Context(), workspace.ID, codersdk.UpdateWorkspaceAutostartRequest{
89+
Schedule: "",
90+
})
91+
if err != nil {
92+
return err
93+
}
94+
95+
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nThe %s workspace will no longer automatically start.\n\n", workspace.Name)
96+
97+
return nil
98+
},
99+
}
100+
}

cli/workspaceautostart_test.go

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package cli_test
2+
3+
import (
4+
"bytes"
5+
"context"
6+
"testing"
7+
8+
"github.com/coder/coder/cli/clitest"
9+
"github.com/coder/coder/coderd/coderdtest"
10+
"github.com/coder/coder/codersdk"
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
func TestWorkspaceAutostart(t *testing.T) {
15+
t.Parallel()
16+
17+
t.Run("EnableDisableOK", func(t *testing.T) {
18+
t.Parallel()
19+
20+
var (
21+
ctx = context.Background()
22+
client = coderdtest.New(t, nil)
23+
_ = coderdtest.NewProvisionerDaemon(t, client)
24+
user = coderdtest.CreateFirstUser(t, client)
25+
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
26+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
27+
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
28+
workspace = coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
29+
sched = "CRON_TZ=Europe/Dublin 30 9 1-5"
30+
stdoutBuf = &bytes.Buffer{}
31+
)
32+
33+
cmd, root := clitest.New(t, "workspaces", "autostart", "enable", workspace.Name, sched)
34+
clitest.SetupConfig(t, client, root)
35+
cmd.SetOut(stdoutBuf)
36+
37+
err := cmd.Execute()
38+
require.NoError(t, err, "unexpected error")
39+
require.Contains(t, stdoutBuf.String(), "will automatically start at", "unexpected output")
40+
41+
// Ensure autostart schedule updated
42+
updated, err := client.Workspace(ctx, workspace.ID)
43+
require.NoError(t, err, "fetch updated workspace")
44+
require.Equal(t, sched, updated.AutostartSchedule, "expected autostart schedule to be set")
45+
46+
// Disable schedule
47+
cmd, root = clitest.New(t, "workspaces", "autostart", "disable", workspace.Name)
48+
clitest.SetupConfig(t, client, root)
49+
cmd.SetOut(stdoutBuf)
50+
51+
err = cmd.Execute()
52+
require.NoError(t, err, "unexpected error")
53+
require.Contains(t, stdoutBuf.String(), "will no longer automatically start", "unexpected output")
54+
55+
// Ensure autostart schedule updated
56+
updated, err = client.Workspace(ctx, workspace.ID)
57+
require.NoError(t, err, "fetch updated workspace")
58+
require.Empty(t, updated.AutostartSchedule, "expected autostart schedule to not be set")
59+
})
60+
61+
t.Run("Enable_NotFound", func(t *testing.T) {
62+
t.Parallel()
63+
64+
var (
65+
client = coderdtest.New(t, nil)
66+
_ = coderdtest.NewProvisionerDaemon(t, client)
67+
user = coderdtest.CreateFirstUser(t, client)
68+
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
69+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
70+
sched = "CRON_TZ=Europe/Dublin 30 9 1-5"
71+
)
72+
73+
cmd, root := clitest.New(t, "workspaces", "autostart", "enable", "doesnotexist", sched)
74+
clitest.SetupConfig(t, client, root)
75+
76+
err := cmd.Execute()
77+
require.ErrorContains(t, err, "status code 404: no workspace found by name", "unexpected error")
78+
})
79+
80+
t.Run("Disable_NotFound", func(t *testing.T) {
81+
t.Parallel()
82+
83+
var (
84+
client = coderdtest.New(t, nil)
85+
_ = coderdtest.NewProvisionerDaemon(t, client)
86+
user = coderdtest.CreateFirstUser(t, client)
87+
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
88+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
89+
)
90+
91+
cmd, root := clitest.New(t, "workspaces", "autostart", "disable", "doesnotexist")
92+
clitest.SetupConfig(t, client, root)
93+
94+
err := cmd.Execute()
95+
require.ErrorContains(t, err, "status code 404: no workspace found by name", "unexpected error")
96+
})
97+
98+
t.Run("Enable_InvalidSchedule", func(t *testing.T) {
99+
t.Parallel()
100+
101+
var (
102+
ctx = context.Background()
103+
client = coderdtest.New(t, nil)
104+
_ = coderdtest.NewProvisionerDaemon(t, client)
105+
user = coderdtest.CreateFirstUser(t, client)
106+
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
107+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
108+
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
109+
workspace = coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
110+
sched = "sdfasdfasdf asdf asdf"
111+
)
112+
113+
cmd, root := clitest.New(t, "workspaces", "autostart", "enable", workspace.Name, sched)
114+
clitest.SetupConfig(t, client, root)
115+
116+
err := cmd.Execute()
117+
require.ErrorContains(t, err, "failed to parse int from sdfasdfasdf: strconv.Atoi:", "unexpected error")
118+
119+
// Ensure nothing happened
120+
updated, err := client.Workspace(ctx, workspace.ID)
121+
require.NoError(t, err, "fetch updated workspace")
122+
require.Empty(t, updated.AutostartSchedule, "expected autostart schedule to be empty")
123+
})
124+
125+
t.Run("Enable_NoSchedule", func(t *testing.T) {
126+
t.Parallel()
127+
128+
var (
129+
ctx = context.Background()
130+
client = coderdtest.New(t, nil)
131+
_ = coderdtest.NewProvisionerDaemon(t, client)
132+
user = coderdtest.CreateFirstUser(t, client)
133+
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
134+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
135+
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
136+
workspace = coderdtest.CreateWorkspace(t, client, codersdk.Me, project.ID)
137+
)
138+
139+
cmd, root := clitest.New(t, "workspaces", "autostart", "enable", workspace.Name)
140+
clitest.SetupConfig(t, client, root)
141+
142+
err := cmd.Execute()
143+
require.ErrorContains(t, err, "accepts 2 arg(s), received 1", "unexpected error")
144+
145+
// Ensure nothing happened
146+
updated, err := client.Workspace(ctx, workspace.ID)
147+
require.NoError(t, err, "fetch updated workspace")
148+
require.Empty(t, updated.AutostartSchedule, "expected autostart schedule to be empty")
149+
})
150+
}

0 commit comments

Comments
 (0)