Merge branch 'master' into sh-headless-chrome-support
This commit is contained in:
commit
3e75b7fa81
203 changed files with 1959 additions and 1176 deletions
|
@ -474,7 +474,6 @@ db:rollback-mysql:
|
|||
variables:
|
||||
SIZE: "1"
|
||||
SETUP_DB: "false"
|
||||
RAILS_ENV: "development"
|
||||
script:
|
||||
- git clone https://gitlab.com/gitlab-org/gitlab-test.git
|
||||
/home/git/repositories/gitlab-org/gitlab-test.git
|
||||
|
|
18
.rubocop.yml
18
.rubocop.yml
|
@ -251,6 +251,10 @@ Layout/Tab:
|
|||
Layout/TrailingBlankLines:
|
||||
Enabled: true
|
||||
|
||||
# Avoid trailing whitespace.
|
||||
Layout/TrailingWhitespace:
|
||||
Enabled: true
|
||||
|
||||
# Style #######################################################################
|
||||
|
||||
# Check the naming of accessor methods for get_/set_.
|
||||
|
@ -1174,29 +1178,33 @@ RSpec/VerifiedDoubles:
|
|||
GitlabSecurity/DeepMunge:
|
||||
Enabled: true
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- 'lib/**/*.rake'
|
||||
- 'spec/**/*'
|
||||
|
||||
GitlabSecurity/PublicSend:
|
||||
Enabled: true
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- 'config/**/*'
|
||||
- 'db/**/*'
|
||||
- 'features/**/*'
|
||||
- 'lib/**/*.rake'
|
||||
- 'qa/**/*'
|
||||
- 'spec/**/*'
|
||||
|
||||
GitlabSecurity/RedirectToParamsUpdate:
|
||||
Enabled: true
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- 'lib/**/*.rake'
|
||||
- 'spec/**/*'
|
||||
|
||||
GitlabSecurity/SqlInjection:
|
||||
Enabled: true
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- 'lib/**/*.rake'
|
||||
- 'spec/**/*'
|
||||
|
||||
GitlabSecurity/SystemCommandInjection:
|
||||
Enabled: true
|
||||
Exclude:
|
||||
- 'spec/**/*'
|
||||
- 'lib/**/*.rake'
|
||||
- 'spec/**/*'
|
||||
|
|
|
@ -57,11 +57,6 @@ Layout/SpaceInsideParens:
|
|||
Layout/SpaceInsidePercentLiteralDelimiters:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 89
|
||||
# Cop supports --auto-correct.
|
||||
Layout/TrailingWhitespace:
|
||||
Enabled: false
|
||||
|
||||
# Offense count: 272
|
||||
RSpec/EmptyLineAfterFinalLet:
|
||||
Enabled: false
|
||||
|
|
2
Gemfile
2
Gemfile
|
@ -232,7 +232,7 @@ gem 'ace-rails-ap', '~> 4.1.0'
|
|||
gem 'mousetrap-rails', '~> 1.4.6'
|
||||
|
||||
# Detect and convert string character encoding
|
||||
gem 'charlock_holmes', '~> 0.7.3'
|
||||
gem 'charlock_holmes', '~> 0.7.5'
|
||||
|
||||
# Faster JSON
|
||||
gem 'oj', '~> 2.17.4'
|
||||
|
|
|
@ -117,7 +117,7 @@ GEM
|
|||
activesupport (>= 4.0.0)
|
||||
mime-types (>= 1.16)
|
||||
cause (0.1)
|
||||
charlock_holmes (0.7.3)
|
||||
charlock_holmes (0.7.5)
|
||||
childprocess (0.7.0)
|
||||
ffi (~> 1.0, >= 1.0.11)
|
||||
chronic (0.10.2)
|
||||
|
@ -983,7 +983,7 @@ DEPENDENCIES
|
|||
capybara (~> 2.15)
|
||||
capybara-screenshot (~> 1.0.0)
|
||||
carrierwave (~> 1.1)
|
||||
charlock_holmes (~> 0.7.3)
|
||||
charlock_holmes (~> 0.7.5)
|
||||
chronic (~> 0.10.2)
|
||||
chronic_duration (~> 0.10.6)
|
||||
concurrent-ruby (~> 1.0.5)
|
||||
|
|
16
PROCESS.md
16
PROCESS.md
|
@ -141,18 +141,22 @@ the stable branch are:
|
|||
* Fixes for security issues
|
||||
* New or updated translations (as long as they do not touch application code)
|
||||
|
||||
Any merge requests cherry-picked into the stable branch for a previous release
|
||||
will also be picked into the latest stable branch. These fixes will be shipped
|
||||
in the next RC for that release if it is before the 22nd. If the fixes are are
|
||||
completed on or after the 22nd, they will be shipped in a patch for that
|
||||
release.
|
||||
|
||||
During the feature freeze all merge requests that are meant to go into the upcoming
|
||||
release should have the correct milestone assigned _and_ have the label
|
||||
~"Pick into Stable" set, so that release managers can find and pick them.
|
||||
Merge requests without a milestone and this label will
|
||||
not be merged into any stable branches.
|
||||
|
||||
Fixes marked like this will be shipped in the next RC for that release. Once
|
||||
the final RC has been prepared ready for release on the 22nd, further fixes
|
||||
marked ~"Pick into Stable" will go into a patch for that release.
|
||||
|
||||
If a merge request is to be picked into more than one release it will also need
|
||||
the ~"Pick into Backports" label set to remind the release manager to change
|
||||
the milestone after cherry-picking. As before, it should still have the
|
||||
~"Pick into Stable" label and the milestone of the highest release it will be
|
||||
picked into.
|
||||
|
||||
### Asking for an exception
|
||||
|
||||
If you think a merge request should go into an RC or patch even though it does not meet these requirements,
|
||||
|
|
|
@ -17,7 +17,7 @@ window.CommitsList = (function() {
|
|||
}
|
||||
});
|
||||
|
||||
Pager.init(limit, false, false, this.processCommits);
|
||||
Pager.init(parseInt(limit, 10), false, false, this.processCommits);
|
||||
|
||||
this.content = $("#commits-list");
|
||||
this.searchField = $("#commits-search");
|
||||
|
|
|
@ -42,6 +42,10 @@ $(() => {
|
|||
$components.each(function () {
|
||||
const $this = $(this);
|
||||
const noteId = $this.attr(':note-id');
|
||||
const discussionId = $this.attr(':discussion-id');
|
||||
|
||||
if ($this.is('comment-and-resolve-btn') && !discussionId) return;
|
||||
|
||||
const tmp = Vue.extend({
|
||||
template: $this.get(0).outerHTML
|
||||
});
|
||||
|
|
|
@ -644,7 +644,7 @@ import initChangesDropdown from './init_changes_dropdown';
|
|||
return Dispatcher;
|
||||
})();
|
||||
|
||||
$(function() {
|
||||
$(window).on('load', function() {
|
||||
new Dispatcher();
|
||||
});
|
||||
}).call(window);
|
||||
|
|
|
@ -15,6 +15,10 @@ export const setOpenMenu = (menu = null) => { currentOpenMenu = menu; };
|
|||
|
||||
export const slope = (a, b) => (b.y - a.y) / (b.x - a.x);
|
||||
|
||||
let headerHeight = 50;
|
||||
|
||||
export const getHeaderHeight = () => headerHeight;
|
||||
|
||||
export const canShowActiveSubItems = (el) => {
|
||||
const isHiddenByMedia = bp.getBreakpointSize() === 'sm' || bp.getBreakpointSize() === 'md';
|
||||
|
||||
|
@ -74,7 +78,7 @@ export const moveSubItemsToPosition = (el, subItems) => {
|
|||
const isAbove = top < boundingRect.top;
|
||||
|
||||
subItems.classList.add('fly-out-list');
|
||||
subItems.style.transform = `translate3d(0, ${Math.floor(top)}px, 0)`; // eslint-disable-line no-param-reassign
|
||||
subItems.style.transform = `translate3d(0, ${Math.floor(top) - headerHeight}px, 0)`; // eslint-disable-line no-param-reassign
|
||||
|
||||
const subItemsRect = subItems.getBoundingClientRect();
|
||||
|
||||
|
@ -153,6 +157,8 @@ export default () => {
|
|||
}, getHideSubItemsInterval());
|
||||
});
|
||||
|
||||
headerHeight = document.querySelector('.nav-sidebar').offsetTop;
|
||||
|
||||
items.forEach((el) => {
|
||||
const subItems = el.querySelector('.sidebar-sub-level-items');
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export const isSticky = (el, scrollY, stickyTop) => {
|
||||
const top = el.offsetTop - scrollY;
|
||||
|
||||
if (top === stickyTop) {
|
||||
if (top <= stickyTop) {
|
||||
el.classList.add('is-stuck');
|
||||
} else {
|
||||
el.classList.remove('is-stuck');
|
||||
|
|
|
@ -132,8 +132,9 @@ import './project_select';
|
|||
import './project_show';
|
||||
import './project_variables';
|
||||
import './projects_list';
|
||||
import './render_gfm';
|
||||
import './syntax_highlight';
|
||||
import './render_math';
|
||||
import './render_gfm';
|
||||
import './right_sidebar';
|
||||
import './search';
|
||||
import './search_autocomplete';
|
||||
|
@ -141,7 +142,6 @@ import './smart_interval';
|
|||
import './star';
|
||||
import './subscription';
|
||||
import './subscription_select';
|
||||
import './syntax_highlight';
|
||||
|
||||
import './dispatcher';
|
||||
|
||||
|
|
|
@ -43,10 +43,12 @@ export default class NewNavSidebar {
|
|||
}
|
||||
|
||||
toggleCollapsedSidebar(collapsed) {
|
||||
this.$sidebar.toggleClass('sidebar-icons-only', collapsed);
|
||||
const breakpoint = bp.getBreakpointSize();
|
||||
|
||||
if (this.$sidebar.length) {
|
||||
this.$sidebar.toggleClass('sidebar-icons-only', collapsed);
|
||||
this.$page.toggleClass('page-with-new-sidebar', !collapsed);
|
||||
this.$page.toggleClass('page-with-icon-sidebar', collapsed);
|
||||
this.$page.toggleClass('page-with-icon-sidebar', breakpoint === 'sm' ? true : collapsed);
|
||||
}
|
||||
NewNavSidebar.setCollapsedCookie(collapsed);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,5 @@
|
|||
return this;
|
||||
};
|
||||
|
||||
$(document).on('ready load', function() {
|
||||
return $('body').renderGFM();
|
||||
});
|
||||
$(() => $('body').renderGFM());
|
||||
}).call(window);
|
||||
|
|
|
@ -43,8 +43,10 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="repository-view tree-content-holder">
|
||||
<repo-sidebar/><div v-if="isMini"
|
||||
<div class="repository-view">
|
||||
<div class="tree-content-holder" :class="{'tree-content-holder-mini' : isMini}">
|
||||
<repo-sidebar/>
|
||||
<div v-if="isMini"
|
||||
class="panel-right"
|
||||
:class="{'edit-mode': editMode}">
|
||||
<repo-tabs/>
|
||||
|
@ -53,6 +55,7 @@ export default {
|
|||
class="blob-viewer-container"/>
|
||||
<repo-file-buttons/>
|
||||
</div>
|
||||
</div>
|
||||
<repo-commit-section/>
|
||||
<popup-dialog
|
||||
v-show="dialog.open"
|
||||
|
|
|
@ -71,7 +71,7 @@ export default {
|
|||
/>
|
||||
<div v-if="!isConfidential" class="no-value confidential-value">
|
||||
<i class="fa fa-eye is-not-confidential"></i>
|
||||
This issue is not confidential
|
||||
Not confidential
|
||||
</div>
|
||||
<div v-else class="value confidential-value hide-collapsed">
|
||||
<i aria-hidden="true" data-hidden="true" class="fa fa-eye-slash is-confidential"></i>
|
||||
|
|
|
@ -204,6 +204,16 @@
|
|||
}
|
||||
}
|
||||
|
||||
div.avatar {
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.center {
|
||||
line-height: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
strong {
|
||||
color: $gl-text-color;
|
||||
}
|
||||
|
|
|
@ -161,6 +161,8 @@
|
|||
}
|
||||
|
||||
.nav-controls {
|
||||
@include new-style-dropdown;
|
||||
|
||||
display: inline-block;
|
||||
float: right;
|
||||
text-align: right;
|
||||
|
|
|
@ -97,9 +97,9 @@ $new-sidebar-collapsed-width: 50px;
|
|||
top: $header-height;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: auto;
|
||||
background-color: $gray-normal;
|
||||
box-shadow: inset -2px 0 0 $border-color;
|
||||
transform: translate3d(0, 0, 0);
|
||||
|
||||
&.sidebar-icons-only {
|
||||
width: $new-sidebar-collapsed-width;
|
||||
|
@ -176,6 +176,12 @@ $new-sidebar-collapsed-width: 50px;
|
|||
}
|
||||
}
|
||||
|
||||
.nav-sidebar-inner-scroll {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.with-performance-bar .nav-sidebar {
|
||||
top: $header-height + $performance-bar-height;
|
||||
}
|
||||
|
|
|
@ -81,6 +81,7 @@
|
|||
border: 1px solid $white-normal;
|
||||
padding: 5px;
|
||||
max-height: calc(100vh - 100px);
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.emoji-block {
|
||||
|
|
|
@ -47,14 +47,26 @@
|
|||
margin: 20px;
|
||||
}
|
||||
|
||||
.repository-view.tree-content-holder {
|
||||
.repository-view {
|
||||
border: 1px solid $border-color;
|
||||
border-radius: $border-radius-default;
|
||||
color: $almost-black;
|
||||
|
||||
.tree-content-holder {
|
||||
display: flex;
|
||||
max-height: 100vh;
|
||||
min-height: 300px;
|
||||
}
|
||||
|
||||
.tree-content-holder-mini {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.panel-right {
|
||||
display: inline-block;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 80%;
|
||||
height: 100%;
|
||||
|
||||
.monaco-editor.vs {
|
||||
.line-numbers {
|
||||
|
@ -85,16 +97,17 @@
|
|||
}
|
||||
|
||||
.blob-viewer-container {
|
||||
height: calc(100vh - 62px);
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
#tabs {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding-left: 0;
|
||||
margin-bottom: 0;
|
||||
display: flex;
|
||||
white-space: nowrap;
|
||||
width: 100%;
|
||||
overflow-y: hidden;
|
||||
overflow-x: auto;
|
||||
|
||||
|
@ -222,14 +235,12 @@
|
|||
}
|
||||
|
||||
#sidebar {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
|
||||
&.sidebar-mini {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
width: 20%;
|
||||
border-right: 1px solid $white-normal;
|
||||
min-height: 475px;
|
||||
height: calc(100vh + 20px);
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ module IssuableActions
|
|||
def destroy
|
||||
issuable.destroy
|
||||
destroy_method = "destroy_#{issuable.class.name.underscore}".to_sym
|
||||
TodoService.new.public_send(destroy_method, issuable, current_user)
|
||||
TodoService.new.public_send(destroy_method, issuable, current_user) # rubocop:disable GitlabSecurity/PublicSend
|
||||
|
||||
name = issuable.human_class_name
|
||||
flash[:notice] = "The #{name} was successfully deleted."
|
||||
|
|
|
@ -64,7 +64,7 @@ class Import::GithubController < Import::BaseController
|
|||
end
|
||||
|
||||
def import_enabled?
|
||||
__send__("#{provider}_import_enabled?")
|
||||
__send__("#{provider}_import_enabled?") # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
def new_import_url
|
||||
|
|
|
@ -89,7 +89,7 @@ class UploadsController < ApplicationController
|
|||
|
||||
@uploader.retrieve_from_store!(params[:filename])
|
||||
else
|
||||
@uploader = @model.send(upload_mount)
|
||||
@uploader = @model.public_send(upload_mount) # rubocop:disable GitlabSecurity/PublicSend
|
||||
|
||||
redirect_to @uploader.url unless @uploader.file_storage?
|
||||
end
|
||||
|
|
|
@ -128,10 +128,10 @@ module CommitsHelper
|
|||
# avatar: true will prepend the avatar image
|
||||
# size: size of the avatar image in px
|
||||
def commit_person_link(commit, options = {})
|
||||
user = commit.send(options[:source])
|
||||
user = commit.public_send(options[:source]) # rubocop:disable GitlabSecurity/PublicSend
|
||||
|
||||
source_name = clean(commit.send "#{options[:source]}_name".to_sym)
|
||||
source_email = clean(commit.send "#{options[:source]}_email".to_sym)
|
||||
source_name = clean(commit.public_send(:"#{options[:source]}_name")) # rubocop:disable GitlabSecurity/PublicSend
|
||||
source_email = clean(commit.public_send(:"#{options[:source]}_email")) # rubocop:disable GitlabSecurity/PublicSend
|
||||
|
||||
person_name = user.try(:name) || source_name
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ module ImportHelper
|
|||
end
|
||||
|
||||
def provider_project_link(provider, path_with_namespace)
|
||||
url = __send__("#{provider}_project_url", path_with_namespace)
|
||||
url = __send__("#{provider}_project_url", path_with_namespace) # rubocop:disable GitlabSecurity/PublicSend
|
||||
|
||||
link_to path_with_namespace, url, target: '_blank', rel: 'noopener noreferrer'
|
||||
end
|
||||
|
|
|
@ -174,7 +174,14 @@ module IssuablesHelper
|
|||
end
|
||||
|
||||
def assigned_issuables_count(issuable_type)
|
||||
current_user.public_send("assigned_open_#{issuable_type}_count")
|
||||
case issuable_type
|
||||
when :issues
|
||||
current_user.assigned_open_issues_count
|
||||
when :merge_requests
|
||||
current_user.assigned_open_merge_requests_count
|
||||
else
|
||||
raise ArgumentError, "invalid issuable `#{issuable_type}`"
|
||||
end
|
||||
end
|
||||
|
||||
def issuable_filter_params
|
||||
|
@ -298,10 +305,6 @@ module IssuablesHelper
|
|||
cookies[:collapsed_gutter] == 'true'
|
||||
end
|
||||
|
||||
def base_issuable_scope(issuable)
|
||||
issuable.project.send(issuable.class.table_name).send(issuable_state_scope(issuable))
|
||||
end
|
||||
|
||||
def issuable_state_scope(issuable)
|
||||
if issuable.respond_to?(:merged?) && issuable.merged?
|
||||
:merged
|
||||
|
|
|
@ -32,7 +32,18 @@ module MilestonesHelper
|
|||
end
|
||||
|
||||
def milestone_issues_by_label_count(milestone, label, state:)
|
||||
milestone.issues.with_label(label.title).send(state).size
|
||||
issues = milestone.issues.with_label(label.title)
|
||||
issues =
|
||||
case state
|
||||
when :opened
|
||||
issues.opened
|
||||
when :closed
|
||||
issues.closed
|
||||
else
|
||||
raise ArgumentError, "invalid milestone state `#{state}`"
|
||||
end
|
||||
|
||||
issues.size
|
||||
end
|
||||
|
||||
# Returns count of milestones for different states
|
||||
|
|
|
@ -149,15 +149,16 @@ module ProjectsHelper
|
|||
# Don't show option "everyone with access" if project is private
|
||||
options = project_feature_options
|
||||
|
||||
level = @project.project_feature.public_send(field) # rubocop:disable GitlabSecurity/PublicSend
|
||||
|
||||
if @project.private?
|
||||
level = @project.project_feature.send(field)
|
||||
disabled_option = ProjectFeature::ENABLED
|
||||
highest_available_option = ProjectFeature::PRIVATE if level == disabled_option
|
||||
end
|
||||
|
||||
options = options_for_select(
|
||||
options.invert,
|
||||
selected: highest_available_option || @project.project_feature.public_send(field),
|
||||
selected: highest_available_option || level,
|
||||
disabled: disabled_option
|
||||
)
|
||||
|
||||
|
@ -488,7 +489,7 @@ module ProjectsHelper
|
|||
end
|
||||
|
||||
def filename_path(project, filename)
|
||||
if project && blob = project.repository.send(filename)
|
||||
if project && blob = project.repository.public_send(filename) # rubocop:disable GitlabSecurity/PublicSend
|
||||
project_blob_path(
|
||||
project,
|
||||
tree_join(project.default_branch, blob.name)
|
||||
|
|
|
@ -2,7 +2,7 @@ module VersionCheckHelper
|
|||
def version_status_badge
|
||||
if Rails.env.production? && current_application_settings.version_check_enabled
|
||||
image_url = VersionCheck.new.url
|
||||
image_tag image_url, class: 'js-version-status-badge', lazy: false
|
||||
image_tag image_url, class: 'js-version-status-badge'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -194,10 +194,7 @@ module Ci
|
|||
# * Maximum length is 63 bytes
|
||||
# * First/Last Character is not a hyphen
|
||||
def ref_slug
|
||||
ref.to_s
|
||||
.downcase
|
||||
.gsub(/[^a-z0-9]/, '-')[0..62]
|
||||
.gsub(/(\A-+|-+\z)/, '')
|
||||
Gitlab::Utils.slugify(ref.to_s)
|
||||
end
|
||||
|
||||
# Variables whose value does not depend on environment
|
||||
|
|
|
@ -200,7 +200,7 @@ class Commit
|
|||
end
|
||||
|
||||
def method_missing(m, *args, &block)
|
||||
@raw.send(m, *args, &block)
|
||||
@raw.__send__(m, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
def respond_to_missing?(method, include_private = false)
|
||||
|
@ -383,6 +383,6 @@ class Commit
|
|||
end
|
||||
|
||||
def gpg_commit
|
||||
@gpg_commit ||= Gitlab::Gpg::Commit.new(self)
|
||||
@gpg_commit ||= Gitlab::Gpg::Commit.for_commit(self)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -78,7 +78,7 @@ module CacheMarkdownField
|
|||
def cached_html_up_to_date?(markdown_field)
|
||||
html_field = cached_markdown_fields.html_field(markdown_field)
|
||||
|
||||
cached = cached_html_for(markdown_field).present? && __send__(markdown_field).present?
|
||||
cached = cached_html_for(markdown_field).present? && __send__(markdown_field).present? # rubocop:disable GitlabSecurity/PublicSend
|
||||
return false unless cached
|
||||
|
||||
markdown_changed = attribute_changed?(markdown_field) || false
|
||||
|
@ -93,14 +93,14 @@ module CacheMarkdownField
|
|||
end
|
||||
|
||||
def attribute_invalidated?(attr)
|
||||
__send__("#{attr}_invalidated?")
|
||||
__send__("#{attr}_invalidated?") # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
def cached_html_for(markdown_field)
|
||||
raise ArgumentError.new("Unknown field: #{field}") unless
|
||||
cached_markdown_fields.markdown_fields.include?(markdown_field)
|
||||
|
||||
__send__(cached_markdown_fields.html_field(markdown_field))
|
||||
__send__(cached_markdown_fields.html_field(markdown_field)) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
included do
|
||||
|
|
|
@ -9,7 +9,7 @@ module InternalId
|
|||
def set_iid
|
||||
if iid.blank?
|
||||
parent = project || group
|
||||
records = parent.send(self.class.name.tableize)
|
||||
records = parent.public_send(self.class.name.tableize) # rubocop:disable GitlabSecurity/PublicSend
|
||||
records = records.with_deleted if self.paranoid?
|
||||
max_iid = records.maximum(:iid)
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ module Mentionable
|
|||
end
|
||||
|
||||
self.class.mentionable_attrs.each do |attr, options|
|
||||
text = __send__(attr)
|
||||
text = __send__(attr) # rubocop:disable GitlabSecurity/PublicSend
|
||||
options = options.merge(
|
||||
cache_key: [self, attr],
|
||||
author: author,
|
||||
|
@ -100,7 +100,7 @@ module Mentionable
|
|||
end
|
||||
|
||||
self.class.mentionable_attrs.any? do |attr, _|
|
||||
__send__(attr) =~ reference_pattern
|
||||
__send__(attr) =~ reference_pattern # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ module Participable
|
|||
if attr.respond_to?(:call)
|
||||
source.instance_exec(current_user, ext, &attr)
|
||||
else
|
||||
process << source.__send__(attr)
|
||||
process << source.__send__(attr) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
end
|
||||
when Enumerable, ActiveRecord::Relation
|
||||
|
|
|
@ -32,6 +32,6 @@ module ProjectFeaturesCompatibility
|
|||
build_project_feature unless project_feature
|
||||
|
||||
access_level = Gitlab::Utils.to_boolean(value) ? ProjectFeature::ENABLED : ProjectFeature::DISABLED
|
||||
project_feature.send(:write_attribute, field, access_level)
|
||||
project_feature.__send__(:write_attribute, field, access_level) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,4 +18,8 @@ class GpgSignature < ActiveRecord::Base
|
|||
def commit
|
||||
project.commit(commit_sha)
|
||||
end
|
||||
|
||||
def gpg_commit
|
||||
Gitlab::Gpg::Commit.new(project, commit_sha)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,7 @@ module Network
|
|||
end
|
||||
|
||||
def method_missing(m, *args, &block)
|
||||
@commit.send(m, *args, &block)
|
||||
@commit.__send__(m, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
def space
|
||||
|
|
|
@ -920,14 +920,14 @@ class Project < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def execute_hooks(data, hooks_scope = :push_hooks)
|
||||
hooks.send(hooks_scope).each do |hook|
|
||||
hooks.public_send(hooks_scope).each do |hook| # rubocop:disable GitlabSecurity/PublicSend
|
||||
hook.async_execute(data, hooks_scope.to_s)
|
||||
end
|
||||
end
|
||||
|
||||
def execute_services(data, hooks_scope = :push_hooks)
|
||||
# Call only service hooks that are active for this scope
|
||||
services.send(hooks_scope).each do |service|
|
||||
services.public_send(hooks_scope).each do |service| # rubocop:disable GitlabSecurity/PublicSend
|
||||
service.async_execute(data)
|
||||
end
|
||||
end
|
||||
|
@ -1282,12 +1282,16 @@ class Project < ActiveRecord::Base
|
|||
status.zero?
|
||||
end
|
||||
|
||||
def full_path_slug
|
||||
Gitlab::Utils.slugify(full_path.to_s)
|
||||
end
|
||||
|
||||
def predefined_variables
|
||||
[
|
||||
{ key: 'CI_PROJECT_ID', value: id.to_s, public: true },
|
||||
{ key: 'CI_PROJECT_NAME', value: path, public: true },
|
||||
{ key: 'CI_PROJECT_PATH', value: full_path, public: true },
|
||||
{ key: 'CI_PROJECT_PATH_SLUG', value: full_path.parameterize, public: true },
|
||||
{ key: 'CI_PROJECT_PATH_SLUG', value: full_path_slug, public: true },
|
||||
{ key: 'CI_PROJECT_NAMESPACE', value: namespace.full_path, public: true },
|
||||
{ key: 'CI_PROJECT_URL', value: web_url, public: true }
|
||||
]
|
||||
|
|
|
@ -115,7 +115,7 @@ class ChatNotificationService < Service
|
|||
|
||||
def get_channel_field(event)
|
||||
field_name = event_channel_name(event)
|
||||
self.public_send(field_name)
|
||||
self.public_send(field_name) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
def build_event_channels
|
||||
|
|
|
@ -53,7 +53,7 @@ class HipchatService < Service
|
|||
return unless supported_events.include?(data[:object_kind])
|
||||
message = create_message(data)
|
||||
return unless message.present?
|
||||
gate[room].send('GitLab', message, message_options(data))
|
||||
gate[room].send('GitLab', message, message_options(data)) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
def test(data)
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
class ProtectableDropdown
|
||||
REF_TYPES = %i[branches tags].freeze
|
||||
|
||||
def initialize(project, ref_type)
|
||||
raise ArgumentError, "invalid ref type `#{ref_type}`" unless ref_type.in?(REF_TYPES)
|
||||
|
||||
@project = project
|
||||
@ref_type = ref_type
|
||||
end
|
||||
|
@ -16,7 +20,7 @@ class ProtectableDropdown
|
|||
private
|
||||
|
||||
def refs
|
||||
@project.repository.public_send(@ref_type)
|
||||
@project.repository.public_send(@ref_type) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
def ref_names
|
||||
|
@ -24,7 +28,7 @@ class ProtectableDropdown
|
|||
end
|
||||
|
||||
def protections
|
||||
@project.public_send("protected_#{@ref_type}")
|
||||
@project.public_send("protected_#{@ref_type}") # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
def non_wildcard_protected_ref_names
|
||||
|
|
|
@ -48,7 +48,9 @@ class Repository
|
|||
alias_method(original, name)
|
||||
|
||||
define_method(name) do
|
||||
cache_method_output(name, fallback: fallback, memoize_only: memoize_only) { __send__(original) }
|
||||
cache_method_output(name, fallback: fallback, memoize_only: memoize_only) do
|
||||
__send__(original) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -443,9 +445,9 @@ class Repository
|
|||
def method_missing(m, *args, &block)
|
||||
if m == :lookup && !block_given?
|
||||
lookup_cache[m] ||= {}
|
||||
lookup_cache[m][args.join(":")] ||= raw_repository.send(m, *args, &block)
|
||||
lookup_cache[m][args.join(":")] ||= raw_repository.__send__(m, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
|
||||
else
|
||||
raw_repository.send(m, *args, &block)
|
||||
raw_repository.__send__(m, *args, &block) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -776,7 +778,7 @@ class Repository
|
|||
end
|
||||
|
||||
actions.each do |options|
|
||||
index.public_send(options.delete(:action), options)
|
||||
index.public_send(options.delete(:action), options) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
options = {
|
||||
|
|
|
@ -1070,7 +1070,7 @@ class User < ActiveRecord::Base
|
|||
# Added according to https://github.com/plataformatec/devise/blob/7df57d5081f9884849ca15e4fde179ef164a575f/README.md#activejob-integration
|
||||
def send_devise_notification(notification, *args)
|
||||
return true unless can?(:receive_notifications)
|
||||
devise_mailer.send(notification, self, *args).deliver_later
|
||||
devise_mailer.__send__(notification, self, *args).deliver_later # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
# This works around a bug in Devise 4.2.0 that erroneously causes a user to
|
||||
|
|
|
@ -58,7 +58,7 @@ class AkismetService
|
|||
}
|
||||
|
||||
begin
|
||||
akismet_client.public_send(type, options[:ip_address], options[:user_agent], params)
|
||||
akismet_client.public_send(type, options[:ip_address], options[:user_agent], params) # rubocop:disable GitlabSecurity/PublicSend
|
||||
true
|
||||
rescue => e
|
||||
Rails.logger.error("Unable to connect to Akismet: #{e}, skipping!")
|
||||
|
|
|
@ -23,7 +23,7 @@ module Ci
|
|||
end
|
||||
|
||||
attributes = CLONE_ACCESSORS.map do |attribute|
|
||||
[attribute, build.send(attribute)]
|
||||
[attribute, build.public_send(attribute)] # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
attributes.push([:user, current_user])
|
||||
|
|
|
@ -11,6 +11,7 @@ module Commits
|
|||
def commit_change(action)
|
||||
raise NotImplementedError unless repository.respond_to?(action)
|
||||
|
||||
# rubocop:disable GitlabSecurity/PublicSend
|
||||
repository.public_send(
|
||||
action,
|
||||
current_user,
|
||||
|
|
|
@ -90,8 +90,19 @@ class GitPushService < BaseService
|
|||
end
|
||||
|
||||
def update_signatures
|
||||
@push_commits.each do |commit|
|
||||
CreateGpgSignatureWorker.perform_async(commit.sha, @project.id)
|
||||
commit_shas = @push_commits.last(PROCESS_COMMIT_LIMIT).map(&:sha)
|
||||
|
||||
return if commit_shas.empty?
|
||||
|
||||
shas_with_cached_signatures = GpgSignature.where(commit_sha: commit_shas).pluck(:commit_sha)
|
||||
commit_shas -= shas_with_cached_signatures
|
||||
|
||||
return if commit_shas.empty?
|
||||
|
||||
commit_shas = Gitlab::Git::Commit.shas_with_signatures(project.repository, commit_shas)
|
||||
|
||||
commit_shas.each do |sha|
|
||||
CreateGpgSignatureWorker.perform_async(sha, project.id)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -338,7 +338,7 @@ class IssuableBaseService < BaseService
|
|||
|
||||
def invalidate_cache_counts(issuable, users: [], skip_project_cache: false)
|
||||
users.each do |user|
|
||||
user.public_send("invalidate_#{issuable.model_name.singular}_cache_counts")
|
||||
user.public_send("invalidate_#{issuable.model_name.singular}_cache_counts") # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
unless skip_project_cache
|
||||
|
|
|
@ -31,7 +31,7 @@ module Members
|
|||
source.members.find_by(condition) ||
|
||||
source.requesters.find_by!(condition)
|
||||
else
|
||||
source.public_send(scope).find_by!(condition)
|
||||
source.public_send(scope).find_by!(condition) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ module MergeRequests
|
|||
end
|
||||
|
||||
def after_create(issuable)
|
||||
event_service.open_mr(issuable, current_user)
|
||||
todo_service.new_merge_request(issuable, current_user)
|
||||
issuable.cache_merge_request_closes_issues!(current_user)
|
||||
update_merge_requests_head_pipeline(issuable)
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# rubocop:disable GitlabSecurity/PublicSend
|
||||
|
||||
# NotificationService class
|
||||
#
|
||||
# Used for notifying users with emails about different events
|
||||
|
|
|
@ -4,7 +4,7 @@ class SystemHooksService
|
|||
end
|
||||
|
||||
def execute_hooks(data, hooks_scope = :all)
|
||||
SystemHook.public_send(hooks_scope).find_each do |hook|
|
||||
SystemHook.public_send(hooks_scope).find_each do |hook| # rubocop:disable GitlabSecurity/PublicSend
|
||||
hook.async_execute(data, 'system_hooks')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,7 +18,7 @@ module TestHooks
|
|||
end
|
||||
|
||||
error_message = catch(:validation_error) do
|
||||
sample_data = self.__send__(trigger_data_method)
|
||||
sample_data = self.__send__(trigger_data_method) # rubocop:disable GitlabSecurity/PublicSend
|
||||
|
||||
return hook.execute(sample_data, trigger)
|
||||
end
|
||||
|
|
|
@ -189,7 +189,7 @@
|
|||
= icon('chevron-down')
|
||||
%ul.dropdown-menu
|
||||
%li
|
||||
%a Sort by date
|
||||
= link_to 'Sort by date', '#'
|
||||
|
||||
= link_to 'New issue', '#', class: 'btn btn-new btn-inverted'
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.nav-sidebar{ class: ("sidebar-icons-only" if collapsed_sidebar?) }
|
||||
.nav-sidebar-inner-scroll
|
||||
.context-header
|
||||
= link_to admin_root_path, title: 'Admin Overview' do
|
||||
.avatar-container.s40.settings-avatar
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.nav-sidebar{ class: ("sidebar-icons-only" if collapsed_sidebar?) }
|
||||
.nav-sidebar-inner-scroll
|
||||
.context-header
|
||||
= link_to group_path(@group), title: @group.name do
|
||||
.avatar-container.s40.group-avatar
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.nav-sidebar{ class: ("sidebar-icons-only" if collapsed_sidebar?) }
|
||||
.nav-sidebar-inner-scroll
|
||||
.context-header
|
||||
= link_to profile_path, title: 'Profile Settings' do
|
||||
.avatar-container.s40.settings-avatar
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
.nav-sidebar{ class: ("sidebar-icons-only" if collapsed_sidebar?) }
|
||||
.nav-sidebar-inner-scroll
|
||||
- can_edit = can?(current_user, :admin_project, @project)
|
||||
.context-header
|
||||
= link_to project_path(@project), title: @project.name do
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
= link_to 'Close merge request', merge_request_path(@merge_request, merge_request: { state_event: :close }), method: :put, class: "btn btn-nr btn-comment btn-close close-mr-link js-note-target-close", title: "Close merge request", data: { original_text: "Close merge request", alternative_text: "Comment & close merge request"}
|
||||
- if @merge_request.reopenable?
|
||||
= link_to 'Reopen merge request', merge_request_path(@merge_request, merge_request: { state_event: :reopen }), method: :put, class: "btn btn-nr btn-comment btn-reopen reopen-mr-link js-note-target-close js-note-target-reopen", title: "Reopen merge request", data: { original_text: "Reopen merge request", alternative_text: "Comment & reopen merge request"}
|
||||
%comment-and-resolve-btn{ "inline-template" => true, ":discussion-id" => "" }
|
||||
%comment-and-resolve-btn{ "inline-template" => true }
|
||||
%button.btn.btn-nr.btn-default.append-right-10.js-comment-resolve-button{ "v-if" => "showButton", type: "submit", data: { project_path: "#{project_path(@merge_request.project)}" } }
|
||||
{{ buttonText }}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
.col-sm-6.milestone-actions
|
||||
- if can?(current_user, :admin_milestones, @group)
|
||||
- if milestone.is_group_milestone?
|
||||
= link_to edit_group_milestone_path(@group, milestone.id), class: "btn btn-xs btn-grouped" do
|
||||
= link_to edit_group_milestone_path(@group, milestone), class: "btn btn-xs btn-grouped" do
|
||||
Edit
|
||||
\
|
||||
- if milestone.closed?
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
.pull-right
|
||||
- if can?(current_user, :admin_milestones, group)
|
||||
- if milestone.is_group_milestone?
|
||||
= link_to edit_group_milestone_path(group, milestone.iid), class: "btn btn btn-grouped" do
|
||||
= link_to edit_group_milestone_path(group, milestone), class: "btn btn btn-grouped" do
|
||||
Edit
|
||||
- if milestone.active?
|
||||
= link_to 'Close Milestone', group_milestone_route(milestone, {state_event: :close }), method: :put, class: "btn btn-grouped btn-close"
|
||||
|
|
|
@ -4,13 +4,9 @@ class CreateGpgSignatureWorker
|
|||
|
||||
def perform(commit_sha, project_id)
|
||||
project = Project.find_by(id: project_id)
|
||||
|
||||
return unless project
|
||||
|
||||
commit = project.commit(commit_sha)
|
||||
|
||||
return unless commit
|
||||
|
||||
commit.signature
|
||||
# This calculates and caches the signature in the database
|
||||
Gitlab::Gpg::Commit.new(project, commit_sha).signature
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,6 +4,6 @@ class GitlabShellWorker
|
|||
include DedicatedSidekiqQueue
|
||||
|
||||
def perform(action, *arg)
|
||||
gitlab_shell.send(action, *arg)
|
||||
gitlab_shell.__send__(action, *arg) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Added tests for commits API unauthenticated user and public/private project
|
||||
merge_request: 13287
|
||||
author: Jacopo Beschi @jacopo-beschi
|
4
changelogs/unreleased/34643-fix-project-path-slugify.yml
Normal file
4
changelogs/unreleased/34643-fix-project-path-slugify.yml
Normal file
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Fix CI_PROJECT_PATH_SLUG slugify
|
||||
merge_request: 13350
|
||||
author: Ivan Chernov
|
5
changelogs/unreleased/commits-list-page-limit.yml
Normal file
5
changelogs/unreleased/commits-list-page-limit.yml
Normal file
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix commit list not loading the correct page when scrolling
|
||||
merge_request:
|
||||
author:
|
||||
type: fixed
|
|
@ -649,6 +649,9 @@ test:
|
|||
default:
|
||||
path: tmp/tests/repositories/
|
||||
gitaly_address: unix:tmp/tests/gitaly/gitaly.socket
|
||||
failure_count_threshold: 999999
|
||||
failure_wait_time: 0
|
||||
storage_timeout: 30
|
||||
broken:
|
||||
path: tmp/tests/non-existent-repositories
|
||||
gitaly_address: unix:tmp/tests/gitaly/gitaly.socket
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
# rubocop:disable GitlabSecurity/PublicSend
|
||||
|
||||
require_dependency Rails.root.join('lib/gitlab') # Load Gitlab as soon as possible
|
||||
|
||||
class Settings < Settingslogic
|
||||
|
|
|
@ -37,12 +37,12 @@ def validate_storages_config
|
|||
storage_validation_error("#{name} is not a valid storage, because it has no `path` key. Refer to gitlab.yml.example for an updated example")
|
||||
end
|
||||
|
||||
%w(failure_count_threshold failure_wait_time failure_reset_time storage_timeout).each do |setting|
|
||||
%w(failure_count_threshold failure_reset_time storage_timeout).each do |setting|
|
||||
# Falling back to the defaults is fine!
|
||||
next if repository_storage[setting].nil?
|
||||
|
||||
unless repository_storage[setting].to_f > 0
|
||||
storage_validation_error("#{setting}, for storage `#{name}` needs to be greater than 0")
|
||||
storage_validation_error("`#{setting}` for storage `#{name}` needs to be greater than 0")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
20
config/initializers/active_record_array_type_casting.rb
Normal file
20
config/initializers/active_record_array_type_casting.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
module ActiveRecord
|
||||
class PredicateBuilder
|
||||
class ArrayHandler
|
||||
module TypeCasting
|
||||
def call(attribute, value)
|
||||
# This is necessary because by default ActiveRecord does not respect
|
||||
# custom type definitions (like our `ShaAttribute`) when providing an
|
||||
# array in `where`, like in `where(commit_sha: [sha1, sha2, sha3])`.
|
||||
model = attribute.relation&.engine
|
||||
type = model.user_provided_columns[attribute.name] if model
|
||||
value = value.map { |value| type.type_cast_for_database(value) } if type
|
||||
|
||||
super(attribute, value)
|
||||
end
|
||||
end
|
||||
|
||||
prepend TypeCasting
|
||||
end
|
||||
end
|
||||
end
|
26
db/post_migrate/20170815060945_remove_duplicate_mr_events.rb
Normal file
26
db/post_migrate/20170815060945_remove_duplicate_mr_events.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
|
||||
# for more information on how to write migrations for GitLab.
|
||||
|
||||
class RemoveDuplicateMrEvents < ActiveRecord::Migration
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
DOWNTIME = false
|
||||
|
||||
class Event < ActiveRecord::Base
|
||||
self.table_name = 'events'
|
||||
end
|
||||
|
||||
def up
|
||||
base_condition = "action = 1 AND target_type = 'MergeRequest' AND created_at > '2017-08-13'"
|
||||
Event.select('target_id, count(*)')
|
||||
.where(base_condition)
|
||||
.group('target_id').having('count(*) > 1').each do |event|
|
||||
duplicates = Event.where("#{base_condition} AND target_id = #{event.target_id}").pluck(:id)
|
||||
duplicates.shift
|
||||
|
||||
Event.where(id: duplicates).delete_all
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
end
|
||||
end
|
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20170809161910) do
|
||||
ActiveRecord::Schema.define(version: 20170815060945) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
## Databases
|
||||
|
||||
- [Merge Request Checklist](database_merge_request_checklist.md)
|
||||
- [What requires downtime?](what_requires_downtime.md)
|
||||
- [Adding database indexes](adding_database_indexes.md)
|
||||
- [Post Deployment Migrations](post_deployment_migrations.md)
|
||||
|
@ -56,6 +57,9 @@
|
|||
- [Background Migrations](background_migrations.md)
|
||||
- [Storing SHA1 Hashes As Binary](sha1_as_binary.md)
|
||||
- [Iterating Tables In Batches](iterating_tables_in_batches.md)
|
||||
- [Ordering Table Columns](ordering_table_columns.md)
|
||||
- [Verifying Database Capabilities](verifying_database_capabilities.md)
|
||||
- [Hash Indexes](hash_indexes.md)
|
||||
|
||||
## i18n
|
||||
|
||||
|
|
15
doc/development/database_merge_request_checklist.md
Normal file
15
doc/development/database_merge_request_checklist.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Merge Request Checklist
|
||||
|
||||
When creating a merge request that performs database related changes (schema
|
||||
changes, adjusting queries to optimise performance, etc) you should use the
|
||||
merge request template called "Database Changes". This template contains a
|
||||
checklist of steps to follow to make sure the changes are up to snuff.
|
||||
|
||||
To use the checklist, create a new merge request and click on the "Choose a
|
||||
template" dropdown, then click "Database Changes".
|
||||
|
||||
An example of this checklist can be found at
|
||||
https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/12463.
|
||||
|
||||
The source code of the checklist can be found in at
|
||||
https://gitlab.com/gitlab-org/gitlab-ce/blob/master/.gitlab/merge_request_templates/Database%20Changes.md
|
20
doc/development/hash_indexes.md
Normal file
20
doc/development/hash_indexes.md
Normal file
|
@ -0,0 +1,20 @@
|
|||
# Hash Indexes
|
||||
|
||||
Both PostgreSQL and MySQL support hash indexes besides the regular btree
|
||||
indexes. Hash indexes however are to be avoided at all costs. While they may
|
||||
_sometimes_ provide better performance the cost of rehashing can be very high.
|
||||
More importantly: at least until PostgreSQL 10.0 hash indexes are not
|
||||
WAL-logged, meaning they are not replicated to any replicas. From the PostgreSQL
|
||||
documentation:
|
||||
|
||||
> Hash index operations are not presently WAL-logged, so hash indexes might need
|
||||
> to be rebuilt with REINDEX after a database crash if there were unwritten
|
||||
> changes. Also, changes to hash indexes are not replicated over streaming or
|
||||
> file-based replication after the initial base backup, so they give wrong
|
||||
> answers to queries that subsequently use them. For these reasons, hash index
|
||||
> use is presently discouraged.
|
||||
|
||||
RuboCop is configured to register an offence when it detects the use of a hash
|
||||
index.
|
||||
|
||||
Instead of using hash indexes you should use regular btree indexes.
|
127
doc/development/ordering_table_columns.md
Normal file
127
doc/development/ordering_table_columns.md
Normal file
|
@ -0,0 +1,127 @@
|
|||
# Ordering Table Columns
|
||||
|
||||
Similar to C structures the space of a table is influenced by the order of
|
||||
columns. This is because the size of columns is aligned depending on the type of
|
||||
the column. Take the following column order for example:
|
||||
|
||||
* id (integer, 4 bytes)
|
||||
* name (text, variable)
|
||||
* user_id (integer, 4 bytes)
|
||||
|
||||
Integers are aligned to the word size. This means that on a 64 bit platform the
|
||||
actual size of each column would be: 8 bytes, variable, 8 bytes. This means that
|
||||
each row will require at least 16 bytes for the two integers, and a variable
|
||||
amount for the text field. If a table has a few rows this is not an issue, but
|
||||
once you start storing millions of rows you can save space by using a different
|
||||
order. For the above example a more ideal column order would be the following:
|
||||
|
||||
* id (integer, 4 bytes)
|
||||
* user_id (integer, 4 bytes)
|
||||
* name (text, variable)
|
||||
|
||||
In this setup the `id` and `user_id` columns can be packed together, which means
|
||||
we only need 8 bytes to store _both_ of them. This in turn each row will require
|
||||
8 bytes less of space.
|
||||
|
||||
For GitLab we require that columns of new tables are ordered based to use the
|
||||
least amount of space. An easy way of doing this is to order them based on the
|
||||
type size in descending order with variable sizes (string and text columns for
|
||||
example) at the end.
|
||||
|
||||
## Type Sizes
|
||||
|
||||
While the PostgreSQL docuemntation
|
||||
(https://www.postgresql.org/docs/current/static/datatype.html) contains plenty
|
||||
of information we will list the sizes of common types here so it's easier to
|
||||
look them up. Here "word" refers to the word size, which is 4 bytes for a 32
|
||||
bits platform and 8 bytes for a 64 bits platform.
|
||||
|
||||
| Type | Size | Aligned To |
|
||||
|:-----------------|:-------------------------------------|:-----------|
|
||||
| smallint | 2 bytes | 1 word |
|
||||
| integer | 4 bytes | 1 word |
|
||||
| bigint | 8 bytes | 8 bytes |
|
||||
| real | 4 bytes | 1 word |
|
||||
| double precision | 8 bytes | 8 bytes |
|
||||
| boolean | 1 byte | not needed |
|
||||
| text / string | variable, 1 byte plus the data | 1 word |
|
||||
| bytea | variable, 1 or 4 bytes plus the data | 1 word |
|
||||
| timestamp | 8 bytes | 8 bytes |
|
||||
| timestamptz | 8 bytes | 8 bytes |
|
||||
| date | 4 bytes | 1 word |
|
||||
|
||||
A "variable" size means the actual size depends on the value being stored. If
|
||||
PostgreSQL determines this can be embedded directly into a row it may do so, but
|
||||
for very large values it will store the data externally and store a pointer (of
|
||||
1 word in size) in the column. Because of this variable sized columns should
|
||||
always be at the end of a table.
|
||||
|
||||
## Real Example
|
||||
|
||||
Let's use the "events" table as an example, which currently has the following
|
||||
layout:
|
||||
|
||||
| Column | Type | Size |
|
||||
|:------------|:----------------------------|:---------|
|
||||
| id | integer | 4 bytes |
|
||||
| target_type | character varying | variable |
|
||||
| target_id | integer | 4 bytes |
|
||||
| title | character varying | variable |
|
||||
| data | text | variable |
|
||||
| project_id | integer | 4 bytes |
|
||||
| created_at | timestamp without time zone | 8 bytes |
|
||||
| updated_at | timestamp without time zone | 8 bytes |
|
||||
| action | integer | 4 bytes |
|
||||
| author_id | integer | 4 bytes |
|
||||
|
||||
After adding padding to align the columns this would translate to columns being
|
||||
divided into fixed size chunks as follows:
|
||||
|
||||
| Chunk Size | Columns |
|
||||
|:-----------|:------------------|
|
||||
| 8 bytes | id |
|
||||
| variable | target_type |
|
||||
| 8 bytes | target_id |
|
||||
| variable | title |
|
||||
| variable | data |
|
||||
| 8 bytes | project_id |
|
||||
| 8 bytes | created_at |
|
||||
| 8 bytes | updated_at |
|
||||
| 8 bytes | action, author_id |
|
||||
|
||||
This means that excluding the variable sized data we need at least 48 bytes per
|
||||
row.
|
||||
|
||||
We can optimise this by using the following column order instead:
|
||||
|
||||
| Column | Type | Size |
|
||||
|:------------|:----------------------------|:---------|
|
||||
| created_at | timestamp without time zone | 8 bytes |
|
||||
| updated_at | timestamp without time zone | 8 bytes |
|
||||
| id | integer | 4 bytes |
|
||||
| target_id | integer | 4 bytes |
|
||||
| project_id | integer | 4 bytes |
|
||||
| action | integer | 4 bytes |
|
||||
| author_id | integer | 4 bytes |
|
||||
| target_type | character varying | variable |
|
||||
| title | character varying | variable |
|
||||
| data | text | variable |
|
||||
|
||||
This would produce the following chunks:
|
||||
|
||||
| Chunk Size | Columns |
|
||||
|:-----------|:-------------------|
|
||||
| 8 bytes | created_at |
|
||||
| 8 bytes | updated_at |
|
||||
| 8 bytes | id, target_id |
|
||||
| 8 bytes | project_id, action |
|
||||
| 8 bytes | author_id |
|
||||
| variable | target_type |
|
||||
| variable | title |
|
||||
| variable | data |
|
||||
|
||||
Here we only need 40 bytes per row excluding the variable sized data. 8 bytes
|
||||
being saved may not sound like much, but for tables as large as the "events"
|
||||
table it does begin to matter. For example, when storing 80 000 000 rows this
|
||||
translates to a space saving of at least 610 MB: all by just changing the order
|
||||
of a few columns.
|
|
@ -1,7 +1,8 @@
|
|||
# Serializing Data
|
||||
|
||||
**Summary:** don't store serialized data in the database, use separate columns
|
||||
and/or tables instead.
|
||||
and/or tables instead. This includes storing of comma separated values as a
|
||||
string.
|
||||
|
||||
Rails makes it possible to store serialized data in JSON, YAML or other formats.
|
||||
Such a field can be defined as follows:
|
||||
|
|
|
@ -216,4 +216,30 @@ exact same results. This also means there's no need to add an index on
|
|||
`created_at` to ensure consistent performance as `id` is already indexed by
|
||||
default.
|
||||
|
||||
## Use WHERE EXISTS instead of WHERE IN
|
||||
|
||||
While `WHERE IN` and `WHERE EXISTS` can be used to produce the same data it is
|
||||
recommended to use `WHERE EXISTS` whenever possible. While in many cases
|
||||
PostgreSQL can optimise `WHERE IN` quite well there are also many cases where
|
||||
`WHERE EXISTS` will perform (much) better.
|
||||
|
||||
In Rails you have to use this by creating SQL fragments:
|
||||
|
||||
```ruby
|
||||
Project.where('EXISTS (?)', User.select(1).where('projects.creator_id = users.id AND users.foo = X'))
|
||||
```
|
||||
|
||||
This would then produce a query along the lines of the following:
|
||||
|
||||
```sql
|
||||
SELECT *
|
||||
FROM projects
|
||||
WHERE EXISTS (
|
||||
SELECT 1
|
||||
FROM users
|
||||
WHERE projects.creator_id = users.id
|
||||
AND users.foo = X
|
||||
)
|
||||
```
|
||||
|
||||
[gin-index]: http://www.postgresql.org/docs/current/static/gin.html
|
||||
|
|
26
doc/development/verifying_database_capabilities.md
Normal file
26
doc/development/verifying_database_capabilities.md
Normal file
|
@ -0,0 +1,26 @@
|
|||
# Verifying Database Capabilities
|
||||
|
||||
Sometimes certain bits of code may only work on a certain database and/or
|
||||
version. While we try to avoid such code as much as possible sometimes it is
|
||||
necessary to add database (version) specific behaviour.
|
||||
|
||||
To facilitate this we have the following methods that you can use:
|
||||
|
||||
* `Gitlab::Database.postgresql?`: returns `true` if PostgreSQL is being used
|
||||
* `Gitlab::Database.mysql?`: returns `true` if MySQL is being used
|
||||
* `Gitlab::Database.version`: returns the PostgreSQL version number as a string
|
||||
in the format `X.Y.Z`. This method does not work for MySQL
|
||||
|
||||
This allows you to write code such as:
|
||||
|
||||
```ruby
|
||||
if Gitlab::Database.postgresql?
|
||||
if Gitlab::Database.version.to_f >= 9.6
|
||||
run_really_fast_query
|
||||
else
|
||||
run_fast_query
|
||||
end
|
||||
else
|
||||
run_query
|
||||
end
|
||||
```
|
|
@ -1,5 +1,9 @@
|
|||
# How to create a project in GitLab
|
||||
|
||||
>**Notes:**
|
||||
- For a list of words that are not allowed to be used as project names see the
|
||||
[reserved names][reserved].
|
||||
|
||||
1. In your dashboard, click the green **New project** button or use the plus
|
||||
icon in the upper right corner of the navigation bar.
|
||||
|
||||
|
@ -26,3 +30,4 @@
|
|||
1. Click **Create project**.
|
||||
|
||||
[import it]: ../workflow/importing/README.md
|
||||
[reserved]: ../user/reserved_names.md
|
||||
|
|
|
@ -80,7 +80,7 @@ Make sure you have the right version of Git installed
|
|||
# Install Git
|
||||
sudo apt-get install -y git-core
|
||||
|
||||
# Make sure Git is version 2.8.4 or higher
|
||||
# Make sure Git is version 2.13.0 or higher
|
||||
git --version
|
||||
|
||||
Is the system packaged Git too old? Remove it and compile from source.
|
||||
|
|
|
@ -57,6 +57,10 @@ By doing so:
|
|||
|
||||
## Create a new group
|
||||
|
||||
> **Notes:**
|
||||
- For a list of words that are not allowed to be used as group names see the
|
||||
[reserved names][reserved].
|
||||
|
||||
You can create a group in GitLab from:
|
||||
|
||||
1. The Groups page: expand the left menu, click **Groups**, and click the green button **New group**:
|
||||
|
@ -214,3 +218,4 @@ for the group (GitLab admins only, available in [GitLab Enterprise Edition Start
|
|||
|
||||
[permissions]: ../permissions.md#permissions
|
||||
[ee]: https://about.gitlab.com/products/
|
||||
[reserved]: ../reserved_names.md
|
||||
|
|
|
@ -83,10 +83,7 @@ structure.
|
|||
- You need to be an Owner of a group in order to be able to create
|
||||
a subgroup. For more information check the [permissions table][permissions].
|
||||
- For a list of words that are not allowed to be used as group names see the
|
||||
[`path_regex.rb` file][reserved] under the `TOP_LEVEL_ROUTES`, `PROJECT_WILDCARD_ROUTES` and `GROUP_ROUTES` lists:
|
||||
- `TOP_LEVEL_ROUTES`: are names that are reserved as usernames or top level groups
|
||||
- `PROJECT_WILDCARD_ROUTES`: are names that are reserved for child groups or projects.
|
||||
- `GROUP_ROUTES`: are names that are reserved for all groups or projects.
|
||||
[reserved names][reserved].
|
||||
|
||||
To create a subgroup:
|
||||
|
||||
|
@ -175,5 +172,5 @@ Here's a list of what you can't do with subgroups:
|
|||
|
||||
[ce-2772]: https://gitlab.com/gitlab-org/gitlab-ce/issues/2772
|
||||
[permissions]: ../../permissions.md#group
|
||||
[reserved]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/path_regex.rb
|
||||
[reserved]: ../../reserved_names.md
|
||||
[issue]: https://gitlab.com/gitlab-org/gitlab-ce/issues/30472#note_27747600
|
||||
|
|
109
doc/user/reserved_names.md
Normal file
109
doc/user/reserved_names.md
Normal file
|
@ -0,0 +1,109 @@
|
|||
# Reserved project and group names
|
||||
|
||||
Not all project & group names are allowed because they would conflict with
|
||||
existing routes used by GitLab.
|
||||
|
||||
For a list of words that are not allowed to be used as group or project names, see the
|
||||
[`path_regex.rb` file][reserved] under the `TOP_LEVEL_ROUTES`, `PROJECT_WILDCARD_ROUTES` and `GROUP_ROUTES` lists:
|
||||
- `TOP_LEVEL_ROUTES`: are names that are reserved as usernames or top level groups
|
||||
- `PROJECT_WILDCARD_ROUTES`: are names that are reserved for child groups or projects.
|
||||
- `GROUP_ROUTES`: are names that are reserved for all groups or projects.
|
||||
|
||||
## Reserved project names
|
||||
|
||||
It is currently not possible to create a project with the following names:
|
||||
|
||||
- -
|
||||
- badges
|
||||
- blame
|
||||
- blob
|
||||
- builds
|
||||
- commits
|
||||
- create
|
||||
- create_dir
|
||||
- edit
|
||||
- environments/folders
|
||||
- files
|
||||
- find_file
|
||||
- gitlab-lfs/objects
|
||||
- info/lfs/objects
|
||||
- new
|
||||
- preview
|
||||
- raw
|
||||
- refs
|
||||
- tree
|
||||
- update
|
||||
- wikis
|
||||
|
||||
## Reserved group names
|
||||
|
||||
Currently the following names are reserved as top level groups:
|
||||
|
||||
- 503.html
|
||||
- -
|
||||
- .well-known
|
||||
- 404.html
|
||||
- 422.html
|
||||
- 500.html
|
||||
- 502.html
|
||||
- abuse_reports
|
||||
- admin
|
||||
- api
|
||||
- apple-touch-icon-precomposed.png
|
||||
- apple-touch-icon.png
|
||||
- files
|
||||
- assets
|
||||
- autocomplete
|
||||
- ci
|
||||
- dashboard
|
||||
- deploy.html
|
||||
- explore
|
||||
- favicon.ico
|
||||
- groups
|
||||
- header_logo_dark.png
|
||||
- header_logo_light.png
|
||||
- health_check
|
||||
- help
|
||||
- import
|
||||
- invites
|
||||
- jwt
|
||||
- koding
|
||||
- notification_settings
|
||||
- oauth
|
||||
- profile
|
||||
- projects
|
||||
- public
|
||||
- robots.txt
|
||||
- s
|
||||
- search
|
||||
- sent_notifications
|
||||
- slash-command-logo.png
|
||||
- snippets
|
||||
- u
|
||||
- unicorn_test
|
||||
- unsubscribes
|
||||
- uploads
|
||||
- users
|
||||
|
||||
These group names are unavailable as subgroup names:
|
||||
|
||||
- -
|
||||
- activity
|
||||
- analytics
|
||||
- audit_events
|
||||
- avatar
|
||||
- edit
|
||||
- group_members
|
||||
- hooks
|
||||
- issues
|
||||
- labels
|
||||
- ldap
|
||||
- ldap_group_links
|
||||
- merge_requests
|
||||
- milestones
|
||||
- notification_setting
|
||||
- pipeline_quota
|
||||
- projects
|
||||
- subgroups
|
||||
|
||||
[reserved]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/path_regex.rb
|
BIN
doc/user/search/img/group_issues_filter.png
Normal file
BIN
doc/user/search/img/group_issues_filter.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
|
@ -40,6 +40,14 @@ The same process is valid for merge requests. Navigate to your project's **Merge
|
|||
and click **Search or filter results...**. Merge requests can be filtered by author, assignee,
|
||||
milestone, and label.
|
||||
|
||||
## Issues and merge requests per group
|
||||
|
||||
Similar to **Issues and merge requests per project**, you can also search for issues
|
||||
within a group. Navigate to a group's **Issues** tab and query search results in
|
||||
the same way as you do for projects.
|
||||
|
||||
![filter issues in a group](img/group_issues_filter.png)
|
||||
|
||||
## Search history
|
||||
|
||||
You can view recent searches by clicking on the little arrow-clock icon, which is to the left of the search input. Click the search entry to run that search again. This feature is available for issues and merge requests. Searches are stored locally in your browser.
|
||||
|
|
|
@ -122,7 +122,7 @@ module API
|
|||
error_classes = [MissingTokenError, TokenNotFoundError,
|
||||
ExpiredError, RevokedError, InsufficientScopeError]
|
||||
|
||||
base.send :rescue_from, *error_classes, oauth2_bearer_token_error_handler
|
||||
base.__send__(:rescue_from, *error_classes, oauth2_bearer_token_error_handler) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
def oauth2_bearer_token_error_handler
|
||||
|
|
|
@ -541,8 +541,9 @@ module API
|
|||
target_url = "namespace_project_#{target_type}_url"
|
||||
target_anchor = "note_#{todo.note_id}" if todo.note_id?
|
||||
|
||||
Gitlab::Routing.url_helpers.public_send(target_url,
|
||||
todo.project.namespace, todo.project, todo.target, anchor: target_anchor)
|
||||
Gitlab::Routing
|
||||
.url_helpers
|
||||
.public_send(target_url, todo.project.namespace, todo.project, todo.target, anchor: target_anchor) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
expose :body
|
||||
|
|
|
@ -153,7 +153,7 @@ module API
|
|||
render_api_error!('Scope contains invalid value', 400)
|
||||
end
|
||||
|
||||
runners.send(scope)
|
||||
runners.public_send(scope) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
def get_runner(id)
|
||||
|
|
|
@ -22,7 +22,7 @@ module API
|
|||
use :pagination
|
||||
end
|
||||
get ":id/#{noteables_str}/:noteable_id/notes" do
|
||||
noteable = user_project.send(noteables_str.to_sym).find(params[:noteable_id])
|
||||
noteable = user_project.public_send(noteables_str.to_sym).find(params[:noteable_id]) # rubocop:disable GitlabSecurity/PublicSend
|
||||
|
||||
if can?(current_user, noteable_read_ability_name(noteable), noteable)
|
||||
# We exclude notes that are cross-references and that cannot be viewed
|
||||
|
@ -50,7 +50,7 @@ module API
|
|||
requires :noteable_id, type: Integer, desc: 'The ID of the noteable'
|
||||
end
|
||||
get ":id/#{noteables_str}/:noteable_id/notes/:note_id" do
|
||||
noteable = user_project.send(noteables_str.to_sym).find(params[:noteable_id])
|
||||
noteable = user_project.public_send(noteables_str.to_sym).find(params[:noteable_id]) # rubocop:disable GitlabSecurity/PublicSend
|
||||
note = noteable.notes.find(params[:note_id])
|
||||
can_read_note = can?(current_user, noteable_read_ability_name(noteable), noteable) && !note.cross_reference_not_visible_for?(current_user)
|
||||
|
||||
|
@ -76,7 +76,7 @@ module API
|
|||
noteable_id: params[:noteable_id]
|
||||
}
|
||||
|
||||
noteable = user_project.send(noteables_str.to_sym).find(params[:noteable_id])
|
||||
noteable = user_project.public_send(noteables_str.to_sym).find(params[:noteable_id]) # rubocop:disable GitlabSecurity/PublicSend
|
||||
|
||||
if can?(current_user, noteable_read_ability_name(noteable), noteable)
|
||||
if params[:created_at] && (current_user.admin? || user_project.owner == current_user)
|
||||
|
|
|
@ -95,10 +95,10 @@ module Banzai
|
|||
private
|
||||
|
||||
def external_issues_cached(attribute)
|
||||
return project.public_send(attribute) unless RequestStore.active?
|
||||
return project.public_send(attribute) unless RequestStore.active? # rubocop:disable GitlabSecurity/PublicSend
|
||||
|
||||
cached_attributes = RequestStore[:banzai_external_issues_tracker_attributes] ||= Hash.new { |h, k| h[k] = {} }
|
||||
cached_attributes[project.id][attribute] = project.public_send(attribute) if cached_attributes[project.id][attribute].nil?
|
||||
cached_attributes[project.id][attribute] = project.public_send(attribute) if cached_attributes[project.id][attribute].nil? # rubocop:disable GitlabSecurity/PublicSend
|
||||
cached_attributes[project.id][attribute]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -37,7 +37,7 @@ module Banzai
|
|||
|
||||
objects.each_with_index do |object, index|
|
||||
redacted_data = redacted[index]
|
||||
object.__send__("redacted_#{attribute}_html=", redacted_data[:document].to_html.html_safe)
|
||||
object.__send__("redacted_#{attribute}_html=", redacted_data[:document].to_html.html_safe) # rubocop:disable GitlabSecurity/PublicSend
|
||||
object.user_visible_reference_count = redacted_data[:visible_reference_count]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -18,7 +18,7 @@ module Banzai
|
|||
define_method(meth) do |text, context|
|
||||
context = transform_context(context)
|
||||
|
||||
html_pipeline.send(meth, text, context)
|
||||
html_pipeline.__send__(meth, text, context) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -43,7 +43,7 @@ module Banzai
|
|||
|
||||
# Same as +render_field+, but without consulting or updating the cache field
|
||||
def self.cacheless_render_field(object, field, options = {})
|
||||
text = object.__send__(field)
|
||||
text = object.__send__(field) # rubocop:disable GitlabSecurity/PublicSend
|
||||
context = object.banzai_render_context(field).merge(options)
|
||||
|
||||
cacheless_render(text, context)
|
||||
|
@ -156,7 +156,7 @@ module Banzai
|
|||
# method.
|
||||
def self.full_cache_multi_key(cache_key, pipeline_name)
|
||||
return unless cache_key
|
||||
Rails.cache.send(:expanded_key, full_cache_key(cache_key, pipeline_name))
|
||||
Rails.cache.__send__(:expanded_key, full_cache_key(cache_key, pipeline_name)) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
# GitLab EE needs to disable updates on GET requests in Geo
|
||||
|
|
|
@ -13,7 +13,7 @@ module Bitbucket
|
|||
def method_missing(method, *args)
|
||||
return super unless self.respond_to?(method)
|
||||
|
||||
self.send(method, *args) do |item|
|
||||
self.__send__(method, *args) do |item| # rubocop:disable GitlabSecurity/PublicSend
|
||||
block_given? ? yield(item) : item
|
||||
end
|
||||
end
|
||||
|
|
|
@ -208,7 +208,7 @@ module Ci
|
|||
return unless command = stack.shift()
|
||||
|
||||
if self.respond_to?("on_#{command}", true)
|
||||
self.send("on_#{command}", stack)
|
||||
self.__send__("on_#{command}", stack) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
evaluate_command_stack(stack)
|
||||
|
|
|
@ -109,7 +109,7 @@ module DeclarativePolicy
|
|||
name = name.to_sym
|
||||
|
||||
if delegation_block.nil?
|
||||
delegation_block = proc { @subject.__send__(name) }
|
||||
delegation_block = proc { @subject.__send__(name) } # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
own_delegations[name] = delegation_block
|
||||
|
|
|
@ -93,7 +93,7 @@ module DeclarativePolicy
|
|||
def method_missing(m, *a, &b)
|
||||
return super unless @context_class.respond_to?(m)
|
||||
|
||||
@context_class.__send__(m, *a, &b)
|
||||
@context_class.__send__(m, *a, &b) # rubocop:disable GitlabSecurity/PublicSend
|
||||
end
|
||||
|
||||
def respond_to_missing?(m)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue