Read about our upcoming Code of Conduct on this issue

Commit d2d4059e authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 5137254cfcca
...@@ -456,7 +456,7 @@ group :ed25519 do ...@@ -456,7 +456,7 @@ group :ed25519 do
end end
# Gitaly GRPC protocol definitions # Gitaly GRPC protocol definitions
gem 'gitaly', '~> 1.81.0' gem 'gitaly', '~> 1.85.0'
gem 'grpc', '~> 1.24.0' gem 'grpc', '~> 1.24.0'
......
...@@ -360,7 +360,7 @@ GEM ...@@ -360,7 +360,7 @@ GEM
po_to_json (>= 1.0.0) po_to_json (>= 1.0.0)
rails (>= 3.2.0) rails (>= 3.2.0)
git (1.5.0) git (1.5.0)
gitaly (1.81.0) gitaly (1.85.0)
grpc (~> 1.0) grpc (~> 1.0)
github-markup (1.7.0) github-markup (1.7.0)
gitlab-chronic (0.10.5) gitlab-chronic (0.10.5)
...@@ -1209,7 +1209,7 @@ DEPENDENCIES ...@@ -1209,7 +1209,7 @@ DEPENDENCIES
gettext (~> 3.2.2) gettext (~> 3.2.2)
gettext_i18n_rails (~> 1.8.0) gettext_i18n_rails (~> 1.8.0)
gettext_i18n_rails_js (~> 1.3) gettext_i18n_rails_js (~> 1.3)
gitaly (~> 1.81.0) gitaly (~> 1.85.0)
github-markup (~> 1.7.0) github-markup (~> 1.7.0)
gitlab-chronic (~> 0.10.5) gitlab-chronic (~> 0.10.5)
gitlab-labkit (= 0.9.1) gitlab-labkit (= 0.9.1)
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# More info at https://github.com/guard/guard#readme # More info at https://github.com/guard/guard#readme
cmd = ENV['SPRING'] ? 'spring rspec' : 'bundle exec rspec' cmd = ENV['GUARD_CMD'] || (ENV['SPRING'] ? 'spring rspec' : 'bundle exec rspec')
guard :rspec, cmd: cmd do guard :rspec, cmd: cmd do
require "guard/rspec/dsl" require "guard/rspec/dsl"
......
...@@ -129,9 +129,6 @@ export default { ...@@ -129,9 +129,6 @@ export default {
crossplaneInstalled() { crossplaneInstalled() {
return this.applications.crossplane.status === APPLICATION_STATUS.INSTALLED; return this.applications.crossplane.status === APPLICATION_STATUS.INSTALLED;
}, },
enableClusterApplicationElasticStack() {
return gon.features && gon.features.enableClusterApplicationElasticStack;
},
ingressModSecurityDescription() { ingressModSecurityDescription() {
const escapedUrl = _.escape(this.ingressModSecurityHelpPath); const escapedUrl = _.escape(this.ingressModSecurityHelpPath);
...@@ -655,7 +652,6 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity ...@@ -655,7 +652,6 @@ Crossplane runs inside your Kubernetes cluster and supports secure connectivity
</div> </div>
</application-row> </application-row>
<application-row <application-row
v-if="enableClusterApplicationElasticStack"
id="elastic_stack" id="elastic_stack"
:logo-url="elasticStackLogo" :logo-url="elasticStackLogo"
:title="applications.elastic_stack.title" :title="applications.elastic_stack.title"
......
...@@ -107,10 +107,16 @@ export default { ...@@ -107,10 +107,16 @@ export default {
return acc.concat({ return acc.concat({
name, name,
path, path,
to: `/-/tree/${this.ref}${path}`, to: `/-/tree/${escape(this.ref)}${path}`,
}); });
}, },
[{ name: this.projectShortPath, path: '/', to: `/-/tree/${this.ref}/` }], [
{
name: this.projectShortPath,
path: '/',
to: `/-/tree/${escape(this.ref)}/`,
},
],
); );
}, },
canCreateMrFromFork() { canCreateMrFromFork() {
......
...@@ -28,7 +28,7 @@ export default { ...@@ -28,7 +28,7 @@ export default {
return splitArray.join('/'); return splitArray.join('/');
}, },
parentRoute() { parentRoute() {
return { path: `/-/tree/${this.commitRef}/${this.parentPath}` }; return { path: `/-/tree/${escape(this.commitRef)}/${this.parentPath}` };
}, },
}, },
methods: { methods: {
......
...@@ -90,7 +90,7 @@ export default { ...@@ -90,7 +90,7 @@ export default {
}, },
computed: { computed: {
routerLinkTo() { routerLinkTo() {
return this.isFolder ? { path: `/-/tree/${this.ref}/${this.path}` } : null; return this.isFolder ? { path: `/-/tree/${escape(this.ref)}/${this.path}` } : null;
}, },
iconName() { iconName() {
return `fa-${getIconName(this.type, this.path)}`; return `fa-${getIconName(this.type, this.path)}`;
......
...@@ -27,7 +27,10 @@ export function fetchLogsTree(client, path, offset, resolver = null) { ...@@ -27,7 +27,10 @@ export function fetchLogsTree(client, path, offset, resolver = null) {
fetchpromise = axios fetchpromise = axios
.get( .get(
`${gon.relative_url_root}/${projectPath}/-/refs/${ref}/logs_tree/${path.replace(/^\//, '')}`, `${gon.relative_url_root}/${projectPath}/-/refs/${escape(ref)}/logs_tree/${path.replace(
/^\//,
'',
)}`,
{ {
params: { format: 'json', offset }, params: { format: 'json', offset },
}, },
......
...@@ -12,7 +12,7 @@ export default function createRouter(base, baseRef) { ...@@ -12,7 +12,7 @@ export default function createRouter(base, baseRef) {
base: joinPaths(gon.relative_url_root || '', base), base: joinPaths(gon.relative_url_root || '', base),
routes: [ routes: [
{ {
path: `/-/tree/${baseRef}(/.*)?`, path: `/-/tree/${escape(baseRef)}(/.*)?`,
name: 'treePath', name: 'treePath',
component: TreePage, component: TreePage,
props: route => ({ props: route => ({
......
...@@ -12,9 +12,6 @@ class Clusters::ClustersController < Clusters::BaseController ...@@ -12,9 +12,6 @@ class Clusters::ClustersController < Clusters::BaseController
before_action :authorize_update_cluster!, only: [:update] before_action :authorize_update_cluster!, only: [:update]
before_action :authorize_admin_cluster!, only: [:destroy, :clear_cache] before_action :authorize_admin_cluster!, only: [:destroy, :clear_cache]
before_action :update_applications_status, only: [:cluster_status] before_action :update_applications_status, only: [:cluster_status]
before_action only: [:show] do
push_frontend_feature_flag(:enable_cluster_application_elastic_stack)
end
helper_method :token_in_session helper_method :token_in_session
......
...@@ -64,6 +64,10 @@ def render_diffs ...@@ -64,6 +64,10 @@ def render_diffs
options = additional_attributes.merge(diff_view: diff_view) options = additional_attributes.merge(diff_view: diff_view)
if @merge_request.project.context_commits_enabled?
options[:context_commits] = @merge_request.context_commits
end
render json: DiffsSerializer.new(request).represent(diffs, options) render json: DiffsSerializer.new(request).represent(diffs, options)
end end
......
...@@ -116,6 +116,15 @@ def pipelines ...@@ -116,6 +116,15 @@ def pipelines
} }
end end
def context_commits
return render_404 unless project.context_commits_enabled?
# Get commits from repository
# or from cache if already merged
commits = ContextCommitsFinder.new(project, @merge_request, { search: params[:search], limit: params[:limit], offset: params[:offset] }).execute
render json: CommitEntity.represent(commits, { type: :full, request: merge_request })
end
def test_reports def test_reports
reports_response(@merge_request.compare_test_reports) reports_response(@merge_request.compare_test_reports)
end end
......
...@@ -81,7 +81,7 @@ def assign_append_sha ...@@ -81,7 +81,7 @@ def assign_append_sha
def assign_archive_vars def assign_archive_vars
if params[:id] if params[:id]
@ref, @filename = extract_ref(params[:id]) @ref, @filename = extract_ref_and_filename(params[:id])
else else
@ref = params[:ref] @ref = params[:ref]
@filename = nil @filename = nil
...@@ -89,6 +89,26 @@ def assign_archive_vars ...@@ -89,6 +89,26 @@ def assign_archive_vars
rescue InvalidPathError rescue InvalidPathError
render_404 render_404
end end
# path can be of the form:
# master
# master/first.zip
# master/first/second.tar.gz
# master/first/second/third.zip
#
# In the archive case, we know that the last value is always the filename, so we
# do a greedy match to extract the ref. This avoid having to pull all ref names
# from Redis.
def extract_ref_and_filename(id)
path = id.strip
data = path.match(/(.*)\/(.*)/)
if data
[data[1], data[2]]
else
[path, nil]
end
end
end end
Projects::RepositoriesController.prepend_if_ee('EE::Projects::RepositoriesController') Projects::RepositoriesController.prepend_if_ee('EE::Projects::RepositoriesController')
# frozen_string_literal: true
class ContextCommitsFinder
def initialize(project, merge_request, params = {})
@project = project
@merge_request = merge_request
@search = params[:search]
@limit = (params[:limit] || 40).to_i
@offset = (params[:offset] || 0).to_i
end
def execute
commits = init_collection
commits = filter_existing_commits(commits)
commits
end
private
attr_reader :project, :merge_request, :search, :limit, :offset
def init_collection
commits =
if search.present?
search_commits
else
project.repository.commits(merge_request.source_branch, { limit: limit, offset: offset })
end
commits
end
def filter_existing_commits(commits)
commits.select! { |commit| already_included_ids.exclude?(commit.id) }
commits
end
def search_commits
key = search.strip
commits = []
if Commit.valid_hash?(key)
mr_existing_commits_ids = merge_request.commits.map(&:id)
if mr_existing_commits_ids.exclude? key
commit_by_sha = project.repository.commit(key)
commits = [commit_by_sha] if commit_by_sha
end
else
commits = project.repository.find_commits_by_message(search, nil, nil, 20)
end
commits
end
def already_included_ids
mr_existing_commits_ids = merge_request.commits.map(&:id)
mr_context_commits_ids = merge_request.context_commits.map(&:id)
mr_existing_commits_ids + mr_context_commits_ids
end
end
...@@ -29,6 +29,8 @@ def diff_options ...@@ -29,6 +29,8 @@ def diff_options
if action_name == 'diff_for_path' if action_name == 'diff_for_path'
options[:expanded] = true options[:expanded] = true
options[:paths] = params.values_at(:old_path, :new_path) options[:paths] = params.values_at(:old_path, :new_path)
elsif action_name == 'show'
options[:include_context_commits] = true unless @project.context_commits_enabled?
end end
options options
......
# frozen_string_literal: true
module CachedCommit
extend ActiveSupport::Concern
def to_hash
Gitlab::Git::Commit::SERIALIZE_KEYS.each_with_object({}) do |key, hash|
hash[key] = public_send(key) # rubocop:disable GitlabSecurity/PublicSend
end
end
# We don't save these, because they would need a table or a serialised
# field. They aren't used anywhere, so just pretend the commit has no parents.
def parent_ids
[]
end
end
...@@ -34,6 +34,8 @@ class MergeRequest < ApplicationRecord ...@@ -34,6 +34,8 @@ class MergeRequest < ApplicationRecord
has_internal_id :iid, scope: :target_project, track_if: -> { !importing? }, init: ->(s) { s&.target_project&.merge_requests&.maximum(:iid) } has_internal_id :iid, scope: :target_project, track_if: -> { !importing? }, init: ->(s) { s&.target_project&.merge_requests&.maximum(:iid) }
has_many :merge_request_diffs has_many :merge_request_diffs
has_many :merge_request_context_commits
has_many :merge_request_context_commit_diff_files, through: :merge_request_context_commits, source: :diff_files
has_many :merge_request_milestones has_many :merge_request_milestones
has_many :milestones, through: :merge_request_milestones has_many :milestones, through: :merge_request_milestones
...@@ -399,6 +401,10 @@ def to_reference(from = nil, full: false) ...@@ -399,6 +401,10 @@ def to_reference(from = nil, full: false)
"#{project.to_reference_base(from, full: full)}#{reference}" "#{project.to_reference_base(from, full: full)}#{reference}"
end end
def context_commits
@context_commits ||= merge_request_context_commits.map(&:to_commit)
end
def commits(limit: nil) def commits(limit: nil)
return merge_request_diff.commits(limit: limit) if persisted? return merge_request_diff.commits(limit: limit) if persisted?
......
# frozen_string_literal: true
class MergeRequestContextCommit < ApplicationRecord
include CachedCommit
include ShaAttribute
belongs_to :merge_request
has_many :diff_files, class_name: 'MergeRequestContextCommitDiffFile'
sha_attribute :sha
validates :sha, presence: true
validates :sha, uniqueness: { message: 'has already been added' }
# delete all MergeRequestContextCommit & MergeRequestContextCommitDiffFile for given merge_request & commit SHAs
def self.delete_bulk(merge_request, commits)
commit_ids = commits.map(&:sha)
merge_request.merge_request_context_commits.where(sha: commit_ids).delete_all
end
# create MergeRequestContextCommit by given commit sha and it's diff file record
def self.bulk_insert(*args)
Gitlab::Database.bulk_insert('merge_request_context_commits', *args)
end
def to_commit
# Here we are storing the commit sha because to_hash removes the sha parameter and we lose
# the reference, this happens because we are storing the ID in db and the Commit class replaces
# id with sha and removes it, so in our case it will be some incremented integer which is not
# what we want
commit_hash = attributes.except('id').to_hash
commit_hash['id'] = sha
Commit.from_hash(commit_hash, merge_request.target_project)
end
end
# frozen_string_literal: true
class MergeRequestContextCommitDiffFile < ApplicationRecord
include Gitlab::EncodingHelper
include ShaAttribute
include DiffFile
belongs_to :merge_request_context_commit, inverse_of: :diff_files
sha_attribute :sha
alias_attribute :id, :sha
# create MergeRequestContextCommitDiffFile by given diff file record(s)
def self.bulk_insert(*args)
Gitlab::Database.bulk_insert('merge_request_context_commit_diff_files', *args)
end
end
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment