bamboo_service.rb 3.21 KB
Newer Older
Drew Blessing's avatar
Drew Blessing committed
1 2 3
class BambooService < CiService
  prop_accessor :bamboo_url, :build_key, :username, :password

Robert Speicher's avatar
Robert Speicher committed
4
  validates :bamboo_url, presence: true, url: true, if: :activated?
Drew Blessing's avatar
Drew Blessing committed
5
  validates :build_key, presence: true, if: :activated?
6 7
  validates :username,
    presence: true,
8
    if: ->(service) { service.activated? && service.password }
9 10
  validates :password,
    presence: true,
11
    if: ->(service) { service.activated? && service.username }
Drew Blessing's avatar
Drew Blessing committed
12 13 14 15

  attr_accessor :response

  after_save :compose_service_hook, if: :activated?
16
  before_update :reset_password
Drew Blessing's avatar
Drew Blessing committed
17 18 19 20 21 22

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

23
  def reset_password
24
    if bamboo_url_changed? && !password_touched?
25 26 27 28
      self.password = nil
    end
  end

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

57 58 59
  def supported_events
    %w(push)
  end
Robert Speicher's avatar
Robert Speicher committed
60

Drew Blessing's avatar
Drew Blessing committed
61
  def build_info(sha)
62
    @response = get_path("rest/api/latest/result?label=#{sha}")
Drew Blessing's avatar
Drew Blessing committed
63 64
  end

Valery Sizov's avatar
Valery Sizov committed
65
  def build_page(sha, ref)
Drew Blessing's avatar
Drew Blessing committed
66 67 68 69
    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.
70
      URI.join("#{bamboo_url}/", "browse/#{build_key}").to_s
Drew Blessing's avatar
Drew Blessing committed
71 72 73
    else
      # If actual build link is available, go to build result page.
      result_key = @response['results']['results']['result']['planResultKey']['key']
74
      URI.join("#{bamboo_url}/", "browse/#{result_key}").to_s
Drew Blessing's avatar
Drew Blessing committed
75 76 77
    end
  end

Valery Sizov's avatar
Valery Sizov committed
78
  def commit_status(sha, ref)
Drew Blessing's avatar
Drew Blessing committed
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
    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

99
  def execute(data)
100
    return unless supported_events.include?(data[:object_kind])
101

102 103 104 105 106 107 108 109 110 111 112
    get_path("updateAndBuild.action?buildKey=#{build_key}")
  end

  private

  def build_url(path)
    URI.join("#{bamboo_url}/", path).to_s
  end

  def get_path(path)
    url = build_url(path)
113 114 115 116 117

    if username.blank? && password.blank?
      HTTParty.get(url, verify: false)
    else
      url << '&os_authType=basic'
118 119 120 121 122
      HTTParty.get(url, verify: false,
                        basic_auth: {
                          username: username,
                          password: password
                        })
123
    end
Drew Blessing's avatar
Drew Blessing committed
124 125
  end
end