Skip to content

Commit a7fd5d2

Browse files
committed
Merge remote-tracking branch 'origin' into debounce-fix
2 parents 1903e42 + 1d8a4ed commit a7fd5d2

36 files changed

+1042
-423
lines changed

.github/dependabot.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ updates:
9292
- dependency-name: "@types/node"
9393
update-types:
9494
- version-update:semver-major
95+
open-pull-requests-limit: 15
9596
groups:
9697
react:
9798
patterns:

.github/workflows/ci.yaml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ jobs:
5353
docs:
5454
- "docs/**"
5555
- "README.md"
56-
- "examples/templates/**"
5756
- "examples/web-server/**"
5857
- "examples/monitoring/**"
5958
- "examples/lima/**"
@@ -741,7 +740,7 @@ jobs:
741740
uses: ./.github/actions/setup-sqlc
742741

743742
- name: GHCR Login
744-
uses: docker/login-action@v2
743+
uses: docker/login-action@v3
745744
with:
746745
registry: ghcr.io
747746
username: ${{ github.actor }}

.github/workflows/contrib.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
steps:
3535
- name: cla
3636
if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have read the CLA Document and I hereby sign the CLA') || github.event_name == 'pull_request_target'
37-
uses: contributor-assistant/github-action@v2.3.0
37+
uses: contributor-assistant/github-action@v2.3.1
3838
env:
3939
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
4040
# the below token should have repo scope and must be manually added by you in the repository's secret

.github/workflows/docker-base.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ jobs:
3535
uses: actions/checkout@v4
3636

3737
- name: Docker login
38-
uses: docker/login-action@v2
38+
uses: docker/login-action@v3
3939
with:
4040
registry: ghcr.io
4141
username: ${{ github.actor }}

.github/workflows/dogfood.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ jobs:
4646
- run: nix build .#devEnvImage && ./result | docker load
4747

4848
- name: Login to DockerHub
49-
uses: docker/login-action@v2
49+
uses: docker/login-action@v3
5050
with:
5151
username: ${{ secrets.DOCKERHUB_USERNAME }}
5252
password: ${{ secrets.DOCKERHUB_PASSWORD }}

.github/workflows/pr-deploy.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,7 @@ jobs:
216216
uses: ./.github/actions/setup-sqlc
217217

218218
- name: GHCR Login
219-
uses: docker/login-action@v2
219+
uses: docker/login-action@v3
220220
with:
221221
registry: ghcr.io
222222
username: ${{ github.actor }}

.github/workflows/release.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ jobs:
8585
cat "$CODER_RELEASE_NOTES_FILE"
8686
8787
- name: Docker Login
88-
uses: docker/login-action@v2
88+
uses: docker/login-action@v3
8989
with:
9090
registry: ghcr.io
9191
username: ${{ github.actor }}

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,6 @@ scaletest/terraform/secrets.tfvars
6464

6565
# Nix
6666
result
67+
68+
# Data dumps from unit tests
69+
**/*.test.sql

.prettierignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ scaletest/terraform/secrets.tfvars
6767

6868
# Nix
6969
result
70+
71+
# Data dumps from unit tests
72+
**/*.test.sql
7073
# .prettierignore.include:
7174
# Helm templates contain variables that are invalid YAML and can't be formatted
7275
# by Prettier.

cli/testdata/coder_templates_init_--help.golden

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ USAGE:
66
Get started with a templated template.
77

88
OPTIONS:
9-
--id aws-ecs-container|aws-linux|aws-windows|azure-linux|do-linux|docker|docker-with-dotfiles|fly-docker-image|gcp-linux|gcp-vm-container|gcp-windows|kubernetes
9+
--id aws-ecs-container|aws-linux|aws-windows|azure-linux|do-linux|docker|docker-with-dotfiles|gcp-linux|gcp-vm-container|gcp-windows|kubernetes
1010
Specify a given example template by ID.
1111

1212
———

coderd/database/dbtestutil/db.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
11
package dbtestutil
22

