bamboo_service.rb 4.17 KB
Newer Older
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
1 2 3 4
# == Schema Information
#
# Table name: services
#
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
5
#  id                    :integer          not null, primary key
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
6 7
#  type                  :string
#  title                 :string
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
8
#  project_id            :integer
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
9 10 11
#  created_at            :datetime         not null
#  updated_at            :datetime         not null
#  active                :boolean          not null
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
12 13
#  properties            :text
#  template              :boolean          default(FALSE)
14 15 16 17
#  push_events           :boolean          default(TRUE)
#  issues_events         :boolean          default(TRUE)
#  merge_requests_events :boolean          default(TRUE)
#  tag_push_events       :boolean          default(TRUE)
18
#  note_events           :boolean          default(TRUE), not null
Stan Hu's avatar
Stan Hu committed
19
#  build_events          :boolean          default(FALSE), not null
Zeger-Jan van de Weg's avatar
Zeger-Jan van de Weg committed
20 21 22
#  category              :string           default("common"), not null
#  default               :boolean          default(FALSE)
#  wiki_page_events      :boolean          default(TRUE)
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
23 24
#

Drew Blessing's avatar
Drew Blessing committed
25 26 27 28 29
class BambooService < CiService
  include HTTParty

  prop_accessor :bamboo_url, :build_key, :username, :password

Robert Speicher's avatar
Robert Speicher committed
30
  validates :bamboo_url, presence: true, url: true, if: :activated?
Drew Blessing's avatar
Drew Blessing committed
31
  validates :build_key, presence: true, if: :activated?
32 33
  validates :username,
    presence: true,
34
    if: ->(service) { service.activated? && service.password }
35 36
  validates :password,
    presence: true,
37
    if: ->(service) { service.activated? && service.username }
Drew Blessing's avatar
Drew Blessing committed
38 39 40 41

  attr_accessor :response

  after_save :compose_service_hook, if: :activated?
42
  before_update :reset_password
Drew Blessing's avatar
Drew Blessing committed
43 44 45 46 47 48

  def compose_service_hook
    hook = service_hook || build_service_hook
    hook.save
  end

49
  def reset_password
50
    if bamboo_url_changed? && !password_touched?
51 52 53 54
      self.password = nil
    end
  end

Drew Blessing's avatar
Drew Blessing committed
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
  def title
    'Atlassian Bamboo CI'
  end

  def description
    'A continuous integration and build server'
  end

  def help
    'You must set up automatic revision labeling and a repository trigger in Bamboo.'
  end

  def to_param
    'bamboo'
  end

  def fields
    [
        { type: 'text', name: 'bamboo_url',
          placeholder: 'Bamboo root URL like https://bamboo.example.com' },
        { type: 'text', name: 'build_key',
          placeholder: 'Bamboo build plan key like KEY' },
        { type: 'text', name: 'username',
          placeholder: 'A user with API access, if applicable' },
        { type: 'password', name: 'password' },
    ]
  end

83 84 85
  def supported_events
    %w(push)
  end
Robert Speicher's avatar
Robert Speicher committed
86

Drew Blessing's avatar
Drew Blessing committed
87
  def build_info(sha)
88
    url = URI.join(bamboo_url, "/rest/api/latest/result?label=#{sha}").to_s
Drew Blessing's avatar
Drew Blessing committed
89 90

    if username.blank? && password.blank?
91
      @response = HTTParty.get(url, verify: false)
Drew Blessing's avatar
Drew Blessing committed
92
    else
93
      url << '&os_authType=basic'
Drew Blessing's avatar
Drew Blessing committed
94
      auth = {
95 96
        username: username,
        password: password
Drew Blessing's avatar
Drew Blessing committed
97
      }
98
      @response = HTTParty.get(url, verify: false, basic_auth: auth)
Drew Blessing's avatar
Drew Blessing committed
99 100 101
    end
  end

Valery Sizov's avatar
Valery Sizov committed
102
  def build_page(sha, ref)
Drew Blessing's avatar
Drew Blessing committed
103 104 105 106
    build_info(sha) if @response.nil? || !@response.code

    if @response.code != 200 || @response['results']['results']['size'] == '0'
      # If actual build link can't be determined, send user to build summary page.
107
      URI.join(bamboo_url, "/browse/#{build_key}").to_s
Drew Blessing's avatar
Drew Blessing committed
108 109 110
    else
      # If actual build link is available, go to build result page.
      result_key = @response['results']['results']['result']['planResultKey']['key']
111
      URI.join(bamboo_url, "/browse/#{result_key}").to_s
Drew Blessing's avatar
Drew Blessing committed
112 113 114
    end
  end

Valery Sizov's avatar
Valery Sizov committed
115
  def commit_status(sha, ref)
Drew Blessing's avatar
Drew Blessing committed
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
    build_info(sha) if @response.nil? || !@response.code
    return :error unless @response.code == 200 || @response.code == 404

    status = if @response.code == 404 || @response['results']['results']['size'] == '0'
               'Pending'
             else
               @response['results']['results']['result']['buildState']
             end

    if status.include?('Success')
      'success'
    elsif status.include?('Failed')
      'failed'
    elsif status.include?('Pending')
      'pending'
    else
      :error
    end
  end

136
  def execute(data)
137
    return unless supported_events.include?(data[:object_kind])
138

Drew Blessing's avatar
Drew Blessing committed
139
    # Bamboo requires a GET and does not take any data.
140 141
    url = URI.join(bamboo_url, "/updateAndBuild.action?buildKey=#{build_key}").to_s
    self.class.get(url, verify: false)
Drew Blessing's avatar
Drew Blessing committed
142 143
  end
end