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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
# == Schema Information
#
# Table name: services
#
# 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)
# note_events :boolean default(TRUE), not null
#
class BambooService < CiService
include HTTParty
prop_accessor :bamboo_url, :build_key, :username, :password
validates :bamboo_url,
presence: true,
format: { with: /\A#{URI.regexp}\z/ },
if: :activated?
validates :build_key, presence: true, if: :activated?
validates :username,
presence: true,
if: ->(service) { service.password? },
if: :activated?
validates :password,
presence: true,
if: ->(service) { service.username? },
if: :activated?
attr_accessor :response
after_save :compose_service_hook, if: :activated?
before_update :reset_password
def compose_service_hook
hook = service_hook || build_service_hook
hook.save
end
def reset_password
if prop_updated?(:bamboo_url)
self.password = nil
end
end
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
def supported_events
%w(push)
end
def build_info(sha)
url = URI.parse("#{bamboo_url}/rest/api/latest/result?label=#{sha}")
if username.blank? && password.blank?
@response = HTTParty.get(parsed_url.to_s, verify: false)
else
get_url = "#{url}&os_authType=basic"
auth = {
username: username,
password: password,
}
@response = HTTParty.get(get_url, verify: false, basic_auth: auth)
end
end
def build_page(sha, ref)
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.
"#{bamboo_url}/browse/#{build_key}"
else
# If actual build link is available, go to build result page.
result_key = @response['results']['results']['result']['planResultKey']['key']
"#{bamboo_url}/browse/#{result_key}"
end
end
def commit_status(sha, ref)
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
def execute(data)
return unless supported_events.include?(data[:object_kind])
# Bamboo requires a GET and does not take any data.
self.class.get("#{bamboo_url}/updateAndBuild.action?buildKey=#{build_key}",
verify: false)
end
end
|