Commit 0ba4dc11 authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge branch 'jenkins-service' into 'master'

Jenkins service

Show build status on MergeRequest page.
Requires GitLab Hook plugin to be installed in Jenkins
parents 0b259abe 90342c9e
......@@ -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
......
......@@ -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)
......
......@@ -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
......
# 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?
......
# == 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
......@@ -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}"
});
.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
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment