BigW Consortium Gitlab

gitlab_ci_service.rb 3.92 KB
Newer Older
1 2 3 4
# == Schema Information
#
# Table name: services
#
5 6 7 8 9 10 11 12 13 14 15 16 17
#  id                    :integer          not null, primary key
#  type                  :string(255)
#  title                 :string(255)
#  project_id            :integer
#  created_at            :datetime
#  updated_at            :datetime
#  active                :boolean          default(FALSE), not null
#  properties            :text
#  template              :boolean          default(FALSE)
#  push_events           :boolean          default(TRUE)
#  issues_events         :boolean          default(TRUE)
#  merge_requests_events :boolean          default(TRUE)
#  tag_push_events       :boolean          default(TRUE)
Stan Hu committed
18
#  note_events           :boolean          default(TRUE), not null
19 20
#

21
class GitlabCiService < CiService
Valery Sizov committed
22 23
  API_PREFIX = "api/v1"

24
  prop_accessor :project_url, :token, :enable_ssl_verification
25 26 27 28 29 30
  validates :project_url,
    presence: true,
    format: { with: /\A#{URI.regexp(%w(http https))}\z/, message: "should be a valid url" }, if: :activated?
  validates :token,
    presence: true,
    format: { with: /\A([A-Za-z0-9]+)\z/ },  if: :activated?
31

32 33
  after_save :compose_service_hook, if: :activated?

34 35 36
  def compose_service_hook
    hook = service_hook || build_service_hook
    hook.url = [project_url, "/build", "?token=#{token}"].join("")
37
    hook.enable_ssl_verification = enable_ssl_verification
38 39
    hook.save
  end
40

41 42 43 44
  def supported_events
    %w(push tag_push)
  end

45
  def execute(data)
46
    return unless supported_events.include?(data[:object_kind])
47

48
    sha = data[:checkout_sha]
49

50 51 52 53 54 55
    if sha.present?
      file = ci_yaml_file(sha)

      if file && file.data
        data.merge!(ci_yaml_file: file.data)
      end
56 57
    end

58 59 60
    service_hook.execute(data)
  end

Valery Sizov committed
61
  def commit_status_path(sha, ref)
Valery Sizov committed
62
    URI::encode(project_url + "/refs/#{ref}/commits/#{sha}/status.json?token=#{token}")
63 64
  end

Valery Sizov committed
65
  def get_ci_build(sha, ref)
66
    @ci_builds ||= {}
Valery Sizov committed
67
    @ci_builds[sha] ||= HTTParty.get(commit_status_path(sha, ref), verify: false)
68 69
  end

Valery Sizov committed
70 71
  def commit_status(sha, ref)
    response = get_ci_build(sha, ref)
72 73 74 75 76 77

    if response.code == 200 and response["status"]
      response["status"]
    else
      :error
    end
78 79
  rescue Errno::ECONNREFUSED
    :error
80 81
  end

Valery Sizov committed
82
  def fork_registration(new_project, private_token)
Valery Sizov committed
83 84 85
    params = {
      id:                  new_project.id,
      name_with_namespace: new_project.name_with_namespace,
86
      path_with_namespace: new_project.path_with_namespace,
Valery Sizov committed
87 88 89 90 91 92
      web_url:             new_project.web_url,
      default_branch:      new_project.default_branch,
      ssh_url_to_repo:     new_project.ssh_url_to_repo
    }

    HTTParty.post(
Valery Sizov committed
93
      fork_registration_path,
Valery Sizov committed
94 95 96
      body: {
        project_id: project.id,
        project_token: token,
Valery Sizov committed
97 98
        private_token: private_token,
        data: params },
Valery Sizov committed
99 100 101 102
      verify: false
    )
  end

Valery Sizov committed
103 104
  def commit_coverage(sha, ref)
    response = get_ci_build(sha, ref)
105 106 107 108

    if response.code == 200 and response["coverage"]
      response["coverage"]
    end
109 110
  rescue Errno::ECONNREFUSED
    nil
111 112
  end

Valery Sizov committed
113
  def build_page(sha, ref)
Valery Sizov committed
114
    URI::encode(project_url + "/refs/#{ref}/commits/#{sha}")
115
  end
116 117 118 119 120 121 122 123

  def builds_path
    project_url + "?ref=" + project.default_branch
  end

  def status_img_path
    project_url + "/status.png?ref=" + project.default_branch
  end
124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139

  def title
    'GitLab CI'
  end

  def description
    'Continuous integration server from GitLab'
  end

  def to_param
    'gitlab_ci'
  end

  def fields
    [
      { type: 'text', name: 'token', placeholder: 'GitLab CI project specific token' },
140 141
      { type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3' },
      { type: 'checkbox', name: 'enable_ssl_verification', title: "Enable SSL verification" }
142 143
    ]
  end
Valery Sizov committed
144 145 146

  private

147 148
  def ci_yaml_file(sha)
    repository.blob_at(sha, '.gitlab-ci.yml')
149 150
  end

Valery Sizov committed
151 152 153
  def fork_registration_path
    project_url.sub(/projects\/\d*/, "#{API_PREFIX}/forks")
  end
154 155 156 157

  def repository
    project.repository
  end
158
end