summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-05-24 09:10:31 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-05-24 09:10:31 +0000
commit0a35aa97051a1255e0bd8f12f30afd25ead228ff (patch)
tree90bdfdd0d28f19d844c11c92945ab67346866045 /app
parentf6df57b3011cb21c504878daf5d7b6678e07078a (diff)
downloadgitlab-ce-0a35aa97051a1255e0bd8f12f30afd25ead228ff.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/locale/sprintf.js6
-rw-r--r--app/assets/stylesheets/framework.scss2
-rw-r--r--app/assets/stylesheets/framework/contextual_sidebar.scss (renamed from app/assets/stylesheets/framework/contextual_sidebar_refactoring/contextual_sidebar_base.scss)4
-rw-r--r--app/assets/stylesheets/framework/contextual_sidebar_refactoring/contextual_sidebar.scss7
-rw-r--r--app/assets/stylesheets/framework/contextual_sidebar_refactoring/contextual_sidebar_variant.scss383
-rw-r--r--app/assets/stylesheets/performance_bar.scss4
-rw-r--r--app/helpers/nav/top_nav_helper.rb7
-rw-r--r--app/helpers/nav_helper.rb1
-rw-r--r--app/models/concerns/packages/debian/component_file.rb4
-rw-r--r--app/services/packages/debian/generate_distribution_service.rb53
-rw-r--r--app/services/packages/debian/process_changes_service.rb2
-rw-r--r--app/views/layouts/_startup_css.haml3
-rw-r--r--app/views/layouts/application.html.haml4
-rw-r--r--app/views/shared/members/_invite_group.html.haml2
-rw-r--r--app/workers/all_queues.yml9
-rw-r--r--app/workers/packages/debian/generate_distribution_worker.rb44
16 files changed, 115 insertions, 420 deletions
diff --git a/app/assets/javascripts/locale/sprintf.js b/app/assets/javascripts/locale/sprintf.js
index 82fc816fe9e..e1749331d90 100644
--- a/app/assets/javascripts/locale/sprintf.js
+++ b/app/assets/javascripts/locale/sprintf.js
@@ -15,8 +15,10 @@ export default (input, parameters, escapeParameters = true) => {
let output = input;
if (parameters) {
- Object.keys(parameters).forEach((parameterName) => {
- const parameterValue = parameters[parameterName];
+ const mappedParameters = new Map(Object.entries(parameters));
+
+ mappedParameters.forEach((key, parameterName) => {
+ const parameterValue = mappedParameters.get(parameterName);
const escapedParameterValue = escapeParameters ? escape(parameterValue) : parameterValue;
output = output.replace(new RegExp(`%{${parameterName}}`, 'g'), escapedParameterValue);
});
diff --git a/app/assets/stylesheets/framework.scss b/app/assets/stylesheets/framework.scss
index 603747aa490..3126c690514 100644
--- a/app/assets/stylesheets/framework.scss
+++ b/app/assets/stylesheets/framework.scss
@@ -39,7 +39,7 @@
@import 'framework/selects';
@import 'framework/sidebar';
@import 'framework/contextual_sidebar_header';
-@import 'framework/contextual_sidebar_refactoring/contextual_sidebar';
+@import 'framework/contextual_sidebar';
@import 'framework/tables';
@import 'framework/notes';
@import 'framework/tabs';
diff --git a/app/assets/stylesheets/framework/contextual_sidebar_refactoring/contextual_sidebar_base.scss b/app/assets/stylesheets/framework/contextual_sidebar.scss
index 3d9b555c8d5..6299d4b236f 100644
--- a/app/assets/stylesheets/framework/contextual_sidebar_refactoring/contextual_sidebar_base.scss
+++ b/app/assets/stylesheets/framework/contextual_sidebar.scss
@@ -175,6 +175,10 @@
overflow: auto;
}
+.with-performance-bar .nav-sidebar {
+ top: $header-height + $performance-bar-height;
+}
+
.sidebar-sub-level-items {
display: none;
padding-bottom: 8px;
diff --git a/app/assets/stylesheets/framework/contextual_sidebar_refactoring/contextual_sidebar.scss b/app/assets/stylesheets/framework/contextual_sidebar_refactoring/contextual_sidebar.scss
deleted file mode 100644
index 905ac260203..00000000000
--- a/app/assets/stylesheets/framework/contextual_sidebar_refactoring/contextual_sidebar.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-body:not(.sidebar-refactoring) {
- @import 'contextual_sidebar_base';
-}
-
-body.sidebar-refactoring {
- @import 'contextual_sidebar_variant';
-}
diff --git a/app/assets/stylesheets/framework/contextual_sidebar_refactoring/contextual_sidebar_variant.scss b/app/assets/stylesheets/framework/contextual_sidebar_refactoring/contextual_sidebar_variant.scss
deleted file mode 100644
index 03e92a27f75..00000000000
--- a/app/assets/stylesheets/framework/contextual_sidebar_refactoring/contextual_sidebar_variant.scss
+++ /dev/null
@@ -1,383 +0,0 @@
-.page-with-contextual-sidebar {
- transition: padding-left $sidebar-transition-duration;
-
- @include media-breakpoint-up(md) {
- padding-left: $contextual-sidebar-collapsed-width;
- }
-
- @include media-breakpoint-up(xl) {
- padding-left: $contextual-sidebar-width;
- }
-
- .issues-bulk-update.right-sidebar.right-sidebar-expanded .issuable-sidebar-header {
- padding: 10px 0 15px;
- }
-}
-
-.page-with-icon-sidebar {
- @include media-breakpoint-up(md) {
- padding-left: $contextual-sidebar-collapsed-width;
- }
-}
-
-.settings-avatar {
- background-color: $white;
-
- svg {
- fill: $gl-text-color-secondary;
- margin: auto;
- }
-}
-
-@mixin collapse-contextual-sidebar-content {
-
- @include context-header-collapsed;
-
- .sidebar-top-level-items > li {
- .sidebar-sub-level-items {
- &:not(.flyout-list) {
- display: none;
- }
- }
- }
-
- .nav-icon-container {
- margin-right: 0;
- }
-
- .toggle-sidebar-button {
- padding: 16px;
- width: $contextual-sidebar-collapsed-width - 1px;
-
- .collapse-text,
- .icon-chevron-double-lg-left {
- display: none;
- }
-
- .icon-chevron-double-lg-right {
- display: block;
- margin: 0;
- }
- }
-}
-
-.nav-sidebar {
- transition: width $sidebar-transition-duration, left $sidebar-transition-duration;
- position: fixed;
- z-index: 600;
- width: $contextual-sidebar-width;
- top: $header-height;
- bottom: 0;
- left: 0;
- background: linear-gradient($purple-200, $orange-200);
- box-shadow: inset -1px 0 0 $border-color;
- transform: translate3d(0, 0, 0);
-
- &:not(.sidebar-collapsed-desktop) {
- @media (min-width: map-get($grid-breakpoints, sm)) and (max-width: map-get($grid-breakpoints, sm)) {
- box-shadow: inset -1px 0 0 $border-color, 2px 1px 3px $dropdown-shadow-color;
- }
- }
-
- @mixin collapse-contextual-sidebar {
- width: $contextual-sidebar-collapsed-width;
-
- .nav-sidebar-inner-scroll {
- overflow-x: hidden;
- }
-
- .badge.badge-pill:not(.fly-out-badge),
- .nav-item-name {
- @include gl-sr-only;
- }
-
- .sidebar-top-level-items > li > a {
- min-height: 45px;
- }
-
- .fly-out-top-item {
- display: block;
- }
-
- .avatar-container {
- margin: 0 auto;
- }
- }
-
- &.sidebar-collapsed-desktop {
- @include collapse-contextual-sidebar;
- }
-
- &.sidebar-expanded-mobile {
- left: 0;
- }
-
- a {
- text-decoration: none;
- }
-
- ul {
- padding-left: 0;
- list-style: none;
- }
-
- li {
- white-space: nowrap;
-
- a {
- transition: padding $sidebar-transition-duration;
- display: flex;
- align-items: center;
- padding: 12px $gl-padding;
- color: $gl-text-color-secondary;
- }
-
- .nav-item-name {
- flex: 1;
- }
-
- &.active {
- > a {
- font-weight: $gl-font-weight-bold;
- }
- }
- }
-
- @include media-breakpoint-down(sm) {
- left: (-$contextual-sidebar-width);
- }
-
- .nav-icon-container {
- display: flex;
- margin-right: 8px;
- }
-
- .fly-out-top-item {
- display: none;
- }
-
- svg {
- height: 16px;
- width: 16px;
- }
-
- @media (min-width: map-get($grid-breakpoints, md)) and (max-width: map-get($grid-breakpoints, xl) - 1px) {
- &:not(.sidebar-expanded-mobile) {
- @include collapse-contextual-sidebar;
- @include collapse-contextual-sidebar-content;
- }
- }
-}
-
-.nav-sidebar-inner-scroll {
- height: 100%;
- width: 100%;
- overflow: auto;
-}
-
-.sidebar-sub-level-items {
- display: none;
- padding-bottom: 8px;
-
- > li {
- a {
- padding: 8px 16px 8px 40px;
-
- &:hover,
- &:focus {
- background: $link-active-background;
- color: $gl-text-color;
- }
- }
-
- &.active {
- a {
- &,
- &:hover,
- &:focus {
- background: $link-active-background;
- }
- }
- }
- }
-}
-
-.sidebar-top-level-items {
- margin-bottom: 60px;
-
- > li {
- > a {
- @include media-breakpoint-up(sm) {
- margin-right: 1px;
- }
-
- &:hover {
- color: $gl-text-color;
- }
- }
-
- &.is-showing-fly-out {
- > a {
- margin-right: 1px;
- }
-
- .sidebar-sub-level-items {
- @include media-breakpoint-up(sm) {
- position: fixed;
- top: 0;
- left: 0;
- min-width: 150px;
- margin-top: -1px;
- padding: 4px 1px;
- background-color: $white;
- box-shadow: 2px 1px 3px $dropdown-shadow-color;
- border: 1px solid $gray-darker;
- border-left: 0;
- border-radius: 0 3px 3px 0;
-
- &::before {
- content: '';
- position: absolute;
- top: -30px;
- bottom: -30px;
- left: -10px;
- right: -30px;
- z-index: -1;
- }
-
- &.is-above {
- margin-top: 1px;
- }
-
- .divider {
- height: 1px;
- margin: 4px -1px;
- padding: 0;
- background-color: $dropdown-divider-bg;
- }
-
- > .active {
- box-shadow: none;
-
- > a {
- background-color: transparent;
- }
- }
-
- a {
- padding: 8px 16px;
- color: $gl-text-color;
-
- &:hover,
- &:focus {
- background-color: $gray-darker;
- }
- }
- }
- }
- }
-
- .badge.badge-pill {
- background-color: $inactive-badge-background;
- color: $gl-text-color-secondary;
- }
-
- &.active {
- background: $link-active-background;
-
- > a {
- margin-left: 4px;
- // Subtract width of left border on active element
- padding-left: $gl-padding-12;
- }
-
- .badge.badge-pill {
- font-weight: $gl-font-weight-bold;
- }
-
- .sidebar-sub-level-items:not(.is-fly-out-only) {
- display: block;
- }
- }
-
- &.active > a:hover,
- &.is-over > a {
- background-color: $link-hover-background;
- }
- }
-}
-
-// Collapsed nav
-
-.toggle-sidebar-button,
-.close-nav-button {
- @include side-panel-toggle;
-}
-
-.toggle-sidebar-button,
-.close-nav-button {
- position: fixed;
- bottom: 0;
- width: $contextual-sidebar-width - 1px;
- border-top: 1px solid $border-color;
-
- svg {
- margin-right: 8px;
- }
-
- .icon-chevron-double-lg-right {
- display: none;
- }
-}
-
-.collapse-text {
- white-space: nowrap;
- overflow: hidden;
-}
-
-.sidebar-collapsed-desktop {
- @include collapse-contextual-sidebar-content;
-}
-
-.fly-out-top-item {
- > a {
- display: flex;
- }
-
- .fly-out-badge {
- margin-left: 8px;
- }
-}
-
-.fly-out-top-item-name {
- flex: 1;
-}
-
-// Mobile nav
-
-.close-nav-button {
- display: none;
-}
-
-@include media-breakpoint-down(sm) {
- .close-nav-button {
- display: flex;
- }
-
- .toggle-sidebar-button {
- display: none;
- }
-
- .mobile-overlay {
- display: none;
-
- &.mobile-nav-open {
- display: block;
- position: fixed;
- background-color: $black-transparent;
- height: 100%;
- width: 100%;
- z-index: $zindex-dropdown-menu;
- }
- }
-}
diff --git a/app/assets/stylesheets/performance_bar.scss b/app/assets/stylesheets/performance_bar.scss
index 62736c7de5f..bcc3c35e00e 100644
--- a/app/assets/stylesheets/performance_bar.scss
+++ b/app/assets/stylesheets/performance_bar.scss
@@ -135,7 +135,3 @@
#modal-peek-pg-queries-content {
color: $black;
}
-
-.with-performance-bar .nav-sidebar {
- top: $header-height + $performance-bar-height !important;
-}
diff --git a/app/helpers/nav/top_nav_helper.rb b/app/helpers/nav/top_nav_helper.rb
index 16eaab4c7c8..25c6167185a 100644
--- a/app/helpers/nav/top_nav_helper.rb
+++ b/app/helpers/nav/top_nav_helper.rb
@@ -44,6 +44,13 @@ module Nav
**snippets_menu_item_attrs
)
end
+
+ builder.add_secondary_menu_item(
+ id: 'help',
+ title: _('Help'),
+ icon: 'question-o',
+ href: help_path
+ )
end
def build_view_model(builder:, project:, group:)
diff --git a/app/helpers/nav_helper.rb b/app/helpers/nav_helper.rb
index b5171dfbebd..3a6b9ed2cfc 100644
--- a/app/helpers/nav_helper.rb
+++ b/app/helpers/nav_helper.rb
@@ -12,6 +12,7 @@ module NavHelper
def page_with_sidebar_class
class_name = page_gutter_class
class_name << 'page-with-contextual-sidebar' if defined?(@left_sidebar) && @left_sidebar
+ class_name << 'sidebar-refactoring' if Feature.enabled?(:sidebar_refactor, current_user, default_enabled: :yaml)
class_name << 'page-with-icon-sidebar' if collapsed_sidebar? && @left_sidebar
class_name -= ['right-sidebar-expanded'] if defined?(@right_sidebar) && !@right_sidebar
diff --git a/app/models/concerns/packages/debian/component_file.rb b/app/models/concerns/packages/debian/component_file.rb
index c41635a0d16..9cf66c756a0 100644
--- a/app/models/concerns/packages/debian/component_file.rb
+++ b/app/models/concerns/packages/debian/component_file.rb
@@ -50,6 +50,8 @@ module Packages
scope :with_file_type, ->(file_type) { where(file_type: file_type) }
+ scope :with_architecture, ->(architecture) { where(architecture: architecture) }
+
scope :with_architecture_name, ->(architecture_name) do
left_outer_joins(:architecture)
.where("packages_debian_#{container_type}_architectures" => { name: architecture_name })
@@ -60,7 +62,7 @@ module Packages
scope :preload_distribution, -> { includes(component: :distribution) }
- scope :created_before, ->(reference) { where("#{table_name}.created_at < ?", reference) }
+ scope :updated_before, ->(reference) { where("#{table_name}.updated_at < ?", reference) }
mount_file_store_uploader Packages::Debian::ComponentFileUploader
diff --git a/app/services/packages/debian/generate_distribution_service.rb b/app/services/packages/debian/generate_distribution_service.rb
index 67348af1a49..651325c49a0 100644
--- a/app/services/packages/debian/generate_distribution_service.rb
+++ b/app/services/packages/debian/generate_distribution_service.rb
@@ -6,6 +6,8 @@ module Packages
include Gitlab::Utils::StrongMemoize
include ExclusiveLeaseGuard
+ ONE_HOUR = 1.hour.freeze
+
# used by ExclusiveLeaseGuard
DEFAULT_LEASE_TIMEOUT = 1.hour.to_i.freeze
@@ -62,7 +64,7 @@ module Packages
def initialize(distribution)
@distribution = distribution
- @last_generated_at = nil
+ @oldest_kept_generated_at = nil
@md5sum = []
@sha256 = []
end
@@ -70,7 +72,10 @@ module Packages
def execute
try_obtain_lease do
@distribution.transaction do
- @last_generated_at = @distribution.component_files.maximum(:created_at)
+ # We consider `apt-get update` can take at most one hour
+ # We keep all generations younger than one hour
+ # and the previous generation
+ @oldest_kept_generated_at = @distribution.component_files.updated_before(release_date - ONE_HOUR).maximum(:updated_at)
generate_component_files
generate_release
destroy_old_component_files
@@ -96,7 +101,7 @@ module Packages
.with_debian_file_type(package_file_type)
.find_each
.map(&method(:package_stanza_from_fields))
- create_component_file(component, component_file_type, architecture, package_file_type, paragraphs.join("\n"))
+ reuse_or_create_component_file(component, component_file_type, architecture, paragraphs.join("\n"))
end
def package_stanza_from_fields(package_file)
@@ -127,17 +132,32 @@ module Packages
end
end
- def create_component_file(component, component_file_type, architecture, package_file_type, content)
- component_file = component.files.create!(
- file_type: component_file_type,
- architecture: architecture,
- compression_type: nil,
- file: CarrierWaveStringFile.new(content),
- file_md5: Digest::MD5.hexdigest(content),
- file_sha256: Digest::SHA256.hexdigest(content)
- )
- @md5sum.append(" #{component_file.file_md5} #{component_file.size.to_s.rjust(8)} #{component_file.relative_path}")
- @sha256.append(" #{component_file.file_sha256} #{component_file.size.to_s.rjust(8)} #{component_file.relative_path}")
+ def reuse_or_create_component_file(component, component_file_type, architecture, content)
+ file_md5 = Digest::MD5.hexdigest(content)
+ file_sha256 = Digest::SHA256.hexdigest(content)
+ component_file = component.files
+ .with_file_type(component_file_type)
+ .with_architecture(architecture)
+ .with_compression_type(nil)
+ .with_file_sha256(file_sha256)
+ .last
+
+ if component_file
+ component_file.touch(time: release_date)
+ else
+ component_file = component.files.create!(
+ updated_at: release_date,
+ file_type: component_file_type,
+ architecture: architecture,
+ compression_type: nil,
+ file: CarrierWaveStringFile.new(content),
+ file_md5: file_md5,
+ file_sha256: file_sha256
+ )
+ end
+
+ @md5sum.append(" #{file_md5} #{component_file.size.to_s.rjust(8)} #{component_file.relative_path}")
+ @sha256.append(" #{file_sha256} #{component_file.size.to_s.rjust(8)} #{component_file.relative_path}")
end
def generate_release
@@ -187,10 +207,9 @@ module Packages
end
def destroy_old_component_files
- # Only keep the last generation and one hour before
- return if @last_generated_at.nil?
+ return if @oldest_kept_generated_at.nil?
- @distribution.component_files.created_before(@last_generated_at - 1.hour).destroy_all # rubocop:disable Cop/DestroyAll
+ @distribution.component_files.updated_before(@oldest_kept_generated_at).destroy_all # rubocop:disable Cop/DestroyAll
end
# used by ExclusiveLeaseGuard
diff --git a/app/services/packages/debian/process_changes_service.rb b/app/services/packages/debian/process_changes_service.rb
index 881ad2c46f4..b6e81012656 100644
--- a/app/services/packages/debian/process_changes_service.rb
+++ b/app/services/packages/debian/process_changes_service.rb
@@ -25,6 +25,8 @@ module Packages
update_files_metadata
update_changes_metadata
end
+
+ ::Packages::Debian::GenerateDistributionWorker.perform_async(:project, package.debian_distribution.id)
end
end
diff --git a/app/views/layouts/_startup_css.haml b/app/views/layouts/_startup_css.haml
index d50ebf49482..7d3cfe28007 100644
--- a/app/views/layouts/_startup_css.haml
+++ b/app/views/layouts/_startup_css.haml
@@ -2,5 +2,4 @@
%style
= Rails.application.assets_manifest.find_sources("themes/#{user_application_theme_css_filename}.css").first.to_s.html_safe if user_application_theme_css_filename
- - if sidebar_refactor_disabled?
- = Rails.application.assets_manifest.find_sources("startup/startup-#{startup_filename}.css").first.to_s.html_safe
+ = Rails.application.assets_manifest.find_sources("startup/startup-#{startup_filename}.css").first.to_s.html_safe
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 47c092e199a..58408ec822c 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -1,12 +1,10 @@
- page_classes = page_class << @html_class
- page_classes = page_classes.flatten.compact
-- body_classes = [user_application_theme, user_tab_width, @body_class, client_class_list]
-- body_classes << 'sidebar-refactoring' if sidebar_refactor_enabled?
!!! 5
%html{ lang: I18n.locale, class: page_classes }
= render "layouts/head"
- %body{ class: body_classes, data: body_data }
+ %body{ class: "#{user_application_theme} #{user_tab_width} #{@body_class} #{client_class_list}", data: body_data }
= render "layouts/init_auto_complete" if @gfm_form
= render "layouts/init_client_detection_flags"
= render 'peek/bar'
diff --git a/app/views/shared/members/_invite_group.html.haml b/app/views/shared/members/_invite_group.html.haml
index d59f2950df6..58f658ce9c3 100644
--- a/app/views/shared/members/_invite_group.html.haml
+++ b/app/views/shared/members/_invite_group.html.haml
@@ -9,6 +9,8 @@
.form-group
= label_tag group_link_field, _("Select a group to invite"), class: "label-bold"
= groups_select_tag(group_link_field, data: { skip_groups: @skip_groups }, class: 'input-clamp qa-group-select-field', required: true)
+ .form-text.text-muted.gl-mb-3
+ = _('Group sharing provides access to all group members (including members who inherited group membership from a parent group).')
.form-group
= label_tag group_access_field, _("Max access level"), class: "label-bold"
.select-wrapper
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index af84230a1d1..4357bf301b0 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -1326,6 +1326,15 @@
:weight: 1
:idempotent:
:tags: []
+- :name: package_repositories:packages_debian_generate_distribution
+ :worker_name: Packages::Debian::GenerateDistributionWorker
+ :feature_category: :package_registry
+ :has_external_dependencies:
+ :urgency: :low
+ :resource_boundary: :unknown
+ :weight: 1
+ :idempotent: true
+ :tags: []
- :name: package_repositories:packages_debian_process_changes
:worker_name: Packages::Debian::ProcessChangesWorker
:feature_category: :package_registry
diff --git a/app/workers/packages/debian/generate_distribution_worker.rb b/app/workers/packages/debian/generate_distribution_worker.rb
new file mode 100644
index 00000000000..68fdd80ffb1
--- /dev/null
+++ b/app/workers/packages/debian/generate_distribution_worker.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+module Packages
+ module Debian
+ class GenerateDistributionWorker # rubocop:disable Scalability/IdempotentWorker
+ include ApplicationWorker
+ include Gitlab::Utils::StrongMemoize
+
+ # The worker is idempotent, by reusing component files with the same file_sha256.
+ #
+ # See GenerateDistributionService#find_or_create_component_file
+ deduplicate :until_executed
+ idempotent!
+
+ queue_namespace :package_repositories
+ feature_category :package_registry
+
+ loggable_arguments 0
+
+ def perform(container_type, distribution_id)
+ @container_type = container_type
+ @distribution_id = distribution_id
+
+ return unless distribution
+
+ ::Packages::Debian::GenerateDistributionService.new(distribution).execute
+ end
+
+ private
+
+ def container_class
+ return ::Packages::Debian::GroupDistribution if @container_type == :group
+
+ ::Packages::Debian::ProjectDistribution
+ end
+
+ def distribution
+ strong_memoize(:distribution) do
+ container_class.find_by_id(@distribution_id)
+ end
+ end
+ end
+ end
+end