summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--app/controllers/projects/services_controller.rb3
-rw-r--r--app/models/project.rb3
-rw-r--r--app/models/project_services/bamboo_service.rb105
-rw-r--r--app/views/projects/services/_form.html.haml4
-rw-r--r--doc/README.md1
-rw-r--r--doc/project_services/bamboo.md60
-rw-r--r--doc/project_services/project_services.md18
-rw-r--r--features/project/service.feature6
-rw-r--r--features/steps/project/services.rb20
10 files changed, 218 insertions, 3 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 01ae3562ded..f01267c460c 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -3,6 +3,7 @@ v 7.5.0
- Add time zone configuration on gitlab.yml (Sullivan Senechal)
- Fix LDAP authentication for Git HTTP access
- Fix LDAP config lookup for provider 'ldap'
+ - Add Atlassian Bamboo CI service (Drew Blessing)
v 7.4.2
- Fix internal snippet exposing for unauthenticated users
diff --git a/app/controllers/projects/services_controller.rb b/app/controllers/projects/services_controller.rb
index b50f6286459..a5f30dcfd9d 100644
--- a/app/controllers/projects/services_controller.rb
+++ b/app/controllers/projects/services_controller.rb
@@ -41,7 +41,8 @@ class Projects::ServicesController < Projects::ApplicationController
params.require(:service).permit(
:title, :token, :type, :active, :api_key, :subdomain,
:room, :recipients, :project_url, :webhook,
- :user_key, :device, :priority, :sound
+ :user_key, :device, :priority, :sound, :bamboo_url, :username, :password,
+ :build_key
)
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 613f98ba44b..c58c9b551c9 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -65,6 +65,7 @@ class Project < ActiveRecord::Base
has_one :gemnasium_service, dependent: :destroy
has_one :slack_service, dependent: :destroy
has_one :buildbox_service, dependent: :destroy
+ has_one :bamboo_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
@@ -313,7 +314,7 @@ class Project < ActiveRecord::Base
end
def available_services_names
- %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack pushover buildbox)
+ %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack pushover buildbox bamboo)
end
def gitlab_ci?
diff --git a/app/models/project_services/bamboo_service.rb b/app/models/project_services/bamboo_service.rb
new file mode 100644
index 00000000000..b9eec9ab21e
--- /dev/null
+++ b/app/models/project_services/bamboo_service.rb
@@ -0,0 +1,105 @@
+class BambooService < CiService
+ include HTTParty
+
+ prop_accessor :bamboo_url, :build_key, :username, :password
+
+ validates :bamboo_url, presence: true,
+ format: { with: URI::regexp }, 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?
+
+ def compose_service_hook
+ hook = service_hook || build_service_hook
+ hook.save
+ 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 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)
+ 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)
+ 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)
+ # Bamboo requires a GET and does not take any data.
+ self.class.get("#{bamboo_url}/updateAndBuild.action?buildKey=#{build_key}",
+ verify: false)
+ end
+end
diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml
index 16d59d1fe9d..1151f22c7e8 100644
--- a/app/views/projects/services/_form.html.haml
+++ b/app/views/projects/services/_form.html.haml
@@ -28,7 +28,7 @@
- @service.fields.each do |field|
- name = field[:name]
- - value = @service.send(name)
+ - value = @service.send(name) unless field[:type] == 'password'
- type = field[:type]
- placeholder = field[:placeholder]
- choices = field[:choices]
@@ -45,6 +45,8 @@
= f.check_box name
- elsif type == 'select'
= f.select name, options_for_select(choices, value ? value : default_choice), {}, { class: "form-control" }
+ - elsif type == 'password'
+ = f.password_field name, class: 'form-control'
.form-actions
= f.submit 'Save', class: 'btn btn-save'
diff --git a/doc/README.md b/doc/README.md
index a8e21f75714..7343d5ae273 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -5,6 +5,7 @@
- [API](api/README.md) Explore how you can access GitLab via a simple and powerful API.
- [Markdown](markdown/markdown.md) Learn what you can do with GitLab's advanced formatting system.
- [Permissions](permissions/permissions.md) Learn what each role in a project (guest/reporter/developer/master/owner) can do.
+- [Project Services](project_services/project_services.md) Explore how project services can integrate a project with external services, such as for CI.
- [Public access](public_access/public_access.md) Learn how you can allow public and internal access to a project.
- [SSH](ssh/README.md) Setup your ssh keys and deploy keys for secure access to your projects.
- [Web hooks](web_hooks/web_hooks.md) Let GitLab notify you when new code has been pushed to your project.
diff --git a/doc/project_services/bamboo.md b/doc/project_services/bamboo.md
new file mode 100644
index 00000000000..51668128c62
--- /dev/null
+++ b/doc/project_services/bamboo.md
@@ -0,0 +1,60 @@
+# Atlassian Bamboo CI Service
+
+GitLab provides integration with Atlassian Bamboo for continuous integration.
+When configured, pushes to a project will trigger a build in Bamboo automatically.
+Merge requests will also display CI status showing whether the build is pending,
+failed, or completed successfully. It also provides a link to the Bamboo build
+page for more information.
+
+Bamboo doesn't quite provide the same features as a traditional build system when
+it comes to accepting webhooks and commit data. There are a few things that
+need to be configured in a Bamboo build plan before GitLab can integrate.
+
+## Setup
+
+### Complete these steps in Bamboo:
+
+1. Navigate to a Bamboo build plan and choose 'Configure plan' from the 'Actions'
+dropdown.
+1. Select the 'Triggers' tab.
+1. Click 'Add trigger'.
+1. Enter a description such as 'GitLab trigger'
+1. Choose 'Repository triggers the build when changes are committed'
+1. Check one or more repositories checkboxes
+1. Enter the GitLab IP address in the 'Trigger IP addresses' box. This is a
+whitelist of IP addresses that are allowed to trigger Bamboo builds.
+1. Save the trigger.
+1. In the left pane, select a build stage. If you have multiple build stages
+you want to select the last stage that contains the git checkout task.
+1. Select the 'Miscellaneous' tab.
+1. Under 'Pattern Match Labelling' put '${bamboo.repository.revision.number}'
+in the 'Labels' box.
+1. Save
+
+Bamboo is now ready to accept triggers from GitLab. Next, set up the Bamboo
+service in GitLab
+
+### Complete these steps in GitLab:
+
+1. Navigate to the project you want to configure to trigger builds.
+1. Select 'Settings' in the top navigation.
+1. Select 'Services' in the left navigation.
+1. Click 'Atlassian Bamboo CI'
+1. Select the 'Active' checkbox.
+1. Enter the base URL of your Bamboo server. 'https://bamboo.example.com'
+1. Enter the build key from your Bamboo build plan. Build keys are a short,
+all capital letter, identifier that is unique. It will be something like PR-BLD
+1. If necessary, enter username and password for a Bamboo user that has
+access to trigger the build plan. Leave these fields blank if you do not require
+authentication.
+1. Save or optionally click 'Test Settings'. Please note that 'Test Settings'
+will actually trigger a build in Bamboo.
+
+## Troubleshooting
+
+If builds are not triggered, these are a couple of things to keep in mind.
+
+1. Ensure you entered the right GitLab IP address in Bamboo under 'Trigger
+IP addresses'.
+1. Remember that GitLab only triggers builds on push events. A commit via the
+web interface will not trigger CI currently.
diff --git a/doc/project_services/project_services.md b/doc/project_services/project_services.md
new file mode 100644
index 00000000000..20a69a211dd
--- /dev/null
+++ b/doc/project_services/project_services.md
@@ -0,0 +1,18 @@
+# Project Services
+
+__Project integrations with external services for continuous integration and more.__
+
+## Services
+
+- Assemblia
+- [Atlassian Bamboo CI](bamboo.md) An Atlassian product for continous integration.
+- Build box
+- Campfire
+- Emails on push
+- Flowdock
+- Gemnasium
+- GitLab CI
+- Hipchat
+- PivotalTracker
+- Pushover
+- Slack
diff --git a/features/project/service.feature b/features/project/service.feature
index af88eaefa8f..88fd038d45f 100644
--- a/features/project/service.feature
+++ b/features/project/service.feature
@@ -54,3 +54,9 @@ Feature: Project Services
And I click email on push service link
And I fill email on push settings
Then I should see email on push service settings saved
+
+ Scenario: Activate Atlassian Bamboo CI service
+ When I visit project "Shop" services page
+ 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
diff --git a/features/steps/project/services.rb b/features/steps/project/services.rb
index 5bd60f99c84..17d62210d10 100644
--- a/features/steps/project/services.rb
+++ b/features/steps/project/services.rb
@@ -14,6 +14,7 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
page.should have_content 'GitLab CI'
page.should have_content 'Assembla'
page.should have_content 'Pushover'
+ page.should have_content 'Atlassian Bamboo'
end
step 'I click gitlab-ci service link' do
@@ -137,4 +138,23 @@ class Spinach::Features::ProjectServices < Spinach::FeatureSteps
find_field('Priority').find('option[selected]').value.should == '1'
find_field('Sound').find('option[selected]').value.should == 'bike'
end
+
+ step 'I click Atlassian Bamboo CI service link' do
+ click_link 'Atlassian Bamboo CI'
+ end
+
+ step 'I fill Atlassian Bamboo CI settings' do
+ check 'Active'
+ fill_in 'Bamboo url', with: 'http://bamboo.example.com'
+ fill_in 'Build key', with: 'KEY'
+ fill_in 'Username', with: 'user'
+ fill_in 'Password', with: 'verySecret'
+ click_button 'Save'
+ end
+
+ step 'I should see Atlassian Bamboo CI service settings saved' do
+ find_field('Bamboo url').value.should == 'http://bamboo.example.com'
+ find_field('Build key').value.should == 'KEY'
+ find_field('Username').value.should == 'user'
+ end
end