Commit fbf241e8 authored by Filipa Lacerda's avatar Filipa Lacerda

Merge branch 'master' into issue-discussions-refactor

* master: (42 commits)
  alternative route for download archive
  Add missing command to compile GetText files
  Prevent user from changing username with container registry tags
  Rename RPC 'Exists' to 'RepositoryExists'
  Fix the sticky changes bar on commits page
  Fix ee_compat_check when EE branch uses a prefix
  Removed display styles when hiding the fly out navigation
  Explain why we use select all for project_url_constrainer.rb
  Fix pikaday being undefined
  Add a helper to stub storage settings with defaults
  Enable the Layout/SpaceBeforeBlockBraces cop
  update Install from Source instructions
  Translations can be picked without asking for exceptions
  Ask for exceptions in advance
  Don't require stackprof in Gemfile
  Synchronous Korean translation in zanata
  Use full path of user's avatar in webhooks
  Update icon color on hover
  Align all nav items in sidebar
  Fix height of collapsed sidebar items
  ...
parents 16b15a11 188181b7
......@@ -514,8 +514,11 @@ codeclimate:
services:
- docker:dind
script:
- cp .rubocop.yml .rubocop.yml.bak
- grep -v "rubocop-gitlab-security" .rubocop.yml.bak > .rubocop.yml
- docker run --env CODECLIMATE_CODE="$PWD" --volume "$PWD":/code --volume /var/run/docker.sock:/var/run/docker.sock --volume /tmp/cc:/tmp/cc codeclimate/codeclimate analyze -f json > raw_codeclimate.json
- cat raw_codeclimate.json | docker run -i stedolan/jq -c 'map({check_name,fingerprint,location})' > codeclimate.json
- mv .rubocop.yml.bak .rubocop.yml
artifacts:
paths: [codeclimate.json]
......
require:
- rubocop-rspec
- rubocop-gitlab-security
- ./rubocop/rubocop
inherit_from: .rubocop_todo.yml
......@@ -206,6 +207,13 @@ Layout/SpaceAroundKeyword:
Layout/SpaceAroundOperators:
Enabled: true
# Checks that block braces have or don't have a space before the opening
# brace depending on configuration.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: space, no_space
Layout/SpaceBeforeBlockBraces:
Enabled: true
# No spaces before commas.
Layout/SpaceBeforeComma:
Enabled: true
......@@ -1156,3 +1164,35 @@ RSpec/SubjectStub:
# Prefer using verifying doubles over normal doubles.
RSpec/VerifiedDoubles:
Enabled: false
# GitlabSecurity ##############################################################
GitlabSecurity/DeepMunge:
Enabled: true
Exclude:
- 'spec/**/*'
- 'lib/**/*.rake'
GitlabSecurity/PublicSend:
Enabled: true
Exclude:
- 'spec/**/*'
- 'lib/**/*.rake'
GitlabSecurity/RedirectToParamsUpdate:
Enabled: true
Exclude:
- 'spec/**/*'
- 'lib/**/*.rake'
GitlabSecurity/SqlInjection:
Enabled: true
Exclude:
- 'spec/**/*'
- 'lib/**/*.rake'
GitlabSecurity/SystemCommandInjection:
Enabled: true
Exclude:
- 'spec/**/*'
- 'lib/**/*.rake'
......@@ -26,13 +26,6 @@ Layout/IndentArray:
Layout/IndentHash:
Enabled: false
# Offense count: 174
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: space, no_space
Layout/SpaceBeforeBlockBraces:
Enabled: false
# Offense count: 8
# Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment.
......
......@@ -341,6 +341,7 @@ group :development, :test do
gem 'rubocop', '~> 0.49.1', require: false
gem 'rubocop-rspec', '~> 1.15.1', require: false
gem 'rubocop-gitlab-security', '~> 0.0.6', require: false
gem 'scss_lint', '~> 0.54.0', require: false
gem 'haml_lint', '~> 0.26.0', require: false
gem 'simplecov', '~> 0.14.0', require: false
......@@ -354,7 +355,7 @@ group :development, :test do
gem 'activerecord_sane_schema_dumper', '0.2'
gem 'stackprof', '~> 0.2.10'
gem 'stackprof', '~> 0.2.10', require: false
end
group :test do
......
......@@ -548,7 +548,7 @@ GEM
rubypants (~> 0.2)
orm_adapter (0.5.0)
os (0.9.6)
parallel (1.11.2)
parallel (1.12.0)
paranoia (2.3.1)
activerecord (>= 4.0, < 5.2)
parser (2.4.0.0)
......@@ -741,8 +741,9 @@ GEM
rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
rubocop-gitlab-security (0.0.6)
rubocop (>= 0.47.1)
rubocop-rspec (1.15.1)
rubocop (>= 0.42.0)
ruby-fogbugz (0.2.1)
crack (~> 0.4)
ruby-prof (0.16.2)
......@@ -1088,6 +1089,7 @@ DEPENDENCIES
rspec-set (~> 0.1.3)
rspec_profiling (~> 0.0.5)
rubocop (~> 0.49.1)
rubocop-gitlab-security (~> 0.0.6)
rubocop-rspec (~> 1.15.1)
ruby-fogbugz (~> 0.2.1)
ruby-prof (~> 0.16.2)
......
......@@ -119,6 +119,12 @@ only be left until after the freeze if:
are aware of it.
* It is in the correct milestone, with the ~Deliverable label.
If a merge request is not ready, but the developers and Product Manager
responsible for the feature think it is essential that it is in the release,
they can [ask for an exception](#asking-for-an-exception) in advance. This is
preferable to merging something that we are not confident in, but should still
be a rare case: most features can be allowed to slip a release.
All Community Edition merge requests from GitLab team members merged on the
freeze date (the 7th) should have a corresponding Enterprise Edition merge
request, even if there are no conflicts. This is to reduce the size of the
......@@ -128,11 +134,26 @@ information, see
### After the 7th
Once the stable branch is frozen, only fixes for [regressions](#regressions)
and security issues will be cherry-picked into the stable branch.
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.
Once the stable branch is frozen, the only MRs that can be cherry-picked into
the stable branch are:
* Fixes for [regressions](#regressions)
* 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.
### 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,
you can ask for an exception to be made. Exceptions require sign-off from 3 people besides the developer:
......@@ -152,11 +173,7 @@ When in doubt, we err on the side of _not_ cherry-picking.
For example, it is likely that an exception will be made for a trivial 1-5 line performance improvement
(e.g. adding a database index or adding `includes` to a query), but not for a new feature, no matter how relatively small or thoroughly tested.
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.
All MRs which have had exceptions granted must be merged by the 15th.
### Regressions
......
......@@ -76,6 +76,7 @@ import initLegacyFilters from './init_legacy_filters';
import initIssuableSidebar from './init_issuable_sidebar';
import GpgBadges from './gpg_badges';
import UserFeatureHelper from './helpers/user_feature_helper';
import initChangesDropdown from './init_changes_dropdown';
(function() {
var Dispatcher;
......@@ -227,6 +228,7 @@ import UserFeatureHelper from './helpers/user_feature_helper';
break;
case 'projects:compare:show':
new gl.Diff();
initChangesDropdown();
break;
case 'projects:branches:new':
case 'projects:branches:create':
......@@ -319,6 +321,7 @@ import UserFeatureHelper from './helpers/user_feature_helper';
container: '.js-commit-pipeline-graph',
}).bindEvents();
initNotes();
initChangesDropdown();
$('.commit-info.branches').load(document.querySelector('.js-commit-box').dataset.commitPath);
break;
case 'projects:commit:pipelines':
......
/* eslint-disable wrap-iife, func-names, space-before-function-paren, comma-dangle, prefer-template, consistent-return, class-methods-use-this, arrow-body-style, no-unused-vars, no-underscore-dangle, no-new, max-len, no-sequences, no-unused-expressions, no-param-reassign */
/* global dateFormat */
/* global Pikaday */
import Pikaday from 'pikaday';
import DateFix from './lib/utils/datefix';
class DueDateSelect {
......
/* global bp */
import Cookies from 'js-cookie';
import './breakpoints';
export const canShowSubItems = () => bp.getBreakpointSize() === 'md' || bp.getBreakpointSize() === 'lg';
export const canShowActiveSubItems = (el) => {
const isHiddenByMedia = bp.getBreakpointSize() === 'sm' || bp.getBreakpointSize() === 'md';
if (el.classList.contains('active') && !isHiddenByMedia) {
return Cookies.get('sidebar_collapsed') === 'true';
}
return true;
};
export const canShowSubItems = () => bp.getBreakpointSize() === 'sm' || bp.getBreakpointSize() === 'md' || bp.getBreakpointSize() === 'lg';
export const calculateTop = (boundingRect, outerHeight) => {
const windowHeight = window.innerHeight;
......@@ -14,9 +24,10 @@ export const calculateTop = (boundingRect, outerHeight) => {
export const showSubLevelItems = (el) => {
const subItems = el.querySelector('.sidebar-sub-level-items');
if (!subItems || !canShowSubItems()) return;
if (!subItems || !canShowSubItems() || !canShowActiveSubItems(el)) return;
subItems.style.display = 'block';
el.classList.add('is-showing-fly-out');
el.classList.add('is-over');
const boundingRect = el.getBoundingClientRect();
......@@ -34,15 +45,17 @@ export const showSubLevelItems = (el) => {
export const hideSubLevelItems = (el) => {
const subItems = el.querySelector('.sidebar-sub-level-items');
if (!subItems || !canShowSubItems()) return;
if (!subItems || !canShowSubItems() || !canShowActiveSubItems(el)) return;
el.classList.remove('is-showing-fly-out');
el.classList.remove('is-over');
subItems.style.display = 'none';
subItems.style.display = '';
subItems.style.transform = '';
subItems.classList.remove('is-above');
};
export default () => {
const items = [...document.querySelectorAll('.sidebar-top-level-items > li:not(.active)')]
const items = [...document.querySelectorAll('.sidebar-top-level-items > li')]
.filter(el => el.querySelector('.sidebar-sub-level-items'));
items.forEach((el) => {
......
import stickyMonitor from './lib/utils/sticky';
export default () => {
stickyMonitor(document.querySelector('.js-diff-files-changed'));
$('.js-diff-stats-dropdown').glDropdown({
filterable: true,
remoteFilter: false,
});
};
......@@ -2,8 +2,8 @@
/* global GitLab */
/* global Autosave */
/* global dateFormat */
/* global Pikaday */
import Pikaday from 'pikaday';
import UsersSelect from './users_select';
import GfmAutoComplete from './gfm_auto_complete';
import ZenMode from './zen_mode';
......
......@@ -7,7 +7,6 @@
import jQuery from 'jquery';
import _ from 'underscore';
import Cookies from 'js-cookie';
import Pikaday from 'pikaday';
import Dropzone from 'dropzone';
import Sortable from 'vendor/Sortable';
......@@ -20,7 +19,6 @@ import 'vendor/fuzzaldrin-plus';
window.jQuery = jQuery;
window.$ = jQuery;
window._ = _;
window.Pikaday = Pikaday;
window.Dropzone = Dropzone;
window.Sortable = Sortable;
......
/* global Pikaday */
/* global dateFormat */
import Pikaday from 'pikaday';
(() => {
// Add datepickers to all `js-access-expiration-date` elements. If those elements are
// children of an element with the `clearable-input` class, and have a sibling
......
......@@ -7,7 +7,7 @@ import Cookies from 'js-cookie';
import './breakpoints';
import './flash';
import BlobForkSuggestion from './blob/blob_fork_suggestion';
import stickyMonitor from './lib/utils/sticky';
import initChangesDropdown from './init_changes_dropdown';
/* eslint-disable max-len */
// MergeRequestTabs
......@@ -267,9 +267,7 @@ import stickyMonitor from './lib/utils/sticky';
const $container = $('#diffs');
$container.html(data.html);
this.initChangesDropdown();
stickyMonitor(document.querySelector('.js-diff-files-changed'));
initChangesDropdown();
if (typeof gl.diffNotesCompileComponents !== 'undefined') {
gl.diffNotesCompileComponents();
......@@ -319,13 +317,6 @@ import stickyMonitor from './lib/utils/sticky';
});
}
initChangesDropdown() {
$('.js-diff-stats-dropdown').glDropdown({
filterable: true,
remoteFilter: false,
});
}
// Show or hide the loading spinner
//
// status - Boolean, true to show, false to hide
......
......@@ -104,11 +104,14 @@ $new-sidebar-collapsed-width: 50px;
&.sidebar-icons-only {
width: $new-sidebar-collapsed-width;
.nav-item-name,
.badge,
.project-title {
display: none;
}
.nav-item-name {
opacity: 0;
}
}
&.nav-sidebar-expanded {
......@@ -182,7 +185,7 @@ $new-sidebar-collapsed-width: 50px;
> li {
a {
padding: 8px 16px 8px 50px;
padding: 8px 16px 8px 40px;
&:hover,
&:focus {
......@@ -215,12 +218,15 @@ $new-sidebar-collapsed-width: 50px;
&:hover {
color: $gl-text-color;
svg {
fill: $gl-text-color;
}
}
}
&:not(.active) {
&.is-showing-fly-out {
> a {
margin-left: 1px;
margin-right: 2px;
}
......@@ -271,6 +277,14 @@ $new-sidebar-collapsed-width: 50px;
}
}
> .active {
box-shadow: none;
> a {
background-color: transparent;
}
}
a {
padding: 8px 16px;
color: $gl-text-color;
......@@ -294,6 +308,7 @@ $new-sidebar-collapsed-width: 50px;
> a {
margin-left: 4px;
padding-left: 12px;
}
.badge {
......@@ -354,7 +369,7 @@ $new-sidebar-collapsed-width: 50px;
.sidebar-icons-only {
.context-header {
height: 60px;
height: 61px;
a {
padding: 10px 4px;
......
......@@ -574,10 +574,14 @@
@media (min-width: $screen-sm-min) {
position: -webkit-sticky;
position: sticky;
top: 84px;
top: 34px;
background-color: $white-light;
z-index: 190;
&.diff-files-changed-merge-request {
top: 84px;
}
+ .files,
+ .alert {
margin-top: 1px;
......
......@@ -35,7 +35,7 @@
.commit-box,
.info-well,
.commit-ci-menu,
.files-changed,
.files-changed-inner,
.limited-header-width,
.limited-width-notes {
@extend .fixed-width-container;
......
......@@ -117,7 +117,7 @@ class ApplicationController < ActionController::Base
Raven.capture_exception(exception) if sentry_enabled?
application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace
application_trace.map!{ |t| " #{t}\n" }
application_trace.map! { |t| " #{t}\n" }
logger.error "\n#{exception.class.name} (#{exception.message}):\n#{application_trace.join}"
end
......
......@@ -68,15 +68,15 @@ class Import::GithubController < Import::BaseController
end
def new_import_url
public_send("new_import_#{provider}_url")
public_send("new_import_#{provider}_url") # rubocop:disable GitlabSecurity/PublicSend
end
def status_import_url
public_send("status_import_#{provider}_url")
public_send("status_import_#{provider}_url") # rubocop:disable GitlabSecurity/PublicSend
end
def callback_import_url
public_send("callback_import_#{provider}_url")
public_send("callback_import_#{provider}_url") # rubocop:disable GitlabSecurity/PublicSend
end
def provider_unauthorized
......
......@@ -15,7 +15,7 @@ class Import::GitlabController < Import::BaseController
@already_added_projects = current_user.created_projects.where(import_type: "gitlab")
already_added_projects_names = @already_added_projects.pluck(:import_source)
@repos = @repos.to_a.reject{ |repo| already_added_projects_names.include? repo["path_with_namespace"] }
@repos = @repos.to_a.reject { |repo| already_added_projects_names.include? repo["path_with_namespace"] }
end
def jobs
......
......@@ -3,7 +3,7 @@ module GraphHelper
refs = ""
# Commit::ref_names already strips the refs/XXX from important refs (e.g. refs/heads/XXX)
# so anything leftover is internally used by GitLab
commit_refs = commit.ref_names(repo).reject{ |name| name.starts_with?('refs/') }
commit_refs = commit.ref_names(repo).reject { |name| name.starts_with?('refs/') }
refs << commit_refs.join(' ')
# append note count
......
......@@ -151,7 +151,7 @@ module IssuablesHelper
end
def issuable_labels_tooltip(labels, limit: 5)
first, last = labels.partition.with_index{ |_, i| i < limit }
first, last = labels.partition.with_index { |_, i| i < limit }
label_names = first.collect(&:name)
label_names << "and #{last.size} more" unless last.empty?
......@@ -234,7 +234,7 @@ module IssuablesHelper
end
def issuables_count_for_state(issuable_type, state, finder: nil)
finder ||= public_send("#{issuable_type}_finder")
finder ||= public_send("#{issuable_type}_finder") # rubocop:disable GitlabSecurity/PublicSend
cache_key = finder.state_counter_cache_key
@counts ||= {}
......@@ -329,7 +329,7 @@ module IssuablesHelper
end
def selected_template(issuable)
params[:issuable_template] if issuable_templates(issuable).any?{ |template| template[:name] == params[:issuable_template] }
params[:issuable_template] if issuable_templates(issuable).any? { |template| template[:name] == params[:issuable_template] }
end
def issuable_todo_button_data(issuable, todo, is_collapsed)
......
......@@ -43,11 +43,11 @@ module LabelsHelper
def label_filter_path(subject, label, type: :issue)
case subject
when Group
send("#{type.to_s.pluralize}_group_path",
send("#{type.to_s.pluralize}_group_path", # rubocop:disable GitlabSecurity/PublicSend
subject,
label_name: [label.name])
when Project
send("namespace_project_#{type.to_s.pluralize}_path",
send("namespace_project_#{type.to_s.pluralize}_path", # rubocop:disable GitlabSecurity/PublicSend
subject.namespace,
subject,
label_name: [label.name])
......
......@@ -58,7 +58,7 @@ module Spammable
options.fetch(:spam_title, false)
end
public_send(attr.first) if attr && respond_to?(attr.first.to_sym)
public_send(attr.first) if attr && respond_to?(attr.first.to_sym) # rubocop:disable GitlabSecurity/PublicSend
end
def spam_description
......@@ -66,12 +66,12 @@ module Spammable
options.fetch(:spam_description, false)
end
public_send(attr.first) if attr && respond_to?(attr.first.to_sym)
public_send(attr.first) if attr && respond_to?(attr.first.to_sym) # rubocop:disable GitlabSecurity/PublicSend
end
def spammable_text
result = self.class.spammable_attrs.map do |attr|
public_send(attr.first)
public_send(attr.first) # rubocop:disable GitlabSecurity/PublicSend
end
result.reject(&:blank?).join("\n")
......
......@@ -44,7 +44,8 @@ module TokenAuthenticatable
end
define_method("ensure_#{token_field}!") do
send("reset_#{token_field}!") if read_attribute(token_field).blank?
send("reset_#{token_field}!") if read_attribute(token_field).blank? # rubocop:disable GitlabSecurity/PublicSend
read_attribute(token_field)
end
......
......@@ -162,7 +162,7 @@ class MergeRequest < ActiveRecord::Base
target = unscoped.where(target_project_id: relation).select(:id)
union = Gitlab::SQL::Union.new([source, target])
where("merge_requests.id IN (#{union.to_sql})")
where("merge_requests.id IN (#{union.to_sql})") # rubocop:disable GitlabSecurity/SqlInjection
end
WIP_REGEX = /\A\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i.freeze
......
......@@ -26,7 +26,7 @@ class MergeRequestDiffCommit < ActiveRecord::Base
def to_hash
Gitlab::Git::Commit::SERIALIZE_KEYS.each_with_object({}) do |key, hash|
hash[key] = public_send(key)
hash[key] = public_send(key) # rubocop:disable GitlabSecurity/PublicSend
end
end
......
......@@ -206,7 +206,7 @@ module Network
# Visit branching chains
leaves.each do |l|
parents = l.parents(@map).select{|p| p.space.zero?}
parents = l.parents(@map).select {|p| p.space.zero?}
parents.each do |p|
place_chain(p, l.time)
end
......
......@@ -77,20 +77,20 @@ class Note < ActiveRecord::Base
# Scopes
scope :for_commit_id, ->(commit_id) { where(noteable_type: "Commit", commit_id: commit_id) }
scope :system, ->{ where(system: true) }
scope :user, ->{ where(system: false) }
scope :common, ->{ where(noteable_type: ["", nil]) }
scope :fresh, ->{ order(created_at: :asc, id: :asc) }
scope :updated_after, ->(time){ where('updated_at > ?', time) }
scope :inc_author_project, ->{ includes(:project, :author) }
scope :inc_author, ->{ includes(:author) }
scope :system, -> { where(system: true) }
scope :user, -> { where(system: false) }
scope :common, -> { where(noteable_type: ["", nil]) }
scope :fresh, -> { order(created_at: :asc, id: :asc) }
scope :updated_after, ->(time) { where('updated_at > ?', time) }
scope :inc_author_project, -> { includes(:project, :author) }
scope :inc_author, -> { includes(:author) }
scope :inc_relations_for_view, -> do
includes(:project, :author, :updated_by, :resolved_by, :award_emoji, :system_note_metadata)
end
scope :diff_notes, ->{ where(type: %w(LegacyDiffNote DiffNote)) }
scope :new_diff_notes, ->{ where(type: 'DiffNote') }
scope :non_diff_notes, ->{ where(type: ['Note', 'DiscussionNote', nil]) }
scope :diff_notes, -> { where(type: %w(LegacyDiffNote DiffNote)) }
scope :new_diff_notes, -> { where(type: 'DiffNote') }
scope :non_diff_notes, -> { where(type: ['Note', 'DiscussionNote', nil]) }
scope :with_associations, -> do
# FYI noteable cannot be loaded for LegacyDiffNote for commits
......
......@@ -66,6 +66,6 @@ class NotificationSetting < ActiveRecord::Base
alias_method :failed_pipeline?, :failed_pipeline
def event_enabled?(event)
respond_to?(event) && !!public_send(event)
respond_to?(event) && !!public_send(event) # rubocop:disable GitlabSecurity/PublicSend
end
end
......@@ -415,7 +415,7 @@ class Project < ActiveRecord::Base
union = Gitlab::SQL::Union.new([projects, namespaces])
where("projects.id IN (#{union.to_sql})")
where("projects.id IN (#{union.to_sql})") # rubocop:disable GitlabSecurity/SqlInjection
end
def search_by_title(query)
......@@ -825,7 +825,7 @@ class Project < ActiveRecord::Base
if template.nil?
# If no template, we should create an instance. Ex `build_gitlab_ci_service`
public_send("build_#{service_name}_service")
public_send("build_#{service_name}_service") # rubocop:disable GitlabSecurity/PublicSend
else
Service.build_from_template(id, template)
end
......@@ -1046,13 +1046,18 @@ class Project < ActiveRecord::Base
end
def change_head(branch)
repository.before_change_head
repository.rugged.references.create('HEAD',
"refs/heads/#{branch}",
force: true)
repository.copy_gitattributes(branch)
repository.after_change_head
reload_default_branch
if repository.branch_exists?(branch)
repository.before_change_head
repository.rugged.references.create('HEAD',
"refs/heads/#{branch}",
force: true)
repository.copy_gitattributes(branch)
repository.after_change_head
reload_default_branch
else
errors.add(:base, "Could not change HEAD: branch '#{branch}' does not exist")
false
end
end
def forked_from?(project)
......@@ -1326,7 +1331,7 @@ class Project < ActiveRecord::Base
end
def append_or_update_attribute(name, value)
old_values = public_send(name.to_s)
old_values = public_send(name.to_s) # rubocop:disable GitlabSecurity/PublicSend
if Project.reflect_on_association(name).try(:macro) == :has_many && old_values.any?
update_attribute(name, old_values + value)
......
......@@ -55,7 +55,7 @@ class ProjectFeature < ActiveRecord::Base
end
def access_level(feature)
public_send(ProjectFeature.access_level_attribute(feature))
public_send(ProjectFeature.access_level_attribute(feature)) # rubocop:disable GitlabSecurity/PublicSend
end
def builds_enabled?
......@@ -80,7 +80,7 @@ class ProjectFeature < ActiveRecord::Base
# which cannot be higher than repository access level
def repository_children_level
validator = lambda do |field|
level = public_send(field) || ProjectFeature::ENABLED
level = public_send(field) || ProjectFeature::ENABLED # rubocop:disable GitlabSecurity/PublicSend
not_allowed = level > repository_access_level
self.errors.add(field, "cannot have higher visibility level than repository access level") if not_allowed
end
......
......@@ -14,7 +14,7 @@ class ProjectStatistics < ActiveRecord::Base
def refresh!(only: nil)
STATISTICS_COLUMNS.each do |column, generator|
if only.blank? || only.include?(column)
public_send("update_#{column}")
public_send("update_#{column}") # rubocop:disable GitlabSecurity/PublicSend
end
end
......
......@@ -300,7 +300,7 @@ class Repository
expire_method_caches(to_refresh)
to_refresh.each { |method| send(method) }
to_refresh.each { |method| send(method) } # rubocop:disable GitlabSecurity/PublicSend
end
def expire_branch_cache(branch_name = nil)
......
......@@ -148,6 +148,8 @@ class User < ActiveRecord::Base
uniqueness: { case_sensitive: false }
validate :namespace_uniq, if: :username_changed?
validate :namespace_move_dir_allowed, if: :username_changed?
validate :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? }
validate :unique_email, if: :email_changed?
validate :owns_notification_email, if: :notification_email_changed?
......@@ -487,6 +489,12 @@ class User < ActiveRecord::Base
end
end
def namespace_move_dir_allowed
if namespace&.any_project_has_container_registry_tags?
errors.add(:username, 'cannot be changed if a personal project has container registry tags.')
end
end
def avatar_type
unless avatar.image?
errors.add :avatar, "only images allowed"
......@@ -528,7 +536,7 @@ class User < ActiveRecord::Base
union = Gitlab::SQL::Union
.new([groups.select(:id), authorized_projects.select(:namespace_id)])
Group.where("namespaces.id IN (#{union.to_sql})")
Group.where("namespaces.id IN (#{union.to_sql})") # rubocop:disable GitlabSecurity/SqlInjection
end
# Returns a relation of groups the user has access to, including their parent
......@@ -719,8 +727,8 @@ class User < ActiveRecord::Base
def sanitize_attrs
%w[username skype linkedin twitter].each do |attr|
value = public_send(attr)
public_send("#{attr}=", Sanitize.clean(value)) if value.present?
value = public_send(attr) # rubocop:disable GitlabSecurity/PublicSend
public_send("#{attr}=", Sanitize.clean(value)) if value.present? # rubocop:disable GitlabSecurity/PublicSend
end
end
......@@ -779,7 +787,7 @@ class User < ActiveRecord::Base
def with_defaults
User.defaults.each do |k, v|
public_send("#{k}=", v)
public_send("#{k}=", v) # rubocop:disable GitlabSecurity/PublicSend
end
self
......@@ -825,7 +833,7 @@ class User < ActiveRecord::Base
{
name: name,
username: username,
avatar_url: avatar_url
avatar_url: avatar_url(only_path: false)
}
end
......@@ -919,7 +927,7 @@ class User < ActiveRecord::Base
def ci_authorized_runners
@ci_authorized_runners ||= begin
runner_ids = Ci::RunnerProject
.where("ci_runner_projects.project_id IN (#{ci_projects_union.to_sql})")
.where("ci_runner_projects.project_id IN (#{ci_projects_union.to_sql})") # rubocop:disable GitlabSecurity/SqlInjection
.select(:runner_id)
Ci::Runner.specific.where(id: runner_ids)
end
......
......@@ -35,6 +35,6 @@ class AnalyticsBuildEntity < Grape::Entity
private
def url_to(route, build, id = nil)
public_send("#{route}_url", build.project.namespace, build.project, id || build)
public_send("#{route}_url", build.project.namespace, build.project, id || build) # rubocop:disable GitlabSecurity/PublicSend
end
end
......@@ -24,6 +24,6 @@ class AnalyticsIssueEntity < Grape::Entity
private
def url_to(route, id)
public_send("#{route}_url", request.project.namespace, request.project, id)
public_send("#{route}_url", request.project.namespace, request.project, id) # rubocop:disable GitlabSecurity/PublicSend
end
end
......@@ -46,6 +46,6 @@ class JobEntity < Grape::Entity
end
def path_to(route, build)
send("#{route}_path", build.project.namespace, build.project, build)
send("#{route}_path", build.project.namespace, build.project, build) # rubocop:disable GitlabSecurity/PublicSend
end
end
......@@ -16,6 +16,7 @@ module Issues
spam_check(issue, current_user)
issue.move_to_end
# current_user (defined in BaseService) is not available within run_after_commit block
user = current_user
issue.run_after_commit do
NewIssueWorker.perform_async(issue.id, user.id)
......
......@@ -37,7 +37,7 @@ module Labels
union = Gitlab::SQL::Union.new(label_ids)
Label.where("labels.id IN (#{union.to_sql})").reorder(nil).uniq
Label.where("labels.id IN (#{union.to_sql})").reorder(nil).uniq # rubocop:disable GitlabSecurity/SqlInjection
end
def group_labels_applied_to_issues
......
......@@ -17,6 +17,7 @@ module MergeRequests
end
def before_create(merge_request)
# current_user (defined in BaseService) is not available within run_after_commit block
user = current_user
merge_request.run_after_commit do
NewMergeRequestWorker.perform_async(merge_request.id, user.id)
......
......@@ -10,7 +10,7 @@ module Projects
end
if changing_default_branch?
project.change_head(params[:default_branch])
return error("Could not set the default branch") unless project.change_head(params[:default_branch])
end
if project.update_attributes(params.except(:default_branch))
......
......@@ -74,7 +74,8 @@
= link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username }
%li
= link_to "Settings", profile_path
= render 'shared/user_dropdown_experimental_features'
%li
= link_to "Turn on new navigation", profile_preferences_path(anchor: "new-navigation")
%li.divider
%li
= link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link"
......
......@@ -68,7 +68,8 @@
= link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username }
%li
= link_to "Settings", profile_path
= render 'shared/user_dropdown_experimental_features'
%li
= link_to "Turn off new navigation", profile_preferences_path(anchor: "new-navigation")
%li.divider
%li
= link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link"
......
......@@ -18,8 +18,6 @@
= scheme.name
.col-sm-12
%hr
%h3#experimental-features Experimental features
%hr
.col-lg-4.profile-settings-sidebar#new-navigation
%h4.prepend-top-0
New Navigation
......@@ -42,28 +40,6 @@
New
.col-sm-12
%hr
.col-lg-4.profile-settings-sidebar#new-repository
%h4.prepend-top-0
New Repository
%p
This setting allows you to turn on or off the new upcoming repository concept.
.col-lg-8.syntax-theme
.nav-wip
%p
The new repository is currently a work-in-progress concept and only usable on wide-screens. There are a number of improvements that we are working on in order to further refine the repository view.
%p
%a{ href: 'https://gitlab.com/gitlab-org/gitlab-ce/issues/31890', target: 'blank' } Learn more
about the improvements that are coming soon!
= label_tag do
.preview= image_tag "old_repo.png"
%input.js-experiment-feature-toggle{ type: "radio", value: "false", name: "new_repo", checked: !show_new_repo? }
Old
= label_tag do
.preview= image_tag "new_repo.png"
%input.js-experiment-feature-toggle{ type: "radio", value: "true", name: "new_repo", checked: show_new_repo? }
New
.col-sm-12
%hr
.col-lg-4.profile-settings-sidebar
%h4.prepend-top-0
Behavior
......
......@@ -2,22 +2,24 @@
- show_whitespace_toggle = local_assigns.fetch(:show_whitespace_toggle, true)
- can_create_note = !@diff_notes_disabled && can?(current_user, :create_note, diffs.project)
- diff_files = diffs.diff_files
- merge_request = local_assigns.fetch(:merge_request, false)
.content-block.oneline-block.files-changed.diff-files-changed.js-diff-files-changed
.inline-parallel-buttons
- if !diffs_expanded? && diff_files.any? { |diff_file| diff_file.collapsed? }
= link_to 'Expand all', url_for(params.merge(expanded: 1, format: nil)), class: 'btn btn-default'
- if show_whitespace_toggle
- if current_controller?(:commit)
= commit_diff_whitespace_link(diffs.project, @commit, class: 'hidden-xs')
- elsif current_controller?('projects/merge_requests/diffs')
= diff_merge_request_whitespace_link(diffs.project, @merge_request, class: 'hidden-xs')
- elsif current_controller?(:compare)
= diff_compare_whitespace_link(diffs.project, params[:from], params[:to], class: 'hidden-xs')
.btn-group
= inline_diff_btn
= parallel_diff_btn
= render 'projects/diffs/stats', diff_files: diff_files
.content-block.oneline-block.files-changed.diff-files-changed.js-diff-files-changed{ class: ("diff-files-changed-merge-request" if merge_request) }
.files-changed-inner
.inline-parallel-buttons
- if !diffs_expanded? && diff_files.any? { |diff_file| diff_file.collapsed? }
= link_to 'Expand all', url_for(params.merge(expanded: 1, format: nil)), class: 'btn btn-default'
- if show_whitespace_toggle
- if current_controller?(:commit)
= commit_diff_whitespace_link(diffs.project, @commit, class: 'hidden-xs')
- elsif current_controller?('projects/merge_requests/diffs')
= diff_merge_request_whitespace_link(diffs.project, @merge_request, class: 'hidden-xs')
- elsif current_controller?(:compare)
= diff_compare_whitespace_link(diffs.project, params[:from], params[:to], class: 'hidden-xs')
.btn-group
= inline_diff_btn
= parallel_diff_btn
= render 'projects/diffs/stats', diff_files: diff_files
- if render_overflow_warning?(diff_files)
= render 'projects/diffs/warning', diff_files: diffs
......
- if @merge_request_diff.collected? || @merge_request_diff.overflow?
= render 'projects/merge_requests/diffs/versions'
= render "projects/diffs/diffs", diffs: @diffs, environment: @environment
= render "projects/diffs/diffs", diffs: @diffs, environment: @environment, merge_request: true
- elsif @merge_request_diff.empty?
.nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
%li= link_to 'Experimental features', profile_preferences_path(anchor: 'experimental-features')
module NewIssuable
attr_reader :issuable, :user
def ensure_objects_found(issuable_id, user_id)
@issuable = issuable_class.find_by(id: issuable_id)
unless @issuable
log_error(issuable_class, issuable_id)
return false
end
def objects_found?(issuable_id, user_id)
set_user(user_id)
set_issuable(issuable_id)
user && issuable
end
def set_user(user_id)
@user = User.find_by(id: user_id)
unless @user
log_error(User, user_id)
return false
end
true
log_error(User, user_id) unless @user
end
def set_issuable(issuable_id)
@issuable = issuable_class.find_by(id: issuable_id)
log_error(issuable_class, issuable_id) unless @issuable
end
def log_error(record_class, record_id)
......
......@@ -4,7 +4,7 @@ class NewIssueWorker
include NewIssuable
def perform(issue_id, user_id)
return unless ensure_objects_found(issue_id, user_id)
return unless objects_found?(issue_id, user_id)
EventCreateService.new.open_issue(issuable, user)
NotificationService.new.new_issue(issuable, user)
......
......@@ -4,7 +4,7 @@ class NewMergeRequestWorker
include NewIssuable
def perform(merge_request_id, user_id)
return unless ensure_objects_found(merge_request_id, user_id)
return unless objects_found?(merge_request_id, user_id)
EventCreateService.new.open_mr(issuable, user)
NotificationService.new.new_merge_request(issuable, user)
......
......@@ -4,7 +4,7 @@ class PagesWorker
sidekiq_options queue: :pages, retry: false
def perform(action, *arg)
send(action, *arg)
send(action, *arg) # rubocop:disable GitlabSecurity/PublicSend
end
def deploy(build_id)
......
#!/usr/bin/env ruby
require 'bundler/setup'
require 'stackprof'
$:.unshift 'spec'
require 'rails_helper'
......@@ -13,4 +14,4 @@ StackProf.run(mode: :wall, out: output_file, interval: interval) do
RSpec::Core::Runner.run(ARGV, $stderr, $stdout)
end
system("stackprof #{output_file} --text --limit #{limit}")
system("bundle exec stackprof #{output_file} --text --limit #{limit}")
---
title: Use full path of user's avatar in webhooks
merge_request: 13401
author: Vitaliy @blackst0ne Klachkov
---
title: Add checks for branch existence before changing HEAD
merge_request: 13359
author: Vitaliy @blackst0ne Klachkov
---
title: Simplify checking if objects exist code in new issaubles workers
merge_request:
author:
---
title: Add missing validation error for username change with container registry tags
merge_request: 13356
author:
......@@ -176,7 +176,7 @@ module Gitlab
next unless name.include?('namespace_project')
define_method(name.sub('namespace_project', 'project')) do |project, *args|
send(name, project&.namespace, project, *args)
send(name, project&.namespace, project, *args) # rubocop:disable GitlabSecurity/PublicSend
end
end
end
......
......@@ -71,7 +71,7 @@ class Settings < Settingslogic
# check that `current` (string or integer) is a contant in `modul`.
def verify_constant(modul, current, default)
constant = modul.constants.find{ |name| modul.const_get(name) == current }
constant = modul.constants.find { |name| modul.const_get(name) == current }
value = constant.nil? ? default : modul.const_get(constant)
if current.is_a? String
value = modul.const_get(current.upcase) rescue default
......
......@@ -18,7 +18,7 @@ module ActiveRecord
lock_col = self.class.locking_column
previous_lock_value = send(lock_col).to_i
previous_lock_value = send(lock_col).to_i # rubocop:disable GitlabSecurity/PublicSend
# This line is added as a patch
previous_lock_value = nil if previous_lock_value == '0' || previous_lock_value == 0
......@@ -48,7 +48,7 @@ module ActiveRecord
# If something went wrong, revert the version.
rescue Exception
send(lock_col + '=', previous_lock_value)
send(lock_col + '=', previous_lock_value) # rubocop:disable GitlabSecurity/PublicSend
raise
end
end
......
......@@ -3,6 +3,9 @@
resource :repository, only: [:create] do
member do
get ':ref/archive', constraints: { format: Gitlab::PathRegex.archive_formats_regex, ref: /.+/ }, action: 'archive', as: 'archive'
# deprecated since GitLab 9.5
get 'archive', constraints: { format: Gitlab::PathRegex.archive_formats_regex }, as: 'archive_alternative'
end
end
......
......@@ -10,7 +10,7 @@ class AddUniqueIndexToLabels < ActiveRecord::Migration
def up
select_all('SELECT title, project_id, COUNT(id) as cnt FROM labels GROUP BY project_id, title HAVING COUNT(id) > 1').each do |label|
label_title = quote_string(label['title'])
duplicated_ids = select_all("SELECT id FROM labels WHERE project_id = #{label['project_id']} AND title = '#{label_title}' ORDER BY id ASC").map{ |label| label['id'] }
duplicated_ids = select_all("SELECT id FROM labels WHERE project_id = #{label['project_id']} AND title = '#{label_title}' ORDER BY id ASC").map { |label| label['id'] }
label_id = duplicated_ids.first
duplicated_ids.delete(label_id)
......
......@@ -30,7 +30,7 @@ class CleanupNamespacelessPendingDeleteProjects < ActiveRecord::Migration
private
def pending_delete_batch
connection.exec_query(find_batch).map{ |row| row['id'].to_i }
connection.exec_query(find_batch).map { |row| row['id'].to_i }
end
BATCH_SIZE = 5000
......
......@@ -3,7 +3,7 @@
Welcome to [GitLab](https://about.gitlab.com/), a Git-based fully featured
platform for software development!
We offer four different products for you and your company:
GitLab offers the most scalable Git-based fully integrated platform for software development, with flexible products and subscription plans:
- **GitLab Community Edition (CE)** is an [opensource product](https://gitlab.com/gitlab-org/gitlab-ce/),
self-hosted, free to use. Every feature available in GitLab CE is also available on GitLab Enterprise Edition (Starter and Premium) and GitLab.com.
......
......@@ -9,6 +9,33 @@ documentation](http://docs.gitlab.com/ee/administration/audit_events.html)
System log files are typically plain text in a standard log file format.
This guide talks about how to read and use these system log files.
## `production_json.log`
This file lives in `/var/log/gitlab/gitlab-rails/production_json.log` for
Omnibus GitLab packages or in `/home/git/gitlab/log/production_json.log` for
installations from source. (When Gitlab is running in an environment
other than production, the corresponding logfile is shown here.)
It contains a structured log for Rails controller requests received from
GitLab, thanks to [Lograge](https://github.com/roidrage/lograge/). Note that
requests from the API [are not yet logged to this
file](https://gitlab.com/gitlab-org/gitlab-ce/issues/36189).
Each line contains a JSON line that can be ingested by Elasticsearch, Splunk, etc. For example:
```json
{"method":"GET","path":"/gitlab/gitlab-ce/issues/1234","format":"html","controller":"Projects::IssuesController","action":"show","status":200,"duration":229.03,"view":174.07,"db":13.24,"time":"2017-08-08T20:15:54.821Z","params":{"namespace_id":"gitlab","project_id":"gitlab-ce","id":"1234"},"remote_ip":"18.245.0.1","user_id":1,"username":"admin"}
```
In this example, you can see this was a GET request for a specific issue. Notice each line also contains performance data:
1. `duration`: the total time taken to retrieve the request
2. `view`: total time taken inside the Rails views
3. `db`: total time to retrieve data from the database
In addition, the log contains the IP address from which the request originated
(`remote_ip`) as well as the user's ID (`user_id`), and username (`username`).
## `production.log`
This file lives in `/var/log/gitlab/gitlab-rails/production.log` for
......
......@@ -296,9 +296,9 @@ sudo usermod -aG redis git
### Clone the Source
# Clone GitLab repository
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 9-4-stable gitlab
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 9-5-stable gitlab
**Note:** You can change `9-4-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
**Note:** You can change `9-5-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
### Configure It
......@@ -507,15 +507,17 @@ Check if GitLab and its environment are configured correctly:
sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
### Compile GetText PO files
sudo -u git -H bundle exec rake gettext:pack RAILS_ENV=production
sudo -u git -H bundle exec rake gettext:po_to_json RAILS_ENV=production
### Compile Assets
sudo -u git -H yarn install --production --pure-lockfile
sudo -u git -H bundle exec rake gitlab:assets:compile RAILS_ENV=production NODE_ENV=production
### Compile GetText PO files
sudo -u git -H bundle exec rake gettext:compile RAILS_ENV=production
### Start Your GitLab Instance
sudo service gitlab start
......
......@@ -31,7 +31,7 @@ X-Gitlab-Event: System Hook
"path": "storecloud",
"path_with_namespace": "jsmith/storecloud",
"project_id": 74,
"project_visibility": "private",
"project_visibility": "private"
}
```
......@@ -48,7 +48,7 @@ X-Gitlab-Event: System Hook
"path": "underscore",
"path_with_namespace": "jsmith/underscore",
"project_id": 73,
"project_visibility": "internal",
"project_visibility": "internal"
}
```
......@@ -66,7 +66,7 @@ X-Gitlab-Event: System Hook
"owner_name": "John Smith",
"owner_email": "johnsmith@gmail.com",
"project_visibility": "internal",
"old_path_with_namespace": "jsmith/overscore",
"old_path_with_namespace": "jsmith/overscore"
}
```
......@@ -84,7 +84,7 @@ X-Gitlab-Event: System Hook
"owner_name": "John Smith",
"owner_email": "johnsmith@gmail.com",
"project_visibility": "internal",
"old_path_with_namespace": "jsmith/overscore",
"old_path_with_namespace": "jsmith/overscore"
}
```
......@@ -101,7 +101,7 @@ X-Gitlab-Event: System Hook
"path": "storecloud",
"path_with_namespace": "jsmith/storecloud",
"project_id": 74,
"project_visibility": "private",
"project_visibility": "private"
}
```
......@@ -121,7 +121,7 @@ X-Gitlab-Event: System Hook
"user_name": "John Smith",
"user_username": "johnsmith",
"user_id": 41,
"project_visibility": "private",
"project_visibility": "private"
}
```
......@@ -141,7 +141,7 @@ X-Gitlab-Event: System Hook
"user_name": "John Smith",
"user_username": "johnsmith",
"user_id": 41,
"project_visibility": "private",
"project_visibility": "private"
}
```
......
......@@ -100,6 +100,7 @@ cd /home/git/gitlab
sudo -u git -H git fetch --all
sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically
sudo -u git -H git checkout -- locale
```
For GitLab Community Edition:
......@@ -236,6 +237,11 @@ sudo -u git -H bundle clean
# Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
# Compile GetText PO files
sudo -u git -H bundle exec rake gettext:pack RAILS_ENV=production
sudo -u git -H bundle exec rake gettext:po_to_json RAILS_ENV=production
# Update node dependencies and recompile assets
sudo -u git -H bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile RAILS_ENV=production NODE_ENV=production
......
......@@ -100,6 +100,7 @@ cd /home/git/gitlab
sudo -u git -H git fetch --all
sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically
sudo -u git -H git checkout -- locale
```
For GitLab Community Edition:
......@@ -272,6 +273,10 @@ sudo -u git -H bundle clean
# Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
# Compile GetText PO files
sudo -u git -H bundle exec rake gettext:compile RAILS_ENV=production
# Update node dependencies and recompile assets
sudo -u git -H bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile RAILS_ENV=production NODE_ENV=production
......
......@@ -100,6 +100,7 @@ cd /home/git/gitlab
sudo -u git -H git fetch --all
sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically
sudo -u git -H git checkout -- locale
```
For GitLab Community Edition:
......@@ -285,6 +286,10 @@ sudo -u git -H bundle clean
# Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
# Compile GetText PO files
sudo -u git -H bundle exec rake gettext:compile RAILS_ENV=production
# Update node dependencies and recompile assets
sudo -u git -H bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile RAILS_ENV=production NODE_ENV=production
......
......@@ -295,6 +295,10 @@ sudo -u git -H bundle clean
# Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
# Compile GetText PO files
sudo -u git -H bundle exec rake gettext:compile RAILS_ENV=production
# Update node dependencies and recompile assets
sudo -u git -H bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile RAILS_ENV=production NODE_ENV=production
......
......@@ -35,7 +35,7 @@ current version with `cat VERSION`).
cd /home/git/gitlab
sudo -u git -H git fetch --all
sudo -u git -H git checkout -- Gemfile.lock db/schema.rb
sudo -u git -H git checkout -- Gemfile.lock db/schema.rb locale
sudo -u git -H git checkout LATEST_TAG -b LATEST_TAG
```
......@@ -56,11 +56,21 @@ sudo -u git -H bundle clean
# Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
### 4. Compile GetText PO files
Internationalization was added in `v9.2.0` so these commands are only
required for versions equal or major to it.
```bash
sudo -u git -H bundle exec rake gettext:pack RAILS_ENV=production
sudo -u git -H bundle exec rake gettext:po_to_json RAILS_ENV=production
```
# Clean up assets and cache
sudo -u git -H bundle exec rake yarn:install gitlab:assets:clean gitlab:assets:compile cache:clear RAILS_ENV=production NODE_ENV=production
```
### 4. Update gitlab-workhorse to the corresponding version
### 5. Update gitlab-workhorse to the corresponding version
```bash
cd /home/git/gitlab
......@@ -68,7 +78,7 @@ cd /home/git/gitlab
sudo -u git -H bundle exec rake "gitlab:workhorse:install[/home/git/gitlab-workhorse]" RAILS_ENV=production
```
### 5. Update gitlab-shell to the corresponding version
### 6. Update gitlab-shell to the corresponding version
```bash
cd /home/git/gitlab-shell
......@@ -78,14 +88,14 @@ sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_SHELL_VERSION` -b v`ca
sudo -u git -H sh -c 'if [ -x bin/compile ]; then bin/compile; fi'
```
### 6. Start application
### 7. Start application
```bash
sudo service gitlab start
sudo service nginx restart
```
### 7. Check application status
### 8. Check application status
Check if GitLab and its environment are configured correctly:
......
......@@ -132,7 +132,7 @@ module API
expose :lfs_enabled?, as: :lfs_enabled
expose :creator_id
expose :namespace, using: 'API::Entities::Namespace'
expose :forked_from_project, using: Entities::BasicProjectDetails, if: lambda{ |project, options| project.forked? }
expose :forked_from_project, using: Entities::BasicProjectDetails, if: lambda { |project, options| project.forked? }
expose :import_status
expose :import_error, if: lambda { |_project, options| options[:user_can_admin_project] }
expose :avatar_url do |user, options|
......
# rubocop:disable GitlabSecurity/PublicSend
module API
module Helpers
module MembersHelpers
def find_source(source_type, id)
public_send("find_#{source_type}!", id)
public_send("find_#{source_type}!", id) # rubocop:disable GitlabSecurity/PublicSend
end
def authorize_admin_source!(source_type, source)
......
......@@ -139,7 +139,7 @@ module API
helpers do
def find_project_noteable(noteables_str, noteable_id)
public_send("find_project_#{noteables_str.singularize}", noteable_id)
public_send("find_project_#{noteables_str.singularize}", noteable_id) # rubocop:disable GitlabSecurity/PublicSend
end
def noteable_read_ability_name(noteable)
......
......@@ -68,7 +68,7 @@ module API
expose :lfs_enabled?, as: :lfs_enabled
expose :creator_id
expose :namespace, using: 'API::Entities::Namespace'
expose :forked_from_project, using: ::API::Entities::BasicProjectDetails, if: lambda{ |project, options| project.forked? }
expose :forked_from_project, using: ::API::Entities::BasicProjectDetails, if: lambda { |project, options| project.forked? }
expose :avatar_url do |user, options|
user.avatar_url(only_path: false)
end
......
......@@ -198,11 +198,11 @@ module Backup
end
def archives_to_backup
ARCHIVES_TO_BACKUP.map{ |name| (name + ".tar.gz") unless skipped?(name) }.compact
ARCHIVES_TO_BACKUP.map { |name| (name + ".tar.gz") unless skipped?(name) }.compact
end
def folders_to_backup
FOLDERS_TO_BACKUP.reject{ |name| skipped?(name) }
FOLDERS_TO_BACKUP.reject { |name| skipped?(name) }
end
def disabled_features
......
......@@ -254,7 +254,7 @@ module Ci
def state
state = STATE_PARAMS.inject({}) do |h, param|
h[param] = send(param)
h[param] = send(param) # rubocop:disable GitlabSecurity/PublicSend
h
end
Base64.urlsafe_encode64(state.to_json)
......@@ -266,7 +266,7 @@ module Ci
return if state[:offset].to_i > stream.size
STATE_PARAMS.each do |param|
send("#{param}=".to_sym, state[param])
send("#{param}=".to_sym, state[param]) # rubocop:disable GitlabSecurity/PublicSend
end
end
......
......@@ -47,7 +47,7 @@ module Ci
def collect
query = project.pipelines
.where("? > #{Ci::Pipeline.table_name}.created_at AND #{Ci::Pipeline.table_name}.created_at > ?", @to, @from)
.where("? > #{Ci::Pipeline.table_name}.created_at AND #{Ci::Pipeline.table_name}.created_at > ?", @to, @from) # rubocop:disable GitlabSecurity/SqlInjection
totals_count = grouped_count(query)
success_count = grouped_count(query.success)
......
......@@ -6,6 +6,8 @@ class ProjectUrlConstrainer
return false unless DynamicPathValidator.valid_project_path?(full_path)
# We intentionally allow SELECT(*) here so result of this query can be used
# as cache for further Project.find_by_full_path calls within request
Project.find_by_full_path(full_path, follow_redirects: request.get?).present?
end
end
......@@ -21,7 +21,7 @@ module Gitlab
def to_hash
hash = {}
serialize_keys.each { |key| hash[key] = send(key) }
serialize_keys.each { |key| hash[key] = send(key) } # rubocop:disable GitlabSecurity/PublicSend
hash
end
......
......@@ -98,10 +98,11 @@ module Gitlab
if status.zero?
@ee_branch_found = ee_branch_prefix
else
_, status = step("Fetching origin/#{ee_branch_suffix}", %W[git fetch origin #{ee_branch_suffix}])
return
end
_, status = step("Fetching origin/#{ee_branch_suffix}", %W[git fetch origin #{ee_branch_suffix}])
if status.zero?
@ee_branch_found = ee_branch_suffix
else
......
......@@ -319,7 +319,7 @@ module Gitlab
def to_hash
serialize_keys.map.with_object({}) do |key, hash|
hash[key] = send(key)
hash[key] = send(key) # rubocop:disable GitlabSecurity/PublicSend
end
end
......@@ -412,7 +412,7 @@ module Gitlab
raw_commit = hash.symbolize_keys
serialize_keys.each do |key|
send("#{key}=", raw_commit[key])
send("#{key}=", raw_commit[key]) # rubocop:disable GitlabSecurity/PublicSend
end
end
......
......@@ -143,7 +143,7 @@ module Gitlab
hash = {}
SERIALIZE_KEYS.each do |key|
hash[key] = send(key)
hash[key] = send(key) # rubocop:disable GitlabSecurity/PublicSend
end
hash
......@@ -221,7 +221,7 @@ module Gitlab
raw_diff = hash.symbolize_keys
SERIALIZE_KEYS.each do |key|
send(:"#{key}=", raw_diff[key.to_sym])
send(:"#{key}=", raw_diff[key.to_sym]) # rubocop:disable GitlabSecurity/PublicSend
end
end
......
......@@ -7,13 +7,13 @@ module Gitlab
def initialize(params)
params.each do |key, val|
public_send(:"#{key}=", val)
public_send(:"#{key}=", val) # rubocop:disable GitlabSecurity/PublicSend
end
end
def ==(other)
FIELDS.all? do |field|
public_send(field) == other.public_send(field)
public_send(field) == other.public_send(field) # rubocop:disable GitlabSecurity/PublicSend
end
end
end
......
......@@ -10,7 +10,7 @@ module Gitlab
def exists?
request = Gitaly::RepositoryExistsRequest.new(repository: @gitaly_repo)
GitalyClient.call(@storage, :repository_service, :exists, request).exists
GitalyClient.call(@storage, :repository_service, :repository_exists, request).exists
end
def garbage_collect(create_bitmap)
......
......@@ -71,7 +71,7 @@ module Gitlab
end
def config
Gitlab.config.omniauth.providers.find{|provider| provider.name == "gitlab"}
Gitlab.config.omniauth.providers.find {|provider| provider.name == "gitlab"}
end
def gitlab_options
......
......@@ -45,7 +45,7 @@ module Gitlab
end
def all
REFERABLES.each { |referable| send(referable.to_s.pluralize) }
REFERABLES.each { |referable| send(referable.to_s.pluralize) } # rubocop:disable GitlabSecurity/PublicSend
@references.values.flatten
end
......
......@@ -18,7 +18,7 @@ module StaticModel
#
# Pass it along if we respond to it.
def [](key)
send(key) if respond_to?(key)
send(key) if respond_to?(key) # rubocop:disable GitlabSecurity/PublicSend
end
def to_param
......
......@@ -18,8 +18,11 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache off;
# The same address as passed to GitLab Pages: `-listen-proxy`
proxy_pass http://localhost:8090/;
proxy_pass http://localhost:8090/;
}
# Define custom error pages
......
......@@ -67,8 +67,11 @@ server {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache off;
# The same address as passed to GitLab Pages: `-listen-proxy`
proxy_pass http://localhost:8090/;
proxy_pass http://localhost:8090/;
}
# Define custom error pages
......
......@@ -41,8 +41,6 @@ namespace :gitlab do
end
namespace :gitlab_shell do
include SystemCheck::Helpers
desc "GitLab | Check the configuration of GitLab Shell"
task check: :environment do
warn_user_is_not_gitlab
......@@ -249,8 +247,6 @@ namespace :gitlab do
end
namespace :sidekiq do
include SystemCheck::Helpers
desc "GitLab | Check the configuration of Sidekiq"
task check: :environment do
warn_user_is_not_gitlab
......@@ -309,8 +305,6 @@ namespace :gitlab do
end
namespace :incoming_email do
include SystemCheck::Helpers
desc "GitLab | Check the configuration of Reply by email"
task check: :environment do
warn_user_is_not_gitlab
......@@ -444,8 +438,6 @@ namespace :gitlab do
end
namespace :ldap do
include SystemCheck::Helpers
task :check, [:limit] => :environment do |_, args|
# Only show up to 100 results because LDAP directories can be very big.
# This setting only affects the `rake gitlab:check` script.
......@@ -501,8 +493,6 @@ namespace :gitlab do
end
namespace :repo do
include SystemCheck::Helpers
desc "GitLab | Check the integrity of the repositories managed by GitLab"
task check: :environment do
Gitlab.config.repositories.storages.each do |name, repository_storage|
......@@ -517,8 +507,6 @@ namespace :gitlab do
end
namespace :user do
include SystemCheck::Helpers
desc "GitLab | Check the integrity of a specific user's repositories"
task :check_repos, [:username] => :environment do |t, args|
username = args[:username] || prompt("Check repository integrity for fsername? ".color(:blue))
......
......@@ -21,7 +21,7 @@ namespace :gitlab do
create_gitaly_configuration
# In CI we run scripts/gitaly-test-build instead of this command
unless ENV['CI'].present?
Bundler.with_original_env { run_command!(%w[/usr/bin/env -u RUBYOPT] + [command]) }
Bundler.with_original_env { run_command!(%w[/usr/bin/env -u RUBYOPT -u BUNDLE_GEMFILE] + [command]) }
end
end
end
......
......@@ -4,5 +4,5 @@ require 'tasks/gitlab/task_helpers'
StateMachines::Machine.ignore_method_conflicts = true if ENV['CRON']
namespace :gitlab do
include Gitlab::TaskHelpers
extend SystemCheck::Helpers
end
......@@ -5,6 +5,8 @@ module Gitlab
TaskAbortedByUserError = Class.new(StandardError)
module TaskHelpers
extend self
# Ask if the user wants to continue
#
# Returns "yes" the user chose to continue
......
# chang-ho,cha <changho.cha@gmail.com>, 2017. #zanata
# Korean translations for gitlab package.
# Copyright (C) 2017 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the gitlab package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2017.
# Huang Tao <htve@outlook.com>, 2017. #zanata
msgid ""
msgstr ""
......@@ -8,12 +11,12 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"PO-Revision-Date: 2017-08-06 09:40-0400\n"
"PO-Revision-Date: 2017-08-08 08:32-0400\n"
"Last-Translator: chang-ho,cha <changho.cha@gmail.com>\n"
"Language-Team: Korean (https://translate.zanata.org/project/view/GitLab)\n"
"Language: ko\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Zanata 3.9.6\n"
"Plural-Forms: nplurals=1; plural=0\n"
msgid "%d commit"
msgid_plural "%d commits"
......@@ -25,7 +28,7 @@ msgid_plural ""
msgstr[0] "%s 추가 커밋은 성능 이슈를 방지하기 위해 생략되었습니다."
msgid "%{commit_author_link} committed %{commit_timeago}"
msgstr "%{commit_timeago} 에 %{commit_author_link} 이(가) 커밋하였습니다. "
msgstr "%{commit_timeago} 에 %{commit_author_link} 님이 커밋하였습니다. "
msgid "1 pipeline"
msgid_plural "%d pipelines"
......@@ -791,7 +794,7 @@ msgid "Select target branch"
msgstr "대상 브랜치 선택"
msgid "Set a password on your account to pull or push via %{protocol}."
msgstr "%{protocol}을(를) 통해 Pull 하거나 Push하려면 계정에 패스워드를 설정하십시오."
msgstr "%{protocol} 프로토콜을 통해 Pull 하거나 Push하려면 계정에 패스워드를 설정하십시오."
msgid "Set up CI"
msgstr "CI 설정"
......@@ -1122,7 +1125,7 @@ msgid ""
"You are going to remove %{group_name}.\n"
"Removed groups CANNOT be restored!\n"
"Are you ABSOLUTELY sure?"
msgstr "%{group_name}을(를) 제거하려고합니다.\n"
msgstr "%{group_name} 그룹을 제거하려고합니다.\n"
"\"정말로\" 확실합니까?"
msgid ""
......@@ -1130,7 +1133,7 @@ msgid ""
"Removed project CANNOT be restored!\n"
"Are you ABSOLUTELY sure?"
msgstr ""
"%{project_name_with_namespace}을(를) 삭제하려고합니다.\n"
"%{project_name_with_namespace} 프로젝트를 삭제하려고합니다.\n"
"삭제된 프로젝트를 복원 할 수 없습니다!\n"
"\"정말로\" 확실합니까?"
......@@ -1185,7 +1188,7 @@ msgid ""
"You won't be able to pull or push project code via SSH until you "
"%{add_ssh_key_link} to your profile"
msgstr ""
"당신의 프로필에 %{add_ssh_key_link} 을(를) 하기 전에는 SSH를 통해 프로젝트 코드를 Pull 하거나 Push 할 수 "
"당신의 프로필에 %{add_ssh_key_link} 하기 전에는 SSH를 통해 프로젝트 코드를 Pull 하거나 Push 할 수 "
"없습니다"
msgid "Your name"
......
......@@ -127,7 +127,7 @@ describe Admin::UsersController do
describe 'POST create' do
it 'creates the user' do
expect{ post :create, user: attributes_for(:user) }.to change{ User.count }.by(1)
expect { post :create, user: attributes_for(:user) }.to change { User.count }.by(1)
end
it 'shows only one error message for an invalid email' do
......
......@@ -24,7 +24,7 @@ describe InvitesController do
describe 'GET #decline' do
it 'declines user' do
get :decline, id: token
expect{member.reload}.to raise_error ActiveRecord::RecordNotFound
expect {member.reload}.to raise_error ActiveRecord::RecordNotFound
expect(response).to have_http_status(302)
expect(flash[:notice]).to include 'You have declined the invitation to join'
......
......@@ -292,13 +292,13 @@ describe Projects::IssuesController do
it 'rejects an issue recognized as a spam' do
expect(Gitlab::Recaptcha).to receive(:load_configurations!).and_return(true)
expect { update_spam_issue }.not_to change{ issue.reload.title }
expect { update_spam_issue }.not_to change { issue.reload.title }
end
it 'rejects an issue recognized as a spam when recaptcha disabled' do
stub_application_setting(recaptcha_enabled: false)
expect { update_spam_issue }.not_to change{ issue.reload.title }
expect { update_spam_issue }.not_to change { issue.reload.title }
end
it 'creates a spam log' do
......@@ -358,7 +358,7 @@ describe Projects::IssuesController do
end
it 'accepts an issue after recaptcha is verified' do
expect{ update_verified_issue }.to change{ issue.reload.title }.to(spammy_title)
expect { update_verified_issue }.to change { issue.reload.title }.to(spammy_title)
end
it 'marks spam log as recaptcha_verified' do
......
......@@ -67,7 +67,7 @@ describe Projects::TodosController do
end
it "doesn't create todo" do
expect{ go }.not_to change { user.todos.count }
expect { go }.not_to change { user.todos.count }
expect(response).to have_http_status(404)
end
end
......@@ -135,7 +135,7 @@ describe Projects::TodosController do
end
it "doesn't create todo" do
expect{ go }.not_to change { user.todos.count }
expect { go }.not_to change { user.todos.count }
expect(response).to have_http_status(404)
end
end
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment