Skip to content

Commit 66f33ad

Browse files
committed
Merge branch 'main' into tailnet
2 parents 7fe91a2 + daadb9a commit 66f33ad

File tree

164 files changed

+5093
-2227
lines changed

Some content is hidden

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

164 files changed

+5093
-2227
lines changed

.github/workflows/coder.yaml

+3-1
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,8 @@ jobs:
369369
./scripts/build_go_matrix.sh \
370370
--output ./dist/ \
371371
--package-linux \
372-
linux:amd64
372+
linux:amd64 \
373+
windows:amd64
373374
374375
- name: Install Release
375376
run: |
@@ -387,6 +388,7 @@ jobs:
387388
name: coder
388389
path: |
389390
./dist/*.zip
391+
./dist/*.exe
390392
./dist/*.tar.gz
391393
./dist/*.apk
392394
./dist/*.deb

.gitignore

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ node_modules
1313
vendor
1414
.eslintcache
1515
yarn-error.log
16-
gotests.xml
1716
gotests.coverage
1817
.idea
1918
.DS_Store
@@ -41,3 +40,4 @@ site/out/
4140

4241
.vscode/*.log
4342
**/*.swp
43+
.coderv2/*

Makefile

+2-2
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,10 @@ test: test-clean
172172
.PHONY: test
173173

174174
test-postgres: test-clean test-postgres-docker
175-
DB_FROM=$(shell go run scripts/migrate-ci/main.go) gotestsum --junitfile="gotests.xml" --packages="./..." -- \
175+
DB=ci DB_FROM=$(shell go run scripts/migrate-ci/main.go) gotestsum --junitfile="gotests.xml" --packages="./..." -- \
176176
-covermode=atomic -coverprofile="gotests.coverage" -timeout=30m \
177177
-coverpkg=./...,github.com/coder/coder/codersdk \
178-
-count=2 -race -failfast
178+
-count=1 -race -failfast
179179
.PHONY: test-postgres
180180

181181
test-postgres-docker:

agent/reaper/reaper_stub.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ func IsInitProcess() bool {
77
return false
88
}
99

10-
func ForkReap(opt ...Option) error {
10+
func ForkReap(_ ...Option) error {
1111
return nil
1212
}

buildinfo/buildinfo.go

+21-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package buildinfo
33
import (
44
"fmt"
55
"runtime/debug"
6+
"strings"
67
"sync"
78
"time"
89

@@ -24,6 +25,11 @@ var (
2425
tag string
2526
)
2627

28+
const (
29+
// develPrefix is prefixed to developer versions of the application.
30+
develPrefix = "v0.0.0-devel"
31+
)
32+
2733
// Version returns the semantic version of the build.
2834
// Use golang.org/x/mod/semver to compare versions.
2935
func Version() string {
@@ -35,7 +41,7 @@ func Version() string {
3541
if tag == "" {
3642
// This occurs when the tag hasn't been injected,
3743
// like when using "go run".
38-
version = "v0.0.0-devel" + revision
44+
version = develPrefix + revision
3945
return
4046
}
4147
version = "v" + tag
@@ -48,6 +54,20 @@ func Version() string {
4854
return version
4955
}
5056

57+
// VersionsMatch compares the two versions. It assumes the versions match if
58+
// the major and the minor versions are equivalent. Patch versions are
59+
// disregarded. If it detects that either version is a developer build it
60+
// returns true.
61+
func VersionsMatch(v1, v2 string) bool {
62+
// Developer versions are disregarded...hopefully they know what they are
63+
// doing.
64+
if strings.HasPrefix(v1, develPrefix) || strings.HasPrefix(v2, develPrefix) {
65+
return true
66+
}
67+
68+
return semver.MajorMinor(v1) == semver.MajorMinor(v2)
69+
}
70+
5171
// ExternalURL returns a URL referencing the current Coder version.
5272
// For production builds, this will link directly to a release.
5373
// For development builds, this will link to a commit.

buildinfo/buildinfo_test.go

+67
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package buildinfo_test
22

33
import (
4+
"fmt"
45
"testing"
56

67
"github.com/stretchr/testify/require"
@@ -29,4 +30,70 @@ func TestBuildInfo(t *testing.T) {
2930
_, valid := buildinfo.Time()
3031
require.False(t, valid)
3132
})
33+
34+
t.Run("VersionsMatch", func(t *testing.T) {
35+
t.Parallel()
36+
37+
type testcase struct {
38+
name string
39+
v1 string
40+
v2 string
41+
expectMatch bool
42+
}
43+
44+
cases := []testcase{
45+
{
46+
name: "OK",
47+
v1: "v1.2.3",
48+
v2: "v1.2.3",
49+
expectMatch: true,
50+
},
51+
// Test that we return true if a developer version is detected.
52+
// Developers do not need to be warned of mismatched versions.
53+
{
54+
name: "DevelIgnored",
55+
v1: "v0.0.0-devel+123abac",
56+
v2: "v1.2.3",
57+
expectMatch: true,
58+
},
59+
// Our CI instance uses a "-devel" prerelease
60+
// flag. This is not the same as a developer WIP build.
61+
{
62+
name: "DevelPreleaseNotIgnored",
63+
v1: "v1.1.1-devel+123abac",
64+
v2: "v1.2.3",
65+
expectMatch: false,
66+
},
67+
{
68+
name: "MajorMismatch",
69+
v1: "v1.2.3",
70+
v2: "v0.1.2",
71+
expectMatch: false,
72+
},
73+
{
74+
name: "MinorMismatch",
75+
v1: "v1.2.3",
76+
v2: "v1.3.2",
77+
expectMatch: false,
78+
},
79+
// Different patches are ok, breaking changes are not allowed
80+
// in patches.
81+
{
82+
name: "PatchMismatch",
83+
v1: "v1.2.3+hash.whocares",
84+
v2: "v1.2.4+somestuff.hm.ok",
85+
expectMatch: true,
86+
},
87+
}
88+
89+
for _, c := range cases {
90+
c := c
91+
t.Run(c.name, func(t *testing.T) {
92+
t.Parallel()
93+
require.Equal(t, c.expectMatch, buildinfo.VersionsMatch(c.v1, c.v2),
94+
fmt.Sprintf("expected match=%v for version %s and %s", c.expectMatch, c.v1, c.v2),
95+
)
96+
})
97+
}
98+
})
3299
}

cli/cliflag/cliflag.go

+9-4
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func StringArrayVarP(flagset *pflag.FlagSet, ptr *[]string, name string, shortha
4747
def = strings.Split(val, ",")
4848
}
4949
}
50-
flagset.StringArrayVarP(ptr, name, shorthand, def, usage)
50+
flagset.StringArrayVarP(ptr, name, shorthand, def, fmtUsage(usage, env))
5151
}
5252

5353
// Uint8VarP sets a uint8 flag on the given flag set.
@@ -102,9 +102,14 @@ func DurationVarP(flagset *pflag.FlagSet, ptr *time.Duration, name string, short
102102
}
103103

104104
func fmtUsage(u string, env string) string {
105-
if env == "" {
106-
return fmt.Sprintf("%s.", u)
105+
if env != "" {
106+
// Avoid double dotting.
107+
dot := "."
108+
if strings.HasSuffix(u, ".") {
109+
dot = ""
110+
}
111+
u = fmt.Sprintf("%s%s\nConsumes $%s", u, dot, env)
107112
}
108113

109-
return fmt.Sprintf("%s - consumes $%s.", u, env)
114+
return u
110115
}

cli/cliflag/cliflag_test.go

+6-6
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func TestCliflag(t *testing.T) {
2424
require.NoError(t, err)
2525
require.Equal(t, def, got)
2626
require.Contains(t, flagset.FlagUsages(), usage)
27-
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf(" - consumes $%s", env))
27+
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf("Consumes $%s", env))
2828
})
2929

3030
t.Run("StringEnvVar", func(t *testing.T) {
@@ -48,7 +48,7 @@ func TestCliflag(t *testing.T) {
4848
require.NoError(t, err)
4949
require.Equal(t, def, got)
5050
require.Contains(t, flagset.FlagUsages(), usage)
51-
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf(" - consumes $%s", env))
51+
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf("Consumes $%s", env))
5252
})
5353

5454
t.Run("StringVarPEnvVar", func(t *testing.T) {
@@ -74,7 +74,7 @@ func TestCliflag(t *testing.T) {
7474
require.NoError(t, err)
7575
require.Equal(t, def, got)
7676
require.Contains(t, flagset.FlagUsages(), usage)
77-
require.NotContains(t, flagset.FlagUsages(), " - consumes")
77+
require.NotContains(t, flagset.FlagUsages(), "Consumes")
7878
})
7979

8080
t.Run("StringArrayDefault", func(t *testing.T) {
@@ -117,7 +117,7 @@ func TestCliflag(t *testing.T) {
117117
require.NoError(t, err)
118118
require.Equal(t, uint8(def), got)
119119
require.Contains(t, flagset.FlagUsages(), usage)
120-
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf(" - consumes $%s", env))
120+
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf("Consumes $%s", env))
121121
})
122122

123123
t.Run("IntEnvVar", func(t *testing.T) {
@@ -156,7 +156,7 @@ func TestCliflag(t *testing.T) {
156156
require.NoError(t, err)
157157
require.Equal(t, def, got)
158158
require.Contains(t, flagset.FlagUsages(), usage)
159-
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf(" - consumes $%s", env))
159+
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf("Consumes $%s", env))
160160
})
161161

162162
t.Run("BoolEnvVar", func(t *testing.T) {
@@ -195,7 +195,7 @@ func TestCliflag(t *testing.T) {
195195
require.NoError(t, err)
196196
require.Equal(t, def, got)
197197
require.Contains(t, flagset.FlagUsages(), usage)
198-
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf(" - consumes $%s", env))
198+
require.Contains(t, flagset.FlagUsages(), fmt.Sprintf("Consumes $%s", env))
199199
})
200200

201201
t.Run("DurationEnvVar", func(t *testing.T) {

cli/cliui/cliui.go

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ var Styles = struct {
2626
Checkmark,
2727
Code,
2828
Crossmark,
29+
DateTimeStamp,
2930
Error,
3031
Field,
3132
Keyword,
@@ -42,6 +43,7 @@ var Styles = struct {
4243
Checkmark: defaultStyles.Checkmark,
4344
Code: defaultStyles.Code,
4445
Crossmark: defaultStyles.Error.Copy().SetString("✘"),
46+
DateTimeStamp: defaultStyles.LabelDim,
4547
Error: defaultStyles.Error,
4648
Field: defaultStyles.Code.Copy().Foreground(lipgloss.AdaptiveColor{Light: "#000000", Dark: "#FFFFFF"}),
4749
Keyword: defaultStyles.Keyword,

cli/create.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ func create() *cobra.Command {
155155
return err
156156
}
157157

158-
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nThe %s workspace has been created!\n", cliui.Styles.Keyword.Render(workspace.Name))
158+
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nThe %s workspace has been created at %s!\n", cliui.Styles.Keyword.Render(workspace.Name), cliui.Styles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
159159
return nil
160160
},
161161
}

cli/create_test.go

+17-19
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package cli_test
22

33
import (
44
"context"
5-
"database/sql"
65
"fmt"
76
"os"
87
"testing"
@@ -13,7 +12,6 @@ import (
1312

1413
"github.com/coder/coder/cli/clitest"
1514
"github.com/coder/coder/coderd/coderdtest"
16-
"github.com/coder/coder/coderd/database"
1715
"github.com/coder/coder/codersdk"
1816
"github.com/coder/coder/provisioner/echo"
1917
"github.com/coder/coder/provisionersdk/proto"
@@ -255,38 +253,38 @@ func TestCreate(t *testing.T) {
255253

256254
t.Run("FailedDryRun", func(t *testing.T) {
257255
t.Parallel()
258-
client, api := coderdtest.NewWithAPI(t, &coderdtest.Options{IncludeProvisionerD: true})
256+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
259257
user := coderdtest.CreateFirstUser(t, client)
260258
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
261-
Parse: echo.ParseComplete,
259+
Parse: []*proto.Parse_Response{{
260+
Type: &proto.Parse_Response_Complete{
261+
Complete: &proto.Parse_Complete{
262+
ParameterSchemas: echo.ParameterSuccess,
263+
},
264+
},
265+
}},
262266
ProvisionDryRun: []*proto.Provision_Response{
263267
{
264268
Type: &proto.Provision_Response_Complete{
265-
Complete: &proto.Provision_Complete{
266-
Error: "test error",
267-
},
269+
Complete: &proto.Provision_Complete{},
268270
},
269271
},
270272
},
271273
})
272274

275+
tempDir := t.TempDir()
276+
parameterFile, err := os.CreateTemp(tempDir, "testParameterFile*.yaml")
277+
require.NoError(t, err)
278+
defer parameterFile.Close()
279+
_, _ = parameterFile.WriteString(fmt.Sprintf("%s: %q", echo.ParameterExecKey, echo.ParameterError("fail")))
280+
273281
// The template import job should end up failed, but we need it to be
274282
// succeeded so the dry-run can begin.
275283
version = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
276-
require.Equal(t, codersdk.ProvisionerJobFailed, version.Job.Status, "job is not failed")
277-
err := api.Database.UpdateProvisionerJobWithCompleteByID(context.Background(), database.UpdateProvisionerJobWithCompleteByIDParams{
278-
ID: version.Job.ID,
279-
CompletedAt: sql.NullTime{
280-
Time: time.Now(),
281-
Valid: true,
282-
},
283-
UpdatedAt: time.Now(),
284-
Error: sql.NullString{},
285-
})
286-
require.NoError(t, err, "update provisioner job")
284+
require.Equal(t, codersdk.ProvisionerJobSucceeded, version.Job.Status, "job is not failed")
287285

288286
_ = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
289-
cmd, root := clitest.New(t, "create", "test")
287+
cmd, root := clitest.New(t, "create", "test", "--parameter-file", parameterFile.Name())
290288
clitest.SetupConfig(t, client, root)
291289
pty := ptytest.New(t)
292290
cmd.SetIn(pty.Input())

cli/delete.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ func deleteWorkspace() *cobra.Command {
4848
return err
4949
}
5050

51-
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nThe %s workspace has been deleted!\n", cliui.Styles.Keyword.Render(workspace.Name))
51+
_, _ = fmt.Fprintf(cmd.OutOrStdout(), "\nThe %s workspace has been deleted at %s!\n", cliui.Styles.Keyword.Render(workspace.Name), cliui.Styles.DateTimeStamp.Render(time.Now().Format(time.Stamp)))
5252
return nil
5353
},
5454
}

cli/dotfiles.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ func dotfiles() *cobra.Command {
2424
cmd := &cobra.Command{
2525
Use: "dotfiles [git_repo_url]",
2626
Args: cobra.ExactArgs(1),
27-
Short: "Checkout and install a dotfiles repository.",
27+
Short: "Check out and install a dotfiles repository.",
2828
Example: "coder dotfiles [-y] git@github.com:example/dotfiles.git",
2929
RunE: func(cmd *cobra.Command, args []string) error {
3030
var (

cli/gitssh_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ func TestGitSSH(t *testing.T) {
5858
coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
5959

6060
// start workspace agent
61-
cmd, root := clitest.New(t, "agent", "--agent-token", agentToken, "--agent-url", client.URL.String())
61+
cmd, root := clitest.New(t, "agent", "--agent-token", agentToken, "--agent-url", client.URL.String(), "--wireguard=false")
6262
agentClient := client
6363
clitest.SetupConfig(t, agentClient, root)
6464
ctx, cancelFunc := context.WithCancel(context.Background())

0 commit comments

Comments
 (0)