Skip to content

Commit a4dc322

Browse files
committed
Merge branch 'main' into abhineetjain/improve-logout
2 parents c80858c + 61ffd03 commit a4dc322

File tree

78 files changed

+1189
-733
lines changed

Some content is hidden

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

78 files changed

+1189
-733
lines changed

.github/workflows/coder.yaml

+5-5
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ jobs:
171171
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}
172172

173173
- name: Install goreleaser
174-
uses: jaxxstorm/action-install-gh-release@v1.6.0
174+
uses: jaxxstorm/action-install-gh-release@v1.7.1
175175
env:
176176
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
177177
with:
@@ -240,7 +240,7 @@ jobs:
240240
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}
241241

242242
- name: Install goreleaser
243-
uses: jaxxstorm/action-install-gh-release@v1.6.0
243+
uses: jaxxstorm/action-install-gh-release@v1.7.1
244244
env:
245245
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
246246
with:
@@ -335,7 +335,7 @@ jobs:
335335
path: ${{ steps.go-cache-paths.outputs.go-mod }}
336336
key: ${{ runner.os }}-release-go-mod-${{ hashFiles('**/go.sum') }}
337337

338-
- uses: goreleaser/goreleaser-action@v2
338+
- uses: goreleaser/goreleaser-action@v3
339339
with:
340340
install-only: true
341341

@@ -354,7 +354,7 @@ jobs:
354354
run: make -B site/out/index.html
355355

356356
- name: Build Release
357-
uses: goreleaser/goreleaser-action@v2.9.1
357+
uses: goreleaser/goreleaser-action@v3
358358
with:
359359
version: latest
360360
args: release --snapshot --rm-dist --skip-sign
@@ -467,7 +467,7 @@ jobs:
467467
with:
468468
node-version: "14"
469469

470-
- uses: goreleaser/goreleaser-action@v2
470+
- uses: goreleaser/goreleaser-action@v3
471471
with:
472472
install-only: true
473473

.github/workflows/release.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ jobs:
8080
run: make site/out/index.html
8181

8282
- name: Run GoReleaser
83-
uses: goreleaser/goreleaser-action@v2.9.1
83+
uses: goreleaser/goreleaser-action@v3
8484
with:
8585
version: latest
8686
args: release --rm-dist

.golangci.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ run:
201201
concurrency: 4
202202
skip-dirs:
203203
- node_modules
204+
skip-files:
205+
- scripts/rules.go
204206
timeout: 5m
205207

206208
# Over time, add more and more linters from

.vscode/settings.json

+3
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
"drpcserver",
1616
"Dsts",
1717
"fatih",
18+
"Formik",
1819
"goarch",
1920
"gographviz",
2021
"goleak",
2122
"gossh",
2223
"gsyslog",
2324
"hashicorp",
2425
"hclsyntax",
26+
"httpapi",
2527
"httpmw",
2628
"idtoken",
2729
"Iflag",
@@ -63,6 +65,7 @@
6365
"tfjson",
6466
"tfstate",
6567
"trimprefix",
68+
"typegen",
6669
"unconvert",
6770
"Untar",
6871
"VMID",

agent/agent_test.go

