UpdateDeploymentsForProject updates the deployments of a project. Care must be taken to avoid one broken deployment from blocking updates to other healthy deployments.
(ctx context.Context, p *database.Project)
| 137 | // UpdateDeploymentsForProject updates the deployments of a project. |
| 138 | // Care must be taken to avoid one broken deployment from blocking updates to other healthy deployments. |
| 139 | func (s *Service) UpdateDeploymentsForProject(ctx context.Context, p *database.Project) error { |
| 140 | ds, err := s.DB.FindDeploymentsForProject(ctx, p.ID, "", "") |
| 141 | if err != nil { |
| 142 | return err |
| 143 | } |
| 144 | |
| 145 | grp, ctx := errgroup.WithContext(ctx) |
| 146 | grp.SetLimit(100) |
| 147 | var prodErr error |
| 148 | for _, d := range ds { |
| 149 | grp.Go(func() error { |
| 150 | // If this is the primary prod deployment and the primary branch has changed, update the deployment branch too. |
| 151 | branch := d.Branch |
| 152 | if p.PrimaryDeploymentID != nil && *p.PrimaryDeploymentID == d.ID && p.PrimaryBranch != d.Branch { |
| 153 | branch = p.PrimaryBranch |
| 154 | } |
| 155 | err := s.UpdateDeployment(ctx, d, branch) |
| 156 | if err != nil { |
| 157 | if ctx.Err() != nil { |
| 158 | return ctx.Err() |
| 159 | } |
| 160 | if p.PrimaryDeploymentID != nil && *p.PrimaryDeploymentID == d.ID { |
| 161 | prodErr = err |
| 162 | } |
| 163 | s.Logger.Warn("failed to update deployment", zap.String("deployment_id", d.ID), zap.Error(err), observability.ZapCtx(ctx)) |
| 164 | } |
| 165 | return nil |
| 166 | }) |
| 167 | } |
| 168 | |
| 169 | err = grp.Wait() |
| 170 | if err != nil { |
| 171 | return err |
| 172 | } |
| 173 | |
| 174 | return prodErr |
| 175 | } |
| 176 | |
| 177 | // StartDeploymentInner provisions a runtime and initializes an instance on it. |
| 178 | // The implementation is idempotent, enabling it to be called from a retryable background job. |
no test coverage detected