Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: extend workspace build reasons to track connection types#18827

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
kacpersaw merged 15 commits intomainfromkacpersaw/extend-build-reason
Jul 22, 2025
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
Show all changes
15 commits
Select commitHold shift + click to select a range
15f24ac
add new build reasons to track what triggers workspace builds
kacpersawJul 9, 2025
905f755
change ssh_connection UI label
kacpersawJul 10, 2025
5dd67fe
Use UserAgent header to detect jetbrains connection, regenerate models
kacpersawJul 10, 2025
0c4280c
Add tests
kacpersawJul 10, 2025
ed3cb9a
Fix UI test
kacpersawJul 10, 2025
c9ed52e
Merge branch 'main' into kacpersaw/extend-build-reason
kacpersawJul 14, 2025
99e548f
Remove User-Agent check
kacpersawJul 14, 2025
c87cb53
Update flag description
kacpersawJul 14, 2025
6803ace
enhance workspace build data and audit log with build reason display
kacpersawJul 15, 2025
2b5c4f2
Reformat code
kacpersawJul 15, 2025
1526164
Merge branch 'main' into kacpersaw/extend-build-reason
kacpersawJul 15, 2025
3d33137
Fix migration numbers
kacpersawJul 15, 2025
da376fd
replace getDisplayInitiatorBuildReason with buildReasonLabels and sys…
kacpersawJul 16, 2025
cc20293
Reformat
kacpersawJul 16, 2025
229b9c0
Merge remote-tracking branch 'origin/main' into kacpersaw/extend-buil…
kacpersawJul 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletioncli/parameter.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -145,9 +145,11 @@ func parseParameterMapFile(parameterFile string) (map[string]string, error) {
return parameterMap, nil
}

// buildFlags contains options relating to troubleshooting provisioner jobs.
// buildFlags contains options relating to troubleshooting provisioner jobs
// and setting the reason for the workspace build.
type buildFlags struct {
provisionerLogDebug bool
reason string
}

