Commit 4e9f718e authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 5707f305
...@@ -34,6 +34,7 @@ If applicable, any groups/projects that are happy to have this feature turned on ...@@ -34,6 +34,7 @@ If applicable, any groups/projects that are happy to have this feature turned on
- [ ] Test on staging - [ ] Test on staging
- [ ] Ensure that documentation has been updated - [ ] Ensure that documentation has been updated
- [ ] Enable on GitLab.com for individual groups/projects listed above and verify behaviour - [ ] Enable on GitLab.com for individual groups/projects listed above and verify behaviour
- [ ] Coordinate a time to enable the flag with `#production` and `#g_delivery` on slack.
- [ ] Announce on the issue an estimated time this will be enabled on GitLab.com - [ ] Announce on the issue an estimated time this will be enabled on GitLab.com
- [ ] Enable on GitLab.com by running chatops command in `#production` - [ ] Enable on GitLab.com by running chatops command in `#production`
- [ ] Cross post chatops slack command to `#support_gitlab-com` and in your team channel - [ ] Cross post chatops slack command to `#support_gitlab-com` and in your team channel
......
...@@ -4215,7 +4215,7 @@ Please view this file on the master branch, on stable branches it's out of date. ...@@ -4215,7 +4215,7 @@ Please view this file on the master branch, on stable branches it's out of date.
## 8.14.0 (2016-11-22) ## 8.14.0 (2016-11-22)
- Added Backfill service for Geo. !861 - Added Backfill service for Geo. !861
- Fix for autosuggested approvers(https://gitlab.com/gitlab-org/gitlab-ee/issues/1273). - Fix for autosuggested approvers(https://gitlab.com/gitlab-org/gitlab/issues/1273).
- Gracefully recover from previously failed rebase. - Gracefully recover from previously failed rebase.
- Disable retries for remote mirror update worker. !848 - Disable retries for remote mirror update worker. !848
- Fix Approvals API documentation. - Fix Approvals API documentation.
......
...@@ -8367,7 +8367,7 @@ entry. ...@@ -8367,7 +8367,7 @@ entry.
- Reinstate is_admin flag in users api when authenticated user is an admin. !12211 (rickettm) - Reinstate is_admin flag in users api when authenticated user is an admin. !12211 (rickettm)
- Fix edit button for deploy keys available from other projects. !12301 (Alexander Randa) - Fix edit button for deploy keys available from other projects. !12301 (Alexander Randa)
- Fix passing CI_ENVIRONMENT_NAME and CI_ENVIRONMENT_SLUG for CI_ENVIRONMENT_URL. !12344 - Fix passing CI_ENVIRONMENT_NAME and CI_ENVIRONMENT_SLUG for CI_ENVIRONMENT_URL. !12344
- Disable environment list refresh due to bug https://gitlab.com/gitlab-org/gitlab-ee/issues/2677. !12347 - Disable environment list refresh due to bug https://gitlab.com/gitlab-org/gitlab/issues/2677. !12347
- Standardize timeline note margins across different viewport sizes. !12364 - Standardize timeline note margins across different viewport sizes. !12364
- Fix Ordered Task List Items. !31483 (Jared Deckard <jared.deckard@gmail.com>) - Fix Ordered Task List Items. !31483 (Jared Deckard <jared.deckard@gmail.com>)
- Upgrade dependency to Go 1.8.3. !31943 - Upgrade dependency to Go 1.8.3. !31943
......
...@@ -311,7 +311,7 @@ gem 'gettext', '~> 3.2.2', require: false, group: :development ...@@ -311,7 +311,7 @@ gem 'gettext', '~> 3.2.2', require: false, group: :development
gem 'batch-loader', '~> 1.4.0' gem 'batch-loader', '~> 1.4.0'
# Perf bar # Perf bar
# https://gitlab.com/gitlab-org/gitlab-ee/issues/13996 # https://gitlab.com/gitlab-org/gitlab/issues/13996
gem 'gitlab-peek', '~> 0.0.1', require: 'peek' gem 'gitlab-peek', '~> 0.0.1', require: 'peek'
# Snowplow events tracking # Snowplow events tracking
......
...@@ -33,10 +33,11 @@ export default { ...@@ -33,10 +33,11 @@ export default {
}, },
[types.ADD_NEW_REPLY_TO_DISCUSSION](state, note) { [types.ADD_NEW_REPLY_TO_DISCUSSION](state, note) {
const noteObj = utils.findNoteObjectById(state.discussions, note.discussion_id); const discussion = utils.findNoteObjectById(state.discussions, note.discussion_id);
const existingNote = discussion && utils.findNoteObjectById(discussion.notes, note.id);
if (noteObj) { if (discussion && !existingNote) {
noteObj.notes.push(note); discussion.notes.push(note);
} }
}, },
......
...@@ -523,6 +523,7 @@ ...@@ -523,6 +523,7 @@
margin-top: 4px; margin-top: 4px;
color: $gl-text-color; color: $gl-text-color;
left: auto; left: auto;
max-height: $dropdown-max-height-lg;
li.current-user { li.current-user {
padding: $dropdown-item-padding-y $dropdown-item-padding-x; padding: $dropdown-item-padding-y $dropdown-item-padding-x;
......
...@@ -21,6 +21,23 @@ ...@@ -21,6 +21,23 @@
- if current_user_menu?(:settings) - if current_user_menu?(:settings)
%li %li
= link_to s_("CurrentUser|Settings"), profile_path, data: { qa_selector: 'settings_link' } = link_to s_("CurrentUser|Settings"), profile_path, data: { qa_selector: 'settings_link' }
- if current_user_menu?(:help)
%li.divider.d-md-none
%li.d-md-none
= link_to _("Help"), help_path
%li.d-md-none
= link_to _("Support"), support_url
= render_if_exists "shared/learn_gitlab_menu_item"
%li.d-md-none
= link_to _("Submit feedback"), "https://about.gitlab.com/submit-feedback"
- if current_user_menu?(:help) || current_user_menu?(:settings) || current_user_menu?(:profile)
= render 'shared/user_dropdown_contributing_link'
= render_if_exists 'shared/user_dropdown_instance_review'
- if Gitlab.com?
%li.js-canary-link.d-md-none
= link_to _("Switch to GitLab Next"), "https://next.gitlab.com/"
- if current_user_menu?(:sign_out) - if current_user_menu?(:sign_out)
%li.divider %li.divider
%li %li
......
...@@ -33,9 +33,9 @@ ...@@ -33,9 +33,9 @@
- if current_user - if current_user
= render 'layouts/header/new_dropdown' = render 'layouts/header/new_dropdown'
- if header_link?(:search) - if header_link?(:search)
%li.nav-item.d-none.d-sm-none.d-md-block.m-auto %li.nav-item.d-none.d-lg-block.m-auto
= render 'layouts/search' unless current_controller?(:search) = render 'layouts/search' unless current_controller?(:search)
%li.nav-item.d-inline-block.d-sm-none.d-md-none %li.nav-item.d-inline-block.d-lg-none
= link_to search_path_url, title: _('Search'), aria: { label: _('Search') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do = link_to search_path_url, title: _('Search'), aria: { label: _('Search') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('search', size: 16) = sprite_icon('search', size: 16)
- if header_link?(:issues) - if header_link?(:issues)
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
= sprite_icon('todo-done', size: 16) = sprite_icon('todo-done', size: 16)
%span.badge.badge-pill.todos-count{ class: ('hidden' if todos_pending_count.zero?) } %span.badge.badge-pill.todos-count{ class: ('hidden' if todos_pending_count.zero?) }
= todos_count_format(todos_pending_count) = todos_count_format(todos_pending_count)
%li.nav-item.header-help.dropdown %li.nav-item.header-help.dropdown.d-none.d-md-block
= link_to help_path, class: 'header-help-dropdown-toggle', data: { toggle: "dropdown" } do = link_to help_path, class: 'header-help-dropdown-toggle', data: { toggle: "dropdown" } do
= sprite_icon('question', size: 16) = sprite_icon('question', size: 16)
= sprite_icon('angle-down', css_class: 'caret-down') = sprite_icon('angle-down', css_class: 'caret-down')
......
...@@ -10,37 +10,26 @@ ...@@ -10,37 +10,26 @@
= render "layouts/nav/projects_dropdown/show" = render "layouts/nav/projects_dropdown/show"
- if dashboard_nav_link?(:groups) - if dashboard_nav_link?(:groups)
= nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { id: 'nav-groups-dropdown', class: "home dropdown header-groups qa-groups-dropdown", data: { track_label: "groups_dropdown", track_event: "click_dropdown", track_value: "" } }) do = nav_link(controller: ['dashboard/groups', 'explore/groups'], html_options: { id: 'nav-groups-dropdown', class: "d-none d-md-block home dropdown header-groups qa-groups-dropdown", data: { track_label: "groups_dropdown", track_event: "click_dropdown", track_value: "" } }) do
%button.btn{ type: 'button', data: { toggle: "dropdown" } } %button.btn{ type: 'button', data: { toggle: "dropdown" } }
= _('Groups') = _('Groups')
= sprite_icon('angle-down', css_class: 'caret-down') = sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu.frequent-items-dropdown-menu .dropdown-menu.frequent-items-dropdown-menu
= render "layouts/nav/groups_dropdown/show" = render "layouts/nav/groups_dropdown/show"
- if dashboard_nav_link?(:activity)
= nav_link(path: 'dashboard#activity', html_options: { class: ["d-none d-xl-block", ("d-lg-block" unless has_extra_nav_icons?)] }) do
= link_to activity_dashboard_path, class: 'dashboard-shortcuts-activity' do
= _('Activity')
- if dashboard_nav_link?(:milestones)
= nav_link(controller: 'dashboard/milestones', html_options: { class: ["d-none d-xl-block", ("d-lg-block" unless has_extra_nav_icons?)] }) do
= link_to dashboard_milestones_path, class: 'dashboard-shortcuts-milestones' do
= _('Milestones')
- if dashboard_nav_link?(:snippets)
= nav_link(controller: 'dashboard/snippets', html_options: { class: ["d-none d-xl-block", ("d-lg-block" unless has_extra_nav_icons?)] }) do
= link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets qa-snippets-link' do
= _('Snippets')
= render_if_exists 'layouts/nav/sidebar/analytics_link' = render_if_exists 'layouts/nav/sidebar/analytics_link'
- if any_dashboard_nav_link?([:groups, :milestones, :activity, :snippets]) - if any_dashboard_nav_link?([:groups, :milestones, :activity, :snippets])
%li.header-more.dropdown.d-xl-none{ class: ('d-lg-none' unless has_extra_nav_icons?) } %li.header-more.dropdown
%a{ href: "#", data: { toggle: "dropdown" } } %a{ href: "#", data: { toggle: "dropdown" } }
= _('More') = _('More')
= sprite_icon('angle-down', css_class: 'caret-down') = sprite_icon('angle-down', css_class: 'caret-down')
.dropdown-menu .dropdown-menu
%ul %ul
- if dashboard_nav_link?(:groups)
%li.d-md-none
= link_to dashboard_groups_path do
= _('Groups')
- if dashboard_nav_link?(:activity) - if dashboard_nav_link?(:activity)
= nav_link(path: 'dashboard#activity') do = nav_link(path: 'dashboard#activity') do
= link_to activity_dashboard_path do = link_to activity_dashboard_path do
...@@ -53,20 +42,20 @@ ...@@ -53,20 +42,20 @@
- if dashboard_nav_link?(:snippets) - if dashboard_nav_link?(:snippets)
= nav_link(controller: 'dashboard/snippets') do = nav_link(controller: 'dashboard/snippets') do
= link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets' do = link_to dashboard_snippets_path, class: 'dashboard-shortcuts-snippets qa-snippets-link' do
= _('Snippets') = _('Snippets')
= render_if_exists 'layouts/nav/sidebar/analytics_more_link' = render_if_exists 'layouts/nav/sidebar/analytics_more_link'
%li.dropdown.d-lg-none %li.dropdown
= render_if_exists 'dashboard/nav_link_list' = render_if_exists 'dashboard/nav_link_list'
- if can?(current_user, :read_instance_statistics) - if can?(current_user, :read_instance_statistics)
= nav_link(controller: [:conversational_development_index, :cohorts], html_options: { class: 'd-lg-none' }) do = nav_link(controller: [:conversational_development_index, :cohorts]) do
= link_to instance_statistics_root_path do = link_to instance_statistics_root_path do
= _('Instance Statistics') = _('Instance Statistics')
- if current_user.admin? - if current_user.admin?
= nav_link(controller: 'admin/dashboard') do = nav_link(controller: 'admin/dashboard') do
= link_to admin_root_path, class: 'd-lg-none admin-icon qa-admin-area-link' do = link_to admin_root_path, class: 'admin-icon qa-admin-area-link d-xl-none' do
= _('Admin Area') = _('Admin Area')
- if Feature.enabled?(:user_mode_in_session) - if Feature.enabled?(:user_mode_in_session)
- if header_link?(:admin_mode) - if header_link?(:admin_mode)
...@@ -79,45 +68,19 @@ ...@@ -79,45 +68,19 @@
= _('Enter admin mode') = _('Enter admin mode')
- if Gitlab::Sherlock.enabled? - if Gitlab::Sherlock.enabled?
%li %li
= link_to sherlock_transactions_path, class: 'd-lg-none admin-icon' do = link_to sherlock_transactions_path, class: 'admin-icon' do
= _('Sherlock Transactions') = _('Sherlock Transactions')
- if current_user.admin?
= nav_link(controller: 'admin/dashboard', html_options: { class: "d-none d-xl-block"}) do
= link_to admin_root_path, class: 'admin-icon qa-admin-area-link', title: _('Admin Area'), aria: { label: _('Admin Area') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('admin', size: 18)
-# Shortcut to Dashboard > Projects -# Shortcut to Dashboard > Projects
- if dashboard_nav_link?(:projects) - if dashboard_nav_link?(:projects)
%li.hidden %li.hidden
= link_to dashboard_projects_path, class: 'dashboard-shortcuts-projects' do = link_to dashboard_projects_path, class: 'dashboard-shortcuts-projects' do
= _('Projects') = _('Projects')
- if current_controller?('ide')
%li.line-separator.d-none.d-sm-block
= nav_link(controller: 'ide') do
= link_to '#', class: 'dashboard-shortcuts-web-ide' do
= _('Web IDE')
%li.dropdown{ class: 'd-none d-lg-block' }
= render_if_exists 'dashboard/nav_link'
- if can?(current_user, :read_instance_statistics)
= nav_link(controller: [:conversational_development_index, :cohorts], html_options: { class: "d-none d-lg-block d-xl-block"}) do
= link_to instance_statistics_root_path, title: _('Instance Statistics'), aria: { label: _('Instance Statistics') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('chart', size: 18)
- if current_user.admin?
= nav_link(controller: 'admin/dashboard', html_options: { class: "d-none d-lg-block d-xl-block"}) do
= link_to admin_root_path, class: 'admin-icon qa-admin-area-link', title: _('Admin Area'), aria: { label: _('Admin Area') }, data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= sprite_icon('admin', size: 18)
- if Feature.enabled?(:user_mode_in_session)
- if header_link?(:admin_mode)
= nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block d-xl-block"}) do
= link_to destroy_admin_session_path, title: _('Leave admin mode'), aria: { label: _('Leave admin mode') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
= sprite_icon('lock-open', size: 18)
- elsif current_user.admin?
= nav_link(controller: 'admin/sessions', html_options: { class: "d-none d-lg-block d-xl-block"}) do
= link_to new_admin_session_path, title: _('Enter admin mode'), aria: { label: _('Enter admin mode') }, data: { toggle: 'tooltip', placement: 'bottom', container: 'body' } do
= sprite_icon('lock', size: 18)
- if Gitlab::Sherlock.enabled?
%li
= link_to sherlock_transactions_path, class: 'admin-icon d-none d-lg-block d-xl-block', title: _('Sherlock Transactions'),
data: {toggle: 'tooltip', placement: 'bottom', container: 'body'} do
= icon('tachometer fw')
= render_if_exists 'layouts/nav/geo_primary_node_url' = render_if_exists 'layouts/nav/geo_primary_node_url'
---
title: Fix new discussion replies sometimes showing up twice
merge_request: 17255
author:
type: fixed
---
title: Update top nav bar to fit all content in at all screen sizes
merge_request:
author:
type: fixed
---
title: Added 'copy link' in epic comment dropdown.
merge_request: 17224
author:
type: added
---
title: Catch unhandled exceptions in health checks
merge_request: 17694
author:
type: fixed
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
# Sync remaining records for issues/merge_requests tables where state_id # Sync remaining records for issues/merge_requests tables where state_id
# is still null. # is still null.
# For more information check: https://gitlab.com/gitlab-org/gitlab-ee/issues/26823 # For more information check: https://gitlab.com/gitlab-org/gitlab/issues/26823
# It creates a temporary index before performing the UPDATES to sync values. # It creates a temporary index before performing the UPDATES to sync values.
# #
# In 09-11-2019 we have the following numbers for records with state_id == nil: # In 09-11-2019 we have the following numbers for records with state_id == nil:
......
...@@ -28,77 +28,13 @@ to something that evaluates as `false`. The same works for running tests ...@@ -28,77 +28,13 @@ to something that evaluates as `false`. The same works for running tests
## Separation of EE code ## Separation of EE code
We want a [single code base][] eventually, but before we reach the goal, All EE code should be put inside the `ee/` top-level directory. The
we still need to merge changes from GitLab CE to EE. To help us get there,
we should make sure that we no longer edit CE files in place in order to
implement EE features.
Instead, all EE code should be put inside the `ee/` top-level directory. The
rest of the code should be as close to the CE files as possible. rest of the code should be as close to the CE files as possible.
[single code base]: https://gitlab.com/gitlab-org/gitlab/issues/2952#note_41016454
### EE-specific comments
When complete separation can't be achieved with the `ee/` directory, you can wrap
code in EE specific comments to designate the difference from CE/EE and add
some context for someone resolving a conflict.
```rb
# EE-specific start
stub_licensed_features(variable_environment_scope: true)
# EE specific end
```
```haml
-# EE-specific start
= render 'ci/variables/environment_scope', form_field: form_field, variable: variable
-# EE-specific end
```
EE-specific comments should not be backported to CE.
**Note:** This is only meant as a workaround, we should follow up and
resolve this soon.
### Detection of EE-only files
For each commit (except on `master`), the `ee-files-location-check` CI job tries
to detect if there are any new files that are EE-only. If any file is detected,
the job fails with an explanation of why and what to do to make it pass.
Basically, the fix is simple: `git mv <file> ee/<file>`.
#### How to name your branches?
For any EE branch, the job will try to detect its CE counterpart by removing any
`ee-` prefix or `-ee` suffix from the EE branch name, and matching the last
branch that contains it.
For instance, from the EE branch `new-shiny-feature-ee` (or
`ee-new-shiny-feature`), the job would find the corresponding CE branches:
- `new-shiny-feature`
- `ce-new-shiny-feature`
- `new-shiny-feature-ce`
- `my-super-new-shiny-feature-in-ce`
#### Whitelist some EE-only files that cannot be moved to `ee/`
The `ee-files-location-check` CI job provides a whitelist of files or folders
that cannot or should not be moved to `ee/`. Feel free to open an issue to
discuss adding a new file/folder to this whitelist.
For instance, it was decided that moving EE-only files from `qa/` to `ee/qa/`
would make it difficult to build the `gitLab-{ce,ee}-qa` Docker images and it
was [not worth the complexity].
[not worth the complexity]: https://gitlab.com/gitlab-org/gitlab/issues/4997#note_59764702
### EE-only features ### EE-only features
If the feature being developed is not present in any form in CE, we don't If the feature being developed is not present in any form in CE, we don't
need to put the codes under `EE` namespace. For example, an EE model could need to put the code under the `EE` namespace. For example, an EE model could
go into: `ee/app/models/awesome.rb` using `Awesome` as the class name. This go into: `ee/app/models/awesome.rb` using `Awesome` as the class name. This
is applied not only to models. Here's a list of other examples: is applied not only to models. Here's a list of other examples:
...@@ -116,7 +52,7 @@ is applied not only to models. Here's a list of other examples: ...@@ -116,7 +52,7 @@ is applied not only to models. Here's a list of other examples:
- `ee/app/views/foo.html.haml` - `ee/app/views/foo.html.haml`
- `ee/app/views/foo/_bar.html.haml` - `ee/app/views/foo/_bar.html.haml`
This works because for every path that are present in CE's eager-load/auto-load This works because for every path that is present in CE's eager-load/auto-load
paths, we add the same `ee/`-prepended path in [`config/application.rb`]. paths, we add the same `ee/`-prepended path in [`config/application.rb`].
This also applies to views. This also applies to views.
...@@ -441,13 +377,10 @@ CE and EE. ...@@ -441,13 +377,10 @@ CE and EE.
The advantages of this: The advantages of this:
- Minimal code difference between CE and EE. - Very clear hints about where we're extending EE views while reading CE code.
- Very clear hints about where we're extending EE views while reading CE codes.
The disadvantage of this: The disadvantage of this:
- Slightly more work while developing EE features, because now we need to
port `render_if_exists` to CE.
- If we have typos in the partial name, it would be silently ignored. - If we have typos in the partial name, it would be silently ignored.
##### Caveats ##### Caveats
...@@ -858,7 +791,7 @@ end ...@@ -858,7 +791,7 @@ end
### Code in `spec/` ### Code in `spec/`
When you're testing EE-only features, avoid adding examples to the When you're testing EE-only features, avoid adding examples to the
existing CE specs. Also do no change existing CE examples, since they existing CE specs. Also do not change existing CE examples, since they
should remain working as-is when EE is running without a license. should remain working as-is when EE is running without a license.
Instead place EE specs in the `ee/spec` folder. Instead place EE specs in the `ee/spec` folder.
...@@ -992,10 +925,8 @@ For regular JS files, the approach is similar. ...@@ -992,10 +925,8 @@ For regular JS files, the approach is similar.
## SCSS code in `assets/stylesheets` ## SCSS code in `assets/stylesheets`
To separate EE-specific styles in SCSS files, if a component you're adding styles for If a component you're adding styles for is limited to EE, it is better to have a
is limited to only EE, it is better to have a separate SCSS file in appropriate directory separate SCSS file in an appropriate directory within `app/assets/stylesheets`.
within `app/assets/stylesheets`.
See [backporting changes](#backporting-changes-from-ee-to-ce) for instructions on how to merge changes safely.
In some cases, this is not entirely possible or creating dedicated SCSS file is an overkill, In some cases, this is not entirely possible or creating dedicated SCSS file is an overkill,
e.g. a text style of some component is different for EE. In such cases, e.g. a text style of some component is different for EE. In such cases,
...@@ -1037,24 +968,6 @@ to avoid conflicts during CE to EE merge. ...@@ -1037,24 +968,6 @@ to avoid conflicts during CE to EE merge.
// EE-specific end // EE-specific end
``` ```
## Backporting changes from EE to CE
Until the work completed to merge the ce and ee codebases, which is tracked on [epic &802](https://gitlab.com/groups/gitlab-org/-/epics/802), there exists times in which some changes for EE require specific changes to the CE
code base. Examples of backports include the following:
- Features intended or originally built for EE that are later decided to move to CE
- Sometimes some code in CE may impact the EE feature
Here is a workflow to make sure those changes end up backported safely into CE too.
1. **Make your changes in the EE branch.** If possible, keep a separated commit (to be squashed) to help backporting and review.
1. **Open merge request to EE project.**
1. **Apply the changes you made to CE files in a branch of the CE project.** (Tip: Use `patch` with the diff from your commit in EE branch)
1. **Open merge request to CE project**, referring it's a backport of EE changes and link to MR open in EE.
1. Once EE MR is merged, the MR towards CE can be merged. **But not before**.
**Note:** regarding SCSS, make sure the files living outside `/ee/` don't diverge between CE and EE projects.
## GitLab-svgs ## GitLab-svgs
Conflicts in `app/assets/images/icons.json` or `app/assets/images/icons.svg` can Conflicts in `app/assets/images/icons.json` or `app/assets/images/icons.svg` can
......
...@@ -516,11 +516,6 @@ glob otherwise your shell may split it into multiple arguments: ...@@ -516,11 +516,6 @@ glob otherwise your shell may split it into multiple arguments:
yarn karma -f 'spec/javascripts/ide/**/file_spec.js' yarn karma -f 'spec/javascripts/ide/**/file_spec.js'
``` ```
## RSpec feature integration tests
Information on setting up and running RSpec integration tests with
[Capybara] can be found in the [Testing Best Practices](best_practices.md).
## Frontend test fixtures ## Frontend test fixtures
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. 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.
...@@ -598,7 +593,6 @@ end ...@@ -598,7 +593,6 @@ end
[karma]: http://karma-runner.github.io/ [karma]: http://karma-runner.github.io/
[vue-test]: ../fe_guide/vue.md#testing-vue-components [vue-test]: ../fe_guide/vue.md#testing-vue-components
[rspec]: https://github.com/rspec/rspec-rails#feature-specs [rspec]: https://github.com/rspec/rspec-rails#feature-specs
[capybara]: https://github.com/teamcapybara/capybara
[jasmine]: https://jasmine.github.io/ [jasmine]: https://jasmine.github.io/
## Overview of Frontend Testing Levels ## Overview of Frontend Testing Levels
...@@ -955,7 +949,11 @@ graph RL ...@@ -955,7 +949,11 @@ graph RL
In contrast to [frontend integration tests](#frontend-integration-tests), feature tests make requests against the real backend instead of using fixtures. In contrast to [frontend integration tests](#frontend-integration-tests), feature tests make requests against the real backend instead of using fixtures.
This also implies that database queries are executed which makes this category significantly slower. This also implies that database queries are executed which makes this category significantly slower.
See also the [RSpec testing guidelines](../testing_guide/best_practices.md#rspec). See also
- The [RSpec testing guidelines](../testing_guide/best_practices.md#rspec).
- System / Feature tests in the [Testing Best Practices](best_practices.md#system--feature-tests).
- [Issue #26159](https://gitlab.com/gitlab-org/gitlab/issues/26159) which aims at combine those guidelines with this page.
```mermaid ```mermaid
graph RL graph RL
......
...@@ -484,6 +484,9 @@ sudo -u git -H git config --global repack.writeBitmaps true ...@@ -484,6 +484,9 @@ sudo -u git -H git config --global repack.writeBitmaps true
# Enable push options # Enable push options
sudo -u git -H git config --global receive.advertisePushOptions true sudo -u git -H git config --global receive.advertisePushOptions true
# Enable fsyncObjectFiles to reduce risk of repository corruption if the server crashes
sudo -u git -H git config --global core.fsyncObjectFiles true
# Configure Redis connection settings # Configure Redis connection settings
sudo -u git -H cp config/resque.yml.example config/resque.yml sudo -u git -H cp config/resque.yml.example config/resque.yml
......
...@@ -14,6 +14,8 @@ module Gitlab ...@@ -14,6 +14,8 @@ module Gitlab
else else
HealthChecks::Result.new(false, "unexpected #{human_name} check result: #{check_result}") HealthChecks::Result.new(false, "unexpected #{human_name} check result: #{check_result}")
end end
rescue => e
HealthChecks::Result.new(false, "unexpected #{human_name} check result: #{e}")
end end
def metrics def metrics
......
...@@ -27,20 +27,4 @@ RSpec.describe 'Dashboard Active Tab', :js do ...@@ -27,20 +27,4 @@ RSpec.describe 'Dashboard Active Tab', :js do
subject { visit dashboard_groups_path } subject { visit dashboard_groups_path }
end end
end end
context 'on activity projects' do
it_behaves_like 'page has active tab', 'Activity' do
subject { visit activity_dashboard_path }
end
end
context 'on instance statistics' do
subject { visit instance_statistics_root_path }
it 'shows Instance Statistics` as active' do
subject
expect(find('.navbar-sub-nav li.active')).to have_link('Instance Statistics')
end
end
end end
...@@ -48,9 +48,22 @@ describe('Notes Store mutations', () => { ...@@ -48,9 +48,22 @@ describe('Notes Store mutations', () => {
}); });
describe('ADD_NEW_REPLY_TO_DISCUSSION', () => { describe('ADD_NEW_REPLY_TO_DISCUSSION', () => {
it('should add a reply to a specific discussion', () => {
const state = { discussions: [discussionMock] };
const newReply = Object.assign({}, note, { discussion_id: discussionMock.id }); const newReply = Object.assign({}, note, { discussion_id: discussionMock.id });
let state;
beforeEach(() => {
state = { discussions: [{ ...discussionMock }] };
});
it('should add a reply to a specific discussion', () => {
mutations.ADD_NEW_REPLY_TO_DISCUSSION(state, newReply);
expect(state.discussions[0].notes.length).toEqual(4);
});
it('should not add the note if it already exists in the discussion', () => {
mutations.ADD_NEW_REPLY_TO_DISCUSSION(state, newReply);
mutations.ADD_NEW_REPLY_TO_DISCUSSION(state, newReply); mutations.ADD_NEW_REPLY_TO_DISCUSSION(state, newReply);
expect(state.discussions[0].notes.length).toEqual(4); expect(state.discussions[0].notes.length).toEqual(4);
......
...@@ -57,5 +57,13 @@ shared_context 'simple_check' do |metrics_prefix, check_name, success_result| ...@@ -57,5 +57,13 @@ shared_context 'simple_check' do |metrics_prefix, check_name, success_result|
it { is_expected.to have_attributes(success: false, message: "#{described_class.human_name} check timed out") } it { is_expected.to have_attributes(success: false, message: "#{described_class.human_name} check timed out") }
end end
context 'Check is raising an unhandled exception' do
before do
allow(described_class).to receive(:check ).and_raise "unexpected error"
end
it { is_expected.to have_attributes(success: false, message: "unexpected #{described_class.human_name} check result: unexpected error") }
end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment