(ctx context.Context, requestName string)
| 1030 | } |
| 1031 | |
| 1032 | func (s *SQLService) doExportFromIssue(ctx context.Context, requestName string) (*v1pb.ExportResponse, error) { |
| 1033 | // Try to parse as rollout name first (more specific), then fallback to stage name |
| 1034 | var planID int64 |
| 1035 | var projectID string |
| 1036 | var err error |
| 1037 | projectID, planID, err = common.GetProjectIDPlanIDFromRolloutName(requestName) |
| 1038 | if err != nil { |
| 1039 | // If rollout parsing fails, try parsing as stage name |
| 1040 | projectID, planID, _, err = common.GetProjectIDPlanIDMaybeStageID(requestName) |
| 1041 | if err != nil { |
| 1042 | return nil, connect.NewError(connect.CodeInvalidArgument, errors.Errorf("failed to parse request name as rollout or stage: %v", err)) |
| 1043 | } |
| 1044 | } |
| 1045 | |
| 1046 | plan, err := s.store.GetPlan(ctx, &store.FindPlanMessage{ |
| 1047 | Workspace: common.GetWorkspaceIDFromContext(ctx), |
| 1048 | ProjectID: projectID, |
| 1049 | UID: &planID, |
| 1050 | }) |
| 1051 | if err != nil { |
| 1052 | return nil, connect.NewError(connect.CodeInternal, errors.Errorf("failed to get rollout: %v", err)) |
| 1053 | } |
| 1054 | if plan == nil { |
| 1055 | return nil, connect.NewError(connect.CodeNotFound, errors.Errorf("rollout %d not found in project %s", planID, projectID)) |
| 1056 | } |
| 1057 | |
| 1058 | tasks, err := s.store.ListTasks(ctx, &store.TaskFind{Workspace: common.GetWorkspaceIDFromContext(ctx), ProjectID: projectID, PlanID: &plan.UID}) |
| 1059 | if err != nil { |
| 1060 | return nil, connect.NewError(connect.CodeInternal, errors.Errorf("failed to get tasks: %v", err)) |
| 1061 | } |
| 1062 | if len(tasks) == 0 { |
| 1063 | return nil, connect.NewError(connect.CodeInvalidArgument, errors.Errorf("rollout %d has no task", plan.UID)) |
| 1064 | } |
| 1065 | |
| 1066 | // Get password from the plan spec |
| 1067 | // For export data plans, there is always exactly one spec |
| 1068 | var passwordStr string |
| 1069 | if len(plan.Config.Specs) > 0 { |
| 1070 | if exportConfig := plan.Config.Specs[0].GetExportDataConfig(); exportConfig != nil && exportConfig.Password != nil { |
| 1071 | passwordStr = *exportConfig.Password |
| 1072 | } |
| 1073 | } |
| 1074 | |
| 1075 | pendingEncrypts := []*encryptContent{} |
| 1076 | |
| 1077 | for _, task := range tasks { |
| 1078 | // Skip tasks that are marked as skipped (they don't have archives) |
| 1079 | if task.Payload.GetSkipped() { |
| 1080 | continue |
| 1081 | } |
| 1082 | |
| 1083 | taskRuns, err := s.store.ListTaskRuns(ctx, &store.FindTaskRunMessage{ |
| 1084 | Workspace: common.GetWorkspaceIDFromContext(ctx), |
| 1085 | ProjectID: projectID, |
| 1086 | TaskUID: &task.ID, |
| 1087 | Status: &[]storepb.TaskRun_Status{storepb.TaskRun_DONE}, |
| 1088 | }) |
| 1089 | if err != nil { |
no test coverage detected