Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/models')
-rw-r--r--app/models/application_setting.rb4
-rw-r--r--app/models/ci/build.rb60
-rw-r--r--app/models/commit.rb15
-rw-r--r--app/models/commit_status.rb12
-rw-r--r--app/models/concerns/editable.rb7
-rw-r--r--app/models/concerns/issuable.rb1
-rw-r--r--app/models/conversational_development_index/card.rb26
-rw-r--r--app/models/conversational_development_index/idea_to_production_step.rb19
-rw-r--r--app/models/conversational_development_index/metric.rb21
-rw-r--r--app/models/issue.rb4
-rw-r--r--app/models/key.rb9
-rw-r--r--app/models/label.rb2
-rw-r--r--app/models/lfs_objects_project.rb3
-rw-r--r--app/models/list.rb2
-rw-r--r--app/models/namespace.rb5
-rw-r--r--app/models/note.rb1
-rw-r--r--app/models/project.rb5
-rw-r--r--app/models/project_services/asana_service.rb3
-rw-r--r--app/models/project_services/assembla_service.rb2
-rw-r--r--app/models/project_services/bamboo_service.rb4
-rw-r--r--app/models/project_services/buildkite_service.rb4
-rw-r--r--app/models/project_services/campfire_service.rb4
-rw-r--r--app/models/project_services/chat_notification_service.rb6
-rw-r--r--app/models/project_services/custom_issue_tracker_service.rb6
-rw-r--r--app/models/project_services/deployment_service.rb4
-rw-r--r--app/models/project_services/drone_ci_service.rb4
-rw-r--r--app/models/project_services/external_wiki_service.rb2
-rw-r--r--app/models/project_services/flowdock_service.rb2
-rw-r--r--app/models/project_services/gemnasium_service.rb4
-rw-r--r--app/models/project_services/hipchat_service.rb2
-rw-r--r--app/models/project_services/irker_service.rb2
-rw-r--r--app/models/project_services/issue_tracker_service.rb6
-rw-r--r--app/models/project_services/jira_service.rb12
-rw-r--r--app/models/project_services/mock_ci_service.rb7
-rw-r--r--app/models/project_services/mock_monitoring_service.rb4
-rw-r--r--app/models/project_services/pipelines_email_service.rb3
-rw-r--r--app/models/project_services/pivotaltracker_service.rb3
-rw-r--r--app/models/project_services/prometheus_service.rb3
-rw-r--r--app/models/project_services/pushover_service.rb6
-rw-r--r--app/models/project_services/teamcity_service.rb4
-rw-r--r--app/models/snippet.rb1
-rw-r--r--app/models/user.rb6
42 files changed, 212 insertions, 88 deletions
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 3d12f3c306b..9e04976e8fd 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -143,7 +143,7 @@ class ApplicationSetting < ActiveRecord::Base
validates_each :restricted_visibility_levels do |record, attr, value|
value&.each do |level|
- unless Gitlab::VisibilityLevel.options.has_value?(level)
+ unless Gitlab::VisibilityLevel.options.value?(level)
record.errors.add(attr, "'#{level}' is not a valid visibility level")
end
end
@@ -151,7 +151,7 @@ class ApplicationSetting < ActiveRecord::Base
validates_each :import_sources do |record, attr, value|
value&.each do |source|
- unless Gitlab::ImportSources.options.has_value?(source)
+ unless Gitlab::ImportSources.options.value?(source)
record.errors.add(attr, "'#{source}' is not a import source")
end
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 58dfdd87652..cec1ca89a6a 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -47,8 +47,8 @@ module Ci
before_destroy { unscoped_project }
after_create :execute_hooks
- after_save :update_project_statistics, if: :artifacts_size_changed?
- after_destroy :update_project_statistics
+ after_commit :update_project_statistics_after_save, on: [:create, :update]
+ after_commit :update_project_statistics, on: :destroy
class << self
# This is needed for url_for to work,
@@ -138,6 +138,17 @@ module Ci
ExpandVariables.expand(environment, simple_variables) if environment
end
+ def environment_url
+ return @environment_url if defined?(@environment_url)
+
+ @environment_url =
+ if unexpanded_url = options&.dig(:environment, :url)
+ ExpandVariables.expand(unexpanded_url, simple_variables)
+ else
+ persisted_environment&.external_url
+ end
+ end
+
def has_environment?
environment.present?
end
@@ -198,20 +209,23 @@ module Ci
# All variables, including those dependent on other variables
def variables
- variables = simple_variables
- variables += persisted_environment.predefined_variables if persisted_environment.present?
- variables
+ simple_variables.concat(persisted_environment_variables)
end
def merge_request
- merge_requests = MergeRequest.includes(:merge_request_diff)
- .where(source_branch: ref,
- source_project: pipeline.project)
- .reorder(iid: :asc)
-
- merge_requests.find do |merge_request|
- merge_request.commits_sha.include?(pipeline.sha)
- end
+ return @merge_request if defined?(@merge_request)
+
+ @merge_request ||=
+ begin
+ merge_requests = MergeRequest.includes(:merge_request_diff)
+ .where(source_branch: ref,
+ source_project: pipeline.project)
+ .reorder(iid: :desc)
+
+ merge_requests.find do |merge_request|
+ merge_request.commits_sha.include?(pipeline.sha)
+ end
+ end
end
def repo_url
@@ -335,7 +349,7 @@ module Ci
end
def has_expiring_artifacts?
- artifacts_expire_at.present?
+ artifacts_expire_at.present? && artifacts_expire_at > Time.now
end
def keep_artifacts!
@@ -462,6 +476,18 @@ module Ci
variables.concat(legacy_variables)
end
+ def persisted_environment_variables
+ return [] unless persisted_environment
+
+ variables = persisted_environment.predefined_variables
+
+ if url = environment_url
+ variables << { key: 'CI_ENVIRONMENT_URL', value: url, public: true }
+ end
+
+ variables
+ end
+
def legacy_variables
variables = [
{ key: 'CI_BUILD_ID', value: id.to_s, public: true },
@@ -491,5 +517,11 @@ module Ci
ProjectCacheWorker.perform_async(project_id, [], [:build_artifacts_size])
end
+
+ def update_project_statistics_after_save
+ if previous_changes.include?('artifacts_size')
+ update_project_statistics
+ end
+ end
end
end
diff --git a/app/models/commit.rb b/app/models/commit.rb
index dbc0a22829e..bfa3a624e70 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -14,7 +14,7 @@ class Commit
participant :committer
participant :notes_with_associations
- attr_accessor :project
+ attr_accessor :project, :author
DIFF_SAFE_LINES = Gitlab::Git::DiffCollection::DEFAULT_LIMITS[:max_lines]
@@ -177,7 +177,7 @@ class Commit
if RequestStore.active?
key = "commit_author:#{author_email.downcase}"
# nil is a valid value since no author may exist in the system
- if RequestStore.store.has_key?(key)
+ if RequestStore.store.key?(key)
@author = RequestStore.store[key]
else
@author = find_author_by_any_email
@@ -326,11 +326,12 @@ class Commit
end
def raw_diffs(*args)
- if Gitlab::GitalyClient.feature_enabled?(:commit_raw_diffs)
- Gitlab::GitalyClient::Commit.new(project.repository).diff_from_parent(self, *args)
- else
- raw.diffs(*args)
- end
+ # Uncomment when https://gitlab.com/gitlab-org/gitaly/merge_requests/170 is merged
+ # if Gitlab::GitalyClient.feature_enabled?(:commit_raw_diffs)
+ # Gitlab::GitalyClient::Commit.new(project.repository).diff_from_parent(self, *args)
+ # else
+ raw.diffs(*args)
+ # end
end
def raw_deltas
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index fe63728ea23..8b4ed49269d 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -18,7 +18,7 @@ class CommitStatus < ActiveRecord::Base
validates :name, presence: true
alias_attribute :author, :user
-
+
scope :failed_but_allowed, -> do
where(allow_failure: true, status: [:failed, :canceled])
end
@@ -83,14 +83,15 @@ class CommitStatus < ActiveRecord::Base
next if transition.loopback?
commit_status.run_after_commit do
- pipeline.try do |pipeline|
+ if pipeline
if complete? || manual?
PipelineProcessWorker.perform_async(pipeline.id)
else
PipelineUpdateWorker.perform_async(pipeline.id)
end
- ExpireJobCacheWorker.perform_async(commit_status.id)
end
+
+ ExpireJobCacheWorker.perform_async(commit_status.id)
end
end
@@ -126,6 +127,11 @@ class CommitStatus < ActiveRecord::Base
false
end
+ # To be overriden when inherrited from
+ def retryable?
+ false
+ end
+
def stuck?
false
end
diff --git a/app/models/concerns/editable.rb b/app/models/concerns/editable.rb
new file mode 100644
index 00000000000..c62c7e1e936
--- /dev/null
+++ b/app/models/concerns/editable.rb
@@ -0,0 +1,7 @@
+module Editable
+ extend ActiveSupport::Concern
+
+ def is_edited?
+ last_edited_at.present? && last_edited_at != created_at
+ end
+end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 075ec575f9d..ea10d004c9c 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -15,6 +15,7 @@ module Issuable
include Taskable
include TimeTrackable
include Importable
+ include Editable
# This object is used to gather issuable meta data for displaying
# upvotes, downvotes, notes and closing merge requests count for issues and merge requests
diff --git a/app/models/conversational_development_index/card.rb b/app/models/conversational_development_index/card.rb
new file mode 100644
index 00000000000..e8f09dc9161
--- /dev/null
+++ b/app/models/conversational_development_index/card.rb
@@ -0,0 +1,26 @@
+module ConversationalDevelopmentIndex
+ class Card
+ attr_accessor :metric, :title, :description, :feature, :blog, :docs
+
+ def initialize(metric:, title:, description:, feature:, blog:, docs: nil)
+ self.metric = metric
+ self.title = title
+ self.description = description
+ self.feature = feature
+ self.blog = blog
+ self.docs = docs
+ end
+
+ def instance_score
+ metric.instance_score(feature)
+ end
+
+ def leader_score
+ metric.leader_score(feature)
+ end
+
+ def percentage_score
+ metric.percentage_score(feature)
+ end
+ end
+end
diff --git a/app/models/conversational_development_index/idea_to_production_step.rb b/app/models/conversational_development_index/idea_to_production_step.rb
new file mode 100644
index 00000000000..6e1753c9f30
--- /dev/null
+++ b/app/models/conversational_development_index/idea_to_production_step.rb
@@ -0,0 +1,19 @@
+module ConversationalDevelopmentIndex
+ class IdeaToProductionStep
+ attr_accessor :metric, :title, :features
+
+ def initialize(metric:, title:, features:)
+ self.metric = metric
+ self.title = title
+ self.features = features
+ end
+
+ def percentage_score
+ sum = features.sum do |feature|
+ metric.percentage_score(feature)
+ end
+
+ sum / features.size.to_f
+ end
+ end
+end
diff --git a/app/models/conversational_development_index/metric.rb b/app/models/conversational_development_index/metric.rb
new file mode 100644
index 00000000000..f42f516f99a
--- /dev/null
+++ b/app/models/conversational_development_index/metric.rb
@@ -0,0 +1,21 @@
+module ConversationalDevelopmentIndex
+ class Metric < ActiveRecord::Base
+ include Presentable
+
+ self.table_name = 'conversational_development_index_metrics'
+
+ def instance_score(feature)
+ self["instance_#{feature}"]
+ end
+
+ def leader_score(feature)
+ self["leader_#{feature}"]
+ end
+
+ def percentage_score(feature)
+ return 100 if leader_score(feature).zero?
+
+ 100 * instance_score(feature) / leader_score(feature)
+ end
+ end
+end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index a88dbb3e065..693cc21bb40 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -251,9 +251,9 @@ class Issue < ActiveRecord::Base
def as_json(options = {})
super(options).tap do |json|
- json[:subscribed] = subscribed?(options[:user], project) if options.has_key?(:user) && options[:user]
+ json[:subscribed] = subscribed?(options[:user], project) if options.key?(:user) && options[:user]
- if options.has_key?(:labels)
+ if options.key?(:labels)
json[:labels] = labels.as_json(
project: project,
only: [:id, :title, :description, :color, :priority],
diff --git a/app/models/key.rb b/app/models/key.rb
index b7956052c3f..cb8f10f6d55 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -1,7 +1,6 @@
require 'digest/md5'
class Key < ActiveRecord::Base
- include AfterCommitQueue
include Sortable
LAST_USED_AT_REFRESH_TIME = 1.day.to_i
@@ -25,10 +24,10 @@ class Key < ActiveRecord::Base
delegate :name, :email, to: :user, prefix: true
- after_create :add_to_shell
- after_create :notify_user
+ after_commit :add_to_shell, on: :create
+ after_commit :notify_user, on: :create
after_create :post_create_hook
- after_destroy :remove_from_shell
+ after_commit :remove_from_shell, on: :destroy
after_destroy :post_destroy_hook
def key=(value)
@@ -93,6 +92,6 @@ class Key < ActiveRecord::Base
end
def notify_user
- run_after_commit { NotificationService.new.new_key(self) }
+ NotificationService.new.new_key(self)
end
end
diff --git a/app/models/label.rb b/app/models/label.rb
index 074239702f8..955d6b4079b 100644
--- a/app/models/label.rb
+++ b/app/models/label.rb
@@ -172,7 +172,7 @@ class Label < ActiveRecord::Base
def as_json(options = {})
super(options).tap do |json|
- json[:priority] = priority(options[:project]) if options.has_key?(:project)
+ json[:priority] = priority(options[:project]) if options.key?(:project)
end
end
diff --git a/app/models/lfs_objects_project.rb b/app/models/lfs_objects_project.rb
index 007eed5600a..b0625c52b62 100644
--- a/app/models/lfs_objects_project.rb
+++ b/app/models/lfs_objects_project.rb
@@ -6,8 +6,7 @@ class LfsObjectsProject < ActiveRecord::Base
validates :lfs_object_id, uniqueness: { scope: [:project_id], message: "already exists in project" }
validates :project_id, presence: true
- after_create :update_project_statistics
- after_destroy :update_project_statistics
+ after_commit :update_project_statistics, on: [:create, :destroy]
private
diff --git a/app/models/list.rb b/app/models/list.rb
index fbd19acd1f5..ba7353a1325 100644
--- a/app/models/list.rb
+++ b/app/models/list.rb
@@ -28,7 +28,7 @@ class List < ActiveRecord::Base
def as_json(options = {})
super(options).tap do |json|
- if options.has_key?(:label)
+ if options.key?(:label)
json[:label] = label.as_json(
project: board.project,
only: [:id, :title, :description, :color]
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index aebee06d560..b48d73dcae7 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -6,6 +6,7 @@ class Namespace < ActiveRecord::Base
include Gitlab::ShellAdapter
include Gitlab::CurrentSettings
include Routable
+ include AfterCommitQueue
# Prevent users from creating unreasonably deep level of nesting.
# The number 20 was taken based on maximum nesting level of
@@ -242,7 +243,9 @@ class Namespace < ActiveRecord::Base
# Remove namespace directroy async with delay so
# GitLab has time to remove all projects first
- GitlabShellWorker.perform_in(5.minutes, :rm_namespace, repository_storage_path, new_path)
+ run_after_commit do
+ GitlabShellWorker.perform_in(5.minutes, :rm_namespace, repository_storage_path, new_path)
+ end
end
end
diff --git a/app/models/note.rb b/app/models/note.rb
index 832c68243fb..563af47f314 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -13,6 +13,7 @@ class Note < ActiveRecord::Base
include AfterCommitQueue
include ResolvableNote
include IgnorableColumn
+ include Editable
ignore_column :original_discussion_id
diff --git a/app/models/project.rb b/app/models/project.rb
index 446329557d5..d21ff274b6e 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -471,7 +471,9 @@ class Project < ActiveRecord::Base
end
def reset_cache_and_import_attrs
- ProjectCacheWorker.perform_async(self.id)
+ run_after_commit do
+ ProjectCacheWorker.perform_async(self.id)
+ end
self.import_data&.destroy
end
@@ -1226,6 +1228,7 @@ class Project < ActiveRecord::Base
{ key: 'CI_PROJECT_ID', value: id.to_s, public: true },
{ key: 'CI_PROJECT_NAME', value: path, public: true },
{ key: 'CI_PROJECT_PATH', value: path_with_namespace, public: true },
+ { key: 'CI_PROJECT_PATH_SLUG', value: path_with_namespace.parameterize, public: true },
{ key: 'CI_PROJECT_NAMESPACE', value: namespace.full_path, public: true },
{ key: 'CI_PROJECT_URL', value: web_url, public: true }
]
diff --git a/app/models/project_services/asana_service.rb b/app/models/project_services/asana_service.rb
index 3728f5642e4..9ce2d1153a7 100644
--- a/app/models/project_services/asana_service.rb
+++ b/app/models/project_services/asana_service.rb
@@ -34,7 +34,8 @@ http://app.asana.com/-/account_api'
{
type: 'text',
name: 'api_key',
- placeholder: 'User Personal Access Token. User must have access to task, all comments will be attributed to this user.'
+ placeholder: 'User Personal Access Token. User must have access to task, all comments will be attributed to this user.',
+ required: true
},
{
type: 'text',
diff --git a/app/models/project_services/assembla_service.rb b/app/models/project_services/assembla_service.rb
index aeeff8917bf..ae6af732ed4 100644
--- a/app/models/project_services/assembla_service.rb
+++ b/app/models/project_services/assembla_service.rb
@@ -18,7 +18,7 @@ class AssemblaService < Service
def fields
[
- { type: 'text', name: 'token', placeholder: '' },
+ { type: 'text', name: 'token', placeholder: '', required: true },
{ type: 'text', name: 'subdomain', placeholder: '' }
]
end
diff --git a/app/models/project_services/bamboo_service.rb b/app/models/project_services/bamboo_service.rb
index 3f5b3eb159b..42939ea0ec8 100644
--- a/app/models/project_services/bamboo_service.rb
+++ b/app/models/project_services/bamboo_service.rb
@@ -47,9 +47,9 @@ class BambooService < CiService
def fields
[
{ type: 'text', name: 'bamboo_url',
- placeholder: 'Bamboo root URL like https://bamboo.example.com' },
+ placeholder: 'Bamboo root URL like https://bamboo.example.com', required: true },
{ type: 'text', name: 'build_key',
- placeholder: 'Bamboo build plan key like KEY' },
+ placeholder: 'Bamboo build plan key like KEY', required: true },
{ type: 'text', name: 'username',
placeholder: 'A user with API access, if applicable' },
{ type: 'password', name: 'password' }
diff --git a/app/models/project_services/buildkite_service.rb b/app/models/project_services/buildkite_service.rb
index 5fb95050b83..fc30f6e3365 100644
--- a/app/models/project_services/buildkite_service.rb
+++ b/app/models/project_services/buildkite_service.rb
@@ -58,11 +58,11 @@ class BuildkiteService < CiService
[
{ type: 'text',
name: 'token',
- placeholder: 'Buildkite project GitLab token' },
+ placeholder: 'Buildkite project GitLab token', required: true },
{ type: 'text',
name: 'project_url',
- placeholder: "#{ENDPOINT}/example/project" },
+ placeholder: "#{ENDPOINT}/example/project", required: true },
{ type: 'checkbox',
name: 'enable_ssl_verification',
diff --git a/app/models/project_services/campfire_service.rb b/app/models/project_services/campfire_service.rb
index 0de59af5652..c3f5b310619 100644
--- a/app/models/project_services/campfire_service.rb
+++ b/app/models/project_services/campfire_service.rb
@@ -18,7 +18,7 @@ class CampfireService < Service
def fields
[
- { type: 'text', name: 'token', placeholder: '' },
+ { type: 'text', name: 'token', placeholder: '', required: true },
{ type: 'text', name: 'subdomain', placeholder: '' },
{ type: 'text', name: 'room', placeholder: '' }
]
@@ -76,7 +76,7 @@ class CampfireService < Service
# Returns a list of rooms, or [].
# https://github.com/basecamp/campfire-api/blob/master/sections/rooms.md#get-rooms
def rooms(auth)
- res = self.class.get("/rooms.json", auth)
+ res = self.class.get("/rooms.json", auth)
res.code == 200 ? res["rooms"] : []
end
diff --git a/app/models/project_services/chat_notification_service.rb b/app/models/project_services/chat_notification_service.rb
index 779ef54cfcb..6d1a321f651 100644
--- a/app/models/project_services/chat_notification_service.rb
+++ b/app/models/project_services/chat_notification_service.rb
@@ -21,10 +21,6 @@ class ChatNotificationService < Service
end
end
- def can_test?
- valid?
- end
-
def self.supported_events
%w[push issue confidential_issue merge_request note tag_push
pipeline wiki_page]
@@ -36,7 +32,7 @@ class ChatNotificationService < Service
def default_fields
[
- { type: 'text', name: 'webhook', placeholder: "e.g. #{webhook_placeholder}" },
+ { type: 'text', name: 'webhook', placeholder: "e.g. #{webhook_placeholder}", required: true },
{ type: 'text', name: 'username', placeholder: 'e.g. GitLab' },
{ type: 'checkbox', name: 'notify_only_broken_pipelines' },
{ type: 'checkbox', name: 'notify_only_default_branch' }
diff --git a/app/models/project_services/custom_issue_tracker_service.rb b/app/models/project_services/custom_issue_tracker_service.rb
index dea915a4d05..b9e3e982b64 100644
--- a/app/models/project_services/custom_issue_tracker_service.rb
+++ b/app/models/project_services/custom_issue_tracker_service.rb
@@ -31,9 +31,9 @@ class CustomIssueTrackerService < IssueTrackerService
[
{ type: 'text', name: 'title', placeholder: title },
{ type: 'text', name: 'description', placeholder: description },
- { type: 'text', name: 'project_url', placeholder: 'Project url' },
- { type: 'text', name: 'issues_url', placeholder: 'Issue url' },
- { type: 'text', name: 'new_issue_url', placeholder: 'New Issue url' }
+ { type: 'text', name: 'project_url', placeholder: 'Project url', required: true },
+ { type: 'text', name: 'issues_url', placeholder: 'Issue url', required: true },
+ { type: 'text', name: 'new_issue_url', placeholder: 'New Issue url', required: true }
]
end
end
diff --git a/app/models/project_services/deployment_service.rb b/app/models/project_services/deployment_service.rb
index 91a55514a9a..5b8320158fc 100644
--- a/app/models/project_services/deployment_service.rb
+++ b/app/models/project_services/deployment_service.rb
@@ -30,4 +30,8 @@ class DeploymentService < Service
def terminals(environment)
raise NotImplementedError
end
+
+ def can_test?
+ false
+ end
end
diff --git a/app/models/project_services/drone_ci_service.rb b/app/models/project_services/drone_ci_service.rb
index 2717c240f05..f6cade9c290 100644
--- a/app/models/project_services/drone_ci_service.rb
+++ b/app/models/project_services/drone_ci_service.rb
@@ -93,8 +93,8 @@ class DroneCiService < CiService
def fields
[
- { type: 'text', name: 'token', placeholder: 'Drone CI project specific token' },
- { type: 'text', name: 'drone_url', placeholder: 'http://drone.example.com' },
+ { type: 'text', name: 'token', placeholder: 'Drone CI project specific token', required: true },
+ { type: 'text', name: 'drone_url', placeholder: 'http://drone.example.com', required: true },
{ type: 'checkbox', name: 'enable_ssl_verification', title: "Enable SSL verification" }
]
end
diff --git a/app/models/project_services/external_wiki_service.rb b/app/models/project_services/external_wiki_service.rb
index b4d7c977ce4..720ad61162e 100644
--- a/app/models/project_services/external_wiki_service.rb
+++ b/app/models/project_services/external_wiki_service.rb
@@ -19,7 +19,7 @@ class ExternalWikiService < Service
def fields
[
- { type: 'text', name: 'external_wiki_url', placeholder: 'The URL of the external Wiki' }
+ { type: 'text', name: 'external_wiki_url', placeholder: 'The URL of the external Wiki', required: true }
]
end
diff --git a/app/models/project_services/flowdock_service.rb b/app/models/project_services/flowdock_service.rb
index 2a05d757eb4..2db95b9aaa3 100644
--- a/app/models/project_services/flowdock_service.rb
+++ b/app/models/project_services/flowdock_service.rb
@@ -18,7 +18,7 @@ class FlowdockService < Service
def fields
[
- { type: 'text', name: 'token', placeholder: 'Flowdock Git source token' }
+ { type: 'text', name: 'token', placeholder: 'Flowdock Git source token', required: true }
]
end
diff --git a/app/models/project_services/gemnasium_service.rb b/app/models/project_services/gemnasium_service.rb
index f271e1f1739..017a9b2df6e 100644
--- a/app/models/project_services/gemnasium_service.rb
+++ b/app/models/project_services/gemnasium_service.rb
@@ -18,8 +18,8 @@ class GemnasiumService < Service
def fields
[
- { type: 'text', name: 'api_key', placeholder: 'Your personal API KEY on gemnasium.com ' },
- { type: 'text', name: 'token', placeholder: 'The project\'s slug on gemnasium.com' }
+ { type: 'text', name: 'api_key', placeholder: 'Your personal API KEY on gemnasium.com ', required: true },
+ { type: 'text', name: 'token', placeholder: 'The project\'s slug on gemnasium.com', required: true }
]
end
diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb
index c19fed339ba..e3906943ecd 100644
--- a/app/models/project_services/hipchat_service.rb
+++ b/app/models/project_services/hipchat_service.rb
@@ -33,7 +33,7 @@ class HipchatService < Service
def fields
[
- { type: 'text', name: 'token', placeholder: 'Room token' },
+ { type: 'text', name: 'token', placeholder: 'Room token', required: true },
{ type: 'text', name: 'room', placeholder: 'Room name or ID' },
{ type: 'checkbox', name: 'notify' },
{ type: 'select', name: 'color', choices: %w(yellow red green purple gray random) },
diff --git a/app/models/project_services/irker_service.rb b/app/models/project_services/irker_service.rb
index a51d43adcb9..19357f90810 100644
--- a/app/models/project_services/irker_service.rb
+++ b/app/models/project_services/irker_service.rb
@@ -49,7 +49,7 @@ class IrkerService < Service
help: 'A default IRC URI to prepend before each recipient (optional)',
placeholder: 'irc://irc.network.net:6697/' },
{ type: 'textarea', name: 'recipients',
- placeholder: 'Recipients/channels separated by whitespaces',
+ placeholder: 'Recipients/channels separated by whitespaces', required: true,
help: 'Recipients have to be specified with a full URI: '\
'irc[s]://irc.network.net[:port]/#channel. Special cases: if '\
'you want the channel to be a nickname instead, append ",isnick" to ' \
diff --git a/app/models/project_services/issue_tracker_service.rb b/app/models/project_services/issue_tracker_service.rb
index eddf308eae3..ff138b9066d 100644
--- a/app/models/project_services/issue_tracker_service.rb
+++ b/app/models/project_services/issue_tracker_service.rb
@@ -32,9 +32,9 @@ class IssueTrackerService < Service
def fields
[
{ type: 'text', name: 'description', placeholder: description },
- { type: 'text', name: 'project_url', placeholder: 'Project url' },
- { type: 'text', name: 'issues_url', placeholder: 'Issue url' },
- { type: 'text', name: 'new_issue_url', placeholder: 'New Issue url' }
+ { type: 'text', name: 'project_url', placeholder: 'Project url', required: true },
+ { type: 'text', name: 'issues_url', placeholder: 'Issue url', required: true },
+ { type: 'text', name: 'new_issue_url', placeholder: 'New Issue url', required: true }
]
end
diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb
index 25d098b63c0..2450fb43212 100644
--- a/app/models/project_services/jira_service.rb
+++ b/app/models/project_services/jira_service.rb
@@ -86,11 +86,11 @@ class JiraService < IssueTrackerService
def fields
[
- { type: 'text', name: 'url', title: 'Web URL', placeholder: 'https://jira.example.com' },
+ { type: 'text', name: 'url', title: 'Web URL', placeholder: 'https://jira.example.com', required: true },
{ type: 'text', name: 'api_url', title: 'JIRA API URL', placeholder: 'If different from Web URL' },
- { type: 'text', name: 'project_key', placeholder: 'Project Key' },
- { type: 'text', name: 'username', placeholder: '' },
- { type: 'password', name: 'password', placeholder: '' },
+ { type: 'text', name: 'project_key', placeholder: 'Project Key', required: true },
+ { type: 'text', name: 'username', placeholder: '', required: true },
+ { type: 'password', name: 'password', placeholder: '', required: true },
{ type: 'text', name: 'jira_issue_transition_id', placeholder: '' }
]
end
@@ -175,10 +175,6 @@ class JiraService < IssueTrackerService
{ success: result.present?, result: result }
end
- def can_test?
- username.present? && password.present?
- end
-
# JIRA does not need test data.
# We are requesting the project that belongs to the project key.
def test_data(user = nil, project = nil)
diff --git a/app/models/project_services/mock_ci_service.rb b/app/models/project_services/mock_ci_service.rb
index 546b6e0a498..72ddf9a4be3 100644
--- a/app/models/project_services/mock_ci_service.rb
+++ b/app/models/project_services/mock_ci_service.rb
@@ -21,7 +21,8 @@ class MockCiService < CiService
[
{ type: 'text',
name: 'mock_service_url',
- placeholder: 'http://localhost:4004' }
+ placeholder: 'http://localhost:4004',
+ required: true }
]
end
@@ -79,4 +80,8 @@ class MockCiService < CiService
:error
end
end
+
+ def can_test?
+ false
+ end
end
diff --git a/app/models/project_services/mock_monitoring_service.rb b/app/models/project_services/mock_monitoring_service.rb
index dd04e04e198..ed0318c6b27 100644
--- a/app/models/project_services/mock_monitoring_service.rb
+++ b/app/models/project_services/mock_monitoring_service.rb
@@ -14,4 +14,8 @@ class MockMonitoringService < MonitoringService
def metrics(environment)
JSON.parse(File.read(Rails.root + 'spec/fixtures/metrics.json'))
end
+
+ def can_test?
+ false
+ end
end
diff --git a/app/models/project_services/pipelines_email_service.rb b/app/models/project_services/pipelines_email_service.rb
index f824171ad09..9d37184be2c 100644
--- a/app/models/project_services/pipelines_email_service.rb
+++ b/app/models/project_services/pipelines_email_service.rb
@@ -53,7 +53,8 @@ class PipelinesEmailService < Service
[
{ type: 'textarea',
name: 'recipients',
- placeholder: 'Emails separated by comma' },
+ placeholder: 'Emails separated by comma',
+ required: true },
{ type: 'checkbox',
name: 'notify_only_broken_pipelines' }
]
diff --git a/app/models/project_services/pivotaltracker_service.rb b/app/models/project_services/pivotaltracker_service.rb
index d86f4f6f448..f9dfa2e91c3 100644
--- a/app/models/project_services/pivotaltracker_service.rb
+++ b/app/models/project_services/pivotaltracker_service.rb
@@ -23,7 +23,8 @@ class PivotaltrackerService < Service
{
type: 'text',
name: 'token',
- placeholder: 'Pivotal Tracker API token.'
+ placeholder: 'Pivotal Tracker API token.',
+ required: true
},
{
type: 'text',
diff --git a/app/models/project_services/prometheus_service.rb b/app/models/project_services/prometheus_service.rb
index ec72cb6856d..110b8bc209b 100644
--- a/app/models/project_services/prometheus_service.rb
+++ b/app/models/project_services/prometheus_service.rb
@@ -49,7 +49,8 @@ class PrometheusService < MonitoringService
type: 'text',
name: 'api_url',
title: 'API URL',
- placeholder: 'Prometheus API Base URL, like http://prometheus.example.com/'
+ placeholder: 'Prometheus API Base URL, like http://prometheus.example.com/',
+ required: true
}
]
end
diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb
index fc29a5277bb..aa7bd4c3c84 100644
--- a/app/models/project_services/pushover_service.rb
+++ b/app/models/project_services/pushover_service.rb
@@ -19,10 +19,10 @@ class PushoverService < Service
def fields
[
- { type: 'text', name: 'api_key', placeholder: 'Your application key' },
- { type: 'text', name: 'user_key', placeholder: 'Your user key' },
+ { type: 'text', name: 'api_key', placeholder: 'Your application key', required: true },
+ { type: 'text', name: 'user_key', placeholder: 'Your user key', required: true },
{ type: 'text', name: 'device', placeholder: 'Leave blank for all active devices' },
- { type: 'select', name: 'priority', choices:
+ { type: 'select', name: 'priority', required: true, choices:
[
['Lowest Priority', -2],
['Low Priority', -1],
diff --git a/app/models/project_services/teamcity_service.rb b/app/models/project_services/teamcity_service.rb
index b16beb406b9..cbe137452bd 100644
--- a/app/models/project_services/teamcity_service.rb
+++ b/app/models/project_services/teamcity_service.rb
@@ -50,9 +50,9 @@ class TeamcityService < CiService
def fields
[
{ type: 'text', name: 'teamcity_url',
- placeholder: 'TeamCity root URL like https://teamcity.example.com' },
+ placeholder: 'TeamCity root URL like https://teamcity.example.com', required: true },
{ type: 'text', name: 'build_type',
- placeholder: 'Build configuration ID' },
+ placeholder: 'Build configuration ID', required: true },
{ type: 'text', name: 'username',
placeholder: 'A user with permissions to trigger a manual build' },
{ type: 'password', name: 'password' }
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index 882e2fa0594..6c3358685fe 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -8,6 +8,7 @@ class Snippet < ActiveRecord::Base
include Awardable
include Mentionable
include Spammable
+ include Editable
cache_markdown_field :title, pipeline: :single_line
cache_markdown_field :content
diff --git a/app/models/user.rb b/app/models/user.rb
index 32048da6c6f..e6eb9d09656 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -101,6 +101,7 @@ class User < ActiveRecord::Base
has_many :snippets, dependent: :destroy, foreign_key: :author_id
has_many :notes, dependent: :destroy, foreign_key: :author_id
+ has_many :issues, dependent: :destroy, foreign_key: :author_id
has_many :merge_requests, dependent: :destroy, foreign_key: :author_id
has_many :events, dependent: :destroy, foreign_key: :author_id
has_many :subscriptions, dependent: :destroy
@@ -120,11 +121,6 @@ class User < ActiveRecord::Base
has_many :assigned_issues, class_name: "Issue", through: :issue_assignees, source: :issue
has_many :assigned_merge_requests, dependent: :nullify, foreign_key: :assignee_id, class_name: "MergeRequest"
- # Issues that a user owns are expected to be moved to the "ghost" user before
- # the user is destroyed. If the user owns any issues during deletion, this
- # should be treated as an exceptional condition.
- has_many :issues, dependent: :restrict_with_exception, foreign_key: :author_id
-
#
# Validations
#