948743600e
Tier 1 of the post-review cleanup. Each item is independently safe; bundling because they're all small, mechanical, and lint-passing. - fix(clone): unify injectTokenIntoURL across Docker and Sprites — Sprites used to ignore GH_TOKEN entirely (a user with only GH_TOKEN set got 401 on Sprites clone but worked on Docker). Promote one `injectGitHubTokenIntoCloneURL` helper, accept both env vars (GITHUB_TOKEN wins, matching Docker), and use the documented `https://x-access-token:T@github.com/` form on both surfaces. - fix(executor-popover): swap the <span tabIndex role="button"> trigger for <Button variant="ghost"> so Enter/Space activation, focus rings on Safari, and disabled semantics come for free. - test(docker): rewrite TestDockerStopInstance_PreservesSessionDirOnPlainStop to drive the real DockerExecutor.StopInstance path with ContainerID="" (skips the docker daemon, exercises the kandev-side cleanup branch). Previous version only iterated shouldRunExecutorCleanup strings — would pass even if StopInstance always cleaned up. Now table-driven over preserve+destructive reasons with on-disk asserts. - refactor(orchestrator): drop dead `_ = arg` parameters from persist* helpers (persistResumeState, persistModelSwitchState, persistLaunchState). Brings signatures from 9→6 args, under the funlen lint cap. - refactor(orchestrator): collapse byte-identical isContainerizedExecutor ≡ isCloneBasedExecutorType predicate into one. - refactor(lifecycle): drop dead getMetadataBool, FileUploader.RunCommand, expandMountSource {home} arm (no production agent ships {home} in Mounts; codex_acp_test asserts it), dockerTaskBranch one-line wrapper.
65 lines
2.0 KiB
Go
65 lines
2.0 KiB
Go
package lifecycle
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/kandev/kandev/internal/common/logger"
|
|
"github.com/kandev/kandev/internal/worktree"
|
|
)
|
|
|
|
// DockerPreparer prepares a Docker-based execution environment.
|
|
// Steps: validate Docker → pull/build image (if needed).
|
|
type DockerPreparer struct {
|
|
logger *logger.Logger
|
|
}
|
|
|
|
// NewDockerPreparer creates a new DockerPreparer.
|
|
func NewDockerPreparer(log *logger.Logger) *DockerPreparer {
|
|
return &DockerPreparer{
|
|
logger: log.WithFields(zap.String("component", "docker-preparer")),
|
|
}
|
|
}
|
|
|
|
func (p *DockerPreparer) Name() string { return "docker" }
|
|
|
|
func (p *DockerPreparer) Prepare(ctx context.Context, req *EnvPrepareRequest, onProgress PrepareProgressCallback) (*EnvPrepareResult, error) {
|
|
start := time.Now()
|
|
var steps []PrepareStep
|
|
|
|
// Step 1: Validate Docker availability
|
|
step := beginStep("Validate Docker")
|
|
reportProgress(onProgress, step, 0, 1)
|
|
completeStepSuccess(&step)
|
|
steps = append(steps, step)
|
|
reportProgress(onProgress, step, 0, 1)
|
|
|
|
return &EnvPrepareResult{
|
|
Success: true,
|
|
Steps: steps,
|
|
WorkspacePath: req.WorkspacePath,
|
|
Duration: time.Since(start),
|
|
WorktreeBranch: nonWorktreeTaskBranch(req),
|
|
}, nil
|
|
}
|
|
|
|
// nonWorktreeTaskBranch resolves the kandev-managed feature branch for executors
|
|
// that don't go through the host-side worktree path (Docker, Sprites). On a
|
|
// fresh launch it generates a deterministic branch name from the task title +
|
|
// task ID prefix so the same task always lands on the same branch even when
|
|
// the env row was created before this fix and didn't persist a name. On resume
|
|
// the orchestrator carries the previously-generated branch back via
|
|
// req.WorktreeBranch and we keep it as-is.
|
|
func nonWorktreeTaskBranch(req *EnvPrepareRequest) string {
|
|
if req.WorktreeBranch != "" {
|
|
return req.WorktreeBranch
|
|
}
|
|
suffix := req.TaskID
|
|
if len(suffix) > 6 {
|
|
suffix = suffix[:6]
|
|
}
|
|
return worktree.TaskBranchNameWithSuffix(req.TaskTitle, req.TaskID, req.WorktreeBranchPrefix, suffix)
|
|
}
|