+9-8
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"github.com/pion/udp"
2121
"github.com/pion/webrtc/v3"
2222
"github.com/pkg/sftp"
23+
"github.com/stretchr/testify/assert"
2324
"github.com/stretchr/testify/require"
2425
"go.uber.org/goleak"
2526
"golang.org/x/crypto/ssh"
@@ -119,7 +120,7 @@ func TestAgent(t *testing.T) {
119120
done := make(chan struct{})
120121
go func() {
121122
conn, err := local.Accept()
122-
require.NoError(t, err)
123+
assert.NoError(t, err)
123124
_ = conn.Close()
124125
close(done)
125126
}()
@@ -367,7 +368,7 @@ func setupSSHCommand(t *testing.T, beforeArgs []string, afterArgs []string) *exe
367368
return
368369
}
369370
ssh, err := agentConn.SSH()
370-
require.NoError(t, err)
371+
assert.NoError(t, err)
371372
go io.Copy(conn, ssh)
372373
go io.Copy(ssh, conn)
373374
}
@@ -409,7 +410,7 @@ func setupAgent(t *testing.T, metadata agent.Metadata, ptyTimeout time.Duration)
409410
})
410411
api := proto.NewDRPCPeerBrokerClient(provisionersdk.Conn(client))
411412
stream, err := api.NegotiateConnection(context.Background())
412-
require.NoError(t, err)
413+
assert.NoError(t, err)
413414
conn, err := peerbroker.Dial(stream, []webrtc.ICEServer{}, &peer.ConnOptions{
414415
Logger: slogtest.Make(t, nil),
415416
})
@@ -444,13 +445,13 @@ func testAccept(t *testing.T, c net.Conn) {
444445
func assertReadPayload(t *testing.T, r io.Reader, payload []byte) {
445446
b := make([]byte, len(payload)+16)
446447
n, err := r.Read(b)
447-
require.NoError(t, err, "read payload")
448-
require.Equal(t, len(payload), n, "read payload length does not match")
449-
require.Equal(t, payload, b[:n])
448+
assert.NoError(t, err, "read payload")
449+
assert.Equal(t, len(payload), n, "read payload length does not match")
450+
assert.Equal(t, payload, b[:n])
450451
}
451452

452453
func assertWritePayload(t *testing.T, w io.Writer, payload []byte) {
453454
n, err := w.Write(payload)
454-
require.NoError(t, err, "write payload")
455-
require.Equal(t, len(payload), n, "payload length does not match")
455+
assert.NoError(t, err, "write payload")
456+
assert.Equal(t, len(payload), n, "payload length does not match")
456457
}

cli/cliui/agent_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"time"
77

88
"github.com/spf13/cobra"
9-
"github.com/stretchr/testify/require"
9+
"github.com/stretchr/testify/assert"
1010
"go.uber.org/atomic"
1111

1212
"github.com/coder/coder/cli/cliui"
@@ -43,7 +43,7 @@ func TestAgent(t *testing.T) {
4343
go func() {
4444
defer close(done)
4545
err := cmd.Execute()
46-
require.NoError(t, err)
46+
assert.NoError(t, err)
4747
}()
4848
ptty.ExpectMatch("lost connection")
4949
disconnected.Store(true)

cli/cliui/prompt_test.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"time"
1111

1212
"github.com/spf13/cobra"
13+
"github.com/stretchr/testify/assert"
1314
"github.com/stretchr/testify/require"
1415

1516
"github.com/coder/coder/cli/cliui"
@@ -27,7 +28,7 @@ func TestPrompt(t *testing.T) {
2728
resp, err := newPrompt(ptty, cliui.PromptOptions{
2829
Text: "Example",
2930
}, nil)
30-
require.NoError(t, err)
31+
assert.NoError(t, err)
3132
msgChan <- resp
3233
}()
3334
ptty.ExpectMatch("Example")
@@ -44,7 +45,7 @@ func TestPrompt(t *testing.T) {
4445
Text: "Example",
4546
IsConfirm: true,
4647
}, nil)
47-
require.NoError(t, err)
48+
assert.NoError(t, err)
4849
doneChan <- resp
4950
}()
5051
ptty.ExpectMatch("Example")
@@ -80,7 +81,7 @@ func TestPrompt(t *testing.T) {
8081
cliui.AllowSkipPrompt(cmd)
8182
cmd.SetArgs([]string{"-y"})
8283
})
83-
require.NoError(t, err)
84+
assert.NoError(t, err)
8485
doneChan <- resp
8586
}()
8687

@@ -101,7 +102,7 @@ func TestPrompt(t *testing.T) {
101102
resp, err := newPrompt(ptty, cliui.PromptOptions{
102103
Text: "Example",
103104
}, nil)
104-
require.NoError(t, err)
105+
assert.NoError(t, err)
105106
doneChan <- resp
106107
}()
107108
ptty.ExpectMatch("Example")
@@ -117,7 +118,7 @@ func TestPrompt(t *testing.T) {
117118
resp, err := newPrompt(ptty, cliui.PromptOptions{
118119
Text: "Example",
119120
}, nil)
120-
require.NoError(t, err)
121+
assert.NoError(t, err)
121122
doneChan <- resp
122123
}()
123124
ptty.ExpectMatch("Example")
@@ -133,7 +134,7 @@ func TestPrompt(t *testing.T) {
133134
resp, err := newPrompt(ptty, cliui.PromptOptions{
134135
Text: "Example",
135136
}, nil)
136-
require.NoError(t, err)
137+
assert.NoError(t, err)
137138
doneChan <- resp
138139
}()
139140
ptty.ExpectMatch("Example")

