Merge branch 'jenkins-service' into 'master'

Jenkins service

Show build status on MergeRequest page.
Requires GitLab Hook plugin to be installed in Jenkins
This commit is contained in:
Dmitriy Zaporozhets
2014-05-15 09:45:15 +00:00
11 changed files with 155 additions and 17 deletions
@@ -161,7 +161,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
def ci_status
status = @merge_request.source_project.gitlab_ci_service.commit_status(merge_request.last_commit.sha)
status = @merge_request.source_project.ci_service.commit_status(merge_request.last_commit.sha)
response = {status: status}
render json: response
+1 -1
View File
@@ -32,7 +32,7 @@ module MergeRequestsHelper
end
def ci_build_details_path merge_request
merge_request.source_project.gitlab_ci_service.build_page(merge_request.last_commit.sha)
merge_request.source_project.ci_service.build_page(merge_request.last_commit.sha)
end
def merge_path_description(merge_request, separator)
+14 -1
View File
@@ -56,6 +56,9 @@ class Project < ActiveRecord::Base
has_one :git_hook, dependent: :destroy
has_one :last_event, -> {order 'events.created_at DESC'}, class_name: 'Event', foreign_key: 'project_id'
# Project services
has_many :services
has_one :gitlab_ci_service, dependent: :destroy
has_one :campfire_service, dependent: :destroy
has_one :emails_on_push_service, dependent: :destroy
@@ -66,6 +69,8 @@ class Project < ActiveRecord::Base
has_one :gemnasium_service, dependent: :destroy
has_one :slack_service, dependent: :destroy
has_one :jira_service, dependent: :destroy
has_one :jenkins_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
# Merge Requests for target project should be removed with it
@@ -318,13 +323,21 @@ class Project < ActiveRecord::Base
end
def available_services_names
%w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack jira)
%w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack jira jenkins)
end
def gitlab_ci?
gitlab_ci_service && gitlab_ci_service.active
end
def ci_services
services.select { |service| service.category == :ci }
end
def ci_service
@ci_service ||= services.select(&:activated?).first
end
def jira_tracker?
self.issues_tracker == "jira"
end
+34
View File
@@ -0,0 +1,34 @@
# Base class for CI services
# List methods you need to implement to get your CI service
# working with GitLab Merge Requests
class CiService < Service
def category
:ci
end
# Return complete url to build page
#
# Ex.
# http://jenkins.example.com:8888/job/test1/scm/bySHA1/12d65c
#
def build_page(sha)
# implement inside child
end
# Return string with build status or :error symbol
#
# Allowed states: 'success', 'failed', 'running', 'pending'
#
#
# Ex.
# @service.commit_status('13be4ac')
# # => 'success'
#
# @service.commit_status('2abe4ac')
# # => 'running'
#
#
def commit_status(sha)
# implement inside child
end
end
@@ -17,7 +17,7 @@
# api_key :string(255)
#
class GitlabCiService < Service
class GitlabCiService < CiService
attr_accessible :project_url
validates :project_url, presence: true, if: :activated?
@@ -0,0 +1,79 @@
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# token :string(255)
# project_id :integer not null
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# project_url :string(255)
# subdomain :string(255)
# room :string(255)
# recipients :text
# api_key :string(255)
#
class JenkinsService < CiService
attr_accessible :project_url
validates :project_url, presence: true, if: :activated?
delegate :execute, to: :service_hook, prefix: nil
after_save :compose_service_hook, if: :activated?
def compose_service_hook
hook = service_hook || build_service_hook
jenkins_url = project_url.sub(/job\/.*/, '')
hook.url = jenkins_url + "/gitlab/build_now"
hook.save
end
def title
'Jenkins CI'
end
def description
'An extendable open source continuous integration server'
end
def help
'You must have installed GitLab Hook plugin into Jenkins.'
end
def to_param
'jenkins'
end
def fields
[
{ type: 'text', name: 'project_url', placeholder: 'Jenkins project URL like http://jenkins.example.com/job/my-project/' }
]
end
def build_page sha
project_url + "/scm/bySHA1/#{sha}"
end
def commit_status sha
response = HTTParty.get(build_page(sha), verify: false)
if response.code == 200
if response.include?('alt="Success"')
'success'
elsif response.include?('alt="Failed"')
'failed'
elsif response.include?('alt="In progress"')
'running'
else
'pending'
end
else
:error
end
end
end
+8
View File
@@ -33,6 +33,10 @@ class Service < ActiveRecord::Base
active
end
def category
:common
end
def title
# implement inside child
end
@@ -41,6 +45,10 @@ class Service < ActiveRecord::Base
# implement inside child
end
def help
# implement inside child
end
def to_param
# implement inside child
end
@@ -37,7 +37,7 @@
url_to_automerge_check: "#{automerge_check_project_merge_request_path(@project, @merge_request)}",
check_enable: #{@merge_request.unchecked? ? "true" : "false"},
url_to_ci_check: "#{ci_status_project_merge_request_path(@project, @merge_request)}",
ci_enable: #{@project.gitlab_ci? ? "true" : "false"},
ci_enable: #{@project.ci_service ? "true" : "false"},
current_status: "#{@merge_request.merge_status_name}",
action: "#{controller.action_name}"
});
@@ -1,5 +1,5 @@
.panel.mr-state-widget.panel-default
- if @merge_request.source_project.gitlab_ci? && @commits.any?
- if @merge_request.source_project.ci_service && @commits.any?
.panel-heading
= render "projects/merge_requests/show/mr_ci"
.panel-body
@@ -18,6 +18,10 @@
%li= msg
- if @service.help.present?
.bs-callout
= @service.help
.form-group
= f.label :active, "Active", class: "control-label"
.col-sm-10
+11 -11
View File
@@ -189,9 +189,9 @@ ActiveRecord::Schema.define(version: 20140513095908) do
t.datetime "updated_at"
t.string "type"
t.string "description", default: "", null: false
t.string "avatar"
t.string "ldap_cn"
t.integer "ldap_access"
t.string "avatar"
end
add_index "namespaces", ["name"], name: "index_namespaces_on_name", using: :btree
@@ -238,20 +238,20 @@ ActiveRecord::Schema.define(version: 20140513095908) do
t.datetime "created_at"
t.datetime "updated_at"
t.integer "creator_id"
t.boolean "issues_enabled", default: true, null: false
t.boolean "wall_enabled", default: true, null: false
t.boolean "merge_requests_enabled", default: true, null: false
t.boolean "wiki_enabled", default: true, null: false
t.boolean "issues_enabled", default: true, null: false
t.boolean "wall_enabled", default: true, null: false
t.boolean "merge_requests_enabled", default: true, null: false
t.boolean "wiki_enabled", default: true, null: false
t.integer "namespace_id"
t.string "issues_tracker", default: "gitlab", null: false
t.string "issues_tracker", default: "gitlab", null: false
t.string "issues_tracker_id"
t.boolean "snippets_enabled", default: true, null: false
t.boolean "snippets_enabled", default: true, null: false
t.datetime "last_activity_at"
t.string "import_url"
t.integer "visibility_level", default: 0, null: false
t.boolean "archived", default: false, null: false
t.integer "visibility_level", default: 0, null: false
t.boolean "archived", default: false, null: false
t.string "import_status"
t.float "repository_size", default: 0.0
t.float "repository_size", default: 0.0
t.text "merge_requests_template"
end
@@ -357,6 +357,7 @@ ActiveRecord::Schema.define(version: 20140513095908) do
t.integer "notification_level", default: 1, null: false
t.datetime "password_expires_at"
t.integer "created_by_id"
t.datetime "last_credential_check_at"
t.string "avatar"
t.string "confirmation_token"
t.datetime "confirmed_at"
@@ -364,7 +365,6 @@ ActiveRecord::Schema.define(version: 20140513095908) do
t.string "unconfirmed_email"
t.boolean "hide_no_ssh_key", default: false
t.string "website_url", default: "", null: false
t.datetime "last_credential_check_at"
end
add_index "users", ["admin"], name: "index_users_on_admin", using: :btree