Skip to content
Snippets Groups Projects
Commit ced0b445 authored by Kamil Trzcińśki's avatar Kamil Trzcińśki
Browse files

Merge branch 'master' into 'backstage/gb/use-persisted-stages-to-improve-pipelines-table'

# Conflicts:
#   db/schema.rb
parents da246582 1fc6935e
No related branches found
No related tags found
No related merge requests found
Showing
with 121 additions and 120 deletions
Loading
Loading
@@ -349,7 +349,7 @@ on those issues. Please select someone with relevant experience from the
[GitLab team][team]. If there is nobody mentioned with that expertise look in
the commit history for the affected files to find someone.
 
[described in our handbook]: https://about.gitlab.com/handbook/engineering/issues/issue-triage-policies/
[described in our handbook]: https://about.gitlab.com/handbook/engineering/issue-triage/
[issue bash events]: https://gitlab.com/gitlab-org/gitlab-ce/issues/17815
 
### Feature proposals
Loading
Loading
Loading
Loading
@@ -168,6 +168,7 @@ the stable branch are:
 
* Fixes for [regressions](#regressions)
* Fixes for security issues
* Fixes or improvements to automated QA scenarios
* New or updated translations (as long as they do not touch application code)
 
During the feature freeze all merge requests that are meant to go into the
Loading
Loading
Loading
Loading
@@ -126,5 +126,5 @@ Please see [Getting help for GitLab](https://about.gitlab.com/getting-help/) on
 
## Is it awesome?
 
Thanks for [asking this question](https://twitter.com/supersloth/status/489462789384056832) Joshua.
[These people](https://twitter.com/gitlab/likes) seem to like it.
Loading
Loading
@@ -265,10 +265,10 @@ export default {
/>
 
<section
v-if="mr.maintainerEditAllowed"
v-if="mr.allowCollaboration"
class="mr-info-list mr-links"
>
{{ s__("mrWidget|Allows edits from maintainers") }}
{{ s__("mrWidget|Allows commits from members who can merge to the target branch") }}
</section>
 
<mr-widget-related-links
Loading
Loading
Loading
Loading
@@ -83,7 +83,7 @@ export default class MergeRequestStore {
this.canBeMerged = data.can_be_merged || false;
this.isMergeAllowed = data.mergeable || false;
this.mergeOngoing = data.merge_ongoing;
this.maintainerEditAllowed = data.allow_maintainer_to_push;
this.allowCollaboration = data.allow_collaboration;
 
// Cherry-pick and Revert actions related
this.canCherryPickInCurrentMR = currentUser.can_cherry_pick_on_current_merge_request || false;
Loading
Loading
Loading
Loading
@@ -124,15 +124,18 @@
break;
}
},
hideOnSmallScreen(item) {
return !item.first && !item.last && !item.next && !item.prev && !item.active;
},
},
};
</script>
<template>
<div
v-if="showPagination"
class="gl-pagination"
class="gl-pagination prepend-top-default"
>
<ul class="pagination clearfix">
<ul class="pagination justify-content-center">
<li
v-for="(item, index) in getItems"
:key="index"
Loading
Loading
@@ -142,12 +145,17 @@
'js-next-button': item.next,
'js-last-button': item.last,
'js-first-button': item.first,
'd-none d-md-block': hideOnSmallScreen(item),
separator: item.separator,
active: item.active,
disabled: item.disabled
disabled: item.disabled || item.separator
}"
class="page-item"
>
<a @click.prevent="changePage(item.title, item.disabled)">
<a
@click.prevent="changePage(item.title, item.disabled)"
class="page-link"
>
{{ item.title }}
</a>
</li>
Loading
Loading
Loading
Loading
@@ -24,6 +24,11 @@ html {
font-size: 14px;
}
 
legend {
border-bottom: 1px solid $border-color;
margin-bottom: 20px;
}
button,
html [type="button"],
[type="reset"],
Loading
Loading
@@ -183,7 +188,9 @@ table {
 
.nav-tabs {
.nav-link {
border: 0;
border-top: 0;
border-left: 0;
border-right: 0;
}
 
.nav-item {
Loading
Loading
Loading
Loading
@@ -115,9 +115,3 @@ body {
.with-performance-bar .layout-page {
margin-top: $header-height + $performance-bar-height;
}
.vertical-center {
min-height: 100vh;
display: flex;
align-items: center;
}
.gl-pagination {
text-align: center;
border-top: 1px solid $border-color;
margin: 0;
margin-top: 0;
.pagination {
padding: 0;
margin: 20px 0;
a {
cursor: pointer;
}
.separator,
.separator:hover {
a {
cursor: default;
background-color: $gray-light;
padding: $gl-vert-padding;
}
}
}
.gap,
.gap:hover {
background-color: $gray-light;
padding: $gl-vert-padding;
cursor: default;
}
}
.card > .gl-pagination {
margin: 0;
}
/**
* Extra-small screen pagination.
*/
@media (max-width: 320px) {
.gl-pagination {
.first,
.last {
display: none;
}
.page-item {
display: none;
&.active {
display: inline;
}
}
}
}
/**
* Small screen pagination
*/
@include media-breakpoint-down(xs) {
.gl-pagination {
.pagination li a {
padding: 6px 10px;
}
.page-item {
display: none;
&.active {
display: inline;
}
}
}
}
/**
* Medium screen pagination
*/
@media (min-width: map-get($grid-breakpoints, xs)) and (max-width: map-get($grid-breakpoints, sm)) {
.gl-pagination {
.page-item {
display: none;
&.active,
&.sibling {
display: inline;
}
}
a {
color: inherit;
text-decoration: none;
}
}
Loading
Loading
@@ -485,6 +485,15 @@
.sidebar-collapsed-user {
padding-bottom: 0;
margin-bottom: 10px;
.author_link {
padding-left: 0;
.avatar {
position: static;
margin: 0;
}
}
}
 
.issuable-header-btn {
Loading
Loading
Loading
Loading
@@ -130,12 +130,17 @@ class ApplicationController < ActionController::Base
end
 
def access_denied!(message = nil)
# If we display a custom access denied message to the user, we don't want to
# hide existence of the resource, rather tell them they cannot access it using
# the provided message
status = message.present? ? :forbidden : :not_found
respond_to do |format|
format.any { head :not_found }
format.any { head status }
format.html do
render "errors/access_denied",
layout: "errors",
status: 404,
status: status,
locals: { message: message }
end
end
Loading
Loading
Loading
Loading
@@ -15,7 +15,7 @@ class Projects::MergeRequests::ApplicationController < Projects::ApplicationCont
 
def merge_request_params_attributes
[
:allow_maintainer_to_push,
:allow_collaboration,
:assignee_id,
:description,
:force_remove_source_branch,
Loading
Loading
Loading
Loading
@@ -13,6 +13,10 @@ module Users
 
def index
@redirect = redirect_path
if @term.accepted_by_user?(current_user)
flash.now[:notice] = "You have already accepted the Terms of Service as #{current_user.to_reference}"
end
end
 
def accept
Loading
Loading
Loading
Loading
@@ -126,8 +126,8 @@ module MergeRequestsHelper
link_to(url[merge_request.project, merge_request], data: data_attrs, &block)
end
 
def allow_maintainer_push_unavailable_reason(merge_request)
return if merge_request.can_allow_maintainer_to_push?(current_user)
def allow_collaboration_unavailable_reason(merge_request)
return if merge_request.can_allow_collaboration?(current_user)
 
minimum_visibility = [merge_request.target_project.visibility_level,
merge_request.source_project.visibility_level].min
Loading
Loading
Loading
Loading
@@ -412,7 +412,10 @@ module ProjectsHelper
exports_path = File.join(Settings.shared['path'], 'tmp/project_exports')
filtered_message = message.strip.gsub(exports_path, "[REPO EXPORT PATH]")
 
disk_path = Gitlab.config.repositories.storages[project.repository_storage].legacy_disk_path
disk_path = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
Gitlab.config.repositories.storages[project.repository_storage].legacy_disk_path
end
filtered_message.gsub(disk_path.chomp('/'), "[REPOS PATH]")
end
 
Loading
Loading
class ApplicationSetting
class Term < ActiveRecord::Base
include CacheMarkdownField
has_many :term_agreements
 
validates :terms, presence: true
 
Loading
Loading
@@ -9,5 +10,10 @@ class ApplicationSetting
def self.latest
order(:id).last
end
def accepted_by_user?(user)
user.accepted_term_id == id ||
term_agreements.accepted.where(user: user).exists?
end
end
end
Loading
Loading
@@ -219,10 +219,8 @@ module Ci
 
cache_attributes(values)
 
if persist_cached_data?
self.assign_attributes(values)
self.save if self.changed?
end
# We save data without validation, it will always change due to `contacted_at`
self.update_columns(values) if persist_cached_data?
end
 
def pick_build!(build)
Loading
Loading
Loading
Loading
@@ -4,11 +4,14 @@ module Avatarable
included do
prepend ShadowMethods
include ObjectStorage::BackgroundMove
include Gitlab::Utils::StrongMemoize
 
validate :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? }
validates :avatar, file_size: { maximum: 200.kilobytes.to_i }
 
mount_uploader :avatar, AvatarUploader
after_initialize :add_avatar_to_batch
end
 
module ShadowMethods
Loading
Loading
@@ -18,6 +21,17 @@ module Avatarable
 
avatar_path(only_path: args.fetch(:only_path, true)) || super
end
def retrieve_upload(identifier, paths)
upload = retrieve_upload_from_batch(identifier)
# This fallback is needed when deleting an upload, because we may have
# already been removed from the DB. We have to check an explicit `#nil?`
# because it's a BatchLoader instance.
upload = super if upload.nil?
upload
end
end
 
def avatar_type
Loading
Loading
@@ -52,4 +66,37 @@ module Avatarable
 
url_base + avatar.local_url
end
# Path that is persisted in the tracking Upload model. Used to fetch the
# upload from the model.
def upload_paths(identifier)
avatar_mounter.blank_uploader.store_dirs.map { |store, path| File.join(path, identifier) }
end
private
def retrieve_upload_from_batch(identifier)
BatchLoader.for(identifier: identifier, model: self).batch(key: self.class) do |upload_params, loader, args|
model_class = args[:key]
paths = upload_params.flat_map do |params|
params[:model].upload_paths(params[:identifier])
end
Upload.where(uploader: AvatarUploader, path: paths).find_each do |upload|
model = model_class.instantiate('id' => upload.model_id)
loader.call({ model: model, identifier: File.basename(upload.path) }, upload)
end
end
end
def add_avatar_to_batch
return unless avatar_mounter
avatar_mounter.read_identifiers.each { |identifier| retrieve_upload_from_batch(identifier) }
end
def avatar_mounter
strong_memoize(:avatar_mounter) { _mounter(:avatar) }
end
end
Loading
Loading
@@ -36,4 +36,8 @@ module WithUploads
upload.destroy
end
end
def retrieve_upload(_identifier, paths)
uploads.find_by(path: paths)
end
end
Loading
Loading
@@ -1125,21 +1125,21 @@ class MergeRequest < ActiveRecord::Base
project.merge_requests.merged.where(author_id: author_id).empty?
end
 
def allow_maintainer_to_push
maintainer_push_possible? && super
def allow_collaboration
collaborative_push_possible? && super
end
 
alias_method :allow_maintainer_to_push?, :allow_maintainer_to_push
alias_method :allow_collaboration?, :allow_collaboration
 
def maintainer_push_possible?
def collaborative_push_possible?
source_project.present? && for_fork? &&
target_project.visibility_level > Gitlab::VisibilityLevel::PRIVATE &&
source_project.visibility_level > Gitlab::VisibilityLevel::PRIVATE &&
!ProtectedBranch.protected?(source_project, source_branch)
end
 
def can_allow_maintainer_to_push?(user)
maintainer_push_possible? &&
def can_allow_collaboration?(user)
collaborative_push_possible? &&
Ability.allowed?(user, :push_code, source_project)
end
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment