Merge pull request #8439 from glasspelican/Teamcity
Teamcity integration using 8.1 rest api
This commit is contained in:
commit
25a42a56cf
7 changed files with 149 additions and 3 deletions
|
@ -1,7 +1,7 @@
|
|||
v 7.7.0
|
||||
-
|
||||
-
|
||||
-
|
||||
- Add Jetbrains Teamcity CI service (Jason Lippert)
|
||||
-
|
||||
-
|
||||
-
|
||||
|
|
|
@ -42,7 +42,7 @@ class Projects::ServicesController < Projects::ApplicationController
|
|||
:title, :token, :type, :active, :api_key, :subdomain,
|
||||
:room, :recipients, :project_url, :webhook,
|
||||
:user_key, :device, :priority, :sound, :bamboo_url, :username, :password,
|
||||
:build_key, :server
|
||||
:build_key, :server, :teamcity_url, :build_type
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -66,6 +66,7 @@ class Project < ActiveRecord::Base
|
|||
has_one :slack_service, dependent: :destroy
|
||||
has_one :buildbox_service, dependent: :destroy
|
||||
has_one :bamboo_service, dependent: :destroy
|
||||
has_one :teamcity_service, dependent: :destroy
|
||||
has_one :pushover_service, dependent: :destroy
|
||||
has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id"
|
||||
has_one :forked_from_project, through: :forked_project_link
|
||||
|
@ -314,7 +315,8 @@ class Project < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def available_services_names
|
||||
%w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack pushover buildbox bamboo)
|
||||
%w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla
|
||||
emails_on_push gemnasium slack pushover buildbox bamboo teamcity)
|
||||
end
|
||||
|
||||
def gitlab_ci?
|
||||
|
|
116
app/models/project_services/teamcity_service.rb
Normal file
116
app/models/project_services/teamcity_service.rb
Normal file
|
@ -0,0 +1,116 @@
|
|||
class TeamcityService < CiService
|
||||
include HTTParty
|
||||
|
||||
prop_accessor :teamcity_url, :build_type, :username, :password
|
||||
|
||||
validates :teamcity_url, presence: true,
|
||||
format: { with: URI::regexp }, if: :activated?
|
||||
validates :build_type, 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?
|
||||
|
||||
def compose_service_hook
|
||||
hook = service_hook || build_service_hook
|
||||
hook.save
|
||||
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 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.parse("#{teamcity_url}/httpAuth/app/rest/builds/"\
|
||||
"branch:unspecified:any,number:#{sha}")
|
||||
auth = {
|
||||
username: username,
|
||||
password: password,
|
||||
}
|
||||
@response = HTTParty.get("#{url}", verify: false, basic_auth: auth)
|
||||
end
|
||||
|
||||
def build_page(sha)
|
||||
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.
|
||||
"#{teamcity_url}/viewLog.html?buildTypeId=#{build_type}"
|
||||
else
|
||||
# If actual build link is available, go to build result page.
|
||||
built_id = @response['build']['id']
|
||||
"#{teamcity_url}/viewLog.html?buildId=#{built_id}"\
|
||||
"&buildTypeId=#{build_type}"
|
||||
end
|
||||
end
|
||||
|
||||
def commit_status(sha)
|
||||
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)
|
||||
auth = {
|
||||
username: username,
|
||||
password: password,
|
||||
}
|
||||
|
||||
branch = data[:ref]
|
||||
|
||||
self.class.post("#{teamcity_url}/httpAuth/app/rest/buildQueue",
|
||||
body: "<build branchName=\"#{branch}\">"\
|
||||
"<buildType id=\"#{build_type}\"/>"\
|
||||
'</build>',
|
||||
headers: { 'Content-type' => 'application/xml' },
|
||||
basic_auth: auth
|
||||
)
|
||||
end
|
||||
end
|
|
@ -16,3 +16,4 @@ __Project integrations with external services for continuous integration and mor
|
|||
- PivotalTracker
|
||||
- Pushover
|
||||
- Slack
|
||||
- TeamCity
|
|
@ -66,3 +66,10 @@ Feature: Project Services
|
|||
And I click Atlassian Bamboo CI service link
|
||||
And I fill Atlassian Bamboo CI settings
|
||||
Then I should see Atlassian Bamboo CI service settings saved
|
||||
|
||||
Scenario: Activate jetBrains TeamCity CI service
|
||||
When I visit project "Shop" services page
|
||||
And I click jetBrains TeamCity CI service link
|
||||
And I fill jetBrains TeamCity CI settings
|
||||
Then I should see jetBrains TeamCity CI service settings saved
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
|
|||
page.should have_content 'Assembla'
|
||||
page.should have_content 'Pushover'
|
||||
page.should have_content 'Atlassian Bamboo'
|
||||
page.should have_content 'JetBrains TeamCity'
|
||||
end
|
||||
|
||||
step 'I click gitlab-ci service link' do
|
||||
|
@ -168,4 +169,23 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
|
|||
find_field('Build key').value.should == 'KEY'
|
||||
find_field('Username').value.should == 'user'
|
||||
end
|
||||
|
||||
step 'I click JetBrains TeamCity CI service link' do
|
||||
click_link 'JetBrains TeamCity CI'
|
||||
end
|
||||
|
||||
step 'I fill JetBrains TeamCity CI settings' do
|
||||
check 'Active'
|
||||
fill_in 'Teamcity url', with: 'http://teamcity.example.com'
|
||||
fill_in 'Build type', with: 'GitlabTest_Build'
|
||||
fill_in 'Username', with: 'user'
|
||||
fill_in 'Password', with: 'verySecret'
|
||||
click_button 'Save'
|
||||
end
|
||||
|
||||
step 'I should see JetBrains TeamCity CI service settings saved' do
|
||||
find_field('Teamcity url').value.should == 'http://teamcity.example.com'
|
||||
find_field('Build type').value.should == 'GitlabTest_Build'
|
||||
find_field('Username').value.should == 'user'
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue