gitlab-org--gitlab-foss/app/models/project_services/teamcity_service.rb
Zeger-Jan van de Weg 47da013cf8 Annotate the models
2016-05-06 08:27:46 +02:00

159 lines
4.4 KiB
Ruby

# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string
# title :string
# project_id :integer
# created_at :datetime not null
# updated_at :datetime not null
# active :boolean 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
# build_events :boolean default(FALSE), not null
# category :string default("common"), not null
# default :boolean default(FALSE)
# wiki_page_events :boolean default(TRUE)
#
class TeamcityService < CiService
include HTTParty
prop_accessor :teamcity_url, :build_type, :username, :password
validates :teamcity_url, presence: true, url: true, if: :activated?
validates :build_type, presence: true, if: :activated?
validates :username,
presence: true,
if: ->(service) { service.activated? && service.password }
validates :password,
presence: true,
if: ->(service) { service.activated? && service.username }
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 teamcity_url_changed? && !password_touched?
self.password = nil
end
end
def title
'JetBrains TeamCity CI'
end
def description
'A continuous integration and build server'
end
def help
'The build configuration in Teamcity must use the build format '\
'number %build.vcs.number% '\
'you will also want to configure monitoring of all branches so merge '\
'requests build, that setting is in the vsc root advanced settings.'
end
def to_param
'teamcity'
end
def supported_events
%w(push)
end
def fields
[
{ type: 'text', name: 'teamcity_url',
placeholder: 'TeamCity root URL like https://teamcity.example.com' },
{ type: 'text', name: 'build_type',
placeholder: 'Build configuration ID' },
{ type: 'text', name: 'username',
placeholder: 'A user with permissions to trigger a manual build' },
{ type: 'password', name: 'password' },
]
end
def build_info(sha)
url = URI.join(
teamcity_url,
"/httpAuth/app/rest/builds/branch:unspecified:any,number:#{sha}"
).to_s
auth = {
username: username,
password: password
}
@response = HTTParty.get(url, verify: false, basic_auth: auth)
end
def build_page(sha, ref)
build_info(sha) if @response.nil? || !@response.code
if @response.code != 200
# If actual build link can't be determined,
# send user to build summary page.
URI.join(teamcity_url, "/viewLog.html?buildTypeId=#{build_type}").to_s
else
# If actual build link is available, go to build result page.
built_id = @response['build']['id']
URI.join(
teamcity_url,
"/viewLog.html?buildId=#{built_id}&buildTypeId=#{build_type}"
).to_s
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
'Pending'
else
@response['build']['status']
end
if status.include?('SUCCESS')
'success'
elsif status.include?('FAILURE')
'failed'
elsif status.include?('Pending')
'pending'
else
:error
end
end
def execute(data)
return unless supported_events.include?(data[:object_kind])
auth = {
username: username,
password: password,
}
branch = Gitlab::Git.ref_name(data[:ref])
self.class.post(
URI.join(teamcity_url, '/httpAuth/app/rest/buildQueue').to_s,
body: "<build branchName=\"#{branch}\">"\
"<buildType id=\"#{build_type}\"/>"\
'</build>',
headers: { 'Content-type' => 'application/xml' },
basic_auth: auth
)
end
end