2018-11-20 20:47:30 +05:30
# frozen_string_literal: true
2015-04-26 12:48:37 +05:30
class BambooService < CiService
2021-04-29 21:17:54 +05:30
include ActionView :: Helpers :: UrlHelper
2017-08-17 22:00:37 +05:30
include ReactiveService
2015-04-26 12:48:37 +05:30
prop_accessor :bamboo_url , :build_key , :username , :password
2018-11-08 19:23:39 +05:30
validates :bamboo_url , presence : true , public_url : true , if : :activated?
2015-04-26 12:48:37 +05:30
validates :build_key , presence : true , if : :activated?
validates :username ,
presence : true ,
2015-12-23 02:04:40 +05:30
if : - > ( service ) { service . activated? && service . password }
2015-04-26 12:48:37 +05:30
validates :password ,
presence : true ,
2015-12-23 02:04:40 +05:30
if : - > ( service ) { service . activated? && service . username }
2015-04-26 12:48:37 +05:30
attr_accessor :response
after_save :compose_service_hook , if : :activated?
2015-10-24 18:46:33 +05:30
before_update :reset_password
2015-04-26 12:48:37 +05:30
def compose_service_hook
hook = service_hook || build_service_hook
hook . save
end
2015-10-24 18:46:33 +05:30
def reset_password
if bamboo_url_changed? && ! password_touched?
self . password = nil
end
end
2015-04-26 12:48:37 +05:30
def title
2021-04-29 21:17:54 +05:30
s_ ( 'BambooService|Atlassian Bamboo' )
2015-04-26 12:48:37 +05:30
end
def description
2021-04-29 21:17:54 +05:30
s_ ( 'BambooService|Use the Atlassian Bamboo CI/CD server with GitLab.' )
2015-04-26 12:48:37 +05:30
end
def help
2021-04-29 21:17:54 +05:30
docs_link = link_to _ ( 'Learn more.' ) , Rails . application . routes . url_helpers . help_page_url ( 'user/project/integrations/bamboo' ) , target : '_blank' , rel : 'noopener noreferrer'
s_ ( 'BambooService|Use Atlassian Bamboo to run CI/CD pipelines. You must set up automatic revision labeling and a repository trigger in Bamboo. %{docs_link}' ) . html_safe % { docs_link : docs_link . html_safe }
2015-04-26 12:48:37 +05:30
end
2017-08-17 22:00:37 +05:30
def self . to_param
2015-04-26 12:48:37 +05:30
'bamboo'
end
def fields
[
2021-04-29 21:17:54 +05:30
{
type : 'text' ,
name : 'bamboo_url' ,
title : s_ ( 'BambooService|Bamboo URL' ) ,
placeholder : s_ ( 'https://bamboo.example.com' ) ,
help : s_ ( 'BambooService|Bamboo service root URL.' ) ,
required : true
} ,
{
type : 'text' ,
name : 'build_key' ,
placeholder : s_ ( 'KEY' ) ,
help : s_ ( 'BambooService|Bamboo build plan key.' ) ,
required : true
} ,
{
type : 'text' ,
name : 'username' ,
help : s_ ( 'BambooService|The user with API access to the Bamboo server.' )
} ,
{
type : 'password' ,
name : 'password' ,
non_empty_password_title : s_ ( 'ProjectService|Enter new password' ) ,
non_empty_password_help : s_ ( 'ProjectService|Leave blank to use your current password' )
}
2015-04-26 12:48:37 +05:30
]
end
2017-08-17 22:00:37 +05:30
def build_page ( sha , ref )
with_reactive_cache ( sha , ref ) { | cached | cached [ :build_page ] }
2015-04-26 12:48:37 +05:30
end
2015-12-23 02:04:40 +05:30
2017-08-17 22:00:37 +05:30
def commit_status ( sha , ref )
with_reactive_cache ( sha , ref ) { | cached | cached [ :commit_status ] }
2015-04-26 12:48:37 +05:30
end
2017-08-17 22:00:37 +05:30
def execute ( data )
return unless supported_events . include? ( data [ :object_kind ] )
2018-11-08 19:23:39 +05:30
get_path ( " updateAndBuild.action " , { buildKey : build_key } )
2017-08-17 22:00:37 +05:30
end
def calculate_reactive_cache ( sha , ref )
2020-04-22 19:07:51 +05:30
response = try_get_path ( " rest/api/latest/result/byChangeset/ #{ sha } " )
2017-08-17 22:00:37 +05:30
{ build_page : read_build_page ( response ) , commit_status : read_commit_status ( response ) }
end
2015-04-26 12:48:37 +05:30
2017-08-17 22:00:37 +05:30
private
2019-03-02 22:35:43 +05:30
def get_build_result ( response )
2020-04-22 19:07:51 +05:30
return if response & . code != 200
2019-03-02 22:35:43 +05:30
# May be nil if no result, a single result hash, or an array if multiple results for a given changeset.
result = response . dig ( 'results' , 'results' , 'result' )
# In case of multiple results, arbitrarily assume the last one is the most relevant.
return result . last if result . is_a? ( Array )
result
2018-12-13 13:39:08 +05:30
end
2017-08-17 22:00:37 +05:30
def read_build_page ( response )
2019-03-02 22:35:43 +05:30
result = get_build_result ( response )
2019-02-15 15:39:39 +05:30
key =
2019-03-02 22:35:43 +05:30
if result . blank?
2019-02-15 15:39:39 +05:30
# If actual build link can't be determined, send user to build summary page.
build_key
else
# If actual build link is available, go to build result page.
2019-03-02 22:35:43 +05:30
result . dig ( 'planResultKey' , 'key' )
2019-02-15 15:39:39 +05:30
end
build_url ( " browse/ #{ key } " )
2015-04-26 12:48:37 +05:30
end
2017-08-17 22:00:37 +05:30
def read_commit_status ( response )
2020-04-22 19:07:51 +05:30
return :error unless response && ( response . code == 200 || response . code == 404 )
2015-04-26 12:48:37 +05:30
2019-03-02 22:35:43 +05:30
result = get_build_result ( response )
status =
if result . blank?
'Pending'
else
result . dig ( 'buildState' )
end
return :error unless status . present?
2015-04-26 12:48:37 +05:30
if status . include? ( 'Success' )
'success'
elsif status . include? ( 'Failed' )
'failed'
elsif status . include? ( 'Pending' )
'pending'
else
:error
end
end
2020-04-22 19:07:51 +05:30
def try_get_path ( path , query_params = { } )
params = build_get_params ( query_params )
params [ :extra_log_info ] = { project_id : project_id }
Gitlab :: HTTP . try_get ( build_url ( path ) , params )
end
def get_path ( path , query_params = { } )
Gitlab :: HTTP . get ( build_url ( path ) , build_get_params ( query_params ) )
end
2016-06-16 23:09:34 +05:30
def build_url ( path )
2019-02-15 15:39:39 +05:30
Gitlab :: Utils . append_path ( bamboo_url , path )
2016-06-16 23:09:34 +05:30
end
2020-04-22 19:07:51 +05:30
def build_get_params ( query_params )
params = { verify : false , query : query_params }
return params if username . blank? && password . blank?
2016-06-16 23:09:34 +05:30
2020-04-22 19:07:51 +05:30
query_params [ :os_authType ] = 'basic'
params [ :basic_auth ] = basic_auth
params
end
def basic_auth
{ username : username , password : password }
2015-04-26 12:48:37 +05:30
end
end