bamboo_service.rb 3.98 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 6 7 8 9 10 11 12 13
#  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)
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
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
20 21
#

Drew Blessing's avatar
Drew Blessing committed
22 23 24 25 26
class BambooService < CiService
  include HTTParty

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

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

  attr_accessor :response

  after_save :compose_service_hook, if: :activated?
39
  before_update :reset_password
Drew Blessing's avatar
Drew Blessing committed
40 41 42 43 44 45

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

46
  def reset_password
47
    if bamboo_url_changed? && !password_touched?
48 49 50 51
      self.password = nil
    end
  end

Drew Blessing's avatar
Drew Blessing committed
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
  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

80 81 82
  def supported_events
    %w(push)
  end
Robert Speicher's avatar
Robert Speicher committed
83

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

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

Valery Sizov's avatar
Valery Sizov committed
99
  def build_page(sha, ref)
Drew Blessing's avatar
Drew Blessing committed
100 101 102 103
    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.
104
      URI.join(bamboo_url, "/browse/#{build_key}").to_s
Drew Blessing's avatar
Drew Blessing committed
105 106 107
    else
      # If actual build link is available, go to build result page.
      result_key = @response['results']['results']['result']['planResultKey']['key']
108
      URI.join(bamboo_url, "/browse/#{result_key}").to_s
Drew Blessing's avatar
Drew Blessing committed
109 110 111
    end
  end

Valery Sizov's avatar
Valery Sizov committed
112
  def commit_status(sha, ref)
Drew Blessing's avatar
Drew Blessing committed
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
    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

133
  def execute(data)
134
    return unless supported_events.include?(data[:object_kind])
135

Drew Blessing's avatar
Drew Blessing committed
136
    # Bamboo requires a GET and does not take any data.
137 138
    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
139 140
  end
end