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

Add latest changes from gitlab-org/gitlab@master

parent 8320f795
No related branches found
No related tags found
No related merge requests found
Showing
with 183 additions and 38 deletions
import axios from 'axios';
import csrf from './csrf';
import suppressAjaxErrorsDuringNavigation from './suppress_ajax_errors_during_navigation';
 
axios.defaults.headers.common[csrf.headerKey] = csrf.token;
// Used by Rails to check if it is a valid XHR request
Loading
Loading
@@ -25,6 +26,20 @@ axios.interceptors.response.use(
},
);
 
let isUserNavigating = false;
window.addEventListener('beforeunload', () => {
isUserNavigating = true;
});
// Ignore AJAX errors caused by requests
// being cancelled due to browser navigation
const { gon } = window;
const featureFlagEnabled = gon && gon.features && gon.features.suppressAjaxNavigationErrors;
axios.interceptors.response.use(
response => response,
err => suppressAjaxErrorsDuringNavigation(err, isUserNavigating, featureFlagEnabled),
);
export default axios;
 
/**
Loading
Loading
Loading
Loading
@@ -15,6 +15,8 @@ export const getPagePath = (index = 0) => {
return page.split(':')[index];
};
 
export const getDashPath = (path = window.location.pathname) => path.split('/-/')[1] || null;
export const isInGroupsPage = () => getPagePath() === 'groups';
 
export const isInProjectPage = () => getPagePath() === 'projects';
Loading
Loading
/**
* An Axios error interceptor that suppresses AJAX errors caused
* by the request being cancelled when the user navigates to a new page
*/
export default (err, isUserNavigating, featureFlagEnabled) => {
if (featureFlagEnabled && isUserNavigating && err.code === 'ECONNABORTED') {
// If the user is navigating away from the current page,
// prevent .then() and .catch() handlers from being
// called by returning a Promise that never resolves
return new Promise(() => {});
}
// The error is not related to browser navigation,
// so propagate the error
return Promise.reject(err);
};
Loading
Loading
@@ -69,6 +69,7 @@ export default {
'commentsDisabled',
'getNoteableData',
'userCanReply',
'discussionTabCounter',
]),
noteableType() {
return this.noteableData.noteableType;
Loading
Loading
@@ -95,13 +96,13 @@ export default {
}
},
allDiscussions() {
if (this.discussonsCount) {
this.discussonsCount.textContent = this.allDiscussions.length;
if (this.discussionsCount && !this.isLoading) {
this.discussionsCount.textContent = this.discussionTabCounter;
}
},
},
created() {
this.discussonsCount = document.querySelector('.js-discussions-count');
this.discussionsCount = document.querySelector('.js-discussions-count');
 
this.setNotesData(this.notesData);
this.setNoteableData(this.noteableData);
Loading
Loading
/* eslint-disable no-new */
 
import { getPagePath } from '~/lib/utils/common_utils';
import { getPagePath, getDashPath } from '~/lib/utils/common_utils';
import { ACTIVE_TAB_SHARED, ACTIVE_TAB_ARCHIVED } from '~/groups/constants';
import NewGroupChild from '~/groups/new_group_child';
import notificationsDropdown from '~/notifications_dropdown';
Loading
Loading
@@ -12,9 +12,8 @@ import GroupTabs from './group_tabs';
export default function initGroupDetails(actionName = 'show') {
const newGroupChildWrapper = document.querySelector('.js-new-project-subgroup');
const loadableActions = [ACTIVE_TAB_SHARED, ACTIVE_TAB_ARCHIVED];
const paths = window.location.pathname.split('/');
const subpath = paths[paths.length - 1];
let action = loadableActions.includes(subpath) ? subpath : getPagePath(1);
const dashPath = getDashPath();
let action = loadableActions.includes(dashPath) ? dashPath : getPagePath(1);
if (actionName && action === actionName) {
action = 'show'; // 'show' resets GroupTabs to default action through base class
}
Loading
Loading
Loading
Loading
@@ -11,6 +11,8 @@ module Boards
def index
lists = Boards::Lists::ListService.new(board.parent, current_user).execute(board)
 
List.preload_preferences_for_user(lists, current_user)
render json: serialize_as_json(lists)
end
 
Loading
Loading
@@ -51,7 +53,10 @@ module Boards
service = Boards::Lists::GenerateService.new(board_parent, current_user)
 
if service.execute(board)
lists = board.lists.movable.preload_associations(current_user)
lists = board.lists.movable.preload_associations
List.preload_preferences_for_user(lists, current_user)
render json: serialize_as_json(lists)
else
head :unprocessable_entity
Loading
Loading
Loading
Loading
@@ -234,6 +234,7 @@ module Ci
end
 
after_transition pending: :running do |build|
build.pipeline.persistent_ref.create
build.deployment&.run
 
build.run_after_commit do
Loading
Loading
# frozen_string_literal: true
module Ci
##
# The persistent pipeline ref to ensure runners can safely fetch source code
# even if force-push/source-branch-deletion happens.
class PersistentRef
include ActiveModel::Model
attr_accessor :pipeline
delegate :project, :sha, to: :pipeline
delegate :repository, to: :project
delegate :ref_exists?, :create_ref, :delete_refs, to: :repository
def exist?
return unless enabled?
ref_exists?(path)
rescue
false
end
def create
return unless enabled? && !exist?
create_ref(sha, path)
rescue => e
Gitlab::Sentry
.track_acceptable_exception(e, extra: { pipeline_id: pipeline.id })
end
def delete
return unless enabled?
delete_refs(path)
rescue Gitlab::Git::Repository::NoRepository
# no-op
rescue => e
Gitlab::Sentry
.track_acceptable_exception(e, extra: { pipeline_id: pipeline.id })
end
def path
"refs/#{Repository::REF_PIPELINES}/#{pipeline.id}"
end
private
def enabled?
Feature.enabled?(:depend_on_persistent_pipeline_ref, project)
end
end
end
Loading
Loading
@@ -174,6 +174,8 @@ module Ci
 
after_transition any => ::Ci::Pipeline.completed_statuses do |pipeline|
pipeline.run_after_commit do
pipeline.persistent_ref.delete
pipeline.all_merge_requests.each do |merge_request|
next unless merge_request.auto_merge_enabled?
 
Loading
Loading
@@ -853,6 +855,10 @@ module Ci
end
end
 
def persistent_ref
@persistent_ref ||= PersistentRef.new(pipeline: self)
end
private
 
def ci_yaml_from_repo
Loading
Loading
Loading
Loading
@@ -21,20 +21,10 @@ class List < ApplicationRecord
scope :destroyable, -> { where(list_type: list_types.slice(*destroyable_types).values) }
scope :movable, -> { where(list_type: list_types.slice(*movable_types).values) }
 
scope :preload_associations, -> (user) do
preload(:board, label: :priorities)
end
scope :preload_associations, -> { preload(:board, label: :priorities) }
 
scope :ordered, -> { order(:list_type, :position) }
 
# Loads list with preferences for given user
# if preferences exists for user or not
scope :with_preferences_for, -> (user) do
return unless user
includes(:list_user_preferences).where(list_user_preferences: { user_id: [user.id, nil] })
end
alias_method :preferences, :list_user_preferences
 
class << self
Loading
Loading
@@ -45,25 +35,25 @@ class List < ApplicationRecord
def movable_types
[:label]
end
def preload_preferences_for_user(lists, user)
return unless user
lists.each { |list| list.preferences_for(user) }
end
end
 
def preferences_for(user)
return preferences.build unless user
 
if preferences.loaded?
preloaded_preferences_for(user)
else
preferences.find_or_initialize_by(user: user)
end
end
BatchLoader.for(list_id: id, user_id: user.id).batch(default_value: preferences.build(user: user)) do |items, loader|
list_ids = items.map { |i| i[:list_id] }
user_ids = items.map { |i| i[:user_id] }
 
def preloaded_preferences_for(user)
user_preferences =
preferences.find do |preference|
preference.user_id == user.id
ListUserPreference.where(list_id: list_ids, user_id: user_ids).find_each do |preference|
loader.call({ list_id: preference.list_id, user_id: preference.user_id }, preference)
end
user_preferences || preferences.build(user: user)
end
end
 
def update_preferences_for(user, preferences = {})
Loading
Loading
Loading
Loading
@@ -6,6 +6,7 @@ class Repository
REF_MERGE_REQUEST = 'merge-requests'
REF_KEEP_AROUND = 'keep-around'
REF_ENVIRONMENTS = 'environments'
REF_PIPELINES = 'pipelines'
 
ARCHIVE_CACHE_TIME = 60 # Cache archives referred to by a (mutable) ref for 1 minute
ARCHIVE_CACHE_TIME_IMMUTABLE = 3600 # Cache archives referred to by an immutable reference for 1 hour
Loading
Loading
@@ -16,7 +17,7 @@ class Repository
replace
#{REF_ENVIRONMENTS}
#{REF_KEEP_AROUND}
#{REF_ENVIRONMENTS}
#{REF_PIPELINES}
].freeze
 
include Gitlab::RepositoryCacheAdapter
Loading
Loading
Loading
Loading
@@ -34,7 +34,8 @@ module Ci
 
def refspecs
specs = []
specs << refspec_for_merge_request_ref if merge_request_ref?
specs << refspec_for_pipeline_ref if merge_request_ref?
specs << refspec_for_persistent_ref if persistent_ref_exist?
 
if git_depth > 0
specs << refspec_for_branch(ref) if branch? || legacy_detached_merge_request_pipeline?
Loading
Loading
@@ -86,10 +87,22 @@ module Ci
"+#{Gitlab::Git::TAG_REF_PREFIX}#{ref}:#{RUNNER_REMOTE_TAG_PREFIX}#{ref}"
end
 
def refspec_for_merge_request_ref
def refspec_for_pipeline_ref
"+#{ref}:#{ref}"
end
 
def refspec_for_persistent_ref
"+#{persistent_ref_path}:#{persistent_ref_path}"
end
def persistent_ref_exist?
pipeline.persistent_ref.exist?
end
def persistent_ref_path
pipeline.persistent_ref.path
end
def git_depth_variable
strong_memoize(:git_depth_variable) do
variables&.find { |variable| variable[:key] == 'GIT_DEPTH' }
Loading
Loading
Loading
Loading
@@ -6,7 +6,7 @@ module Boards
def execute(board)
board.lists.create(list_type: :backlog) unless board.lists.backlog.exists?
 
board.lists.preload_associations(current_user)
board.lists.preload_associations
end
end
end
Loading
Loading
---
title: Naming a project "shared" will no longer automatically open the "Shared Projects" tab.
merge_request: 16847
author: Jesse Hall @jessehall3
type: fixed
---
title: Create a persistent ref per pipeline for keeping pipelines run from force-push
and merged results
merge_request: 17043
author:
type: fixed
---
title: Add trigram index on snippet content
merge_request: 17806
author:
type: performance
---
title: Increase the limit of includes in CI file to 100
merge_request: 17807
author:
type: fixed
---
title: Suppress error messages shown when navigating to a new page
merge_request: 17706
author:
type: fixed
Loading
Loading
@@ -209,9 +209,7 @@ module.exports = {
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local].[hash:8].[ext]',
},
name: '[name].[hash:8].[ext]',
},
},
],
Loading
Loading
# frozen_string_literal: true
class AddIndexOnSnippetContent < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_NAME = 'index_snippets_on_content_trigram'
disable_ddl_transaction!
def up
add_concurrent_index :snippets, :content, name: INDEX_NAME, using: :gin, opclass: { content: :gin_trgm_ops }
end
def down
remove_concurrent_index_by_name(:snippets, INDEX_NAME)
end
end
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