Skip to content

Commit 1d934e8

Browse files
committed
Merge branch 'main' into parameter
2 parents 5d9ac64 + 3ab8d57 commit 1d934e8

File tree

68 files changed

+1543
-1453
lines changed

Some content is hidden

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

68 files changed

+1543
-1453
lines changed

.github/workflows/coder.yaml

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,12 @@ jobs:
6464
- '**'
6565
docs:
6666
- 'docs/**'
67-
# For testing:
68-
# - '.github/**'
6967
sh:
7068
- "**.sh"
69+
go:
70+
- "**.go"
71+
tf:
72+
- "**.tf"
7173
ts:
7274
- 'site/**'
7375
k8s:
@@ -92,6 +94,8 @@ jobs:
9294
name: style/lint/golangci
9395
timeout-minutes: 5
9496
runs-on: ubuntu-latest
97+
needs: changes
98+
if: needs.changes.outputs.go == 'true'
9599
steps:
96100
- uses: actions/checkout@v3
97101
- uses: actions/setup-go@v3
@@ -115,6 +119,8 @@ jobs:
115119
name: style/lint/shellcheck
116120
timeout-minutes: 5
117121
runs-on: ubuntu-latest
122+
needs: changes
123+
if: needs.changes.outputs.sh == 'true'
118124
steps:
119125
- uses: actions/checkout@v3
120126
- name: Run ShellCheck
@@ -128,6 +134,8 @@ jobs:
128134
name: "style/lint/typescript"
129135
timeout-minutes: 5
130136
runs-on: ubuntu-latest
137+
needs: changes
138+
if: needs.changes.outputs.ts == 'true'
131139
steps:
132140
- name: Checkout
133141
uses: actions/checkout@v3
@@ -247,6 +255,8 @@ jobs:
247255
name: "style/fmt"
248256
runs-on: ubuntu-latest
249257
timeout-minutes: 5
258+
needs: changes
259+
if: needs.changes.outputs.sh == 'true' || needs.changes.outputs.ts == 'true' || needs.changes.outputs.tf == 'true'
250260
steps:
251261
- name: Checkout
252262
uses: actions/checkout@v3
@@ -280,6 +290,7 @@ jobs:
280290
name: "test/go"
281291
runs-on: ${{ matrix.os }}
282292
timeout-minutes: 20
293+
needs: changes
283294
strategy:
284295
matrix:
285296
os:
@@ -288,30 +299,36 @@ jobs:
288299
- windows-2022
289300
steps:
290301
- uses: actions/checkout@v3
302+
if: needs.changes.outputs.go == 'true'
291303

292304
- uses: actions/setup-go@v3
305+
if: needs.changes.outputs.go == 'true'
293306
with:
294307
go-version: "~1.19"
295308

296309
- name: Echo Go Cache Paths
310+
if: needs.changes.outputs.go == 'true'
297311
id: go-cache-paths
298312
run: |
299313
echo "::set-output name=go-build::$(go env GOCACHE)"
300314
echo "::set-output name=go-mod::$(go env GOMODCACHE)"
301315
302316
- name: Go Build Cache
317+
if: needs.changes.outputs.go == 'true'
303318
uses: actions/cache@v3
304319
with:
305320
path: ${{ steps.go-cache-paths.outputs.go-build }}
306321
key: ${{ runner.os }}-go-build-${{ hashFiles('**/go.**', '**.go') }}
307322

308323
- name: Go Mod Cache
324+
if: needs.changes.outputs.go == 'true'
309325
uses: actions/cache@v3
310326
with:
311327
path: ${{ steps.go-cache-paths.outputs.go-mod }}
312328
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}
313329

314330
- name: Install gotestsum
331+
if: needs.changes.outputs.go == 'true'
315332
uses: jaxxstorm/action-install-gh-release@v1.7.1
316333
env:
317334
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -320,11 +337,13 @@ jobs:
320337
tag: v1.7.0
321338

322339
- uses: hashicorp/setup-terraform@v2
340+
if: needs.changes.outputs.go == 'true'
323341
with:
324342
terraform_version: 1.1.9
325343
terraform_wrapper: false
326344

327345
- name: Test with Mock Database
346+
if: needs.changes.outputs.go == 'true'
328347
id: test
329348
shell: bash
330349
run: |
@@ -350,7 +369,7 @@ jobs:
350369
# that is no guarantee, see:
351370
# https://github.com/codecov/codecov-action/issues/788
352371
continue-on-error: true
353-
if: steps.test.outputs.cover && github.actor != 'dependabot[bot]' && !github.event.pull_request.head.repo.fork
372+
if: steps.test.outputs.cover && github.actor != 'dependabot[bot]' && !github.event.pull_request.head.repo.fork && needs.changes.outputs.go == 'true'
354373
with:
355374
token: ${{ secrets.CODECOV_TOKEN }}
356375
files: ./gotests.coverage
@@ -364,6 +383,8 @@ jobs:
364383
# goroutines. Setting this to the timeout +5m should work quite well
365384
# even if some of the preceding steps are slow.
366385
timeout-minutes: 25
386+
needs: changes
387+
if: needs.changes.outputs.go == 'true'
367388
steps:
368389
- uses: actions/checkout@v3
369390

@@ -489,6 +510,7 @@ jobs:
489510
go mod download
490511
491512
version="$(./scripts/version.sh)"
513+
make gen/mark-fresh
492514
make -j \
493515
build/coder_"$version"_windows_amd64.zip \
494516
build/coder_"$version"_linux_amd64.{tar.gz,deb}
@@ -517,6 +539,8 @@ jobs:
517539
name: "test/js"
518540
runs-on: ubuntu-latest
519541
timeout-minutes: 20
542+
needs: changes
543+
if: needs.changes.outputs.ts == 'true'
520544
steps:
521545
- uses: actions/checkout@v3
522546

@@ -555,9 +579,8 @@ jobs:
555579

556580
test-e2e:
557581
name: "test/e2e/${{ matrix.os }}"
558-
needs:
559-
- changes
560-
if: needs.changes.outputs.docs-only == 'false'
582+
needs: changes
583+
if: needs.changes.outputs.go == 'true' || needs.changes.outputs.ts == 'true' || needs.changes.outputs.tf == 'true'
561584
runs-on: ${{ matrix.os }}
562585
timeout-minutes: 20
563586
strategy:

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ site/**/*.typegen.ts
3131
site/build-storybook.log
3232

3333
# Build
34-
build/
35-
dist/
34+
/build/
35+
/dist/
3636
site/out/
3737

3838
*.tfstate

cli/cliui/table.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ func DisplayTable(out any, sort string, filterColumns []string) (string, error)
6767
}
6868

6969
// Get the list of table column headers.
70-
headersRaw, err := TypeToTableHeaders(v.Type().Elem())
70+
headersRaw, err := typeToTableHeaders(v.Type().Elem())
7171
if err != nil {
7272
return "", xerrors.Errorf("get table headers recursively for type %q: %w", v.Type().Elem().String(), err)
7373
}
@@ -207,10 +207,10 @@ func isStructOrStructPointer(t reflect.Type) bool {
207207
return t.Kind() == reflect.Struct || (t.Kind() == reflect.Pointer && t.Elem().Kind() == reflect.Struct)
208208
}
209209

210-
// TypeToTableHeaders converts a type to a slice of column names. If the given
210+
// typeToTableHeaders converts a type to a slice of column names. If the given
211211
// type is invalid (not a struct or a pointer to a struct, has invalid table
212212
// tags, etc.), an error is returned.
213-
func TypeToTableHeaders(t reflect.Type) ([]string, error) {
213+
func typeToTableHeaders(t reflect.Type) ([]string, error) {
214214
if !isStructOrStructPointer(t) {
215215
return nil, xerrors.Errorf("typeToTableHeaders called with a non-struct or a non-pointer-to-a-struct type")
216216
}
@@ -235,7 +235,7 @@ func TypeToTableHeaders(t reflect.Type) ([]string, error) {
235235
return nil, xerrors.Errorf("field %q in type %q is marked as recursive but does not contain a struct or a pointer to a struct", field.Name, t.String())
236236
}
237237

238-
childNames, err := TypeToTableHeaders(fieldType)
238+
childNames, err := typeToTableHeaders(fieldType)
239239
if err != nil {
240240
return nil, xerrors.Errorf("get child field header names for field %q in type %q: %w", field.Name, fieldType.String(), err)
241241
}
@@ -305,3 +305,18 @@ func valueToTableMap(val reflect.Value) (map[string]any, error) {
305305

306306
return row, nil
307307
}
308+
309+
// TableHeaders returns the table header names of all
310+
// fields in tSlice. tSlice must be a slice of some type.
311+
func TableHeaders(tSlice any) ([]string, error) {
312+
v := reflect.Indirect(reflect.ValueOf(tSlice))
313+
rawHeaders, err := typeToTableHeaders(v.Type().Elem())
314+
if err != nil {
315+
return nil, xerrors.Errorf("type to table headers: %w", err)
316+
}
317+
out := make([]string, 0, len(rawHeaders))
318+
for _, hdr := range rawHeaders {
319+
out = append(out, strings.Replace(hdr, " ", "_", -1))
320+
}
321+
return out, nil
322+
}

cli/cliui/table_test.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,28 @@ baz baz1 baz3 Aug 2 15:49:10
327327
})
328328
}
329329

330+
func Test_TableHeaders(t *testing.T) {
331+
t.Parallel()
332+
s := []tableTest1{}
333+
expectedFields := []string{
334+
"name",
335+
"age",
336+
"roles",
337+
"sub_1_name",
338+
"sub_1_age",
339+
"sub_2_name",
340+
"sub_2_age",
341+
"sub_3_inner_name",
342+
"sub_3_inner_age",
343+
"sub_4",
344+
"time",
345+
"time_ptr",
346+
}
347+
headers, err := cliui.TableHeaders(s)
348+
require.NoError(t, err)
349+
require.EqualValues(t, expectedFields, headers)
350+
}
351+
330352
// compareTables normalizes the incoming table lines
331353
func compareTables(t *testing.T, expected, out string) {
332354
t.Helper()

cli/list.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package cli
22

33
import (
44
"fmt"
5-
"reflect"
65
"strings"
76
"time"
87

@@ -128,14 +127,10 @@ func list() *cobra.Command {
128127
},
129128
}
130129

131-
v := reflect.Indirect(reflect.ValueOf(displayWorkspaces))
132-
availColumns, err := cliui.TypeToTableHeaders(v.Type().Elem())
130+
availColumns, err := cliui.TableHeaders(displayWorkspaces)
133131
if err != nil {
134132
panic(err)
135133
}
136-
for i, s := range availColumns {
137-
availColumns[i] = strings.Replace(s, " ", "_", -1)
138-
}
139134
columnString := strings.Join(availColumns[:], ", ")
140135

141136
cmd.Flags().BoolVarP(&all, "all", "a", false,

coderd/coderd.go

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"github.com/coder/coder/coderd/rbac"
3636
"github.com/coder/coder/coderd/telemetry"
3737
"github.com/coder/coder/coderd/tracing"
38+
"github.com/coder/coder/coderd/workspacequota"
3839
"github.com/coder/coder/coderd/wsconncache"
3940
"github.com/coder/coder/codersdk"
4041
"github.com/coder/coder/site"
@@ -55,6 +56,7 @@ type Options struct {
5556
CacheDir string
5657

5758
Auditor audit.Auditor
59+
WorkspaceQuotaEnforcer workspacequota.Enforcer
5860
AgentConnectionUpdateFrequency time.Duration
5961
AgentInactiveDisconnectTimeout time.Duration
6062
// APIRateLimit is the minutely throughput rate limit per user or ip.
@@ -120,6 +122,9 @@ func New(options *Options) *API {
120122
if options.Auditor == nil {
121123
options.Auditor = audit.NewNop()
122124
}
125+
if options.WorkspaceQuotaEnforcer == nil {
126+
options.WorkspaceQuotaEnforcer = workspacequota.NewNop()
127+
}
123128

124129
siteCacheDir := options.CacheDir
125130
if siteCacheDir != "" {
@@ -145,10 +150,12 @@ func New(options *Options) *API {
145150
Authorizer: options.Authorizer,
146151
Logger: options.Logger,
147152
},
148-
metricsCache: metricsCache,
149-
Auditor: atomic.Pointer[audit.Auditor]{},
153+
metricsCache: metricsCache,
154+
Auditor: atomic.Pointer[audit.Auditor]{},
155+
WorkspaceQuotaEnforcer: atomic.Pointer[workspacequota.Enforcer]{},
150156
}
151157
api.Auditor.Store(&options.Auditor)
158+
api.WorkspaceQuotaEnforcer.Store(&options.WorkspaceQuotaEnforcer)
152159
api.workspaceAgentCache = wsconncache.New(api.dialWorkspaceAgentTailnet, 0)
153160
api.derpServer = derp.NewServer(key.NewNode(), tailnet.Logger(options.Logger))
154161
oauthConfigs := &httpmw.OAuth2Configs{
@@ -517,6 +524,7 @@ type API struct {
517524
*Options
518525
Auditor atomic.Pointer[audit.Auditor]
519526
WorkspaceClientCoordinateOverride atomic.Pointer[func(rw http.ResponseWriter) bool]
527+
WorkspaceQuotaEnforcer atomic.Pointer[workspacequota.Enforcer]
520528
HTTPAuth *HTTPAuthorizer
521529

522530
// APIHandler serves "/api/v2"

coderd/database/databasefake/databasefake.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,6 +702,22 @@ func (q *fakeQuerier) GetWorkspaceBuildByID(_ context.Context, id uuid.UUID) (da
702702
return database.WorkspaceBuild{}, sql.ErrNoRows
703703
}
704704

705+
func (q *fakeQuerier) GetWorkspaceCountByUserID(_ context.Context, id uuid.UUID) (int64, error) {
706+
q.mutex.RLock()
707+
defer q.mutex.RUnlock()
708+
var count int64
709+
for _, workspace := range q.workspaces {
710+
if workspace.OwnerID.String() == id.String() {
711+
if workspace.Deleted {
712+
continue
713+
}
714+
715+
count++
716+
}
717+
}
718+
return count, nil
719+
}
720+
705721
func (q *fakeQuerier) GetWorkspaceBuildByJobID(_ context.Context, jobID uuid.UUID) (database.WorkspaceBuild, error) {
706722
q.mutex.RLock()
707723
defer q.mutex.RUnlock()
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DROP INDEX users_email_lower_idx;

coderd/database/querier.go

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

coderd/database/queries.sql.go

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

0 commit comments

Comments
 (0)