cli/cliui/provisionerjob_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"time"
1010

1111
"github.com/spf13/cobra"
12-
"github.com/stretchr/testify/require"
12+
"github.com/stretchr/testify/assert"
1313

1414
"github.com/coder/coder/cli/cliui"
1515
"github.com/coder/coder/coderd/database"
@@ -90,9 +90,9 @@ func TestProvisionerJob(t *testing.T) {
9090
go func() {
9191
<-test.Next
9292
currentProcess, err := os.FindProcess(os.Getpid())
93-
require.NoError(t, err)
93+
assert.NoError(t, err)
9494
err = currentProcess.Signal(os.Interrupt)
95-
require.NoError(t, err)
95+
assert.NoError(t, err)
9696
<-test.Next
9797
test.JobMutex.Lock()
9898
test.Job.Status = codersdk.ProvisionerJobCanceled
@@ -150,7 +150,7 @@ func newProvisionerJob(t *testing.T) provisionerJobTest {
150150
defer close(done)
151151
err := cmd.ExecuteContext(context.Background())
152152
if err != nil {
153-
require.ErrorIs(t, err, cliui.Canceled)
153+
assert.ErrorIs(t, err, cliui.Canceled)
154154
}
155155
}()
156156
t.Cleanup(func() {

cli/cliui/resources_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"testing"
55
"time"
66

7-
"github.com/stretchr/testify/require"
7+
"github.com/stretchr/testify/assert"
88

99
"github.com/coder/coder/cli/cliui"
1010
"github.com/coder/coder/coderd/database"
@@ -32,7 +32,7 @@ func TestWorkspaceResources(t *testing.T) {
3232
}}, cliui.WorkspaceResourcesOptions{
3333
WorkspaceName: "example",
3434
})
35-
require.NoError(t, err)
35+
assert.NoError(t, err)
3636
close(done)
3737
}()
3838
ptty.ExpectMatch("coder ssh example")
@@ -85,7 +85,7 @@ func TestWorkspaceResources(t *testing.T) {
8585
HideAgentState: false,
8686
HideAccess: false,
8787
})
88-
require.NoError(t, err)
88+
assert.NoError(t, err)
8989
close(done)
9090
}()
9191
ptty.ExpectMatch("google_compute_disk.root")

cli/cliui/select_test.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"testing"
66

77
"github.com/spf13/cobra"
8+
"github.com/stretchr/testify/assert"
89
"github.com/stretchr/testify/require"
910

1011
"github.com/coder/coder/cli/cliui"
@@ -21,7 +22,7 @@ func TestSelect(t *testing.T) {
2122
resp, err := newSelect(ptty, cliui.SelectOptions{
2223
Options: []string{"First", "Second"},
2324
})
24-
require.NoError(t, err)
25+
assert.NoError(t, err)
2526
msgChan <- resp
2627
}()
2728
require.Equal(t, "First", <-msgChan)

cli/configssh_test.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"testing"
1212

1313
"github.com/google/uuid"
14+
"github.com/stretchr/testify/assert"
1415
"github.com/stretchr/testify/require"
1516

