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

Add latest changes from gitlab-org/gitlab@master

parent 96b0c124
No related branches found
No related tags found
No related merge requests found
Showing
with 187 additions and 83 deletions
Loading
@@ -61,8 +61,10 @@ export const getFileData = (
Loading
@@ -61,8 +61,10 @@ export const getFileData = (
{ path, makeFileActive = true, openFile = makeFileActive }, { path, makeFileActive = true, openFile = makeFileActive },
) => { ) => {
const file = state.entries[path]; const file = state.entries[path];
const fileDeletedAndReadded = getters.isFileDeletedAndReadded(path);
   
if (file.raw || (file.tempFile && !file.prevPath)) return Promise.resolve(); if (file.raw || (file.tempFile && !file.prevPath && !fileDeletedAndReadded))
return Promise.resolve();
   
commit(types.TOGGLE_LOADING, { entry: file }); commit(types.TOGGLE_LOADING, { entry: file });
   
Loading
@@ -102,11 +104,16 @@ export const setFileMrChange = ({ commit }, { file, mrChange }) => {
Loading
@@ -102,11 +104,16 @@ export const setFileMrChange = ({ commit }, { file, mrChange }) => {
   
export const getRawFileData = ({ state, commit, dispatch, getters }, { path }) => { export const getRawFileData = ({ state, commit, dispatch, getters }, { path }) => {
const file = state.entries[path]; const file = state.entries[path];
const stagedFile = state.stagedFiles.find(f => f.path === path);
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
const fileDeletedAndReadded = getters.isFileDeletedAndReadded(path);
service service
.getRawFileData(file) .getRawFileData(fileDeletedAndReadded ? stagedFile : file)
.then(raw => { .then(raw => {
if (!(file.tempFile && !file.prevPath)) commit(types.SET_FILE_RAW_DATA, { file, raw }); if (!(file.tempFile && !file.prevPath && !fileDeletedAndReadded))
commit(types.SET_FILE_RAW_DATA, { file, raw, fileDeletedAndReadded });
if (file.mrChange && file.mrChange.new_file === false) { if (file.mrChange && file.mrChange.new_file === false) {
const baseSha = const baseSha =
(getters.currentMergeRequest && getters.currentMergeRequest.baseCommitSha) || ''; (getters.currentMergeRequest && getters.currentMergeRequest.baseCommitSha) || '';
Loading
@@ -151,7 +158,7 @@ export const changeFileContent = ({ commit, dispatch, state }, { path, content }
Loading
@@ -151,7 +158,7 @@ export const changeFileContent = ({ commit, dispatch, state }, { path, content }
   
if (file.changed && indexOfChangedFile === -1) { if (file.changed && indexOfChangedFile === -1) {
commit(types.ADD_FILE_TO_CHANGED, path); commit(types.ADD_FILE_TO_CHANGED, path);
} else if (!file.changed && indexOfChangedFile !== -1) { } else if (!file.changed && !file.tempFile && indexOfChangedFile !== -1) {
commit(types.REMOVE_FILE_FROM_CHANGED, path); commit(types.REMOVE_FILE_FROM_CHANGED, path);
} }
   
Loading
Loading
Loading
@@ -54,27 +54,29 @@ export default {
Loading
@@ -54,27 +54,29 @@ export default {
} }
}); });
}, },
[types.SET_FILE_RAW_DATA](state, { file, raw }) { [types.SET_FILE_RAW_DATA](state, { file, raw, fileDeletedAndReadded = false }) {
const openPendingFile = state.openFiles.find( const openPendingFile = state.openFiles.find(
f => f.path === file.path && f.pending && !(f.tempFile && !f.prevPath), f =>
f.path === file.path && f.pending && !(f.tempFile && !f.prevPath && !fileDeletedAndReadded),
); );
const stagedFile = state.stagedFiles.find(f => f.path === file.path);
   
if (file.tempFile && file.content === '') { if (file.tempFile && file.content === '' && !fileDeletedAndReadded) {
Object.assign(state.entries[file.path], { Object.assign(state.entries[file.path], { content: raw });
content: raw, } else if (fileDeletedAndReadded) {
}); Object.assign(stagedFile, { raw });
} else { } else {
Object.assign(state.entries[file.path], { Object.assign(state.entries[file.path], { raw });
raw,
});
} }
   
if (!openPendingFile) return; if (!openPendingFile) return;
   
if (!openPendingFile.tempFile) { if (!openPendingFile.tempFile) {
openPendingFile.raw = raw; openPendingFile.raw = raw;
} else if (openPendingFile.tempFile) { } else if (openPendingFile.tempFile && !fileDeletedAndReadded) {
openPendingFile.content = raw; openPendingFile.content = raw;
} else if (fileDeletedAndReadded) {
Object.assign(stagedFile, { raw });
} }
}, },
[types.SET_FILE_BASE_RAW_DATA](state, { file, baseRaw }) { [types.SET_FILE_BASE_RAW_DATA](state, { file, baseRaw }) {
Loading
Loading
const MARKDOWN_EXTENSIONS = ['mdown', 'mkd', 'mkdn', 'md', 'markdown']; const FILENAMES = ['index', 'readme'];
const ASCIIDOC_EXTENSIONS = ['adoc', 'ad', 'asciidoc'];
const OTHER_EXTENSIONS = ['textile', 'rdoc', 'org', 'creole', 'wiki', 'mediawiki', 'rst'];
const EXTENSIONS = [...MARKDOWN_EXTENSIONS, ...ASCIIDOC_EXTENSIONS, ...OTHER_EXTENSIONS];
const PLAIN_FILENAMES = ['readme', 'index'];
const FILE_REGEXP = new RegExp(
`^(${PLAIN_FILENAMES.join('|')})(.(${EXTENSIONS.join('|')}))?$`,
'i',
);
const PLAIN_FILE_REGEXP = new RegExp(`^(${PLAIN_FILENAMES.join('|')})`, 'i');
const EXTENSIONS_REGEXP = new RegExp(`.(${EXTENSIONS.join('|')})$`, 'i');
   
// eslint-disable-next-line import/prefer-default-export const MARKUP_EXTENSIONS = [
export const readmeFile = blobs => { 'ad',
const readMeFiles = blobs.filter(f => f.name.search(FILE_REGEXP) !== -1); 'adoc',
'asciidoc',
'creole',
'markdown',
'md',
'mdown',
'mediawiki',
'mkd',
'mkdn',
'org',
'rdoc',
'rst',
'textile',
'wiki',
];
   
const previewableReadme = readMeFiles.find(f => f.name.search(EXTENSIONS_REGEXP) !== -1); const isRichReadme = file => {
const plainReadme = readMeFiles.find(f => f.name.search(PLAIN_FILE_REGEXP) !== -1); const re = new RegExp(`^(${FILENAMES.join('|')})\\.(${MARKUP_EXTENSIONS.join('|')})$`, 'i');
return re.test(file.name);
};
   
return previewableReadme || plainReadme; const isPlainReadme = file => {
const re = new RegExp(`^(${FILENAMES.join('|')})$`, 'i');
return re.test(file.name);
}; };
// eslint-disable-next-line import/prefer-default-export
export const readmeFile = blobs => blobs.find(isRichReadme) || blobs.find(isPlainReadme);
Loading
@@ -4,7 +4,6 @@ class ProjectCiCdSetting < ApplicationRecord
Loading
@@ -4,7 +4,6 @@ class ProjectCiCdSetting < ApplicationRecord
include IgnorableColumns include IgnorableColumns
# https://gitlab.com/gitlab-org/gitlab/issues/36651 # https://gitlab.com/gitlab-org/gitlab/issues/36651
ignore_column :merge_trains_enabled, remove_with: '12.7', remove_after: '2019-12-22' ignore_column :merge_trains_enabled, remove_with: '12.7', remove_after: '2019-12-22'
belongs_to :project, inverse_of: :ci_cd_settings belongs_to :project, inverse_of: :ci_cd_settings
   
# The version of the schema that first introduced this model/table. # The version of the schema that first introduced this model/table.
Loading
Loading
# frozen_string_literal: true # frozen_string_literal: true
   
# SpamCheckService # SpamCheckMethods
# #
# Provide helper methods for checking if a given spammable object has # Provide helper methods for checking if a given spammable object has
# potential spam data. # potential spam data.
# #
# Dependencies: # Dependencies:
# - params with :request # - params with :request
#
module SpamCheckService module SpamCheckMethods
# rubocop:disable Gitlab/ModuleWithInstanceVariables # rubocop:disable Gitlab/ModuleWithInstanceVariables
def filter_spam_check_params def filter_spam_check_params
@request = params.delete(:request) @request = params.delete(:request)
Loading
Loading
# frozen_string_literal: true # frozen_string_literal: true
   
class CreateSnippetService < BaseService class CreateSnippetService < BaseService
include SpamCheckService include SpamCheckMethods
   
def execute def execute
filter_spam_check_params filter_spam_check_params
Loading
Loading
Loading
@@ -2,7 +2,7 @@
Loading
@@ -2,7 +2,7 @@
   
module Issues module Issues
class CreateService < Issues::BaseService class CreateService < Issues::BaseService
include SpamCheckService include SpamCheckMethods
include ResolveDiscussions include ResolveDiscussions
   
def execute def execute
Loading
Loading
Loading
@@ -2,7 +2,7 @@
Loading
@@ -2,7 +2,7 @@
   
module Issues module Issues
class UpdateService < Issues::BaseService class UpdateService < Issues::BaseService
include SpamCheckService include SpamCheckMethods
   
def execute(issue) def execute(issue)
handle_move_between_ids(issue) handle_move_between_ids(issue)
Loading
Loading
# frozen_string_literal: true # frozen_string_literal: true
   
class UpdateSnippetService < BaseService class UpdateSnippetService < BaseService
include SpamCheckService include SpamCheckMethods
   
attr_accessor :snippet attr_accessor :snippet
   
Loading
Loading
---
title: "Web IDE: Fix Incorrect diff of deletion and addition of the same file"
merge_request: 21680
author:
type: fixed
# frozen_string_literal: true
class DropProjectCiCdSettingsMergeTrainsEnabled < ActiveRecord::Migration[5.2]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
remove_column :project_ci_cd_settings, :merge_trains_enabled
end
def down
add_column_with_default :project_ci_cd_settings, :merge_trains_enabled, :boolean, default: false, allow_null: true
end
end
Loading
@@ -3098,7 +3098,6 @@ ActiveRecord::Schema.define(version: 2020_01_08_155731) do
Loading
@@ -3098,7 +3098,6 @@ ActiveRecord::Schema.define(version: 2020_01_08_155731) do
t.integer "project_id", null: false t.integer "project_id", null: false
t.boolean "group_runners_enabled", default: true, null: false t.boolean "group_runners_enabled", default: true, null: false
t.boolean "merge_pipelines_enabled" t.boolean "merge_pipelines_enabled"
t.boolean "merge_trains_enabled", default: false, null: false
t.integer "default_git_depth" t.integer "default_git_depth"
t.index ["project_id"], name: "index_project_ci_cd_settings_on_project_id", unique: true t.index ["project_id"], name: "index_project_ci_cd_settings_on_project_id", unique: true
end end
Loading
Loading
Loading
@@ -32,11 +32,11 @@ In the case of [custom domains](#custom-domains) (but not
Loading
@@ -32,11 +32,11 @@ In the case of [custom domains](#custom-domains) (but not
ports `80` and/or `443`. For that reason, there is some flexibility in the way ports `80` and/or `443`. For that reason, there is some flexibility in the way
which you can set it up: which you can set it up:
   
1. Run the Pages daemon in the same server as GitLab, listening on a secondary IP. - Run the Pages daemon in the same server as GitLab, listening on a **secondary IP**.
1. Run the Pages daemon in a separate server. In that case, the - Run the Pages daemon in a [separate server](#running-gitlab-pages-on-a-separate-server). In that case, the
[Pages path](#change-storage-path) must also be present in the server that [Pages path](#change-storage-path) must also be present in the server that
the Pages daemon is installed, so you will have to share it via network. the Pages daemon is installed, so you will have to share it via network.
1. Run the Pages daemon in the same server as GitLab, listening on the same IP - Run the Pages daemon in the same server as GitLab, listening on the same IP
but on different ports. In that case, you will have to proxy the traffic with but on different ports. In that case, you will have to proxy the traffic with
a loadbalancer. If you choose that route note that you should use TCP load a loadbalancer. If you choose that route note that you should use TCP load
balancing for HTTPS. If you use TLS-termination (HTTPS-load balancing) the balancing for HTTPS. If you use TLS-termination (HTTPS-load balancing) the
Loading
@@ -182,7 +182,7 @@ The [GitLab Pages README](https://gitlab.com/gitlab-org/gitlab-pages#caveats) ha
Loading
@@ -182,7 +182,7 @@ The [GitLab Pages README](https://gitlab.com/gitlab-org/gitlab-pages#caveats) ha
In addition to the wildcard domains, you can also have the option to configure In addition to the wildcard domains, you can also have the option to configure
GitLab Pages to work with custom domains. Again, there are two options here: GitLab Pages to work with custom domains. Again, there are two options here:
support custom domains with and without TLS certificates. The easiest setup is support custom domains with and without TLS certificates. The easiest setup is
that without TLS certificates. In either case, you'll need a secondary IP. If that without TLS certificates. In either case, you'll need a **secondary IP**. If
you have IPv6 as well as IPv4 addresses, you can use them both. you have IPv6 as well as IPv4 addresses, you can use them both.
   
### Custom domains ### Custom domains
Loading
Loading
Loading
@@ -426,7 +426,7 @@ Status: 200 OK
Loading
@@ -426,7 +426,7 @@ Status: 200 OK
The link to the next page contains an additional filter `id_after=42` which excludes records we have retrieved already. The link to the next page contains an additional filter `id_after=42` which excludes records we have retrieved already.
Note the type of filter depends on the `order_by` option used and we may have more than one additional filter. Note the type of filter depends on the `order_by` option used and we may have more than one additional filter.
   
The `Link` header is absent when the end of the collection has been reached and there are no additional records to retrieve. When the end of the collection has been reached and there are no additional records to retrieve, the `Link` header is absent and the resulting array is empty.
   
We recommend using only the given link to retrieve the next page instead of building your own URL. Apart from the headers shown, We recommend using only the given link to retrieve the next page instead of building your own URL. Apart from the headers shown,
we don't expose additional pagination headers. we don't expose additional pagination headers.
Loading
Loading
Loading
@@ -4,6 +4,7 @@ module API
Loading
@@ -4,6 +4,7 @@ module API
module Helpers module Helpers
include Gitlab::Utils include Gitlab::Utils
include Helpers::Pagination include Helpers::Pagination
include Helpers::PaginationStrategies
   
SUDO_HEADER = "HTTP_SUDO" SUDO_HEADER = "HTTP_SUDO"
GITLAB_SHARED_SECRET_HEADER = "Gitlab-Shared-Secret" GITLAB_SHARED_SECRET_HEADER = "Gitlab-Shared-Secret"
Loading
Loading
Loading
@@ -3,34 +3,9 @@
Loading
@@ -3,34 +3,9 @@
module API module API
module Helpers module Helpers
module Pagination module Pagination
# This returns an ActiveRecord relation
def paginate(relation) def paginate(relation)
Gitlab::Pagination::OffsetPagination.new(self).paginate(relation) Gitlab::Pagination::OffsetPagination.new(self).paginate(relation)
end end
# This applies pagination and executes the query
# It always returns an array instead of an ActiveRecord relation
def paginate_and_retrieve!(relation)
offset_or_keyset_pagination(relation).to_a
end
private
def offset_or_keyset_pagination(relation)
return paginate(relation) unless keyset_pagination_enabled?
request_context = Gitlab::Pagination::Keyset::RequestContext.new(self)
unless Gitlab::Pagination::Keyset.available?(request_context, relation)
return error!('Keyset pagination is not yet available for this type of request', 405)
end
Gitlab::Pagination::Keyset.paginate(request_context, relation)
end
def keyset_pagination_enabled?
params[:pagination] == 'keyset' && Feature.enabled?(:api_keyset_pagination, default_enabled: true)
end
end end
end end
end end
# frozen_string_literal: true
module API
module Helpers
module PaginationStrategies
def paginate_with_strategies(relation)
paginator = paginator(relation)
yield(paginator.paginate(relation)).tap do |records, _|
paginator.finalize(records)
end
end
def paginator(relation)
return Gitlab::Pagination::OffsetPagination.new(self) unless keyset_pagination_enabled?
request_context = Gitlab::Pagination::Keyset::RequestContext.new(self)
unless Gitlab::Pagination::Keyset.available?(request_context, relation)
return error!('Keyset pagination is not yet available for this type of request', 405)
end
Gitlab::Pagination::Keyset::Pager.new(request_context)
end
private
def keyset_pagination_enabled?
params[:pagination] == 'keyset' && Feature.enabled?(:api_keyset_pagination, default_enabled: true)
end
end
end
end
Loading
@@ -90,18 +90,22 @@ module API
Loading
@@ -90,18 +90,22 @@ module API
def present_projects(projects, options = {}) def present_projects(projects, options = {})
projects = reorder_projects(projects) projects = reorder_projects(projects)
projects = apply_filters(projects) projects = apply_filters(projects)
projects = paginate(projects)
projects, options = with_custom_attributes(projects, options)
   
options = options.reverse_merge( records, options = paginate_with_strategies(projects) do |projects|
with: current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails, projects, options = with_custom_attributes(projects, options)
statistics: params[:statistics],
current_user: current_user, options = options.reverse_merge(
license: false with: current_user ? Entities::ProjectWithAccess : Entities::BasicProjectDetails,
) statistics: params[:statistics],
options[:with] = Entities::BasicProjectDetails if params[:simple] current_user: current_user,
license: false
)
options[:with] = Entities::BasicProjectDetails if params[:simple]
[options[:with].prepare_relation(projects, options), options]
end
   
present options[:with].prepare_relation(projects, options), options present records, options
end end
   
def translate_params_for_compatibility(params) def translate_params_for_compatibility(params)
Loading
Loading
Loading
@@ -17,7 +17,7 @@ module Gitlab
Loading
@@ -17,7 +17,7 @@ module Gitlab
allow_failure type stage when start_in artifacts cache allow_failure type stage when start_in artifacts cache
dependencies before_script needs after_script variables dependencies before_script needs after_script variables
environment coverage retry parallel extends interruptible timeout environment coverage retry parallel extends interruptible timeout
resource_group].freeze resource_group release].freeze
   
REQUIRED_BY_NEEDS = %i[stage].freeze REQUIRED_BY_NEEDS = %i[stage].freeze
   
Loading
@@ -151,14 +151,18 @@ module Gitlab
Loading
@@ -151,14 +151,18 @@ module Gitlab
description: 'Coverage configuration for this job.', description: 'Coverage configuration for this job.',
inherit: false inherit: false
   
entry :release, Entry::Release,
description: 'This job will produce a release.',
inherit: false
helpers :before_script, :script, :stage, :type, :after_script, helpers :before_script, :script, :stage, :type, :after_script,
:cache, :image, :services, :only, :except, :variables, :cache, :image, :services, :only, :except, :variables,
:artifacts, :environment, :coverage, :retry, :rules, :artifacts, :environment, :coverage, :retry, :rules,
:parallel, :needs, :interruptible :parallel, :needs, :interruptible, :release
   
attributes :script, :tags, :allow_failure, :when, :dependencies, attributes :script, :tags, :allow_failure, :when, :dependencies,
:needs, :retry, :parallel, :extends, :start_in, :rules, :needs, :retry, :parallel, :extends, :start_in, :rules,
:interruptible, :timeout, :resource_group :interruptible, :timeout, :resource_group, :release
   
def self.matching?(name, config) def self.matching?(name, config)
!name.to_s.start_with?('.') && !name.to_s.start_with?('.') &&
Loading
@@ -243,6 +247,7 @@ module Gitlab
Loading
@@ -243,6 +247,7 @@ module Gitlab
interruptible: interruptible_defined? ? interruptible_value : nil, interruptible: interruptible_defined? ? interruptible_value : nil,
timeout: has_timeout? ? ChronicDuration.parse(timeout.to_s) : nil, timeout: has_timeout? ? ChronicDuration.parse(timeout.to_s) : nil,
artifacts: artifacts_value, artifacts: artifacts_value,
release: release_value,
after_script: after_script_value, after_script: after_script_value,
ignore: ignored?, ignore: ignored?,
needs: needs_defined? ? needs_value : nil, needs: needs_defined? ? needs_value : nil,
Loading
Loading
# frozen_string_literal: true
module Gitlab
module Ci
class Config
module Entry
##
# Entry that represents a release configuration.
#
class Release < ::Gitlab::Config::Entry::Node
include ::Gitlab::Config::Entry::Configurable
include ::Gitlab::Config::Entry::Validatable
include ::Gitlab::Config::Entry::Attributable
ALLOWED_KEYS = %i[tag_name name description assets].freeze
attributes %i[tag_name name assets].freeze
# Attributable description conflicts with
# ::Gitlab::Config::Entry::Node.description
def has_description?
true
end
def description
config[:description]
end
entry :assets, Entry::Release::Assets, description: 'Release assets.'
validations do
validates :config, allowed_keys: ALLOWED_KEYS
validates :tag_name, presence: true
validates :description, type: String, presence: true
end
helpers :assets
def value
@config[:assets] = assets_value if @config.key?(:assets)
@config
end
end
end
end
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