Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions cmd/lk/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -557,6 +557,10 @@ func createAgent(ctx context.Context, cmd *cli.Command) error {
}
}

if err := agentfs.ValidateLockFiles(os.DirFS(workingDir), projectType); err != nil {
return err
}

region := cmd.String("region")
if region == "" {
availableRegionsStr, ok := settingsMap["available_regions"]
Expand Down Expand Up @@ -733,6 +737,10 @@ func deployAgent(ctx context.Context, cmd *cli.Command) error {
}
}

if err := agentfs.ValidateLockFiles(os.DirFS(workingDir), projectType); err != nil {
return err
}

buildContext, cancel := context.WithTimeout(ctx, buildTimeout)
defer cancel()
excludeFiles := []string{fmt.Sprintf("**/%s", config.LiveKitTOMLFile)}
Expand Down
37 changes: 37 additions & 0 deletions pkg/agentfs/detect.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,40 @@ func DetectProjectType(dir fs.FS) (ProjectType, error) {

return ProjectTypeUnknown, errors.New("project type could not be identified; expected package.json, requirements.txt, pyproject.toml, or lock files")
}

// ValidateLockFiles checks if the required lock files exist for the given project type.
// This ensures that dependency sync commands (e.g., uv sync, npm install) have been run
// before deployment, preventing build failures.
func ValidateLockFiles(dir fs.FS, projectType ProjectType) error {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function definitely need to be double-checked. It's probably correct for uv projects but I'm not familiar with all the other kinds of project.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing we could do is allow this check to be bypassed when --skip-sdk-check is set, as we already do with similar project detection tasks in case somebody is using a non-standard package manager or something.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise it looks correct to me. You could add some tests similar to this: https://github.com/livekit/livekit-cli/blob/main/pkg/agentfs/sdk_version_check_test.go#L9

switch projectType {
case ProjectTypePythonUV:
if !util.FileExists(dir, "uv.lock") {
return errors.New("uv.lock file not found. Please run 'uv sync' to generate the lock file before deployment")
}
case ProjectTypePythonPip:
// Check if project uses poetry or pipenv which require lock files
if util.FileExists(dir, "poetry.lock") {
// Poetry project - lock file should already exist if detected
return nil
}
if util.FileExists(dir, "Pipfile.lock") {
// Pipenv project - lock file should already exist if detected
return nil
}
// For requirements.txt projects, no lock file is required
// pyproject.toml without poetry/pipenv also doesn't require a lock file
return nil
case ProjectTypeNode:
// Check for any of the common lock files
hasLockFile := util.FileExists(dir, "package-lock.json") ||
util.FileExists(dir, "yarn.lock") ||
util.FileExists(dir, "pnpm-lock.yaml") ||
util.FileExists(dir, "bun.lockb")
if !hasLockFile {
return errors.New("no lock file found (package-lock.json, yarn.lock, pnpm-lock.yaml, or bun.lockb). Please run 'npm install', 'yarn install', 'pnpm install', or 'bun install' to generate a lock file before deployment")
}
case ProjectTypeUnknown:
return errors.New("unknown project type, cannot validate lock files")
}
return nil
}
Loading