Skip to content

Commit f2c6ab6

Browse files
committed
Merge branch 'main' of https://github.com/coder/coder into bq/xray-ui
2 parents da85eec + 76e7328 commit f2c6ab6

File tree

126 files changed

+2564
-1772
lines changed

Some content is hidden

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

126 files changed

+2564
-1772
lines changed

.dockerignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Ignore all files and folders
2+
**
3+
4+
# Include flake.nix and flake.lock
5+
!flake.nix
6+
!flake.lock

.github/workflows/ci.yaml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,8 @@ jobs:
516516
NODE_OPTIONS: "--max_old_space_size=4096"
517517
STORYBOOK: true
518518
with:
519-
buildScriptName: "storybook:build"
519+
# Do a fast, testing build for change previews
520+
buildScriptName: "storybook:ci"
520521
exitOnceUploaded: true
521522
# This will prevent CI from failing when Chromatic detects visual changes
522523
exitZeroOnChanges: true
@@ -530,6 +531,8 @@ jobs:
530531
# Run TurboSnap to trace file dependencies to related stories
531532
# and tell chromatic to only take snapshots of relevent stories
532533
onlyChanged: true
534+
# Avoid uploading single files, because that's very slow
535+
zip: true
533536

534537
# This is a separate step for mainline only that auto accepts and changes
535538
# instead of holding CI up. Since we squash/merge, this is defensive to
@@ -547,13 +550,16 @@ jobs:
547550
autoAcceptChanges: true
548551
# This will prevent CI from failing when Chromatic detects visual changes
549552
exitZeroOnChanges: true
553+
# Do a full build with documentation for mainline builds
550554
buildScriptName: "storybook:build"
551555
projectToken: 695c25b6cb65
552556
workingDir: "./site"
553557
storybookBaseDir: "./site"
554558
# Run TurboSnap to trace file dependencies to related stories
555559
# and tell chromatic to only take snapshots of relevent stories
556560
onlyChanged: true
561+
# Avoid uploading single files, because that's very slow
562+
zip: true
557563

558564
offlinedocs:
559565
name: offlinedocs
@@ -726,7 +732,7 @@ jobs:
726732
727733
# Define specific tags
728734
tags=("$tag" "main" "latest")
729-
735+
730736
# Create and push a multi-arch manifest for each tag
731737
# we are adding `latest` tag and keeping `main` for backward
732738
# compatibality

.github/workflows/dogfood.yaml

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,14 @@ on:
77
paths:
88
- "dogfood/**"
99
- ".github/workflows/dogfood.yaml"
10+
- "flake.lock"
11+
- "flake.nix"
1012
pull_request:
1113
paths:
1214
- "dogfood/**"
1315
- ".github/workflows/dogfood.yaml"
16+
- "flake.lock"
17+
- "flake.nix"
1418
workflow_dispatch:
1519

1620
jobs:
@@ -45,17 +49,31 @@ jobs:
4549
username: ${{ secrets.DOCKERHUB_USERNAME }}
4650
password: ${{ secrets.DOCKERHUB_PASSWORD }}
4751

48-
- name: Build and push
52+
- name: Build and push Non-Nix image
4953
uses: depot/build-push-action@v1
5054
with:
5155
project: b4q6ltmpzh
5256
token: ${{ secrets.DEPOT_TOKEN }}
5357
buildx-fallback: true
5458
context: "{{defaultContext}}:dogfood"
5559
pull: true
60+
save: true
5661
push: ${{ github.ref == 'refs/heads/main' }}
5762
tags: "codercom/oss-dogfood:${{ steps.docker-tag-name.outputs.tag }},codercom/oss-dogfood:latest"
5863

64+
- name: Build and push Nix image
65+
uses: depot/build-push-action@v1
66+
with:
67+
project: b4q6ltmpzh
68+
token: ${{ secrets.DEPOT_TOKEN }}
69+
buildx-fallback: true
70+
context: "."
71+
file: "dogfood/Dockerfile.nix"
72+
pull: true
73+
save: true
74+
push: ${{ github.ref == 'refs/heads/main' }}
75+
tags: "codercom/oss-dogfood-nix:${{ steps.docker-tag-name.outputs.tag }},codercom/oss-dogfood-nix:latest"
76+
5977
deploy_template:
6078
needs: build_image
6179
runs-on: ubuntu-latest

cli/login.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818

1919
"github.com/coder/pretty"
2020

21+
"github.com/coder/coder/v2/buildinfo"
2122
"github.com/coder/coder/v2/cli/clibase"
2223
"github.com/coder/coder/v2/cli/cliui"
2324
"github.com/coder/coder/v2/coderd/userpassword"
@@ -175,7 +176,7 @@ func (r *RootCmd) login() *clibase.Cmd {
175176
// Try to check the version of the server prior to logging in.
176177
// It may be useful to warn the user if they are trying to login
177178
// on a very old client.
178-
err = r.checkVersions(inv, client)
179+
err = r.checkVersions(inv, client, buildinfo.Version())
179180
if err != nil {
180181
// Checking versions isn't a fatal error so we print a warning
181182
// and proceed.

cli/root.go

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ func (r *RootCmd) PrintWarnings(client *codersdk.Client) clibase.MiddlewareFunc
602602
warningErr = make(chan error)
603603
)
604604
go func() {
605-
versionErr <- r.checkVersions(inv, client)
605+
versionErr <- r.checkVersions(inv, client, buildinfo.Version())
606606
close(versionErr)
607607
}()
608608

@@ -812,38 +812,39 @@ func formatExamples(examples ...example) string {
812812
return sb.String()
813813
}
814814

815-
func (r *RootCmd) checkVersions(i *clibase.Invocation, client *codersdk.Client) error {
815+
// checkVersions checks to see if there's a version mismatch between the client
816+
// and server and prints a message nudging the user to upgrade if a mismatch
817+
// is detected. forceCheck is a test flag and should always be false in production.
818+
//
819+
//nolint:revive
820+
func (r *RootCmd) checkVersions(i *clibase.Invocation, client *codersdk.Client, clientVersion string) error {
816821
if r.noVersionCheck {
817822
return nil
818823
}
819824

820825
ctx, cancel := context.WithTimeout(i.Context(), 10*time.Second)
821826
defer cancel()
822827

823-
clientVersion := buildinfo.Version()
824-
info, err := client.BuildInfo(ctx)
828+
serverInfo, err := client.BuildInfo(ctx)
825829
// Avoid printing errors that are connection-related.
826830
if isConnectionError(err) {
827831
return nil
828832
}
829-
830833
if err != nil {
831834
return xerrors.Errorf("build info: %w", err)
832835
}
833836

834-
fmtWarningText := `version mismatch: client %s, server %s
835-
`
836-
// Our installation script doesn't work on Windows, so instead we direct the user
837-
// to the GitHub release page to download the latest installer.
838-
if runtime.GOOS == "windows" {
839-
fmtWarningText += `download the server version from: https://github.com/coder/coder/releases/v%s`
840-
} else {
841-
fmtWarningText += `download the server version with: 'curl -L https://coder.com/install.sh | sh -s -- --version %s'`
842-
}
837+
if !buildinfo.VersionsMatch(clientVersion, serverInfo.Version) {
838+
upgradeMessage := defaultUpgradeMessage(serverInfo.CanonicalVersion())
839+
if serverInfo.UpgradeMessage != "" {
840+
upgradeMessage = serverInfo.UpgradeMessage
841+
}
842+
843+
fmtWarningText := "version mismatch: client %s, server %s\n%s"
844+
fmtWarn := pretty.Sprint(cliui.DefaultStyles.Warn, fmtWarningText)
845+
warning := fmt.Sprintf(fmtWarn, clientVersion, serverInfo.Version, upgradeMessage)
843846

844-
if !buildinfo.VersionsMatch(clientVersion, info.Version) {
845-
warn := cliui.DefaultStyles.Warn
846-
_, _ = fmt.Fprintf(i.Stderr, pretty.Sprint(warn, fmtWarningText), clientVersion, info.Version, strings.TrimPrefix(info.CanonicalVersion(), "v"))
847+
_, _ = fmt.Fprint(i.Stderr, warning)
847848
_, _ = fmt.Fprintln(i.Stderr)
848849
}
849850

@@ -1216,3 +1217,13 @@ func SlimUnsupported(w io.Writer, cmd string) {
12161217
//nolint:revive
12171218
os.Exit(1)
12181219
}
1220+
1221+
func defaultUpgradeMessage(version string) string {
1222+
// Our installation script doesn't work on Windows, so instead we direct the user
1223+
// to the GitHub release page to download the latest installer.
1224+
version = strings.TrimPrefix(version, "v")
1225+
if runtime.GOOS == "windows" {
1226+
return fmt.Sprintf("download the server version from: https://github.com/coder/coder/releases/v%s", version)
1227+
}
1228+
return fmt.Sprintf("download the server version with: 'curl -L https://coder.com/install.sh | sh -s -- --version %s'", version)
1229+
}

cli/root_internal_test.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,24 @@
11
package cli
22

33
import (
4+
"bytes"
5+
"fmt"
6+
"net/http"
7+
"net/http/httptest"
8+
"net/url"
49
"os"
510
"runtime"
611
"testing"
712

813
"github.com/stretchr/testify/require"
914
"go.uber.org/goleak"
15+
16+
"github.com/coder/coder/v2/buildinfo"
17+
"github.com/coder/coder/v2/cli/cliui"
18+
"github.com/coder/coder/v2/coderd"
19+
"github.com/coder/coder/v2/coderd/httpapi"
20+
"github.com/coder/coder/v2/codersdk"
21+
"github.com/coder/pretty"
1022
)
1123

1224
func Test_formatExamples(t *testing.T) {
@@ -84,3 +96,85 @@ func TestMain(m *testing.M) {
8496
goleak.IgnoreTopFunction("github.com/lib/pq.NewDialListener"),
8597
)
8698
}
99+
100+
func Test_checkVersions(t *testing.T) {
101+
t.Parallel()
102+
103+
t.Run("CustomUpgradeMessage", func(t *testing.T) {
104+
t.Parallel()
105+
106+
expectedUpgradeMessage := "My custom upgrade message"
107+
108+
srv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
109+
httpapi.Write(r.Context(), rw, http.StatusOK, codersdk.BuildInfoResponse{
110+
ExternalURL: buildinfo.ExternalURL(),
111+
// Provide a version that will not match
112+
Version: "v1.0.0",
113+
AgentAPIVersion: coderd.AgentAPIVersionREST,
114+
// does not matter what the url is
115+
DashboardURL: "https://example.com",
116+
WorkspaceProxy: false,
117+
UpgradeMessage: expectedUpgradeMessage,
118+
})
119+
}))
120+
defer srv.Close()
121+
surl, err := url.Parse(srv.URL)
122+
require.NoError(t, err)
123+
124+
client := codersdk.New(surl)
125+
126+
r := &RootCmd{}
127+
128+
cmd, err := r.Command(nil)
129+
require.NoError(t, err)
130+
131+
var buf bytes.Buffer
132+
inv := cmd.Invoke()
133+
inv.Stderr = &buf
134+
135+
err = r.checkVersions(inv, client, "v2.0.0")
136+
require.NoError(t, err)
137+
138+
fmtOutput := fmt.Sprintf("version mismatch: client v2.0.0, server v1.0.0\n%s", expectedUpgradeMessage)
139+
expectedOutput := fmt.Sprintln(pretty.Sprint(cliui.DefaultStyles.Warn, fmtOutput))
140+
require.Equal(t, expectedOutput, buf.String())
141+
})
142+
143+
t.Run("DefaultUpgradeMessage", func(t *testing.T) {
144+
t.Parallel()
145+
146+
srv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
147+
httpapi.Write(r.Context(), rw, http.StatusOK, codersdk.BuildInfoResponse{
148+
ExternalURL: buildinfo.ExternalURL(),
149+
// Provide a version that will not match
150+
Version: "v1.0.0",
151+
AgentAPIVersion: coderd.AgentAPIVersionREST,
152+
// does not matter what the url is
153+
DashboardURL: "https://example.com",
154+
WorkspaceProxy: false,
155+
UpgradeMessage: "",
156+
})
157+
}))
158+
defer srv.Close()
159+
surl, err := url.Parse(srv.URL)
160+
require.NoError(t, err)
161+
162+
client := codersdk.New(surl)
163+
164+
r := &RootCmd{}
165+
166+
cmd, err := r.Command(nil)
167+
require.NoError(t, err)
168+
169+
var buf bytes.Buffer
170+
inv := cmd.Invoke()
171+
inv.Stderr = &buf
172+
173+
err = r.checkVersions(inv, client, "v2.0.0")
174+
require.NoError(t, err)
175+
176+
fmtOutput := fmt.Sprintf("version mismatch: client v2.0.0, server v1.0.0\n%s", defaultUpgradeMessage("v1.0.0"))
177+
expectedOutput := fmt.Sprintln(pretty.Sprint(cliui.DefaultStyles.Warn, fmtOutput))
178+
require.Equal(t, expectedOutput, buf.String())
179+
})
180+
}

cli/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
673673
}()
674674

675675
options.Database = database.New(sqlDB)
676-
options.Pubsub, err = pubsub.New(ctx, sqlDB, dbURL)
676+
options.Pubsub, err = pubsub.New(ctx, logger.Named("pubsub"), sqlDB, dbURL)
677677
if err != nil {
678678
return xerrors.Errorf("create pubsub: %w", err)
679679
}

cli/testdata/coder_server_--help.golden

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ CLIENT OPTIONS:
6565
These options change the behavior of how clients interact with the Coder.
6666
Clients include the coder cli, vs code extension, and the web UI.
6767

68+
--cli-upgrade-message string, $CODER_CLI_UPGRADE_MESSAGE
69+
The upgrade message to display to users when a client/server mismatch
70+
is detected. By default it instructs users to update using 'curl -L
71+
https://coder.com/install.sh | sh'.
72+
6873
--ssh-config-options string-array, $CODER_SSH_CONFIG_OPTIONS
6974
These SSH config options will override the default SSH config options.
7075
Provide options in "key=value" or "key value" format separated by

cli/testdata/server-config.yaml.golden

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,11 @@ client:
433433
# incorrectly can break SSH to your deployment, use cautiously.
434434
# (default: <unset>, type: string-array)
435435
sshConfigOptions: []
436+
# The upgrade message to display to users when a client/server mismatch is
437+
# detected. By default it instructs users to update using 'curl -L
438+
# https://coder.com/install.sh | sh'.
439+
# (default: <unset>, type: string)
440+
cliUpgradeMessage: ""
436441
# The renderer to use when opening a web terminal. Valid values are 'canvas',
437442
# 'webgl', or 'dom'.
438443
# (default: canvas, type: string)

0 commit comments

Comments
 (0)