summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/ci/frontend.gitlab-ci.yml37
-rw-r--r--.gitlab/ci/rails.gitlab-ci.yml1
-rw-r--r--.haml-lint.yml4
-rw-r--r--.rubocop.yml4
-rw-r--r--app/assets/javascripts/boards/components/board_blank_state.vue11
-rw-r--r--app/assets/javascripts/boards/ee_functions.js7
-rw-r--r--app/assets/javascripts/boards/index.js17
-rw-r--r--app/assets/javascripts/commons/polyfills.js1
-rw-r--r--app/assets/javascripts/ide/stores/mutations/file.js12
-rw-r--r--app/assets/javascripts/ide/stores/utils.js2
-rw-r--r--app/controllers/chaos_controller.rb54
-rw-r--r--app/controllers/ide_controller.rb1
-rw-r--r--app/controllers/projects/merge_requests/creations_controller.rb8
-rw-r--r--app/models/concerns/issuable.rb7
-rw-r--r--app/models/dashboard_group_milestone.rb3
-rw-r--r--app/models/environment.rb47
-rw-r--r--app/services/issuable/clone/attributes_rewriter.rb2
-rw-r--r--app/views/admin/users/index.html.haml2
-rw-r--r--app/views/devise/sessions/_new_ldap.html.haml4
-rw-r--r--app/views/projects/merge_requests/creations/_new_compare.html.haml2
-rw-r--r--app/views/projects/merge_requests/creations/_new_submit.html.haml3
-rw-r--r--app/workers/all_queues.yml6
-rw-r--r--app/workers/chaos/cpu_spin_worker.rb12
-rw-r--r--app/workers/chaos/db_spin_worker.rb12
-rw-r--r--app/workers/chaos/kill_worker.rb12
-rw-r--r--app/workers/chaos/leak_mem_worker.rb12
-rw-r--r--app/workers/chaos/sleep_worker.rb12
-rw-r--r--app/workers/concerns/chaos_queue.rb9
-rw-r--r--changelogs/unreleased/64295-predictable-environment-slugs.yml5
-rw-r--r--changelogs/unreleased/an-sidekiq-chaos.yml5
-rw-r--r--changelogs/unreleased/bjk-64064_cache_metrics.yml5
-rw-r--r--changelogs/unreleased/fe-delete-old-boardservice.yml6
-rw-r--r--changelogs/unreleased/fj-count-web-ide-merge-requests.yml5
-rw-r--r--changelogs/unreleased/georgekoltsov-64311-set-visibility-private-if-internal-restricted.yml5
-rw-r--r--changelogs/unreleased/group-milestones-dashboard-blunceford.yml5
-rw-r--r--config/karma.config.js10
-rw-r--r--config/routes.rb2
-rw-r--r--config/sidekiq_queues.yml1
-rw-r--r--doc/administration/auth/ldap-ee.md2
-rw-r--r--doc/administration/gitaly/index.md670
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_metrics.md3
-rw-r--r--doc/administration/repository_storage_types.md4
-rw-r--r--doc/api/container_registry.md4
-rw-r--r--doc/api/lint.md2
-rw-r--r--doc/api/users.md3
-rw-r--r--doc/ci/examples/end_to_end_testing_webdriverio/index.md2
-rw-r--r--doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md9
-rw-r--r--doc/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/img/merge_train_position_v12_0.pngbin0 -> 18121 bytes
-rw-r--r--doc/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md39
-rw-r--r--doc/development/README.md1
-rw-r--r--doc/development/chaos_endpoints.md31
-rw-r--r--doc/development/code_review.md3
-rw-r--r--doc/development/documentation/improvement-workflow.md6
-rw-r--r--doc/development/documentation/styleguide.md10
-rw-r--r--doc/development/fe_guide/frontend_faq.md6
-rw-r--r--doc/development/fe_guide/style_guide_js.md4
-rw-r--r--doc/development/fe_guide/style_guide_scss.md2
-rw-r--r--doc/development/import_export.md4
-rw-r--r--doc/development/interacting_components.md29
-rw-r--r--doc/development/licensed_feature_availability.md6
-rw-r--r--doc/development/performance.md8
-rw-r--r--doc/development/policies.md4
-rw-r--r--doc/development/testing_guide/end_to_end/page_objects.md2
-rw-r--r--doc/development/testing_guide/end_to_end/quick_start_guide.md24
-rw-r--r--doc/development/testing_guide/frontend_testing.md23
-rw-r--r--doc/integration/elasticsearch.md6
-rw-r--r--doc/integration/jenkins_deprecated.md2
-rw-r--r--doc/integration/jira_development_panel.md6
-rw-r--r--doc/subscriptions/index.md8
-rw-r--r--doc/topics/autodevops/index.md4
-rw-r--r--doc/user/application_security/dast/index.md22
-rw-r--r--doc/user/application_security/index.md6
-rw-r--r--doc/user/application_security/security_dashboard/index.md4
-rw-r--r--doc/user/group/bulk_editing/img/bulk-editing.pngbin0 -> 100007 bytes
-rw-r--r--doc/user/group/bulk_editing/index.md22
-rw-r--r--doc/user/group/index.md4
-rw-r--r--doc/user/markdown.md14
-rw-r--r--doc/user/project/bulk_editing.md23
-rw-r--r--doc/user/project/integrations/img/prometheus_dashboard_area_panel_type.pngbin0 -> 65101 bytes
-rw-r--r--doc/user/project/integrations/img/prometheus_dashboard_single_stat_panel_type.pngbin0 -> 26781 bytes
-rw-r--r--doc/user/project/integrations/prometheus.md61
-rw-r--r--doc/user/project/issue_board.md4
-rw-r--r--doc/user/project/issues/index.md5
-rw-r--r--doc/user/project/issues/managing_issues.md4
-rw-r--r--doc/user/project/issues/sorting_issue_lists.md30
-rw-r--r--doc/user/project/merge_requests/index.md11
-rw-r--r--doc/user/project/quick_actions.md6
-rw-r--r--doc/user/project/settings/import_export.md5
-rw-r--r--lib/gitlab/chaos.rb49
-rw-r--r--lib/gitlab/import_export/project_tree_restorer.rb1
-rw-r--r--lib/gitlab/metrics/subscribers/rails_cache.rb15
-rw-r--r--lib/gitlab/slug/environment.rb58
-rw-r--r--lib/gitlab/usage_data.rb4
-rw-r--r--lib/gitlab/usage_data_counters/web_ide_counter.rb18
-rw-r--r--lib/tasks/frontend.rake21
-rw-r--r--lib/tasks/karma.rake11
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb8
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb6
-rw-r--r--qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb4
-rw-r--r--qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb3
-rw-r--r--spec/controllers/chaos_controller_spec.rb127
-rw-r--r--spec/controllers/dashboard/milestones_controller_spec.rb15
-rw-r--r--spec/controllers/ide_controller_spec.rb17
-rw-r--r--spec/controllers/projects/merge_requests/creations_controller_spec.rb42
-rw-r--r--spec/frontend/environment.js8
-rw-r--r--spec/frontend/fixtures/abuse_reports.rb (renamed from spec/javascripts/fixtures/abuse_reports.rb)2
-rw-r--r--spec/frontend/fixtures/admin_users.rb (renamed from spec/javascripts/fixtures/admin_users.rb)2
-rw-r--r--spec/frontend/fixtures/application_settings.rb (renamed from spec/javascripts/fixtures/application_settings.rb)2
-rw-r--r--spec/frontend/fixtures/autocomplete_sources.rb (renamed from spec/javascripts/fixtures/autocomplete_sources.rb)2
-rw-r--r--spec/frontend/fixtures/blob.rb (renamed from spec/javascripts/fixtures/blob.rb)2
-rw-r--r--spec/frontend/fixtures/boards.rb (renamed from spec/javascripts/fixtures/boards.rb)2
-rw-r--r--spec/frontend/fixtures/branches.rb (renamed from spec/javascripts/fixtures/branches.rb)2
-rw-r--r--spec/frontend/fixtures/clusters.rb (renamed from spec/javascripts/fixtures/clusters.rb)2
-rw-r--r--spec/frontend/fixtures/commit.rb (renamed from spec/javascripts/fixtures/commit.rb)2
-rw-r--r--spec/frontend/fixtures/deploy_keys.rb (renamed from spec/javascripts/fixtures/deploy_keys.rb)2
-rw-r--r--spec/frontend/fixtures/groups.rb (renamed from spec/javascripts/fixtures/groups.rb)4
-rw-r--r--spec/frontend/fixtures/issues.rb (renamed from spec/javascripts/fixtures/issues.rb)6
-rw-r--r--spec/frontend/fixtures/jobs.rb (renamed from spec/javascripts/fixtures/jobs.rb)4
-rw-r--r--spec/frontend/fixtures/labels.rb (renamed from spec/javascripts/fixtures/labels.rb)4
-rw-r--r--spec/frontend/fixtures/merge_requests.rb (renamed from spec/javascripts/fixtures/merge_requests.rb)2
-rw-r--r--spec/frontend/fixtures/merge_requests_diffs.rb (renamed from spec/javascripts/fixtures/merge_requests_diffs.rb)3
-rw-r--r--spec/frontend/fixtures/pipeline_schedules.rb (renamed from spec/javascripts/fixtures/pipeline_schedules.rb)4
-rw-r--r--spec/frontend/fixtures/pipelines.rb (renamed from spec/javascripts/fixtures/pipelines.rb)2
-rw-r--r--spec/frontend/fixtures/projects.rb (renamed from spec/javascripts/fixtures/projects.rb)12
-rw-r--r--spec/frontend/fixtures/prometheus_service.rb (renamed from spec/javascripts/fixtures/prometheus_service.rb)2
-rw-r--r--spec/frontend/fixtures/raw.rb (renamed from spec/javascripts/fixtures/raw.rb)0
-rw-r--r--spec/frontend/fixtures/search.rb (renamed from spec/javascripts/fixtures/search.rb)2
-rw-r--r--spec/frontend/fixtures/services.rb (renamed from spec/javascripts/fixtures/services.rb)2
-rw-r--r--spec/frontend/fixtures/sessions.rb (renamed from spec/javascripts/fixtures/sessions.rb)2
-rw-r--r--spec/frontend/fixtures/snippet.rb (renamed from spec/javascripts/fixtures/snippet.rb)2
-rw-r--r--spec/frontend/fixtures/static/README.md3
-rw-r--r--spec/frontend/fixtures/static/ajax_loading_spinner.html (renamed from spec/javascripts/fixtures/static/ajax_loading_spinner.html)0
-rw-r--r--spec/frontend/fixtures/static/balsamiq_viewer.html (renamed from spec/javascripts/fixtures/static/balsamiq_viewer.html)0
-rw-r--r--spec/frontend/fixtures/static/create_item_dropdown.html (renamed from spec/javascripts/fixtures/static/create_item_dropdown.html)0
-rw-r--r--spec/frontend/fixtures/static/environments/table.html (renamed from spec/javascripts/fixtures/static/environments/table.html)0
-rw-r--r--spec/frontend/fixtures/static/environments_logs.html29
-rw-r--r--spec/frontend/fixtures/static/event_filter.html (renamed from spec/javascripts/fixtures/static/event_filter.html)0
-rw-r--r--spec/frontend/fixtures/static/gl_dropdown.html (renamed from spec/javascripts/fixtures/static/gl_dropdown.html)0
-rw-r--r--spec/frontend/fixtures/static/gl_field_errors.html (renamed from spec/javascripts/fixtures/static/gl_field_errors.html)0
-rw-r--r--spec/frontend/fixtures/static/images/green_box.png (renamed from spec/javascripts/fixtures/static/images/green_box.png)bin1306 -> 1306 bytes
-rw-r--r--spec/frontend/fixtures/static/images/one_white_pixel.png (renamed from spec/javascripts/fixtures/static/images/one_white_pixel.png)bin68 -> 68 bytes
-rw-r--r--spec/frontend/fixtures/static/images/red_box.png (renamed from spec/javascripts/fixtures/static/images/red_box.png)bin1305 -> 1305 bytes
-rw-r--r--spec/frontend/fixtures/static/issuable_filter.html (renamed from spec/javascripts/fixtures/static/issuable_filter.html)0
-rw-r--r--spec/frontend/fixtures/static/issue_sidebar_label.html (renamed from spec/javascripts/fixtures/static/issue_sidebar_label.html)0
-rw-r--r--spec/frontend/fixtures/static/line_highlighter.html (renamed from spec/javascripts/fixtures/static/line_highlighter.html)0
-rw-r--r--spec/frontend/fixtures/static/linked_tabs.html (renamed from spec/javascripts/fixtures/static/linked_tabs.html)0
-rw-r--r--spec/frontend/fixtures/static/merge_requests_show.html (renamed from spec/javascripts/fixtures/static/merge_requests_show.html)0
-rw-r--r--spec/frontend/fixtures/static/mini_dropdown_graph.html (renamed from spec/javascripts/fixtures/static/mini_dropdown_graph.html)0
-rw-r--r--spec/frontend/fixtures/static/notebook_viewer.html (renamed from spec/javascripts/fixtures/static/notebook_viewer.html)0
-rw-r--r--spec/frontend/fixtures/static/oauth_remember_me.html (renamed from spec/javascripts/fixtures/static/oauth_remember_me.html)0
-rw-r--r--spec/frontend/fixtures/static/pdf_viewer.html (renamed from spec/javascripts/fixtures/static/pdf_viewer.html)0
-rw-r--r--spec/frontend/fixtures/static/pipeline_graph.html (renamed from spec/javascripts/fixtures/static/pipeline_graph.html)0
-rw-r--r--spec/frontend/fixtures/static/pipelines.html (renamed from spec/javascripts/fixtures/static/pipelines.html)0
-rw-r--r--spec/frontend/fixtures/static/project_select_combo_button.html (renamed from spec/javascripts/fixtures/static/project_select_combo_button.html)0
-rw-r--r--spec/frontend/fixtures/static/projects.json (renamed from spec/javascripts/fixtures/static/projects.json)0
-rw-r--r--spec/frontend/fixtures/static/search_autocomplete.html (renamed from spec/javascripts/fixtures/static/search_autocomplete.html)0
-rw-r--r--spec/frontend/fixtures/static/signin_tabs.html (renamed from spec/javascripts/fixtures/static/signin_tabs.html)0
-rw-r--r--spec/frontend/fixtures/static/sketch_viewer.html (renamed from spec/javascripts/fixtures/static/sketch_viewer.html)0
-rw-r--r--spec/frontend/fixtures/todos.rb (renamed from spec/javascripts/fixtures/todos.rb)4
-rw-r--r--spec/frontend/fixtures/u2f.rb (renamed from spec/javascripts/fixtures/u2f.rb)4
-rw-r--r--spec/frontend/helpers/fixtures.js7
-rw-r--r--spec/javascripts/boards/board_blank_state_spec.js19
-rw-r--r--spec/javascripts/fixtures/.gitignore7
-rw-r--r--spec/javascripts/fixtures/static/README.md3
-rw-r--r--spec/javascripts/ide/stores/modules/commit/actions_spec.js2
-rw-r--r--spec/javascripts/ide/stores/mutations/file_spec.js37
-rw-r--r--spec/javascripts/test_constants.js4
-rw-r--r--spec/lib/gitlab/import_export/project_tree_restorer_spec.rb20
-rw-r--r--spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb10
-rw-r--r--spec/lib/gitlab/slug/environment_spec.rb38
-rw-r--r--spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb35
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb10
-rw-r--r--spec/models/concerns/issuable_spec.rb21
-rw-r--r--spec/models/environment_spec.rb26
-rw-r--r--spec/support/helpers/javascript_fixtures_helpers.rb2
-rw-r--r--spec/support/helpers/test_env.rb3
177 files changed, 1583 insertions, 684 deletions
diff --git a/.gitlab/ci/frontend.gitlab-ci.yml b/.gitlab/ci/frontend.gitlab-ci.yml
index 45a6a177943..b00d2f46088 100644
--- a/.gitlab/ci/frontend.gitlab-ci.yml
+++ b/.gitlab/ci/frontend.gitlab-ci.yml
@@ -113,37 +113,6 @@ compile-assets pull-cache:
- master@gitlab-org/gitlab-ee
- /(^docs[\/-].*|.*-docs$)/
-gitlab:ui:visual:
- extends: .dedicated-runner
- before_script: []
- allow_failure: true
- dependencies:
- - compile-assets
- - compile-assets pull-cache
- script:
- # Remove node modules from GitLab that may conflict with gitlab-ui
- - rm -r node_modules
- - git clone https://gitlab.com/gitlab-org/gitlab-ui.git
- - cp public/assets/application-*.css gitlab-ui/styles/application.css
- - cd gitlab-ui
- - yarn install
- - CSS_URL=./application.css yarn test
- only:
- changes:
- - app/assets/stylesheets/*.scss
- - app/assets/stylesheets/**/*.scss
- - app/assets/stylesheets/**/**/*.scss
- except:
- refs:
- - /(^docs[\/-].*|.*-docs$)/
- - master
- variables:
- - $CI_COMMIT_MESSAGE =~ /\[skip visual\]/i
- artifacts:
- paths:
- - gitlab-ui/tests/__image_snapshots__/
- when: always
-
karma:
extends: .dedicated-no-docs-pull-cache-job
<<: *use-pg
@@ -168,6 +137,8 @@ karma:
paths:
- chrome_debug.log
- coverage-javascript/
+ - tmp/tests/frontend/
+# see https://gitlab.com/gitlab-org/gitlab-ce/issues/64756
# reports:
# junit: junit_karma.xml
@@ -181,7 +152,7 @@ jest:
script:
- scripts/gitaly-test-spawn
- date
- - bundle exec rake karma:fixtures
+ - bundle exec rake frontend:fixtures
- date
- yarn jest --ci --coverage
artifacts:
@@ -191,6 +162,8 @@ jest:
paths:
- coverage-frontend/
- junit_jest.xml
+ - tmp/tests/frontend/
+# see https://gitlab.com/gitlab-org/gitlab-ce/issues/64756
# reports:
# junit: junit_jest.xml
cache:
diff --git a/.gitlab/ci/rails.gitlab-ci.yml b/.gitlab/ci/rails.gitlab-ci.yml
index c7a51beeee5..d0b1f1ab98f 100644
--- a/.gitlab/ci/rails.gitlab-ci.yml
+++ b/.gitlab/ci/rails.gitlab-ci.yml
@@ -80,6 +80,7 @@
- rspec_profiling/
- tmp/capybara/
- tmp/memory_test/
+# see https://gitlab.com/gitlab-org/gitlab-ce/issues/64756
# reports:
# junit: junit_rspec.xml
diff --git a/.haml-lint.yml b/.haml-lint.yml
index 0412b24a48c..399fa9656a0 100644
--- a/.haml-lint.yml
+++ b/.haml-lint.yml
@@ -118,7 +118,6 @@ linters:
- Lint/ParenthesesAsGroupedExpression
- Lint/RedundantWithIndex
- Lint/SafeNavigationConsistency
- - Lint/Syntax
- Metrics/BlockNesting
- Naming/VariableName
- Performance/RedundantMatch
@@ -155,6 +154,9 @@ linters:
enabled: true
style: space
+ Syntax:
+ enabled: true
+
Indentation:
enabled: true
character: space # or tab
diff --git a/.rubocop.yml b/.rubocop.yml
index e5fe527e611..79e06439ac2 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -60,8 +60,8 @@ Style/FrozenStringLiteralComment:
RSpec/FilePath:
Exclude:
- 'qa/**/*'
- - 'spec/javascripts/fixtures/*'
- - 'ee/spec/javascripts/fixtures/*'
+ - 'spec/frontend/fixtures/*'
+ - 'ee/spec/frontend/fixtures/*'
- 'spec/requests/api/v3/*'
Naming/FileName:
diff --git a/app/assets/javascripts/boards/components/board_blank_state.vue b/app/assets/javascripts/boards/components/board_blank_state.vue
index d8b0b60c183..9f26337d153 100644
--- a/app/assets/javascripts/boards/components/board_blank_state.vue
+++ b/app/assets/javascripts/boards/components/board_blank_state.vue
@@ -1,6 +1,6 @@
<script>
import { __ } from '~/locale';
-/* global ListLabel */
+import ListLabel from '~/boards/models/label';
import Cookies from 'js-cookie';
import boardsStore from '../stores/boards_store';
@@ -30,13 +30,17 @@ export default {
});
// Save the labels
- gl.boardService
+ boardsStore
.generateDefaultLists()
.then(res => res.data)
.then(data => {
data.forEach(listObj => {
const list = boardsStore.findList('title', listObj.title);
+ if (!list) {
+ return;
+ }
+
list.id = listObj.id;
list.label.id = listObj.label.id;
list.getIssues().catch(() => {
@@ -69,8 +73,7 @@ export default {
<span
:style="{ backgroundColor: label.color }"
class="label-color position-relative d-inline-block rounded"
- >
- </span>
+ ></span>
{{ label.title }}
</li>
</ul>
diff --git a/app/assets/javascripts/boards/ee_functions.js b/app/assets/javascripts/boards/ee_functions.js
new file mode 100644
index 00000000000..583270fcae5
--- /dev/null
+++ b/app/assets/javascripts/boards/ee_functions.js
@@ -0,0 +1,7 @@
+export const setPromotionState = () => {};
+
+export const setWeigthFetchingState = () => {};
+export const setEpicFetchingState = () => {};
+
+export const getMilestoneTitle = () => ({});
+export const getBoardsModalData = () => ({});
diff --git a/app/assets/javascripts/boards/index.js b/app/assets/javascripts/boards/index.js
index f5a617a85ad..3bded4a3258 100644
--- a/app/assets/javascripts/boards/index.js
+++ b/app/assets/javascripts/boards/index.js
@@ -30,6 +30,13 @@ import {
} from '~/lib/utils/common_utils';
import boardConfigToggle from 'ee_else_ce/boards/config_toggle';
import toggleFocusMode from 'ee_else_ce/boards/toggle_focus';
+import {
+ setPromotionState,
+ setWeigthFetchingState,
+ setEpicFetchingState,
+ getMilestoneTitle,
+ getBoardsModalData,
+} from 'ee_else_ce/boards/ee_functions';
import mountMultipleBoardsSwitcher from './mount_multiple_boards_switcher';
let issueBoardsApp;
@@ -129,6 +136,7 @@ export default () => {
});
boardsStore.addBlankState();
+ setPromotionState(boardsStore);
this.loading = false;
})
.catch(() => {
@@ -143,6 +151,8 @@ export default () => {
const { sidebarInfoEndpoint } = newIssue;
if (sidebarInfoEndpoint && newIssue.subscribed === undefined) {
newIssue.setFetchingState('subscriptions', true);
+ setWeigthFetchingState(newIssue, true);
+ setEpicFetchingState(newIssue, true);
BoardService.getIssueInfo(sidebarInfoEndpoint)
.then(res => res.data)
.then(data => {
@@ -157,6 +167,8 @@ export default () => {
} = convertObjectPropsToCamelCase(data);
newIssue.setFetchingState('subscriptions', false);
+ setWeigthFetchingState(newIssue, false);
+ setEpicFetchingState(newIssue, false);
newIssue.updateData({
humanTimeSpent: humanTotalTimeSpent,
timeSpent: totalTimeSpent,
@@ -169,6 +181,7 @@ export default () => {
})
.catch(() => {
newIssue.setFetchingState('subscriptions', false);
+ setWeigthFetchingState(newIssue, false);
Flash(__('An error occurred while fetching sidebar data'));
});
}
@@ -203,6 +216,7 @@ export default () => {
el: document.getElementById('js-add-list'),
data: {
filters: boardsStore.state.filters,
+ ...getMilestoneTitle($boardApp),
},
mounted() {
initNewListDropdown();
@@ -222,6 +236,7 @@ export default () => {
return {
modal: ModalStore.store,
store: boardsStore.state,
+ ...getBoardsModalData($boardApp),
canAdminList: this.$options.el.hasAttribute('data-can-admin-list'),
};
},
@@ -285,6 +300,6 @@ export default () => {
});
}
- toggleFocusMode(ModalStore, boardsStore);
+ toggleFocusMode(ModalStore, boardsStore, $boardApp);
mountMultipleBoardsSwitcher();
};
diff --git a/app/assets/javascripts/commons/polyfills.js b/app/assets/javascripts/commons/polyfills.js
index a4394ab7e92..7a6ad3dc771 100644
--- a/app/assets/javascripts/commons/polyfills.js
+++ b/app/assets/javascripts/commons/polyfills.js
@@ -13,6 +13,7 @@ import 'core-js/es/string/code-point-at';
import 'core-js/es/string/from-code-point';
import 'core-js/es/string/includes';
import 'core-js/es/string/starts-with';
+import 'core-js/es/string/ends-with';
import 'core-js/es/symbol';
import 'core-js/es/map';
import 'core-js/es/weak-map';
diff --git a/app/assets/javascripts/ide/stores/mutations/file.js b/app/assets/javascripts/ide/stores/mutations/file.js
index a52f1e235ed..1442ea7dbfa 100644
--- a/app/assets/javascripts/ide/stores/mutations/file.js
+++ b/app/assets/javascripts/ide/stores/mutations/file.js
@@ -43,10 +43,14 @@ export default {
[stateEntry, stagedFile, openFile, changedFile].forEach(f => {
if (f) {
- Object.assign(f, convertObjectPropsToCamelCase(data, { dropKeys: ['raw', 'baseRaw'] }), {
- raw: (stateEntry && stateEntry.raw) || null,
- baseRaw: null,
- });
+ Object.assign(
+ f,
+ convertObjectPropsToCamelCase(data, { dropKeys: ['path', 'name', 'raw', 'baseRaw'] }),
+ {
+ raw: (stateEntry && stateEntry.raw) || null,
+ baseRaw: null,
+ },
+ );
}
});
},
diff --git a/app/assets/javascripts/ide/stores/utils.js b/app/assets/javascripts/ide/stores/utils.js
index 04470064c1f..366314536c6 100644
--- a/app/assets/javascripts/ide/stores/utils.js
+++ b/app/assets/javascripts/ide/stores/utils.js
@@ -159,7 +159,7 @@ export const createCommitPayload = ({
});
export const createNewMergeRequestUrl = (projectUrl, source, target) =>
- `${projectUrl}/merge_requests/new?merge_request[source_branch]=${source}&merge_request[target_branch]=${target}`;
+ `${projectUrl}/merge_requests/new?merge_request[source_branch]=${source}&merge_request[target_branch]=${target}&nav_source=webide`;
const sortTreesByTypeAndName = (a, b) => {
if (a.type === 'tree' && b.type === 'blob') {
diff --git a/app/controllers/chaos_controller.rb b/app/controllers/chaos_controller.rb
index 2985da35d83..ac008165c16 100644
--- a/app/controllers/chaos_controller.rb
+++ b/app/controllers/chaos_controller.rb
@@ -1,57 +1,38 @@
# frozen_string_literal: true
class ChaosController < ActionController::Base
- before_action :validate_chaos_secret, unless: :development?
- before_action :request_start_time
+ before_action :validate_chaos_secret, unless: :development_or_test?
def leakmem
- retainer = []
- # Add `n` 1mb chunks of memory to the retainer array
- memory_mb.times { retainer << "x" * 1.megabyte }
-
- Kernel.sleep(duration_left)
-
- render plain: "OK"
+ do_chaos :leak_mem, Chaos::LeakMemWorker, memory_mb, duration_s
end
def cpu_spin
- rand while Time.now < expected_end_time
-
- render plain: "OK"
+ do_chaos :cpu_spin, Chaos::CpuSpinWorker, duration_s
end
def db_spin
- while Time.now < expected_end_time
- ActiveRecord::Base.connection.execute("SELECT 1")
-
- end_interval_time = Time.now + [duration_s, interval_s].min
- rand while Time.now < end_interval_time
- end
+ do_chaos :db_spin, Chaos::DbSpinWorker, duration_s, interval_s
end
def sleep
- Kernel.sleep(duration_left)
-
- render plain: "OK"
+ do_chaos :sleep, Chaos::SleepWorker, duration_s
end
def kill
- Process.kill("KILL", Process.pid)
+ do_chaos :kill, Chaos::KillWorker
end
private
- def request_start_time
- @start_time ||= Time.now
- end
-
- def expected_end_time
- request_start_time + duration_s
- end
+ def do_chaos(method, worker, *args)
+ if async
+ worker.perform_async(*args)
+ else
+ Gitlab::Chaos.public_send(method, *args) # rubocop: disable GitlabSecurity/PublicSend
+ end
- def duration_left
- # returns 0 if over time
- [expected_end_time - Time.now, 0].max
+ render plain: "OK"
end
def validate_chaos_secret
@@ -91,7 +72,12 @@ class ChaosController < ActionController::Base
memory_mb.to_i
end
- def development?
- Rails.env.development?
+ def async
+ async = params[:async] || false
+ Gitlab::Utils.to_boolean(async)
+ end
+
+ def development_or_test?
+ Rails.env.development? || Rails.env.test?
end
end
diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb
index eeeebe430a7..af1e6cc703b 100644
--- a/app/controllers/ide_controller.rb
+++ b/app/controllers/ide_controller.rb
@@ -4,5 +4,6 @@ class IdeController < ApplicationController
layout 'fullscreen'
def index
+ Gitlab::UsageDataCounters::WebIdeCounter.increment_views_count
end
end
diff --git a/app/controllers/projects/merge_requests/creations_controller.rb b/app/controllers/projects/merge_requests/creations_controller.rb
index 32cefe54613..6ac5bb90706 100644
--- a/app/controllers/projects/merge_requests/creations_controller.rb
+++ b/app/controllers/projects/merge_requests/creations_controller.rb
@@ -23,6 +23,8 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
@merge_request = ::MergeRequests::CreateService.new(project, current_user, merge_request_params).execute
if @merge_request.valid?
+ incr_count_webide_merge_request
+
redirect_to(merge_request_path(@merge_request))
else
@source_project = @merge_request.source_project
@@ -135,4 +137,10 @@ class Projects::MergeRequests::CreationsController < Projects::MergeRequests::Ap
def whitelist_query_limiting
Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab-ce/issues/42384')
end
+
+ def incr_count_webide_merge_request
+ return if params[:nav_source] != 'webide'
+
+ Gitlab::UsageDataCounters::WebIdeCounter.increment_merge_requests_count
+ end
end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 952de92cae1..e60b6497cb7 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -427,4 +427,11 @@ module Issuable
def wipless_title_changed(old_title)
old_title != title
end
+
+ ##
+ # Overridden on EE module
+ #
+ def supports_milestone?
+ respond_to?(:milestone_id)
+ end
end
diff --git a/app/models/dashboard_group_milestone.rb b/app/models/dashboard_group_milestone.rb
index 74aa04ab7d0..ec52f1ed370 100644
--- a/app/models/dashboard_group_milestone.rb
+++ b/app/models/dashboard_group_milestone.rb
@@ -15,8 +15,7 @@ class DashboardGroupMilestone < GlobalMilestone
milestones = Milestone.of_groups(groups.select(:id))
.reorder_by_due_date_asc
.order_by_name_asc
- .active
milestones = milestones.search_title(params[:search_title]) if params[:search_title].present?
- milestones.map { |m| new(m) }
+ Milestone.filter_by_state(milestones, params[:state]).map { |m| new(m) }
end
end
diff --git a/app/models/environment.rb b/app/models/environment.rb
index b8ee54c1696..392481ea0cc 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -4,11 +4,6 @@ class Environment < ApplicationRecord
include Gitlab::Utils::StrongMemoize
include ReactiveCaching
- # Used to generate random suffixes for the slug
- LETTERS = ('a'..'z').freeze
- NUMBERS = ('0'..'9').freeze
- SUFFIX_CHARS = LETTERS.to_a + NUMBERS.to_a
-
belongs_to :project, required: true
has_many :deployments, -> { success }, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
@@ -203,40 +198,6 @@ class Environment < ApplicationRecord
super.presence || generate_slug
end
- # An environment name is not necessarily suitable for use in URLs, DNS
- # or other third-party contexts, so provide a slugified version. A slug has
- # the following properties:
- # * contains only lowercase letters (a-z), numbers (0-9), and '-'
- # * begins with a letter
- # * has a maximum length of 24 bytes (OpenShift limitation)
- # * cannot end with `-`
- def generate_slug
- # Lowercase letters and numbers only
- slugified = +name.to_s.downcase.gsub(/[^a-z0-9]/, '-')
-
- # Must start with a letter
- slugified = 'env-' + slugified unless LETTERS.cover?(slugified[0])
-
- # Repeated dashes are invalid (OpenShift limitation)
- slugified.gsub!(/\-+/, '-')
-
- # Maximum length: 24 characters (OpenShift limitation)
- slugified = slugified[0..23]
-
- # Cannot end with a dash (Kubernetes label limitation)
- slugified.chop! if slugified.end_with?('-')
-
- # Add a random suffix, shortening the current string if necessary, if it
- # has been slugified. This ensures uniqueness.
- if slugified != name
- slugified = slugified[0..16]
- slugified << '-' unless slugified.end_with?('-')
- slugified << random_suffix
- end
-
- self.slug = slugified
- end
-
def external_url_for(path, commit_sha)
return unless self.external_url
@@ -274,11 +235,7 @@ class Environment < ApplicationRecord
private
- # Slugifying a name may remove the uniqueness guarantee afforded by it being
- # based on name (which must be unique). To compensate, we add a random
- # 6-byte suffix in those circumstances. This is not *guaranteed* uniqueness,
- # but the chance of collisions is vanishingly small
- def random_suffix
- (0..5).map { SUFFIX_CHARS.sample }.join
+ def generate_slug
+ self.slug = Gitlab::Slug::Environment.new(name).generate
end
end
diff --git a/app/services/issuable/clone/attributes_rewriter.rb b/app/services/issuable/clone/attributes_rewriter.rb
index 0300cc0d8d3..3c061d35558 100644
--- a/app/services/issuable/clone/attributes_rewriter.rb
+++ b/app/services/issuable/clone/attributes_rewriter.rb
@@ -17,6 +17,8 @@ module Issuable
private
def cloneable_milestone
+ return unless new_entity.supports_milestone?
+
title = original_entity.milestone&.title
return unless title
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index c3d5ce0fe70..6fc7ec1bb6f 100644
--- a/app/views/admin/users/index.html.haml
+++ b/app/views/admin/users/index.html.haml
@@ -52,7 +52,7 @@
= icon("search", class: "search-icon")
= button_tag s_('AdminUsers|Search users') if Rails.env.test?
.dropdown.user-sort-dropdown
- - toggle_text = if @sort.present? then users_sort_options_hash[@sort] else sort_title_name end
+ - toggle_text = @sort.present? ? users_sort_options_hash[@sort] : sort_title_name
= dropdown_toggle(toggle_text, { toggle: 'dropdown' })
%ul.dropdown-menu.dropdown-menu-right
%li.dropdown-header
diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml
index a8e34b6da9c..31c4bb0e33e 100644
--- a/app/views/devise/sessions/_new_ldap.html.haml
+++ b/app/views/devise/sessions/_new_ldap.html.haml
@@ -3,10 +3,10 @@
= form_tag(omniauth_callback_path(:user, server['provider_name']), id: 'new_ldap_user', class: "gl-show-field-errors") do
.form-group
= label_tag :username, "#{server['label']} Username"
- = text_field_tag :username, nil, { class: "form-control top", title: "This field is required.", autofocus: "autofocus", data: { qa_selector: 'username_field' } required: true }
+ = text_field_tag :username, nil, { class: "form-control top", title: "This field is required.", autofocus: "autofocus", data: { qa_selector: 'username_field' }, required: true }
.form-group
= label_tag :password
- = password_field_tag :password, nil, { class: "form-control bottom", title: "This field is required.", data: { qa_selector: 'password_field' }required: true }
+ = password_field_tag :password, nil, { class: "form-control bottom", title: "This field is required.", data: { qa_selector: 'password_field' }, required: true }
- if devise_mapping.rememberable?
.remember-me
%label{ for: "remember_me" }
diff --git a/app/views/projects/merge_requests/creations/_new_compare.html.haml b/app/views/projects/merge_requests/creations/_new_compare.html.haml
index 11272a67f93..be01905dd35 100644
--- a/app/views/projects/merge_requests/creations/_new_compare.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_compare.html.haml
@@ -2,6 +2,8 @@
New Merge Request
= form_for [@project.namespace.becomes(Namespace), @project, @merge_request], url: project_new_merge_request_path(@project), method: :get, html: { class: "merge-request-form js-requires-input" } do |f|
+ - if params[:nav_source].present?
+ = hidden_field_tag(:nav_source, params[:nav_source])
.hide.alert.alert-danger.mr-compare-errors
.js-merge-request-new-compare.row{ 'data-source-branch-url': project_new_merge_request_branch_from_path(@source_project), 'data-target-branch-url': project_new_merge_request_branch_to_path(@source_project) }
.col-lg-6
diff --git a/app/views/projects/merge_requests/creations/_new_submit.html.haml b/app/views/projects/merge_requests/creations/_new_submit.html.haml
index 464f8fa65e9..543441b9479 100644
--- a/app/views/projects/merge_requests/creations/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/creations/_new_submit.html.haml
@@ -17,6 +17,9 @@
= f.hidden_field :target_project_id
= f.hidden_field :target_branch, id: ''
+ - if params[:nav_source].present?
+ = hidden_field_tag(:nav_source, params[:nav_source])
+
.mr-compare.merge-request.js-merge-request-new-submit{ 'data-mr-submit-action': "#{j params[:tab].presence || 'new'}" }
- if @commits.empty?
.commits-empty
diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml
index 3d34bfc05c7..991a177018e 100644
--- a/app/workers/all_queues.yml
+++ b/app/workers/all_queues.yml
@@ -3,6 +3,12 @@
- auto_merge:auto_merge_process
+- chaos:chaos_cpu_spin
+- chaos:chaos_db_spin
+- chaos:chaos_kill
+- chaos:chaos_leak_mem
+- chaos:chaos_sleep
+
- cronjob:admin_email
- cronjob:expire_build_artifacts
- cronjob:gitlab_usage_ping
diff --git a/app/workers/chaos/cpu_spin_worker.rb b/app/workers/chaos/cpu_spin_worker.rb
new file mode 100644
index 00000000000..43a32c3274f
--- /dev/null
+++ b/app/workers/chaos/cpu_spin_worker.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Chaos
+ class CpuSpinWorker
+ include ApplicationWorker
+ include ChaosQueue
+
+ def perform(duration_s)
+ Gitlab::Chaos.cpu_spin(duration_s)
+ end
+ end
+end
diff --git a/app/workers/chaos/db_spin_worker.rb b/app/workers/chaos/db_spin_worker.rb
new file mode 100644
index 00000000000..217ddabbcb6
--- /dev/null
+++ b/app/workers/chaos/db_spin_worker.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Chaos
+ class DbSpinWorker
+ include ApplicationWorker
+ include ChaosQueue
+
+ def perform(duration_s, interval_s)
+ Gitlab::Chaos.db_spin(duration_s, interval_s)
+ end
+ end
+end
diff --git a/app/workers/chaos/kill_worker.rb b/app/workers/chaos/kill_worker.rb
new file mode 100644
index 00000000000..bbad53c9b86
--- /dev/null
+++ b/app/workers/chaos/kill_worker.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Chaos
+ class KillWorker
+ include ApplicationWorker
+ include ChaosQueue
+
+ def perform
+ Gitlab::Chaos.kill
+ end
+ end
+end
diff --git a/app/workers/chaos/leak_mem_worker.rb b/app/workers/chaos/leak_mem_worker.rb
new file mode 100644
index 00000000000..0caa99e0de9
--- /dev/null
+++ b/app/workers/chaos/leak_mem_worker.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Chaos
+ class LeakMemWorker
+ include ApplicationWorker
+ include ChaosQueue
+
+ def perform(memory_mb, duration_s)
+ Gitlab::Chaos.leak_mem(memory_mb, duration_s)
+ end
+ end
+end
diff --git a/app/workers/chaos/sleep_worker.rb b/app/workers/chaos/sleep_worker.rb
new file mode 100644
index 00000000000..7c724c4cb4e
--- /dev/null
+++ b/app/workers/chaos/sleep_worker.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+module Chaos
+ class SleepWorker
+ include ApplicationWorker
+ include ChaosQueue
+
+ def perform(duration_s)
+ Gitlab::Chaos.sleep(duration_s)
+ end
+ end
+end
diff --git a/app/workers/concerns/chaos_queue.rb b/app/workers/concerns/chaos_queue.rb
new file mode 100644
index 00000000000..e406509d12d
--- /dev/null
+++ b/app/workers/concerns/chaos_queue.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+#
+module ChaosQueue
+ extend ActiveSupport::Concern
+
+ included do
+ queue_namespace :chaos
+ end
+end
diff --git a/changelogs/unreleased/64295-predictable-environment-slugs.yml b/changelogs/unreleased/64295-predictable-environment-slugs.yml
new file mode 100644
index 00000000000..de581b2b8e1
--- /dev/null
+++ b/changelogs/unreleased/64295-predictable-environment-slugs.yml
@@ -0,0 +1,5 @@
+---
+title: Use predictable environment slugs
+merge_request: 30551
+author:
+type: added
diff --git a/changelogs/unreleased/an-sidekiq-chaos.yml b/changelogs/unreleased/an-sidekiq-chaos.yml
new file mode 100644
index 00000000000..cede35c95cc
--- /dev/null
+++ b/changelogs/unreleased/an-sidekiq-chaos.yml
@@ -0,0 +1,5 @@
+---
+title: Adds chaos endpoints to Sidekiq
+merge_request: 30814
+author:
+type: other
diff --git a/changelogs/unreleased/bjk-64064_cache_metrics.yml b/changelogs/unreleased/bjk-64064_cache_metrics.yml
new file mode 100644
index 00000000000..c9baff7cb7b
--- /dev/null
+++ b/changelogs/unreleased/bjk-64064_cache_metrics.yml
@@ -0,0 +1,5 @@
+---
+title: Adjust redis cache metrics
+merge_request: 30572
+author:
+type: changed
diff --git a/changelogs/unreleased/fe-delete-old-boardservice.yml b/changelogs/unreleased/fe-delete-old-boardservice.yml
new file mode 100644
index 00000000000..bb06bfe80d5
--- /dev/null
+++ b/changelogs/unreleased/fe-delete-old-boardservice.yml
@@ -0,0 +1,6 @@
+---
+title: Change BoardService in favor of boardsStore on board blank state of the component
+ board
+merge_request: 30546
+author: eduarmreyes
+type: other
diff --git a/changelogs/unreleased/fj-count-web-ide-merge-requests.yml b/changelogs/unreleased/fj-count-web-ide-merge-requests.yml
new file mode 100644
index 00000000000..adcd0af37e8
--- /dev/null
+++ b/changelogs/unreleased/fj-count-web-ide-merge-requests.yml
@@ -0,0 +1,5 @@
+---
+title: Add Web IDE Usage Ping for Create SMAU
+merge_request: 30800
+author:
+type: changed
diff --git a/changelogs/unreleased/georgekoltsov-64311-set-visibility-private-if-internal-restricted.yml b/changelogs/unreleased/georgekoltsov-64311-set-visibility-private-if-internal-restricted.yml
new file mode 100644
index 00000000000..18af16e5216
--- /dev/null
+++ b/changelogs/unreleased/georgekoltsov-64311-set-visibility-private-if-internal-restricted.yml
@@ -0,0 +1,5 @@
+---
+title: Set visibility level 'Private' for restricted 'Internal' imported projects when 'Internal' visibility setting is restricted in admin settings
+merge_request: 30522
+author:
+type: other
diff --git a/changelogs/unreleased/group-milestones-dashboard-blunceford.yml b/changelogs/unreleased/group-milestones-dashboard-blunceford.yml
new file mode 100644
index 00000000000..a6ded27cb8c
--- /dev/null
+++ b/changelogs/unreleased/group-milestones-dashboard-blunceford.yml
@@ -0,0 +1,5 @@
+---
+title: Fix bug in dashboard display of closed milestones
+merge_request: 30820
+author:
+type: fixed
diff --git a/config/karma.config.js b/config/karma.config.js
index 2a5bf3581e0..97794225a3f 100644
--- a/config/karma.config.js
+++ b/config/karma.config.js
@@ -107,7 +107,8 @@ if (specFilters.length) {
module.exports = function(config) {
process.env.TZ = 'Etc/UTC';
- const fixturesPath = `${IS_EE ? 'ee/' : ''}spec/javascripts/fixtures`;
+ const fixturesPath = `tmp/tests/frontend/fixtures${IS_EE ? '-ee' : ''}`;
+ const staticFixturesPath = 'spec/frontend/fixtures/static';
const karmaConfig = {
basePath: ROOT_PATH,
@@ -131,8 +132,13 @@ module.exports = function(config) {
frameworks: ['jasmine'],
files: [
{ pattern: 'spec/javascripts/test_bundle.js', watched: false },
- { pattern: `${fixturesPath}/**/*@(.json|.html|.png|.bmpr|.pdf)`, included: false },
+ { pattern: `${fixturesPath}/**/*`, included: false },
+ { pattern: `${staticFixturesPath}/**/*`, included: false },
],
+ proxies: {
+ '/fixtures/': `/base/${fixturesPath}/`,
+ '/fixtures/static/': `/base/${staticFixturesPath}/`,
+ },
preprocessors: {
'spec/javascripts/**/*.js': ['webpack', 'sourcemap'],
'ee/spec/javascripts/**/*.js': ['webpack', 'sourcemap'],
diff --git a/config/routes.rb b/config/routes.rb
index 641807203bf..459f2b22bf0 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -116,7 +116,7 @@ Rails.application.routes.draw do
end
end
- if ENV['GITLAB_CHAOS_SECRET'] || Rails.env.development?
+ if ENV['GITLAB_CHAOS_SECRET'] || Rails.env.development? || Rails.env.test?
resource :chaos, only: [] do
get :leakmem
get :cpu_spin
diff --git a/config/sidekiq_queues.yml b/config/sidekiq_queues.yml
index 80791795390..c7586aa1e38 100644
--- a/config/sidekiq_queues.yml
+++ b/config/sidekiq_queues.yml
@@ -95,6 +95,7 @@
- [update_project_statistics, 1]
- [phabricator_import_import_tasks, 1]
- [update_namespace_statistics, 1]
+ - [chaos, 2]
# EE-specific queues
- [ldap_group_sync, 2]
diff --git a/doc/administration/auth/ldap-ee.md b/doc/administration/auth/ldap-ee.md
index 2f2ee8a27d3..1b7af2d945a 100644
--- a/doc/administration/auth/ldap-ee.md
+++ b/doc/administration/auth/ldap-ee.md
@@ -193,7 +193,7 @@ group, as opposed to the full DN.
to lock down user abilities to invite new members to a group. When enabled following happens:
1. Only administrator can manage memberships of any group including access levels.
-2. Users are not allowed to share project with other groups or invite members to a project created in a group.
+1. Users are not allowed to share project with other groups or invite members to a project created in a group.
## Adjusting LDAP user sync schedule
diff --git a/doc/administration/gitaly/index.md b/doc/administration/gitaly/index.md
index 4407facfca9..0ef88a26ab9 100644
--- a/doc/administration/gitaly/index.md
+++ b/doc/administration/gitaly/index.md
@@ -2,45 +2,35 @@
[Gitaly](https://gitlab.com/gitlab-org/gitaly) is the service that
provides high-level RPC access to Git repositories. Without it, no other
-components can read or write Git data.
+components can read or write Git data. GitLab components that access Git
+repositories (gitlab-rails, gitlab-shell, gitlab-workhorse, etc.) act as clients
+to Gitaly. End users do not have direct access to Gitaly.
-GitLab components that access Git repositories (gitlab-rails,
-gitlab-shell, gitlab-workhorse) act as clients to Gitaly. End users do
-not have direct access to Gitaly.
+In the rest of this page, Gitaly server is referred to the standalone node that
+only runs Gitaly, and Gitaly client to the GitLab Rails node that runs all other
+processes except Gitaly.
## Configuring Gitaly
The Gitaly service itself is configured via a TOML configuration file.
-This file is documented [in the gitaly
+This file is documented [in the Gitaly
repository](https://gitlab.com/gitlab-org/gitaly/blob/master/doc/configuration/README.md).
-To change a Gitaly setting in Omnibus you can use
-`gitaly['my_setting']` in `/etc/gitlab/gitlab.rb`. Changes will be applied
-when you run `gitlab-ctl reconfigure`.
+In case you want to change some of its settings:
-```ruby
-gitaly['prometheus_listen_addr'] = 'localhost:9236'
-```
-
-To change a Gitaly setting in installations from source you can edit
-`/home/git/gitaly/config.toml`. Changes will be applied when you run
-`service gitlab restart`.
+**For Omnibus GitLab**
-```toml
-prometheus_listen_addr = "localhost:9236"
-```
+1. Edit `/etc/gitlab/gitlab.rb` and add or change the [Gitaly settings](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/1dd07197c7e5ae23626aad5a4a070a800b670380/files/gitlab-config-template/gitlab.rb.template#L1622-1676).
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-## Client-side GRPC logs
+**For installations from source**
-Gitaly uses the [gRPC](https://grpc.io/) RPC framework. The Ruby gRPC
-client has its own log file which may contain useful information when
-you are seeing Gitaly errors. You can control the log level of the
-gRPC client with the `GRPC_LOG_LEVEL` environment variable. The
-default level is `WARN`.
+1. Edit `/home/git/gitaly/config.toml` and add or change the [Gitaly settings](https://gitlab.com/gitlab-org/gitaly/blob/master/config.toml.example).
+1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
## Running Gitaly on its own server
-> This is an optional way to deploy Gitaly which can benefit GitLab
+This is an optional way to deploy Gitaly which can benefit GitLab
installations that are larger than a single machine. Most
installations will be better served with the default configuration
used by Omnibus and the GitLab source installation guide.
@@ -53,76 +43,78 @@ But since 11.8 the indexer uses Gitaly for data access as well. NFS can still
be leveraged for redudancy on block level of the Git data. But only has to
be mounted on the Gitaly server.
-NOTE: **Note:** While Gitaly can be used as a replacement for NFS, we do not recommend
-using EFS as it may impact GitLab's performance. Please review the [relevant documentation](../high_availability/nfs.md#avoid-using-awss-elastic-file-system-efs)
+NOTE: **Note:** While Gitaly can be used as a replacement for NFS, it's not recommended
+to use EFS as it may impact GitLab's performance. Review the [relevant documentation](../high_availability/nfs.md#avoid-using-awss-elastic-file-system-efs)
for more details.
### Network architecture
-- gitlab-rails shards repositories into "repository storages"
-- `gitlab-rails/config/gitlab.yml` contains a map from storage names to
- (Gitaly address, Gitaly token) pairs
-- the `storage name` -\> `(Gitaly address, Gitaly token)` map in
- `gitlab.yml` is the single source of truth for the Gitaly network
- topology
-- a (Gitaly address, Gitaly token) corresponds to a Gitaly server
-- a Gitaly server hosts one or more storages
-- Gitaly addresses must be specified in such a way that they resolve
- correctly for ALL Gitaly clients
-- Gitaly clients are: unicorn, sidekiq, gitlab-workhorse,
- gitlab-shell, Elasticsearch Indexer, and Gitaly itself
-- special case: a Gitaly server must be able to make RPC calls **to
- itself** via its own (Gitaly address, Gitaly token) pair as
- specified in `gitlab-rails/config/gitlab.yml`
-- Gitaly servers must not be exposed to the public internet
-
-Gitaly network traffic is unencrypted by default, but supports
-[TLS](#tls-support). Authentication is done through a static token.
-
-NOTE: **Note:** Gitaly network traffic is unencrypted so we recommend a firewall to
-restrict access to your Gitaly server.
+The following list depicts what the network architecture of Gitaly is:
+
+- GitLab Rails shards repositories into [repository storages](../repository_storage_paths.md).
+- `/config/gitlab.yml` contains a map from storage names to
+ `(Gitaly address, Gitaly token)` pairs.
+- the `storage name` -\> `(Gitaly address, Gitaly token)` map in
+ `/config/gitlab.yml` is the single source of truth for the Gitaly network
+ topology.
+- A `(Gitaly address, Gitaly token)` corresponds to a Gitaly server.
+- A Gitaly server hosts one or more storages.
+- Gitaly addresses must be specified in such a way that they resolve
+ correctly for ALL Gitaly clients.
+- Gitaly clients are: Unicorn, Sidekiq, gitlab-workhorse,
+ gitlab-shell, Elasticsearch Indexer, and Gitaly itself.
+- A Gitaly server must be able to make RPC calls **to itself** via its own
+ `(Gitaly address, Gitaly token)` pair as specified in `/config/gitlab.yml`.
+- Gitaly servers must not be exposed to the public internet as Gitaly's network
+ traffic is unencrypted by default. The use of firewall is highly recommended
+ to restrict access to the Gitaly server. Another option is to
+ [use TLS](#tls-support).
+- Authentication is done through a static token which is shared among the Gitaly
+ and GitLab Rails nodes.
Below we describe how to configure a Gitaly server at address
`gitaly.internal:8075` with secret token `abc123secret`. We assume
your GitLab installation has two repository storages, `default` and
`storage1`.
-### Installation
+### 1. Installation
-First install Gitaly using either Omnibus or from source.
+First install Gitaly using either Omnibus GitLab or install it from source:
-Omnibus: [Download/install](https://about.gitlab.com/install/) the Omnibus GitLab
-package you want using **steps 1 and 2** from the GitLab downloads page but
-**_do not_** provide the `EXTERNAL_URL=` value.
+- For Omnibus GitLab: [Download/install](https://about.gitlab.com/install/) the Omnibus GitLab
+ package you want using **steps 1 and 2** from the GitLab downloads page but
+ **_do not_** provide the `EXTERNAL_URL=` value.
+- From source: [Install Gitaly](../../install/installation.md#install-gitaly).
-Source: [Install Gitaly](../../install/installation.md#install-gitaly)
+### 2. Client side token configuration
-### Client side token configuration
+Configure a token on the instance that runs the GitLab Rails application.
-Configure a token on the client side.
+**For Omnibus GitLab**
-Omnibus installations:
+1. On the client node(s), edit `/etc/gitlab/gitlab.rb`:
-```ruby
-# /etc/gitlab/gitlab.rb
-gitlab_rails['gitaly_token'] = 'abc123secret'
-```
+ ```ruby
+ gitlab_rails['gitaly_token'] = 'abc123secret'
+ ```
-Source installations:
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-```yaml
-# /home/git/gitlab/config/gitlab.yml
-gitlab:
- gitaly:
- token: 'abc123secret'
-```
+**For installations from source**
+
+1. On the client node(s), edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ gitlab:
+ gitaly:
+ token: 'abc123secret'
+ ```
-You need to reconfigure (Omnibus) or restart (source) for these
-changes to be picked up.
+1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
-### Gitaly server configuration
+### 3. Gitaly server configuration
-Next, on the Gitaly server, we need to configure storage paths, enable
+Next, on the Gitaly server, you need to configure storage paths, enable
the network listener and configure the token.
NOTE: **Note:** if you want to reduce the risk of downtime when you enable
@@ -137,88 +129,99 @@ the Gitaly server. The easiest way to accomplish this is to copy `/etc/gitlab/gi
from an existing GitLab server to the Gitaly server. Without this shared secret,
Git operations in GitLab will result in an API error.
-NOTE: **Note:** In most or all cases the storage paths below end in `/repositories` which is
-different than `path` in `git_data_dirs` of Omnibus installations. Check the
-directory layout on your Gitaly server to be sure.
-
-Omnibus installations:
-
-<!--
-updates to following example must also be made at
-https://gitlab.com/charts/gitlab/blob/master/doc/advanced/external-gitaly/external-omnibus-gitaly.md#configure-omnibus-gitlab
--->
-
-```ruby
-# /etc/gitlab/gitlab.rb
-
-# Avoid running unnecessary services on the Gitaly server
-postgresql['enable'] = false
-redis['enable'] = false
-nginx['enable'] = false
-prometheus['enable'] = false
-unicorn['enable'] = false
-sidekiq['enable'] = false
-gitlab_workhorse['enable'] = false
-
-# Prevent database connections during 'gitlab-ctl reconfigure'
-gitlab_rails['rake_cache_clear'] = false
-gitlab_rails['auto_migrate'] = false
-
-# Configure the gitlab-shell API callback URL. Without this, `git push` will
-# fail. This can be your 'front door' GitLab URL or an internal load
-# balancer.
-# Don't forget to copy `/etc/gitlab/gitlab-secrets.json` from web server to Gitaly server.
-gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'
-
-# Make Gitaly accept connections on all network interfaces. You must use
-# firewalls to restrict access to this address/port.
-gitaly['listen_addr'] = "0.0.0.0:8075"
-gitaly['auth_token'] = 'abc123secret'
-
-gitaly['storage'] = [
- { 'name' => 'default', 'path' => '/mnt/gitlab/default/repositories' },
- { 'name' => 'storage1', 'path' => '/mnt/gitlab/storage1/repositories' },
-]
-
-# To use TLS for Gitaly you need to add
-gitaly['tls_listen_addr'] = "0.0.0.0:9999"
-gitaly['certificate_path'] = "path/to/cert.pem"
-gitaly['key_path'] = "path/to/key.pem"
-```
+NOTE: **Note:**
+In most or all cases, the storage paths below end in `/repositories` which is
+not that case with `path` in `git_data_dirs` of Omnibus GitLab installations.
+Check the directory layout on your Gitaly server to be sure.
-Source installations:
+**For Omnibus GitLab**
-```toml
-# /home/git/gitaly/config.toml
-listen_addr = '0.0.0.0:8075'
-tls_listen_addr = '0.0.0.0:9999'
+1. Edit `/etc/gitlab/gitlab.rb`:
-[tls]
-certificate_path = /path/to/cert.pem
-key_path = /path/to/key.pem
+ <!--
+ updates to following example must also be made at
+ https://gitlab.com/charts/gitlab/blob/master/doc/advanced/external-gitaly/external-omnibus-gitaly.md#configure-omnibus-gitlab
+ -->
-[auth]
-token = 'abc123secret'
+ ```ruby
+ # /etc/gitlab/gitlab.rb
-[[storage]]
-name = 'default'
-path = '/mnt/gitlab/default/repositories'
+ # Avoid running unnecessary services on the Gitaly server
+ postgresql['enable'] = false
+ redis['enable'] = false
+ nginx['enable'] = false
+ prometheus['enable'] = false
+ unicorn['enable'] = false
+ sidekiq['enable'] = false
+ gitlab_workhorse['enable'] = false
-[[storage]]
-name = 'storage1'
-path = '/mnt/gitlab/storage1/repositories'
-```
+ # Prevent database connections during 'gitlab-ctl reconfigure'
+ gitlab_rails['rake_cache_clear'] = false
+ gitlab_rails['auto_migrate'] = false
+
+ # Configure the gitlab-shell API callback URL. Without this, `git push` will
+ # fail. This can be your 'front door' GitLab URL or an internal load
+ # balancer.
+ # Don't forget to copy `/etc/gitlab/gitlab-secrets.json` from web server to Gitaly server.
+ gitlab_rails['internal_api_url'] = 'https://gitlab.example.com'
-Again, reconfigure (Omnibus) or restart (source).
+ # Make Gitaly accept connections on all network interfaces. You must use
+ # firewalls to restrict access to this address/port.
+ gitaly['listen_addr'] = "0.0.0.0:8075"
+ gitaly['auth_token'] = 'abc123secret'
-### Converting clients to use the Gitaly server
+ gitaly['storage'] = [
+ { 'name' => 'default' },
+ { 'name' => 'storage1' },
+ ]
-Now as the final step update the client machines to switch from using
-their local Gitaly service to the new Gitaly server you just
-configured. This is a risky step because if there is any sort of
-network, firewall, or name resolution problem preventing your GitLab
-server from reaching the Gitaly server then all Gitaly requests will
-fail.
+ # To use TLS for Gitaly you need to add
+ gitaly['tls_listen_addr'] = "0.0.0.0:9999"
+ gitaly['certificate_path'] = "path/to/cert.pem"
+ gitaly['key_path'] = "path/to/key.pem"
+ ```
+
+ NOTE: **Note:**
+ In some cases, you'll have to set `path` for `gitaly['storage']` in the
+ format `'path' => '/mnt/gitlab/<storage name>/repositories'`.
+
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
+**For installations from source**
+
+1. On the client node(s), edit `/home/git/gitaly/config.toml`:
+
+ ```toml
+ listen_addr = '0.0.0.0:8075'
+ tls_listen_addr = '0.0.0.0:9999'
+
+ [tls]
+ certificate_path = /path/to/cert.pem
+ key_path = /path/to/key.pem
+
+ [auth]
+ token = 'abc123secret'
+
+ [[storage]]
+ name = 'default'
+
+ [[storage]]
+ name = 'storage1'
+ ```
+
+ NOTE: **Note:**
+ In some cases, you'll have to set `path` for each `[[storage]]` in the
+ format `path = '/mnt/gitlab/<storage name>/repositories'`.
+
+1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
+
+### 4. Converting clients to use the Gitaly server
+
+As the final step, you need to update the client machines to switch from using
+their local Gitaly service to the new Gitaly server you just configured. This
+is a risky step because if there is any sort of network, firewall, or name
+resolution problem preventing your GitLab server from reaching the Gitaly server,
+then all Gitaly requests will fail.
Additionally, you need to
[disable Rugged if previously manually enabled](../high_availability/nfs.md#improving-nfs-performance-with-gitlab).
@@ -227,41 +230,93 @@ We assume that your Gitaly server can be reached at
`gitaly.internal:8075` from your GitLab server, and that Gitaly can read and
write to `/mnt/gitlab/default` and `/mnt/gitlab/storage1` respectively.
-Omnibus installations:
+**For Omnibus GitLab**
-```ruby
-# /etc/gitlab/gitlab.rb
-git_data_dirs({
- 'default' => { 'gitaly_address' => 'tcp://gitaly.internal:8075' },
- 'storage1' => { 'gitaly_address' => 'tcp://gitaly.internal:8075' },
-})
+1. Edit `/etc/gitlab/gitlab.rb`:
-gitlab_rails['gitaly_token'] = 'abc123secret'
-```
+ ```ruby
+ git_data_dirs({
+ 'default' => { 'gitaly_address' => 'tcp://gitaly.internal:8075' },
+ 'storage1' => { 'gitaly_address' => 'tcp://gitaly.internal:8075' },
+ })
-Source installations:
-
-```yaml
-# /home/git/gitlab/config/gitlab.yml
-gitlab:
- repositories:
- storages:
- default:
- path: /mnt/gitlab/default/repositories
- gitaly_address: tcp://gitaly.internal:8075
- storage1:
- path: /mnt/gitlab/storage1/repositories
- gitaly_address: tcp://gitaly.internal:8075
-
- gitaly:
- token: 'abc123secret'
-```
+ gitlab_rails['gitaly_token'] = 'abc123secret'
+ ```
-Now reconfigure (Omnibus) or restart (source). When you tail the
-Gitaly logs on your Gitaly server (`sudo gitlab-ctl tail gitaly` or
-`tail -f /home/git/gitlab/log/gitaly.log`) you should see requests
-coming in. One sure way to trigger a Gitaly request is to clone a
-repository from your GitLab server over HTTP.
+ NOTE: **Note:**
+ In some cases, you'll have to set `path` for each `git_data_dirs` in the
+ format `'path' => '/mnt/gitlab/<storage name>'`.
+
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+1. Tail the logs to see the requests:
+
+ ```sh
+ sudo gitlab-ctl tail gitaly
+ ```
+
+**For installations from source**
+
+1. Edit `/home/git/gitlab/config/gitlab.yml`:
+
+ ```yaml
+ gitlab:
+ repositories:
+ storages:
+ default:
+ gitaly_address: tcp://gitaly.internal:8075
+ storage1:
+ gitaly_address: tcp://gitaly.internal:8075
+
+ gitaly:
+ token: 'abc123secret'
+ ```
+
+ NOTE: **Note:**
+ In some cases, you'll have to set `path` for each of the `storages` in the
+ format `path: /mnt/gitlab/<storage name>/repositories`.
+
+1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
+1. Tail the logs to see the requests:
+
+ ```sh
+ tail -f /home/git/gitlab/log/gitaly.log
+ ```
+
+When you tail the Gitaly logs on your Gitaly server you should see requests
+coming in. One sure way to trigger a Gitaly request is to clone a repository
+from your GitLab server over HTTP.
+
+### Disabling the Gitaly service in a cluster environment
+
+If you are running Gitaly [as a remote
+service](#running-gitaly-on-its-own-server) you may want to disable
+the local Gitaly service that runs on your GitLab server by default.
+Disabling Gitaly only makes sense when you run GitLab in a custom
+cluster configuration, where different services run on different
+machines. Disabling Gitaly on all machines in the cluster is not a
+valid configuration.
+
+To disable Gitaly on a client node:
+
+**For Omnibus GitLab**
+
+1. Edit `/etc/gitlab/gitlab.rb`:
+
+ ```ruby
+ gitaly['enable'] = false
+ ```
+
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+
+**For installations from source**
+
+1. Edit `/etc/default/gitlab`:
+
+ ```shell
+ gitaly_enabled=false
+ ```
+
+1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
## TLS support
@@ -271,168 +326,128 @@ Gitaly supports TLS encryption. To be able to communicate
with a Gitaly instance that listens for secure connections you will need to use `tls://` url
scheme in the `gitaly_address` of the corresponding storage entry in the GitLab configuration.
-The admin needs to bring their own certificate as we do not provide that automatically.
-The certificate to be used needs to be installed on all Gitaly nodes and on all client nodes that communicate with it following procedures described in [GitLab custom certificate configuration](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates).
+You will need to bring your own certificates as this isn't provided automatically.
+The certificate to be used needs to be installed on all Gitaly nodes and on all
+client nodes that communicate with it following the procedure described in
+[GitLab custom certificate configuration](https://docs.gitlab.com/omnibus/settings/ssl.html#install-custom-public-certificates).
-Note that it is possible to configure Gitaly servers with both an
+NOTE: **Note:**
+It is possible to configure Gitaly servers with both an
unencrypted listening address `listen_addr` and an encrypted listening
address `tls_listen_addr` at the same time. This allows you to do a
gradual transition from unencrypted to encrypted traffic, if necessary.
-To observe what type of connections are actually being used in a
-production environment you can use the following Prometheus query:
-
-```
-sum(rate(gitaly_connections_total[5m])) by (type)
-```
+To configure Gitaly with TLS:
-### Example TLS configuration
+**For Omnibus GitLab**
-### Omnibus installations:
+1. On the client nodes, edit `/etc/gitlab/gitlab.rb`:
-#### On client nodes:
+ ```ruby
+ git_data_dirs({
+ 'default' => { 'gitaly_address' => 'tls://gitaly.internal:9999' },
+ 'storage1' => { 'gitaly_address' => 'tls://gitaly.internal:9999' },
+ })
-```ruby
-# /etc/gitlab/gitlab.rb
-git_data_dirs({
- 'default' => { 'gitaly_address' => 'tls://gitaly.internal:9999' },
- 'storage1' => { 'gitaly_address' => 'tls://gitaly.internal:9999' },
-})
+ gitlab_rails['gitaly_token'] = 'abc123secret'
+ ```
-gitlab_rails['gitaly_token'] = 'abc123secret'
-```
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
+1. On the Gitaly server nodes, edit `/etc/gitlab/gitlab.rb`:
-#### On Gitaly server nodes:
+ ```ruby
+ gitaly['tls_listen_addr'] = "0.0.0.0:9999"
+ gitaly['certificate_path'] = "path/to/cert.pem"
+ gitaly['key_path'] = "path/to/key.pem"
+ ```
-```ruby
-gitaly['tls_listen_addr'] = "0.0.0.0:9999"
-gitaly['certificate_path'] = "path/to/cert.pem"
-gitaly['key_path'] = "path/to/key.pem"
-```
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-### Source installations:
+**For installations from source**
-#### On client nodes:
+1. On the client nodes, edit `/home/git/gitlab/config/gitlab.yml`:
-```yaml
-# /home/git/gitlab/config/gitlab.yml
-gitlab:
- repositories:
- storages:
- default:
- path: /mnt/gitlab/default/repositories
- gitaly_address: tls://gitaly.internal:9999
- storage1:
- path: /mnt/gitlab/storage1/repositories
- gitaly_address: tls://gitaly.internal:9999
+ ```yaml
+ gitlab:
+ repositories:
+ storages:
+ default:
+ gitaly_address: tls://gitaly.internal:9999
+ storage1:
+ gitaly_address: tls://gitaly.internal:9999
- gitaly:
- token: 'abc123secret'
-```
+ gitaly:
+ token: 'abc123secret'
+ ```
-#### On Gitaly server nodes:
+ NOTE: **Note:**
+ In some cases, you'll have to set `path` for each of the `storages` in the
+ format `path: /mnt/gitlab/<storage name>/repositories`.
-```toml
-# /home/git/gitaly/config.toml
-tls_listen_addr = '0.0.0.0:9999'
+1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
+1. On the Gitaly server nodes, edit `/home/git/gitaly/config.toml`:
-[tls]
-certificate_path = '/path/to/cert.pem'
-key_path = '/path/to/key.pem'
-```
+ ```toml
+ tls_listen_addr = '0.0.0.0:9999'
-## Gitaly-ruby
+ [tls]
+ certificate_path = '/path/to/cert.pem'
+ key_path = '/path/to/key.pem'
+ ```
-Gitaly was developed to replace Ruby application code in gitlab-ce/ee.
-In order to save time and/or avoid the risk of rewriting existing
-application logic, in some cases we chose to copy some application code
-from gitlab-ce into Gitaly almost as-is. To be able to run that code, we
-made gitaly-ruby, which is a sidecar process for the main Gitaly Go
-process. Some examples of things that are implemented in gitaly-ruby are
-RPC's that deal with wiki's, and RPC's that create commits on behalf of
-a user, such as merge commits.
-
-### Number of gitaly-ruby workers
-
-Gitaly-ruby has much less capacity than Gitaly itself. If your Gitaly
-server has to handle a lot of request, the default setting of having
-just 1 active gitaly-ruby sidecar might not be enough. If you see
-ResourceExhausted errors from Gitaly it's very likely that you have not
-enough gitaly-ruby capacity.
-
-You can increase the number of gitaly-ruby processes on your Gitaly
-server with the following settings.
+1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
-Omnibus:
+To observe what type of connections are actually being used in a
+production environment you can use the following Prometheus query:
-```ruby
-# /etc/gitlab/gitlab.rb
-# Default is 2 workers. The minimum is 2; 1 worker is always reserved as
-# a passive stand-by.
-gitaly['ruby_num_workers'] = 4
```
-
-Source:
-
-```toml
-# /home/git/gitaly/config.toml
-[gitaly-ruby]
-num_workers = 4
+sum(rate(gitaly_connections_total[5m])) by (type)
```
-### Observing gitaly-ruby traffic
-
-Gitaly-ruby is a somewhat hidden, internal implementation detail of
-Gitaly. There is not that much visibility into what goes on inside
-gitaly-ruby processes.
+## `gitaly-ruby`
-If you have Prometheus set up to scrape your Gitaly process, you can see
-request rates and error codes for individual RPC's in gitaly-ruby by
-querying `grpc_client_handled_total`. Strictly speaking this metric does
-not differentiate between gitaly-ruby and other RPC's, but in practice
-(as of GitLab 11.9), all gRPC calls made by Gitaly itself are internal
-calls from the main Gitaly process to one of its gitaly-ruby sidecars.
+Gitaly was developed to replace the Ruby application code in GitLab.
+In order to save time and/or avoid the risk of rewriting existing
+application logic, in some cases we chose to copy some application code
+from GitLab into Gitaly almost as-is. To be able to run that code,
+`gitaly-ruby` was created, which is a "sidecar" process for the main Gitaly Go
+process. Some examples of things that are implemented in `gitaly-ruby` are
+RPCs that deal with wikis, and RPCs that create commits on behalf of
+a user, such as merge commits.
-Assuming your `grpc_client_handled_total` counter only observes Gitaly,
-the following query shows you RPC's are (most likely) internally
-implemented as calls to gitaly-ruby.
+### Number of `gitaly-ruby` workers
-```
-sum(rate(grpc_client_handled_total[5m])) by (grpc_method) > 0
-```
+`gitaly-ruby` has much less capacity than Gitaly itself. If your Gitaly
+server has to handle a lot of requests, the default setting of having
+just one active `gitaly-ruby` sidecar might not be enough. If you see
+`ResourceExhausted` errors from Gitaly, it's very likely that you have not
+enough `gitaly-ruby` capacity.
-## Disabling or enabling the Gitaly service in a cluster environment
+You can increase the number of `gitaly-ruby` processes on your Gitaly
+server with the following settings.
-If you are running Gitaly [as a remote
-service](#running-gitaly-on-its-own-server) you may want to disable
-the local Gitaly service that runs on your GitLab server by default.
+**For Omnibus GitLab**
-> 'Disabling Gitaly' only makes sense when you run GitLab in a custom
-cluster configuration, where different services run on different
-machines. Disabling Gitaly on all machines in the cluster is not a
-valid configuration.
+1. Edit `/etc/gitlab/gitlab.rb`:
-If you are setting up a GitLab cluster where Gitaly does not need to
-run on all machines, you can disable the Gitaly service in your
-Omnibus installation, add the following line to `/etc/gitlab/gitlab.rb`:
+ ```ruby
+ # Default is 2 workers. The minimum is 2; 1 worker is always reserved as
+ # a passive stand-by.
+ gitaly['ruby_num_workers'] = 4
+ ```
-```ruby
-gitaly['enable'] = false
-```
+1. Save the file and [reconfigure GitLab](../restart_gitlab.md#omnibus-gitlab-reconfigure).
-When you run `gitlab-ctl reconfigure` the Gitaly service will be
-disabled.
+**For installations from source**
-To disable the Gitaly service in a GitLab cluster where you installed
-GitLab from source, add the following to `/etc/default/gitlab` on the
-machine where you want to disable Gitaly.
+1. Edit `/home/git/gitaly/config.toml`:
-```shell
-gitaly_enabled=false
-```
+ ```toml
+ [gitaly-ruby]
+ num_workers = 4
+ ```
-When you run `service gitlab restart` Gitaly will be disabled on this
-particular machine.
+1. Save the file and [restart GitLab](../restart_gitlab.md#installations-from-source).
## Eliminating NFS altogether
@@ -440,19 +455,23 @@ If you are planning to use Gitaly without NFS for your storage needs
and want to eliminate NFS from your environment altogether, there are
a few things that you need to do:
- 1. Make sure the [`git` user home directory](https://docs.gitlab.com/omnibus/settings/configuration.html#moving-the-home-directory-for-a-user) is on local disk.
- 1. Configure [database lookup of SSH keys](../operations/fast_ssh_key_lookup.md)
- to eliminate the need for a shared authorized_keys file.
- 1. Configure [object storage for job artifacts](../job_artifacts.md#using-object-storage)
- including [live tracing](../job_traces.md#new-live-trace-architecture).
- 1. Configure [object storage for LFS objects](../../workflow/lfs/lfs_administration.md#storing-lfs-objects-in-remote-object-storage).
- 1. Configure [object storage for uploads](../uploads.md#using-object-storage-core-only).
-
-NOTE: **Note:** One current feature of GitLab still requires a shared directory (NFS): [GitLab Pages](../../user/project/pages/index.md).
+1. Make sure the [`git` user home directory](https://docs.gitlab.com/omnibus/settings/configuration.html#moving-the-home-directory-for-a-user) is on local disk.
+1. Configure [database lookup of SSH keys](../operations/fast_ssh_key_lookup.md)
+ to eliminate the need for a shared authorized_keys file.
+1. Configure [object storage for job artifacts](../job_artifacts.md#using-object-storage)
+ including [live tracing](../job_traces.md#new-live-trace-architecture).
+1. Configure [object storage for LFS objects](../../workflow/lfs/lfs_administration.md#storing-lfs-objects-in-remote-object-storage).
+1. Configure [object storage for uploads](../uploads.md#using-object-storage-core-only).
+
+NOTE: **Note:**
+One current feature of GitLab that still requires a shared directory (NFS) is
+[GitLab Pages](../../user/project/pages/index.md).
There is [work in progress](https://gitlab.com/gitlab-org/gitlab-pages/issues/196)
to eliminate the need for NFS to support GitLab Pages.
-## Troubleshooting Gitaly in production
+## Troubleshooting
+
+### `gitaly-debug`
Since GitLab 11.6, Gitaly comes with a command-line tool called
`gitaly-debug` that can be run on a Gitaly server to aid in
@@ -462,3 +481,32 @@ Git clone speed for a specific repository on the server.
For an up to date list of sub-commands see [the gitaly-debug
README](https://gitlab.com/gitlab-org/gitaly/blob/master/cmd/gitaly-debug/README.md).
+
+### Client side GRPC logs
+
+Gitaly uses the [gRPC](https://grpc.io/) RPC framework. The Ruby gRPC
+client has its own log file which may contain useful information when
+you are seeing Gitaly errors. You can control the log level of the
+gRPC client with the `GRPC_LOG_LEVEL` environment variable. The
+default level is `WARN`.
+
+### Observing `gitaly-ruby` traffic
+
+[`gitaly-ruby`](#gitaly-ruby) is an internal implementation detail of Gitaly,
+so, there's not that much visibility into what goes on inside
+`gitaly-ruby` processes.
+
+If you have Prometheus set up to scrape your Gitaly process, you can see
+request rates and error codes for individual RPCs in `gitaly-ruby` by
+querying `grpc_client_handled_total`. Strictly speaking, this metric does
+not differentiate between `gitaly-ruby` and other RPCs, but in practice
+(as of GitLab 11.9), all gRPC calls made by Gitaly itself are internal
+calls from the main Gitaly process to one of its `gitaly-ruby` sidecars.
+
+Assuming your `grpc_client_handled_total` counter only observes Gitaly,
+the following query shows you RPCs are (most likely) internally
+implemented as calls to `gitaly-ruby`:
+
+```
+sum(rate(grpc_client_handled_total[5m])) by (grpc_method) > 0
+```
diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md
index 89501f20d99..054fa547704 100644
--- a/doc/administration/monitoring/prometheus/gitlab_metrics.md
+++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md
@@ -34,6 +34,9 @@ The following metrics are available:
| filesystem_writable | Gauge | 9.4 | Whether or not the filesystem is writable |
| filesystem_read_latency_seconds | Gauge | 9.4 | Read latency of a specific filesystem |
| filesystem_readable | Gauge | 9.4 | Whether or not the filesystem is readable |
+| gitlab_cache_misses_total | Counter | 10.2 | Cache read miss |
+| gitlab_cache_operation_duration_seconds | Histogram | 10.2 | Cache access time |
+| gitlab_cache_operations_total | Counter | 12.2 | Cache operations by controller/action |
| http_requests_total | Counter | 9.4 | Rack request count |
| http_request_duration_seconds | Histogram | 9.4 | HTTP response time from rack middleware |
| pipelines_created_total | Counter | 9.4 | Counter of pipelines created |
diff --git a/doc/administration/repository_storage_types.md b/doc/administration/repository_storage_types.md
index 9dea6074a3f..1669f8b128c 100644
--- a/doc/administration/repository_storage_types.md
+++ b/doc/administration/repository_storage_types.md
@@ -105,7 +105,7 @@ question.
To start a migration, enable Hashed Storage for new projects:
1. Go to **Admin > Settings > Repository** and expand the **Repository Storage** section.
-2. Select the **Use hashed storage paths for newly created and renamed projects** checkbox.
+1. Select the **Use hashed storage paths for newly created and renamed projects** checkbox.
Check if the change breaks any existing integration you may have that
either runs on the same machine as your repositories are located, or may login to that machine
@@ -133,7 +133,7 @@ Similar to the migration, to disable Hashed Storage for new
projects:
1. Go to **Admin > Settings > Repository** and expand the **Repository Storage** section.
-2. Uncheck the **Use hashed storage paths for newly created and renamed projects** checkbox.
+1. Uncheck the **Use hashed storage paths for newly created and renamed projects** checkbox.
To schedule a complete rollback, see the
[rake task documentation for storage rollback](raketasks/storage.md#rollback-from-hashed-storage-to-legacy-storage) for instructions.
diff --git a/doc/api/container_registry.md b/doc/api/container_registry.md
index 64ea15bca93..174b93a4f7a 100644
--- a/doc/api/container_registry.md
+++ b/doc/api/container_registry.md
@@ -193,13 +193,13 @@ Examples:
curl --request DELETE --data 'name_regex=[0-9a-z]{40}' --data 'keep_n=5' --data 'older_than=2d' --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"
```
-2. Remove all tags, but keep always the latest 5:
+1. Remove all tags, but keep always the latest 5:
```bash
curl --request DELETE --data 'name_regex=.*' --data 'keep_n=5' --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"
```
-3. Remove all tags that are older than 1 month:
+1. Remove all tags that are older than 1 month:
```bash
curl --request DELETE --data 'name_regex=.*' --data 'older_than=1month' --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/5/registry/repositories/2/tags"
diff --git a/doc/api/lint.md b/doc/api/lint.md
index b9b49f3df27..79f5e629c7f 100644
--- a/doc/api/lint.md
+++ b/doc/api/lint.md
@@ -5,7 +5,7 @@
Checks if your `.gitlab-ci.yml` file is valid.
```
-POST /lint
+POST /ci/lint
```
| Attribute | Type | Required | Description |
diff --git a/doc/api/users.md b/doc/api/users.md
index fdc84826680..b41fd106fc5 100644
--- a/doc/api/users.md
+++ b/doc/api/users.md
@@ -349,6 +349,9 @@ Note that `force_random_password` and `reset_password` take priority
over `password`. In addition, `reset_password` and
`force_random_password` can be used together.
+NOTE: **Note:**
+From [GitLab 12.1](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/29888/), `private_profile` will default to `false`.
+
```
POST /users
```
diff --git a/doc/ci/examples/end_to_end_testing_webdriverio/index.md b/doc/ci/examples/end_to_end_testing_webdriverio/index.md
index 38fcf05f519..38d0d86ffa2 100644
--- a/doc/ci/examples/end_to_end_testing_webdriverio/index.md
+++ b/doc/ci/examples/end_to_end_testing_webdriverio/index.md
@@ -143,7 +143,7 @@ Which brings us to the exciting part: how do we run this in GitLab CI/CD? There
need to do for this:
1. Set up [CI/CD jobs](../../yaml/README.md#introduction) that actually have a browser available.
-2. Update our WebdriverIO configuration to use those browsers to visit the review apps.
+1. Update our WebdriverIO configuration to use those browsers to visit the review apps.
For the scope of this article, we've defined an additional [CI/CD stage](../../yaml/README.md#stages)
`confidence-check` that is executed _after_ the stage that deploys the review app. It uses the `node:latest` [Docker
diff --git a/doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md b/doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md
index a13857bee25..f63b17a9e5a 100644
--- a/doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md
+++ b/doc/ci/merge_request_pipelines/pipelines_for_merged_results/index.md
@@ -6,7 +6,6 @@ last_update: 2019-07-03
# Pipelines for Merged Results **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/7380) in [GitLab Premium](https://about.gitlab.com/pricing/) 11.10.
-> This feature is disabled by default until we resolve issues with [contention handling](https://gitlab.com/gitlab-org/gitlab-ee/issues/11222), but [can be enabled manually](#enabling-pipelines-for-merged-results).
It's possible for your source and target branches to diverge, which can result
in the scenario that source branch's pipeline was green, the target's pipeline was green,
@@ -25,8 +24,10 @@ new ref and a pipeline for this ref validates the result prior to merging.
There are some cases where creating a combined ref is not possible or not wanted.
For example, a source branch that has conflicts with the target branch
-or a merge request that is still in WIP status. In this case, the merge request pipeline falls back to a "detached" state
-and runs on the source branch ref as if it was a regular pipeline.
+or a merge request that is still in WIP status. In this case,
+GitLab doesn't create a merge commit and the pipeline runs on source branch, instead,
+which is a default behavior of [Pipelines for merge requests](../index.md)
+ i.e. `detached` label is shown to the pipelines.
The detached state serves to warn you that you are working in a situation
subjected to merge problems, and helps to highlight that you should
@@ -42,7 +43,7 @@ Pipelines for merged results require:
In addition, pipelines for merged results have the following limitations:
- Forking/cross-repo workflows are not currently supported. To follow progress,
- see [#9713](https://gitlab.com/gitlab-org/gitlab-ee/issues/9713).
+ see [#11934](https://gitlab.com/gitlab-org/gitlab-ee/issues/11934).
- This feature is not available for
[fast forward merges](../../../user/project/merge_requests/fast_forward_merge.md) yet.
To follow progress, see [#58226](https://gitlab.com/gitlab-org/gitlab-ce/issues/58226).
diff --git a/doc/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/img/merge_train_position_v12_0.png b/doc/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/img/merge_train_position_v12_0.png
new file mode 100644
index 00000000000..70916bc0e00
--- /dev/null
+++ b/doc/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/img/merge_train_position_v12_0.png
Binary files differ
diff --git a/doc/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md b/doc/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md
index 57358434c02..44cbcde264c 100644
--- a/doc/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md
+++ b/doc/ci/merge_request_pipelines/pipelines_for_merged_results/merge_trains/index.md
@@ -6,7 +6,6 @@ last_update: 2019-07-03
# Merge Trains **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/9186) in [GitLab Premium](https://about.gitlab.com/pricing/) 12.0.
-> This feature is disabled by default, but [can be enabled manually](#enabling-merge-trains).
[Pipelines for merged results](../index.md#pipelines-for-merged-results-premium) introduces
running a build on the result of the merged code prior to merging, as a way to keep master green.
@@ -33,35 +32,40 @@ Merge trains have the following requirements and limitations:
- This feature requires that
[pipelines for merged results](../index.md#pipelines-for-merged-results-premium) are
**configured properly**.
-- Each merge train can generate a merge ref and run a pipeline **one at a time**.
- We plan to make the pipelines for merged results
- [run in parallel](https://gitlab.com/gitlab-org/gitlab-ee/issues/11222) in a
- future release.
+- Each merge train can run a maximum of **four** pipelines in parallel.
+ If more than four merge requests are added to the merge train, the merge requests
+ will be queued until a slot in the merge train is free. There is no limit to the
+ number of merge requests that can be queued.
+- This feature does not support [squash and merge](../../../../user/project/merge_requests/squash_and_merge.md).
-## Enabling Merge Trains
-
-To enable merge trains at the project level:
-
-1. Visit your project's **Settings > General** and expand **Merge requests**.
-1. Check **Allow merge trains**.
-1. Click **Save changes** button.
-
-![Merge request pipeline config](img/merge_train_config_v12_0.png)
+<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
+Watch this video for a demonstration on [how parallel execution
+of Merge Trains can prevent commits from breaking the default
+branch](https://www.youtube.com/watch?v=D4qCqXgZkHQ).
## How to add a merge request to a merge train
To add a merge request to a merge train:
-1. Click "Start/Add merge train" button in a merge request
+1. Visit a merge request.
+1. Click the **Start/Add to merge train** button.
![Start merge train](img/merge_train_start_v12_0.png)
## How to remove a merge request from a merge train
-1. Click "Remove from merge train" button in the merge request widget.
+1. Visit a merge request.
+1. Click the **Remove from merge train** button.
![Cancel merge train](img/merge_train_cancel_v12_0.png)
+## How to view a merge request's current position on the merge train
+
+After a merge request has been added to the merge train, the merge request's
+current position will be displayed under the pipeline widget:
+
+![Merge train position indicator](img/merge_train_position_v12_0.png)
+
## Start/Add to merge train when pipeline succeeds
You can add a merge request to a merge train only when the latest pipeline in the
@@ -70,7 +74,8 @@ the merge request to a train because the current change of the merge request may
be broken thus it could affect the following merge requests.
In this case, you can schedule to add the merge request to a merge train **when the latest
-pipeline succeeds**. You can see the following button instead of the regular "Start/Add merge train"
+pipeline succeeds** (This pipeline is [Pipelines for merged results](../index.md), not Pipelines for merge train).
+You can see the following button instead of the regular **Start/Add to merge train**
button while the latest pipeline is running.
![Add to merge train when pipeline succeeds](img/merge_train_start_when_pipeline_succeeds_v12_0.png)
diff --git a/doc/development/README.md b/doc/development/README.md
index a74770ae383..4f16473e7e2 100644
--- a/doc/development/README.md
+++ b/doc/development/README.md
@@ -63,6 +63,7 @@ description: 'Learn how to contribute to GitLab.'
- [Routing](routing.md)
- [Repository mirroring](repository_mirroring.md)
- [Git LFS](lfs.md)
+- [Developing against interacting components or features](interacting_components.md)
## Performance guides
diff --git a/doc/development/chaos_endpoints.md b/doc/development/chaos_endpoints.md
index b3406275937..eb6dde2d24e 100644
--- a/doc/development/chaos_endpoints.md
+++ b/doc/development/chaos_endpoints.md
@@ -36,6 +36,10 @@ Replace `secret` with your own secret token.
Once you have enabled the chaos endpoints and restarted the application, you can start testing using the endpoints.
+By default, when invoking a chaos endpoint, the web worker process which receives the request will handle it. This means, for example, that if the Kill
+operation is invoked, the Puma or Unicorn worker process handling the request will be killed. To test these operations in Sidekiq, the `async` parameter on
+each endpoint can be set to `true`. This will run the chaos process in a Sidekiq worker.
+
## Memory leaks
To simulate a memory leak in your application, use the `/-/chaos/leakmem` endpoint.
@@ -47,12 +51,14 @@ The memory is not retained after the request finishes. Once the request has comp
GET /-/chaos/leakmem
GET /-/chaos/leakmem?memory_mb=1024
GET /-/chaos/leakmem?memory_mb=1024&duration_s=50
+GET /-/chaos/leakmem?memory_mb=1024&duration_s=50&async=true
```
-| Attribute | Type | Required | Description |
-| ------------ | ------- | -------- | ---------------------------------------------------------------------------------- |
-| `memory_mb` | integer | no | How much memory, in MB, should be leaked. Defaults to 100MB. |
+| Attribute | Type | Required | Description |
+| ------------ | ------- | -------- | ------------------------------------------------------------------------------------ |
+| `memory_mb` | integer | no | How much memory, in MB, should be leaked. Defaults to 100MB. |
| `duration_s` | integer | no | Minimum duration_s, in seconds, that the memory should be retained. Defaults to 30s. |
+| `async` | boolean | no | Set to true to leak memory in a Sidekiq background worker process |
```bash
curl http://localhost:3000/-/chaos/leakmem?memory_mb=1024&duration_s=10 --header 'X-Chaos-Secret: secret'
@@ -69,11 +75,13 @@ If you're using Unicorn, this is done by killing the worker process.
```
GET /-/chaos/cpu_spin
GET /-/chaos/cpu_spin?duration_s=50
+GET /-/chaos/cpu_spin?duration_s=50&async=true
```
| Attribute | Type | Required | Description |
| ------------ | ------- | -------- | --------------------------------------------------------------------- |
| `duration_s` | integer | no | Duration, in seconds, that the core will be utilised. Defaults to 30s |
+| `async` | boolean | no | Set to true to consume CPU in a Sidekiq background worker process |
```bash
curl http://localhost:3000/-/chaos/cpu_spin?duration_s=60 --header 'X-Chaos-Secret: secret'
@@ -91,12 +99,14 @@ If you're using Unicorn, this is done by killing the worker process.
```
GET /-/chaos/db_spin
GET /-/chaos/db_spin?duration_s=50
+GET /-/chaos/db_spin?duration_s=50&async=true
```
-| Attribute | Type | Required | Description |
-| ------------ | ------- | -------- | --------------------------------------------------------------------- |
-| `interval_s` | float | no | Interval, in seconds, for every DB request. Defaults to 1s |
-| `duration_s` | integer | no | Duration, in seconds, that the core will be utilised. Defaults to 30s |
+| Attribute | Type | Required | Description |
+| ------------ | ------- | -------- | --------------------------------------------------------------------------- |
+| `interval_s` | float | no | Interval, in seconds, for every DB request. Defaults to 1s |
+| `duration_s` | integer | no | Duration, in seconds, that the core will be utilised. Defaults to 30s |
+| `async` | boolean | no | Set to true to perform the operation in a Sidekiq background worker process |
```bash
curl http://localhost:3000/-/chaos/db_spin?interval_s=1&duration_s=60 --header 'X-Chaos-Secret: secret'
@@ -112,11 +122,13 @@ As with the CPU Spin endpoint, this may lead to your request timing out if durat
```
GET /-/chaos/sleep
GET /-/chaos/sleep?duration_s=50
+GET /-/chaos/sleep?duration_s=50&async=true
```
| Attribute | Type | Required | Description |
| ------------ | ------- | -------- | ---------------------------------------------------------------------- |
| `duration_s` | integer | no | Duration, in seconds, that the request will sleep for. Defaults to 30s |
+| `async` | boolean | no | Set to true to sleep in a Sidekiq background worker process |
```bash
curl http://localhost:3000/-/chaos/sleep?duration_s=60 --header 'X-Chaos-Secret: secret'
@@ -132,8 +144,13 @@ Since this endpoint uses the `KILL` signal, the worker is not given a chance to
```
GET /-/chaos/kill
+GET /-/chaos/kill?async=true
```
+| Attribute | Type | Required | Description |
+| ------------ | ------- | -------- | ---------------------------------------------------------------------- |
+| `async` | boolean | no | Set to true to kill a Sidekiq background worker process |
+
```bash
curl http://localhost:3000/-/chaos/kill --header 'X-Chaos-Secret: secret'
curl http://localhost:3000/-/chaos/kill?token=secret
diff --git a/doc/development/code_review.md b/doc/development/code_review.md
index e9c8b193309..a9a46c62d38 100644
--- a/doc/development/code_review.md
+++ b/doc/development/code_review.md
@@ -341,8 +341,7 @@ Enterprise Edition instance. This has some implications:
- [Background migrations](background_migrations.md) run in Sidekiq, and
should only be done for migrations that would take an extreme amount of
time at GitLab.com scale.
-1. **Sidekiq workers**
- [cannot change in a backwards-incompatible way](sidekiq_style_guide.md#removing-or-renaming-queues):
+1. **Sidekiq workers** [cannot change in a backwards-incompatible way](sidekiq_style_guide.md#removing-or-renaming-queues):
1. Sidekiq queues are not drained before a deploy happens, so there will be
workers in the queue from the previous version of GitLab.
1. If you need to change a method signature, try to do so across two releases,
diff --git a/doc/development/documentation/improvement-workflow.md b/doc/development/documentation/improvement-workflow.md
index a12c3d5ea7b..80fbd4b6427 100644
--- a/doc/development/documentation/improvement-workflow.md
+++ b/doc/development/documentation/improvement-workflow.md
@@ -52,9 +52,9 @@ To request a post-merge review, [create an issue for one using the Doc Review te
**3. Maintainer**
1. Review by assigned maintainer, who can always request/require the above reviews. Maintainer review can occur before or after a technical writer review.
-2. Ensure a release milestone of the format XX.Y is set. If the freeze for that release has begun, add the label `pick into <XX.Y>` unless this change is not required for the release. In that case, simply change the milestone.
-3. If EE and CE MRs exist, merge the EE MR first, then the CE MR.
-4. After merging, if there has not been a technical writer review and an issue for a follow-up review was not already created and linked from the MR, [create the issue using the Doc Review template](https://gitlab.com/gitlab-org/gitlab-ce/issues/new?issuable_template=Doc%20Review) and link it from the MR.
+1. Ensure a release milestone of the format XX.Y is set. If the freeze for that release has begun, add the label `pick into <XX.Y>` unless this change is not required for the release. In that case, simply change the milestone.
+1. If EE and CE MRs exist, merge the EE MR first, then the CE MR.
+1. After merging, if there has not been a technical writer review and an issue for a follow-up review was not already created and linked from the MR, [create the issue using the Doc Review template](https://gitlab.com/gitlab-org/gitlab-ce/issues/new?issuable_template=Doc%20Review) and link it from the MR.
## Other ways to help
diff --git a/doc/development/documentation/styleguide.md b/doc/development/documentation/styleguide.md
index 1ca965f8ae9..ccf1deefd91 100644
--- a/doc/development/documentation/styleguide.md
+++ b/doc/development/documentation/styleguide.md
@@ -44,9 +44,9 @@ Include any media types/sources if the content is relevant to readers. You can f
In the software industry, it is a best practice to organize documentatioin in different types. For example, [Divio recommends](https://www.divio.com/blog/documentation/):
1. Tutorials
-2. How-to guides
-3. Explanation
-4. Reference (for example, a glossary)
+1. How-to guides
+1. Explanation
+1. Reference (for example, a glossary)
At GitLab, we have so many product changes in our monthly releases that we can't afford to continually update multiple types of information.
If we have multiple types, the information will become outdated. Therefore, we have a [single template](structure.md) for documentation.
@@ -142,9 +142,9 @@ The table below shows what kind of documentation goes where.
### Working with directories and files
1. When you create a new directory, always start with an `index.md` file.
- Do not use another file name and **do not** create `README.md` files.
+ Do not use another file name and **do not** create `README.md` files.
1. **Do not** use special characters and spaces, or capital letters in file names,
- directory names, branch names, and anything that generates a path.
+ directory names, branch names, and anything that generates a path.
1. When creating a new document and it has more than one word in its name,
make sure to use underscores instead of spaces or dashes (`-`). For example,
a proper naming would be `import_projects_from_github.md`. The same rule
diff --git a/doc/development/fe_guide/frontend_faq.md b/doc/development/fe_guide/frontend_faq.md
index e4225f2bc39..0d2aeffeac0 100644
--- a/doc/development/fe_guide/frontend_faq.md
+++ b/doc/development/fe_guide/frontend_faq.md
@@ -5,12 +5,12 @@
1. **You talk about Frontend FAQ.**
Please share links to it whenever applicable, so more eyes catch when content
gets outdated.
-2. **Keep it short and simple.**
+1. **Keep it short and simple.**
Whenever an answer needs more than two sentences it does not belong here.
-3. **Provide background when possible.**
+1. **Provide background when possible.**
Linking to relevant source code, issue / epic, or other documentation helps
to understand the answer.
-4. **If you see something, do something.**
+1. **If you see something, do something.**
Please remove or update any content that is outdated as soon as you see it.
## FAQ
diff --git a/doc/development/fe_guide/style_guide_js.md b/doc/development/fe_guide/style_guide_js.md
index b50159c2b75..18ef754642d 100644
--- a/doc/development/fe_guide/style_guide_js.md
+++ b/doc/development/fe_guide/style_guide_js.md
@@ -548,7 +548,7 @@ Please check this [rules][eslint-plugin-vue-rules] for more documentation.
<component @click="eventHandler"/>
```
-2. Shorthand `:` is preferable over `v-bind`
+1. Shorthand `:` is preferable over `v-bind`
```javascript
// bad
@@ -558,7 +558,7 @@ Please check this [rules][eslint-plugin-vue-rules] for more documentation.
<component :class="btn"/>
```
-3. Shorthand `#` is preferable over `v-slot`
+1. Shorthand `#` is preferable over `v-slot`
```javascript
// bad
diff --git a/doc/development/fe_guide/style_guide_scss.md b/doc/development/fe_guide/style_guide_scss.md
index 5220c9eeea3..f895cfd36ac 100644
--- a/doc/development/fe_guide/style_guide_scss.md
+++ b/doc/development/fe_guide/style_guide_scss.md
@@ -35,7 +35,7 @@ New utility classes should be added to [`utilities.scss`](https://gitlab.com/git
We recommend a "utility-first" approach.
1. Start with utility classes.
-2. If composing utility classes into a component class removes code duplication and encapsulates a clear responsibility, do it.
+1. If composing utility classes into a component class removes code duplication and encapsulates a clear responsibility, do it.
This encourages an organic growth of component classes and prevents the creation of one-off unreusable classes. Also, the kind of classes that emerge from "utility-first" tend to be design-centered (e.g. `.button`, `.alert`, `.card`) rather than domain-centered (e.g. `.security-report-widget`, `.commit-header-icon`).
diff --git a/doc/development/import_export.md b/doc/development/import_export.md
index 64c91f151c5..4c78c62f5f5 100644
--- a/doc/development/import_export.md
+++ b/doc/development/import_export.md
@@ -229,8 +229,8 @@ meaning that we want to bump the version up in the next version (or patch releas
For example:
1. Add rename to `RelationRenameService` in X.Y
-2. Remove it from `RelationRenameService` in X.Y + 1
-3. Bump Import/Export version in X.Y + 1
+1. Remove it from `RelationRenameService` in X.Y + 1
+1. Bump Import/Export version in X.Y + 1
```ruby
module Gitlab
diff --git a/doc/development/interacting_components.md b/doc/development/interacting_components.md
new file mode 100644
index 00000000000..74d52d808e2
--- /dev/null
+++ b/doc/development/interacting_components.md
@@ -0,0 +1,29 @@
+# Developing against interacting components or features
+
+It's not uncommon that a single code change can reflect and interact with multiple parts of GitLab
+codebase. Furthermore, an existing feature might have an underlying integration or behavior that
+might go unnoticed even by reviewers and maintainers.
+
+The goal of this section is to briefly list interacting pieces to think about
+when making _backend_ changes that might involve multiple features or [components](architecture.md#components).
+
+## Uploads
+
+GitLab supports uploads to [object storage]. That means every feature and
+change that affects uploads should also be tested against [object storage],
+which is _not_ enabled by default in [GDK](https://gitlab.com/gitlab-org/gitlab-development-kit).
+
+When working on a related feature, make sure to enable and test it
+against [Minio](https://gitlab.com/gitlab-org/gitlab-development-kit/blob/master/doc/howto/object_storage.md).
+
+See also [File Storage in GitLab](file_storage.md).
+
+## Merge requests
+
+### Forks
+
+GitLab supports a great amount of features for [merge requests](../user/project/merge_requests/index.md). One
+of them is the ability to create merge requests from and to [forks](../gitlab-basics/fork-project.md),
+which should also be highly considered and tested upon development phase.
+
+[object storage]: https://docs.gitlab.com/charts/advanced/external-object-storage/
diff --git a/doc/development/licensed_feature_availability.md b/doc/development/licensed_feature_availability.md
index 80ec7b8c0cf..29e4ace157b 100644
--- a/doc/development/licensed_feature_availability.md
+++ b/doc/development/licensed_feature_availability.md
@@ -14,7 +14,7 @@ it should be restricted on namespace scope.
1. Add the feature symbol on `EES_FEATURES`, `EEP_FEATURES` or `EEU_FEATURES` constants in
`ee/app/models/license.rb`. Note on `ee/app/models/ee/namespace.rb` that _Bronze_ GitLab.com
features maps to on-premise _EES_, _Silver_ to _EEP_ and _Gold_ to _EEU_.
-2. Check using:
+1. Check using:
```ruby
project.feature_available?(:feature_symbol)
@@ -29,8 +29,8 @@ the instance license.
1. Add the feature symbol on `EES_FEATURES`, `EEP_FEATURES` or `EEU_FEATURES` constants in
`ee/app/models/license.rb`.
-2. Add the same feature symbol to `GLOBAL_FEATURES`
-3. Check using:
+1. Add the same feature symbol to `GLOBAL_FEATURES`
+1. Check using:
```ruby
License.feature_available?(:feature_symbol)
diff --git a/doc/development/performance.md b/doc/development/performance.md
index 8b569a677b6..14b3f8204d2 100644
--- a/doc/development/performance.md
+++ b/doc/development/performance.md
@@ -267,7 +267,7 @@ piece of code is worth optimizing. The only two things you can do are:
1. Think about what the code does, how it's used, how many times it's called and
how much time is spent in it relative to the total execution time (e.g., the
total time spent in a web request).
-2. Ask others (preferably in the form of an issue).
+1. Ask others (preferably in the form of an issue).
Some examples of changes that aren't really important/worth the effort:
@@ -285,10 +285,10 @@ directly in a web request as much as possible. This has numerous benefits such
as:
1. An error won't prevent the request from completing.
-2. The process being slow won't affect the loading time of a page.
-3. In case of a failure it's easy to re-try the process (Sidekiq takes care of
+1. The process being slow won't affect the loading time of a page.
+1. In case of a failure it's easy to re-try the process (Sidekiq takes care of
this automatically).
-4. By isolating the code from a web request it will hopefully be easier to test
+1. By isolating the code from a web request it will hopefully be easier to test
and maintain.
It's especially important to use Sidekiq as much as possible when dealing with
diff --git a/doc/development/policies.md b/doc/development/policies.md
index c4ac42bb40a..833b0acb13e 100644
--- a/doc/development/policies.md
+++ b/doc/development/policies.md
@@ -89,8 +89,8 @@ Each line represents a rule that was evaluated. There are a few things to note:
1. The `-` or `+` symbol indicates whether the rule block was evaluated to be
`false` or `true`, respectively.
-2. The number inside the brackets indicates the score.
-3. The last part of the line (e.g. `@john : Issue/1`) shows the username
+1. The number inside the brackets indicates the score.
+1. The last part of the line (e.g. `@john : Issue/1`) shows the username
and subject for that rule.
Here you can see that the first four rules were evaluated `false` for
diff --git a/doc/development/testing_guide/end_to_end/page_objects.md b/doc/development/testing_guide/end_to_end/page_objects.md
index 29ad49403fe..52957d1a1ab 100644
--- a/doc/development/testing_guide/end_to_end/page_objects.md
+++ b/doc/development/testing_guide/end_to_end/page_objects.md
@@ -27,7 +27,7 @@ When someone later changes `t.text_field :login` in the view associated with
this page to `t.text_field :username` it will generate a different field
identifier, what would effectively break all tests.
-Because we are using `Page::Main::Login.act { sign_in_using_credentials }`
+Because we are using `Page::Main::Login.perform(&:sign_in_using_credentials)`
everywhere, when we want to sign into GitLab, the page object is the single
source of truth, and we will need to update `fill_in :user_login`
to `fill_in :user_username` only in a one place.
diff --git a/doc/development/testing_guide/end_to_end/quick_start_guide.md b/doc/development/testing_guide/end_to_end/quick_start_guide.md
index 3bbf8feab39..14a169dcc1d 100644
--- a/doc/development/testing_guide/end_to_end/quick_start_guide.md
+++ b/doc/development/testing_guide/end_to_end/quick_start_guide.md
@@ -116,9 +116,9 @@ end
Below are the steps that the test covers:
1. The test finds the 'Edit' link for the labels and clicks on it.
-2. Then it fills in the 'Assign labels' input field with the value 'animal::dolphin' and press enters.
-3. Then it clicks in the content body to apply the label and refreshes the page.
-4. Finally, the expectations check that the previous scoped label was removed and that the new one was added.
+1. Then it fills in the 'Assign labels' input field with the value 'animal::dolphin' and press enters.
+1. Then it clicks in the content body to apply the label and refreshes the page.
+1. Finally, the expectations check that the previous scoped label was removed and that the new one was added.
Let's now see how the second test case would look.
@@ -144,9 +144,9 @@ end
Below are the steps that the test covers:
1. The test finds the 'Edit' link for the labels and clicks on it.
-2. Then it fills in the 'Assign labels' input field with the value 'plant::orchid' and press enters.
-3. Then it clicks in the content body to apply the label and refreshes the page.
-4. Finally, the expectations check that both scoped labels are present.
+1. Then it fills in the 'Assign labels' input field with the value 'plant::orchid' and press enters.
+1. Then it clicks in the content body to apply the label and refreshes the page.
+1. Finally, the expectations check that both scoped labels are present.
> Similar to the previous test, this one is also very straightforward, but there is some code duplication. Let's address it.
@@ -290,7 +290,7 @@ As already mentioned in the [best practices](best_practices.md) document, end-to
Some improvements that we could make in our test suite to optimize its time to run are:
1. Having a single test case (an `it` block) that exercises both scenarios to avoid "wasting" time in the tests' pre-conditions, instead of having two different test cases.
-2. Making the selection of labels more performant by allowing for the selection of more than one label in the same reusable method.
+1. Making the selection of labels more performant by allowing for the selection of more than one label in the same reusable method.
Let's look at a suggestion that addresses the above points, one by one:
@@ -332,8 +332,8 @@ To address point 1, we changed the test implementation from two `it` blocks into
> Notice that the implementation of the new and unique `it` block had to change a little bit. Below we describe in details what it does.
1. It selects two scoped labels simultaneously, one from the same scope of the one already applied in the issue during the setup phase (in the `before` block), and another one from a different scope.
-2. It asserts that the correct labels are visible in the `labels_block`, and that the labels were correctly added and removed;
-3. Finally, the `select_label_and_refresh` method is changed to `select_labels_and_refresh`, which accepts an array of labels instead of a single label, and it iterates on them for faster label selection (this is what is used in step 1 explained above.)
+1. It asserts that the correct labels are visible in the `labels_block`, and that the labels were correctly added and removed;
+1. Finally, the `select_label_and_refresh` method is changed to `select_labels_and_refresh`, which accepts an array of labels instead of a single label, and it iterates on them for faster label selection (this is what is used in step 1 explained above.)
### 7. Resources
@@ -542,9 +542,9 @@ end
Notice that we have not only moved the `select_labels_and_refresh` method, but we have also changed its implementation to:
1. Click the `:edit_link_labels` element previously defined, instead of using `find('.block.labels .edit-link').click`
-2. Use `within_element(:dropdown_menu_labels, text: label)`, and inside of it, we call `send_keys_to_element(:dropdown_input_field, [label, :enter])`, which is a method that we will implement in the `QA::Page::Base` class to replace `find('.dropdown-menu-labels .dropdown-input-field').send_keys [label, :enter]`
-3. Use `click_body` after iterating on each label, instead of using `find('#content-body').click`
-4. Iterate on every label again, and then we use `has_element?(:labels_block, text: label)` after clicking the page body (which applies the labels), and before refreshing the page, to avoid test flakiness due to refreshing too fast.
+1. Use `within_element(:dropdown_menu_labels, text: label)`, and inside of it, we call `send_keys_to_element(:dropdown_input_field, [label, :enter])`, which is a method that we will implement in the `QA::Page::Base` class to replace `find('.dropdown-menu-labels .dropdown-input-field').send_keys [label, :enter]`
+1. Use `click_body` after iterating on each label, instead of using `find('#content-body').click`
+1. Iterate on every label again, and then we use `has_element?(:labels_block, text: label)` after clicking the page body (which applies the labels), and before refreshing the page, to avoid test flakiness due to refreshing too fast.
##### Details of `text_of_labels_block`
diff --git a/doc/development/testing_guide/frontend_testing.md b/doc/development/testing_guide/frontend_testing.md
index c909745b1ab..ff28c2ea5e2 100644
--- a/doc/development/testing_guide/frontend_testing.md
+++ b/doc/development/testing_guide/frontend_testing.md
@@ -80,18 +80,20 @@ describe('Component', () => {
Remember that the performance of each test depends on the environment.
### Manual module mocks
+
Jest supports [manual module mocks](https://jestjs.io/docs/en/manual-mocks) by placing a mock in a `__mocks__/` directory next to the source module. **Don't do this.** We want to keep all of our test-related code in one place (the `spec/` folder), and the logic that Jest uses to apply mocks from `__mocks__/` is rather inconsistent.
Instead, our test runner detects manual mocks from `spec/frontend/mocks/`. Any mock placed here is automatically picked up and injected whenever you import its source module.
- Files in `spec/frontend/mocks/ce` will mock the corresponding CE module from `app/assets/javascripts`, mirroring the source module's path.
- - Example: `spec/frontend/mocks/ce/lib/utils/axios_utils` will mock the module `~/lib/utils/axios_utils`.
+ - Example: `spec/frontend/mocks/ce/lib/utils/axios_utils` will mock the module `~/lib/utils/axios_utils`.
- Files in `spec/frontend/mocks/node` will mock NPM packages of the same name or path.
- We don't support mocking EE modules yet.
If a mock is found for which a source module doesn't exist, the test suite will fail. 'Virtual' mocks, or mocks that don't have a 1-to-1 association with a source module, are not supported yet.
#### Writing a mock
+
Create a JS module in the appropriate place in `spec/frontend/mocks/`. That's it. It will automatically mock its source package in all tests.
Make sure that your mock's export has the same format as the mocked module. So, if you're mocking a CommonJS module, you'll need to use `module.exports` instead of the ES6 `export`.
@@ -99,14 +101,15 @@ Make sure that your mock's export has the same format as the mocked module. So,
It might be useful for a mock to expose a property that indicates if the mock was loaded. This way, tests can assert the presence of a mock without calling any logic and causing side-effects. The `~/lib/utils/axios_utils` module mock has such a property, `isMock`, that is `true` in the mock and undefined in the original class. Jest's mock functions also have a `mock` property that you can test.
#### Bypassing mocks
+
If you ever need to import the original module in your tests, use [`jest.requireActual()`](https://jestjs.io/docs/en/jest-object#jestrequireactualmodulename) (or `jest.requireActual().default` for the default export). The `jest.mock()` and `jest.unmock()` won't have an effect on modules that have a manual mock, because mocks are imported and cached before any tests are run.
#### Keep mocks light
+
Global mocks introduce magic and can affect how modules are imported in your tests. Try to keep them as light as possible and dependency-free. A global mock should be useful for any unit test. For example, the `axios_utils` and `jquery` module mocks throw an error when an HTTP request is attempted, since this is useful behaviour in &gt;99% of tests.
When in doubt, construct mocks in your test file using [`jest.mock()`](https://jestjs.io/docs/en/jest-object#jestmockmodulename-factory-options), [`jest.spyOn()`](https://jestjs.io/docs/en/jest-object#jestspyonobject-methodname), etc.
-
## Karma test suite
GitLab uses the [Karma][karma] test runner with [Jasmine] as its test
@@ -462,7 +465,7 @@ See this [section][vue-test].
For running the frontend tests, you need the following commands:
-- `rake karma:fixtures` (re-)generates [fixtures](#frontend-test-fixtures).
+- `rake frontend:fixtures` (re-)generates [fixtures](#frontend-test-fixtures).
- `yarn test` executes the tests.
As long as the fixtures don't change, `yarn test` is sufficient (and saves you some time).
@@ -515,8 +518,8 @@ Information on setting up and running RSpec integration tests with
Code that is added to HAML templates (in `app/views/`) or makes Ajax requests to the backend has tests that require HTML or JSON from the backend.
Fixtures for these tests are located at:
-- `spec/javascripts/fixtures/`, for running tests in CE.
-- `ee/spec/javascripts/fixtures/`, for running tests in EE.
+- `spec/frontend/fixtures/`, for running tests in CE.
+- `ee/spec/frontend/fixtures/`, for running tests in EE.
Fixture files in:
@@ -527,7 +530,7 @@ The following are examples of tests that work for both Karma and Jest:
```javascript
it('makes a request', () => {
- const responseBody = getJSONFixture('some/fixture.json'); // loads spec/javascripts/fixtures/some/fixture.json
+ const responseBody = getJSONFixture('some/fixture.json'); // loads spec/frontend/fixtures/some/fixture.json
axiosMock.onGet(endpoint).reply(200, responseBody);
myButton.click();
@@ -536,7 +539,7 @@ it('makes a request', () => {
});
it('uses some HTML element', () => {
- loadFixtures('some/page.html'); // loads spec/javascripts/fixtures/some/page.html and adds it to the DOM
+ loadFixtures('some/page.html'); // loads spec/frontend/fixtures/some/page.html and adds it to the DOM
const element = document.getElementById('#my-id');
@@ -544,12 +547,12 @@ it('uses some HTML element', () => {
});
```
-HTML and JSON fixtures are generated from backend views and controllers using RSpec (see `spec/javascripts/fixtures/*.rb`).
+HTML and JSON fixtures are generated from backend views and controllers using RSpec (see `spec/frontend/fixtures/*.rb`).
For each fixture, the content of the `response` variable is stored in the output file.
This variable gets automagically set if the test is marked as `type: :request` or `type: :controller`.
-Fixtures are regenerated using the `bin/rake karma:fixtures` command but you can also generate them individually,
-for example `bin/rspec spec/javascripts/fixtures/merge_requests.rb`.
+Fixtures are regenerated using the `bin/rake frontend:fixtures` command but you can also generate them individually,
+for example `bin/rspec spec/frontend/fixtures/merge_requests.rb`.
When creating a new fixture, it often makes sense to take a look at the corresponding tests for the endpoint in `(ee/)spec/controllers/` or `(ee/)spec/requests/`.
## Gotchas
diff --git a/doc/integration/elasticsearch.md b/doc/integration/elasticsearch.md
index 20caac4cb74..626bd259ed6 100644
--- a/doc/integration/elasticsearch.md
+++ b/doc/integration/elasticsearch.md
@@ -354,6 +354,8 @@ There are several rake tasks available to you via the command line:
- Does the same thing as `sudo gitlab-rake gitlab:elastic:create_empty_index`
- [sudo gitlab-rake gitlab:elastic:index_snippets](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/ee/lib/tasks/gitlab/elastic.rake)
- Performs an Elasticsearch import that indexes the snippets data.
+- [sudo gitlab-rake gitlab:elastic:projects_not_indexed](https://gitlab.com/gitlab-org/gitlab-ee/blob/master/ee/lib/tasks/gitlab/elastic.rake)
+ - Displays which projects are not indexed.
### Environment Variables
@@ -469,6 +471,10 @@ Here are some common pitfalls and how to overcome them:
The more data present in your GitLab instance, the longer the indexing process takes.
+- **There are some projects that weren't indexed, but we don't know which ones**
+
+ You can run `sudo gitlab-rake gitlab:elastic:projects_not_indexed` to display projects that aren't indexed.
+
- **No new data is added to the Elasticsearch index when I push code**
When performing the initial indexing of blobs, we lock all projects until the project finishes indexing. It could
diff --git a/doc/integration/jenkins_deprecated.md b/doc/integration/jenkins_deprecated.md
index eae705c9637..bac89ae2dc6 100644
--- a/doc/integration/jenkins_deprecated.md
+++ b/doc/integration/jenkins_deprecated.md
@@ -19,7 +19,7 @@ Requirements:
## Jenkins
1. Install [GitLab Hook plugin](https://wiki.jenkins.io/display/JENKINS/GitLab+Hook+Plugin)
-2. Set up jenkins project
+1. Set up jenkins project
![screen](img/jenkins_project.png)
diff --git a/doc/integration/jira_development_panel.md b/doc/integration/jira_development_panel.md
index 60c7bdabf93..5e906e5af16 100644
--- a/doc/integration/jira_development_panel.md
+++ b/doc/integration/jira_development_panel.md
@@ -59,7 +59,7 @@ There are no special requirements if you are using GitLab.com.
![GitLab Application setup](img/jira_dev_panel_gl_setup_1.png)
- Check `api` in the Scopes section.
-2. Click `Save application`. You will see the generated 'Application Id' and 'Secret' values.
+1. Click `Save application`. You will see the generated 'Application Id' and 'Secret' values.
Copy these values that you will use on the Jira configuration side.
## Jira Configuration
@@ -70,7 +70,7 @@ There are no special requirements if you are using GitLab.com.
![Jira DVCS from Dashboard](img/jira_dev_panel_jira_setup_1.png)
-2. Complete the form
+1. Complete the form
Select GitHub Enterprise for the `Host` field.
@@ -92,7 +92,7 @@ There are no special requirements if you are using GitLab.com.
Ensure that the rest of the checkboxes are checked.
-3. Click `Add` to complete and create the integration.
+1. Click `Add` to complete and create the integration.
Jira takes up to a few minutes to know about (import behind the scenes) all the commits and branches
for all the projects in the GitLab group you specified in the previous step. These are refreshed
diff --git a/doc/subscriptions/index.md b/doc/subscriptions/index.md
index 745a2253e84..68e62fff106 100644
--- a/doc/subscriptions/index.md
+++ b/doc/subscriptions/index.md
@@ -69,6 +69,14 @@ Once your GitLab.com account is linked, you can go to your [Subscriptions](https
Please note that you need to be a group owner to associate a group to your subscription.
+### GitLab.com: Upgrade your subscription plan
+
+GitLab.com subscriptions can be upgraded directly through the [Subscriptions portal](https://customers.gitlab.com/subscriptions).
+
+The Subscriptions portal provides an **Upgrade** button below each GitLab.com
+subscription, which will lead you to a simple
+checkout process.
+
### Confirm or upgrade your GitLab.com subscription details within GitLab
To see the status of your GitLab.com subscription, you can click on the Billings
diff --git a/doc/topics/autodevops/index.md b/doc/topics/autodevops/index.md
index f9ad952aaad..7a92a672801 100644
--- a/doc/topics/autodevops/index.md
+++ b/doc/topics/autodevops/index.md
@@ -789,11 +789,11 @@ To configure your application variables:
1. Go to your project's **Settings > CI/CD**, then expand the section
called **Variables**.
-2. Create a CI Variable, ensuring the key is prefixed with
+1. Create a CI Variable, ensuring the key is prefixed with
`K8S_SECRET_`. For example, you can create a variable with key
`K8S_SECRET_RAILS_MASTER_KEY`.
-3. Run an Auto Devops pipeline either by manually creating a new
+1. Run an Auto Devops pipeline either by manually creating a new
pipeline or by pushing a code change to GitLab.
Auto DevOps pipelines will take your application secret variables to
diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md
index a0a917c5ebd..4b98dd73d76 100644
--- a/doc/user/application_security/dast/index.md
+++ b/doc/user/application_security/dast/index.md
@@ -162,6 +162,28 @@ As the DAST job belongs to a separate `dast` stage that runs after all
[default stages](../../../ci/yaml/README.md#stages),
don't forget to add `stage: dast` when you override the template job definition.
+## Available variables
+
+DAST can be [configured](#customizing-the-dast-settings) using environment variables.
+Since it's a wrapper around the ZAP scanning scripts
+([baseline](https://github.com/zaproxy/zaproxy/wiki/ZAP-Baseline-Scan)
+or [full](https://github.com/zaproxy/zaproxy/wiki/ZAP-Full-Scan) scan), it
+accepts all arguments those scripts recognize (the arguments are the same).
+The choice of the scan type depends on the `DAST_FULL_SCAN_ENABLED` environment
+variable value.
+
+| Environment variable | Required | Description |
+|-----------------------------| ----------|--------------------------------------------------------------------------------|
+| `DAST_WEBSITE` | yes | The URL of the website to scan. |
+| `DAST_AUTH_URL` | no | The authentication URL of the website to scan. |
+| `DAST_USERNAME` | no | The username to authenticate to in the website. |
+| `DAST_PASSWORD` | no | The password to authenticate to in the website. |
+| `DAST_USERNAME_FIELD` | no | The name of username field at the sign-in HTML form. |
+| `DAST_PASSWORD_FIELD` | no | The name of password field at the sign-in HTML form. |
+| `DAST_AUTH_EXCLUDE_URLS` | no | The URLs to skip during the authenticated scan; comma-separated, no spaces in between. |
+| `DAST_TARGET_AVAILABILITY_TIMEOUT` | no | Time limit in seconds to wait for target availability. Scan is attempted nevertheless if it runs out. Integer. Defaults to `60`. |
+| `DAST_FULL_SCAN_ENABLED` | no | Switches the tool to execute [ZAP Full Scan](https://github.com/zaproxy/zaproxy/wiki/ZAP-Full-Scan) instead of [ZAP Baseline Scan](https://github.com/zaproxy/zaproxy/wiki/ZAP-Baseline-Scan). Boolean. `true`, `True`, or `1` are considered as true value, otherwise false. Defaults to `false`. |
+
## Security Dashboard
The Security Dashboard is a good place to get an overview of all the security
diff --git a/doc/user/application_security/index.md b/doc/user/application_security/index.md
index 91e79f6c23b..56a4cbd26d2 100644
--- a/doc/user/application_security/index.md
+++ b/doc/user/application_security/index.md
@@ -115,9 +115,9 @@ generated by GitLab. To apply the fix:
1. Click on the vulnerability.
1. Download and review the patch file `remediation.patch`.
-2. Ensure your local project has the same commit checked out that was used to generate the patch.
-3. Run `git apply remediation.patch`.
-4. Verify and commit the changes to your branch.
+1. Ensure your local project has the same commit checked out that was used to generate the patch.
+1. Run `git apply remediation.patch`.
+1. Verify and commit the changes to your branch.
![Apply patch for dependency scanning](img/vulnerability_solution.png)
diff --git a/doc/user/application_security/security_dashboard/index.md b/doc/user/application_security/security_dashboard/index.md
index 3b01fe66e03..2a2385c00ae 100644
--- a/doc/user/application_security/security_dashboard/index.md
+++ b/doc/user/application_security/security_dashboard/index.md
@@ -26,8 +26,8 @@ To use the project or group security dashboard:
1. At least one project inside a group must be configured with at least one of
the [supported reports](#supported-reports).
-2. The configured jobs must use the [new `reports` syntax](../../../ci/yaml/README.md#artifactsreports).
-3. [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 or newer must be used.
+1. The configured jobs must use the [new `reports` syntax](../../../ci/yaml/README.md#artifactsreports).
+1. [GitLab Runner](https://docs.gitlab.com/runner/) 11.5 or newer must be used.
If you're using the shared Runners on GitLab.com, this is already the case.
## Project Security Dashboard
diff --git a/doc/user/group/bulk_editing/img/bulk-editing.png b/doc/user/group/bulk_editing/img/bulk-editing.png
new file mode 100644
index 00000000000..d08503dc312
--- /dev/null
+++ b/doc/user/group/bulk_editing/img/bulk-editing.png
Binary files differ
diff --git a/doc/user/group/bulk_editing/index.md b/doc/user/group/bulk_editing/index.md
new file mode 100644
index 00000000000..117a46da0ea
--- /dev/null
+++ b/doc/user/group/bulk_editing/index.md
@@ -0,0 +1,22 @@
+# Bulk editing issue milestones **(PREMIUM)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/7249) in
+[GitLab Ultimate](https://about.gitlab.com/pricing/) 12.1.
+
+NOTE: **Note:**
+A permission level of `Reporter` or higher is required in order to manage issues.
+
+Milestones can be updated simultaneously across multiple issues by using the bulk editing feature.
+
+![Bulk editing](img/bulk-editing.png)
+
+To bulk update group issue milestones:
+
+1. Navigate to the issues list.
+1. Click **Edit issues**.
+ - This will open a sidebar on the right-hand side of your screen where an editable field
+ for milestones will be displayed.
+ - Checkboxes will also appear beside each issue.
+1. Check the checkbox beside each issue to be edited.
+1. Select the desired milestone from the sidebar.
+1. Click **Update all**.
diff --git a/doc/user/group/index.md b/doc/user/group/index.md
index db348c678eb..7597105f36f 100644
--- a/doc/user/group/index.md
+++ b/doc/user/group/index.md
@@ -78,6 +78,10 @@ Issues and merge requests are part of projects. For a given group, you can view
[issues](../project/issues/index.md#issues-list) and [merge requests](../project/merge_requests/index.md#merge-requests-per-group) across all projects in that group,
together in a single list view.
+### Bulk editing issues
+
+For details, see [bulk editing issues](../group/bulk_editing/index.md).
+
## Create a new group
> For a list of words that are not allowed to be used as group names see the
diff --git a/doc/user/markdown.md b/doc/user/markdown.md
index 96e74125801..37f3f21f539 100644
--- a/doc/user/markdown.md
+++ b/doc/user/markdown.md
@@ -1160,13 +1160,15 @@ Examples:
+ Or pluses
```
+<!-- The "2." and "4." in the example above are changed to "1." below, only to match the standards on docs.gitlab.com -->
+
1. First ordered list item
-2. Another item
+1. Another item
- Unordered sub-list.
1. Actual numbers don't matter, just that it's a number
1. Ordered sub-list
1. Next ordered sub-list item
-4. And another item.
+1. And another item.
* Unordered lists can use asterisks
- Or minuses
@@ -1184,14 +1186,14 @@ Example:
Second paragraph of first item.
-2. Another item
+1. Another item
```
1. First ordered list item
Second paragraph of first item.
-2. Another item
+1. Another item
---
@@ -1205,14 +1207,14 @@ Example:
Paragraph of first item.
-2. Another item
+1. Another item
```
1. First ordered list item
Paragraph of first item.
-2. Another item
+1. Another item
### Superscripts / Subscripts
diff --git a/doc/user/project/bulk_editing.md b/doc/user/project/bulk_editing.md
index d0c7daf4692..1783f81df3a 100644
--- a/doc/user/project/bulk_editing.md
+++ b/doc/user/project/bulk_editing.md
@@ -13,13 +13,20 @@ by using the bulk editing feature.
![Bulk editing](img/bulk-editing.png)
NOTE: **Note:**
-Bulk editing of issues and merge requests is only available at the project level.
+Bulk editing of merge requests is only available at the project level.
+For more details, see [bulk editing group issues](../group/bulk_editing/index.md).
-To update multiple project issues or merge requests at the same time, navigate to
-their respective lists and click **Edit issues** or **Edit merge requests** available
-in the tab bar. This will open a sidebar on the right-hand side of your screen
-where editable fields will be displayed. Checkboxes will also appear to the left-hand
-side of eachissue or merge request for you to select the items you want to update.
+To update multiple project issues or merge requests at the same time:
-Once you have selected all relevant items, choose the appropriate fields and their
-values from the sidebar and click **Update all** to apply your changes.
+1. Navigate to their respective list.
+
+1. Click **Edit issues** or **Edit merge requests**.
+
+ - This will open a sidebar on the right-hand side of your screen
+ where editable fields will be displayed.
+
+ - Checkboxes will also appear beside each issue or merge request.
+
+1. Check the checkboxes of each items to be edited.
+1. Choose the appropriate fields and their values from the sidebar.
+1. Click **Update all**.
diff --git a/doc/user/project/integrations/img/prometheus_dashboard_area_panel_type.png b/doc/user/project/integrations/img/prometheus_dashboard_area_panel_type.png
new file mode 100644
index 00000000000..7260b11f07b
--- /dev/null
+++ b/doc/user/project/integrations/img/prometheus_dashboard_area_panel_type.png
Binary files differ
diff --git a/doc/user/project/integrations/img/prometheus_dashboard_single_stat_panel_type.png b/doc/user/project/integrations/img/prometheus_dashboard_single_stat_panel_type.png
new file mode 100644
index 00000000000..ce4c54f909d
--- /dev/null
+++ b/doc/user/project/integrations/img/prometheus_dashboard_single_stat_panel_type.png
Binary files differ
diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md
index 72f12972596..61c30e0b0ef 100644
--- a/doc/user/project/integrations/prometheus.md
+++ b/doc/user/project/integrations/prometheus.md
@@ -191,7 +191,7 @@ The following tables outline the details of expected properties.
| Property | Type | Required | Description |
| ------ | ------ | ------ | ------- |
-| `type` | enum | no, defaults to `area-chart` | Specifies the chart type to use. Only `area-chart` is currently supported. |
+| `type` | enum | no, defaults to `area-chart` | Specifies the chart type to use. |
| `title` | string | yes | Heading for the panel. |
| `y_label` | string | no, but highly encouraged | Y-Axis label for the panel. |
| `weight` | number | no, defaults to order in file | Order to appear within the grouping. Lower number means higher priority, which will be higher on the page. Numbers do not need to be consecutive. |
@@ -207,6 +207,65 @@ The following tables outline the details of expected properties.
| `query` | string | yes if `query_range` is not defined | Defines the Prometheus query to be used to populate the chart/panel. If defined, the `query` endpoint of the [Prometheus API](https://prometheus.io/docs/prometheus/latest/querying/api/) will be utilized. |
| `query_range` | string | yes if `query` is not defined | Defines the Prometheus query to be used to populate the chart/panel. If defined, the `query_range` endpoint of the [Prometheus API](https://prometheus.io/docs/prometheus/latest/querying/api/) will be utilized. |
+#### Panel types for dashboards
+
+The below panel types are supported in monitoring dashboards.
+
+##### Area
+
+To add an area panel type to a dashboard, look at the following sample dashboard file:
+
+```yaml
+dashboard: 'Dashboard Title'
+panel_groups:
+ - group: 'Group Title'
+ panels:
+ - type: area-chart
+ title: "Chart Title"
+ y_label: "Y-Axis"
+ metrics:
+ - id: 10
+ query_range: 'http_requests_total'
+ label: "Metric of Ages"
+ unit: "count"
+```
+
+Note the following properties:
+
+| Property | Type | Required | Description |
+| ------ | ------ | ------ | ------ |
+| type | string | no | Type of panel to be rendered. Optional for area panel types |
+| query_range | yes | required | For area panel types, you must use a [range query](https://prometheus.io/docs/prometheus/latest/querying/api/#range-queries) |
+
+![area panel type](img/prometheus_dashboard_area_panel_type.png)
+
+##### Single Stat
+
+To add a single stat panel type to a dashboard, look at the following sample dashboard file:
+
+```yaml
+dashboard: 'Dashboard Title'
+panel_groups:
+ - group: 'Group Title'
+ panels:
+ - title: "Single Stat"
+ type: "single-stat"
+ metrics:
+ - id: 10
+ query: 'max(go_memstats_alloc_bytes{job="prometheus"})'
+ unit: MB
+ label: "Total"
+```
+
+Note the following properties:
+
+| Property | Type | Required | Description |
+| ------ | ------ | ------ | ------ |
+| type | string | yes | Type of panel to be rendered. For single stat panel types, set to `single-stat` |
+| query | string | yes | For single stat panel types, you must use an [instant query](https://prometheus.io/docs/prometheus/latest/querying/api/#instant-queries) |
+
+![single stat panel type](img/prometheus_dashboard_single_stat_panel_type.png)
+
### Setting up alerts for Prometheus metrics **(ULTIMATE)**
#### Managed Prometheus instances
diff --git a/doc/user/project/issue_board.md b/doc/user/project/issue_board.md
index 3eb5581912a..422e4b71424 100644
--- a/doc/user/project/issue_board.md
+++ b/doc/user/project/issue_board.md
@@ -386,6 +386,10 @@ a given board inside your GitLab instance, any time those two issues are subsequ
loaded in any board in the same instance (could be a different project board or a different group board, for example),
that ordering will be maintained.
+This ordering also affects [issue lists](issues/sorting_issue_lists.md).
+Changing the order in an issue board changes the ordering in an issue list,
+and vice versa.
+
### Filtering issues
You should be able to use the filters on top of your Issue Board to show only
diff --git a/doc/user/project/issues/index.md b/doc/user/project/issues/index.md
index e917697e973..6706e1c2e2b 100644
--- a/doc/user/project/issues/index.md
+++ b/doc/user/project/issues/index.md
@@ -89,7 +89,7 @@ Key actions for Issues include:
![Issue view](img/issues_main_view.png)
On an issue's page, you can view [all aspects of the issue](issue_data_and_actions.md),
-and modify them if you you have the necessary [permissions](../../permissions.md).
+and modify them if you have the necessary [permissions](../../permissions.md).
### Issues list
@@ -104,7 +104,8 @@ view, you can also make certain changes [in bulk](../bulk_editing.md) to the dis
For more information, see the [Issue Data and Actions](issue_data_and_actions.md) page
for a rundown of all the fields and information in an issue.
-For sorting by issue priority, see [Label Priority](../labels.md#label-priority).
+You can sort a list of issues several ways, including by issue creation date, milestone due date,
+etc. For more information, see the [Sorting and Ordering Issue Lists](sorting_issue_lists.md) page.
### Issue boards
diff --git a/doc/user/project/issues/managing_issues.md b/doc/user/project/issues/managing_issues.md
index 709588959c1..e9b4e591384 100644
--- a/doc/user/project/issues/managing_issues.md
+++ b/doc/user/project/issues/managing_issues.md
@@ -7,7 +7,9 @@ you can do with issues.
## Create a new Issue
-When you create a new issue, you'll be prompted to fill in the [data and fields of the issue](issue_data_and_actions.md#parts-of-an-issue), as illustrated below.
+When you create a new issue, you'll be prompted to fill in the [data and fields of the issue](issue_data_and_actions.md#parts-of-an-issue), as illustrated below. If you know
+the values you want to assign to an issue, you can use the [Quick actions](../quick_actions.md)
+feature to input values, instead of selecting them from lists.
![New issue from the issues list](img/new_issue.png)
diff --git a/doc/user/project/issues/sorting_issue_lists.md b/doc/user/project/issues/sorting_issue_lists.md
new file mode 100644
index 00000000000..ba120783430
--- /dev/null
+++ b/doc/user/project/issues/sorting_issue_lists.md
@@ -0,0 +1,30 @@
+# Sorting and Ordering Issue Lists
+
+You can sort a list of issues several ways, including by issue creation date, milestone due date,
+etc. The available sorting options can change based on the context of the list.
+For sorting by issue priority, see [Label Priority](../labels.md#label-priority).
+
+In group and project issue lists, it is also possible to order issues manually,
+similar to [issue boards](../issue_board.md#issue-ordering-in-a-list).
+
+## Manual sorting
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-ce/issues/62178) in GitLab 12.1.
+
+When you select **Manual** sorting, you can change
+the order by dragging and dropping the issues. The changed order will persist. Everyone who visits the same list will see the reordered list, with some exceptions.
+
+Each issue is assigned a relative order value, representing its relative
+order with respect to the other issues in the list. When you drag-and-drop reorder
+an issue, its relative order value changes accordingly.
+
+In addition, any time that issue appears in a manually sorted list,
+the updated relative order value will be used for the ordering. This means that
+if issue `A` is drag-and-drop reordered to be above issue `B` by any user in
+a given list inside your GitLab instance, any time those two issues are subsequently
+loaded in any list in the same instance (could be a different project issue list or a
+different group issue list, for example), that ordering will be maintained.
+
+This ordering also affects [issue boards](../issue_board.md#issue-ordering-in-a-list).
+Changing the order in an issue list changes the ordering in an issue board,
+and vice versa.
diff --git a/doc/user/project/merge_requests/index.md b/doc/user/project/merge_requests/index.md
index a4cda65bf6b..8c28e24683f 100644
--- a/doc/user/project/merge_requests/index.md
+++ b/doc/user/project/merge_requests/index.md
@@ -391,6 +391,17 @@ can show the Code Climate report right in the merge request widget area.
[Read more about Code Quality reports.](code_quality.md)
+## Metrics Reports **(PREMIUM)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/9788) in [GitLab Premium][products] 11.10.
+Requires GitLab Runner 11.10 and above.
+
+If you are using [GitLab CI][ci], you can configure your job to output custom
+metrics and GitLab will display the Metrics Report on the merge request so
+that it's fast and easy to identify changes to important metrics.
+
+[Read more about Metrics Report](../../../ci/metrics_reports.md).
+
## Browser Performance Testing **(PREMIUM)**
> Introduced in [GitLab Premium][products] 10.3.
diff --git a/doc/user/project/quick_actions.md b/doc/user/project/quick_actions.md
index 948ac91a886..f81669a41c9 100644
--- a/doc/user/project/quick_actions.md
+++ b/doc/user/project/quick_actions.md
@@ -59,6 +59,12 @@ discussions, and descriptions:
| `/create_merge_request <branch name>` | Create a new merge request starting from the current issue | ✓ | |
| `/relate #issue1 #issue2` | Mark issues as related **(STARTER)** | ✓ | |
+## Autocomplete characters
+
+Many quick actions require a parameter, for example: username, milestone, and
+label. [Autocomplete characters](autocomplete_characters.md) can make it easier
+to enter a parameter, compared to selecting items from a list.
+
## Quick actions for commit messages
The following quick actions are applicable for commit messages:
diff --git a/doc/user/project/settings/import_export.md b/doc/user/project/settings/import_export.md
index 7241df613eb..35d5320c0b1 100644
--- a/doc/user/project/settings/import_export.md
+++ b/doc/user/project/settings/import_export.md
@@ -116,3 +116,8 @@ For more details on the specific data persisted in a project export, see the
1. Click on **Import project** to begin importing. Your newly imported project
page will appear soon.
+
+NOTE: **Note:**
+If use of the `Internal` visibility level
+[is restricted](../../../public_access/public_access.md#restricting-the-use-of-public-or-internal-projects),
+all imported projects are given the visibility of `Private`.
diff --git a/lib/gitlab/chaos.rb b/lib/gitlab/chaos.rb
new file mode 100644
index 00000000000..4f47cdef971
--- /dev/null
+++ b/lib/gitlab/chaos.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+module Gitlab
+ # Chaos methods for GitLab.
+ # See https://docs.gitlab.com/ee/development/chaos_endpoints.html for more details.
+ class Chaos
+ # leak_mem will retain the specified amount of memory and sleep.
+ # On return, the memory will be released.
+ def self.leak_mem(memory_mb, duration_s)
+ start_time = Time.now
+
+ retainer = []
+ # Add `n` 1mb chunks of memory to the retainer array
+ memory_mb.times { retainer << "x" * 1.megabyte }
+
+ duration_left = [start_time + duration_s - Time.now, 0].max
+ Kernel.sleep(duration_left)
+ end
+
+ # cpu_spin will consume all CPU on a single core for the specified duration
+ def self.cpu_spin(duration_s)
+ expected_end_time = Time.now + duration_s
+
+ rand while Time.now < expected_end_time
+ end
+
+ # db_spin will query the database in a tight loop for the specified duration
+ def self.db_spin(duration_s, interval_s)
+ expected_end_time = Time.now + duration_s
+
+ while Time.now < expected_end_time
+ ActiveRecord::Base.connection.execute("SELECT 1")
+
+ end_interval_time = Time.now + [duration_s, interval_s].min
+ rand while Time.now < end_interval_time
+ end
+ end
+
+ # sleep will sleep for the specified duration
+ def self.sleep(duration_s)
+ Kernel.sleep(duration_s)
+ end
+
+ # Kill will send a SIGKILL signal to the current process
+ def self.kill
+ Process.kill("KILL", Process.pid)
+ end
+ end
+end
diff --git a/lib/gitlab/import_export/project_tree_restorer.rb b/lib/gitlab/import_export/project_tree_restorer.rb
index dec99c23a2d..91fe4e5d074 100644
--- a/lib/gitlab/import_export/project_tree_restorer.rb
+++ b/lib/gitlab/import_export/project_tree_restorer.rb
@@ -130,6 +130,7 @@ module Gitlab
def visibility_level
level = override_params['visibility_level'] || json_params['visibility_level'] || @project.visibility_level
level = @project.group.visibility_level if @project.group && level.to_i > @project.group.visibility_level
+ level = Gitlab::VisibilityLevel::PRIVATE if level == Gitlab::VisibilityLevel::INTERNAL && Gitlab::CurrentSettings.restricted_visibility_levels.include?(level)
{ 'visibility_level' => level }
end
diff --git a/lib/gitlab/metrics/subscribers/rails_cache.rb b/lib/gitlab/metrics/subscribers/rails_cache.rb
index 01db507761b..2ee7144fe2f 100644
--- a/lib/gitlab/metrics/subscribers/rails_cache.rb
+++ b/lib/gitlab/metrics/subscribers/rails_cache.rb
@@ -50,7 +50,8 @@ module Gitlab
def observe(key, duration)
return unless current_transaction
- metric_cache_operation_duration_seconds.observe(current_transaction.labels.merge({ operation: key }), duration / 1000.0)
+ metric_cache_operations_total.increment(current_transaction.labels.merge({ operation: key }))
+ metric_cache_operation_duration_seconds.observe({ operation: key }, duration / 1000.0)
current_transaction.increment(:cache_duration, duration, false)
current_transaction.increment(:cache_count, 1, false)
current_transaction.increment("cache_#{key}_duration".to_sym, duration, false)
@@ -63,12 +64,20 @@ module Gitlab
Transaction.current
end
+ def metric_cache_operations_total
+ @metric_cache_operations_total ||= ::Gitlab::Metrics.counter(
+ :gitlab_cache_operations_total,
+ 'Cache operations',
+ Transaction::BASE_LABELS
+ )
+ end
+
def metric_cache_operation_duration_seconds
@metric_cache_operation_duration_seconds ||= ::Gitlab::Metrics.histogram(
:gitlab_cache_operation_duration_seconds,
'Cache access time',
- Transaction::BASE_LABELS.merge({ action: nil }),
- [0.001, 0.01, 0.1, 1, 10]
+ {},
+ [0.00001, 0.0001, 0.001, 0.01, 0.1, 1.0]
)
end
diff --git a/lib/gitlab/slug/environment.rb b/lib/gitlab/slug/environment.rb
new file mode 100644
index 00000000000..1b87d3bb626
--- /dev/null
+++ b/lib/gitlab/slug/environment.rb
@@ -0,0 +1,58 @@
+# frozen_string_literal: true
+
+# An environment name is not necessarily suitable for use in URLs, DNS
+# or other third-party contexts, so provide a slugified version. A slug has
+# the following properties:
+# * contains only lowercase letters (a-z), numbers (0-9), and '-'
+# * begins with a letter
+# * has a maximum length of 24 bytes (OpenShift limitation)
+# * cannot end with `-`
+module Gitlab
+ module Slug
+ class Environment
+ attr_reader :name
+
+ def initialize(name)
+ @name = name
+ end
+
+ def generate
+ # Lowercase letters and numbers only
+ slugified = name.to_s.downcase.gsub(/[^a-z0-9]/, '-')
+
+ # Must start with a letter
+ slugified = 'env-' + slugified unless slugified.match?(/^[a-z]/)
+
+ # Repeated dashes are invalid (OpenShift limitation)
+ slugified.squeeze!('-')
+
+ slugified =
+ if slugified.size > 24 || slugified != name
+ # Maximum length: 24 characters (OpenShift limitation)
+ shorten_and_add_suffix(slugified)
+ else
+ # Cannot end with a dash (Kubernetes label limitation)
+ slugified.chomp('-')
+ end
+
+ slugified
+ end
+
+ private
+
+ def shorten_and_add_suffix(slug)
+ slug = slug[0..16]
+ slug << '-' unless slug.ends_with?('-')
+ slug << suffix
+ end
+
+ # Slugifying a name may remove the uniqueness guarantee afforded by it being
+ # based on name (which must be unique). To compensate, we add a predictable
+ # 6-byte suffix in those circumstances. This is not *guaranteed* uniqueness,
+ # but the chance of collisions is vanishingly small
+ def suffix
+ Digest::SHA2.hexdigest(name.to_s).to_i(16).to_s(36).last(6)
+ end
+ end
+ end
+end
diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb
index 7572c0bdbfd..43072053e57 100644
--- a/lib/gitlab/usage_data.rb
+++ b/lib/gitlab/usage_data.rb
@@ -130,7 +130,9 @@ module Gitlab
def usage_counters
{
- web_ide_commits: Gitlab::UsageDataCounters::WebIdeCounter.total_commits_count
+ web_ide_commits: Gitlab::UsageDataCounters::WebIdeCounter.total_commits_count,
+ web_ide_merge_requests: Gitlab::UsageDataCounters::WebIdeCounter.total_merge_requests_count,
+ web_ide_views: Gitlab::UsageDataCounters::WebIdeCounter.total_views_count
}
end
diff --git a/lib/gitlab/usage_data_counters/web_ide_counter.rb b/lib/gitlab/usage_data_counters/web_ide_counter.rb
index 6fbffb94c58..899ad0db9c0 100644
--- a/lib/gitlab/usage_data_counters/web_ide_counter.rb
+++ b/lib/gitlab/usage_data_counters/web_ide_counter.rb
@@ -6,6 +6,8 @@ module Gitlab
extend RedisCounter
COMMITS_COUNT_KEY = 'WEB_IDE_COMMITS_COUNT'
+ MERGE_REQUEST_COUNT_KEY = 'WEB_IDE_MERGE_REQUESTS_COUNT'
+ VIEWS_COUNT_KEY = 'WEB_IDE_VIEWS_COUNT'
class << self
def increment_commits_count
@@ -15,6 +17,22 @@ module Gitlab
def total_commits_count
total_count(COMMITS_COUNT_KEY)
end
+
+ def increment_merge_requests_count
+ increment(MERGE_REQUEST_COUNT_KEY)
+ end
+
+ def total_merge_requests_count
+ total_count(MERGE_REQUEST_COUNT_KEY)
+ end
+
+ def increment_views_count
+ increment(VIEWS_COUNT_KEY)
+ end
+
+ def total_views_count
+ total_count(VIEWS_COUNT_KEY)
+ end
end
end
end
diff --git a/lib/tasks/frontend.rake b/lib/tasks/frontend.rake
new file mode 100644
index 00000000000..1cac7520227
--- /dev/null
+++ b/lib/tasks/frontend.rake
@@ -0,0 +1,21 @@
+unless Rails.env.production?
+ namespace :frontend do
+ desc 'GitLab | Frontend | Generate fixtures for JavaScript tests'
+ RSpec::Core::RakeTask.new(:fixtures, [:pattern]) do |t, args|
+ args.with_defaults(pattern: '{spec,ee/spec}/frontend/fixtures/*.rb')
+ ENV['NO_KNAPSACK'] = 'true'
+ t.pattern = args[:pattern]
+ t.rspec_opts = '--format documentation'
+ end
+
+ desc 'GitLab | Frontend | Run JavaScript tests'
+ task tests: ['yarn:check'] do
+ sh "yarn test" do |ok, res|
+ abort('rake frontend:tests failed') unless ok
+ end
+ end
+ end
+
+ desc 'GitLab | Frontend | Shortcut for frontend:fixtures and frontend:tests'
+ task frontend: ['frontend:fixtures', 'frontend:tests']
+end
diff --git a/lib/tasks/karma.rake b/lib/tasks/karma.rake
index 2dc14183fa3..36590010406 100644
--- a/lib/tasks/karma.rake
+++ b/lib/tasks/karma.rake
@@ -1,15 +1,8 @@
unless Rails.env.production?
namespace :karma do
+ # alias exists for legacy reasons
desc 'GitLab | Karma | Generate fixtures for JavaScript tests'
- task fixtures: ['karma:rspec_fixtures']
-
- desc 'GitLab | Karma | Generate fixtures using RSpec'
- RSpec::Core::RakeTask.new(:rspec_fixtures, [:pattern]) do |t, args|
- args.with_defaults(pattern: '{spec,ee/spec}/javascripts/fixtures/*.rb')
- ENV['NO_KNAPSACK'] = 'true'
- t.pattern = args[:pattern]
- t.rspec_opts = '--format documentation'
- end
+ task fixtures: ['frontend:fixtures']
desc 'GitLab | Karma | Run JavaScript tests'
task tests: ['yarn:check'] do
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb
index 5eceeb9661c..afddbff75bd 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/check_mentions_for_xss_spec.rb
@@ -3,9 +3,7 @@
module QA
context 'Plan' do
describe 'check xss occurence in @mentions in issues' do
- let(:issue_title) { 'issue title' }
-
- it 'user mentions a user in comment' do
+ before do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
@@ -25,11 +23,13 @@ module QA
end
issue = Resource::Issue.fabricate_via_api! do |issue|
- issue.title = issue_title
+ issue.title = 'issue title'
issue.project = project
end
issue.visit!
+ end
+ it 'user mentions a user in comment' do
Page::Project::Issue::Show.perform do |show_page|
show_page.select_all_activities_filter
show_page.comment('cc-ing you here @eve')
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb
index 2e71ecb5718..78919561a89 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/comment_issue_spec.rb
@@ -3,7 +3,7 @@
module QA
context 'Plan' do
describe 'Issue comments' do
- it 'user comments on an issue and edits the comment' do
+ before do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
@@ -11,7 +11,9 @@ module QA
issue.title = 'issue title'
end
issue.visit!
+ end
+ it 'user comments on an issue and edits the comment' do
Page::Project::Issue::Show.perform do |issue_show_page|
first_version_of_comment = 'First version of the comment'
second_version_of_comment = 'Second version of the comment'
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
index af9514008f9..6f5b6893248 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/filter_issue_comments_spec.rb
@@ -5,7 +5,7 @@ module QA
describe 'filter issue comments activities' do
let(:issue_title) { 'issue title' }
- it 'user filters comments and activities in an issue' do
+ before do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
@@ -14,9 +14,9 @@ module QA
end
issue.visit!
+ end
- expect(page).to have_content(issue_title)
-
+ it 'user filters comments and activities in an issue' do
Page::Project::Issue::Show.perform do |show_page|
my_own_comment = "My own comment"
made_the_issue_confidential = "made the issue confidential"
diff --git a/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb b/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb
index 24dcb32f63f..694a3ffb54b 100644
--- a/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb
+++ b/qa/qa/specs/features/browser_ui/2_plan/issue/issue_suggestions_spec.rb
@@ -5,7 +5,7 @@ module QA
describe 'issue suggestions' do
let(:issue_title) { 'Issue Lists are awesome' }
- it 'user sees issue suggestions when creating a new issue' do
+ before do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
Page::Main::Login.perform(&:sign_in_using_credentials)
@@ -20,7 +20,9 @@ module QA
end
project.visit!
+ end
+ it 'user sees issue suggestions when creating a new issue' do
Page::Project::Show.perform(&:go_to_new_issue)
Page::Project::Issue::New.perform do |new_issue_page|
new_issue_page.add_title("issue")
diff --git a/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb
index 7a36f9ea420..3ce291bf8bc 100644
--- a/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb
+++ b/qa/qa/specs/features/browser_ui/3_create/merge_request/rebase_merge_request_spec.rb
@@ -1,7 +1,8 @@
# frozen_string_literal: true
module QA
- context 'Create' do
+ # Failure issue: https://gitlab.com/gitlab-org/quality/staging/issues/66
+ context 'Create', :quarantine do
describe 'Merge request rebasing' do
it 'user rebases source branch of merge request' do
Runtime::Browser.visit(:gitlab, Page::Main::Login)
diff --git a/spec/controllers/chaos_controller_spec.rb b/spec/controllers/chaos_controller_spec.rb
new file mode 100644
index 00000000000..bafd4a70862
--- /dev/null
+++ b/spec/controllers/chaos_controller_spec.rb
@@ -0,0 +1,127 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe ChaosController do
+ describe '#leakmem' do
+ it 'calls synchronously' do
+ expect(Gitlab::Chaos).to receive(:leak_mem).with(100, 30.seconds)
+
+ get :leakmem
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+
+ it 'call synchronously with params' do
+ expect(Gitlab::Chaos).to receive(:leak_mem).with(1, 2.seconds)
+
+ get :leakmem, params: { memory_mb: 1, duration_s: 2 }
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+
+ it 'calls asynchronously' do
+ expect(Chaos::LeakMemWorker).to receive(:perform_async).with(100, 30.seconds)
+
+ get :leakmem, params: { async: 1 }
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+ end
+
+ describe '#cpu_spin' do
+ it 'calls synchronously' do
+ expect(Gitlab::Chaos).to receive(:cpu_spin).with(30.seconds)
+
+ get :cpu_spin
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+
+ it 'calls synchronously with params' do
+ expect(Gitlab::Chaos).to receive(:cpu_spin).with(3.seconds)
+
+ get :cpu_spin, params: { duration_s: 3 }
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+
+ it 'calls asynchronously' do
+ expect(Chaos::CpuSpinWorker).to receive(:perform_async).with(30.seconds)
+
+ get :cpu_spin, params: { async: 1 }
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+ end
+
+ describe '#db_spin' do
+ it 'calls synchronously' do
+ expect(Gitlab::Chaos).to receive(:db_spin).with(30.seconds, 1.second)
+
+ get :db_spin
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+
+ it 'calls synchronously with params' do
+ expect(Gitlab::Chaos).to receive(:db_spin).with(4.seconds, 5.seconds)
+
+ get :db_spin, params: { duration_s: 4, interval_s: 5 }
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+
+ it 'calls asynchronously' do
+ expect(Chaos::DbSpinWorker).to receive(:perform_async).with(30.seconds, 1.second)
+
+ get :db_spin, params: { async: 1 }
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+ end
+
+ describe '#sleep' do
+ it 'calls synchronously' do
+ expect(Gitlab::Chaos).to receive(:sleep).with(30.seconds)
+
+ get :sleep
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+
+ it 'calls synchronously with params' do
+ expect(Gitlab::Chaos).to receive(:sleep).with(5.seconds)
+
+ get :sleep, params: { duration_s: 5 }
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+
+ it 'calls asynchronously' do
+ expect(Chaos::SleepWorker).to receive(:perform_async).with(30.seconds)
+
+ get :sleep, params: { async: 1 }
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+ end
+
+ describe '#kill' do
+ it 'calls synchronously' do
+ expect(Gitlab::Chaos).to receive(:kill).with(no_args)
+
+ get :kill
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+
+ it 'calls asynchronously' do
+ expect(Chaos::KillWorker).to receive(:perform_async).with(no_args)
+
+ get :kill, params: { async: 1 }
+
+ expect(response).to have_gitlab_http_status(200)
+ end
+ end
+end
diff --git a/spec/controllers/dashboard/milestones_controller_spec.rb b/spec/controllers/dashboard/milestones_controller_spec.rb
index 4de537ae6f8..67939aa4e6a 100644
--- a/spec/controllers/dashboard/milestones_controller_spec.rb
+++ b/spec/controllers/dashboard/milestones_controller_spec.rb
@@ -47,6 +47,8 @@ describe Dashboard::MilestonesController do
describe "#index" do
let(:public_group) { create(:group, :public) }
let!(:public_milestone) { create(:milestone, group: public_group) }
+ let!(:closed_group_milestone) { create(:milestone, group: group, state: 'closed') }
+ let!(:closed_project_milestone) { create(:milestone, project: project, state: 'closed') }
render_views
@@ -59,6 +61,15 @@ describe Dashboard::MilestonesController do
expect(json_response.map { |i| i["group_name"] }.compact).to match_array(group.name)
end
+ it 'returns closed group and project milestones to which the user belongs' do
+ get :index, params: { state: 'closed' }, format: :json
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response.size).to eq(2)
+ expect(json_response.map { |i| i["name"] }).to match_array([closed_group_milestone.name, closed_project_milestone.name])
+ expect(json_response.map { |i| i["group_name"] }.compact).to match_array(group.name)
+ end
+
it 'searches legacy project milestones by title when search_title is given' do
project_milestone = create(:milestone, title: 'Project milestone title', project: project)
@@ -77,11 +88,11 @@ describe Dashboard::MilestonesController do
expect(response.body).not_to include(project_milestone.title)
end
- it 'shows counts of group and project milestones to which the user belongs to' do
+ it 'shows counts of open and closed group and project milestones to which the user belongs to' do
get :index
expect(response.body).to include("Open\n<span class=\"badge badge-pill\">2</span>")
- expect(response.body).to include("Closed\n<span class=\"badge badge-pill\">0</span>")
+ expect(response.body).to include("Closed\n<span class=\"badge badge-pill\">2</span>")
end
context 'external authorization' do
diff --git a/spec/controllers/ide_controller_spec.rb b/spec/controllers/ide_controller_spec.rb
new file mode 100644
index 00000000000..0462f9520d5
--- /dev/null
+++ b/spec/controllers/ide_controller_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe IdeController do
+ let(:user) { create(:user) }
+
+ before do
+ sign_in(user)
+ end
+
+ it 'increases the views counter' do
+ expect(Gitlab::UsageDataCounters::WebIdeCounter).to receive(:increment_views_count)
+
+ get :index
+ end
+end
diff --git a/spec/controllers/projects/merge_requests/creations_controller_spec.rb b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
index 5fefad86ef3..3816e1c7a31 100644
--- a/spec/controllers/projects/merge_requests/creations_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/creations_controller_spec.rb
@@ -212,4 +212,46 @@ describe Projects::MergeRequests::CreationsController do
expect(response).to have_gitlab_http_status(200)
end
end
+
+ describe 'POST create' do
+ let(:params) do
+ {
+ namespace_id: fork_project.namespace.to_param,
+ project_id: fork_project,
+ merge_request: {
+ title: 'Test merge request',
+ source_branch: 'remove-submodule',
+ target_branch: 'master'
+ }
+ }
+ end
+
+ it 'creates merge request' do
+ expect do
+ post_request(params)
+ end.to change { MergeRequest.count }.by(1)
+ end
+
+ context 'when the merge request is not created from the web ide' do
+ it 'counter is not increased' do
+ expect(Gitlab::UsageDataCounters::WebIdeCounter).not_to receive(:increment_merge_requests_count)
+
+ post_request(params)
+ end
+ end
+
+ context 'when the merge request is created from the web ide' do
+ let(:nav_source) { { nav_source: 'webide' } }
+
+ it 'counter is increased' do
+ expect(Gitlab::UsageDataCounters::WebIdeCounter).to receive(:increment_merge_requests_count)
+
+ post_request(params.merge(nav_source))
+ end
+ end
+
+ def post_request(merge_request_params)
+ post :create, params: merge_request_params
+ end
+ end
end
diff --git a/spec/frontend/environment.js b/spec/frontend/environment.js
index a8c8688441d..290c0e797cb 100644
--- a/spec/frontend/environment.js
+++ b/spec/frontend/environment.js
@@ -1,8 +1,11 @@
/* eslint-disable import/no-commonjs */
+const path = require('path');
const { ErrorWithStack } = require('jest-util');
const JSDOMEnvironment = require('jest-environment-jsdom');
+const ROOT_PATH = path.resolve(__dirname, '../..');
+
class CustomEnvironment extends JSDOMEnvironment {
constructor(config, context) {
super(config, context);
@@ -35,9 +38,8 @@ class CustomEnvironment extends JSDOMEnvironment {
this.rejectedPromises.push(error);
};
- this.global.fixturesBasePath = `${process.cwd()}/${
- IS_EE ? 'ee/' : ''
- }spec/javascripts/fixtures`;
+ this.global.fixturesBasePath = `${ROOT_PATH}/tmp/tests/frontend/fixtures${IS_EE ? '-ee' : ''}`;
+ this.global.staticFixturesBasePath = `${ROOT_PATH}/spec/frontend/fixtures`;
// Not yet supported by JSDOM: https://github.com/jsdom/jsdom/issues/317
this.global.document.createRange = () => ({
diff --git a/spec/javascripts/fixtures/abuse_reports.rb b/spec/frontend/fixtures/abuse_reports.rb
index e0aaecf626a..21356390cae 100644
--- a/spec/javascripts/fixtures/abuse_reports.rb
+++ b/spec/frontend/fixtures/abuse_reports.rb
@@ -21,6 +21,6 @@ describe Admin::AbuseReportsController, '(JavaScript fixtures)', type: :controll
it 'abuse_reports/abuse_reports_list.html' do
get :index
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/admin_users.rb b/spec/frontend/fixtures/admin_users.rb
index 22a5de66577..0209594dadc 100644
--- a/spec/javascripts/fixtures/admin_users.rb
+++ b/spec/frontend/fixtures/admin_users.rb
@@ -23,6 +23,6 @@ describe Admin::UsersController, '(JavaScript fixtures)', type: :controller do
get :new
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/application_settings.rb b/spec/frontend/fixtures/application_settings.rb
index d4651fa6ece..38a060580c1 100644
--- a/spec/javascripts/fixtures/application_settings.rb
+++ b/spec/frontend/fixtures/application_settings.rb
@@ -28,6 +28,6 @@ describe Admin::ApplicationSettingsController, '(JavaScript fixtures)', type: :c
get :show
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/autocomplete_sources.rb b/spec/frontend/fixtures/autocomplete_sources.rb
index b20a0159d7d..9e04328e2b9 100644
--- a/spec/javascripts/fixtures/autocomplete_sources.rb
+++ b/spec/frontend/fixtures/autocomplete_sources.rb
@@ -34,6 +34,6 @@ describe Projects::AutocompleteSourcesController, '(JavaScript fixtures)', type:
type_id: issue.id
}
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/blob.rb b/spec/frontend/fixtures/blob.rb
index 07670552cd5..ce5030efbf8 100644
--- a/spec/javascripts/fixtures/blob.rb
+++ b/spec/frontend/fixtures/blob.rb
@@ -29,6 +29,6 @@ describe Projects::BlobController, '(JavaScript fixtures)', type: :controller do
id: 'add-ipython-files/files/ipython/basic.ipynb'
})
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/boards.rb b/spec/frontend/fixtures/boards.rb
index 5835721d3d5..f257d80390f 100644
--- a/spec/javascripts/fixtures/boards.rb
+++ b/spec/frontend/fixtures/boards.rb
@@ -23,6 +23,6 @@ describe Projects::BoardsController, '(JavaScript fixtures)', type: :controller
project_id: project
})
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/branches.rb b/spec/frontend/fixtures/branches.rb
index 204aa9b7c7a..197fe42c52a 100644
--- a/spec/javascripts/fixtures/branches.rb
+++ b/spec/frontend/fixtures/branches.rb
@@ -27,6 +27,6 @@ describe Projects::BranchesController, '(JavaScript fixtures)', type: :controlle
project_id: project
}
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/clusters.rb b/spec/frontend/fixtures/clusters.rb
index 1076404e0e3..f15ef010807 100644
--- a/spec/javascripts/fixtures/clusters.rb
+++ b/spec/frontend/fixtures/clusters.rb
@@ -29,6 +29,6 @@ describe Projects::ClustersController, '(JavaScript fixtures)', type: :controlle
id: cluster
}
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/commit.rb b/spec/frontend/fixtures/commit.rb
index ff9a4bc1adc..a328c455356 100644
--- a/spec/javascripts/fixtures/commit.rb
+++ b/spec/frontend/fixtures/commit.rb
@@ -28,6 +28,6 @@ describe Projects::CommitController, '(JavaScript fixtures)', type: :controller
get :show, params: params
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/deploy_keys.rb b/spec/frontend/fixtures/deploy_keys.rb
index 38eab853da2..fca233c6f59 100644
--- a/spec/javascripts/fixtures/deploy_keys.rb
+++ b/spec/frontend/fixtures/deploy_keys.rb
@@ -38,6 +38,6 @@ describe Projects::DeployKeysController, '(JavaScript fixtures)', type: :control
project_id: project
}, format: :json
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/groups.rb b/spec/frontend/fixtures/groups.rb
index 4d0afc3ce1a..c1bb2d43332 100644
--- a/spec/javascripts/fixtures/groups.rb
+++ b/spec/frontend/fixtures/groups.rb
@@ -21,7 +21,7 @@ describe 'Groups (JavaScript fixtures)', type: :controller do
it 'groups/edit.html' do
get :edit, params: { id: group }
- expect(response).to be_success
+ expect(response).to be_successful
end
end
@@ -29,7 +29,7 @@ describe 'Groups (JavaScript fixtures)', type: :controller do
it 'groups/ci_cd_settings.html' do
get :show, params: { group_id: group }
- expect(response).to be_success
+ expect(response).to be_successful
end
end
end
diff --git a/spec/javascripts/fixtures/issues.rb b/spec/frontend/fixtures/issues.rb
index d8d77f767de..b5eb38e0023 100644
--- a/spec/javascripts/fixtures/issues.rb
+++ b/spec/frontend/fixtures/issues.rb
@@ -48,7 +48,7 @@ describe Projects::IssuesController, '(JavaScript fixtures)', type: :controller
project_id: project
}
- expect(response).to be_success
+ expect(response).to be_successful
end
private
@@ -60,7 +60,7 @@ describe Projects::IssuesController, '(JavaScript fixtures)', type: :controller
id: issue.to_param
}
- expect(response).to be_success
+ expect(response).to be_successful
end
end
@@ -117,6 +117,6 @@ describe API::Issues, '(JavaScript fixtures)', type: :request do
get_related_merge_requests(project.id, issue.iid, user)
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/jobs.rb b/spec/frontend/fixtures/jobs.rb
index 46ccd6f8c8a..a3a7759c85b 100644
--- a/spec/javascripts/fixtures/jobs.rb
+++ b/spec/frontend/fixtures/jobs.rb
@@ -39,7 +39,7 @@ describe Projects::JobsController, '(JavaScript fixtures)', type: :controller do
id: build_with_artifacts.to_param
}
- expect(response).to be_success
+ expect(response).to be_successful
end
it 'jobs/delayed.json' do
@@ -49,6 +49,6 @@ describe Projects::JobsController, '(JavaScript fixtures)', type: :controller do
id: delayed_job.to_param
}, format: :json
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/labels.rb b/spec/frontend/fixtures/labels.rb
index 4d1b7317274..a312287970f 100644
--- a/spec/javascripts/fixtures/labels.rb
+++ b/spec/frontend/fixtures/labels.rb
@@ -35,7 +35,7 @@ describe 'Labels (JavaScript fixtures)' do
group_id: group
}, format: 'json'
- expect(response).to be_success
+ expect(response).to be_successful
end
end
@@ -52,7 +52,7 @@ describe 'Labels (JavaScript fixtures)' do
project_id: project
}, format: 'json'
- expect(response).to be_success
+ expect(response).to be_successful
end
end
end
diff --git a/spec/javascripts/fixtures/merge_requests.rb b/spec/frontend/fixtures/merge_requests.rb
index 05860be2291..88706e96676 100644
--- a/spec/javascripts/fixtures/merge_requests.rb
+++ b/spec/frontend/fixtures/merge_requests.rb
@@ -129,6 +129,6 @@ describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :cont
id: merge_request.to_param
}, format: :html
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/merge_requests_diffs.rb b/spec/frontend/fixtures/merge_requests_diffs.rb
index 03b9b713fd8..b633a0495a6 100644
--- a/spec/javascripts/fixtures/merge_requests_diffs.rb
+++ b/spec/frontend/fixtures/merge_requests_diffs.rb
@@ -1,4 +1,3 @@
-
require 'spec_helper'
describe Projects::MergeRequests::DiffsController, '(JavaScript fixtures)', type: :controller do
@@ -65,6 +64,6 @@ describe Projects::MergeRequests::DiffsController, '(JavaScript fixtures)', type
**extra_params
}, format: :json
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/pipeline_schedules.rb b/spec/frontend/fixtures/pipeline_schedules.rb
index aecd56e6198..a70091a3919 100644
--- a/spec/javascripts/fixtures/pipeline_schedules.rb
+++ b/spec/frontend/fixtures/pipeline_schedules.rb
@@ -28,7 +28,7 @@ describe Projects::PipelineSchedulesController, '(JavaScript fixtures)', type: :
id: pipeline_schedule.id
}
- expect(response).to be_success
+ expect(response).to be_successful
end
it 'pipeline_schedules/edit_with_variables.html' do
@@ -38,6 +38,6 @@ describe Projects::PipelineSchedulesController, '(JavaScript fixtures)', type: :
id: pipeline_schedule_populated.id
}
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/pipelines.rb b/spec/frontend/fixtures/pipelines.rb
index 6b6b0eefab9..ed57eb0aa80 100644
--- a/spec/javascripts/fixtures/pipelines.rb
+++ b/spec/frontend/fixtures/pipelines.rb
@@ -29,6 +29,6 @@ describe Projects::PipelinesController, '(JavaScript fixtures)', type: :controll
project_id: project
}, format: :json
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/projects.rb b/spec/frontend/fixtures/projects.rb
index 94c59207898..b6c29003e57 100644
--- a/spec/javascripts/fixtures/projects.rb
+++ b/spec/frontend/fixtures/projects.rb
@@ -18,6 +18,8 @@ describe 'Projects (JavaScript fixtures)', type: :controller do
end
before do
+ stub_licensed_features(variable_environment_scope: true)
+
project.add_maintainer(admin)
sign_in(admin)
allow(SecureRandom).to receive(:hex).and_return('securerandomhex:thereisnospoon')
@@ -34,7 +36,7 @@ describe 'Projects (JavaScript fixtures)', type: :controller do
id: project
}
- expect(response).to be_success
+ expect(response).to be_successful
end
it 'projects/overview.html' do
@@ -43,7 +45,7 @@ describe 'Projects (JavaScript fixtures)', type: :controller do
id: project_with_repo
}
- expect(response).to be_success
+ expect(response).to be_successful
end
it 'projects/edit.html' do
@@ -52,7 +54,7 @@ describe 'Projects (JavaScript fixtures)', type: :controller do
id: project
}
- expect(response).to be_success
+ expect(response).to be_successful
end
end
@@ -63,7 +65,7 @@ describe 'Projects (JavaScript fixtures)', type: :controller do
project_id: project
}
- expect(response).to be_success
+ expect(response).to be_successful
end
it 'projects/ci_cd_settings_with_variables.html' do
@@ -75,7 +77,7 @@ describe 'Projects (JavaScript fixtures)', type: :controller do
project_id: project_variable_populated
}
- expect(response).to be_success
+ expect(response).to be_successful
end
end
end
diff --git a/spec/javascripts/fixtures/prometheus_service.rb b/spec/frontend/fixtures/prometheus_service.rb
index f3171fdd97b..93ee81120d7 100644
--- a/spec/javascripts/fixtures/prometheus_service.rb
+++ b/spec/frontend/fixtures/prometheus_service.rb
@@ -29,6 +29,6 @@ describe Projects::ServicesController, '(JavaScript fixtures)', type: :controlle
id: service.to_param
}
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/raw.rb b/spec/frontend/fixtures/raw.rb
index 801c80a0112..801c80a0112 100644
--- a/spec/javascripts/fixtures/raw.rb
+++ b/spec/frontend/fixtures/raw.rb
diff --git a/spec/javascripts/fixtures/search.rb b/spec/frontend/fixtures/search.rb
index 22fc546d761..c26c6998ae9 100644
--- a/spec/javascripts/fixtures/search.rb
+++ b/spec/frontend/fixtures/search.rb
@@ -12,6 +12,6 @@ describe SearchController, '(JavaScript fixtures)', type: :controller do
it 'search/show.html' do
get :show
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/services.rb b/spec/frontend/fixtures/services.rb
index 2237702ccca..ee1e088f158 100644
--- a/spec/javascripts/fixtures/services.rb
+++ b/spec/frontend/fixtures/services.rb
@@ -29,6 +29,6 @@ describe Projects::ServicesController, '(JavaScript fixtures)', type: :controlle
id: service.to_param
}
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/javascripts/fixtures/sessions.rb b/spec/frontend/fixtures/sessions.rb
index 92b74c01c89..18574ea06b5 100644
--- a/spec/javascripts/fixtures/sessions.rb
+++ b/spec/frontend/fixtures/sessions.rb
@@ -19,7 +19,7 @@ describe 'Sessions (JavaScript fixtures)' do
it 'sessions/new.html' do
get :new
- expect(response).to be_success
+ expect(response).to be_successful
end
end
end
diff --git a/spec/javascripts/fixtures/snippet.rb b/spec/frontend/fixtures/snippet.rb
index ace84b14eb7..23bcdb47ac6 100644
--- a/spec/javascripts/fixtures/snippet.rb
+++ b/spec/frontend/fixtures/snippet.rb
@@ -28,6 +28,6 @@ describe SnippetsController, '(JavaScript fixtures)', type: :controller do
get(:show, params: { id: snippet.to_param })
- expect(response).to be_success
+ expect(response).to be_successful
end
end
diff --git a/spec/frontend/fixtures/static/README.md b/spec/frontend/fixtures/static/README.md
new file mode 100644
index 00000000000..011601d0df8
--- /dev/null
+++ b/spec/frontend/fixtures/static/README.md
@@ -0,0 +1,3 @@
+# Please do not add new files here!
+
+Instead use a Ruby file in the fixtures root directory (`spec/frontend/fixtures/`).
diff --git a/spec/javascripts/fixtures/static/ajax_loading_spinner.html b/spec/frontend/fixtures/static/ajax_loading_spinner.html
index 0e1ebb32b1c..0e1ebb32b1c 100644
--- a/spec/javascripts/fixtures/static/ajax_loading_spinner.html
+++ b/spec/frontend/fixtures/static/ajax_loading_spinner.html
diff --git a/spec/javascripts/fixtures/static/balsamiq_viewer.html b/spec/frontend/fixtures/static/balsamiq_viewer.html
index cdd723d1a84..cdd723d1a84 100644
--- a/spec/javascripts/fixtures/static/balsamiq_viewer.html
+++ b/spec/frontend/fixtures/static/balsamiq_viewer.html
diff --git a/spec/javascripts/fixtures/static/create_item_dropdown.html b/spec/frontend/fixtures/static/create_item_dropdown.html
index d2d38370092..d2d38370092 100644
--- a/spec/javascripts/fixtures/static/create_item_dropdown.html
+++ b/spec/frontend/fixtures/static/create_item_dropdown.html
diff --git a/spec/javascripts/fixtures/static/environments/table.html b/spec/frontend/fixtures/static/environments/table.html
index 417af564ff1..417af564ff1 100644
--- a/spec/javascripts/fixtures/static/environments/table.html
+++ b/spec/frontend/fixtures/static/environments/table.html
diff --git a/spec/frontend/fixtures/static/environments_logs.html b/spec/frontend/fixtures/static/environments_logs.html
new file mode 100644
index 00000000000..6179d3dbc23
--- /dev/null
+++ b/spec/frontend/fixtures/static/environments_logs.html
@@ -0,0 +1,29 @@
+<div class="js-kubernetes-logs" data-logs-path="/root/kubernetes-app/environments/1/logs">
+ <div class="build-page">
+ <div class="build-trace-container prepend-top-default">
+ <div class="top-bar js-top-bar">
+ <div class="truncated-info hidden-xs pull-left"></div>
+ <div class="dropdown prepend-left-10 js-pod-dropdown">
+ <button aria-expanded="false" class="dropdown-menu-toggle" data-toggle="dropdown" type="button">
+ <i class="fa fa-chevron-down"></i>
+ </button>
+ <div class="dropdown-menu dropdown-menu-selectable dropdown-menu-drop-up"></div>
+ </div>
+ <div class="controllers pull-right">
+ <div class="has-tooltip controllers-buttons" data-container="body" data-placement="top" title="Scroll to top">
+ <button class="js-scroll-up btn-scroll btn-transparent btn-blank" disabled type="button"></button>
+ </div>
+ <div class="has-tooltip controllers-buttons" data-container="body" data-placement="top" title="Scroll to bottom">
+ <button class="js-scroll-down btn-scroll btn-transparent btn-blank" disabled type="button"></button>
+ </div>
+ <div class="refresh-control pull-right">
+ <div class="has-tooltip controllers-buttons" data-container="body" data-placement="top" title="Refresh">
+ <button class="js-refresh-log btn-default btn-refresh" disabled type="button"></button>
+ </div>
+ </div>
+ </div>
+ </div>
+ <pre class="build-trace" id="build-trace"><code class="bash js-build-output"><div class="build-loader-animation js-build-refresh"></div></code></pre>
+ </div>
+ </div>
+</div>
diff --git a/spec/javascripts/fixtures/static/event_filter.html b/spec/frontend/fixtures/static/event_filter.html
index 8e9b6fb1b5c..8e9b6fb1b5c 100644
--- a/spec/javascripts/fixtures/static/event_filter.html
+++ b/spec/frontend/fixtures/static/event_filter.html
diff --git a/spec/javascripts/fixtures/static/gl_dropdown.html b/spec/frontend/fixtures/static/gl_dropdown.html
index 08f6738414e..08f6738414e 100644
--- a/spec/javascripts/fixtures/static/gl_dropdown.html
+++ b/spec/frontend/fixtures/static/gl_dropdown.html
diff --git a/spec/javascripts/fixtures/static/gl_field_errors.html b/spec/frontend/fixtures/static/gl_field_errors.html
index f8470e02b7c..f8470e02b7c 100644
--- a/spec/javascripts/fixtures/static/gl_field_errors.html
+++ b/spec/frontend/fixtures/static/gl_field_errors.html
diff --git a/spec/javascripts/fixtures/static/images/green_box.png b/spec/frontend/fixtures/static/images/green_box.png
index cd1ff9f9ade..cd1ff9f9ade 100644
--- a/spec/javascripts/fixtures/static/images/green_box.png
+++ b/spec/frontend/fixtures/static/images/green_box.png
Binary files differ
diff --git a/spec/javascripts/fixtures/static/images/one_white_pixel.png b/spec/frontend/fixtures/static/images/one_white_pixel.png
index 073fcf40a18..073fcf40a18 100644
--- a/spec/javascripts/fixtures/static/images/one_white_pixel.png
+++ b/spec/frontend/fixtures/static/images/one_white_pixel.png
Binary files differ
diff --git a/spec/javascripts/fixtures/static/images/red_box.png b/spec/frontend/fixtures/static/images/red_box.png
index 73b2927da0f..73b2927da0f 100644
--- a/spec/javascripts/fixtures/static/images/red_box.png
+++ b/spec/frontend/fixtures/static/images/red_box.png
Binary files differ
diff --git a/spec/javascripts/fixtures/static/issuable_filter.html b/spec/frontend/fixtures/static/issuable_filter.html
index 06b70fb43f1..06b70fb43f1 100644
--- a/spec/javascripts/fixtures/static/issuable_filter.html
+++ b/spec/frontend/fixtures/static/issuable_filter.html
diff --git a/spec/javascripts/fixtures/static/issue_sidebar_label.html b/spec/frontend/fixtures/static/issue_sidebar_label.html
index ec8fb30f219..ec8fb30f219 100644
--- a/spec/javascripts/fixtures/static/issue_sidebar_label.html
+++ b/spec/frontend/fixtures/static/issue_sidebar_label.html
diff --git a/spec/javascripts/fixtures/static/line_highlighter.html b/spec/frontend/fixtures/static/line_highlighter.html
index 897a25d6760..897a25d6760 100644
--- a/spec/javascripts/fixtures/static/line_highlighter.html
+++ b/spec/frontend/fixtures/static/line_highlighter.html
diff --git a/spec/javascripts/fixtures/static/linked_tabs.html b/spec/frontend/fixtures/static/linked_tabs.html
index c25463bf1db..c25463bf1db 100644
--- a/spec/javascripts/fixtures/static/linked_tabs.html
+++ b/spec/frontend/fixtures/static/linked_tabs.html
diff --git a/spec/javascripts/fixtures/static/merge_requests_show.html b/spec/frontend/fixtures/static/merge_requests_show.html
index 87e36c9f315..87e36c9f315 100644
--- a/spec/javascripts/fixtures/static/merge_requests_show.html
+++ b/spec/frontend/fixtures/static/merge_requests_show.html
diff --git a/spec/javascripts/fixtures/static/mini_dropdown_graph.html b/spec/frontend/fixtures/static/mini_dropdown_graph.html
index cd0b8dec3fc..cd0b8dec3fc 100644
--- a/spec/javascripts/fixtures/static/mini_dropdown_graph.html
+++ b/spec/frontend/fixtures/static/mini_dropdown_graph.html
diff --git a/spec/javascripts/fixtures/static/notebook_viewer.html b/spec/frontend/fixtures/static/notebook_viewer.html
index 4bbb7bf1094..4bbb7bf1094 100644
--- a/spec/javascripts/fixtures/static/notebook_viewer.html
+++ b/spec/frontend/fixtures/static/notebook_viewer.html
diff --git a/spec/javascripts/fixtures/static/oauth_remember_me.html b/spec/frontend/fixtures/static/oauth_remember_me.html
index 9ba1ffc72fe..9ba1ffc72fe 100644
--- a/spec/javascripts/fixtures/static/oauth_remember_me.html
+++ b/spec/frontend/fixtures/static/oauth_remember_me.html
diff --git a/spec/javascripts/fixtures/static/pdf_viewer.html b/spec/frontend/fixtures/static/pdf_viewer.html
index 350d35a262f..350d35a262f 100644
--- a/spec/javascripts/fixtures/static/pdf_viewer.html
+++ b/spec/frontend/fixtures/static/pdf_viewer.html
diff --git a/spec/javascripts/fixtures/static/pipeline_graph.html b/spec/frontend/fixtures/static/pipeline_graph.html
index 422372bb7d5..422372bb7d5 100644
--- a/spec/javascripts/fixtures/static/pipeline_graph.html
+++ b/spec/frontend/fixtures/static/pipeline_graph.html
diff --git a/spec/javascripts/fixtures/static/pipelines.html b/spec/frontend/fixtures/static/pipelines.html
index 42333f94f2f..42333f94f2f 100644
--- a/spec/javascripts/fixtures/static/pipelines.html
+++ b/spec/frontend/fixtures/static/pipelines.html
diff --git a/spec/javascripts/fixtures/static/project_select_combo_button.html b/spec/frontend/fixtures/static/project_select_combo_button.html
index 50c826051c0..50c826051c0 100644
--- a/spec/javascripts/fixtures/static/project_select_combo_button.html
+++ b/spec/frontend/fixtures/static/project_select_combo_button.html
diff --git a/spec/javascripts/fixtures/static/projects.json b/spec/frontend/fixtures/static/projects.json
index 68a150f602a..68a150f602a 100644
--- a/spec/javascripts/fixtures/static/projects.json
+++ b/spec/frontend/fixtures/static/projects.json
diff --git a/spec/javascripts/fixtures/static/search_autocomplete.html b/spec/frontend/fixtures/static/search_autocomplete.html
index 29db9020424..29db9020424 100644
--- a/spec/javascripts/fixtures/static/search_autocomplete.html
+++ b/spec/frontend/fixtures/static/search_autocomplete.html
diff --git a/spec/javascripts/fixtures/static/signin_tabs.html b/spec/frontend/fixtures/static/signin_tabs.html
index 7e66ab9394b..7e66ab9394b 100644
--- a/spec/javascripts/fixtures/static/signin_tabs.html
+++ b/spec/frontend/fixtures/static/signin_tabs.html
diff --git a/spec/javascripts/fixtures/static/sketch_viewer.html b/spec/frontend/fixtures/static/sketch_viewer.html
index e25e554e568..e25e554e568 100644
--- a/spec/javascripts/fixtures/static/sketch_viewer.html
+++ b/spec/frontend/fixtures/static/sketch_viewer.html
diff --git a/spec/javascripts/fixtures/todos.rb b/spec/frontend/fixtures/todos.rb
index d0c8a6eca01..a7c183d2414 100644
--- a/spec/javascripts/fixtures/todos.rb
+++ b/spec/frontend/fixtures/todos.rb
@@ -29,7 +29,7 @@ describe 'Todos (JavaScript fixtures)' do
it 'todos/todos.html' do
get :index
- expect(response).to be_success
+ expect(response).to be_successful
end
end
@@ -48,7 +48,7 @@ describe 'Todos (JavaScript fixtures)' do
issuable_id: issue_2.id
}, format: 'json'
- expect(response).to be_success
+ expect(response).to be_successful
end
end
end
diff --git a/spec/javascripts/fixtures/u2f.rb b/spec/frontend/fixtures/u2f.rb
index f52832b6efb..8ecbc0390cd 100644
--- a/spec/javascripts/fixtures/u2f.rb
+++ b/spec/frontend/fixtures/u2f.rb
@@ -23,7 +23,7 @@ context 'U2F' do
post :create, params: { user: { login: user.username, password: user.password } }
- expect(response).to be_success
+ expect(response).to be_successful
end
end
@@ -38,7 +38,7 @@ context 'U2F' do
it 'u2f/register.html' do
get :show
- expect(response).to be_success
+ expect(response).to be_successful
end
end
end
diff --git a/spec/frontend/helpers/fixtures.js b/spec/frontend/helpers/fixtures.js
index b77bcd6266e..778196843db 100644
--- a/spec/frontend/helpers/fixtures.js
+++ b/spec/frontend/helpers/fixtures.js
@@ -4,12 +4,15 @@ import path from 'path';
import { ErrorWithStack } from 'jest-util';
export function getFixture(relativePath) {
- const absolutePath = path.join(global.fixturesBasePath, relativePath);
+ const basePath = relativePath.startsWith('static/')
+ ? global.staticFixturesBasePath
+ : global.fixturesBasePath;
+ const absolutePath = path.join(basePath, relativePath);
if (!fs.existsSync(absolutePath)) {
throw new ErrorWithStack(
`Fixture file ${relativePath} does not exist.
-Did you run bin/rake karma:fixtures?`,
+Did you run bin/rake frontend:fixtures?`,
getFixture,
);
}
diff --git a/spec/javascripts/boards/board_blank_state_spec.js b/spec/javascripts/boards/board_blank_state_spec.js
index 8e2a947b0dd..b64859ec32a 100644
--- a/spec/javascripts/boards/board_blank_state_spec.js
+++ b/spec/javascripts/boards/board_blank_state_spec.js
@@ -1,7 +1,6 @@
import Vue from 'vue';
import boardsStore from '~/boards/stores/boards_store';
import BoardBlankState from '~/boards/components/board_blank_state.vue';
-import { mockBoardService } from './mock_data';
describe('Boards blank state', () => {
let vm;
@@ -11,9 +10,10 @@ describe('Boards blank state', () => {
const Comp = Vue.extend(BoardBlankState);
boardsStore.create();
- gl.boardService = mockBoardService();
- spyOn(gl.boardService, 'generateDefaultLists').and.callFake(
+ spyOn(boardsStore, 'addList').and.stub();
+ spyOn(boardsStore, 'removeList').and.stub();
+ spyOn(boardsStore, 'generateDefaultLists').and.callFake(
() =>
new Promise((resolve, reject) => {
if (fail) {
@@ -71,9 +71,14 @@ describe('Boards blank state', () => {
vm.$el.querySelector('.btn-success').click();
setTimeout(() => {
- expect(boardsStore.state.lists.length).toBe(2);
- expect(boardsStore.state.lists[0].title).toEqual('To Do');
- expect(boardsStore.state.lists[1].title).toEqual('Doing');
+ expect(boardsStore.addList).toHaveBeenCalledTimes(2);
+ expect(boardsStore.addList).toHaveBeenCalledWith(
+ jasmine.objectContaining({ title: 'To Do' }),
+ );
+
+ expect(boardsStore.addList).toHaveBeenCalledWith(
+ jasmine.objectContaining({ title: 'Doing' }),
+ );
done();
});
@@ -86,7 +91,7 @@ describe('Boards blank state', () => {
setTimeout(() => {
expect(boardsStore.welcomeIsHidden()).toBeFalsy();
- expect(boardsStore.state.lists.length).toBe(1);
+ expect(boardsStore.removeList).toHaveBeenCalledWith(undefined, 'label');
done();
});
diff --git a/spec/javascripts/fixtures/.gitignore b/spec/javascripts/fixtures/.gitignore
index bed020f5b0a..d6b7ef32c84 100644
--- a/spec/javascripts/fixtures/.gitignore
+++ b/spec/javascripts/fixtures/.gitignore
@@ -1,5 +1,2 @@
-*.html.raw
-*.html
-*.json
-*.pdf
-*.bmpr
+*
+!.gitignore
diff --git a/spec/javascripts/fixtures/static/README.md b/spec/javascripts/fixtures/static/README.md
deleted file mode 100644
index b5c2f8233bf..00000000000
--- a/spec/javascripts/fixtures/static/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# Please do not add new files here!
-
-Instead use a Ruby file in the fixtures root directory (`spec/javascripts/fixtures/`).
diff --git a/spec/javascripts/ide/stores/modules/commit/actions_spec.js b/spec/javascripts/ide/stores/modules/commit/actions_spec.js
index 590af53b3f2..14d861f21d2 100644
--- a/spec/javascripts/ide/stores/modules/commit/actions_spec.js
+++ b/spec/javascripts/ide/stores/modules/commit/actions_spec.js
@@ -411,7 +411,7 @@ describe('IDE commit module actions', () => {
expect(visitUrl).toHaveBeenCalledWith(
`webUrl/merge_requests/new?merge_request[source_branch]=${
store.getters['commit/placeholderBranchName']
- }&merge_request[target_branch]=master`,
+ }&merge_request[target_branch]=master&nav_source=webide`,
);
done();
diff --git a/spec/javascripts/ide/stores/mutations/file_spec.js b/spec/javascripts/ide/stores/mutations/file_spec.js
index 7714f66c9a4..1b41c3c2548 100644
--- a/spec/javascripts/ide/stores/mutations/file_spec.js
+++ b/spec/javascripts/ide/stores/mutations/file_spec.js
@@ -103,6 +103,43 @@ describe('IDE store file mutations', () => {
expect(localState.openFiles[0].rawPath).toEqual(rawPath);
expect(localFile.rawPath).toEqual(rawPath);
});
+
+ it('does not mutate certain props on the file', () => {
+ const path = 'New Path';
+ const name = 'New Name';
+ localFile.path = path;
+ localFile.name = name;
+
+ localState.stagedFiles = [localFile];
+ localState.changedFiles = [localFile];
+ localState.openFiles = [localFile];
+
+ mutations.SET_FILE_DATA(localState, {
+ data: {
+ path: 'Old Path',
+ name: 'Old Name',
+ raw: 'Old Raw',
+ base_raw: 'Old Base Raw',
+ },
+ file: localFile,
+ });
+
+ [
+ localState.stagedFiles[0],
+ localState.changedFiles[0],
+ localState.openFiles[0],
+ localFile,
+ ].forEach(f => {
+ expect(f).toEqual(
+ jasmine.objectContaining({
+ path,
+ name,
+ raw: null,
+ baseRaw: null,
+ }),
+ );
+ });
+ });
});
describe('SET_FILE_RAW_DATA', () => {
diff --git a/spec/javascripts/test_constants.js b/spec/javascripts/test_constants.js
index 77c206585fe..c97d47a6406 100644
--- a/spec/javascripts/test_constants.js
+++ b/spec/javascripts/test_constants.js
@@ -1,6 +1,4 @@
-export const FIXTURES_PATH = `/base/${
- process.env.IS_GITLAB_EE ? 'ee/' : ''
-}spec/javascripts/fixtures`;
+export const FIXTURES_PATH = `/fixtures`;
export const TEST_HOST = 'http://test.host';
export const DUMMY_IMAGE_URL = `${FIXTURES_PATH}/static/images/one_white_pixel.png`;
diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
index e6ce3f1bcea..3b7de185cf1 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -496,6 +496,18 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
end
end
+ context 'with restricted internal visibility' do
+ describe 'internal project' do
+ let(:visibility) { Gitlab::VisibilityLevel::INTERNAL }
+
+ it 'uses private visibility' do
+ stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::INTERNAL])
+
+ expect(restorer.restored_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE)
+ end
+ end
+ end
+
context 'with group visibility' do
before do
group = create(:group, visibility_level: group_visibility)
@@ -528,6 +540,14 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
it 'uses the group visibility' do
expect(restorer.restored_project.visibility_level).to eq(group_visibility)
end
+
+ context 'with restricted internal visibility' do
+ it 'sets private visibility' do
+ stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::INTERNAL])
+
+ expect(restorer.restored_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE)
+ end
+ end
end
end
end
diff --git a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
index 6795c1ab56b..e04056b3450 100644
--- a/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/rails_cache_spec.rb
@@ -201,7 +201,15 @@ describe Gitlab::Metrics::Subscribers::RailsCache do
it 'observes cache metric' do
expect(subscriber.send(:metric_cache_operation_duration_seconds))
.to receive(:observe)
- .with(transaction.labels.merge(operation: :delete), event.duration / 1000.0)
+ .with({ operation: :delete }, event.duration / 1000.0)
+
+ subscriber.observe(:delete, event.duration)
+ end
+
+ it 'increments the operations total' do
+ expect(subscriber.send(:metric_cache_operations_total))
+ .to receive(:increment)
+ .with(transaction.labels.merge(operation: :delete))
subscriber.observe(:delete, event.duration)
end
diff --git a/spec/lib/gitlab/slug/environment_spec.rb b/spec/lib/gitlab/slug/environment_spec.rb
new file mode 100644
index 00000000000..7dc583a94b8
--- /dev/null
+++ b/spec/lib/gitlab/slug/environment_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Slug::Environment do
+ describe '#generate' do
+ {
+ "staging-12345678901234567" => "staging-123456789-q517sa",
+ "9-staging-123456789012345" => "env-9-staging-123-q517sa",
+ "staging-1234567890123456" => "staging-1234567890123456",
+ "staging-1234567890123456-" => "staging-123456789-q517sa",
+ "production" => "production",
+ "PRODUCTION" => "production-q517sa",
+ "review/1-foo" => "review-1-foo-q517sa",
+ "1-foo" => "env-1-foo-q517sa",
+ "1/foo" => "env-1-foo-q517sa",
+ "foo-" => "foo",
+ "foo--bar" => "foo-bar-q517sa",
+ "foo**bar" => "foo-bar-q517sa",
+ "*-foo" => "env-foo-q517sa",
+ "staging-12345678-" => "staging-12345678",
+ "staging-12345678-01234567" => "staging-12345678-q517sa",
+ "" => "env-q517sa",
+ nil => "env-q517sa"
+ }.each do |name, matcher|
+ before do
+ # ('a' * 64).to_i(16).to_s(36).last(6) gives 'q517sa'
+ allow(Digest::SHA2).to receive(:hexdigest).with(name).and_return('a' * 64)
+ end
+
+ it "returns a slug matching #{matcher}, given #{name}" do
+ slug = described_class.new(name).generate
+
+ expect(slug).to match(/\A#{matcher}\z/)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb b/spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb
index fa0cf15e1b2..b5e32d1875f 100644
--- a/spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb
+++ b/spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb
@@ -3,19 +3,34 @@
require 'spec_helper'
describe Gitlab::UsageDataCounters::WebIdeCounter, :clean_gitlab_redis_shared_state do
- describe '.increment_commits_count' do
- it 'increments the web ide commits counter by 1' do
- expect do
- described_class.increment_commits_count
- end.to change { described_class.total_commits_count }.by(1)
+ shared_examples 'counter examples' do
+ it 'increments counter and return the total count' do
+ expect(described_class.public_send(total_counter_method)).to eq(0)
+
+ 2.times { described_class.public_send(increment_counter_method) }
+
+ expect(described_class.public_send(total_counter_method)).to eq(2)
end
end
- describe '.total_commits_count' do
- it 'returns the total amount of web ide commits' do
- 2.times { described_class.increment_commits_count }
+ describe 'commits counter' do
+ let(:increment_counter_method) { :increment_commits_count }
+ let(:total_counter_method) { :total_commits_count }
- expect(described_class.total_commits_count).to eq(2)
- end
+ it_behaves_like 'counter examples'
+ end
+
+ describe 'merge requests counter' do
+ let(:increment_counter_method) { :increment_merge_requests_count }
+ let(:total_counter_method) { :total_merge_requests_count }
+
+ it_behaves_like 'counter examples'
+ end
+
+ describe 'views counter' do
+ let(:increment_counter_method) { :increment_views_count }
+ let(:total_counter_method) { :total_views_count }
+
+ it_behaves_like 'counter examples'
end
end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 90a534de202..270dd652c20 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -57,12 +57,22 @@ describe Gitlab::UsageData do
gitaly
database
avg_cycle_analytics
+ web_ide_views
web_ide_commits
+ web_ide_merge_requests
influxdb_metrics_enabled
prometheus_metrics_enabled
))
end
+ it 'calls expected usage data methods' do
+ expect(Gitlab::UsageDataCounters::WebIdeCounter).to receive(:total_commits_count)
+ expect(Gitlab::UsageDataCounters::WebIdeCounter).to receive(:total_merge_requests_count)
+ expect(Gitlab::UsageDataCounters::WebIdeCounter).to receive(:total_views_count)
+
+ subject
+ end
+
it "gathers usage counts" do
expected_keys = %i(
assignee_lists
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index 68224a56515..e19da41c3fe 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -774,4 +774,25 @@ describe Issuable do
end
end
end
+
+ describe '#supports_milestone?' do
+ let(:group) { create(:group) }
+ let(:project) { create(:project, group: group) }
+
+ context "for issues" do
+ let(:issue) { build(:issue, project: project) }
+
+ it 'returns true' do
+ expect(issue.supports_milestone?).to be_truthy
+ end
+ end
+
+ context "for merge requests" do
+ let(:merge_request) { build(:merge_request, target_project: project, source_project: project) }
+
+ it 'returns true' do
+ expect(merge_request.supports_milestone?).to be_truthy
+ end
+ end
+ end
end
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index fe4d64818b4..ce0681c4331 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -762,32 +762,6 @@ describe Environment, :use_clean_rails_memory_store_caching do
end
end
- describe '#generate_slug' do
- SUFFIX = "-[a-z0-9]{6}".freeze
- {
- "staging-12345678901234567" => "staging-123456789" + SUFFIX,
- "9-staging-123456789012345" => "env-9-staging-123" + SUFFIX,
- "staging-1234567890123456" => "staging-1234567890123456",
- "production" => "production",
- "PRODUCTION" => "production" + SUFFIX,
- "review/1-foo" => "review-1-foo" + SUFFIX,
- "1-foo" => "env-1-foo" + SUFFIX,
- "1/foo" => "env-1-foo" + SUFFIX,
- "foo-" => "foo" + SUFFIX,
- "foo--bar" => "foo-bar" + SUFFIX,
- "foo**bar" => "foo-bar" + SUFFIX,
- "*-foo" => "env-foo" + SUFFIX,
- "staging-12345678-" => "staging-12345678" + SUFFIX,
- "staging-12345678-01234567" => "staging-12345678" + SUFFIX
- }.each do |name, matcher|
- it "returns a slug matching #{matcher}, given #{name}" do
- slug = described_class.new(name: name).generate_slug
-
- expect(slug).to match(/\A#{matcher}\z/)
- end
- end
- end
-
describe '#ref_path' do
subject(:environment) do
create(:environment, name: 'staging / review-1')
diff --git a/spec/support/helpers/javascript_fixtures_helpers.rb b/spec/support/helpers/javascript_fixtures_helpers.rb
index cdd7724cc13..e9129bd263e 100644
--- a/spec/support/helpers/javascript_fixtures_helpers.rb
+++ b/spec/support/helpers/javascript_fixtures_helpers.rb
@@ -19,7 +19,7 @@ module JavaScriptFixturesHelpers
end
def fixture_root_path
- (Gitlab.ee? ? 'ee/' : '') + 'spec/javascripts/fixtures'
+ 'tmp/tests/frontend/fixtures' + (Gitlab.ee? ? '-ee' : '')
end
# Public: Removes all fixture files from given directory
diff --git a/spec/support/helpers/test_env.rb b/spec/support/helpers/test_env.rb
index 16938da50cc..b062631b995 100644
--- a/spec/support/helpers/test_env.rb
+++ b/spec/support/helpers/test_env.rb
@@ -130,7 +130,7 @@ module TestEnv
# Keeps gitlab-shell and gitlab-test
def clean_test_path
Dir[TMP_TEST_PATH].each do |entry|
- unless File.basename(entry) =~ /\A(gitaly|gitlab-(shell|test|test_bare|test-fork|test-fork_bare))\z/
+ unless test_dirs.include?(File.basename(entry))
FileUtils.rm_rf(entry)
end
end
@@ -316,6 +316,7 @@ module TestEnv
# These are directories that should be preserved at cleanup time
def test_dirs
@test_dirs ||= %w[
+ frontend
gitaly
gitlab-shell
gitlab-test