feat: add workspace restart functionality to API (#25757)

This models restart as durable orchestration of existing stop and
start workspace builds instead of adding a new restart transition.
Keeping restart as two existing transitions preserves the current
build/provisioner model.

The child start build is created only after the parent stop build
succeeds, rather than being inserted immediately in a pending
state. That keeps `workspace_builds` aligned with actual
provisioner-ready work and avoids introducing a second
pending-build lifecycle that the provisioner and build acquisition
paths would need to understand.

Refs: https://linear.app/codercom/issue/PLAT-143
This commit is contained in:
George K
2026-07-07 09:18:30 -07:00
committed by GitHub
parent ba094c5706
commit 6af0f4d698
45 changed files with 4412 additions and 144 deletions
@@ -1285,6 +1285,13 @@ func (s *server) FailJob(ctx context.Context, failJob *proto.FailedJob) (*proto.
s.notifyWorkspaceBuildFailed(ctx, workspace, build)
// Wake the orchestrator before the workspace event publish
// below, which returns on error, so a failed UI event cannot
// skip the wake.
if err := wspubsub.PublishWorkspaceBuildOrchestrationWake(ctx, s.Pubsub); err != nil {
s.Logger.Warn(ctx, "failed to publish workspace build orchestration wake", slog.Error(err))
}
msg, err := json.Marshal(wspubsub.WorkspaceEvent{
Kind: wspubsub.WorkspaceEventKindStateChange,
WorkspaceID: workspace.ID,
@@ -2552,6 +2559,15 @@ func (s *server) completeWorkspaceBuildJob(ctx context.Context, job database.Pro
}
}
// Wake the orchestrator before the workspace event publish below,
// which returns on error, so a failed UI event cannot skip the
// wake.
if err := wspubsub.PublishWorkspaceBuildOrchestrationWake(ctx, s.Pubsub); err != nil {
s.Logger.Warn(ctx, "failed to publish workspace build orchestration wake",
slog.Error(err),
)
}
msg, err := json.Marshal(wspubsub.WorkspaceEvent{
Kind: wspubsub.WorkspaceEventKindStateChange,
WorkspaceID: workspace.ID,