Skip to content
Snippets Groups Projects
Commit cbfe03ae authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 3fd97b4b
No related branches found
No related tags found
No related merge requests found
Showing
with 153 additions and 96 deletions
Loading
Loading
@@ -74,17 +74,12 @@
 
// Middle dot divider between each element in a list of items.
.middle-dot-divider {
&::after {
content: '\00B7'; // Middle Dot
padding: 0 6px;
font-weight: $gl-font-weight-bold;
}
@include middle-dot-divider;
}
 
&:last-child {
&::after {
content: '';
padding: 0;
}
.middle-dot-divider-sm {
@include media-breakpoint-up(sm) {
@include middle-dot-divider;
}
}
 
Loading
Loading
@@ -202,10 +197,6 @@
}
 
.user-profile {
.cover-controls a {
margin-left: 5px;
}
.profile-header {
margin: 0 $gl-padding;
 
Loading
Loading
Loading
Loading
@@ -12,11 +12,7 @@ class Projects::Tags::ReleasesController < Projects::ApplicationController
end
 
def update
if release_params[:description].present?
release.update(release_params)
else
release.destroy
end
release.update(release_params) if release.persisted? || release_params[:description].present?
 
redirect_to project_tag_path(@project, tag.name)
end
Loading
Loading
Loading
Loading
@@ -66,7 +66,7 @@ module SubmoduleHelper
project].join('')
 
url_with_dotgit = url_no_dotgit + '.git'
url_with_dotgit == Gitlab::Shell.new.url_to_repo([namespace, '/', project].join(''))
url_with_dotgit == Gitlab::Shell.url_to_repo([namespace, '/', project].join(''))
end
 
def relative_self_url?(url)
Loading
Loading
Loading
Loading
@@ -91,6 +91,21 @@ module UsersHelper
end
end
 
def work_information(user)
return unless user
organization = user.organization
job_title = user.job_title
if organization.present? && job_title.present?
s_('Profile|%{job_title} at %{organization}') % { job_title: job_title, organization: organization }
elsif job_title.present?
job_title
elsif organization.present?
organization
end
end
private
 
def get_profile_tabs
Loading
Loading
Loading
Loading
@@ -61,12 +61,13 @@ module BulkInsertSafe
super
end
 
# Inserts the given ActiveRecord [items] to the table mapped to this class via [InsertAll].
# Inserts the given ActiveRecord [items] to the table mapped to this class.
# Items will be inserted in batches of a given size, where insertion semantics are
# "atomic across all batches", i.e. either all items will be inserted or none.
# "atomic across all batches".
#
# @param [Boolean] validate Whether validations should run on [items]
# @param [Integer] batch_size How many items should at most be inserted at once
# @param [Boolean] skip_duplicates Marks duplicates as allowed, and skips inserting them
# @param [Proc] handle_attributes Block that will receive each item attribute hash
# prior to insertion for further processing
#
Loading
Loading
@@ -75,26 +76,65 @@ module BulkInsertSafe
# - [ActiveRecord::RecordInvalid] on entity validation failures
# - [ActiveRecord::RecordNotUnique] on duplicate key errors
#
# @return true if all items succeeded to be inserted, throws otherwise.
# @return true if operation succeeded, throws otherwise.
#
def bulk_insert!(items, validate: true, batch_size: DEFAULT_BATCH_SIZE, &handle_attributes)
return true if items.empty?
_bulk_insert_in_batches(items, batch_size, validate, &handle_attributes)
def bulk_insert!(items, validate: true, skip_duplicates: false, batch_size: DEFAULT_BATCH_SIZE, &handle_attributes)
_bulk_insert_all!(items,
validate: validate,
on_duplicate: skip_duplicates ? :skip : :raise,
unique_by: nil,
batch_size: batch_size,
&handle_attributes)
end
 
true
# Upserts the given ActiveRecord [items] to the table mapped to this class.
# Items will be inserted or updated in batches of a given size,
# where insertion semantics are "atomic across all batches".
#
# @param [Boolean] validate Whether validations should run on [items]
# @param [Integer] batch_size How many items should at most be inserted at once
# @param [Symbol/Array] unique_by Defines index or columns to use to consider item duplicate
# @param [Proc] handle_attributes Block that will receive each item attribute hash
# prior to insertion for further processing
#
# Unique indexes can be identified by columns or name:
# - unique_by: :isbn
# - unique_by: %i[ author_id name ]
# - unique_by: :index_books_on_isbn
#
# Note that this method will throw on the following occasions:
# - [PrimaryKeySetError] when primary keys are set on entities prior to insertion
# - [ActiveRecord::RecordInvalid] on entity validation failures
# - [ActiveRecord::RecordNotUnique] on duplicate key errors
#
# @return true if operation succeeded, throws otherwise.
#
def bulk_upsert!(items, unique_by:, validate: true, batch_size: DEFAULT_BATCH_SIZE, &handle_attributes)
_bulk_insert_all!(items,
validate: validate,
on_duplicate: :update,
unique_by: unique_by,
batch_size: batch_size,
&handle_attributes)
end
 
private
 
def _bulk_insert_in_batches(items, batch_size, validate_items, &handle_attributes)
def _bulk_insert_all!(items, on_duplicate:, unique_by:, validate:, batch_size:, &handle_attributes)
return true if items.empty?
transaction do
items.each_slice(batch_size) do |item_batch|
attributes = _bulk_insert_item_attributes(item_batch, validate_items, &handle_attributes)
attributes = _bulk_insert_item_attributes(
item_batch, validate, &handle_attributes)
 
insert_all!(attributes)
ActiveRecord::InsertAll
.new(self, attributes, on_duplicate: on_duplicate, unique_by: unique_by)
.execute
end
end
true
end
 
def _bulk_insert_item_attributes(items, validate_items)
Loading
Loading
Loading
Loading
@@ -9,7 +9,6 @@
# needs any special behavior.
module HasRepository
extend ActiveSupport::Concern
include Gitlab::ShellAdapter
include AfterCommitQueue
include Referable
include Gitlab::Utils::StrongMemoize
Loading
Loading
@@ -78,7 +77,7 @@ module HasRepository
end
 
def url_to_repo
gitlab_shell.url_to_repo(full_path)
Gitlab::Shell.url_to_repo(full_path)
end
 
def ssh_url_to_repo
Loading
Loading
Loading
Loading
@@ -1460,13 +1460,14 @@ class Project < ApplicationRecord
# Forked import is handled asynchronously
return if forked? && !force
 
if gitlab_shell.create_project_repository(self)
repository.after_create
true
else
errors.add(:base, _('Failed to create repository via gitlab-shell'))
false
end
repository.create_repository
repository.after_create
true
rescue => err
Gitlab::ErrorTracking.track_exception(err, project: { id: id, full_path: full_path, disk_path: disk_path })
errors.add(:base, _('Failed to create repository'))
false
end
 
def hook_attrs(backward: true)
Loading
Loading
# frozen_string_literal: true
 
class ProjectWiki
include Gitlab::ShellAdapter
include Storage::LegacyProjectWiki
include Gitlab::Utils::StrongMemoize
 
MARKUPS = {
'Markdown' => :markdown,
Loading
Loading
@@ -47,7 +47,7 @@ class ProjectWiki
end
 
def url_to_repo
gitlab_shell.url_to_repo(full_path)
Gitlab::Shell.url_to_repo(full_path)
end
 
def ssh_url_to_repo
Loading
Loading
@@ -64,14 +64,15 @@ class ProjectWiki
 
# Returns the Gitlab::Git::Wiki object.
def wiki
@wiki ||= begin
gl_repository = Gitlab::GlRepository::WIKI.identifier_for_container(project)
raw_repository = Gitlab::Git::Repository.new(project.repository_storage, disk_path + '.git', gl_repository, full_path)
strong_memoize(:wiki) do
repository.create_if_not_exists
raise CouldNotCreateWikiError unless repository_exists?
 
create_repo!(raw_repository) unless raw_repository.exists?
Gitlab::Git::Wiki.new(raw_repository)
Gitlab::Git::Wiki.new(repository.raw)
end
rescue => err
Gitlab::ErrorTracking.track_exception(err, project_wiki: { project_id: project.id, full_path: full_path, disk_path: disk_path })
raise CouldNotCreateWikiError
end
 
def repository_exists?
Loading
Loading
@@ -193,14 +194,6 @@ class ProjectWiki
 
private
 
def create_repo!(raw_repository)
gitlab_shell.create_wiki_repository(project)
raise CouldNotCreateWikiError unless raw_repository.exists?
repository.after_create
end
def commit_details(action, message = nil, title = nil)
commit_message = message.presence || default_message(action, title)
git_user = Gitlab::Git::User.from_gitlab(@user)
Loading
Loading
Loading
Loading
@@ -24,7 +24,7 @@ class Release < ApplicationRecord
 
accepts_nested_attributes_for :links, allow_destroy: true
 
validates :description, :project, :tag, presence: true
validates :project, :tag, presence: true
validates_associated :milestone_releases, message: -> (_, obj) { obj[:value].map(&:errors).map(&:full_messages).join(",") }
 
scope :sorted, -> { order(released_at: :desc) }
Loading
Loading
Loading
Loading
@@ -22,7 +22,7 @@ module Ci
begin
retry_optimistic_lock(ref) do
next false if ref.persisted? &&
(ref.last_updated_by_pipeline_id || 0) >= pipeline.id
(ref.last_updated_by_pipeline_id || 0) > pipeline.id
 
ref.update(status: next_status(ref.status, pipeline.status),
last_updated_by_pipeline: pipeline)
Loading
Loading
Loading
Loading
@@ -52,11 +52,14 @@ module Projects
checksum = repository.checksum
 
# Initialize a git repository on the target path
gitlab_shell.create_repository(new_storage_key, raw_repository.relative_path, full_path)
new_repository = Gitlab::Git::Repository.new(new_storage_key,
raw_repository.relative_path,
raw_repository.gl_repository,
full_path)
new_repository = Gitlab::Git::Repository.new(
new_storage_key,
raw_repository.relative_path,
raw_repository.gl_repository,
full_path
)
new_repository.create_repository
 
new_repository.replicate(raw_repository)
new_checksum = new_repository.checksum
Loading
Loading
Loading
Loading
@@ -99,7 +99,7 @@
%p
GitLab Shell
%span.float-right
= Gitlab::Shell.new.version
= Gitlab::Shell.version
%p
GitLab Workhorse
%span.float-right
Loading
Loading
- page_title "UI Development Kit", "Help"
- lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed fermentum nisi sapien, non consequat lectus aliquam ultrices. Suspendisse sodales est euismod nunc condimentum, a consectetur diam ornare."
- link_classes = "flex-grow-1 mx-1 "
 
.gitlab-ui-dev-kit
%h1 GitLab UI development kit
Loading
Loading
@@ -64,7 +65,12 @@
Cover block for profile page with avatar, name and description
%code .cover-block
.example
.cover-block
.cover-block.user-cover-block
= render layout: 'users/cover_controls' do
= link_to '#', class: link_classes + 'btn btn-default' do
= icon('pencil')
= link_to '#', class: link_classes + 'btn btn-default' do
= icon('rss')
.avatar-holder
= image_tag avatar_icon_for_email('admin@example.com', 90), class: "avatar s90", alt: ''
.cover-title
Loading
Loading
@@ -73,13 +79,6 @@
.cover-desc.cgray
= lorem
 
.cover-controls
= link_to '#', class: 'btn btn-default' do
= icon('pencil')
&nbsp;
= link_to '#', class: 'btn btn-default' do
= icon('rss')
%h2#lists Lists
 
.lead
Loading
Loading
Loading
Loading
@@ -90,7 +90,6 @@
.row
= render 'profiles/name', form: f, user: @user
= f.text_field :id, readonly: true, label: s_('Profiles|User ID'), wrapper: { class: 'col-md-3' }
= f.select :role, ::User.roles.keys.map { |role| [role.titleize, role] }, { prompt: _('Select your role') }, required: true, class: 'input-md'
 
= render_if_exists 'profiles/email_settings', form: f
= f.text_field :skype, class: 'input-md', placeholder: s_("Profiles|username")
Loading
Loading
@@ -101,6 +100,7 @@
= f.text_field :location, readonly: true, help: s_("Profiles|Your location was automatically set based on your %{provider_label} account") % { provider_label: attribute_provider_label(:location) }
- else
= f.text_field :location, label: s_('Profiles|Location'), class: 'input-lg', placeholder: s_("Profiles|City, country")
= f.text_field :job_title, class: 'input-md'
= f.text_field :organization, label: s_('Profiles|Organization'), class: 'input-md', help: s_("Profiles|Who you represent or work for")
= f.text_area :bio, label: s_('Profiles|Bio'), rows: 4, maxlength: 250, help: s_("Profiles|Tell us about yourself in fewer than 250 characters")
%hr
Loading
Loading
.cover-controls.d-flex.px-2.pb-4.d-sm-block.p-sm-0
= yield
%p
%p.mb-1.mb-sm-2.mt-2.mt-sm-3
%span.middle-dot-divider
@#{@user.username}
- if can?(current_user, :read_user_profile, @user)
Loading
Loading
Loading
Loading
@@ -4,30 +4,31 @@
- page_title @user.blocked? ? s_('UserProfile|Blocked user') : @user.name
- page_description @user.bio
- header_title @user.name, user_path(@user)
- link_classes = "flex-grow-1 mx-1 "
 
= content_for :meta_tags do
= auto_discovery_link_tag(:atom, user_url(@user, format: :atom), title: "#{@user.name} activity")
 
.user-profile
.cover-block.user-cover-block{ class: [('border-bottom' if profile_tabs.empty?)] }
.cover-controls
= render layout: 'users/cover_controls' do
- if @user == current_user
= link_to profile_path, class: 'btn btn-default has-tooltip', title: s_('UserProfile|Edit profile'), 'aria-label': 'Edit profile' do
= link_to profile_path, class: link_classes + 'btn btn-default has-tooltip', title: s_('UserProfile|Edit profile'), 'aria-label': 'Edit profile' do
= icon('pencil')
- elsif current_user
- if @user.abuse_report
%button.btn.btn-danger{ title: s_('UserProfile|Already reported for abuse'),
%button{ class: link_classes + 'btn btn-danger mr-1', title: s_('UserProfile|Already reported for abuse'),
data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } }
= icon('exclamation-circle')
- else
= link_to new_abuse_report_path(user_id: @user.id, ref_url: request.referrer), class: 'btn',
= link_to new_abuse_report_path(user_id: @user.id, ref_url: request.referrer), class: link_classes + 'btn',
title: s_('UserProfile|Report abuse'), data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
= icon('exclamation-circle')
- if can?(current_user, :read_user_profile, @user)
= link_to user_path(@user, rss_url_options), class: 'btn btn-default has-tooltip', title: s_('UserProfile|Subscribe'), 'aria-label': 'Subscribe' do
= link_to user_path(@user, rss_url_options), class: link_classes + 'btn btn-default has-tooltip', title: s_('UserProfile|Subscribe'), 'aria-label': 'Subscribe' do
= icon('rss')
- if current_user && current_user.admin?
= link_to [:admin, @user], class: 'btn btn-default', title: s_('UserProfile|View user in admin area'),
= link_to [:admin, @user], class: link_classes + 'btn btn-default', title: s_('UserProfile|View user in admin area'),
data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('users')
 
Loading
Loading
@@ -51,10 +52,18 @@
= emoji_icon(@user.status.emoji)
= markdown_field(@user.status, :message)
= render "users/profile_basic_info"
.cover-desc.cgray
- unless @user.public_email.blank?
.profile-link-holder.middle-dot-divider
= link_to @user.public_email, "mailto:#{@user.public_email}", class: 'text-link'
.cover-desc.cgray.mb-1.mb-sm-2
- unless @user.location.blank?
.profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mb-1.mb-sm-0
= sprite_icon('location', size: 16, css_class: 'vertical-align-sub fgray')
%span.vertical-align-middle
= @user.location
- unless work_information(@user).blank?
.profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline
= sprite_icon('work', size: 16, css_class: 'vertical-align-middle fgray')
%span.vertical-align-middle
= work_information(@user)
.cover-desc.cgray.mb-1.mb-sm-2
- unless @user.skype.blank?
.profile-link-holder.middle-dot-divider
= link_to "skype:#{@user.skype}", title: "Skype" do
Loading
Loading
@@ -64,24 +73,18 @@
= link_to linkedin_url(@user), title: "LinkedIn", target: '_blank', rel: 'noopener noreferrer nofollow' do
= icon('linkedin-square')
- unless @user.twitter.blank?
.profile-link-holder.middle-dot-divider
.profile-link-holder.middle-dot-divider-sm
= link_to twitter_url(@user), title: "Twitter", target: '_blank', rel: 'noopener noreferrer nofollow' do
= icon('twitter-square')
- unless @user.website_url.blank?
.profile-link-holder.middle-dot-divider
.profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mt-1.mt-sm-0
= link_to @user.short_website_url, @user.full_website_url, class: 'text-link', target: '_blank', rel: 'me noopener noreferrer nofollow'
- unless @user.location.blank?
.profile-link-holder.middle-dot-divider
= sprite_icon('location', size: 16, css_class: 'vertical-align-sub')
= @user.location
- unless @user.organization.blank?
.profile-link-holder.middle-dot-divider
= sprite_icon('work', size: 16, css_class: 'vertical-align-sub')
= @user.organization
- unless @user.public_email.blank?
.profile-link-holder.middle-dot-divider-sm.d-block.d-sm-inline.mt-1.mt-sm-0
= link_to @user.public_email, "mailto:#{@user.public_email}", class: 'text-link'
- if @user.bio.present?
.cover-desc.cgray
%p.profile-user-bio
%p.profile-user-bio.font-italic
= @user.bio
 
- unless profile_tabs.empty?
Loading
Loading
---
title: Add CI template to deploy to ECS
merge_request: 26371
author:
type: added
---
title: Optimize Project related count with slack service
merge_request: 26686
author:
type: performance
---
title: Correctly send notification on pipeline retry
merge_request: 26803
author: Jacopo Beschi @jacopo-beschi
type: fixed
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