summaryrefslogtreecommitdiff
path: root/app/models
diff options
context:
space:
mode:
Diffstat (limited to 'app/models')
-rw-r--r--app/models/ci/build.rb1
-rw-r--r--app/models/ci/pipeline.rb38
-rw-r--r--app/models/group.rb10
-rw-r--r--app/models/jira_issue.rb2
-rw-r--r--app/models/personal_access_token.rb20
-rw-r--r--app/models/project.rb20
-rw-r--r--app/models/repository.rb2
-rw-r--r--app/models/service.rb2
-rw-r--r--app/models/user.rb6
9 files changed, 76 insertions, 25 deletions
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 764d8e4e136..d618c84e983 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -341,6 +341,7 @@ module Ci
def erase_artifacts!
remove_artifacts_file!
remove_artifacts_metadata!
+ save
end
def erase(opts = {})
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 4bbfb4cc806..a5f2ac59001 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -94,10 +94,13 @@ module Ci
end
def create_builds(user, trigger_request = nil)
+ ##
+ # We persist pipeline only if there are builds available
+ #
return unless config_processor
- config_processor.stages.any? do |stage|
- CreateBuildsService.new(self).execute(stage, user, 'success', trigger_request).present?
- end
+
+ build_builds_for_stages(config_processor.stages, user,
+ 'success', trigger_request) && save
end
def create_next_builds(build)
@@ -115,10 +118,10 @@ module Ci
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(self).execute(stage, build.user, prior_status, build.trigger_request).present?
- end
+ # build builds for next stage that has builds available
+ # and save pipeline if we have builds
+ build_builds_for_stages(next_stages, build.user, prior_status,
+ build.trigger_request) && save
end
def retried
@@ -139,10 +142,10 @@ module Ci
@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)
+ self.yaml_errors = e.message
nil
rescue
- save_yaml_error("Undefined error")
+ self.yaml_errors = 'Undefined error'
nil
end
end
@@ -169,6 +172,17 @@ module Ci
private
+ def build_builds_for_stages(stages, user, status, trigger_request)
+ ##
+ # Note that `Array#any?` implements a short circuit evaluation, so we
+ # build builds only for the first stage that has builds available.
+ #
+ stages.any? do |stage|
+ CreateBuildsService.new(self)
+ .execute(stage, user, status, trigger_request).present?
+ end
+ end
+
def update_state
statuses.reload
self.status = if yaml_errors.blank?
@@ -181,11 +195,5 @@ module Ci
self.duration = statuses.latest.duration
save
end
-
- def save_yaml_error(error)
- return if self.yaml_errors?
- self.yaml_errors = error
- update_state
- end
end
end
diff --git a/app/models/group.rb b/app/models/group.rb
index b8dffe9f5b9..e66e04371b2 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -9,6 +9,12 @@ class Group < Namespace
has_many :group_members, dependent: :destroy, as: :source, class_name: 'GroupMember'
alias_method :members, :group_members
has_many :users, -> { where(members: { requested_at: nil }) }, through: :group_members
+
+ has_many :owners,
+ -> { where(members: { access_level: Gitlab::Access::OWNER }) },
+ through: :group_members,
+ source: :user
+
has_many :project_group_links, dependent: :destroy
has_many :shared_projects, through: :project_group_links, source: :project
has_many :notification_settings, dependent: :destroy, as: :source
@@ -88,10 +94,6 @@ class Group < Namespace
end
end
- def owners
- @owners ||= group_members.owners.includes(:user).map(&:user)
- end
-
def add_users(user_ids, access_level, current_user = nil)
user_ids.each do |user_id|
Member.add_user(self.group_members, user_id, access_level, current_user)
diff --git a/app/models/jira_issue.rb b/app/models/jira_issue.rb
deleted file mode 100644
index 5b21aac5e43..00000000000
--- a/app/models/jira_issue.rb
+++ /dev/null
@@ -1,2 +0,0 @@
-class JiraIssue < ExternalIssue
-end
diff --git a/app/models/personal_access_token.rb b/app/models/personal_access_token.rb
new file mode 100644
index 00000000000..c4b095e0c04
--- /dev/null
+++ b/app/models/personal_access_token.rb
@@ -0,0 +1,20 @@
+class PersonalAccessToken < ActiveRecord::Base
+ include TokenAuthenticatable
+ add_authentication_token_field :token
+
+ belongs_to :user
+
+ scope :active, -> { where(revoked: false).where("expires_at >= NOW() OR expires_at IS NULL") }
+ scope :inactive, -> { where("revoked = true OR expires_at < NOW()") }
+
+ def self.generate(params)
+ personal_access_token = self.new(params)
+ personal_access_token.ensure_token
+ personal_access_token
+ end
+
+ def revoke!
+ self.revoked = true
+ self.save
+ end
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index fdbc84474ed..8eef22356e2 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -81,7 +81,7 @@ class Project < ActiveRecord::Base
has_one :jira_service, dependent: :destroy
has_one :redmine_service, dependent: :destroy
has_one :custom_issue_tracker_service, dependent: :destroy
- has_one :gitlab_issue_tracker_service, dependent: :destroy
+ has_one :gitlab_issue_tracker_service, dependent: :destroy, inverse_of: :project
has_one :external_wiki_service, dependent: :destroy
has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id"
@@ -262,7 +262,23 @@ class Project < ActiveRecord::Base
#
# Returns a Project, or nil if no project could be found.
def find_with_namespace(path)
- where_paths_in([path]).reorder(nil).take
+ namespace_path, project_path = path.split('/', 2)
+
+ return unless namespace_path && project_path
+
+ namespace_path = connection.quote(namespace_path)
+ project_path = connection.quote(project_path)
+
+ # On MySQL we want to ensure the ORDER BY uses a case-sensitive match so
+ # any literal matches come first, for this we have to use "BINARY".
+ # Without this there's still no guarantee in what order MySQL will return
+ # rows.
+ binary = Gitlab::Database.mysql? ? 'BINARY' : ''
+
+ order_sql = "(CASE WHEN #{binary} namespaces.path = #{namespace_path} " \
+ "AND #{binary} projects.path = #{project_path} THEN 0 ELSE 1 END)"
+
+ where_paths_in([path]).reorder(order_sql).take
end
# Builds a relation to find multiple projects by their full paths.
diff --git a/app/models/repository.rb b/app/models/repository.rb
index e5b277cb198..65d1bad511d 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -243,7 +243,7 @@ class Repository
end
def cache_keys
- %i(size branch_names tag_names commit_count
+ %i(size branch_names tag_names branch_count tag_count commit_count
readme version contribution_guide changelog
license_blob license_key gitignore)
end
diff --git a/app/models/service.rb b/app/models/service.rb
index bf352397509..40d39933ad8 100644
--- a/app/models/service.rb
+++ b/app/models/service.rb
@@ -18,7 +18,7 @@ class Service < ActiveRecord::Base
after_commit :reset_updated_properties
after_commit :cache_project_has_external_issue_tracker
- belongs_to :project
+ belongs_to :project, inverse_of: :services
has_one :service_hook
validates :project_id, presence: true, unless: Proc.new { |service| service.template? }
diff --git a/app/models/user.rb b/app/models/user.rb
index 8d0427da5ab..051745fe252 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -51,6 +51,7 @@ class User < ActiveRecord::Base
# Profile
has_many :keys, dependent: :destroy
has_many :emails, dependent: :destroy
+ has_many :personal_access_tokens, dependent: :destroy
has_many :identities, dependent: :destroy, autosave: true
has_many :u2f_registrations, dependent: :destroy
@@ -267,6 +268,11 @@ class User < ActiveRecord::Base
find_by!('lower(username) = ?', username.downcase)
end
+ def find_by_personal_access_token(token_string)
+ personal_access_token = PersonalAccessToken.active.find_by_token(token_string) if token_string
+ personal_access_token.user if personal_access_token
+ end
+
def by_username_or_id(name_or_id)
find_by('users.username = ? OR users.id = ?', name_or_id.to_s, name_or_id.to_i)
end