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: ...@@ -514,8 +514,11 @@ codeclimate:
services: services:
- docker:dind - docker:dind
script: 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 - 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 - cat raw_codeclimate.json | docker run -i stedolan/jq -c 'map({check_name,fingerprint,location})' > codeclimate.json
- mv .rubocop.yml.bak .rubocop.yml
artifacts: artifacts:
paths: [codeclimate.json] paths: [codeclimate.json]
......
require: require:
- rubocop-rspec - rubocop-rspec
- rubocop-gitlab-security
- ./rubocop/rubocop - ./rubocop/rubocop
inherit_from: .rubocop_todo.yml inherit_from: .rubocop_todo.yml
...@@ -206,6 +207,13 @@ Layout/SpaceAroundKeyword: ...@@ -206,6 +207,13 @@ Layout/SpaceAroundKeyword:
Layout/SpaceAroundOperators: Layout/SpaceAroundOperators:
Enabled: true 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. # No spaces before commas.
Layout/SpaceBeforeComma: Layout/SpaceBeforeComma:
Enabled: true Enabled: true
...@@ -1156,3 +1164,35 @@ RSpec/SubjectStub: ...@@ -1156,3 +1164,35 @@ RSpec/SubjectStub:
# Prefer using verifying doubles over normal doubles. # Prefer using verifying doubles over normal doubles.
RSpec/VerifiedDoubles: RSpec/VerifiedDoubles:
Enabled: false 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: ...@@ -26,13 +26,6 @@ Layout/IndentArray:
Layout/IndentHash: Layout/IndentHash:
Enabled: false Enabled: false
# Offense count: 174
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, SupportedStyles.
# SupportedStyles: space, no_space
Layout/SpaceBeforeBlockBraces:
Enabled: false
# Offense count: 8 # Offense count: 8
# Cop supports --auto-correct. # Cop supports --auto-correct.
# Configuration parameters: AllowForAlignment. # Configuration parameters: AllowForAlignment.
......
...@@ -341,6 +341,7 @@ group :development, :test do ...@@ -341,6 +341,7 @@ group :development, :test do
gem 'rubocop', '~> 0.49.1', require: false gem 'rubocop', '~> 0.49.1', require: false
gem 'rubocop-rspec', '~> 1.15.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 'scss_lint', '~> 0.54.0', require: false
gem 'haml_lint', '~> 0.26.0', require: false gem 'haml_lint', '~> 0.26.0', require: false
gem 'simplecov', '~> 0.14.0', require: false gem 'simplecov', '~> 0.14.0', require: false
...@@ -354,7 +355,7 @@ group :development, :test do ...@@ -354,7 +355,7 @@ group :development, :test do
gem 'activerecord_sane_schema_dumper', '0.2' gem 'activerecord_sane_schema_dumper', '0.2'
gem 'stackprof', '~> 0.2.10' gem 'stackprof', '~> 0.2.10', require: false
end end
group :test do group :test do
......
...@@ -548,7 +548,7 @@ GEM ...@@ -548,7 +548,7 @@ GEM
rubypants (~> 0.2) rubypants (~> 0.2)
orm_adapter (0.5.0) orm_adapter (0.5.0)
os (0.9.6) os (0.9.6)
parallel (1.11.2) parallel (1.12.0)
paranoia (2.3.1) paranoia (2.3.1)
activerecord (>= 4.0, < 5.2) activerecord (>= 4.0, < 5.2)
parser (2.4.0.0) parser (2.4.0.0)
...@@ -741,8 +741,9 @@ GEM ...@@ -741,8 +741,9 @@ GEM
rainbow (>= 1.99.1, < 3.0) rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1) unicode-display_width (~> 1.0, >= 1.0.1)
rubocop-gitlab-security (0.0.6)
rubocop (>= 0.47.1)
rubocop-rspec (1.15.1) rubocop-rspec (1.15.1)
rubocop (>= 0.42.0)
ruby-fogbugz (0.2.1) ruby-fogbugz (0.2.1)
crack (~> 0.4) crack (~> 0.4)
ruby-prof (0.16.2) ruby-prof (0.16.2)
...@@ -1088,6 +1089,7 @@ DEPENDENCIES ...@@ -1088,6 +1089,7 @@ DEPENDENCIES
rspec-set (~> 0.1.3) rspec-set (~> 0.1.3)
rspec_profiling (~> 0.0.5) rspec_profiling (~> 0.0.5)
rubocop (~> 0.49.1) rubocop (~> 0.49.1)
rubocop-gitlab-security (~> 0.0.6)
rubocop-rspec (~> 1.15.1) rubocop-rspec (~> 1.15.1)
ruby-fogbugz (~> 0.2.1) ruby-fogbugz (~> 0.2.1)
ruby-prof (~> 0.16.2) ruby-prof (~> 0.16.2)
......
...@@ -119,6 +119,12 @@ only be left until after the freeze if: ...@@ -119,6 +119,12 @@ only be left until after the freeze if:
are aware of it. are aware of it.
* It is in the correct milestone, with the ~Deliverable label. * 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 All Community Edition merge requests from GitLab team members merged on the
freeze date (the 7th) should have a corresponding Enterprise Edition merge 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 request, even if there are no conflicts. This is to reduce the size of the
...@@ -128,11 +134,26 @@ information, see ...@@ -128,11 +134,26 @@ information, see
### After the 7th ### After the 7th
Once the stable branch is frozen, only fixes for [regressions](#regressions) Once the stable branch is frozen, the only MRs that can be cherry-picked into
and security issues will be cherry-picked into the stable branch. the stable branch are:
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. * Fixes for [regressions](#regressions)
If the fixes are are completed on or after the 22nd, they will be shipped in a patch for that release. * 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, 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: 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. ...@@ -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 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. (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 All MRs which have had exceptions granted must be merged by the 15th.
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.
### Regressions ### Regressions
......
...@@ -76,6 +76,7 @@ import initLegacyFilters from './init_legacy_filters'; ...@@ -76,6 +76,7 @@ import initLegacyFilters from './init_legacy_filters';
import initIssuableSidebar from './init_issuable_sidebar'; import initIssuableSidebar from './init_issuable_sidebar';
import GpgBadges from './gpg_badges'; import GpgBadges from './gpg_badges';
import UserFeatureHelper from './helpers/user_feature_helper'; import UserFeatureHelper from './helpers/user_feature_helper';
import initChangesDropdown from './init_changes_dropdown';
(function() { (function() {
var Dispatcher; var Dispatcher;
...@@ -227,6 +228,7 @@ import UserFeatureHelper from './helpers/user_feature_helper'; ...@@ -227,6 +228,7 @@ import UserFeatureHelper from './helpers/user_feature_helper';
break; break;
case 'projects:compare:show': case 'projects:compare:show':
new gl.Diff(); new gl.Diff();
initChangesDropdown();
break; break;
case 'projects:branches:new': case 'projects:branches:new':
case 'projects:branches:create': case 'projects:branches:create':
...@@ -319,6 +321,7 @@ import UserFeatureHelper from './helpers/user_feature_helper'; ...@@ -319,6 +321,7 @@ import UserFeatureHelper from './helpers/user_feature_helper';
container: '.js-commit-pipeline-graph', container: '.js-commit-pipeline-graph',
}).bindEvents(); }).bindEvents();
initNotes(); initNotes();
initChangesDropdown();
$('.commit-info.branches').load(document.querySelector('.js-commit-box').dataset.commitPath); $('.commit-info.branches').load(document.querySelector('.js-commit-box').dataset.commitPath);
break; break;
case 'projects:commit:pipelines': 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 */ /* 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 dateFormat */
/* global Pikaday */
import Pikaday from 'pikaday';
import DateFix from './lib/utils/datefix'; import DateFix from './lib/utils/datefix';
class DueDateSelect { class DueDateSelect {
......
/* global bp */ /* global bp */
import Cookies from 'js-cookie';
import './breakpoints'; 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) => { export const calculateTop = (boundingRect, outerHeight) => {
const windowHeight = window.innerHeight; const windowHeight = window.innerHeight;
...@@ -14,9 +24,10 @@ export const calculateTop = (boundingRect, outerHeight) => { ...@@ -14,9 +24,10 @@ export const calculateTop = (boundingRect, outerHeight) => {
export const showSubLevelItems = (el) => { export const showSubLevelItems = (el) => {
const subItems = el.querySelector('.sidebar-sub-level-items'); const subItems = el.querySelector('.sidebar-sub-level-items');
if (!subItems || !canShowSubItems()) return; if (!subItems || !canShowSubItems() || !canShowActiveSubItems(el)) return;
subItems.style.display = 'block'; subItems.style.display = 'block';
el.classList.add('is-showing-fly-out');
el.classList.add('is-over'); el.classList.add('is-over');
const boundingRect = el.getBoundingClientRect(); const boundingRect = el.getBoundingClientRect();
...@@ -34,15 +45,17 @@ export const showSubLevelItems = (el) => { ...@@ -34,15 +45,17 @@ export const showSubLevelItems = (el) => {
export const hideSubLevelItems = (el) => { export const hideSubLevelItems = (el) => {
const subItems = el.querySelector('.sidebar-sub-level-items'); 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'); el.classList.remove('is-over');
subItems.style.display = 'none'; subItems.style.display = '';
subItems.style.transform = '';
subItems.classList.remove('is-above'); subItems.classList.remove('is-above');
}; };
export default () => { 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')); .filter(el => el.querySelector('.sidebar-sub-level-items'));
items.forEach((el) => { 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 @@ ...@@ -2,8 +2,8 @@
/* global GitLab */ /* global GitLab */
/* global Autosave */ /* global Autosave */
/* global dateFormat */ /* global dateFormat */
/* global Pikaday */
import Pikaday from 'pikaday';
import UsersSelect from './users_select'; import UsersSelect from './users_select';
import GfmAutoComplete from './gfm_auto_complete'; import GfmAutoComplete from './gfm_auto_complete';
import ZenMode from './zen_mode'; import ZenMode from './zen_mode';
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
import jQuery from 'jquery'; import jQuery from 'jquery';
import _ from 'underscore'; import _ from 'underscore';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import Pikaday from 'pikaday';
import Dropzone from 'dropzone'; import Dropzone from 'dropzone';
import Sortable from 'vendor/Sortable'; import Sortable from 'vendor/Sortable';
...@@ -20,7 +19,6 @@ import 'vendor/fuzzaldrin-plus'; ...@@ -20,7 +19,6 @@ import 'vendor/fuzzaldrin-plus';
window.jQuery = jQuery; window.jQuery = jQuery;
window.$ = jQuery; window.$ = jQuery;
window._ = _; window._ = _;
window.Pikaday = Pikaday;
window.Dropzone = Dropzone; window.Dropzone = Dropzone;
window.Sortable = Sortable; window.Sortable = Sortable;
......
/* global Pikaday */
/* global dateFormat */ /* global dateFormat */
import Pikaday from 'pikaday';
(() => { (() => {
// Add datepickers to all `js-access-expiration-date` elements. If those elements are // 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 // children of an element with the `clearable-input` class, and have a sibling
......
...@@ -7,7 +7,7 @@ import Cookies from 'js-cookie'; ...@@ -7,7 +7,7 @@ import Cookies from 'js-cookie';
import './breakpoints'; import './breakpoints';
import './flash'; import './flash';
import BlobForkSuggestion from './blob/blob_fork_suggestion'; import BlobForkSuggestion from './blob/blob_fork_suggestion';
import stickyMonitor from './lib/utils/sticky'; import initChangesDropdown from './init_changes_dropdown';
/* eslint-disable max-len */ /* eslint-disable max-len */
// MergeRequestTabs // MergeRequestTabs
...@@ -267,9 +267,7 @@ import stickyMonitor from './lib/utils/sticky'; ...@@ -267,9 +267,7 @@ import stickyMonitor from './lib/utils/sticky';
const $container = $('#diffs'); const $container = $('#diffs');
$container.html(data.html); $container.html(data.html);
this.initChangesDropdown(); initChangesDropdown();
stickyMonitor(document.querySelector('.js-diff-files-changed'));
if (typeof gl.diffNotesCompileComponents !== 'undefined') { if (typeof gl.diffNotesCompileComponents !== 'undefined') {
gl.diffNotesCompileComponents(); gl.diffNotesCompileComponents();
...@@ -319,13 +317,6 @@ import stickyMonitor from './lib/utils/sticky'; ...@@ -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 // Show or hide the loading spinner
// //
// status - Boolean, true to show, false to hide // status - Boolean, true to show, false to hide
......
...@@ -104,11 +104,14 @@ $new-sidebar-collapsed-width: 50px; ...@@ -104,11 +104,14 @@ $new-sidebar-collapsed-width: 50px;
&.sidebar-icons-only { &.sidebar-icons-only {
width: $new-sidebar-collapsed-width; width: $new-sidebar-collapsed-width;
.nav-item-name,
.badge, .badge,
.project-title { .project-title {
display: none; display: none;
} }
.nav-item-name {
opacity: 0;
}
} }
&.nav-sidebar-expanded { &.nav-sidebar-expanded {
...@@ -182,7 +185,7 @@ $new-sidebar-collapsed-width: 50px; ...@@ -182,7 +185,7 @@ $new-sidebar-collapsed-width: 50px;
> li { > li {
a { a {
padding: 8px 16px 8px 50px; padding: 8px 16px 8px 40px;
&:hover, &:hover,
&:focus { &:focus {
...@@ -215,12 +218,15 @@ $new-sidebar-collapsed-width: 50px; ...@@ -215,12 +218,15 @@ $new-sidebar-collapsed-width: 50px;
&:hover { &:hover {
color: $gl-text-color; color: $gl-text-color;
svg {
fill: $gl-text-color;
}
} }
} }
&:not(.active) { &.is-showing-fly-out {
> a { > a {
margin-left: 1px;
margin-right: 2px; margin-right: 2px;
} }
...@@ -271,6 +277,14 @@ $new-sidebar-collapsed-width: 50px; ...@@ -271,6 +277,14 @@ $new-sidebar-collapsed-width: 50px;
} }
} }
> .active {
box-shadow: none;
> a {
background-color: transparent;
}
}
a { a {
padding: 8px 16px; padding: 8px 16px;
color: $gl-text-color; color: $gl-text-color;
...@@ -294,6 +308,7 @@ $new-sidebar-collapsed-width: 50px; ...@@ -294,6 +308,7 @@ $new-sidebar-collapsed-width: 50px;
> a { > a {
margin-left: 4px; margin-left: 4px;
padding-left: 12px;
} }
.badge { .badge {
...@@ -354,7 +369,7 @@ $new-sidebar-collapsed-width: 50px; ...@@ -354,7 +369,7 @@ $new-sidebar-collapsed-width: 50px;
.sidebar-icons-only { .sidebar-icons-only {
.context-header { .context-header {
height: 60px; height: 61px;
a { a {
padding: 10px 4px; padding: 10px 4px;
......
...@@ -574,10 +574,14 @@ ...@@ -574,10 +574,14 @@
@media (min-width: $screen-sm-min) { @media (min-width: $screen-sm-min) {
position: -webkit-sticky; position: -webkit-sticky;
position: sticky; position: sticky;
top: 84px; top: 34px;
background-color: $white-light; background-color: $white-light;
z-index: 190; z-index: 190;
&.diff-files-changed-merge-request {
top: 84px;
}
+ .files, + .files,
+ .alert { + .alert {
margin-top: 1px; margin-top: 1px;
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
.commit-box, .commit-box,
.info-well, .info-well,
.commit-ci-menu, .commit-ci-menu,
.files-changed, .files-changed-inner,
.limited-header-width, .limited-header-width,
.limited-width-notes { .limited-width-notes {
@extend .fixed-width-container; @extend .fixed-width-container;
......
...@@ -117,7 +117,7 @@ class ApplicationController < ActionController::Base ...@@ -117,7 +117,7 @@ class ApplicationController < ActionController::Base
Raven.capture_exception(exception) if sentry_enabled? Raven.capture_exception(exception) if sentry_enabled?
application_trace = ActionDispatch::ExceptionWrapper.new(env, exception).application_trace 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}" logger.error "\n#{exception.class.name} (#{exception.message}):\n#{application_trace.join}"
end end
......
...@@ -68,15 +68,15 @@ class Import::GithubController < Import::BaseController ...@@ -68,15 +68,15 @@ class Import::GithubController < Import::BaseController
end end
def new_import_url def new_import_url
public_send("new_import_#{provider}_url") public_send("new_import_#{provider}_url") # rubocop:disable GitlabSecurity/PublicSend
end end
def status_import_url def status_import_url
public_send("status_import_#{provider}_url") public_send("status_import_#{provider}_url") # rubocop:disable GitlabSecurity/PublicSend
end end
def callback_import_url def callback_import_url
public_send("callback_import_#{provider}_url") public_send("callback_import_#{provider}_url") # rubocop:disable GitlabSecurity/PublicSend
end end
def provider_unauthorized def provider_unauthorized
......
...@@ -15,7 +15,7 @@ class Import::GitlabController < Import::BaseController ...@@ -15,7 +15,7 @@ class Import::GitlabController < Import::BaseController
@already_added_projects = current_user.created_projects.where(import_type: "gitlab") @already_added_projects = current_user.created_projects.where(import_type: "gitlab")
already_added_projects_names = @already_added_projects.pluck(:import_source) 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 end
def jobs def jobs
......
...@@ -3,7 +3,7 @@ module GraphHelper ...@@ -3,7 +3,7 @@ module GraphHelper
refs = "" refs = ""
# Commit::ref_names already strips the refs/XXX from important refs (e.g. refs/heads/XXX) # Commit::ref_names already strips the refs/XXX from important refs (e.g. refs/heads/XXX)
# so anything leftover is internally used by GitLab # 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(' ') refs << commit_refs.join(' ')
# append note count # append note count
......
...@@ -151,7 +151,7 @@ module IssuablesHelper ...@@ -151,7 +151,7 @@ module IssuablesHelper
end end
def issuable_labels_tooltip(labels, limit: 5) 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 = first.collect(&:name)
label_names << "and #{last.size} more" unless last.empty? label_names << "and #{last.size} more" unless last.empty?
...@@ -234,7 +234,7 @@ module IssuablesHelper ...@@ -234,7 +234,7 @@ module IssuablesHelper
end end
def issuables_count_for_state(issuable_type, state, finder: nil) 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 cache_key = finder.state_counter_cache_key
@counts ||= {} @counts ||= {}
...@@ -329,7 +329,7 @@ module IssuablesHelper ...@@ -329,7 +329,7 @@ module IssuablesHelper
end end
def selected_template(issuable) 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 end
def issuable_todo_button_data(issuable, todo, is_collapsed) def issuable_todo_button_data(issuable, todo, is_collapsed)
......
...@@ -43,11 +43,11 @@ module LabelsHelper ...@@ -43,11 +43,11 @@ module LabelsHelper
def label_filter_path(subject, label, type: :issue) def label_filter_path(subject, label, type: :issue)
case subject case subject
when Group when Group
send("#{type.to_s.pluralize}_group_path", send("#{type.to_s.pluralize}_group_path", # rubocop:disable GitlabSecurity/PublicSend
subject, subject,
label_name: [label.name]) label_name: [label.name])
when Project 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.namespace,
subject, subject,
label_name: [label.name]) label_name: [label.name])
......
...@@ -58,7 +58,7 @@ module Spammable ...@@ -58,7 +58,7 @@ module Spammable
options.fetch(:spam_title, false) options.fetch(:spam_title, false)
end 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 end
def spam_description def spam_description
...@@ -66,12 +66,12 @@ module Spammable ...@@ -66,12 +66,12 @@ module Spammable
options.fetch(:spam_description, false) options.fetch(:spam_description, false)
end 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 end
def spammable_text def spammable_text
result = self.class.spammable_attrs.map do |attr| result = self.class.spammable_attrs.map do |attr|
public_send(attr.first) public_send(attr.first) # rubocop:disable GitlabSecurity/PublicSend
end end
result.reject(&:blank?).join("\n") result.reject(&:blank?).join("\n")
......
...@@ -44,7 +44,8 @@ module TokenAuthenticatable ...@@ -44,7 +44,8 @@ module TokenAuthenticatable
end end
define_method("ensure_#{token_field}!") do 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) read_attribute(token_field)
end end
......
...@@ -162,7 +162,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -162,7 +162,7 @@ class MergeRequest < ActiveRecord::Base
target = unscoped.where(target_project_id: relation).select(:id) target = unscoped.where(target_project_id: relation).select(:id)
union = Gitlab::SQL::Union.new([source, target]) 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 end
WIP_REGEX = /\A\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i.freeze WIP_REGEX = /\A\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i.freeze
......
...@@ -26,7 +26,7 @@ class MergeRequestDiffCommit < ActiveRecord::Base ...@@ -26,7 +26,7 @@ class MergeRequestDiffCommit < ActiveRecord::Base
def to_hash def to_hash
Gitlab::Git::Commit::SERIALIZE_KEYS.each_with_object({}) do |key, 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
end end
......
...@@ -206,7 +206,7 @@ module Network ...@@ -206,7 +206,7 @@ module Network
# Visit branching chains # Visit branching chains
leaves.each do |l| 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| parents.each do |p|
place_chain(p, l.time) place_chain(p, l.time)
end end
......
...@@ -77,20 +77,20 @@ class Note < ActiveRecord::Base ...@@ -77,20 +77,20 @@ class Note < ActiveRecord::Base
# Scopes # Scopes
scope :for_commit_id, ->(commit_id) { where(noteable_type: "Commit", commit_id: commit_id) } scope :for_commit_id, ->(commit_id) { where(noteable_type: "Commit", commit_id: commit_id) }
scope :system, ->{ where(system: true) } scope :system, -> { where(system: true) }
scope :user, ->{ where(system: false) } scope :user, -> { where(system: false) }
scope :common, ->{ where(noteable_type: ["", nil]) } scope :common, -> { where(noteable_type: ["", nil]) }
scope :fresh, ->{ order(created_at: :asc, id: :asc) } scope :fresh, -> { order(created_at: :asc, id: :asc) }
scope :updated_after, ->(time){ where('updated_at > ?', time) } scope :updated_after, ->(time) { where('updated_at > ?', time) }
scope :inc_author_project, ->{ includes(:project, :author) } scope :inc_author_project, -> { includes(:project, :author) }
scope :inc_author, ->{ includes(:author) } scope :inc_author, -> { includes(:author) }
scope :inc_relations_for_view, -> do scope :inc_relations_for_view, -> do
includes(:project, :author, :updated_by, :resolved_by, :award_emoji, :system_note_metadata) includes(:project, :author, :updated_by, :resolved_by, :award_emoji, :system_note_metadata)
end end
scope :diff_notes, ->{ where(type: %w(LegacyDiffNote DiffNote)) } scope :diff_notes, -> { where(type: %w(LegacyDiffNote DiffNote)) }
scope :new_diff_notes, ->{ where(type: 'DiffNote') } scope :new_diff_notes, -> { where(type: 'DiffNote') }
scope :non_diff_notes, ->{ where(type: ['Note', 'DiscussionNote', nil]) } scope :non_diff_notes, -> { where(type: ['Note', 'DiscussionNote', nil]) }
scope :with_associations, -> do scope :with_associations, -> do
# FYI noteable cannot be loaded for LegacyDiffNote for commits # FYI noteable cannot be loaded for LegacyDiffNote for commits
......
...@@ -66,6 +66,6 @@ class NotificationSetting < ActiveRecord::Base ...@@ -66,6 +66,6 @@ class NotificationSetting < ActiveRecord::Base
alias_method :failed_pipeline?, :failed_pipeline alias_method :failed_pipeline?, :failed_pipeline
def event_enabled?(event) def event_enabled?(event)
respond_to?(event) && !!public_send(event) respond_to?(event) && !!public_send(event) # rubocop:disable GitlabSecurity/PublicSend
end end
end end
...@@ -415,7 +415,7 @@ class Project < ActiveRecord::Base ...@@ -415,7 +415,7 @@ class Project < ActiveRecord::Base
union = Gitlab::SQL::Union.new([projects, namespaces]) 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 end
def search_by_title(query) def search_by_title(query)
...@@ -825,7 +825,7 @@ class Project < ActiveRecord::Base ...@@ -825,7 +825,7 @@ class Project < ActiveRecord::Base
if template.nil? if template.nil?
# If no template, we should create an instance. Ex `build_gitlab_ci_service` # 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 else
Service.build_from_template(id, template) Service.build_from_template(id, template)
end end
...@@ -1046,6 +1046,7 @@ class Project < ActiveRecord::Base ...@@ -1046,6 +1046,7 @@ class Project < ActiveRecord::Base
end end
def change_head(branch) def change_head(branch)
if repository.branch_exists?(branch)
repository.before_change_head repository.before_change_head
repository.rugged.references.create('HEAD', repository.rugged.references.create('HEAD',
"refs/heads/#{branch}", "refs/heads/#{branch}",
...@@ -1053,6 +1054,10 @@ class Project < ActiveRecord::Base ...@@ -1053,6 +1054,10 @@ class Project < ActiveRecord::Base
repository.copy_gitattributes(branch) repository.copy_gitattributes(branch)
repository.after_change_head repository.after_change_head
reload_default_branch reload_default_branch
else
errors.add(:base, "Could not change HEAD: branch '#{branch}' does not exist")
false
end
end end
def forked_from?(project) def forked_from?(project)
...@@ -1326,7 +1331,7 @@ class Project < ActiveRecord::Base ...@@ -1326,7 +1331,7 @@ class Project < ActiveRecord::Base
end end
def append_or_update_attribute(name, value) 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? if Project.reflect_on_association(name).try(:macro) == :has_many && old_values.any?
update_attribute(name, old_values + value) update_attribute(name, old_values + value)
......
...@@ -55,7 +55,7 @@ class ProjectFeature < ActiveRecord::Base ...@@ -55,7 +55,7 @@ class ProjectFeature < ActiveRecord::Base
end end
def access_level(feature) def access_level(feature)
public_send(ProjectFeature.access_level_attribute(feature)) public_send(ProjectFeature.access_level_attribute(feature)) # rubocop:disable GitlabSecurity/PublicSend
end end
def builds_enabled? def builds_enabled?
...@@ -80,7 +80,7 @@ class ProjectFeature < ActiveRecord::Base ...@@ -80,7 +80,7 @@ class ProjectFeature < ActiveRecord::Base
# which cannot be higher than repository access level # which cannot be higher than repository access level
def repository_children_level def repository_children_level
validator = lambda do |field| 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 not_allowed = level > repository_access_level
self.errors.add(field, "cannot have higher visibility level than repository access level") if not_allowed self.errors.add(field, "cannot have higher visibility level than repository access level") if not_allowed
end end
......
...@@ -14,7 +14,7 @@ class ProjectStatistics < ActiveRecord::Base ...@@ -14,7 +14,7 @@ class ProjectStatistics < ActiveRecord::Base
def refresh!(only: nil) def refresh!(only: nil)
STATISTICS_COLUMNS.each do |column, generator| STATISTICS_COLUMNS.each do |column, generator|
if only.blank? || only.include?(column) if only.blank? || only.include?(column)
public_send("update_#{column}") public_send("update_#{column}") # rubocop:disable GitlabSecurity/PublicSend
end end
end end
......
...@@ -300,7 +300,7 @@ class Repository ...@@ -300,7 +300,7 @@ class Repository
expire_method_caches(to_refresh) expire_method_caches(to_refresh)
to_refresh.each { |method| send(method) } to_refresh.each { |method| send(method) } # rubocop:disable GitlabSecurity/PublicSend
end end
def expire_branch_cache(branch_name = nil) def expire_branch_cache(branch_name = nil)
......
...@@ -148,6 +148,8 @@ class User < ActiveRecord::Base ...@@ -148,6 +148,8 @@ class User < ActiveRecord::Base
uniqueness: { case_sensitive: false } uniqueness: { case_sensitive: false }
validate :namespace_uniq, if: :username_changed? 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 :avatar_type, if: ->(user) { user.avatar.present? && user.avatar_changed? }
validate :unique_email, if: :email_changed? validate :unique_email, if: :email_changed?
validate :owns_notification_email, if: :notification_email_changed? validate :owns_notification_email, if: :notification_email_changed?
...@@ -487,6 +489,12 @@ class User < ActiveRecord::Base ...@@ -487,6 +489,12 @@ class User < ActiveRecord::Base
end end
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 def avatar_type
unless avatar.image? unless avatar.image?
errors.add :avatar, "only images allowed" errors.add :avatar, "only images allowed"
...@@ -528,7 +536,7 @@ class User < ActiveRecord::Base ...@@ -528,7 +536,7 @@ class User < ActiveRecord::Base
union = Gitlab::SQL::Union union = Gitlab::SQL::Union
.new([groups.select(:id), authorized_projects.select(:namespace_id)]) .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 end
# Returns a relation of groups the user has access to, including their parent # Returns a relation of groups the user has access to, including their parent
...@@ -719,8 +727,8 @@ class User < ActiveRecord::Base ...@@ -719,8 +727,8 @@ class User < ActiveRecord::Base
def sanitize_attrs def sanitize_attrs
%w[username skype linkedin twitter].each do |attr| %w[username skype linkedin twitter].each do |attr|
value = public_send(attr) value = public_send(attr) # rubocop:disable GitlabSecurity/PublicSend
public_send("#{attr}=", Sanitize.clean(value)) if value.present? public_send("#{attr}=", Sanitize.clean(value)) if value.present? # rubocop:disable GitlabSecurity/PublicSend
end end
end end
...@@ -779,7 +787,7 @@ class User < ActiveRecord::Base ...@@ -779,7 +787,7 @@ class User < ActiveRecord::Base
def with_defaults def with_defaults
User.defaults.each do |k, v| User.defaults.each do |k, v|
public_send("#{k}=", v) public_send("#{k}=", v) # rubocop:disable GitlabSecurity/PublicSend
end end
self self
...@@ -825,7 +833,7 @@ class User < ActiveRecord::Base ...@@ -825,7 +833,7 @@ class User < ActiveRecord::Base
{ {
name: name, name: name,
username: username, username: username,
avatar_url: avatar_url avatar_url: avatar_url(only_path: false)
} }
end end
...@@ -919,7 +927,7 @@ class User < ActiveRecord::Base ...@@ -919,7 +927,7 @@ class User < ActiveRecord::Base
def ci_authorized_runners def ci_authorized_runners
@ci_authorized_runners ||= begin @ci_authorized_runners ||= begin
runner_ids = Ci::RunnerProject 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) .select(:runner_id)
Ci::Runner.specific.where(id: runner_ids) Ci::Runner.specific.where(id: runner_ids)
end end
......
...@@ -35,6 +35,6 @@ class AnalyticsBuildEntity < Grape::Entity ...@@ -35,6 +35,6 @@ class AnalyticsBuildEntity < Grape::Entity
private private
def url_to(route, build, id = nil) 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
end end
...@@ -24,6 +24,6 @@ class AnalyticsIssueEntity < Grape::Entity ...@@ -24,6 +24,6 @@ class AnalyticsIssueEntity < Grape::Entity
private private
def url_to(route, id) 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
end end
...@@ -46,6 +46,6 @@ class JobEntity < Grape::Entity ...@@ -46,6 +46,6 @@ class JobEntity < Grape::Entity
end end
def path_to(route, build) 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
end end
...@@ -16,6 +16,7 @@ module Issues ...@@ -16,6 +16,7 @@ module Issues
spam_check(issue, current_user) spam_check(issue, current_user)
issue.move_to_end issue.move_to_end
# current_user (defined in BaseService) is not available within run_after_commit block
user = current_user user = current_user
issue.run_after_commit do issue.run_after_commit do
NewIssueWorker.perform_async(issue.id, user.id) NewIssueWorker.perform_async(issue.id, user.id)
......
...@@ -37,7 +37,7 @@ module Labels ...@@ -37,7 +37,7 @@ module Labels
union = Gitlab::SQL::Union.new(label_ids) 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 end
def group_labels_applied_to_issues def group_labels_applied_to_issues
......
...@@ -17,6 +17,7 @@ module MergeRequests ...@@ -17,6 +17,7 @@ module MergeRequests
end end
def before_create(merge_request) def before_create(merge_request)
# current_user (defined in BaseService) is not available within run_after_commit block
user = current_user user = current_user
merge_request.run_after_commit do merge_request.run_after_commit do
NewMergeRequestWorker.perform_async(merge_request.id, user.id) NewMergeRequestWorker.perform_async(merge_request.id, user.id)
......
...@@ -10,7 +10,7 @@ module Projects ...@@ -10,7 +10,7 @@ module Projects
end end
if changing_default_branch? 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 end
if project.update_attributes(params.except(:default_branch)) if project.update_attributes(params.except(:default_branch))
......
...@@ -74,7 +74,8 @@ ...@@ -74,7 +74,8 @@
= link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username } = link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username }
%li %li
= link_to "Settings", profile_path = 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.divider
%li %li
= link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link" = link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link"
......
...@@ -68,7 +68,8 @@ ...@@ -68,7 +68,8 @@
= link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username } = link_to "Profile", current_user, class: 'profile-link', data: { user: current_user.username }
%li %li
= link_to "Settings", profile_path = 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.divider
%li %li
= link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link" = link_to "Sign out", destroy_user_session_path, method: :delete, class: "sign-out-link"
......
...@@ -18,8 +18,6 @@ ...@@ -18,8 +18,6 @@
= scheme.name = scheme.name
.col-sm-12 .col-sm-12
%hr %hr
%h3#experimental-features Experimental features
%hr
.col-lg-4.profile-settings-sidebar#new-navigation .col-lg-4.profile-settings-sidebar#new-navigation
%h4.prepend-top-0 %h4.prepend-top-0
New Navigation New Navigation
...@@ -42,28 +40,6 @@ ...@@ -42,28 +40,6 @@
New New
.col-sm-12 .col-sm-12
%hr %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 .col-lg-4.profile-settings-sidebar
%h4.prepend-top-0 %h4.prepend-top-0
Behavior Behavior
......
...@@ -2,8 +2,10 @@ ...@@ -2,8 +2,10 @@
- show_whitespace_toggle = local_assigns.fetch(:show_whitespace_toggle, true) - show_whitespace_toggle = local_assigns.fetch(:show_whitespace_toggle, true)
- can_create_note = !@diff_notes_disabled && can?(current_user, :create_note, diffs.project) - can_create_note = !@diff_notes_disabled && can?(current_user, :create_note, diffs.project)
- diff_files = diffs.diff_files - 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 .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 .inline-parallel-buttons
- if !diffs_expanded? && diff_files.any? { |diff_file| diff_file.collapsed? } - 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' = link_to 'Expand all', url_for(params.merge(expanded: 1, format: nil)), class: 'btn btn-default'
......
- if @merge_request_diff.collected? || @merge_request_diff.overflow? - if @merge_request_diff.collected? || @merge_request_diff.overflow?
= render 'projects/merge_requests/diffs/versions' = 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? - elsif @merge_request_diff.empty?
.nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch} .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 module NewIssuable
attr_reader :issuable, :user attr_reader :issuable, :user
def ensure_objects_found(issuable_id, user_id) def objects_found?(issuable_id, user_id)
@issuable = issuable_class.find_by(id: issuable_id) set_user(user_id)
unless @issuable set_issuable(issuable_id)
log_error(issuable_class, issuable_id)
return false user && issuable
end end
def set_user(user_id)
@user = User.find_by(id: user_id) @user = User.find_by(id: user_id)
unless @user
log_error(User, user_id) log_error(User, user_id) unless @user
return false
end end
true def set_issuable(issuable_id)
@issuable = issuable_class.find_by(id: issuable_id)
log_error(issuable_class, issuable_id) unless @issuable
end end
def log_error(record_class, record_id) def log_error(record_class, record_id)
......
...@@ -4,7 +4,7 @@ class NewIssueWorker ...@@ -4,7 +4,7 @@ class NewIssueWorker
include NewIssuable include NewIssuable
def perform(issue_id, user_id) 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) EventCreateService.new.open_issue(issuable, user)
NotificationService.new.new_issue(issuable, user) NotificationService.new.new_issue(issuable, user)
......
...@@ -4,7 +4,7 @@ class NewMergeRequestWorker ...@@ -4,7 +4,7 @@ class NewMergeRequestWorker
include NewIssuable include NewIssuable
def perform(merge_request_id, user_id) 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) EventCreateService.new.open_mr(issuable, user)
NotificationService.new.new_merge_request(issuable, user) NotificationService.new.new_merge_request(issuable, user)
......
...@@ -4,7 +4,7 @@ class PagesWorker ...@@ -4,7 +4,7 @@ class PagesWorker
sidekiq_options queue: :pages, retry: false sidekiq_options queue: :pages, retry: false
def perform(action, *arg) def perform(action, *arg)
send(action, *arg) send(action, *arg) # rubocop:disable GitlabSecurity/PublicSend
end end
def deploy(build_id) def deploy(build_id)
......
#!/usr/bin/env ruby #!/usr/bin/env ruby
require 'bundler/setup'
require 'stackprof' require 'stackprof'
$:.unshift 'spec' $:.unshift 'spec'
require 'rails_helper' require 'rails_helper'
...@@ -13,4 +14,4 @@ StackProf.run(mode: :wall, out: output_file, interval: interval) do ...@@ -13,4 +14,4 @@ StackProf.run(mode: :wall, out: output_file, interval: interval) do
RSpec::Core::Runner.run(ARGV, $stderr, $stdout) RSpec::Core::Runner.run(ARGV, $stderr, $stdout)
end 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 ...@@ -176,7 +176,7 @@ module Gitlab
next unless name.include?('namespace_project') next unless name.include?('namespace_project')
define_method(name.sub('namespace_project', 'project')) do |project, *args| 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 end
end end
......
...@@ -71,7 +71,7 @@ class Settings < Settingslogic ...@@ -71,7 +71,7 @@ class Settings < Settingslogic
# check that `current` (string or integer) is a contant in `modul`. # check that `current` (string or integer) is a contant in `modul`.
def verify_constant(modul, current, default) 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) value = constant.nil? ? default : modul.const_get(constant)
if current.is_a? String if current.is_a? String
value = modul.const_get(current.upcase) rescue default value = modul.const_get(current.upcase) rescue default
......
...@@ -18,7 +18,7 @@ module ActiveRecord ...@@ -18,7 +18,7 @@ module ActiveRecord
lock_col = self.class.locking_column 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 # This line is added as a patch
previous_lock_value = nil if previous_lock_value == '0' || previous_lock_value == 0 previous_lock_value = nil if previous_lock_value == '0' || previous_lock_value == 0
...@@ -48,7 +48,7 @@ module ActiveRecord ...@@ -48,7 +48,7 @@ module ActiveRecord
# If something went wrong, revert the version. # If something went wrong, revert the version.
rescue Exception rescue Exception
send(lock_col + '=', previous_lock_value) send(lock_col + '=', previous_lock_value) # rubocop:disable GitlabSecurity/PublicSend
raise raise
end end
end end
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
resource :repository, only: [:create] do resource :repository, only: [:create] do
member do member do
get ':ref/archive', constraints: { format: Gitlab::PathRegex.archive_formats_regex, ref: /.+/ }, action: 'archive', as: 'archive' 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
end end
......
...@@ -10,7 +10,7 @@ class AddUniqueIndexToLabels < ActiveRecord::Migration ...@@ -10,7 +10,7 @@ class AddUniqueIndexToLabels < ActiveRecord::Migration
def up 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| 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']) 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 label_id = duplicated_ids.first
duplicated_ids.delete(label_id) duplicated_ids.delete(label_id)
......
...@@ -30,7 +30,7 @@ class CleanupNamespacelessPendingDeleteProjects < ActiveRecord::Migration ...@@ -30,7 +30,7 @@ class CleanupNamespacelessPendingDeleteProjects < ActiveRecord::Migration
private private
def pending_delete_batch 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 end
BATCH_SIZE = 5000 BATCH_SIZE = 5000
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
Welcome to [GitLab](https://about.gitlab.com/), a Git-based fully featured Welcome to [GitLab](https://about.gitlab.com/), a Git-based fully featured
platform for software development! 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/), - **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. 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) ...@@ -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. 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. 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` ## `production.log`
This file lives in `/var/log/gitlab/gitlab-rails/production.log` for This file lives in `/var/log/gitlab/gitlab-rails/production.log` for
......
...@@ -296,9 +296,9 @@ sudo usermod -aG redis git ...@@ -296,9 +296,9 @@ sudo usermod -aG redis git
### Clone the Source ### Clone the Source
# Clone GitLab repository # 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 ### Configure It
...@@ -507,15 +507,17 @@ Check if GitLab and its environment are configured correctly: ...@@ -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 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 ### Compile Assets
sudo -u git -H yarn install --production --pure-lockfile 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 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 ### Start Your GitLab Instance
sudo service gitlab start sudo service gitlab start
......
...@@ -31,7 +31,7 @@ X-Gitlab-Event: System Hook ...@@ -31,7 +31,7 @@ X-Gitlab-Event: System Hook
"path": "storecloud", "path": "storecloud",
"path_with_namespace": "jsmith/storecloud", "path_with_namespace": "jsmith/storecloud",
"project_id": 74, "project_id": 74,
"project_visibility": "private", "project_visibility": "private"
} }
``` ```
...@@ -48,7 +48,7 @@ X-Gitlab-Event: System Hook ...@@ -48,7 +48,7 @@ X-Gitlab-Event: System Hook
"path": "underscore", "path": "underscore",
"path_with_namespace": "jsmith/underscore", "path_with_namespace": "jsmith/underscore",
"project_id": 73, "project_id": 73,
"project_visibility": "internal", "project_visibility": "internal"
} }
``` ```
...@@ -66,7 +66,7 @@ X-Gitlab-Event: System Hook ...@@ -66,7 +66,7 @@ X-Gitlab-Event: System Hook
"owner_name": "John Smith", "owner_name": "John Smith",
"owner_email": "johnsmith@gmail.com", "owner_email": "johnsmith@gmail.com",
"project_visibility": "internal", "project_visibility": "internal",
"old_path_with_namespace": "jsmith/overscore", "old_path_with_namespace": "jsmith/overscore"
} }
``` ```
...@@ -84,7 +84,7 @@ X-Gitlab-Event: System Hook ...@@ -84,7 +84,7 @@ X-Gitlab-Event: System Hook
"owner_name": "John Smith", "owner_name": "John Smith",
"owner_email": "johnsmith@gmail.com", "owner_email": "johnsmith@gmail.com",
"project_visibility": "internal", "project_visibility": "internal",
"old_path_with_namespace": "jsmith/overscore", "old_path_with_namespace": "jsmith/overscore"
} }
``` ```
...@@ -101,7 +101,7 @@ X-Gitlab-Event: System Hook ...@@ -101,7 +101,7 @@ X-Gitlab-Event: System Hook
"path": "storecloud", "path": "storecloud",
"path_with_namespace": "jsmith/storecloud", "path_with_namespace": "jsmith/storecloud",
"project_id": 74, "project_id": 74,
"project_visibility": "private", "project_visibility": "private"
} }
``` ```
...@@ -121,7 +121,7 @@ X-Gitlab-Event: System Hook ...@@ -121,7 +121,7 @@ X-Gitlab-Event: System Hook
"user_name": "John Smith", "user_name": "John Smith",
"user_username": "johnsmith", "user_username": "johnsmith",
"user_id": 41, "user_id": 41,
"project_visibility": "private", "project_visibility": "private"
} }
``` ```
...@@ -141,7 +141,7 @@ X-Gitlab-Event: System Hook ...@@ -141,7 +141,7 @@ X-Gitlab-Event: System Hook
"user_name": "John Smith", "user_name": "John Smith",
"user_username": "johnsmith", "user_username": "johnsmith",
"user_id": 41, "user_id": 41,
"project_visibility": "private", "project_visibility": "private"
} }
``` ```
......
...@@ -100,6 +100,7 @@ cd /home/git/gitlab ...@@ -100,6 +100,7 @@ cd /home/git/gitlab
sudo -u git -H git fetch --all 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 -- db/schema.rb # local changes will be restored automatically
sudo -u git -H git checkout -- locale
``` ```
For GitLab Community Edition: For GitLab Community Edition:
...@@ -236,6 +237,11 @@ sudo -u git -H bundle clean ...@@ -236,6 +237,11 @@ sudo -u git -H bundle clean
# Run database migrations # Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production 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 # 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 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 ...@@ -100,6 +100,7 @@ cd /home/git/gitlab
sudo -u git -H git fetch --all 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 -- db/schema.rb # local changes will be restored automatically
sudo -u git -H git checkout -- locale
``` ```
For GitLab Community Edition: For GitLab Community Edition:
...@@ -272,6 +273,10 @@ sudo -u git -H bundle clean ...@@ -272,6 +273,10 @@ sudo -u git -H bundle clean
# Run database migrations # Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production 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 # 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 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 ...@@ -100,6 +100,7 @@ cd /home/git/gitlab
sudo -u git -H git fetch --all 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 -- db/schema.rb # local changes will be restored automatically
sudo -u git -H git checkout -- locale
``` ```
For GitLab Community Edition: For GitLab Community Edition:
...@@ -285,6 +286,10 @@ sudo -u git -H bundle clean ...@@ -285,6 +286,10 @@ sudo -u git -H bundle clean
# Run database migrations # Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production 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 # 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 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 ...@@ -295,6 +295,10 @@ sudo -u git -H bundle clean
# Run database migrations # Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production 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 # 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 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`). ...@@ -35,7 +35,7 @@ current version with `cat VERSION`).
cd /home/git/gitlab cd /home/git/gitlab
sudo -u git -H git fetch --all 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 sudo -u git -H git checkout LATEST_TAG -b LATEST_TAG
``` ```
...@@ -56,11 +56,21 @@ sudo -u git -H bundle clean ...@@ -56,11 +56,21 @@ sudo -u git -H bundle clean
# Run database migrations # Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production 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 # 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 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 ```bash
cd /home/git/gitlab cd /home/git/gitlab
...@@ -68,7 +78,7 @@ 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 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 ```bash
cd /home/git/gitlab-shell 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 ...@@ -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' sudo -u git -H sh -c 'if [ -x bin/compile ]; then bin/compile; fi'
``` ```
### 6. Start application ### 7. Start application
```bash ```bash
sudo service gitlab start sudo service gitlab start
sudo service nginx restart sudo service nginx restart
``` ```
### 7. Check application status ### 8. Check application status
Check if GitLab and its environment are configured correctly: Check if GitLab and its environment are configured correctly:
......
...@@ -132,7 +132,7 @@ module API ...@@ -132,7 +132,7 @@ module API
expose :lfs_enabled?, as: :lfs_enabled expose :lfs_enabled?, as: :lfs_enabled
expose :creator_id expose :creator_id
expose :namespace, using: 'API::Entities::Namespace' 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_status
expose :import_error, if: lambda { |_project, options| options[:user_can_admin_project] } expose :import_error, if: lambda { |_project, options| options[:user_can_admin_project] }
expose :avatar_url do |user, options| expose :avatar_url do |user, options|
......
# rubocop:disable GitlabSecurity/PublicSend
module API module API
module Helpers module Helpers
module MembersHelpers module MembersHelpers
def find_source(source_type, id) def find_source(source_type, id)
public_send("find_#{source_type}!", id) public_send("find_#{source_type}!", id) # rubocop:disable GitlabSecurity/PublicSend
end end
def authorize_admin_source!(source_type, source) def authorize_admin_source!(source_type, source)
......
...@@ -139,7 +139,7 @@ module API ...@@ -139,7 +139,7 @@ module API
helpers do helpers do
def find_project_noteable(noteables_str, noteable_id) 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 end
def noteable_read_ability_name(noteable) def noteable_read_ability_name(noteable)
......
...@@ -68,7 +68,7 @@ module API ...@@ -68,7 +68,7 @@ module API
expose :lfs_enabled?, as: :lfs_enabled expose :lfs_enabled?, as: :lfs_enabled
expose :creator_id expose :creator_id
expose :namespace, using: 'API::Entities::Namespace' 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| expose :avatar_url do |user, options|
user.avatar_url(only_path: false) user.avatar_url(only_path: false)
end end
......
...@@ -198,11 +198,11 @@ module Backup ...@@ -198,11 +198,11 @@ module Backup
end end
def archives_to_backup 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 end
def folders_to_backup def folders_to_backup
FOLDERS_TO_BACKUP.reject{ |name| skipped?(name) } FOLDERS_TO_BACKUP.reject { |name| skipped?(name) }
end end
def disabled_features def disabled_features
......
...@@ -254,7 +254,7 @@ module Ci ...@@ -254,7 +254,7 @@ module Ci
def state def state
state = STATE_PARAMS.inject({}) do |h, param| state = STATE_PARAMS.inject({}) do |h, param|
h[param] = send(param) h[param] = send(param) # rubocop:disable GitlabSecurity/PublicSend
h h
end end
Base64.urlsafe_encode64(state.to_json) Base64.urlsafe_encode64(state.to_json)
...@@ -266,7 +266,7 @@ module Ci ...@@ -266,7 +266,7 @@ module Ci
return if state[:offset].to_i > stream.size return if state[:offset].to_i > stream.size
STATE_PARAMS.each do |param| STATE_PARAMS.each do |param|
send("#{param}=".to_sym, state[param]) send("#{param}=".to_sym, state[param]) # rubocop:disable GitlabSecurity/PublicSend
end end
end end
......
...@@ -47,7 +47,7 @@ module Ci ...@@ -47,7 +47,7 @@ module Ci
def collect def collect
query = project.pipelines 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) totals_count = grouped_count(query)
success_count = grouped_count(query.success) success_count = grouped_count(query.success)
......
...@@ -6,6 +6,8 @@ class ProjectUrlConstrainer ...@@ -6,6 +6,8 @@ class ProjectUrlConstrainer
return false unless DynamicPathValidator.valid_project_path?(full_path) 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? Project.find_by_full_path(full_path, follow_redirects: request.get?).present?
end end
end end
...@@ -21,7 +21,7 @@ module Gitlab ...@@ -21,7 +21,7 @@ module Gitlab
def to_hash def to_hash
hash = {} hash = {}
serialize_keys.each { |key| hash[key] = send(key) } serialize_keys.each { |key| hash[key] = send(key) } # rubocop:disable GitlabSecurity/PublicSend
hash hash
end end
......
...@@ -98,10 +98,11 @@ module Gitlab ...@@ -98,10 +98,11 @@ module Gitlab
if status.zero? if status.zero?
@ee_branch_found = ee_branch_prefix @ee_branch_found = ee_branch_prefix
else return
_, status = step("Fetching origin/#{ee_branch_suffix}", %W[git fetch origin #{ee_branch_suffix}])
end end
_, status = step("Fetching origin/#{ee_branch_suffix}", %W[git fetch origin #{ee_branch_suffix}])
if status.zero? if status.zero?
@ee_branch_found = ee_branch_suffix @ee_branch_found = ee_branch_suffix
else else
......
...@@ -319,7 +319,7 @@ module Gitlab ...@@ -319,7 +319,7 @@ module Gitlab
def to_hash def to_hash
serialize_keys.map.with_object({}) do |key, hash| serialize_keys.map.with_object({}) do |key, hash|
hash[key] = send(key) hash[key] = send(key) # rubocop:disable GitlabSecurity/PublicSend
end end
end end
...@@ -412,7 +412,7 @@ module Gitlab ...@@ -412,7 +412,7 @@ module Gitlab
raw_commit = hash.symbolize_keys raw_commit = hash.symbolize_keys
serialize_keys.each do |key| serialize_keys.each do |key|
send("#{key}=", raw_commit[key]) send("#{key}=", raw_commit[key]) # rubocop:disable GitlabSecurity/PublicSend
end end
end end
......
...@@ -143,7 +143,7 @@ module Gitlab ...@@ -143,7 +143,7 @@ module Gitlab
hash = {} hash = {}
SERIALIZE_KEYS.each do |key| SERIALIZE_KEYS.each do |key|
hash[key] = send(key) hash[key] = send(key) # rubocop:disable GitlabSecurity/PublicSend
end end
hash hash
...@@ -221,7 +221,7 @@ module Gitlab ...@@ -221,7 +221,7 @@ module Gitlab
raw_diff = hash.symbolize_keys raw_diff = hash.symbolize_keys
SERIALIZE_KEYS.each do |key| 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
end end
......
...@@ -7,13 +7,13 @@ module Gitlab ...@@ -7,13 +7,13 @@ module Gitlab
def initialize(params) def initialize(params)
params.each do |key, val| params.each do |key, val|
public_send(:"#{key}=", val) public_send(:"#{key}=", val) # rubocop:disable GitlabSecurity/PublicSend
end end
end end
def ==(other) def ==(other)
FIELDS.all? do |field| 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 end
end end
......
...@@ -10,7 +10,7 @@ module Gitlab ...@@ -10,7 +10,7 @@ module Gitlab
def exists? def exists?
request = Gitaly::RepositoryExistsRequest.new(repository: @gitaly_repo) 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 end
def garbage_collect(create_bitmap) def garbage_collect(create_bitmap)
......
...@@ -71,7 +71,7 @@ module Gitlab ...@@ -71,7 +71,7 @@ module Gitlab
end end
def config def config
Gitlab.config.omniauth.providers.find{|provider| provider.name == "gitlab"} Gitlab.config.omniauth.providers.find {|provider| provider.name == "gitlab"}
end end
def gitlab_options def gitlab_options
......
...@@ -45,7 +45,7 @@ module Gitlab ...@@ -45,7 +45,7 @@ module Gitlab
end end
def all 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 @references.values.flatten
end end
......
...@@ -18,7 +18,7 @@ module StaticModel ...@@ -18,7 +18,7 @@ module StaticModel
# #
# Pass it along if we respond to it. # Pass it along if we respond to it.
def [](key) def [](key)
send(key) if respond_to?(key) send(key) if respond_to?(key) # rubocop:disable GitlabSecurity/PublicSend
end end
def to_param def to_param
......
...@@ -18,6 +18,9 @@ server { ...@@ -18,6 +18,9 @@ server {
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache off;
# The same address as passed to GitLab Pages: `-listen-proxy` # The same address as passed to GitLab Pages: `-listen-proxy`
proxy_pass http://localhost:8090/; proxy_pass http://localhost:8090/;
} }
......
...@@ -67,6 +67,9 @@ server { ...@@ -67,6 +67,9 @@ server {
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache off;
# The same address as passed to GitLab Pages: `-listen-proxy` # The same address as passed to GitLab Pages: `-listen-proxy`
proxy_pass http://localhost:8090/; proxy_pass http://localhost:8090/;
} }
......
...@@ -41,8 +41,6 @@ namespace :gitlab do ...@@ -41,8 +41,6 @@ namespace :gitlab do
end end
namespace :gitlab_shell do namespace :gitlab_shell do
include SystemCheck::Helpers
desc "GitLab | Check the configuration of GitLab Shell" desc "GitLab | Check the configuration of GitLab Shell"
task check: :environment do task check: :environment do
warn_user_is_not_gitlab warn_user_is_not_gitlab
...@@ -249,8 +247,6 @@ namespace :gitlab do ...@@ -249,8 +247,6 @@ namespace :gitlab do
end end
namespace :sidekiq do namespace :sidekiq do
include SystemCheck::Helpers
desc "GitLab | Check the configuration of Sidekiq" desc "GitLab | Check the configuration of Sidekiq"
task check: :environment do task check: :environment do
warn_user_is_not_gitlab warn_user_is_not_gitlab
...@@ -309,8 +305,6 @@ namespace :gitlab do ...@@ -309,8 +305,6 @@ namespace :gitlab do
end end
namespace :incoming_email do namespace :incoming_email do
include SystemCheck::Helpers
desc "GitLab | Check the configuration of Reply by email" desc "GitLab | Check the configuration of Reply by email"
task check: :environment do task check: :environment do
warn_user_is_not_gitlab warn_user_is_not_gitlab
...@@ -444,8 +438,6 @@ namespace :gitlab do ...@@ -444,8 +438,6 @@ namespace :gitlab do
end end
namespace :ldap do namespace :ldap do
include SystemCheck::Helpers
task :check, [:limit] => :environment do |_, args| task :check, [:limit] => :environment do |_, args|
# Only show up to 100 results because LDAP directories can be very big. # Only show up to 100 results because LDAP directories can be very big.
# This setting only affects the `rake gitlab:check` script. # This setting only affects the `rake gitlab:check` script.
...@@ -501,8 +493,6 @@ namespace :gitlab do ...@@ -501,8 +493,6 @@ namespace :gitlab do
end end
namespace :repo do namespace :repo do
include SystemCheck::Helpers
desc "GitLab | Check the integrity of the repositories managed by GitLab" desc "GitLab | Check the integrity of the repositories managed by GitLab"
task check: :environment do task check: :environment do
Gitlab.config.repositories.storages.each do |name, repository_storage| Gitlab.config.repositories.storages.each do |name, repository_storage|
...@@ -517,8 +507,6 @@ namespace :gitlab do ...@@ -517,8 +507,6 @@ namespace :gitlab do
end end
namespace :user do namespace :user do
include SystemCheck::Helpers
desc "GitLab | Check the integrity of a specific user's repositories" desc "GitLab | Check the integrity of a specific user's repositories"
task :check_repos, [:username] => :environment do |t, args| task :check_repos, [:username] => :environment do |t, args|
username = args[:username] || prompt("Check repository integrity for fsername? ".color(:blue)) username = args[:username] || prompt("Check repository integrity for fsername? ".color(:blue))
......
...@@ -21,7 +21,7 @@ namespace :gitlab do ...@@ -21,7 +21,7 @@ namespace :gitlab do
create_gitaly_configuration create_gitaly_configuration
# In CI we run scripts/gitaly-test-build instead of this command # In CI we run scripts/gitaly-test-build instead of this command
unless ENV['CI'].present? 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 end
end end
......
...@@ -4,5 +4,5 @@ require 'tasks/gitlab/task_helpers' ...@@ -4,5 +4,5 @@ require 'tasks/gitlab/task_helpers'
StateMachines::Machine.ignore_method_conflicts = true if ENV['CRON'] StateMachines::Machine.ignore_method_conflicts = true if ENV['CRON']
namespace :gitlab do namespace :gitlab do
include Gitlab::TaskHelpers extend SystemCheck::Helpers
end end
...@@ -5,6 +5,8 @@ module Gitlab ...@@ -5,6 +5,8 @@ module Gitlab
TaskAbortedByUserError = Class.new(StandardError) TaskAbortedByUserError = Class.new(StandardError)
module TaskHelpers module TaskHelpers
extend self
# Ask if the user wants to continue # Ask if the user wants to continue
# #
# Returns "yes" the user chose 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 # Huang Tao <htve@outlook.com>, 2017. #zanata
msgid "" msgid ""
msgstr "" msgstr ""
...@@ -8,12 +11,12 @@ msgstr "" ...@@ -8,12 +11,12 @@ msgstr ""
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\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" "Last-Translator: chang-ho,cha <changho.cha@gmail.com>\n"
"Language-Team: Korean (https://translate.zanata.org/project/view/GitLab)\n" "Language-Team: Korean (https://translate.zanata.org/project/view/GitLab)\n"
"Language: ko\n" "Language: ko\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Zanata 3.9.6\n" "X-Generator: Zanata 3.9.6\n"
"Plural-Forms: nplurals=1; plural=0\n"
msgid "%d commit" msgid "%d commit"
msgid_plural "%d commits" msgid_plural "%d commits"
...@@ -25,7 +28,7 @@ msgid_plural "" ...@@ -25,7 +28,7 @@ msgid_plural ""
msgstr[0] "%s 추가 커밋은 성능 이슈를 방지하기 위해 생략되었습니다." msgstr[0] "%s 추가 커밋은 성능 이슈를 방지하기 위해 생략되었습니다."
msgid "%{commit_author_link} committed %{commit_timeago}" msgid "%{commit_author_link} committed %{commit_timeago}"
msgstr "%{commit_timeago} 에 %{commit_author_link} 이(가) 커밋하였습니다. " msgstr "%{commit_timeago} 에 %{commit_author_link} 님이 커밋하였습니다. "
msgid "1 pipeline" msgid "1 pipeline"
msgid_plural "%d pipelines" msgid_plural "%d pipelines"
...@@ -791,7 +794,7 @@ msgid "Select target branch" ...@@ -791,7 +794,7 @@ msgid "Select target branch"
msgstr "대상 브랜치 선택" msgstr "대상 브랜치 선택"
msgid "Set a password on your account to pull or push via %{protocol}." 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" msgid "Set up CI"
msgstr "CI 설정" msgstr "CI 설정"
...@@ -1122,7 +1125,7 @@ msgid "" ...@@ -1122,7 +1125,7 @@ msgid ""
"You are going to remove %{group_name}.\n" "You are going to remove %{group_name}.\n"
"Removed groups CANNOT be restored!\n" "Removed groups CANNOT be restored!\n"
"Are you ABSOLUTELY sure?" "Are you ABSOLUTELY sure?"
msgstr "%{group_name}을(를) 제거하려고합니다.\n" msgstr "%{group_name} 그룹을 제거하려고합니다.\n"
"\"정말로\" 확실합니까?" "\"정말로\" 확실합니까?"
msgid "" msgid ""
...@@ -1130,7 +1133,7 @@ msgid "" ...@@ -1130,7 +1133,7 @@ msgid ""
"Removed project CANNOT be restored!\n" "Removed project CANNOT be restored!\n"
"Are you ABSOLUTELY sure?" "Are you ABSOLUTELY sure?"
msgstr "" msgstr ""
"%{project_name_with_namespace}을(를) 삭제하려고합니다.\n" "%{project_name_with_namespace} 프로젝트를 삭제하려고합니다.\n"
"삭제된 프로젝트를 복원 할 수 없습니다!\n" "삭제된 프로젝트를 복원 할 수 없습니다!\n"
"\"정말로\" 확실합니까?" "\"정말로\" 확실합니까?"
...@@ -1185,7 +1188,7 @@ msgid "" ...@@ -1185,7 +1188,7 @@ msgid ""
"You won't be able to pull or push project code via SSH until you " "You won't be able to pull or push project code via SSH until you "
"%{add_ssh_key_link} to your profile" "%{add_ssh_key_link} to your profile"
msgstr "" msgstr ""
"당신의 프로필에 %{add_ssh_key_link} 을(를) 하기 전에는 SSH를 통해 프로젝트 코드를 Pull 하거나 Push 할 수 " "당신의 프로필에 %{add_ssh_key_link} 하기 전에는 SSH를 통해 프로젝트 코드를 Pull 하거나 Push 할 수 "
"없습니다" "없습니다"
msgid "Your name" msgid "Your name"
......
...@@ -127,7 +127,7 @@ describe Admin::UsersController do ...@@ -127,7 +127,7 @@ describe Admin::UsersController do
describe 'POST create' do describe 'POST create' do
it 'creates the user' 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 end
it 'shows only one error message for an invalid email' do it 'shows only one error message for an invalid email' do
......
...@@ -24,7 +24,7 @@ describe InvitesController do ...@@ -24,7 +24,7 @@ describe InvitesController do
describe 'GET #decline' do describe 'GET #decline' do
it 'declines user' do it 'declines user' do
get :decline, id: token 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(response).to have_http_status(302)
expect(flash[:notice]).to include 'You have declined the invitation to join' expect(flash[:notice]).to include 'You have declined the invitation to join'
......
...@@ -292,13 +292,13 @@ describe Projects::IssuesController do ...@@ -292,13 +292,13 @@ describe Projects::IssuesController do
it 'rejects an issue recognized as a spam' do it 'rejects an issue recognized as a spam' do
expect(Gitlab::Recaptcha).to receive(:load_configurations!).and_return(true) 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 end
it 'rejects an issue recognized as a spam when recaptcha disabled' do it 'rejects an issue recognized as a spam when recaptcha disabled' do
stub_application_setting(recaptcha_enabled: false) 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 end
it 'creates a spam log' do it 'creates a spam log' do
...@@ -358,7 +358,7 @@ describe Projects::IssuesController do ...@@ -358,7 +358,7 @@ describe Projects::IssuesController do
end end
it 'accepts an issue after recaptcha is verified' do 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 end
it 'marks spam log as recaptcha_verified' do it 'marks spam log as recaptcha_verified' do
......
...@@ -67,7 +67,7 @@ describe Projects::TodosController do ...@@ -67,7 +67,7 @@ describe Projects::TodosController do
end end
it "doesn't create todo" do 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) expect(response).to have_http_status(404)
end end
end end
...@@ -135,7 +135,7 @@ describe Projects::TodosController do ...@@ -135,7 +135,7 @@ describe Projects::TodosController do
end end
it "doesn't create todo" do 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) expect(response).to have_http_status(404)
end end
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