(ctx context.Context, project *types.Project, options api.PushOptions)
| 46 | } |
| 47 | |
| 48 | func (s *composeService) push(ctx context.Context, project *types.Project, options api.PushOptions) error { |
| 49 | eg, ctx := errgroup.WithContext(ctx) |
| 50 | eg.SetLimit(s.maxConcurrency) |
| 51 | |
| 52 | for _, service := range project.Services { |
| 53 | if service.Build == nil || service.Image == "" { |
| 54 | if options.ImageMandatory && service.Image == "" && service.Provider == nil { |
| 55 | return fmt.Errorf("%q attribute is mandatory to push an image for service %q", "service.image", service.Name) |
| 56 | } |
| 57 | s.events.On(api.Resource{ |
| 58 | ID: service.Name, |
| 59 | Status: api.Done, |
| 60 | Text: "Skipped", |
| 61 | }) |
| 62 | continue |
| 63 | } |
| 64 | tags := []string{service.Image} |
| 65 | if service.Build != nil { |
| 66 | tags = append(tags, service.Build.Tags...) |
| 67 | } |
| 68 | |
| 69 | for _, tag := range tags { |
| 70 | eg.Go(func() error { |
| 71 | s.events.On(newEvent(tag, api.Working, "Pushing")) |
| 72 | err := s.pushServiceImage(ctx, tag, options.Quiet) |
| 73 | if err != nil { |
| 74 | if !options.IgnoreFailures { |
| 75 | s.events.On(newEvent(tag, api.Error, err.Error())) |
| 76 | return err |
| 77 | } |
| 78 | s.events.On(newEvent(tag, api.Warning, err.Error())) |
| 79 | } else { |
| 80 | s.events.On(newEvent(tag, api.Done, "Pushed")) |
| 81 | } |
| 82 | return nil |
| 83 | }) |
| 84 | } |
| 85 | } |
| 86 | return eg.Wait() |
| 87 | } |
| 88 | |
| 89 | func (s *composeService) pushServiceImage(ctx context.Context, tag string, quietPush bool) error { |
| 90 | ref, err := reference.ParseNormalizedNamed(tag) |
no test coverage detected