summaryrefslogtreecommitdiff
path: root/app/models
diff options
context:
space:
mode:
Diffstat (limited to 'app/models')
-rw-r--r--app/models/ability.rb29
-rw-r--r--app/models/abuse_report.rb12
-rw-r--r--app/models/application_setting.rb48
-rw-r--r--app/models/audit_event.rb14
-rw-r--r--app/models/blob.rb8
-rw-r--r--app/models/broadcast_message.rb14
-rw-r--r--app/models/ci/build.rb100
-rw-r--r--app/models/ci/commit.rb160
-rw-r--r--app/models/ci/runner.rb19
-rw-r--r--app/models/ci/runner_project.rb12
-rw-r--r--app/models/ci/trigger.rb13
-rw-r--r--app/models/ci/trigger_request.rb12
-rw-r--r--app/models/ci/variable.rb14
-rw-r--r--app/models/commit.rb19
-rw-r--r--app/models/commit_status.rb90
-rw-r--r--app/models/concerns/internal_id.rb10
-rw-r--r--app/models/concerns/issuable.rb6
-rw-r--r--app/models/concerns/mentionable.rb4
-rw-r--r--app/models/concerns/milestoneish.rb2
-rw-r--r--app/models/concerns/statuseable.rb81
-rw-r--r--app/models/deploy_key.rb15
-rw-r--r--app/models/deploy_keys_project.rb11
-rw-r--r--app/models/email.rb11
-rw-r--r--app/models/event.rb18
-rw-r--r--app/models/external_issue.rb6
-rw-r--r--app/models/forked_project_link.rb11
-rw-r--r--app/models/generic_commit_status.rb34
-rw-r--r--app/models/group.rb17
-rw-r--r--app/models/hooks/project_hook.rb23
-rw-r--r--app/models/hooks/service_hook.rb20
-rw-r--r--app/models/hooks/system_hook.rb23
-rw-r--r--app/models/hooks/web_hook.rb46
-rw-r--r--app/models/identity.rb12
-rw-r--r--app/models/issue.rb67
-rw-r--r--app/models/key.rb15
-rw-r--r--app/models/label.rb22
-rw-r--r--app/models/label_link.rb12
-rw-r--r--app/models/lfs_object.rb12
-rw-r--r--app/models/lfs_objects_project.rb11
-rw-r--r--app/models/member.rb19
-rw-r--r--app/models/members/group_member.rb19
-rw-r--r--app/models/members/project_member.rb19
-rw-r--r--app/models/merge_request.rb38
-rw-r--r--app/models/merge_request_diff.rb15
-rw-r--r--app/models/milestone.rb19
-rw-r--r--app/models/namespace.rb15
-rw-r--r--app/models/note.rb23
-rw-r--r--app/models/oauth_access_token.rb15
-rw-r--r--app/models/personal_snippet.rb16
-rw-r--r--app/models/project.rb104
-rw-r--r--app/models/project_import_data.rb10
-rw-r--r--app/models/project_services/asana_service.rb21
-rw-r--r--app/models/project_services/assembla_service.rb21
-rw-r--r--app/models/project_services/bamboo_service.rb21
-rw-r--r--app/models/project_services/buildkite_service.rb25
-rw-r--r--app/models/project_services/builds_email_service.rb21
-rw-r--r--app/models/project_services/campfire_service.rb21
-rw-r--r--app/models/project_services/ci_service.rb21
-rw-r--r--app/models/project_services/custom_issue_tracker_service.rb21
-rw-r--r--app/models/project_services/drone_ci_service.rb21
-rw-r--r--app/models/project_services/emails_on_push_service.rb21
-rw-r--r--app/models/project_services/external_wiki_service.rb21
-rw-r--r--app/models/project_services/flowdock_service.rb21
-rw-r--r--app/models/project_services/gemnasium_service.rb21
-rw-r--r--app/models/project_services/gitlab_ci_service.rb21
-rw-r--r--app/models/project_services/gitlab_issue_tracker_service.rb21
-rw-r--r--app/models/project_services/hipchat_service.rb25
-rw-r--r--app/models/project_services/irker_service.rb21
-rw-r--r--app/models/project_services/issue_tracker_service.rb23
-rw-r--r--app/models/project_services/jira_service.rb23
-rw-r--r--app/models/project_services/pivotaltracker_service.rb21
-rw-r--r--app/models/project_services/pushover_service.rb21
-rw-r--r--app/models/project_services/redmine_service.rb21
-rw-r--r--app/models/project_services/slack_service.rb28
-rw-r--r--app/models/project_services/slack_service/merge_message.rb2
-rw-r--r--app/models/project_services/slack_service/note_message.rb2
-rw-r--r--app/models/project_services/slack_service/wiki_page_message.rb53
-rw-r--r--app/models/project_services/teamcity_service.rb21
-rw-r--r--app/models/project_snippet.rb18
-rw-r--r--app/models/protected_branch.rb12
-rw-r--r--app/models/release.rb12
-rw-r--r--app/models/repository.rb124
-rw-r--r--app/models/security_event.rb14
-rw-r--r--app/models/sent_notification.rb14
-rw-r--r--app/models/service.rb25
-rw-r--r--app/models/snippet.rb20
-rw-r--r--app/models/subscription.rb13
-rw-r--r--app/models/todo.rb18
-rw-r--r--app/models/user.rb67
-rw-r--r--app/models/users_star_project.rb11
-rw-r--r--app/models/wiki_page.rb4
91 files changed, 552 insertions, 1745 deletions
diff --git a/app/models/ability.rb b/app/models/ability.rb
index c0bf6def7c5..6103a2947e2 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -18,6 +18,7 @@ class Ability
when Namespace then namespace_abilities(user, subject)
when GroupMember then group_member_abilities(user, subject)
when ProjectMember then project_member_abilities(user, subject)
+ when User then user_abilities
else []
end.concat(global_abilities(user))
end
@@ -35,6 +36,8 @@ class Ability
anonymous_project_abilities(subject)
when subject.is_a?(Group) || subject.respond_to?(:group)
anonymous_group_abilities(subject)
+ when subject.is_a?(User)
+ anonymous_user_abilities
else
[]
end
@@ -81,17 +84,17 @@ class Ability
end
def anonymous_group_abilities(subject)
+ rules = []
+
group = if subject.is_a?(Group)
subject
else
subject.group
end
- if group && group.public?
- [:read_group]
- else
- []
- end
+ rules << :read_group if group.public?
+
+ rules
end
def anonymous_personal_snippet_abilities(snippet)
@@ -110,9 +113,14 @@ class Ability
end
end
+ def anonymous_user_abilities
+ [:read_user] unless restricted_public_level?
+ end
+
def global_abilities(user)
rules = []
rules << :create_group if user.can_create_group
+ rules << :read_users_list
rules
end
@@ -163,7 +171,7 @@ class Ability
@public_project_rules ||= project_guest_rules + [
:download_code,
:fork_project,
- :read_commit_status,
+ :read_commit_status
]
end
@@ -284,7 +292,6 @@ class Ability
def group_abilities(user, group)
rules = []
-
rules << :read_group if can_read_group?(user, group)
# Only group masters and group owners can create new projects
@@ -456,6 +463,10 @@ class Ability
rules
end
+ def user_abilities
+ [:read_user]
+ end
+
def abilities
@abilities ||= begin
abilities = Six.new
@@ -470,6 +481,10 @@ class Ability
private
+ def restricted_public_level?
+ current_application_settings.restricted_visibility_levels.include?(Gitlab::VisibilityLevel::PUBLIC)
+ end
+
def named_abilities(name)
[
:"read_#{name}",
diff --git a/app/models/abuse_report.rb b/app/models/abuse_report.rb
index b61f5123127..b01a244032d 100644
--- a/app/models/abuse_report.rb
+++ b/app/models/abuse_report.rb
@@ -1,15 +1,3 @@
-# == Schema Information
-#
-# Table name: abuse_reports
-#
-# id :integer not null, primary key
-# reporter_id :integer
-# user_id :integer
-# message :text
-# created_at :datetime
-# updated_at :datetime
-#
-
class AbuseReport < ActiveRecord::Base
belongs_to :reporter, class_name: 'User'
belongs_to :user
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 36f88154232..7039db2d41e 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -1,51 +1,3 @@
-# == Schema Information
-#
-# Table name: application_settings
-#
-# id :integer not null, primary key
-# default_projects_limit :integer
-# signup_enabled :boolean
-# signin_enabled :boolean
-# gravatar_enabled :boolean
-# sign_in_text :text
-# created_at :datetime
-# updated_at :datetime
-# home_page_url :string(255)
-# default_branch_protection :integer default(2)
-# restricted_visibility_levels :text
-# version_check_enabled :boolean default(TRUE)
-# max_attachment_size :integer default(10), not null
-# default_project_visibility :integer
-# default_snippet_visibility :integer
-# default_group_visibility :integer
-# restricted_signup_domains :text
-# user_oauth_applications :boolean default(TRUE)
-# after_sign_out_path :string(255)
-# session_expire_delay :integer default(10080), not null
-# import_sources :text
-# help_page_text :text
-# admin_notification_email :string(255)
-# shared_runners_enabled :boolean default(TRUE), not null
-# max_artifacts_size :integer default(100), not null
-# runners_registration_token :string
-# require_two_factor_authentication :boolean default(FALSE)
-# two_factor_grace_period :integer default(48)
-# metrics_enabled :boolean default(FALSE)
-# metrics_host :string default("localhost")
-# metrics_username :string
-# metrics_password :string
-# metrics_pool_size :integer default(16)
-# metrics_timeout :integer default(10)
-# metrics_method_call_threshold :integer default(10)
-# recaptcha_enabled :boolean default(FALSE)
-# recaptcha_site_key :string
-# recaptcha_private_key :string
-# metrics_port :integer default(8089)
-# sentry_enabled :boolean default(FALSE)
-# sentry_dsn :string
-# email_author_in_body :boolean default(FALSE)
-#
-
class ApplicationSetting < ActiveRecord::Base
include TokenAuthenticatable
add_authentication_token_field :runners_registration_token
diff --git a/app/models/audit_event.rb b/app/models/audit_event.rb
index 0ed0dd98a59..967ffd46db0 100644
--- a/app/models/audit_event.rb
+++ b/app/models/audit_event.rb
@@ -1,17 +1,3 @@
-# == Schema Information
-#
-# Table name: audit_events
-#
-# id :integer not null, primary key
-# author_id :integer not null
-# type :string(255) not null
-# entity_id :integer not null
-# entity_type :string(255) not null
-# details :text
-# created_at :datetime
-# updated_at :datetime
-#
-
class AuditEvent < ActiveRecord::Base
serialize :details, Hash
diff --git a/app/models/blob.rb b/app/models/blob.rb
index 72e6c5fa3fd..0fea6b7f576 100644
--- a/app/models/blob.rb
+++ b/app/models/blob.rb
@@ -19,6 +19,14 @@ class Blob < SimpleDelegator
new(blob)
end
+ def no_highlighting?
+ size && size > 1.megabyte
+ end
+
+ def only_display_raw?
+ size && size > 5.megabytes
+ end
+
def svg?
text? && language && language.name == 'SVG'
end
diff --git a/app/models/broadcast_message.rb b/app/models/broadcast_message.rb
index 8a0a8a4c2a9..61498140f27 100644
--- a/app/models/broadcast_message.rb
+++ b/app/models/broadcast_message.rb
@@ -1,17 +1,3 @@
-# == Schema Information
-#
-# Table name: broadcast_messages
-#
-# id :integer not null, primary key
-# message :text not null
-# starts_at :datetime
-# ends_at :datetime
-# created_at :datetime
-# updated_at :datetime
-# color :string(255)
-# font :string(255)
-#
-
class BroadcastMessage < ActiveRecord::Base
include Sortable
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 7d33838044b..c9506dd3057 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -1,44 +1,5 @@
-# == Schema Information
-#
-# Table name: ci_builds
-#
-# id :integer not null, primary key
-# project_id :integer
-# status :string(255)
-# finished_at :datetime
-# trace :text
-# created_at :datetime
-# updated_at :datetime
-# started_at :datetime
-# runner_id :integer
-# coverage :float
-# commit_id :integer
-# commands :text
-# job_id :integer
-# name :string(255)
-# deploy :boolean default(FALSE)
-# options :text
-# allow_failure :boolean default(FALSE), not null
-# stage :string(255)
-# trigger_request_id :integer
-# stage_idx :integer
-# tag :boolean
-# ref :string(255)
-# user_id :integer
-# type :string(255)
-# target_url :string(255)
-# description :string(255)
-# artifacts_file :text
-# gl_project_id :integer
-# artifacts_metadata :text
-# erased_by_id :integer
-# erased_at :datetime
-#
-
module Ci
class Build < CommitStatus
- LAZY_ATTRIBUTES = ['trace']
-
belongs_to :runner, class_name: 'Ci::Runner'
belongs_to :trigger_request, class_name: 'Ci::TriggerRequest'
belongs_to :erased_by, class_name: 'User'
@@ -50,25 +11,17 @@ module Ci
scope :unstarted, ->() { where(runner_id: nil) }
scope :ignore_failures, ->() { where(allow_failure: false) }
- scope :similar, ->(build) { where(ref: build.ref, tag: build.tag, trigger_request_id: build.trigger_request_id) }
mount_uploader :artifacts_file, ArtifactUploader
mount_uploader :artifacts_metadata, ArtifactUploader
acts_as_taggable
- # To prevent db load megabytes of data from trace
- default_scope -> { select(Ci::Build.columns_without_lazy) }
-
before_destroy { project }
- class << self
- def columns_without_lazy
- (column_names - LAZY_ATTRIBUTES).map do |column_name|
- "#{table_name}.#{column_name}"
- end
- end
+ after_create :execute_hooks
+ class << self
def last_month
where('created_at > ?', Date.today - 1.month)
end
@@ -126,12 +79,16 @@ module Ci
end
def retried?
- !self.commit.latest_statuses_for_ref(self.ref).include?(self)
+ !self.commit.statuses.latest.include?(self)
+ end
+
+ def retry
+ Ci::Build.retry(self)
end
def depends_on_builds
# Get builds of the same type
- latest_builds = self.commit.builds.similar(self).latest
+ latest_builds = self.commit.builds.latest
# Return builds from previous stages
latest_builds.where('stage_idx < ?', stage_idx)
@@ -230,12 +187,33 @@ module Ci
end
end
+ def trace_length
+ if raw_trace
+ raw_trace.length
+ else
+ 0
+ end
+ end
+
def trace=(trace)
+ recreate_trace_dir
+ File.write(path_to_trace, trace)
+ end
+
+ def recreate_trace_dir
unless Dir.exists?(dir_to_trace)
FileUtils.mkdir_p(dir_to_trace)
end
+ end
+ private :recreate_trace_dir
- File.write(path_to_trace, trace)
+ def append_trace(trace_part, offset)
+ recreate_trace_dir
+
+ File.truncate(path_to_trace, offset) if File.exist?(path_to_trace)
+ File.open(path_to_trace, 'a') do |f|
+ f.write(trace_part)
+ end
end
def dir_to_trace
@@ -365,11 +343,23 @@ module Ci
self.update(erased_by: user, erased_at: Time.now)
end
- private
-
def yaml_variables
+ global_yaml_variables + job_yaml_variables
+ end
+
+ def global_yaml_variables
+ if commit.config_processor
+ commit.config_processor.global_variables.map do |key, value|
+ { key: key, value: value, public: true }
+ end
+ else
+ []
+ end
+ end
+
+ def job_yaml_variables
if commit.config_processor
- commit.config_processor.variables.map do |key, value|
+ commit.config_processor.job_variables(name).map do |key, value|
{ key: key, value: value, public: true }
end
else
diff --git a/app/models/ci/commit.rb b/app/models/ci/commit.rb
index f4cf7034b14..f4b61c75ab6 100644
--- a/app/models/ci/commit.rb
+++ b/app/models/ci/commit.rb
@@ -1,39 +1,28 @@
-# == Schema Information
-#
-# Table name: ci_commits
-#
-# id :integer not null, primary key
-# project_id :integer
-# ref :string(255)
-# sha :string(255)
-# before_sha :string(255)
-# push_data :text
-# created_at :datetime
-# updated_at :datetime
-# tag :boolean default(FALSE)
-# yaml_errors :text
-# committed_at :datetime
-# gl_project_id :integer
-#
-
module Ci
class Commit < ActiveRecord::Base
extend Ci::Model
+ include Statuseable
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
has_many :statuses, class_name: 'CommitStatus'
has_many :builds, class_name: 'Ci::Build'
has_many :trigger_requests, dependent: :destroy, class_name: 'Ci::TriggerRequest'
+ delegate :stages, to: :statuses
+
validates_presence_of :sha
+ validates_presence_of :status
validate :valid_commit_sha
+ # Invalidate object and save if when touched
+ after_touch :update_state
+
def self.truncate_sha(sha)
sha[0...8]
end
- def to_param
- sha
+ def self.stages
+ CommitStatus.where(commit: all).stages
end
def project_id
@@ -68,15 +57,20 @@ module Ci
nil
end
- def stage
- running_or_pending = statuses.latest.running_or_pending.ordered
- running_or_pending.first.try(:stage)
+ def branch?
+ !tag?
end
- def create_builds(ref, tag, user, trigger_request = nil)
+ def retryable?
+ builds.latest.any? do |build|
+ build.failed? && build.retryable?
+ end
+ end
+
+ def create_builds(user, trigger_request = nil)
return unless config_processor
config_processor.stages.any? do |stage|
- CreateBuildsService.new.execute(self, stage, ref, tag, user, trigger_request, 'success').present?
+ CreateBuildsService.new(self).execute(stage, user, 'success', trigger_request).present?
end
end
@@ -84,7 +78,7 @@ module Ci
return unless config_processor
# don't create other builds if this one is retried
- latest_builds = builds.similar(build).latest
+ latest_builds = builds.latest
return unless latest_builds.exists?(build.id)
# get list of stages after this build
@@ -92,88 +86,21 @@ module Ci
next_stages.delete(build.stage)
# get status for all prior builds
- prior_builds = latest_builds.reject { |other_build| next_stages.include?(other_build.stage) }
- status = Ci::Status.get_status(prior_builds)
+ prior_builds = latest_builds.where.not(stage: next_stages)
+ prior_status = prior_builds.status
# create builds for next stages based
next_stages.any? do |stage|
- CreateBuildsService.new.execute(self, stage, build.ref, build.tag, build.user, build.trigger_request, status).present?
+ CreateBuildsService.new(self).execute(stage, build.user, prior_status, build.trigger_request).present?
end
end
- def refs
- statuses.order(:ref).pluck(:ref).uniq
- end
-
- def latest_statuses
- @latest_statuses ||= statuses.latest.to_a
- end
-
- def latest_statuses_for_ref(ref)
- latest_statuses.select { |status| status.ref == ref }
- end
-
- def matrix_builds(build = nil)
- matrix_builds = builds.latest.ordered
- matrix_builds = matrix_builds.similar(build) if build
- matrix_builds.to_a
- end
-
def retried
@retried ||= (statuses.order(id: :desc) - statuses.latest)
end
- def status
- if yaml_errors.present?
- return 'failed'
- end
-
- @status ||= Ci::Status.get_status(latest_statuses)
- end
-
- def pending?
- status == 'pending'
- end
-
- def running?
- status == 'running'
- end
-
- def success?
- status == 'success'
- end
-
- def failed?
- status == 'failed'
- end
-
- def canceled?
- status == 'canceled'
- end
-
- def active?
- running? || pending?
- end
-
- def complete?
- canceled? || success? || failed?
- end
-
- def duration
- duration_array = statuses.map(&:duration).compact
- duration_array.reduce(:+).to_i
- end
-
- def started_at
- @started_at ||= statuses.order('started_at ASC').first.try(:started_at)
- end
-
- def finished_at
- @finished_at ||= statuses.order('finished_at DESC').first.try(:finished_at)
- end
-
def coverage
- coverage_array = latest_statuses.map(&:coverage).compact
+ coverage_array = statuses.latest.map(&:coverage).compact
if coverage_array.size >= 1
'%.2f' % (coverage_array.reduce(:+) / coverage_array.size)
end
@@ -181,23 +108,29 @@ module Ci
def config_processor
return nil unless ci_yaml_file
- @config_processor ||= Ci::GitlabCiYamlProcessor.new(ci_yaml_file, project.path_with_namespace)
- rescue Ci::GitlabCiYamlProcessor::ValidationError, Psych::SyntaxError => e
- save_yaml_error(e.message)
- nil
- rescue
- save_yaml_error("Undefined error")
- nil
+ return @config_processor if defined?(@config_processor)
+
+ @config_processor ||= begin
+ Ci::GitlabCiYamlProcessor.new(ci_yaml_file, project.path_with_namespace)
+ rescue Ci::GitlabCiYamlProcessor::ValidationError, Psych::SyntaxError => e
+ save_yaml_error(e.message)
+ nil
+ rescue
+ save_yaml_error("Undefined error")
+ nil
+ end
end
def ci_yaml_file
+ return @ci_yaml_file if defined?(@ci_yaml_file)
+
@ci_yaml_file ||= begin
blob = project.repository.blob_at(sha, '.gitlab-ci.yml')
blob.load_all_data!(project.repository)
blob.data
+ rescue
+ nil
end
- rescue
- nil
end
def skip_ci?
@@ -206,10 +139,23 @@ module Ci
private
+ def update_state
+ statuses.reload
+ self.status = if yaml_errors.blank?
+ statuses.latest.status || 'skipped'
+ else
+ 'failed'
+ end
+ self.started_at = statuses.started_at
+ self.finished_at = statuses.finished_at
+ self.duration = statuses.latest.duration
+ save
+ end
+
def save_yaml_error(error)
return if self.yaml_errors?
self.yaml_errors = error
- save
+ update_state
end
end
end
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 90349a07594..0cdb64d6c33 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -1,22 +1,3 @@
-# == Schema Information
-#
-# Table name: ci_runners
-#
-# id :integer not null, primary key
-# token :string(255)
-# created_at :datetime
-# updated_at :datetime
-# description :string(255)
-# contacted_at :datetime
-# active :boolean default(TRUE), not null
-# is_shared :boolean default(FALSE)
-# name :string(255)
-# version :string(255)
-# revision :string(255)
-# platform :string(255)
-# architecture :string(255)
-#
-
module Ci
class Runner < ActiveRecord::Base
extend Ci::Model
diff --git a/app/models/ci/runner_project.rb b/app/models/ci/runner_project.rb
index 7b16f207a26..4b44ffa886e 100644
--- a/app/models/ci/runner_project.rb
+++ b/app/models/ci/runner_project.rb
@@ -1,15 +1,3 @@
-# == Schema Information
-#
-# Table name: ci_runner_projects
-#
-# id :integer not null, primary key
-# runner_id :integer not null
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# gl_project_id :integer
-#
-
module Ci
class RunnerProject < ActiveRecord::Base
extend Ci::Model
diff --git a/app/models/ci/trigger.rb b/app/models/ci/trigger.rb
index 2b9a457c8ab..a0b19b51a12 100644
--- a/app/models/ci/trigger.rb
+++ b/app/models/ci/trigger.rb
@@ -1,16 +1,3 @@
-# == Schema Information
-#
-# Table name: ci_triggers
-#
-# id :integer not null, primary key
-# token :string(255)
-# project_id :integer
-# deleted_at :datetime
-# created_at :datetime
-# updated_at :datetime
-# gl_project_id :integer
-#
-
module Ci
class Trigger < ActiveRecord::Base
extend Ci::Model
diff --git a/app/models/ci/trigger_request.rb b/app/models/ci/trigger_request.rb
index 9973d2e5ade..872d5fb31de 100644
--- a/app/models/ci/trigger_request.rb
+++ b/app/models/ci/trigger_request.rb
@@ -1,15 +1,3 @@
-# == Schema Information
-#
-# Table name: ci_trigger_requests
-#
-# id :integer not null, primary key
-# trigger_id :integer not null
-# variables :text
-# created_at :datetime
-# updated_at :datetime
-# commit_id :integer
-#
-
module Ci
class TriggerRequest < ActiveRecord::Base
extend Ci::Model
diff --git a/app/models/ci/variable.rb b/app/models/ci/variable.rb
index e786bd7dd93..10802f64813 100644
--- a/app/models/ci/variable.rb
+++ b/app/models/ci/variable.rb
@@ -1,17 +1,3 @@
-# == Schema Information
-#
-# Table name: ci_variables
-#
-# id :integer not null, primary key
-# project_id :integer
-# key :string(255)
-# value :text
-# encrypted_value :text
-# encrypted_value_salt :string(255)
-# encrypted_value_iv :string(255)
-# gl_project_id :integer
-#
-
module Ci
class Variable < ActiveRecord::Base
extend Ci::Model
diff --git a/app/models/commit.rb b/app/models/commit.rb
index d1f07ccd55c..562c3ed15b2 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -15,8 +15,8 @@ class Commit
DIFF_SAFE_LINES = Gitlab::Git::DiffCollection::DEFAULT_LIMITS[:max_lines]
# Commits above this size will not be rendered in HTML
- DIFF_HARD_LIMIT_FILES = 1000 unless defined?(DIFF_HARD_LIMIT_FILES)
- DIFF_HARD_LIMIT_LINES = 50000 unless defined?(DIFF_HARD_LIMIT_LINES)
+ DIFF_HARD_LIMIT_FILES = 1000
+ DIFF_HARD_LIMIT_LINES = 50000
class << self
def decorate(commits, project)
@@ -207,17 +207,22 @@ class Commit
@raw.short_id(7)
end
- def ci_commit
- project.ci_commit(sha)
+ def ci_commits
+ @ci_commits ||= project.ci_commits.where(sha: sha)
end
def status
- ci_commit.try(:status) || :not_found
+ return @status if defined?(@status)
+ @status ||= ci_commits.status
end
def revert_branch_name
"revert-#{short_id}"
end
+
+ def cherry_pick_branch_name
+ project.repository.next_branch("cherry-pick-#{short_id}", mild: true)
+ end
def revert_description
if merged_merge_request
@@ -253,6 +258,10 @@ class Commit
end.any? { |commit_ref| commit_ref.reverts_commit?(self) }
end
+ def change_type_title
+ merged_merge_request ? 'merge request' : 'commit'
+ end
+
private
def repo_changes
diff --git a/app/models/commit_status.rb b/app/models/commit_status.rb
index 3377a85a55a..cacbc13b391 100644
--- a/app/models/commit_status.rb
+++ b/app/models/commit_status.rb
@@ -1,62 +1,21 @@
-# == Schema Information
-#
-# Table name: ci_builds
-#
-# id :integer not null, primary key
-# project_id :integer
-# status :string(255)
-# finished_at :datetime
-# trace :text
-# created_at :datetime
-# updated_at :datetime
-# started_at :datetime
-# runner_id :integer
-# coverage :float
-# commit_id :integer
-# commands :text
-# job_id :integer
-# name :string(255)
-# deploy :boolean default(FALSE)
-# options :text
-# allow_failure :boolean default(FALSE), not null
-# stage :string(255)
-# trigger_request_id :integer
-# stage_idx :integer
-# tag :boolean
-# ref :string(255)
-# user_id :integer
-# type :string(255)
-# target_url :string(255)
-# description :string(255)
-# artifacts_file :text
-# gl_project_id :integer
-#
-
class CommitStatus < ActiveRecord::Base
+ include Statuseable
+
self.table_name = 'ci_builds'
belongs_to :project, class_name: '::Project', foreign_key: :gl_project_id
- belongs_to :commit, class_name: 'Ci::Commit'
+ belongs_to :commit, class_name: 'Ci::Commit', touch: true
belongs_to :user
validates :commit, presence: true
- validates :status, inclusion: { in: %w(pending running failed success canceled) }
validates_presence_of :name
alias_attribute :author, :user
- scope :running, -> { where(status: 'running') }
- scope :pending, -> { where(status: 'pending') }
- scope :success, -> { where(status: 'success') }
- scope :failed, -> { where(status: 'failed') }
- scope :running_or_pending, -> { where(status: [:running, :pending]) }
- scope :finished, -> { where(status: [:success, :failed, :canceled]) }
- scope :latest, -> { where(id: unscope(:select).select('max(id)').group(:name, :ref)) }
+ scope :latest, -> { where(id: unscope(:select).select('max(id)').group(:name, :commit_id)) }
scope :ordered, -> { order(:ref, :stage_idx, :name) }
- scope :for_ref, ->(ref) { where(ref: ref) }
-
- AVAILABLE_STATUSES = ['pending', 'running', 'success', 'failed', 'canceled']
+ scope :ignored, -> { where(allow_failure: true, status: [:failed, :canceled]) }
state_machine :status, initial: :pending do
event :run do
@@ -86,31 +45,24 @@ class CommitStatus < ActiveRecord::Base
after_transition [:pending, :running] => :success do |commit_status|
MergeRequests::MergeWhenBuildSucceedsService.new(commit_status.commit.project, nil).trigger(commit_status)
end
-
- state :pending, value: 'pending'
- state :running, value: 'running'
- state :failed, value: 'failed'
- state :success, value: 'success'
- state :canceled, value: 'canceled'
end
- delegate :sha, :short_sha, to: :commit, prefix: false
+ delegate :sha, :short_sha, to: :commit
- # TODO: this should be removed with all references
def before_sha
- Gitlab::Git::BLANK_SHA
+ commit.before_sha || Gitlab::Git::BLANK_SHA
end
- def started?
- !pending? && !canceled? && started_at
+ def self.stages
+ order_by = 'max(stage_idx)'
+ group('stage').order(order_by).pluck(:stage, order_by).map(&:first).compact
end
- def active?
- running? || pending?
- end
-
- def complete?
- canceled? || success? || failed?
+ def self.stages_status
+ all.stages.inject({}) do |h, stage|
+ h[stage] = all.where(stage: stage).status
+ h
+ end
end
def ignored?
@@ -118,11 +70,13 @@ class CommitStatus < ActiveRecord::Base
end
def duration
- if started_at && finished_at
- finished_at - started_at
- elsif started_at
- Time.now - started_at
- end
+ duration =
+ if started_at && finished_at
+ finished_at - started_at
+ elsif started_at
+ Time.now - started_at
+ end
+ duration
end
def stuck?
diff --git a/app/models/concerns/internal_id.rb b/app/models/concerns/internal_id.rb
index 51288094ef1..5382dde6765 100644
--- a/app/models/concerns/internal_id.rb
+++ b/app/models/concerns/internal_id.rb
@@ -7,11 +7,13 @@ module InternalId
end
def set_iid
- records = project.send(self.class.name.tableize)
- records = records.with_deleted if self.paranoid?
- max_iid = records.maximum(:iid)
+ if iid.blank?
+ records = project.send(self.class.name.tableize)
+ records = records.with_deleted if self.paranoid?
+ max_iid = records.maximum(:iid)
- self.iid = max_iid.to_i + 1
+ self.iid = max_iid.to_i + 1
+ end
end
def to_param
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 6af76c97cd3..9b77b88ca80 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -36,14 +36,14 @@ module Issuable
scope :only_opened, -> { with_state(:opened) }
scope :only_reopened, -> { with_state(:reopened) }
scope :closed, -> { with_state(:closed) }
- scope :order_milestone_due_desc, -> { joins(:milestone).reorder('milestones.due_date DESC, milestones.id DESC') }
- scope :order_milestone_due_asc, -> { joins(:milestone).reorder('milestones.due_date ASC, milestones.id ASC') }
- scope :with_label, ->(title) { joins(:labels).where(labels: { title: title }) }
+ scope :order_milestone_due_desc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date DESC, milestones.id DESC') }
+ scope :order_milestone_due_asc, -> { outer_join_milestone.reorder('milestones.due_date IS NULL ASC, milestones.due_date ASC, milestones.id ASC') }
scope :without_label, -> { joins("LEFT OUTER JOIN label_links ON label_links.target_type = '#{name}' AND label_links.target_id = #{table_name}.id").where(label_links: { id: nil }) }
scope :join_project, -> { joins(:project) }
scope :references_project, -> { references(:project) }
scope :non_archived, -> { join_project.where(projects: { archived: false }) }
+ scope :outer_join_milestone, -> { joins("LEFT OUTER JOIN milestones ON milestones.id = #{table_name}.milestone_id") }
delegate :name,
:email,
diff --git a/app/models/concerns/mentionable.rb b/app/models/concerns/mentionable.rb
index 98f71ae8cb0..b381d225485 100644
--- a/app/models/concerns/mentionable.rb
+++ b/app/models/concerns/mentionable.rb
@@ -43,8 +43,8 @@ module Mentionable
self
end
- def all_references(current_user = self.author, text = nil)
- ext = Gitlab::ReferenceExtractor.new(self.project, current_user, self.author)
+ def all_references(current_user = nil, text = nil)
+ ext = Gitlab::ReferenceExtractor.new(self.project, current_user || self.author, self.author)
if text
ext.analyze(text)
diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb
index 5b8e3f654ea..7bcc78247ba 100644
--- a/app/models/concerns/milestoneish.rb
+++ b/app/models/concerns/milestoneish.rb
@@ -8,7 +8,7 @@ module Milestoneish
end
def complete?(user = nil)
- total_items_count(user) == closed_items_count(user)
+ total_items_count(user) > 0 && total_items_count(user) == closed_items_count(user)
end
def percent_complete(user = nil)
diff --git a/app/models/concerns/statuseable.rb b/app/models/concerns/statuseable.rb
new file mode 100644
index 00000000000..3ef91caad47
--- /dev/null
+++ b/app/models/concerns/statuseable.rb
@@ -0,0 +1,81 @@
+module Statuseable
+ extend ActiveSupport::Concern
+
+ AVAILABLE_STATUSES = %w(pending running success failed canceled skipped)
+
+ class_methods do
+ def status_sql
+ builds = all.select('count(*)').to_sql
+ success = all.success.select('count(*)').to_sql
+ ignored = all.ignored.select('count(*)').to_sql if all.respond_to?(:ignored)
+ ignored ||= '0'
+ pending = all.pending.select('count(*)').to_sql
+ running = all.running.select('count(*)').to_sql
+ canceled = all.canceled.select('count(*)').to_sql
+ skipped = all.skipped.select('count(*)').to_sql
+
+ deduce_status = "(CASE
+ WHEN (#{builds})=0 THEN NULL
+ WHEN (#{builds})=(#{success})+(#{ignored}) THEN 'success'
+ WHEN (#{builds})=(#{pending}) THEN 'pending'
+ WHEN (#{builds})=(#{canceled})+(#{success})+(#{ignored}) THEN 'canceled'
+ WHEN (#{builds})=(#{skipped}) THEN 'skipped'
+ WHEN (#{running})+(#{pending})>0 THEN 'running'
+ ELSE 'failed'
+ END)"
+
+ deduce_status
+ end
+
+ def status
+ all.pluck(self.status_sql).first
+ end
+
+ def duration
+ duration_array = all.map(&:duration).compact
+ duration_array.reduce(:+)
+ end
+
+ def started_at
+ all.minimum(:started_at)
+ end
+
+ def finished_at
+ all.maximum(:finished_at)
+ end
+ end
+
+ included do
+ validates :status, inclusion: { in: AVAILABLE_STATUSES }
+
+ state_machine :status, initial: :pending do
+ state :pending, value: 'pending'
+ state :running, value: 'running'
+ state :failed, value: 'failed'
+ state :success, value: 'success'
+ state :canceled, value: 'canceled'
+ state :skipped, value: 'skipped'
+ end
+
+ scope :running, -> { where(status: 'running') }
+ scope :pending, -> { where(status: 'pending') }
+ scope :success, -> { where(status: 'success') }
+ scope :failed, -> { where(status: 'failed') }
+ scope :canceled, -> { where(status: 'canceled') }
+ scope :skipped, -> { where(status: 'skipped') }
+ scope :running_or_pending, -> { where(status: [:running, :pending]) }
+ scope :finished, -> { where(status: [:success, :failed, :canceled]) }
+ end
+
+ def started?
+ !pending? && !canceled? && started_at
+ end
+
+ def active?
+ running? || pending?
+ end
+
+ def complete?
+ canceled? || success? || failed?
+ end
+end
diff --git a/app/models/deploy_key.rb b/app/models/deploy_key.rb
index 9ab663c04ad..2c525d4cd7a 100644
--- a/app/models/deploy_key.rb
+++ b/app/models/deploy_key.rb
@@ -1,18 +1,3 @@
-# == Schema Information
-#
-# Table name: keys
-#
-# id :integer not null, primary key
-# user_id :integer
-# created_at :datetime
-# updated_at :datetime
-# key :text
-# title :string(255)
-# type :string(255)
-# fingerprint :string(255)
-# public :boolean default(FALSE), not null
-#
-
class DeployKey < Key
has_many :deploy_keys_projects, dependent: :destroy
has_many :projects, through: :deploy_keys_projects
diff --git a/app/models/deploy_keys_project.rb b/app/models/deploy_keys_project.rb
index 18db521741f..ae8486bd9ac 100644
--- a/app/models/deploy_keys_project.rb
+++ b/app/models/deploy_keys_project.rb
@@ -1,14 +1,3 @@
-# == Schema Information
-#
-# Table name: deploy_keys_projects
-#
-# id :integer not null, primary key
-# deploy_key_id :integer not null
-# project_id :integer not null
-# created_at :datetime
-# updated_at :datetime
-#
-
class DeployKeysProject < ActiveRecord::Base
belongs_to :project
belongs_to :deploy_key
diff --git a/app/models/email.rb b/app/models/email.rb
index b323d1edd10..32a412ab878 100644
--- a/app/models/email.rb
+++ b/app/models/email.rb
@@ -1,14 +1,3 @@
-# == Schema Information
-#
-# Table name: emails
-#
-# id :integer not null, primary key
-# user_id :integer not null
-# email :string(255) not null
-# created_at :datetime
-# updated_at :datetime
-#
-
class Email < ActiveRecord::Base
include Sortable
diff --git a/app/models/event.rb b/app/models/event.rb
index 12183524b79..17ee48b91a8 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -1,19 +1,3 @@
-# == Schema Information
-#
-# Table name: events
-#
-# id :integer not null, primary key
-# target_type :string(255)
-# target_id :integer
-# title :string(255)
-# data :text
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# action :integer
-# author_id :integer
-#
-
class Event < ActiveRecord::Base
include Sortable
default_scope { where.not(author_id: nil) }
@@ -345,7 +329,7 @@ class Event < ActiveRecord::Base
end
def reset_project_activity
- if project
+ if project && Gitlab::ExclusiveLease.new("project:update_last_activity_at:#{project.id}", timeout: 60).try_obtain
project.update_column(:last_activity_at, self.created_at)
end
end
diff --git a/app/models/external_issue.rb b/app/models/external_issue.rb
index b8585d4e577..b7894c99846 100644
--- a/app/models/external_issue.rb
+++ b/app/models/external_issue.rb
@@ -37,4 +37,10 @@ class ExternalIssue
def to_reference(_from_project = nil)
id
end
+
+ def reference_link_text(from_project = nil)
+ return "##{id}" if /^\d+$/.match(id)
+
+ id
+ end
end
diff --git a/app/models/forked_project_link.rb b/app/models/forked_project_link.rb
index 9b0c6263a96..9803bae0bee 100644
--- a/app/models/forked_project_link.rb
+++ b/app/models/forked_project_link.rb
@@ -1,14 +1,3 @@
-# == Schema Information
-#
-# Table name: forked_project_links
-#
-# id :integer not null, primary key
-# forked_to_project_id :integer not null
-# forked_from_project_id :integer not null
-# created_at :datetime
-# updated_at :datetime
-#
-
class ForkedProjectLink < ActiveRecord::Base
belongs_to :forked_to_project, class_name: Project
belongs_to :forked_from_project, class_name: Project
diff --git a/app/models/generic_commit_status.rb b/app/models/generic_commit_status.rb
index 97f4f03a9a5..fa54e3540d0 100644
--- a/app/models/generic_commit_status.rb
+++ b/app/models/generic_commit_status.rb
@@ -1,37 +1,3 @@
-# == Schema Information
-#
-# Table name: ci_builds
-#
-# id :integer not null, primary key
-# project_id :integer
-# status :string(255)
-# finished_at :datetime
-# trace :text
-# created_at :datetime
-# updated_at :datetime
-# started_at :datetime
-# runner_id :integer
-# coverage :float
-# commit_id :integer
-# commands :text
-# job_id :integer
-# name :string(255)
-# deploy :boolean default(FALSE)
-# options :text
-# allow_failure :boolean default(FALSE), not null
-# stage :string(255)
-# trigger_request_id :integer
-# stage_idx :integer
-# tag :boolean
-# ref :string(255)
-# user_id :integer
-# type :string(255)
-# target_url :string(255)
-# description :string(255)
-# artifacts_file :text
-# gl_project_id :integer
-#
-
class GenericCommitStatus < CommitStatus
before_validation :set_default_values
diff --git a/app/models/group.rb b/app/models/group.rb
index 9a04ac70d35..aec92e335e6 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -1,21 +1,4 @@
-# == Schema Information
-#
-# Table name: namespaces
-#
-# id :integer not null, primary key
-# name :string(255) not null
-# path :string(255) not null
-# owner_id :integer
-# visibility_level :integer default(20), not null
-# created_at :datetime
-# updated_at :datetime
-# type :string(255)
-# description :string(255) default(""), not null
-# avatar :string(255)
-#
-
require 'carrierwave/orm/activerecord'
-require 'file_size_validator'
class Group < Namespace
include Gitlab::ConfigHelper
diff --git a/app/models/hooks/project_hook.rb b/app/models/hooks/project_hook.rb
index fe923fafbe0..ba42a8eeb70 100644
--- a/app/models/hooks/project_hook.rb
+++ b/app/models/hooks/project_hook.rb
@@ -1,30 +1,9 @@
-# == Schema Information
-#
-# Table name: web_hooks
-#
-# id :integer not null, primary key
-# url :string(2000)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# type :string default("ProjectHook")
-# service_id :integer
-# push_events :boolean default(TRUE), not null
-# issues_events :boolean default(FALSE), not null
-# merge_requests_events :boolean default(FALSE), not null
-# tag_push_events :boolean default(FALSE)
-# note_events :boolean default(FALSE), not null
-# enable_ssl_verification :boolean default(TRUE)
-# build_events :boolean default(FALSE), not null
-#
-
class ProjectHook < WebHook
belongs_to :project
- scope :push_hooks, -> { where(push_events: true) }
- scope :tag_push_hooks, -> { where(tag_push_events: true) }
scope :issue_hooks, -> { where(issues_events: true) }
scope :note_hooks, -> { where(note_events: true) }
scope :merge_request_hooks, -> { where(merge_requests_events: true) }
scope :build_hooks, -> { where(build_events: true) }
+ scope :wiki_page_hooks, -> { where(wiki_page_events: true) }
end
diff --git a/app/models/hooks/service_hook.rb b/app/models/hooks/service_hook.rb
index 80962264ba2..eef24052a06 100644
--- a/app/models/hooks/service_hook.rb
+++ b/app/models/hooks/service_hook.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: web_hooks
-#
-# id :integer not null, primary key
-# url :string(2000)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# type :string default("ProjectHook")
-# service_id :integer
-# push_events :boolean default(TRUE), not null
-# issues_events :boolean default(FALSE), not null
-# merge_requests_events :boolean default(FALSE), not null
-# tag_push_events :boolean default(FALSE)
-# note_events :boolean default(FALSE), not null
-# enable_ssl_verification :boolean default(TRUE)
-# build_events :boolean default(FALSE), not null
-#
-
class ServiceHook < WebHook
belongs_to :service
diff --git a/app/models/hooks/system_hook.rb b/app/models/hooks/system_hook.rb
index c147d8762a9..777bad1e724 100644
--- a/app/models/hooks/system_hook.rb
+++ b/app/models/hooks/system_hook.rb
@@ -1,22 +1,5 @@
-# == Schema Information
-#
-# Table name: web_hooks
-#
-# id :integer not null, primary key
-# url :string(2000)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# type :string default("ProjectHook")
-# service_id :integer
-# push_events :boolean default(TRUE), not null
-# issues_events :boolean default(FALSE), not null
-# merge_requests_events :boolean default(FALSE), not null
-# tag_push_events :boolean default(FALSE)
-# note_events :boolean default(FALSE), not null
-# enable_ssl_verification :boolean default(TRUE)
-# build_events :boolean default(FALSE), not null
-#
-
class SystemHook < WebHook
+ def async_execute(data, hook_name)
+ Sidekiq::Client.enqueue(SystemHookWorker, id, data, hook_name)
+ end
end
diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb
index 7a13c3f0a39..fde05f729dc 100644
--- a/app/models/hooks/web_hook.rb
+++ b/app/models/hooks/web_hook.rb
@@ -1,23 +1,3 @@
-# == Schema Information
-#
-# Table name: web_hooks
-#
-# id :integer not null, primary key
-# url :string(2000)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# type :string default("ProjectHook")
-# service_id :integer
-# push_events :boolean default(TRUE), not null
-# issues_events :boolean default(FALSE), not null
-# merge_requests_events :boolean default(FALSE), not null
-# tag_push_events :boolean default(FALSE)
-# note_events :boolean default(FALSE), not null
-# enable_ssl_verification :boolean default(TRUE)
-# build_events :boolean default(FALSE), not null
-#
-
class WebHook < ActiveRecord::Base
include Sortable
include HTTParty
@@ -30,6 +10,9 @@ class WebHook < ActiveRecord::Base
default_value_for :build_events, false
default_value_for :enable_ssl_verification, true
+ scope :push_hooks, -> { where(push_events: true) }
+ scope :tag_push_hooks, -> { where(tag_push_events: true) }
+
# HTTParty timeout
default_timeout Gitlab.config.gitlab.webhook_timeout
@@ -40,23 +23,17 @@ class WebHook < ActiveRecord::Base
if parsed_url.userinfo.blank?
response = WebHook.post(url,
body: data.to_json,
- headers: {
- "Content-Type" => "application/json",
- "X-Gitlab-Event" => hook_name.singularize.titleize
- },
+ headers: build_headers(hook_name),
verify: enable_ssl_verification)
else
- post_url = url.gsub("#{parsed_url.userinfo}@", "")
+ post_url = url.gsub("#{parsed_url.userinfo}@", '')
auth = {
username: CGI.unescape(parsed_url.user),
password: CGI.unescape(parsed_url.password),
}
response = WebHook.post(post_url,
body: data.to_json,
- headers: {
- "Content-Type" => "application/json",
- "X-Gitlab-Event" => hook_name.singularize.titleize
- },
+ headers: build_headers(hook_name),
verify: enable_ssl_verification,
basic_auth: auth)
end
@@ -70,4 +47,15 @@ class WebHook < ActiveRecord::Base
def async_execute(data, hook_name)
Sidekiq::Client.enqueue(ProjectWebHookWorker, id, data, hook_name)
end
+
+ private
+
+ def build_headers(hook_name)
+ headers = {
+ 'Content-Type' => 'application/json',
+ 'X-Gitlab-Event' => hook_name.singularize.titleize
+ }
+ headers['X-Gitlab-Token'] = token if token.present?
+ headers
+ end
end
diff --git a/app/models/identity.rb b/app/models/identity.rb
index e1915b079d4..3bacc450e6e 100644
--- a/app/models/identity.rb
+++ b/app/models/identity.rb
@@ -1,15 +1,3 @@
-# == Schema Information
-#
-# Table name: identities
-#
-# id :integer not null, primary key
-# extern_uid :string(255)
-# provider :string(255)
-# user_id :integer
-# created_at :datetime
-# updated_at :datetime
-#
-
class Identity < ActiveRecord::Base
include Sortable
include CaseSensitivity
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 3f188e04770..2d4a9b9f19a 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -1,26 +1,4 @@
-# == Schema Information
-#
-# Table name: issues
-#
-# id :integer not null, primary key
-# title :string(255)
-# assignee_id :integer
-# author_id :integer
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# position :integer default(0)
-# branch_name :string(255)
-# description :text
-# milestone_id :integer
-# state :string(255)
-# iid :integer
-# updated_by_id :integer
-# moved_to_id :integer
-#
-
require 'carrierwave/orm/activerecord'
-require 'file_size_validator'
class Issue < ActiveRecord::Base
include InternalId
@@ -29,6 +7,13 @@ class Issue < ActiveRecord::Base
include Sortable
include Taskable
+ DueDateStruct = Struct.new(:title, :name).freeze
+ NoDueDate = DueDateStruct.new('No Due Date', '0').freeze
+ AnyDueDate = DueDateStruct.new('Any Due Date', '').freeze
+ Overdue = DueDateStruct.new('Overdue', 'overdue').freeze
+ DueThisWeek = DueDateStruct.new('Due This Week', 'week').freeze
+ DueThisMonth = DueDateStruct.new('Due This Month', 'month').freeze
+
ActsAsTaggableOn.strict_case_match = true
belongs_to :project
@@ -40,6 +25,13 @@ class Issue < ActiveRecord::Base
scope :open_for, ->(user) { opened.assigned_to(user) }
scope :in_projects, ->(project_ids) { where(project_id: project_ids) }
+ scope :without_due_date, -> { where(due_date: nil) }
+ scope :due_before, ->(date) { where('issues.due_date < ?', date) }
+ scope :due_between, ->(from_date, to_date) { where('issues.due_date >= ?', from_date).where('issues.due_date <= ?', to_date) }
+
+ scope :order_due_date_asc, -> { reorder('issues.due_date IS NULL, issues.due_date ASC') }
+ scope :order_due_date_desc, -> { reorder('issues.due_date IS NULL, issues.due_date DESC') }
+
state_machine :state, initial: :opened do
event :close do
transition [:reopened, :opened] => :closed
@@ -83,6 +75,15 @@ class Issue < ActiveRecord::Base
@link_reference_pattern ||= super("issues", /(?<issue>\d+)/)
end
+ def self.sort(method)
+ case method.to_s
+ when 'due_date_asc' then order_due_date_asc
+ when 'due_date_desc' then order_due_date_desc
+ else
+ super
+ end
+ end
+
def to_reference(from_project = nil)
reference = "#{self.class.reference_prefix}#{iid}"
@@ -104,10 +105,16 @@ class Issue < ActiveRecord::Base
end
end
- def related_branches
- project.repository.branch_names.select do |branch|
+ # All branches containing the current issue's ID, except for
+ # those with a merge request open referencing the current issue.
+ def related_branches(current_user)
+ branches_with_iid = project.repository.branch_names.select do |branch|
branch =~ /\A#{iid}-(?!\d+-stable)/i
end
+
+ branches_with_merge_request = self.referenced_merge_requests(current_user).map(&:source_branch)
+
+ branches_with_iid - branches_with_merge_request
end
# Reset issue events cache
@@ -151,13 +158,21 @@ class Issue < ActiveRecord::Base
end
def to_branch_name
- "#{iid}-#{title.parameterize}"
+ if self.confidential?
+ "#{iid}-confidential-issue"
+ else
+ "#{iid}-#{title.parameterize}"
+ end
end
def can_be_worked_on?(current_user)
!self.closed? &&
!self.project.forked? &&
- self.related_branches.empty? &&
+ self.related_branches(current_user).empty? &&
self.closed_by_merge_requests(current_user).empty?
end
+
+ def overdue?
+ due_date.try(:past?) || false
+ end
end
diff --git a/app/models/key.rb b/app/models/key.rb
index 0282ad18139..d52afda67d1 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -1,18 +1,3 @@
-# == Schema Information
-#
-# Table name: keys
-#
-# id :integer not null, primary key
-# user_id :integer
-# created_at :datetime
-# updated_at :datetime
-# key :text
-# title :string(255)
-# type :string(255)
-# fingerprint :string(255)
-# public :boolean default(FALSE), not null
-#
-
require 'digest/md5'
class Key < ActiveRecord::Base
diff --git a/app/models/label.rb b/app/models/label.rb
index 55c01cae762..e5ad11983be 100644
--- a/app/models/label.rb
+++ b/app/models/label.rb
@@ -1,17 +1,3 @@
-# == Schema Information
-#
-# Table name: labels
-#
-# id :integer not null, primary key
-# title :string(255)
-# color :string(255)
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# template :boolean default(FALSE)
-# description :string(255)
-#
-
class Label < ActiveRecord::Base
include Referable
include Subscribable
@@ -113,6 +99,14 @@ class Label < ActiveRecord::Base
template
end
+ def text_color
+ LabelsHelper::text_color_for_bg(self.color)
+ end
+
+ def title=(value)
+ write_attribute(:title, Sanitize.clean(value.to_s)) if value.present?
+ end
+
private
def label_format_reference(format = :id)
diff --git a/app/models/label_link.rb b/app/models/label_link.rb
index b94c9c777af..47bd6eaf35f 100644
--- a/app/models/label_link.rb
+++ b/app/models/label_link.rb
@@ -1,15 +1,3 @@
-# == Schema Information
-#
-# Table name: label_links
-#
-# id :integer not null, primary key
-# label_id :integer
-# target_id :integer
-# target_type :string(255)
-# created_at :datetime
-# updated_at :datetime
-#
-
class LabelLink < ActiveRecord::Base
belongs_to :target, polymorphic: true
belongs_to :label
diff --git a/app/models/lfs_object.rb b/app/models/lfs_object.rb
index 86b1b7e2f99..18657c3e1c8 100644
--- a/app/models/lfs_object.rb
+++ b/app/models/lfs_object.rb
@@ -1,15 +1,3 @@
-# == Schema Information
-#
-# Table name: lfs_objects
-#
-# id :integer not null, primary key
-# oid :string(255) not null
-# size :integer not null
-# created_at :datetime
-# updated_at :datetime
-# file :string(255)
-#
-
class LfsObject < ActiveRecord::Base
has_many :lfs_objects_projects, dependent: :destroy
has_many :projects, through: :lfs_objects_projects
diff --git a/app/models/lfs_objects_project.rb b/app/models/lfs_objects_project.rb
index 890736bfc80..0fd5f089db9 100644
--- a/app/models/lfs_objects_project.rb
+++ b/app/models/lfs_objects_project.rb
@@ -1,14 +1,3 @@
-# == Schema Information
-#
-# Table name: lfs_objects_projects
-#
-# id :integer not null, primary key
-# lfs_object_id :integer not null
-# project_id :integer not null
-# created_at :datetime
-# updated_at :datetime
-#
-
class LfsObjectsProject < ActiveRecord::Base
belongs_to :project
belongs_to :lfs_object
diff --git a/app/models/member.rb b/app/models/member.rb
index 60efafef211..d3060f07fc0 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -1,22 +1,3 @@
-# == Schema Information
-#
-# Table name: members
-#
-# id :integer not null, primary key
-# access_level :integer not null
-# source_id :integer not null
-# source_type :string(255) not null
-# user_id :integer
-# notification_level :integer not null
-# type :string(255)
-# created_at :datetime
-# updated_at :datetime
-# created_by_id :integer
-# invite_email :string(255)
-# invite_token :string(255)
-# invite_accepted_at :datetime
-#
-
class Member < ActiveRecord::Base
include Sortable
include Gitlab::Access
diff --git a/app/models/members/group_member.rb b/app/models/members/group_member.rb
index 9fb474a1a93..f63a0debf1a 100644
--- a/app/models/members/group_member.rb
+++ b/app/models/members/group_member.rb
@@ -1,22 +1,3 @@
-# == Schema Information
-#
-# Table name: members
-#
-# id :integer not null, primary key
-# access_level :integer not null
-# source_id :integer not null
-# source_type :string(255) not null
-# user_id :integer
-# notification_level :integer not null
-# type :string(255)
-# created_at :datetime
-# updated_at :datetime
-# created_by_id :integer
-# invite_email :string(255)
-# invite_token :string(255)
-# invite_accepted_at :datetime
-#
-
class GroupMember < Member
SOURCE_TYPE = 'Namespace'
diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb
index 07ddb02ae9d..8dae3bb2ef2 100644
--- a/app/models/members/project_member.rb
+++ b/app/models/members/project_member.rb
@@ -1,22 +1,3 @@
-# == Schema Information
-#
-# Table name: members
-#
-# id :integer not null, primary key
-# access_level :integer not null
-# source_id :integer not null
-# source_type :string(255) not null
-# user_id :integer
-# notification_level :integer not null
-# type :string(255)
-# created_at :datetime
-# updated_at :datetime
-# created_by_id :integer
-# invite_email :string(255)
-# invite_token :string(255)
-# invite_accepted_at :datetime
-#
-
class ProjectMember < Member
SOURCE_TYPE = 'Project'
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index e410febdfff..5460935366c 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -1,35 +1,3 @@
-# == Schema Information
-#
-# Table name: merge_requests
-#
-# id :integer not null, primary key
-# target_branch :string(255) not null
-# source_branch :string(255) not null
-# source_project_id :integer not null
-# author_id :integer
-# assignee_id :integer
-# title :string(255)
-# created_at :datetime
-# updated_at :datetime
-# milestone_id :integer
-# state :string(255)
-# merge_status :string(255)
-# target_project_id :integer not null
-# iid :integer
-# description :text
-# position :integer default(0)
-# locked_at :datetime
-# updated_by_id :integer
-# merge_error :string(255)
-# merge_params :text
-# merge_when_build_succeeds :boolean default(FALSE), not null
-# merge_user_id :integer
-# merge_commit_sha :string
-#
-
-require Rails.root.join("app/models/commit")
-require Rails.root.join("lib/static_model")
-
class MergeRequest < ActiveRecord::Base
include InternalId
include Issuable
@@ -589,7 +557,7 @@ class MergeRequest < ActiveRecord::Base
end
def ci_commit
- @ci_commit ||= source_project.ci_commit(last_commit.id) if last_commit && source_project
+ @ci_commit ||= source_project.ci_commit(last_commit.id, source_branch) if last_commit && source_project
end
def diff_refs
@@ -605,4 +573,8 @@ class MergeRequest < ActiveRecord::Base
def can_be_reverted?(current_user = nil)
merge_commit && !merge_commit.has_been_reverted?(current_user, self)
end
+
+ def can_be_cherry_picked?
+ merge_commit
+ end
end
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index 33884118595..eb42c07b9b9 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -1,18 +1,3 @@
-# == Schema Information
-#
-# Table name: merge_request_diffs
-#
-# id :integer not null, primary key
-# state :string(255)
-# st_commits :text
-# st_diffs :text
-# merge_request_id :integer not null
-# created_at :datetime
-# updated_at :datetime
-#
-
-require Rails.root.join("app/models/commit")
-
class MergeRequestDiff < ActiveRecord::Base
include Sortable
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index 986184dd301..e4fdd23badb 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -1,18 +1,3 @@
-# == Schema Information
-#
-# Table name: milestones
-#
-# id :integer not null, primary key
-# title :string(255) not null
-# project_id :integer not null
-# description :text
-# due_date :date
-# created_at :datetime
-# updated_at :datetime
-# state :string(255)
-# iid :integer
-#
-
class Milestone < ActiveRecord::Base
# Represents a "No Milestone" state used for filtering Issues and Merge
# Requests that have no milestone assigned.
@@ -129,6 +114,10 @@ class Milestone < ActiveRecord::Base
nil
end
+ def title=(value)
+ write_attribute(:title, Sanitize.clean(value.to_s)) if value.present?
+ end
+
# Sorts the issues for the given IDs.
#
# This method runs a single SQL query using a CASE statement to update the
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 55842df1e2d..9c942a8f4e3 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -1,18 +1,3 @@
-# == Schema Information
-#
-# Table name: namespaces
-#
-# id :integer not null, primary key
-# name :string(255) not null
-# path :string(255) not null
-# owner_id :integer
-# created_at :datetime
-# updated_at :datetime
-# type :string(255)
-# description :string(255) default(""), not null
-# avatar :string(255)
-#
-
class Namespace < ActiveRecord::Base
include Sortable
include Gitlab::ShellAdapter
diff --git a/app/models/note.rb b/app/models/note.rb
index b992b2e76f0..0b038edb47b 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -1,25 +1,4 @@
-# == Schema Information
-#
-# Table name: notes
-#
-# id :integer not null, primary key
-# note :text
-# noteable_type :string(255)
-# author_id :integer
-# created_at :datetime
-# updated_at :datetime
-# project_id :integer
-# attachment :string(255)
-# line_code :string(255)
-# commit_id :string(255)
-# noteable_id :integer
-# system :boolean default(FALSE), not null
-# st_diff :text
-# updated_by_id :integer
-#
-
require 'carrierwave/orm/activerecord'
-require 'file_size_validator'
class Note < ActiveRecord::Base
include Gitlab::CurrentSettings
@@ -345,7 +324,7 @@ class Note < ActiveRecord::Base
end
def create_award_emoji
- self.noteable.award_emoji(award_emoji_name, author)
+ self.noteable.award_emoji(award_emoji_name, author)
end
def clear_blank_line_code!
diff --git a/app/models/oauth_access_token.rb b/app/models/oauth_access_token.rb
index c78c7f4aa0e..116fb71ac08 100644
--- a/app/models/oauth_access_token.rb
+++ b/app/models/oauth_access_token.rb
@@ -1,18 +1,3 @@
-# == Schema Information
-#
-# Table name: oauth_access_tokens
-#
-# id :integer not null, primary key
-# resource_owner_id :integer
-# application_id :integer
-# token :string not null
-# refresh_token :string
-# expires_in :integer
-# revoked_at :datetime
-# created_at :datetime not null
-# scopes :string
-#
-
class OauthAccessToken < ActiveRecord::Base
belongs_to :resource_owner, class_name: 'User'
belongs_to :application, class_name: 'Doorkeeper::Application'
diff --git a/app/models/personal_snippet.rb b/app/models/personal_snippet.rb
index 452f3913eef..82c1c4de3a0 100644
--- a/app/models/personal_snippet.rb
+++ b/app/models/personal_snippet.rb
@@ -1,18 +1,2 @@
-# == Schema Information
-#
-# Table name: snippets
-#
-# id :integer not null, primary key
-# title :string(255)
-# content :text
-# author_id :integer not null
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# file_name :string(255)
-# type :string(255)
-# visibility_level :integer default(0), not null
-#
-
class PersonalSnippet < Snippet
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 8f20922e3c5..418b85e028a 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1,46 +1,4 @@
-# == Schema Information
-#
-# Table name: projects
-#
-# id :integer not null, primary key
-# name :string(255)
-# path :string(255)
-# description :text
-# created_at :datetime
-# updated_at :datetime
-# creator_id :integer
-# issues_enabled :boolean default(TRUE), not null
-# wall_enabled :boolean default(TRUE), not null
-# merge_requests_enabled :boolean default(TRUE), not null
-# wiki_enabled :boolean default(TRUE), not null
-# namespace_id :integer
-# issues_tracker :string(255) default("gitlab"), not null
-# issues_tracker_id :string(255)
-# snippets_enabled :boolean default(TRUE), not null
-# last_activity_at :datetime
-# import_url :string(255)
-# visibility_level :integer default(0), not null
-# archived :boolean default(FALSE), not null
-# avatar :string(255)
-# import_status :string(255)
-# repository_size :float default(0.0)
-# star_count :integer default(0), not null
-# import_type :string(255)
-# import_source :string(255)
-# commit_count :integer default(0)
-# import_error :text
-# ci_id :integer
-# builds_enabled :boolean default(TRUE), not null
-# shared_runners_enabled :boolean default(TRUE), not null
-# runners_token :string
-# build_coverage_regex :string
-# build_allow_git_fetch :boolean default(TRUE), not null
-# build_timeout :integer default(3600), not null
-# pending_delete :boolean
-#
-
require 'carrierwave/orm/activerecord'
-require 'file_size_validator'
class Project < ActiveRecord::Base
include Gitlab::ConfigHelper
@@ -63,7 +21,6 @@ class Project < ActiveRecord::Base
default_value_for :merge_requests_enabled, gitlab_config_features.merge_requests
default_value_for :builds_enabled, gitlab_config_features.builds
default_value_for :wiki_enabled, gitlab_config_features.wiki
- default_value_for :wall_enabled, false
default_value_for :snippets_enabled, gitlab_config_features.snippets
default_value_for(:shared_runners_enabled) { current_application_settings.shared_runners_enabled }
@@ -736,19 +693,17 @@ class Project < ActiveRecord::Base
end
def open_branches
- all_branches = repository.branches
+ # We're using a Set here as checking values in a large Set is faster than
+ # checking values in a large Array.
+ protected_set = Set.new(protected_branch_names)
- if protected_branches.present?
- all_branches.reject! do |branch|
- protected_branches_names.include?(branch.name)
- end
+ repository.branches.reject do |branch|
+ protected_set.include?(branch.name)
end
-
- all_branches
end
- def protected_branches_names
- @protected_branches_names ||= protected_branches.map(&:name)
+ def protected_branch_names
+ @protected_branch_names ||= protected_branches.pluck(:name)
end
def root_ref?(branch)
@@ -765,7 +720,7 @@ class Project < ActiveRecord::Base
# Check if current branch name is marked as protected in the system
def protected_branch?(branch_name)
- protected_branches_names.include?(branch_name)
+ protected_branch_names.include?(branch_name)
end
def developers_can_push_to_protected_branch?(branch_name)
@@ -821,18 +776,16 @@ class Project < ActiveRecord::Base
wiki = Repository.new("#{old_path}.wiki", self)
if repo.exists?
- repo.expire_cache
- repo.expire_emptiness_caches
+ repo.before_delete
end
if wiki.exists?
- wiki.expire_cache
- wiki.expire_emptiness_caches
+ wiki.before_delete
end
end
- def hook_attrs
- {
+ def hook_attrs(backward: true)
+ attrs = {
name: name,
description: description,
web_url: web_url,
@@ -843,12 +796,19 @@ class Project < ActiveRecord::Base
visibility_level: visibility_level,
path_with_namespace: path_with_namespace,
default_branch: default_branch,
- # Backward compatibility
- homepage: web_url,
- url: url_to_repo,
- ssh_url: ssh_url_to_repo,
- http_url: http_url_to_repo
}
+
+ # Backward compatibility
+ if backward
+ attrs.merge!({
+ homepage: web_url,
+ url: url_to_repo,
+ ssh_url: ssh_url_to_repo,
+ http_url: http_url_to_repo
+ })
+ end
+
+ attrs
end
# Reset events cache related to this project
@@ -897,6 +857,7 @@ class Project < ActiveRecord::Base
repository.rugged.references.create('HEAD',
"refs/heads/#{branch}",
force: true)
+ repository.copy_gitattributes(branch)
reload_default_branch
end
@@ -957,12 +918,12 @@ class Project < ActiveRecord::Base
!namespace.share_with_group_lock
end
- def ci_commit(sha)
- ci_commits.find_by(sha: sha)
+ def ci_commit(sha, ref)
+ ci_commits.order(id: :desc).find_by(sha: sha, ref: ref)
end
- def ensure_ci_commit(sha)
- ci_commit(sha) || ci_commits.create(sha: sha)
+ def ensure_ci_commit(sha, ref)
+ ci_commit(sha, ref) || ci_commits.create(sha: sha, ref: ref)
end
def enable_ci
@@ -1031,4 +992,11 @@ class Project < ActiveRecord::Base
def wiki
@wiki ||= ProjectWiki.new(self, self.owner)
end
+
+ def schedule_delete!(user_id, params)
+ # Queue this task for after the commit, so once we mark pending_delete it will run
+ run_after_commit { ProjectDestroyWorker.perform_async(id, user_id, params) }
+
+ update_attribute(:pending_delete, true)
+ end
end
diff --git a/app/models/project_import_data.rb b/app/models/project_import_data.rb
index 79efb403058..e2f9ffb69ac 100644
--- a/app/models/project_import_data.rb
+++ b/app/models/project_import_data.rb
@@ -1,14 +1,4 @@
-# == Schema Information
-#
-# Table name: project_import_data
-#
-# id :integer not null, primary key
-# project_id :integer
-# data :text
-#
-
require 'carrierwave/orm/activerecord'
-require 'file_size_validator'
class ProjectImportData < ActiveRecord::Base
belongs_to :project
diff --git a/app/models/project_services/asana_service.rb b/app/models/project_services/asana_service.rb
index 792ad804575..7c23b766763 100644
--- a/app/models/project_services/asana_service.rb
+++ b/app/models/project_services/asana_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
require 'asana'
class AsanaService < Service
diff --git a/app/models/project_services/assembla_service.rb b/app/models/project_services/assembla_service.rb
index 29d841faed8..d839221d315 100644
--- a/app/models/project_services/assembla_service.rb
+++ b/app/models/project_services/assembla_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class AssemblaService < Service
include HTTParty
diff --git a/app/models/project_services/bamboo_service.rb b/app/models/project_services/bamboo_service.rb
index 060062aaf7a..1d1780dcfbf 100644
--- a/app/models/project_services/bamboo_service.rb
+++ b/app/models/project_services/bamboo_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class BambooService < CiService
include HTTParty
diff --git a/app/models/project_services/buildkite_service.rb b/app/models/project_services/buildkite_service.rb
index 3efbfd2eec3..86a06321e21 100644
--- a/app/models/project_services/buildkite_service.rb
+++ b/app/models/project_services/buildkite_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
require "addressable/uri"
class BuildkiteService < CiService
@@ -26,7 +5,7 @@ class BuildkiteService < CiService
prop_accessor :project_url, :token, :enable_ssl_verification
- validates :project_url, presence: true, if: :activated?
+ validates :project_url, presence: true, url: true, if: :activated?
validates :token, presence: true, if: :activated?
after_save :compose_service_hook, if: :activated?
@@ -91,7 +70,7 @@ class BuildkiteService < CiService
{ type: 'text',
name: 'project_url',
placeholder: "#{ENDPOINT}/example/project" },
-
+
{ type: 'checkbox',
name: 'enable_ssl_verification',
title: "Enable SSL verification" }
diff --git a/app/models/project_services/builds_email_service.rb b/app/models/project_services/builds_email_service.rb
index 6ab6d7417b7..54da4d74fc5 100644
--- a/app/models/project_services/builds_email_service.rb
+++ b/app/models/project_services/builds_email_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class BuildsEmailService < Service
prop_accessor :recipients
boolean_accessor :add_pusher
diff --git a/app/models/project_services/campfire_service.rb b/app/models/project_services/campfire_service.rb
index 6e8f0842524..511b2eac792 100644
--- a/app/models/project_services/campfire_service.rb
+++ b/app/models/project_services/campfire_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class CampfireService < Service
prop_accessor :token, :subdomain, :room
validates :token, presence: true, if: :activated?
diff --git a/app/models/project_services/ci_service.rb b/app/models/project_services/ci_service.rb
index d9f0849d147..596c00705ad 100644
--- a/app/models/project_services/ci_service.rb
+++ b/app/models/project_services/ci_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
# Base class for CI services
# List methods you need to implement to get your CI service
# working with GitLab Merge Requests
diff --git a/app/models/project_services/custom_issue_tracker_service.rb b/app/models/project_services/custom_issue_tracker_service.rb
index 88a3e9218cb..6b2b1daa724 100644
--- a/app/models/project_services/custom_issue_tracker_service.rb
+++ b/app/models/project_services/custom_issue_tracker_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class CustomIssueTrackerService < IssueTrackerService
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
diff --git a/app/models/project_services/drone_ci_service.rb b/app/models/project_services/drone_ci_service.rb
index b4724bb647e..966dbc41d73 100644
--- a/app/models/project_services/drone_ci_service.rb
+++ b/app/models/project_services/drone_ci_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class DroneCiService < CiService
prop_accessor :drone_url, :token, :enable_ssl_verification
diff --git a/app/models/project_services/emails_on_push_service.rb b/app/models/project_services/emails_on_push_service.rb
index b831577cd97..e0083c43adb 100644
--- a/app/models/project_services/emails_on_push_service.rb
+++ b/app/models/project_services/emails_on_push_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class EmailsOnPushService < Service
prop_accessor :send_from_committer_email
prop_accessor :disable_diffs
diff --git a/app/models/project_services/external_wiki_service.rb b/app/models/project_services/external_wiki_service.rb
index b402b68665a..f042bfc5210 100644
--- a/app/models/project_services/external_wiki_service.rb
+++ b/app/models/project_services/external_wiki_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class ExternalWikiService < Service
include HTTParty
diff --git a/app/models/project_services/flowdock_service.rb b/app/models/project_services/flowdock_service.rb
index 8605ce66e48..dd00275187f 100644
--- a/app/models/project_services/flowdock_service.rb
+++ b/app/models/project_services/flowdock_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
require "flowdock-git-hook"
class FlowdockService < Service
diff --git a/app/models/project_services/gemnasium_service.rb b/app/models/project_services/gemnasium_service.rb
index 61babe9cfe5..598aca5e06d 100644
--- a/app/models/project_services/gemnasium_service.rb
+++ b/app/models/project_services/gemnasium_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
require "gemnasium/gitlab_service"
class GemnasiumService < Service
diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb
index 33f0d7ea01a..bbc312f5215 100644
--- a/app/models/project_services/gitlab_ci_service.rb
+++ b/app/models/project_services/gitlab_ci_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
# TODO(ayufan): The GitLabCiService is deprecated and the type should be removed when the database entries are removed
class GitlabCiService < CiService
# We override the active accessor to always make GitLabCiService disabled
diff --git a/app/models/project_services/gitlab_issue_tracker_service.rb b/app/models/project_services/gitlab_issue_tracker_service.rb
index eaa5654b9c6..5d17c358330 100644
--- a/app/models/project_services/gitlab_issue_tracker_service.rb
+++ b/app/models/project_services/gitlab_issue_tracker_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class GitlabIssueTrackerService < IssueTrackerService
include Gitlab::Routing.url_helpers
diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb
index 0e3fa4a40fe..0ff4f4c8dd2 100644
--- a/app/models/project_services/hipchat_service.rb
+++ b/app/models/project_services/hipchat_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class HipchatService < Service
MAX_COMMITS = 3
@@ -183,7 +162,7 @@ class HipchatService < Service
title = obj_attr[:title]
merge_request_url = "#{project_url}/merge_requests/#{merge_request_id}"
- merge_request_link = "<a href=\"#{merge_request_url}\">merge request ##{merge_request_id}</a>"
+ merge_request_link = "<a href=\"#{merge_request_url}\">merge request !#{merge_request_id}</a>"
message = "#{user_name} #{state} #{merge_request_link} in " \
"#{project_link}: <b>#{title}</b>"
@@ -224,7 +203,7 @@ class HipchatService < Service
when "MergeRequest"
subj_attr = HashWithIndifferentAccess.new(data[:merge_request])
subject_id = subj_attr[:iid]
- subject_desc = "##{subject_id}"
+ subject_desc = "!#{subject_id}"
subject_type = "merge request"
title = format_title(subj_attr[:title])
when "Snippet"
diff --git a/app/models/project_services/irker_service.rb b/app/models/project_services/irker_service.rb
index 04c714bfaad..91015e6c9b1 100644
--- a/app/models/project_services/irker_service.rb
+++ b/app/models/project_services/irker_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
require 'uri'
class IrkerService < Service
diff --git a/app/models/project_services/issue_tracker_service.rb b/app/models/project_services/issue_tracker_service.rb
index 25045224ce5..6ae9b16d3ce 100644
--- a/app/models/project_services/issue_tracker_service.rb
+++ b/app/models/project_services/issue_tracker_service.rb
@@ -1,27 +1,6 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class IssueTrackerService < Service
- validates :project_url, :issues_url, :new_issue_url, presence: true, if: :activated?
+ validates :project_url, :issues_url, :new_issue_url, presence: true, url: true, if: :activated?
default_value_for :category, 'issue_tracker'
diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb
index 1ed42c4f3e7..beda89d3963 100644
--- a/app/models/project_services/jira_service.rb
+++ b/app/models/project_services/jira_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class JiraService < IssueTrackerService
include HTTParty
include Gitlab::Routing.url_helpers
@@ -28,6 +7,8 @@ class JiraService < IssueTrackerService
prop_accessor :username, :password, :api_url, :jira_issue_transition_id,
:title, :description, :project_url, :issues_url, :new_issue_url
+ validates :api_url, presence: true, url: true, if: :activated?
+
before_validation :set_api_url, :set_jira_issue_transition_id
before_update :reset_password
diff --git a/app/models/project_services/pivotaltracker_service.rb b/app/models/project_services/pivotaltracker_service.rb
index c9a890c7e3f..ad19b7795da 100644
--- a/app/models/project_services/pivotaltracker_service.rb
+++ b/app/models/project_services/pivotaltracker_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class PivotaltrackerService < Service
include HTTParty
diff --git a/app/models/project_services/pushover_service.rb b/app/models/project_services/pushover_service.rb
index e76d9eca2ab..3dd878e4c7d 100644
--- a/app/models/project_services/pushover_service.rb
+++ b/app/models/project_services/pushover_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class PushoverService < Service
include HTTParty
base_uri 'https://api.pushover.net/1'
diff --git a/app/models/project_services/redmine_service.rb b/app/models/project_services/redmine_service.rb
index de974354c77..11cce3e0561 100644
--- a/app/models/project_services/redmine_service.rb
+++ b/app/models/project_services/redmine_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class RedmineService < IssueTrackerService
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb
index d89cf6d17b2..cf9e4d5a8b6 100644
--- a/app/models/project_services/slack_service.rb
+++ b/app/models/project_services/slack_service.rb
@@ -1,28 +1,7 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class SlackService < Service
prop_accessor :webhook, :username, :channel
boolean_accessor :notify_only_broken_builds
- validates :webhook, presence: true, if: :activated?
+ validates :webhook, presence: true, url: true, if: :activated?
def initialize_properties
if properties.nil?
@@ -60,7 +39,7 @@ class SlackService < Service
end
def supported_events
- %w(push issue merge_request note tag_push build)
+ %w(push issue merge_request note tag_push build wiki_page)
end
def execute(data)
@@ -90,6 +69,8 @@ class SlackService < Service
NoteMessage.new(data)
when "build"
BuildMessage.new(data) if should_build_be_notified?(data)
+ when "wiki_page"
+ WikiPageMessage.new(data)
end
opt = {}
@@ -133,3 +114,4 @@ require "slack_service/push_message"
require "slack_service/merge_message"
require "slack_service/note_message"
require "slack_service/build_message"
+require "slack_service/wiki_page_message"
diff --git a/app/models/project_services/slack_service/merge_message.rb b/app/models/project_services/slack_service/merge_message.rb
index e792c258f73..11fc691022b 100644
--- a/app/models/project_services/slack_service/merge_message.rb
+++ b/app/models/project_services/slack_service/merge_message.rb
@@ -50,7 +50,7 @@ class SlackService
end
def merge_request_link
- "[merge request ##{merge_request_id}](#{merge_request_url})"
+ "[merge request !#{merge_request_id}](#{merge_request_url})"
end
def merge_request_url
diff --git a/app/models/project_services/slack_service/note_message.rb b/app/models/project_services/slack_service/note_message.rb
index b15d9a14677..89ba51cb662 100644
--- a/app/models/project_services/slack_service/note_message.rb
+++ b/app/models/project_services/slack_service/note_message.rb
@@ -58,7 +58,7 @@ class SlackService
def create_merge_note(merge_request)
commented_on_message(
- "[merge request ##{merge_request[:iid]}](#{@note_url})",
+ "[merge request !#{merge_request[:iid]}](#{@note_url})",
format_title(merge_request[:title]))
end
diff --git a/app/models/project_services/slack_service/wiki_page_message.rb b/app/models/project_services/slack_service/wiki_page_message.rb
new file mode 100644
index 00000000000..f336d9e7691
--- /dev/null
+++ b/app/models/project_services/slack_service/wiki_page_message.rb
@@ -0,0 +1,53 @@
+class SlackService
+ class WikiPageMessage < BaseMessage
+ attr_reader :user_name
+ attr_reader :title
+ attr_reader :project_name
+ attr_reader :project_url
+ attr_reader :wiki_page_url
+ attr_reader :action
+ attr_reader :description
+
+ def initialize(params)
+ @user_name = params[:user][:name]
+ @project_name = params[:project_name]
+ @project_url = params[:project_url]
+
+ obj_attr = params[:object_attributes]
+ obj_attr = HashWithIndifferentAccess.new(obj_attr)
+ @title = obj_attr[:title]
+ @wiki_page_url = obj_attr[:url]
+ @description = obj_attr[:content]
+
+ @action =
+ case obj_attr[:action]
+ when "create"
+ "created"
+ when "update"
+ "edited"
+ end
+ end
+
+ def attachments
+ description_message
+ end
+
+ private
+
+ def message
+ "#{user_name} #{action} #{wiki_page_link} in #{project_link}: *#{title}*"
+ end
+
+ def description_message
+ [{ text: format(@description), color: attachment_color }]
+ end
+
+ def project_link
+ "[#{project_name}](#{project_url})"
+ end
+
+ def wiki_page_link
+ "[wiki page](#{wiki_page_url})"
+ end
+ end
+end
diff --git a/app/models/project_services/teamcity_service.rb b/app/models/project_services/teamcity_service.rb
index 8dceee5e2c5..b0dcb52eba1 100644
--- a/app/models/project_services/teamcity_service.rb
+++ b/app/models/project_services/teamcity_service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
class TeamcityService < CiService
include HTTParty
diff --git a/app/models/project_snippet.rb b/app/models/project_snippet.rb
index 1f7d85a5f3d..5fba6baa204 100644
--- a/app/models/project_snippet.rb
+++ b/app/models/project_snippet.rb
@@ -1,19 +1,3 @@
-# == Schema Information
-#
-# Table name: snippets
-#
-# id :integer not null, primary key
-# title :string(255)
-# content :text
-# author_id :integer not null
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# file_name :string(255)
-# type :string(255)
-# visibility_level :integer default(0), not null
-#
-
class ProjectSnippet < Snippet
belongs_to :project
belongs_to :author, class_name: "User"
@@ -22,4 +6,6 @@ class ProjectSnippet < Snippet
# Scopes
scope :fresh, -> { order("created_at DESC") }
+
+ participant :author, :notes
end
diff --git a/app/models/protected_branch.rb b/app/models/protected_branch.rb
index 8ebd790a89e..33cf046fa75 100644
--- a/app/models/protected_branch.rb
+++ b/app/models/protected_branch.rb
@@ -1,15 +1,3 @@
-# == Schema Information
-#
-# Table name: protected_branches
-#
-# id :integer not null, primary key
-# project_id :integer not null
-# name :string(255) not null
-# created_at :datetime
-# updated_at :datetime
-# developers_can_push :boolean default(FALSE), not null
-#
-
class ProtectedBranch < ActiveRecord::Base
include Gitlab::ShellAdapter
diff --git a/app/models/release.rb b/app/models/release.rb
index 89f70278af5..e196b84eb18 100644
--- a/app/models/release.rb
+++ b/app/models/release.rb
@@ -1,15 +1,3 @@
-# == Schema Information
-#
-# Table name: releases
-#
-# id :integer not null, primary key
-# tag :string(255)
-# description :text
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-#
-
class Release < ActiveRecord::Base
belongs_to :project
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 308c590e3f8..7aebfe279fb 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -12,11 +12,13 @@ class Repository
attr_accessor :path_with_namespace, :project
def self.clean_old_archives
- repository_downloads_path = Gitlab.config.gitlab.repository_downloads_path
+ Gitlab::Metrics.measure(:clean_old_archives) do
+ repository_downloads_path = Gitlab.config.gitlab.repository_downloads_path
- return unless File.directory?(repository_downloads_path)
+ return unless File.directory?(repository_downloads_path)
- Gitlab::Popen.popen(%W(find #{repository_downloads_path} -not -path #{repository_downloads_path} -mmin +120 -delete))
+ Gitlab::Popen.popen(%W(find #{repository_downloads_path} -not -path #{repository_downloads_path} -mmin +120 -delete))
+ end
end
def initialize(path_with_namespace, project)
@@ -85,13 +87,15 @@ class Repository
nil
end
- def commits(ref, path = nil, limit = nil, offset = nil, skip_merges = false)
+ def commits(ref, path: nil, limit: nil, offset: nil, skip_merges: false, after: nil, before: nil)
options = {
repo: raw_repository,
ref: ref,
path: path,
limit: limit,
offset: offset,
+ after: after,
+ before: before,
# --follow doesn't play well with --skip. See:
# https://gitlab.com/gitlab-org/gitlab-ce/issues/3574#note_3040520
follow: false,
@@ -144,10 +148,20 @@ class Repository
find_branch(branch_name)
end
- def add_tag(tag_name, ref, message = nil)
- before_push_tag
+ def add_tag(user, tag_name, target, message = nil)
+ oldrev = Gitlab::Git::BLANK_SHA
+ ref = Gitlab::Git::TAG_REF_PREFIX + tag_name
+ target = commit(target).try(:id)
+
+ return false unless target
+
+ options = { message: message, tagger: user_to_committer(user) } if message
- gitlab_shell.add_tag(path_with_namespace, tag_name, ref, message)
+ GitHooksService.new.execute(user, path_to_repo, oldrev, target, ref) do
+ rugged.tags.create(tag_name, target, options)
+ end
+
+ find_tag(tag_name)
end
def rm_branch(user, branch_name)
@@ -226,7 +240,8 @@ class Repository
def cache_keys
%i(size branch_names tag_names commit_count
- readme version contribution_guide changelog license)
+ readme version contribution_guide changelog
+ license_blob license_key)
end
def build_cache
@@ -454,32 +469,26 @@ class Repository
def changelog
cache.fetch(:changelog) do
tree(:head).blobs.find do |file|
- file.name =~ /\A(changelog|history)/i
+ file.name =~ /\A(changelog|history|changes|news)/i
end
end
end
- def license
- cache.fetch(:license) do
- licenses = tree(:head).blobs.find_all do |file|
- file.name =~ /\A(copying|license|licence)/i
- end
-
- preferences = [
- /\Alicen[sc]e\z/i, # LICENSE, LICENCE
- /\Alicen[sc]e\./i, # LICENSE.md, LICENSE.txt
- /\Acopying\z/i, # COPYING
- /\Acopying\.(?!lesser)/i, # COPYING.txt
- /Acopying.lesser/i # COPYING.LESSER
- ]
+ def license_blob
+ return nil if !exists? || empty?
- license = nil
- preferences.each do |r|
- license = licenses.find { |l| l.name =~ r }
- break if license
+ cache.fetch(:license_blob) do
+ tree(:head).blobs.find do |file|
+ file.name =~ /\A(licen[sc]e|copying)(\..+|\z)/i
end
+ end
+ end
+
+ def license_key
+ return nil if !exists? || empty?
- license
+ cache.fetch(:license_key) do
+ Licensee.license(path).try(:key)
end
end
@@ -547,15 +556,18 @@ class Repository
commit(sha)
end
- def next_patch_branch
- patch_branch_ids = self.branch_names.map do |n|
- result = n.match(/\Apatch-([0-9]+)\z/)
+ def next_branch(name, opts={})
+ branch_ids = self.branch_names.map do |n|
+ next 1 if n == name
+ result = n.match(/\A#{name}-([0-9]+)\z/)
result[1].to_i if result
end.compact
- highest_patch_branch_id = patch_branch_ids.max || 0
+ highest_branch_id = branch_ids.max || 0
+
+ return name if opts[:mild] && 0 == highest_branch_id
- "patch-#{highest_patch_branch_id + 1}"
+ "#{name}-#{highest_branch_id + 1}"
end
# Remove archives older than 2 hours
@@ -575,7 +587,7 @@ class Repository
end
def contributors
- commits = self.commits(nil, nil, 2000, 0, true)
+ commits = self.commits(nil, limit: 2000, offset: 0, skip_merges: true)
commits.group_by(&:author_email).map do |email, commits|
contributor = Gitlab::Contributor.new
@@ -758,6 +770,28 @@ class Repository
end
end
+ def cherry_pick(user, commit, base_branch, cherry_pick_tree_id = nil)
+ source_sha = find_branch(base_branch).target
+ cherry_pick_tree_id ||= check_cherry_pick_content(commit, base_branch)
+
+ return false unless cherry_pick_tree_id
+
+ commit_with_hooks(user, base_branch) do |ref|
+ committer = user_to_committer(user)
+ source_sha = Rugged::Commit.create(rugged,
+ message: commit.message,
+ author: {
+ email: commit.author_email,
+ name: commit.author_name,
+ time: commit.authored_date
+ },
+ committer: committer,
+ tree: cherry_pick_tree_id,
+ parents: [rugged.lookup(source_sha)],
+ update_ref: ref)
+ end
+ end
+
def check_revert_content(commit, base_branch)
source_sha = find_branch(base_branch).target
args = [commit.id, source_sha]
@@ -772,6 +806,20 @@ class Repository
tree_id
end
+ def check_cherry_pick_content(commit, base_branch)
+ source_sha = find_branch(base_branch).target
+ args = [commit.id, source_sha]
+ args << 1 if commit.merge_commit?
+
+ cherry_pick_index = rugged.cherrypick_commit(*args)
+ return false if cherry_pick_index.conflicts?
+
+ tree_id = cherry_pick_index.write_tree(rugged)
+ return false unless diff_exists?(source_sha, tree_id)
+
+ tree_id
+ end
+
def diff_exists?(sha1, sha2)
rugged.diff(sha1, sha2).size > 0
end
@@ -902,6 +950,16 @@ class Repository
raw_repository.ls_files(actual_ref)
end
+ def copy_gitattributes(ref)
+ actual_ref = ref || root_ref
+ begin
+ raw_repository.copy_gitattributes(actual_ref)
+ true
+ rescue Gitlab::Git::Repository::InvalidRef
+ false
+ end
+ end
+
def main_language
return if empty? || rugged.head_unborn?
diff --git a/app/models/security_event.rb b/app/models/security_event.rb
index 68c00adad59..d131c11cb6c 100644
--- a/app/models/security_event.rb
+++ b/app/models/security_event.rb
@@ -1,16 +1,2 @@
-# == Schema Information
-#
-# Table name: audit_events
-#
-# id :integer not null, primary key
-# author_id :integer not null
-# type :string(255) not null
-# entity_id :integer not null
-# entity_type :string(255) not null
-# details :text
-# created_at :datetime
-# updated_at :datetime
-#
-
class SecurityEvent < AuditEvent
end
diff --git a/app/models/sent_notification.rb b/app/models/sent_notification.rb
index 77115597d71..375f195dba7 100644
--- a/app/models/sent_notification.rb
+++ b/app/models/sent_notification.rb
@@ -1,17 +1,3 @@
-# == Schema Information
-#
-# Table name: sent_notifications
-#
-# id :integer not null, primary key
-# project_id :integer
-# noteable_id :integer
-# noteable_type :string(255)
-# recipient_id :integer
-# commit_id :string(255)
-# line_code :string(255)
-# reply_key :string(255) not null
-#
-
class SentNotification < ActiveRecord::Base
belongs_to :project
belongs_to :noteable, polymorphic: true
diff --git a/app/models/service.rb b/app/models/service.rb
index 721273250ea..de3fd24584a 100644
--- a/app/models/service.rb
+++ b/app/models/service.rb
@@ -1,24 +1,3 @@
-# == Schema Information
-#
-# Table name: services
-#
-# 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)
-# push_events :boolean default(TRUE)
-# issues_events :boolean default(TRUE)
-# merge_requests_events :boolean default(TRUE)
-# tag_push_events :boolean default(TRUE)
-# note_events :boolean default(TRUE), not null
-# build_events :boolean default(FALSE), not null
-#
-
# To add new service you should build a class inherited from Service
# and implement a set of methods
class Service < ActiveRecord::Base
@@ -32,6 +11,7 @@ class Service < ActiveRecord::Base
default_value_for :tag_push_events, true
default_value_for :note_events, true
default_value_for :build_events, true
+ default_value_for :wiki_page_events, true
after_initialize :initialize_properties
@@ -53,6 +33,7 @@ class Service < ActiveRecord::Base
scope :merge_request_hooks, -> { where(merge_requests_events: true, active: true) }
scope :note_hooks, -> { where(note_events: true, active: true) }
scope :build_hooks, -> { where(build_events: true, active: true) }
+ scope :wiki_page_hooks, -> { where(wiki_page_events: true, active: true) }
default_value_for :category, 'common'
@@ -94,7 +75,7 @@ class Service < ActiveRecord::Base
end
def supported_events
- %w(push tag_push issue merge_request)
+ %w(push tag_push issue merge_request wiki_page)
end
def execute(data)
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index b96e3937281..0a3c3b57669 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -1,19 +1,3 @@
-# == Schema Information
-#
-# Table name: snippets
-#
-# id :integer not null, primary key
-# title :string(255)
-# content :text
-# author_id :integer not null
-# project_id :integer
-# created_at :datetime
-# updated_at :datetime
-# file_name :string(255)
-# type :string(255)
-# visibility_level :integer default(0), not null
-#
-
class Snippet < ActiveRecord::Base
include Gitlab::VisibilityLevel
include Linguist::BlobHelper
@@ -112,6 +96,10 @@ class Snippet < ActiveRecord::Base
visibility_level
end
+ def no_highlighting?
+ content.lines.count > 1000
+ end
+
class << self
# Searches for snippets with a matching title or file name.
#
diff --git a/app/models/subscription.rb b/app/models/subscription.rb
index dd800ce110f..3b8aa1eb866 100644
--- a/app/models/subscription.rb
+++ b/app/models/subscription.rb
@@ -1,16 +1,3 @@
-# == Schema Information
-#
-# Table name: subscriptions
-#
-# id :integer not null, primary key
-# user_id :integer
-# subscribable_id :integer
-# subscribable_type :string(255)
-# subscribed :boolean
-# created_at :datetime
-# updated_at :datetime
-#
-
class Subscription < ActiveRecord::Base
belongs_to :user
belongs_to :subscribable, polymorphic: true
diff --git a/app/models/todo.rb b/app/models/todo.rb
index d85f7bfdf57..f8b59fe4126 100644
--- a/app/models/todo.rb
+++ b/app/models/todo.rb
@@ -1,21 +1,3 @@
-# == Schema Information
-#
-# Table name: todos
-#
-# id :integer not null, primary key
-# user_id :integer not null
-# project_id :integer not null
-# target_id :integer
-# target_type :string not null
-# author_id :integer
-# action :integer not null
-# state :string not null
-# created_at :datetime
-# updated_at :datetime
-# note_id :integer
-# commit_id :string
-#
-
class Todo < ActiveRecord::Base
ASSIGNED = 1
MENTIONED = 2
diff --git a/app/models/user.rb b/app/models/user.rb
index 52f2904f450..37179c10788 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,69 +1,4 @@
-# == Schema Information
-#
-# Table name: users
-#
-# id :integer not null, primary key
-# email :string(255) default(""), not null
-# encrypted_password :string(255) default(""), not null
-# reset_password_token :string(255)
-# reset_password_sent_at :datetime
-# remember_created_at :datetime
-# sign_in_count :integer default(0)
-# current_sign_in_at :datetime
-# last_sign_in_at :datetime
-# current_sign_in_ip :string(255)
-# last_sign_in_ip :string(255)
-# created_at :datetime
-# updated_at :datetime
-# name :string(255)
-# admin :boolean default(FALSE), not null
-# projects_limit :integer default(10)
-# skype :string(255) default(""), not null
-# linkedin :string(255) default(""), not null
-# twitter :string(255) default(""), not null
-# authentication_token :string(255)
-# theme_id :integer default(1), not null
-# bio :string(255)
-# failed_attempts :integer default(0)
-# locked_at :datetime
-# username :string(255)
-# can_create_group :boolean default(TRUE), not null
-# can_create_team :boolean default(TRUE), not null
-# state :string(255)
-# color_scheme_id :integer default(1), not null
-# notification_level :integer default(1), not null
-# password_expires_at :datetime
-# created_by_id :integer
-# last_credential_check_at :datetime
-# avatar :string(255)
-# confirmation_token :string(255)
-# confirmed_at :datetime
-# confirmation_sent_at :datetime
-# unconfirmed_email :string(255)
-# hide_no_ssh_key :boolean default(FALSE)
-# website_url :string(255) default(""), not null
-# notification_email :string(255)
-# hide_no_password :boolean default(FALSE)
-# password_automatically_set :boolean default(FALSE)
-# location :string(255)
-# encrypted_otp_secret :string(255)
-# encrypted_otp_secret_iv :string(255)
-# encrypted_otp_secret_salt :string(255)
-# otp_required_for_login :boolean default(FALSE), not null
-# otp_backup_codes :text
-# public_email :string(255) default(""), not null
-# dashboard :integer default(0)
-# project_view :integer default(0)
-# consumed_timestep :integer
-# layout :integer default(0)
-# hide_project_limit :boolean default(FALSE)
-# unlock_token :string
-# otp_grace_period_started_at :datetime
-# external :boolean default(FALSE)
-#
-
require 'carrierwave/orm/activerecord'
-require 'file_size_validator'
class User < ActiveRecord::Base
extend Gitlab::ConfigHelper
@@ -86,7 +21,7 @@ class User < ActiveRecord::Base
default_value_for :theme_id, gitlab_config.default_theme
devise :two_factor_authenticatable,
- otp_secret_encryption_key: File.read(Rails.root.join('.secret')).chomp
+ otp_secret_encryption_key: Gitlab::Application.config.secret_key_base
alias_attribute :two_factor_enabled, :otp_required_for_login
devise :two_factor_backupable, otp_number_of_backup_codes: 10
diff --git a/app/models/users_star_project.rb b/app/models/users_star_project.rb
index 413f3f485a8..0dfe597317e 100644
--- a/app/models/users_star_project.rb
+++ b/app/models/users_star_project.rb
@@ -1,14 +1,3 @@
-# == Schema Information
-#
-# Table name: users_star_projects
-#
-# id :integer not null, primary key
-# project_id :integer not null
-# user_id :integer not null
-# created_at :datetime
-# updated_at :datetime
-#
-
class UsersStarProject < ActiveRecord::Base
belongs_to :project, counter_cache: :star_count, touch: true
belongs_to :user
diff --git a/app/models/wiki_page.rb b/app/models/wiki_page.rb
index 526760779a4..3d5fd9d3ee9 100644
--- a/app/models/wiki_page.rb
+++ b/app/models/wiki_page.rb
@@ -29,6 +29,10 @@ class WikiPage
# new Page values before writing to the Gollum repository.
attr_accessor :attributes
+ def hook_attrs
+ attributes
+ end
+
def initialize(wiki, page = nil, persisted = false)
@wiki = wiki
@page = page