waitRollout waits for pipeline to finish and approves tasks when necessary.
(ctx context.Context, issueName, rolloutName string)
| 73 | |
| 74 | // waitRollout waits for pipeline to finish and approves tasks when necessary. |
| 75 | func (ctl *controller) waitRollout(ctx context.Context, issueName, rolloutName string) error { |
| 76 | ticker := time.NewTicker(300 * time.Millisecond) |
| 77 | defer ticker.Stop() |
| 78 | |
| 79 | // Add timeout to prevent infinite loops |
| 80 | timeout := time.After(2 * time.Minute) |
| 81 | startTime := time.Now() |
| 82 | |
| 83 | // Wait for approval |
| 84 | waitApproval: |
| 85 | for { |
| 86 | select { |
| 87 | case <-timeout: |
| 88 | // Timeout - fetch current state for debugging |
| 89 | issueResp, err := ctl.issueServiceClient.GetIssue(ctx, connect.NewRequest(&v1pb.GetIssueRequest{Name: issueName})) |
| 90 | if err != nil { |
| 91 | return errors.Wrapf(err, "timeout after %v waiting for approval (failed to fetch issue state)", time.Since(startTime)) |
| 92 | } |
| 93 | issue := issueResp.Msg |
| 94 | return errors.Errorf("timeout after %v waiting for approval to complete, current approval status: %s", |
| 95 | time.Since(startTime), issue.ApprovalStatus.String()) |
| 96 | |
| 97 | case <-ticker.C: |
| 98 | issueResp, err := ctl.issueServiceClient.GetIssue(ctx, connect.NewRequest(&v1pb.GetIssueRequest{Name: issueName})) |
| 99 | if err != nil { |
| 100 | return err |
| 101 | } |
| 102 | issue := issueResp.Msg |
| 103 | if issue.ApprovalStatus == v1pb.ApprovalStatus_APPROVED || issue.ApprovalStatus == v1pb.ApprovalStatus_SKIPPED { |
| 104 | break waitApproval |
| 105 | } |
| 106 | // If the issue is pending approval, approve it (test user should be project owner) |
| 107 | if issue.ApprovalStatus == v1pb.ApprovalStatus_PENDING { |
| 108 | _, err := ctl.issueServiceClient.ApproveIssue(ctx, connect.NewRequest(&v1pb.ApproveIssueRequest{ |
| 109 | Name: issueName, |
| 110 | })) |
| 111 | if err != nil { |
| 112 | return errors.Wrapf(err, "failed to approve issue") |
| 113 | } |
| 114 | } |
| 115 | } |
| 116 | } |
| 117 | |
| 118 | rolloutResp, err := ctl.rolloutServiceClient.GetRollout(ctx, connect.NewRequest(&v1pb.GetRolloutRequest{ |
| 119 | Name: rolloutName, |
| 120 | })) |
| 121 | if err != nil { |
| 122 | return err |
| 123 | } |
| 124 | rollout := rolloutResp.Msg |
| 125 | for _, stage := range rollout.Stages { |
| 126 | var runTasks []string |
| 127 | for _, task := range stage.Tasks { |
| 128 | if task.Status == v1pb.Task_NOT_STARTED { |
| 129 | runTasks = append(runTasks, task.Name) |
| 130 | } |
| 131 | } |
| 132 | if len(runTasks) > 0 { |