retry_build_service.rb 1.29 KB
Newer Older
1 2
# frozen_string_literal: true

3
module Ci
4
  class RetryBuildService < ::BaseService
5
    CLONE_ACCESSORS = %i[pipeline project ref tag options commands name
6
                         allow_failure stage stage_id stage_idx trigger_request
7
                         yaml_variables when environment coverage_regex
8
                         description tag_list protected].freeze
9

10
    def execute(build)
11
      reprocess!(build).tap do |new_build|
12 13
        build.pipeline.mark_as_processable_after_stage(build.stage_idx)

14
        new_build.enqueue!
15

16
        MergeRequests::AddTodoWhenBuildFailsService
17
          .new(project, current_user)
18 19
          .close(new_build)
      end
20 21
    end

22
    def reprocess!(build)
23
      unless can?(current_user, :update_build, build)
24 25
        raise Gitlab::Access::AccessDeniedError
      end
26

27
      attributes = CLONE_ACCESSORS.map do |attribute|
28
        [attribute, build.public_send(attribute)] # rubocop:disable GitlabSecurity/PublicSend
29 30 31 32
      end

      attributes.push([:user, current_user])

33 34
      build.retried = true

35 36
      Ci::Build.transaction do
        # mark all other builds of that name as retried
Kamil Trzcinski's avatar
Kamil Trzcinski committed
37 38
        build.pipeline.builds.latest
          .where(name: build.name)
39 40 41 42
          .update_all(retried: true)

        project.builds.create!(Hash[attributes])
      end
43 44 45
    end
  end
end