33
import (
4+
"bytes"
45
"context"
56
"database/sql"
67
"fmt"
78
"net/url"
89
"os"
10+
"os/exec"
11+
"path/filepath"
12+
"regexp"
913
"strings"
1014
"testing"
15+
"time"
1116

1217
"github.com/stretchr/testify/require"
18+
"golang.org/x/xerrors"
1319

1420
"github.com/coder/coder/v2/coderd/database"
1521
"github.com/coder/coder/v2/coderd/database/dbfake"
@@ -24,6 +30,7 @@ func WillUsePostgres() bool {
2430

2531
type options struct {
2632
fixedTimezone string
33+
dumpOnFailure bool
2734
}
2835

2936
type Option func(*options)
@@ -35,6 +42,13 @@ func WithTimezone(tz string) Option {
3542
}
3643
}
3744

45+
// WithDumpOnFailure will dump the entire database on test failure.
46+
func WithDumpOnFailure() Option {
47+
return func(o *options) {
48+
o.dumpOnFailure = true
49+
}
50+
}
51+
3852
func NewDB(t testing.TB, opts ...Option) (database.Store, pubsub.Pubsub) {
3953
t.Helper()
4054

@@ -74,6 +88,9 @@ func NewDB(t testing.TB, opts ...Option) (database.Store, pubsub.Pubsub) {
7488
t.Cleanup(func() {
7589
_ = sqlDB.Close()
7690
})
91+
if o.dumpOnFailure {
92+
t.Cleanup(func() { DumpOnFailure(t, connectionURL) })
93+
}
7794
db = database.New(sqlDB)
7895

7996
ps, err = pubsub.New(context.Background(), sqlDB, connectionURL)
@@ -110,3 +127,87 @@ func dbNameFromConnectionURL(t testing.TB, connectionURL string) string {
110127
require.NoError(t, err)
111128
return strings.TrimPrefix(u.Path, "/")
112129
}
130+
131+
// DumpOnFailure exports the database referenced by connectionURL to a file
132+
// corresponding to the current test, with a suffix indicating the time the
133+
// test was run.
134+
// To import this into a new database (assuming you have already run make test-postgres-docker):
135+
// - Create a new test database:
136+
// go run ./scripts/migrate-ci/main.go and note the database name it outputs
137+
// - Import the file into the above database:
138+
// psql 'postgres://postgres:postgres@127.0.0.1:5432/<dbname>?sslmode=disable' -f <path to file.test.sql>
139+
// - Run a dev server against that database:
140+
// ./scripts/coder-dev.sh server --postgres-url='postgres://postgres:postgres@127.0.0.1:5432/<dbname>?sslmode=disable'
141+
func DumpOnFailure(t testing.TB, connectionURL string) {
142+
if !t.Failed() {
143+
return
144+
}
145+
cwd, err := filepath.Abs(".")
146+
if err != nil {
147+
t.Errorf("dump on failure: cannot determine current working directory")
148+
return
149+
}
150+
snakeCaseName := regexp.MustCompile("[^a-zA-Z0-9-_]+").ReplaceAllString(t.Name(), "_")
151+
now := time.Now()
152+
timeSuffix := fmt.Sprintf("%d%d%d%d%d%d", now.Year(), now.Month(), now.Day(), now.Hour(), now.Minute(), now.Second())
153+
outPath := filepath.Join(cwd, snakeCaseName+"."+timeSuffix+".test.sql")
154+
dump, err := pgDump(connectionURL)
155+
if err != nil {
156+
t.Errorf("dump on failure: failed to run pg_dump")
157+
return
158+
}
159+
if err := os.WriteFile(outPath, filterDump(dump), 0o600); err != nil {
160+
t.Errorf("dump on failure: failed to write: %s", err.Error())
161+
return
162+
}
163+
t.Logf("Dumped database to %q due to failed test. I hope you find what you're looking for!", outPath)
164+
}
165+
166+
// pgDump runs pg_dump against dbURL and returns the output.
167+
func pgDump(dbURL string) ([]byte, error) {
168+
if _, err := exec.LookPath("pg_dump"); err != nil {
169+
return nil, xerrors.Errorf("could not find pg_dump in path: %w", err)
170+
}
171+
cmdArgs := []string{
172+
"pg_dump",
173+
dbURL,
174+
"--data-only",
175+
"--column-inserts",
176+
"--no-comments",
177+
"--no-privileges",
178+
"--no-publication",
179+
"--no-security-labels",
180+
"--no-subscriptions",
181+
"--no-tablespaces",
182+
// "--no-unlogged-table-data", // some tables are unlogged and may contain data of interest
183+
"--no-owner",
184+
"--exclude-table=schema_migrations",
185+
}
186+
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...) // nolint:gosec
187+
cmd.Env = []string{
188+
// "PGTZ=UTC", // This is probably not going to be useful if tz has been changed.
189+
"PGCLIENTENCODINDG=UTF8",
190+
"PGDATABASE=", // we should always specify the database name in the connection string
191+
}
192+
var stdout bytes.Buffer
193+
cmd.Stdout = &stdout
194+
if err := cmd.Run(); err != nil {
195+
return nil, xerrors.Errorf("exec pg_dump: %w", err)
196+
}
197+
return stdout.Bytes(), nil
198+
}
199+
200+
func filterDump(dump []byte) []byte {
201+
lines := bytes.Split(dump, []byte{'\n'})
202+
var buf bytes.Buffer
203+
for _, line := range lines {
204+
// We dump in column-insert format, so these are the only lines
205+
// we care about
206+
if !bytes.HasPrefix(line, []byte("INSERT")) {
207+
continue
208+
}
209+
_, _ = buf.Write(line)
210+
_, _ = buf.WriteRune('\n')
211+
}
212+
return buf.Bytes()
213+
}

coderd/database/dump.sql

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
ALTER TABLE ONLY workspaces
2+
ALTER COLUMN last_used_at
3+
SET DATA TYPE timestamp
4+
USING last_used_at::timestamptz AT TIME ZONE 'UTC',
5+
ALTER COLUMN last_used_at
6+
SET DEFAULT '0001-01-01 00:00:00'::timestamp;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
ALTER TABLE ONLY workspaces
2+
ALTER COLUMN last_used_at
3+
SET DATA TYPE timestamptz
4+
USING last_used_at::timestamp AT TIME ZONE 'UTC',
5+
ALTER COLUMN last_used_at
6+
SET DEFAULT '0001-01-01 00:00:00+00:00'::timestamptz;

coderd/workspaceagents.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1808,7 +1808,7 @@ func convertWorkspaceAgentMetadata(db []database.WorkspaceAgentMetadatum) []code
18081808
Result: codersdk.WorkspaceAgentMetadataResult{
18091809
Value: datum.Value,
18101810
Error: datum.Error,
1811-
CollectedAt: datum.CollectedAt,
1811+
CollectedAt: datum.CollectedAt.UTC(),
18121812
Age: int64(time.Since(datum.CollectedAt).Seconds()),
18131813
},
18141814
Description: codersdk.WorkspaceAgentMetadataDescription{

coderd/workspaceagents_test.go

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ import (
2323
"github.com/coder/coder/v2/agent"
2424
"github.com/coder/coder/v2/coderd/coderdtest"
2525
"github.com/coder/coder/v2/coderd/database"
26-
"github.com/coder/coder/v2/coderd/database/dbtestutil"
2726
"github.com/coder/coder/v2/coderd/database/dbtime"
2827
"github.com/coder/coder/v2/codersdk"
2928
"github.com/coder/coder/v2/codersdk/agentsdk"
@@ -1185,12 +1184,8 @@ func TestWorkspaceAgent_LifecycleState(t *testing.T) {
11851184
func TestWorkspaceAgent_Metadata(t *testing.T) {
11861185
t.Parallel()
11871186

1188-
// nolint:gocritic // https://github.com/coder/coder/issues/9682
1189-
db, ps := dbtestutil.NewDB(t, dbtestutil.WithTimezone("UTC"))
11901187
client := coderdtest.New(t, &coderdtest.Options{
11911188
IncludeProvisionerDaemon: true,
1192-
Database: db,
1193-
Pubsub: ps,
11941189
})
11951190
user := coderdtest.CreateFirstUser(t, client)
11961191
authToken := uuid.NewString()

coderd/workspaces_test.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1515,12 +1515,8 @@ func TestWorkspaceFilterManual(t *testing.T) {
15151515
t.Run("LastUsed", func(t *testing.T) {
15161516
t.Parallel()
15171517

1518-
// nolint:gocritic // https://github.com/coder/coder/issues/9682
1519-
db, ps := dbtestutil.NewDB(t, dbtestutil.WithTimezone("UTC"))
15201518
client, _, api := coderdtest.NewWithAPI(t, &coderdtest.Options{
15211519
IncludeProvisionerDaemon: true,
1522-
Database: db,
1523-
Pubsub: ps,
15241520
})
15251521
user := coderdtest.CreateFirstUser(t, client)
15261522
authToken := uuid.NewString()

docs/cli/templates_init.md

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/images/display-apps.png

25.1 KB
Loading

docs/templates/index.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,29 @@ By default, all templates allow developers to connect over SSH and a web
411411
terminal. See [Configuring Web IDEs](../ides/web-ides.md) to learn how to give
412412
users access to additional web applications.
413413

414+
Template administrators can hide apps like the web-based Terminal or VS Code
415+
Desktop with the
416+
[`display_apps`](https://registry.terraform.io/providers/coder/coder/0.11.2/docs/resources/agent#display_apps)
417+
configuration in the
418+
[`coder_agent`](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent)
419+
resource. For example, the following configuration block will hide all default
420+
Coder apps except the web terminal.
421+
422+
```hcl
423+
display_apps {
424+
vscode = false
425+
vscode_insiders = false
426+
ssh_helper = false
427+
port_forwarding_helper = false
428+
web_terminal = true
429+
}
430+
```
431+
432+
Example use cases for `display_apps` are JetBrains users or zero-trust
433+
deployments who do not want nor should have access to a local VS Code IDE.
434+
435+
![display-apps](../images/display-apps.png)
436+
414437
### Data source
415438

416439
When a workspace is being started or stopped, the `coder_workspace` data source

0 commit comments

Comments
 (0)