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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
|
# frozen_string_literal: true
module Integrations
class Bamboo < BaseCi
include ReactivelyCached
prepend EnableSslVerification
field :bamboo_url,
title: -> { s_('BambooService|Bamboo URL') },
placeholder: -> { s_('https://bamboo.example.com') },
help: -> { s_('BambooService|Bamboo root URL.') },
description: -> { s_('Bamboo root URL (for example, `https://bamboo.example.com`).') },
exposes_secrets: true,
required: true
field :build_key,
help: -> { s_('BambooService|Bamboo build plan key.') },
description: -> { s_('Bamboo build plan key (for example, `KEY`).') },
non_empty_password_title: -> { s_('BambooService|Enter new build key') },
non_empty_password_help: -> { s_('BambooService|Leave blank to use your current build key.') },
placeholder: -> { _('KEY') },
required: true,
is_secret: true
field :username,
help: -> { s_('BambooService|User with API access to the Bamboo server.') },
description: -> { s_('User with API access to the Bamboo server.') },
required: true
field :password,
type: :password,
non_empty_password_title: -> { s_('ProjectService|Enter new password') },
non_empty_password_help: -> { s_('ProjectService|Leave blank to use your current password') },
description: -> { s_('Password of the user.') },
required: true
with_options if: :activated? do
validates :bamboo_url, presence: true, public_url: true
validates :build_key, presence: true
end
validates :username, presence: true, if: ->(integration) { integration.activated? && integration.password }
validates :password, presence: true, if: ->(integration) { integration.activated? && integration.username }
attr_accessor :response
def self.title
s_('BambooService|Atlassian Bamboo')
end
def self.description
s_('BambooService|Run CI/CD pipelines with Atlassian Bamboo.')
end
def self.help
build_help_page_url(
'user/project/integrations/bamboo.md',
s_('BambooService|Run CI/CD pipelines with Atlassian Bamboo. You must set up automatic revision ' \
'labeling and a repository trigger in Bamboo.')
)
end
def self.to_param
'bamboo'
end
def build_page(sha, ref)
with_reactive_cache(sha, ref) { |cached| cached[:build_page] }
end
def commit_status(sha, ref)
with_reactive_cache(sha, ref) { |cached| cached[:commit_status] }
end
def execute(data)
return unless supported_events.include?(data[:object_kind])
get_path("updateAndBuild.action", { buildKey: build_key })
end
def calculate_reactive_cache(sha, _ref)
response = try_get_path("rest/api/latest/result/byChangeset/#{sha}")
{ build_page: read_build_page(response), commit_status: read_commit_status(response) }
end
def avatar_url
ActionController::Base.helpers.image_path(
'illustrations/third-party-logos/integrations-logos/atlassian-bamboo.svg'
)
end
private
def get_build_result(response)
return if response&.code != 200
# 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
end
def read_build_page(response)
result = get_build_result(response)
key =
if result.blank?
# 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.
result.dig('planResultKey', 'key')
end
build_url("browse/#{key}")
end
def read_commit_status(response)
return :error unless response && (response.code == 200 || response.code == 404)
result = get_build_result(response)
status =
if result.blank?
'Pending'
else
result['buildState']
end
return :error unless status.present?
if status.include?('Success')
'success'
elsif status.include?('Failed')
'failed'
elsif status.include?('Pending')
'pending'
else
:error
end
end
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
def build_url(path)
Gitlab::Utils.append_path(bamboo_url, path)
end
def build_get_params(query_params)
params = { verify: enable_ssl_verification, query: query_params }
return params if username.blank? && password.blank?
query_params[:os_authType] = 'basic'
params[:basic_auth] = basic_auth
params
end
def basic_auth
{ username: username, password: password }
end
end
end
|