1617
"cdr.dev/slog/sloggers/slogtest"
@@ -96,7 +97,7 @@ func TestConfigSSH(t *testing.T) {
9697
return
9798
}
9899
ssh, err := agentConn.SSH()
99-
require.NoError(t, err)
100+
assert.NoError(t, err)
100101
go io.Copy(conn, ssh)
101102
go io.Copy(ssh, conn)
102103
}
@@ -120,7 +121,7 @@ func TestConfigSSH(t *testing.T) {
120121
go func() {
121122
defer close(doneChan)
122123
err := cmd.Execute()
123-
require.NoError(t, err)
124+
assert.NoError(t, err)
124125
}()
125126
<-doneChan
126127

cli/create.go

+33-6
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,20 @@ import (
1010

1111
"github.com/coder/coder/cli/cliflag"
1212
"github.com/coder/coder/cli/cliui"
13+
"github.com/coder/coder/coderd/autobuild/schedule"
1314
"github.com/coder/coder/codersdk"
1415
)
1516

1617
func create() *cobra.Command {
1718
var (
18-
workspaceName string
19-
templateName string
20-
parameterFile string
19+
autostartMinute string
20+
autostartHour string
21+
autostartDow string
22+
parameterFile string
23+
templateName string
24+
ttl time.Duration
25+
tzName string
26+
workspaceName string
2127
)
2228
cmd := &cobra.Command{
2329
Annotations: workspaceCommand,
@@ -54,6 +60,20 @@ func create() *cobra.Command {
5460
}
5561
}
5662

63+
tz, err := time.LoadLocation(tzName)
64+
if err != nil {
65+
return xerrors.Errorf("Invalid workspace autostart timezone: %w", err)
66+
}
67+
schedSpec := fmt.Sprintf("CRON_TZ=%s %s %s * * %s", tz.String(), autostartMinute, autostartHour, autostartDow)
68+
_, err = schedule.Weekly(schedSpec)
69+
if err != nil {
70+
return xerrors.Errorf("invalid workspace autostart schedule: %w", err)
71+
}
72+
73+
if ttl == 0 {
74+
return xerrors.Errorf("TTL must be at least 1 minute")
75+
}
76+
5777
_, err = client.WorkspaceByOwnerAndName(cmd.Context(), organization.ID, codersdk.Me, workspaceName)
5878
if err == nil {
5979
return xerrors.Errorf("A workspace already exists named %q!", workspaceName)
@@ -174,9 +194,11 @@ func create() *cobra.Command {
174194

175195
before := time.Now()
176196
workspace, err := client.CreateWorkspace(cmd.Context(), organization.ID, codersdk.CreateWorkspaceRequest{
177-
TemplateID: template.ID,
178-
Name: workspaceName,
179-
ParameterValues: parameters,
197+
TemplateID: template.ID,
198+
Name: workspaceName,
199+
AutostartSchedule: &schedSpec,
200+
TTL: &ttl,
201+
ParameterValues: parameters,
180202
})
181203
if err != nil {
182204
return err
@@ -207,5 +229,10 @@ func create() *cobra.Command {
207229
cliui.AllowSkipPrompt(cmd)
208230
cliflag.StringVarP(cmd.Flags(), &templateName, "template", "t", "CODER_TEMPLATE_NAME", "", "Specify a template name.")
209231
cliflag.StringVarP(cmd.Flags(), &parameterFile, "parameter-file", "", "CODER_PARAMETER_FILE", "", "Specify a file path with parameter values.")
232+
cliflag.StringVarP(cmd.Flags(), &autostartMinute, "autostart-minute", "", "CODER_WORKSPACE_AUTOSTART_MINUTE", "0", "Specify the minute(s) at which the workspace should autostart (e.g. 0).")
233+
cliflag.StringVarP(cmd.Flags(), &autostartHour, "autostart-hour", "", "CODER_WORKSPACE_AUTOSTART_HOUR", "9", "Specify the hour(s) at which the workspace should autostart (e.g. 9).")
234+
cliflag.StringVarP(cmd.Flags(), &autostartDow, "autostart-day-of-week", "", "CODER_WORKSPACE_AUTOSTART_DOW", "MON-FRI", "Specify the days(s) on which the workspace should autostart (e.g. MON,TUE,WED,THU,FRI)")
235+
cliflag.StringVarP(cmd.Flags(), &tzName, "tz", "", "TZ", "", "Specify your timezone location for workspace autostart (e.g. US/Central).")
236+
cliflag.DurationVarP(cmd.Flags(), &ttl, "ttl", "", "CODER_WORKSPACE_TTL", 8*time.Hour, "Specify a time-to-live (TTL) for the workspace (e.g. 8h).")
210237
return cmd
211238
}

0 commit comments

Comments
 (0)