func (bf *buildFlags) cliOptions() []serpent.Option {
Expand All@@ -160,5 +162,17 @@ This is useful for troubleshooting build issues.`,
Value: serpent.BoolOf(&bf.provisionerLogDebug),
Hidden: true,
},
{
Flag: "reason",
Description: `Sets the reason for the workspace build (cli, vscode_connection, jetbrains_connection).`,
Value: serpent.EnumOf(
&bf.reason,
string(codersdk.BuildReasonCLI),
string(codersdk.BuildReasonVSCodeConnection),
string(codersdk.BuildReasonJetbrainsConnection),
),
Default: string(codersdk.BuildReasonCLI),
Hidden: true,
},
}
}
4 changes: 3 additions & 1 deletioncli/ssh.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -873,7 +873,9 @@ func getWorkspaceAndAgent(ctx context.Context, inv *serpent.Invocation, client *
// It's possible for a workspace build to fail due to the template requiring starting
// workspaces with the active version.
_, _ = fmt.Fprintf(inv.Stderr, "Workspace was stopped, starting workspace to allow connecting to %q...\n", workspace.Name)
_, err = startWorkspace(inv, client, workspace, workspaceParameterFlags{}, buildFlags{}, WorkspaceStart)
_, err = startWorkspace(inv, client, workspace, workspaceParameterFlags{}, buildFlags{
reason: string(codersdk.BuildReasonSSHConnection),
}, WorkspaceStart)
if cerr, ok := codersdk.AsError(err); ok {
switch cerr.StatusCode() {
case http.StatusConflict:
Expand Down
3 changes: 3 additions & 0 deletionscli/start.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -169,6 +169,9 @@ func buildWorkspaceStartRequest(inv *serpent.Invocation, client *codersdk.Client
ifbuildFlags.provisionerLogDebug {
wbr.LogLevel=codersdk.ProvisionerLogLevelDebug
}
ifbuildFlags.reason!="" {
wbr.Reason=codersdk.CreateWorkspaceBuildReason(buildFlags.reason)
}

returnwbr,nil
}
Expand Down
36 changes: 36 additions & 0 deletionscli/start_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -477,3 +477,39 @@ func TestStart_NoWait(t *testing.T) {
pty.ExpectMatch("workspace has been started in no-wait mode")
_ = testutil.TryReceive(ctx, t, doneChan)
}

func TestStart_WithReason(t *testing.T) {
t.Parallel()
ctx := testutil.Context(t, testutil.WaitShort)

// Prepare user, template, workspace
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
owner := coderdtest.CreateFirstUser(t, client)
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
version1 := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version1.ID)
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version1.ID)
workspace := coderdtest.CreateWorkspace(t, member, template.ID)
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)

// Stop the workspace
build := coderdtest.CreateWorkspaceBuild(t, member, workspace, database.WorkspaceTransitionStop)
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, build.ID)

// Start the workspace with reason
inv, root := clitest.New(t, "start", workspace.Name, "--reason", "cli")
clitest.SetupConfig(t, member, root)
doneChan := make(chan struct{})
pty := ptytest.New(t).Attach(inv)
go func() {
defer close(doneChan)
err := inv.Run()
assert.NoError(t, err)
}()

pty.ExpectMatch("workspace has been started")
_ = testutil.TryReceive(ctx, t, doneChan)

workspace = coderdtest.MustWorkspace(t, member, workspace.ID)
require.Equal(t, codersdk.BuildReasonCLI, workspace.LatestBuild.Reason)
}
46 changes: 44 additions & 2 deletionscoderd/apidoc/docs.go
View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

51 changes: 49 additions & 2 deletionscoderd/apidoc/swagger.json
View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

7 changes: 6 additions & 1 deletioncoderd/database/dump.sql
View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
-- It's not possible to delete enum values.
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
ALTERTYPE build_reason ADD VALUE IF NOT EXISTS'dashboard';
ALTERTYPE build_reason ADD VALUE IF NOT EXISTS'cli';
ALTERTYPE build_reason ADD VALUE IF NOT EXISTS'ssh_connection';
ALTERTYPE build_reason ADD VALUE IF NOT EXISTS'vscode_connection';
ALTERTYPE build_reason ADD VALUE IF NOT EXISTS'jetbrains_connection';
29 changes: 22 additions & 7 deletionscoderd/database/models.go
View file
Open in desktop

Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.

8 changes: 7 additions & 1 deletioncoderd/workspacebuilds.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -329,20 +329,26 @@ func (api *API) workspaceBuildByBuildNumber(rw http.ResponseWriter, r *http.Requ
func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
ctx := r.Context()
apiKey := httpmw.APIKey(r)

workspace := httpmw.WorkspaceParam(r)
var createBuild codersdk.CreateWorkspaceBuildRequest
if !httpapi.Read(ctx, rw, r, &createBuild) {
return
}

builder := wsbuilder.New(workspace, database.WorkspaceTransition(createBuild.Transition), *api.BuildUsageChecker.Load()).
transition := database.WorkspaceTransition(createBuild.Transition)
builder := wsbuilder.New(workspace, transition, *api.BuildUsageChecker.Load()).
Initiator(apiKey.UserID).
RichParameterValues(createBuild.RichParameterValues).
LogLevel(string(createBuild.LogLevel)).
DeploymentValues(api.Options.DeploymentValues).
Experiments(api.Experiments).
TemplateVersionPresetID(createBuild.TemplateVersionPresetID)

if transition == database.WorkspaceTransitionStart && createBuild.Reason != "" {
builder = builder.Reason(database.BuildReason(createBuild.Reason))
}

var (
previousWorkspaceBuild database.WorkspaceBuild
workspaceBuild *database.WorkspaceBuild
Expand Down
24 changes: 24 additions & 0 deletionscoderd/workspacebuilds_test.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1808,6 +1808,30 @@ func TestPostWorkspaceBuild(t *testing.T) {
assert.True(t, build.MatchedProvisioners.MostRecentlySeen.Valid)
}
})
t.Run("WithReason", func(t *testing.T) {
t.Parallel()
client, closeDaemon := coderdtest.NewWithProvisionerCloser(t, &coderdtest.Options{
IncludeProvisionerDaemon: true,
})
user := coderdtest.CreateFirstUser(t, client)
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, template.ID)
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
_ = closeDaemon.Close()

ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
defer cancel()

build, err := client.CreateWorkspaceBuild(ctx, workspace.ID, codersdk.CreateWorkspaceBuildRequest{
TemplateVersionID: template.ActiveVersionID,
Transition: codersdk.WorkspaceTransitionStart,
Reason: codersdk.CreateWorkspaceBuildReasonDashboard,
})
require.NoError(t, err)
require.Equal(t, codersdk.BuildReasonDashboard, build.Reason)
})
}

func TestWorkspaceBuildTimings(t *testing.T) {
Expand Down
10 changes: 10 additions & 0 deletionscodersdk/workspacebuilds.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -49,6 +49,16 @@ const (
// BuildReasonDormancy "dormancy" is used when a build to stop a workspace is triggered due to inactivity (dormancy).
// The initiator id/username in this case is the workspace owner and can be ignored.
BuildReasonDormancy BuildReason = "dormancy"
// BuildReasonDashboard "dashboard" is used when a build to start a workspace is triggered by the dashboard.
BuildReasonDashboard BuildReason = "dashboard"
// BuildReasonCLI "cli" is used when a build to start a workspace is triggered by the CLI.
BuildReasonCLI BuildReason = "cli"
// BuildReasonSSHConnection "ssh_connection" is used when a build to start a workspace is triggered by an SSH connection.
BuildReasonSSHConnection BuildReason = "ssh_connection"
// BuildReasonVSCodeConnection "vscode_connection" is used when a build to start a workspace is triggered by a VS Code connection.
BuildReasonVSCodeConnection BuildReason = "vscode_connection"
// BuildReasonJetbrainsConnection "jetbrains_connection" is used when a build to start a workspace is triggered by a JetBrains connection.
BuildReasonJetbrainsConnection BuildReason = "jetbrains_connection"
)

// WorkspaceBuild is an at-point representation of a workspace state.
Expand Down
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp