Skip to content

Commit e50fd7c

Browse files
authored
Merge branch 'main' into cj/dogfood-tasks
2 parents 34b0423 + b2b3edf commit e50fd7c

Some content is hidden

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

54 files changed

+1387
-908
lines changed

.github/workflows/release.yaml

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,36 @@ env:
3232
CODER_RELEASE_NOTES: ${{ inputs.release_notes }}
3333

3434
jobs:
35+
# Only allow maintainers/admins to release.
36+
check-perms:
37+
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || 'ubuntu-latest' }}
38+
steps:
39+
- name: Allow only maintainers/admins
40+
uses: actions/github-script@v7.0.1
41+
with:
42+
github-token: ${{ secrets.GITHUB_TOKEN }}
43+
script: |
44+
const {data} = await github.rest.repos.getCollaboratorPermissionLevel({
45+
owner: context.repo.owner,
46+
repo: context.repo.repo,
47+
username: context.actor
48+
});
49+
const role = data.role_name || data.user?.role_name || data.permission;
50+
const perms = data.user?.permissions || {};
51+
core.info(`Actor ${context.actor} permission=${data.permission}, role_name=${role}`);
52+
53+
const allowed =
54+
role === 'admin' ||
55+
role === 'maintain' ||
56+
perms.admin === true ||
57+
perms.maintain === true;
58+
59+
if (!allowed) core.setFailed('Denied: requires maintain or admin');
60+
3561
# build-dylib is a separate job to build the dylib on macOS.
3662
build-dylib:
3763
runs-on: ${{ github.repository_owner == 'coder' && 'depot-macos-latest' || 'macos-latest' }}
64+
needs: check-perms
3865
steps:
3966
# Harden Runner doesn't work on macOS.
4067
- name: Checkout
@@ -114,7 +141,7 @@ jobs:
114141

115142
release:
116143
name: Build and publish
117-
needs: build-dylib
144+
needs: [build-dylib, check-perms]
118145
runs-on: ${{ github.repository_owner == 'coder' && 'depot-ubuntu-22.04-8' || 'ubuntu-latest' }}
119146
permissions:
120147
# Required to publish a release

cli/schedule.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ When enabling scheduled stop, enter a duration in one of the following formats:
4646
* 2m (2 minutes)
4747
* 2 (2 minutes)
4848
`
49-
scheduleExtendDescriptionLong = `
49+
scheduleExtendDescriptionLong = `Extends the workspace deadline.
5050
* The new stop time is calculated from *now*.
5151
* The new stop time must be at least 30 minutes in the future.
5252
* The workspace template may restrict the maximum workspace runtime.
@@ -157,6 +157,13 @@ func (r *RootCmd) scheduleStart() *serpent.Command {
157157
return err
158158
}
159159

160+
// Autostart configuration is not supported for prebuilt workspaces.
161+
// Prebuild lifecycle is managed by the reconciliation loop, with scheduling behavior
162+
// defined per preset at the template level, not per workspace.
163+
if workspace.IsPrebuild {
164+
return xerrors.Errorf("autostart configuration is not supported for prebuilt workspaces")
165+
}
166+
160167
var schedStr *string
161168
if inv.Args[1] != "manual" {
162169
sched, err := parseCLISchedule(inv.Args[1:]...)
@@ -205,6 +212,13 @@ func (r *RootCmd) scheduleStop() *serpent.Command {
205212
return err
206213
}
207214

215+
// Autostop configuration is not supported for prebuilt workspaces.
216+
// Prebuild lifecycle is managed by the reconciliation loop, with scheduling behavior
217+
// defined per preset at the template level, not per workspace.
218+
if workspace.IsPrebuild {
219+
return xerrors.Errorf("autostop configuration is not supported for prebuilt workspaces")
220+
}
221+
208222
var durMillis *int64
209223
if inv.Args[1] != "manual" {
210224
dur, err := parseDuration(inv.Args[1])
@@ -255,6 +269,13 @@ func (r *RootCmd) scheduleExtend() *serpent.Command {
255269
return xerrors.Errorf("get workspace: %w", err)
256270
}
257271

272+
// Deadline extensions are not supported for prebuilt workspaces.
273+
// Prebuild lifecycle is managed by the reconciliation loop, with TTL behavior
274+
// defined per preset at the template level, not per workspace.
275+
if workspace.IsPrebuild {
276+
return xerrors.Errorf("extend configuration is not supported for prebuilt workspaces")
277+
}
278+
258279
loc, err := tz.TimezoneIANA()
259280
if err != nil {
260281
loc = time.UTC // best effort

cli/testdata/coder_schedule_extend_--help.golden

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ USAGE:
77

88
Aliases: override-stop
99

10-
* The new stop time is calculated from *now*.
10+
Extends the workspace deadline.
11+
* The new stop time is calculated from *now*.
1112
* The new stop time must be at least 30 minutes in the future.
1213
* The workspace template may restrict the maximum workspace runtime.
1314

coderd/autobuild/lifecycle_executor_test.go

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1251,15 +1251,23 @@ func TestExecutorPrebuilds(t *testing.T) {
12511251
}()
12521252

12531253
// Then: the prebuilt workspace should remain in a start transition
1254-
prebuildStats := <-statsCh
1254+
prebuildStats := testutil.RequireReceive(ctx, t, statsCh)
12551255
require.Len(t, prebuildStats.Errors, 0)
12561256
require.Len(t, prebuildStats.Transitions, 0)
12571257
require.Equal(t, codersdk.WorkspaceTransitionStart, prebuild.LatestBuild.Transition)
12581258
prebuild = coderdtest.MustWorkspace(t, client, prebuild.ID)
12591259
require.Equal(t, codersdk.BuildReasonInitiator, prebuild.LatestBuild.Reason)
12601260

12611261
// Given: a user claims the prebuilt workspace
1262-
dbWorkspace := dbgen.ClaimPrebuild(t, db, user.ID, "claimedWorkspace-autostop", preset.ID)
1262+
dbWorkspace := dbgen.ClaimPrebuild(
1263+
t, db,
1264+
clock.Now(),
1265+
user.ID,
1266+
"claimedWorkspace-autostop",
1267+
preset.ID,
1268+
sql.NullString{},
1269+
sql.NullTime{},
1270+
sql.NullInt64{})
12631271
workspace := coderdtest.MustWorkspace(t, client, dbWorkspace.ID)
12641272

12651273
// When: the autobuild executor ticks *after* the deadline:
@@ -1269,7 +1277,7 @@ func TestExecutorPrebuilds(t *testing.T) {
12691277
}()
12701278

12711279
// Then: the workspace should be stopped
1272-
workspaceStats := <-statsCh
1280+
workspaceStats := testutil.RequireReceive(ctx, t, statsCh)
12731281
require.Len(t, workspaceStats.Errors, 0)
12741282
require.Len(t, workspaceStats.Transitions, 1)
12751283
require.Contains(t, workspaceStats.Transitions, workspace.ID)
@@ -1336,7 +1344,7 @@ func TestExecutorPrebuilds(t *testing.T) {
13361344
}()
13371345

13381346
// Then: the prebuilt workspace should remain in a stop transition
1339-
prebuildStats := <-statsCh
1347+
prebuildStats := testutil.RequireReceive(ctx, t, statsCh)
13401348
require.Len(t, prebuildStats.Errors, 0)
13411349
require.Len(t, prebuildStats.Transitions, 0)
13421350
require.Equal(t, codersdk.WorkspaceTransitionStop, prebuild.LatestBuild.Transition)
@@ -1353,7 +1361,15 @@ func TestExecutorPrebuilds(t *testing.T) {
13531361
database.WorkspaceTransitionStart)
13541362

13551363
// Given: a user claims the prebuilt workspace
1356-
dbWorkspace := dbgen.ClaimPrebuild(t, db, user.ID, "claimedWorkspace-autostart", preset.ID)
1364+
dbWorkspace := dbgen.ClaimPrebuild(
1365+
t, db,
1366+
clock.Now(),
1367+
user.ID,
1368+
"claimedWorkspace-autostart",
1369+
preset.ID,
1370+
autostartSched,
1371+
sql.NullTime{},
1372+
sql.NullInt64{})
13571373
workspace := coderdtest.MustWorkspace(t, client, dbWorkspace.ID)
13581374

13591375
// Given: the prebuilt workspace goes to a stop status
@@ -1374,7 +1390,7 @@ func TestExecutorPrebuilds(t *testing.T) {
13741390
}()
13751391

13761392
// Then: the workspace should eventually be started
1377-
workspaceStats := <-statsCh
1393+
workspaceStats := testutil.RequireReceive(ctx, t, statsCh)
13781394
require.Len(t, workspaceStats.Errors, 0)
13791395
require.Len(t, workspaceStats.Transitions, 1)
13801396
require.Contains(t, workspaceStats.Transitions, workspace.ID)
@@ -1486,8 +1502,8 @@ func setupTestDBWorkspaceBuild(
14861502
Architecture: "i386",
14871503
OperatingSystem: "linux",
14881504
LifecycleState: database.WorkspaceAgentLifecycleStateReady,
1489-
StartedAt: sql.NullTime{Time: time.Now().Add(time.Hour), Valid: true},
1490-
ReadyAt: sql.NullTime{Time: time.Now().Add(-1 * time.Hour), Valid: true},
1505+
StartedAt: sql.NullTime{Time: clock.Now().Add(time.Hour), Valid: true},
1506+
ReadyAt: sql.NullTime{Time: clock.Now().Add(-1 * time.Hour), Valid: true},
14911507
APIKeyScope: database.AgentKeyScopeEnumAll,
14921508
})
14931509

@@ -1524,8 +1540,9 @@ func setupTestDBPrebuiltWorkspace(
15241540
OrganizationID: orgID,
15251541
OwnerID: database.PrebuildsSystemUserID,
15261542
Deleted: false,
1527-
CreatedAt: time.Now().Add(-time.Hour * 2),
1543+
CreatedAt: clock.Now().Add(-time.Hour * 2),
15281544
AutostartSchedule: options.AutostartSchedule,
1545+
LastUsedAt: clock.Now(),
15291546
})
15301547
setupTestDBWorkspaceBuild(ctx, t, clock, db, ps, orgID, workspace.ID, templateVersionID, presetID, buildTransition)
15311548

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy