diff options
author | Dmitriy Zaporozhets <dzaporozhets@gitlab.com> | 2015-02-12 20:02:23 +0000 |
---|---|---|
committer | Dmitriy Zaporozhets <dzaporozhets@gitlab.com> | 2015-02-12 20:02:23 +0000 |
commit | 714ca5189ee6da5f25d7930b48d8216aa4eb936e (patch) | |
tree | fd4665736e41d1f93480ce8a357cf8a04c736cf4 /app | |
parent | 30cf916b263c187fe231acb6e622d21297092add (diff) | |
parent | e8271226b1a474f097909b8006d78dd60bbca7be (diff) | |
download | gitlab-ce-714ca5189ee6da5f25d7930b48d8216aa4eb936e.tar.gz |
Merge branch 'issues_tracker_template' into 'master'
Issues trackers template
If admin defines service template, service in project will be prefilled with the template data.
See merge request !1503
Diffstat (limited to 'app')
29 files changed, 233 insertions, 48 deletions
diff --git a/app/controllers/admin/services_controller.rb b/app/controllers/admin/services_controller.rb new file mode 100644 index 00000000000..e80cabd6e18 --- /dev/null +++ b/app/controllers/admin/services_controller.rb @@ -0,0 +1,51 @@ +class Admin::ServicesController < Admin::ApplicationController + before_filter :service, only: [:edit, :update] + + def index + @services = services_templates + end + + def edit + unless service.present? + redirect_to admin_application_settings_services_path, + alert: "Service is unknown or it doesn't exist" + end + end + + def update + if service.update_attributes(application_services_params[:service]) + redirect_to admin_application_settings_services_path, + notice: 'Application settings saved successfully' + else + render :edit + end + end + + private + + def services_templates + templates = [] + + Service.available_services_names.each do |service_name| + service_template = service_name.concat("_service").camelize.constantize + templates << service_template.where(template: true).first_or_create + end + + templates + end + + def service + @service ||= Service.where(id: params[:id], template: true).first + end + + def application_services_params + params.permit(:id, + service: [ + :title, :token, :type, :active, :api_key, :subdomain, + :room, :recipients, :project_url, :webhook, + :user_key, :device, :priority, :sound, :bamboo_url, :username, :password, + :build_key, :server, :teamcity_url, :build_type, + :description, :issues_url, :new_issue_url, :restrict_to_branch + ]) + end +end diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb index d640728519a..50be458bf24 100644 --- a/app/models/concerns/mentionable.rb +++ b/app/models/concerns/mentionable.rb @@ -67,9 +67,10 @@ module Mentionable return [] if text.blank? ext = Gitlab::ReferenceExtractor.new ext.analyze(text, p) - (ext.issues_for + - ext.merge_requests_for + - ext.commits_for).uniq - [local_reference] + + (ext.issues_for(p) + + ext.merge_requests_for(p) + + ext.commits_for(p)).uniq - [local_reference] end # Create a cross-reference Note for each GFM reference to another Mentionable found in +mentionable_text+. diff --git a/app/models/external_issue.rb b/app/models/external_issue.rb new file mode 100644 index 00000000000..50efcb32f1b --- /dev/null +++ b/app/models/external_issue.rb @@ -0,0 +1,25 @@ +class ExternalIssue + def initialize(issue_identifier, project) + @issue_identifier, @project = issue_identifier, project + end + + def to_s + @issue_identifier.to_s + end + + def id + @issue_identifier.to_s + end + + def iid + @issue_identifier.to_s + end + + def ==(other) + other.is_a?(self.class) && (to_s == other.to_s) + end + + def project + @project + end +end diff --git a/app/models/project.rb b/app/models/project.rb index e53b268c8ea..56e1aa29040 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -353,18 +353,28 @@ class Project < ActiveRecord::Base end def build_missing_services - available_services_names.each do |service_name| - service = services.find { |service| service.to_param == service_name } + services_templates = Service.where(template: true) + + Service.available_services_names.each do |service_name| + service = find_service(services, service_name) # If service is available but missing in db - # we should create an instance. Ex `create_gitlab_ci_service` - service = self.send :"create_#{service_name}_service" if service.nil? + if service.nil? + # We should check if template for the service exists + template = find_service(services_templates, service_name) + + if template.nil? + # If no template, we should create an instance. Ex `create_gitlab_ci_service` + service = self.send :"create_#{service_name}_service" + else + Service.create_from_template(self.id, template) + end + end end end - def available_services_names - %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla asana - emails_on_push gemnasium slack pushover buildbox bamboo teamcity jira redmine custom_issue_tracker) + def find_service(list, name) + list.find { |service| service.to_param == name } end def gitlab_ci? diff --git a/app/models/project_services/asana_service.rb b/app/models/project_services/asana_service.rb index db1e7a2b1cb..66b72572b9c 100644 --- a/app/models/project_services/asana_service.rb +++ b/app/models/project_services/asana_service.rb @@ -2,14 +2,15 @@ # # Table name: services # -# id :integer not null, primary key -# type :string(255) -# title :string(255) -# project_id :integer not null -# created_at :datetime -# updated_at :datetime -# active :boolean default(FALSE), not null -# properties :text +# id :integer not null, primary key +# type :string(255) +# title :string(255) +# project_id :integer +# created_at :datetime +# updated_at :datetime +# active :boolean default(FALSE), not null +# properties :text +# template :boolean default(FALSE) # require 'asana' diff --git a/app/models/project_services/assembla_service.rb b/app/models/project_services/assembla_service.rb index 0b90a14f39c..cf7598f35eb 100644 --- a/app/models/project_services/assembla_service.rb +++ b/app/models/project_services/assembla_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class AssemblaService < Service diff --git a/app/models/project_services/bamboo_service.rb b/app/models/project_services/bamboo_service.rb index 745609e5911..df68803152f 100644 --- a/app/models/project_services/bamboo_service.rb +++ b/app/models/project_services/bamboo_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class BambooService < CiService diff --git a/app/models/project_services/buildbox_service.rb b/app/models/project_services/buildbox_service.rb index 0ab67b79fe4..058c890ae45 100644 --- a/app/models/project_services/buildbox_service.rb +++ b/app/models/project_services/buildbox_service.rb @@ -5,13 +5,13 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # - require "addressable/uri" class BuildboxService < CiService diff --git a/app/models/project_services/campfire_service.rb b/app/models/project_services/campfire_service.rb index 3116c311052..14b6b87a0b7 100644 --- a/app/models/project_services/campfire_service.rb +++ b/app/models/project_services/campfire_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class CampfireService < Service diff --git a/app/models/project_services/ci_service.rb b/app/models/project_services/ci_service.rb index b1d5e49ede3..5a26c25b3c3 100644 --- a/app/models/project_services/ci_service.rb +++ b/app/models/project_services/ci_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # # Base class for CI services diff --git a/app/models/project_services/custom_issue_tracker_service.rb b/app/models/project_services/custom_issue_tracker_service.rb index 5845e2d3525..b29d1c86881 100644 --- a/app/models/project_services/custom_issue_tracker_service.rb +++ b/app/models/project_services/custom_issue_tracker_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class CustomIssueTrackerService < IssueTrackerService diff --git a/app/models/project_services/emails_on_push_service.rb b/app/models/project_services/emails_on_push_service.rb index b9071b98295..86693ad0c7e 100644 --- a/app/models/project_services/emails_on_push_service.rb +++ b/app/models/project_services/emails_on_push_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class EmailsOnPushService < Service diff --git a/app/models/project_services/flowdock_service.rb b/app/models/project_services/flowdock_service.rb index 86705f5dabd..13e2dfceb1a 100644 --- a/app/models/project_services/flowdock_service.rb +++ b/app/models/project_services/flowdock_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # require "flowdock-git-hook" diff --git a/app/models/project_services/gemnasium_service.rb b/app/models/project_services/gemnasium_service.rb index 18fdd204ecd..a2c87ae88f1 100644 --- a/app/models/project_services/gemnasium_service.rb +++ b/app/models/project_services/gemnasium_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # require "gemnasium/gitlab_service" diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb index 248f749b310..f4b463e8199 100644 --- a/app/models/project_services/gitlab_ci_service.rb +++ b/app/models/project_services/gitlab_ci_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class GitlabCiService < CiService diff --git a/app/models/project_services/gitlab_issue_tracker_service.rb b/app/models/project_services/gitlab_issue_tracker_service.rb index 25e399883b7..b1eab24df19 100644 --- a/app/models/project_services/gitlab_issue_tracker_service.rb +++ b/app/models/project_services/gitlab_issue_tracker_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class GitlabIssueTrackerService < IssueTrackerService diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb index c4c563b3cca..003e06a4c80 100644 --- a/app/models/project_services/hipchat_service.rb +++ b/app/models/project_services/hipchat_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class HipchatService < Service diff --git a/app/models/project_services/issue_tracker_service.rb b/app/models/project_services/issue_tracker_service.rb index b19c02bab44..51b2fb3dcc7 100644 --- a/app/models/project_services/issue_tracker_service.rb +++ b/app/models/project_services/issue_tracker_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class IssueTrackerService < Service @@ -77,12 +78,14 @@ class IssueTrackerService < Service end def set_project_url - id = self.project.issues_tracker_id + if self.project + id = self.project.issues_tracker_id - if id - issues_tracker['project_url'].gsub(":issues_tracker_id", id) - else - issues_tracker['project_url'] + if id + issues_tracker['project_url'].gsub(":issues_tracker_id", id) + end end + + issues_tracker['project_url'] end end diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb index 7a32b0e8c2c..a159c287485 100644 --- a/app/models/project_services/jira_service.rb +++ b/app/models/project_services/jira_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class JiraService < IssueTrackerService diff --git a/app/models/project_services/pivotaltracker_service.rb b/app/models/project_services/pivotaltracker_service.rb index 09e114f9cca..287812c57a5 100644 --- a/app/models/project_services/pivotaltracker_service.rb +++ b/app/models/project_services/pivotaltracker_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class PivotaltrackerService < Service diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb index a9b23f97ba0..3a3af59390a 100644 --- a/app/models/project_services/pushover_service.rb +++ b/app/models/project_services/pushover_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class PushoverService < Service diff --git a/app/models/project_services/redmine_service.rb b/app/models/project_services/redmine_service.rb index 547b2401832..e1dc10415e0 100644 --- a/app/models/project_services/redmine_service.rb +++ b/app/models/project_services/redmine_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class RedmineService < IssueTrackerService diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb index 963f5440b6f..297d8bbb5d4 100644 --- a/app/models/project_services/slack_service.rb +++ b/app/models/project_services/slack_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class SlackService < Service diff --git a/app/models/project_services/teamcity_service.rb b/app/models/project_services/teamcity_service.rb index 287f5c0e84e..c4b6ef5d9a9 100644 --- a/app/models/project_services/teamcity_service.rb +++ b/app/models/project_services/teamcity_service.rb @@ -5,11 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text +# template :boolean default(FALSE) # class TeamcityService < CiService diff --git a/app/models/service.rb b/app/models/service.rb index caabe8e971d..f87d875c10a 100644 --- a/app/models/service.rb +++ b/app/models/service.rb @@ -5,12 +5,12 @@ # id :integer not null, primary key # type :string(255) # title :string(255) -# project_id :integer not null +# project_id :integer # created_at :datetime # updated_at :datetime # active :boolean default(FALSE), not null # properties :text -# +# template :boolean default(FALSE) # To add new service you should build a class inherited from Service # and implement a set of methods @@ -25,7 +25,7 @@ class Service < ActiveRecord::Base belongs_to :project has_one :service_hook - validates :project_id, presence: true + validates :project_id, presence: true, unless: Proc.new { |service| service.template? } scope :visible, -> { where.not(type: 'GitlabIssueTrackerService') } @@ -33,6 +33,10 @@ class Service < ActiveRecord::Base active end + def template? + template + end + def category :common end @@ -94,7 +98,15 @@ class Service < ActiveRecord::Base self.category == :issue_tracker end - def self.issue_tracker_service_list - Service.select(&:issue_tracker?).map{ |s| s.to_param } + def self.available_services_names + %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla asana + emails_on_push gemnasium slack pushover buildbox bamboo teamcity jira redmine custom_issue_tracker) + end + + def self.create_from_template(project_id, template) + service = template.dup + service.template = false + service.project_id = project_id + service if service.save end end diff --git a/app/views/admin/services/_form.html.haml b/app/views/admin/services/_form.html.haml new file mode 100644 index 00000000000..d8242e37621 --- /dev/null +++ b/app/views/admin/services/_form.html.haml @@ -0,0 +1,36 @@ +%h3.page-title + = @service.title + +%p #{@service.description} template + += form_for :service, url: admin_application_settings_service_path, method: :put, html: { class: 'form-horizontal fieldset-form' } do |f| + - if @service.errors.any? + #error_explanation + .alert.alert-danger + - @service.errors.full_messages.each do |msg| + %p= msg + + - @service.fields.each do |field| + - name = field[:name] + - value = @service.send(name) unless field[:type] == 'password' + - type = field[:type] + - placeholder = field[:placeholder] + - choices = field[:choices] + - default_choice = field[:default_choice] + + .form-group + = f.label name, class: "control-label" + .col-sm-10 + - if type == 'text' + = f.text_field name, class: "form-control", placeholder: placeholder + - elsif type == 'textarea' + = f.text_area name, rows: 5, class: "form-control", placeholder: placeholder + - elsif type == 'checkbox' + = 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/app/views/admin/services/edit.html.haml b/app/views/admin/services/edit.html.haml new file mode 100644 index 00000000000..bcc5832792f --- /dev/null +++ b/app/views/admin/services/edit.html.haml @@ -0,0 +1 @@ += render 'form' diff --git a/app/views/admin/services/index.html.haml b/app/views/admin/services/index.html.haml new file mode 100644 index 00000000000..1d3e192a325 --- /dev/null +++ b/app/views/admin/services/index.html.haml @@ -0,0 +1,22 @@ +%h3.page-title Service templates +%p.light Service template allows you to set default values for project services + +%table.table + %thead + %tr + %th + %th Service + %th Desription + %th Last edit + - @services.sort_by(&:title).each do |service| + %tr + %td + = icon("copy", class: 'clgray') + %td + = link_to edit_admin_application_settings_service_path(service.id) do + %strong= service.title + %td + = service.description + %td.light + = time_ago_in_words service.updated_at + ago diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml index 4813a4f16f5..4f864926d08 100644 --- a/app/views/layouts/nav/_admin.html.haml +++ b/app/views/layouts/nav/_admin.html.haml @@ -46,6 +46,12 @@ %span Applications + = nav_link(controller: :application_settings) do + = link_to admin_application_settings_services_path, title: 'Service Templates' do + %i.fa.fa-copy + %span + Service Templates + = nav_link(controller: :application_settings, html_options: { class: 'separate-item'}) do = link_to admin_application_settings_path, title: 'Settings' do %i.fa.fa-cogs |