summaryrefslogtreecommitdiff
path: root/app/models/integrations/drone_ci.rb
blob: 0f02135681586be75dfa70a237ede1e9865e42e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# frozen_string_literal: true

module Integrations
  class DroneCi < BaseCi
    include ReactiveService
    include ServicePushDataValidations

    prop_accessor :drone_url, :token
    boolean_accessor :enable_ssl_verification

    validates :drone_url, presence: true, public_url: true, if: :activated?
    validates :token, presence: true, if: :activated?

    after_save :compose_service_hook, if: :activated?

    def compose_service_hook
      hook = service_hook || build_service_hook
      # If using a service template, project may not be available
      hook.url = [drone_url, "/api/hook", "?owner=#{project.namespace.full_path}", "&name=#{project.path}", "&access_token=#{token}"].join if project
      hook.enable_ssl_verification = !!enable_ssl_verification
      hook.save
    end

    def execute(data)
      case data[:object_kind]
      when 'push'
        service_hook.execute(data) if push_valid?(data)
      when 'merge_request'
        service_hook.execute(data) if merge_request_valid?(data)
      when 'tag_push'
        service_hook.execute(data) if tag_push_valid?(data)
      end
    end

    def allow_target_ci?
      true
    end

    def self.supported_events
      %w(push merge_request tag_push)
    end

    def commit_status_path(sha, ref)
      Gitlab::Utils.append_path(
        drone_url,
        "gitlab/#{project.full_path}/commits/#{sha}?branch=#{Addressable::URI.encode_component(ref.to_s)}&access_token=#{token}")
    end

    def commit_status(sha, ref)
      with_reactive_cache(sha, ref) { |cached| cached[:commit_status] }
    end

    def calculate_reactive_cache(sha, ref)
      response = Gitlab::HTTP.try_get(
        commit_status_path(sha, ref),
        verify: enable_ssl_verification,
        extra_log_info: { project_id: project_id },
        use_read_total_timeout: true
      )

      status =
        if response && response.code == 200 && response['status']
          case response['status']
          when 'killed'
            :canceled
          when 'failure', 'error'
            # Because drone return error if some test env failed
            :failed
          else
            response["status"]
          end
        else
          :error
        end

      { commit_status: status }
    end

    def build_page(sha, ref)
      Gitlab::Utils.append_path(
        drone_url,
        "gitlab/#{project.full_path}/redirect/commits/#{sha}?branch=#{Addressable::URI.encode_component(ref.to_s)}")
    end

    def title
      'Drone'
    end

    def description
      s_('ProjectService|Run CI/CD pipelines with Drone.')
    end

    def self.to_param
      'drone_ci'
    end

    def help
      s_('ProjectService|Run CI/CD pipelines with Drone.')
    end

    def fields
      [
        { type: 'text', name: 'token', help: s_('ProjectService|Token for the Drone project.'), required: true },
        { type: 'text', name: 'drone_url', title: s_('ProjectService|Drone server URL'), placeholder: 'http://drone.example.com', required: true },
        { type: 'checkbox', name: 'enable_ssl_verification', title: "Enable SSL verification" }
      ]
    end
  end
end