feat: remote tab in task-create dialog — multi-row GitHub repo picker (#1116)
This commit is contained in:
@@ -289,9 +289,13 @@ func (s *Service) createTaskRepositories(ctx context.Context, taskID, workspaceI
|
||||
// Multi-repo validation: each repository may appear at most once per task.
|
||||
// Without this guard the unique (task_id, repository_id) constraint on
|
||||
// task_repositories would surface as an opaque DB error mid-loop, leaving
|
||||
// some rows already inserted.
|
||||
// some rows already inserted. Name the repository (owner/name) instead of
|
||||
// the raw UUID so the create-task dialog's error toast is human-readable —
|
||||
// two PR URLs of the same repo (e.g. /pull/1116 and /pull/1117) collapse
|
||||
// to the same repositoryID and hit this path.
|
||||
if seen[repositoryID] {
|
||||
return fmt.Errorf("repository %q listed more than once for the task", repositoryID)
|
||||
label := s.repoDisplayLabel(ctx, repoInput, repositoryID)
|
||||
return fmt.Errorf("repository %q is listed more than once for this task", label)
|
||||
}
|
||||
seen[repositoryID] = true
|
||||
metadata := make(map[string]interface{})
|
||||
@@ -314,6 +318,28 @@ func (s *Service) createTaskRepositories(ctx context.Context, taskID, workspaceI
|
||||
return nil
|
||||
}
|
||||
|
||||
// repoDisplayLabel returns a human-readable label for a repository to surface
|
||||
// in the duplicate-repository error. It prefers owner/name parsed from the
|
||||
// input's GitHub URL, then the resolved repo entity's owner/name (or bare
|
||||
// name), and finally falls back to the repositoryID so the message is never
|
||||
// empty. Best-effort: lookup failures degrade to the next fallback.
|
||||
func (s *Service) repoDisplayLabel(ctx context.Context, repoInput TaskRepositoryInput, repositoryID string) string {
|
||||
if repoInput.GitHubURL != "" {
|
||||
if owner, name, err := parseGitHubRepoURL(repoInput.GitHubURL); err == nil {
|
||||
return owner + "/" + name
|
||||
}
|
||||
}
|
||||
if repo, err := s.repoEntities.GetRepository(ctx, repositoryID); err == nil && repo != nil {
|
||||
if repo.ProviderOwner != "" && repo.ProviderName != "" {
|
||||
return repo.ProviderOwner + "/" + repo.ProviderName
|
||||
}
|
||||
if repo.Name != "" {
|
||||
return repo.Name
|
||||
}
|
||||
}
|
||||
return repositoryID
|
||||
}
|
||||
|
||||
// resolveRepoInput resolves a RepositoryInput to a repositoryID and baseBranch,
|
||||
// creating the repository if it doesn't exist yet.
|
||||
func (s *Service) resolveRepoInput(ctx context.Context, workspaceID string, repoInput TaskRepositoryInput, repoByPath map[string]*models.Repository) (repositoryID, baseBranch string, err error) {
|
||||
|
||||
Reference in New Issue
Block a user