summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-04-16 09:09:37 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-04-16 09:09:37 +0000
commit513eff621044e77bc00cd1b4ae0cb5e0e7c2e77e (patch)
tree1de915ccc488a661129b410db83ad9f20a7c806c
parent1ab35c9208287638a097abc895738fbc0c0860e6 (diff)
downloadgitlab-ce-513eff621044e77bc00cd1b4ae0cb5e0e7c2e77e.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/admin/application_settings/setup_metrics_and_profiling.js8
-rw-r--r--app/assets/javascripts/diffs/store/utils.js1
-rw-r--r--app/assets/javascripts/logs/constants.js2
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/index.js9
-rw-r--r--app/assets/javascripts/pages/admin/application_settings/payload_previewer.js (renamed from app/assets/javascripts/pages/admin/application_settings/usage_ping_payload.js)4
-rw-r--r--app/assets/javascripts/static_site_editor/components/saved_changes_message.vue2
-rw-r--r--app/assets/javascripts/static_site_editor/components/static_site_editor.vue12
-rw-r--r--app/assets/javascripts/static_site_editor/components/submit_changes_error.vue24
-rw-r--r--app/assets/javascripts/static_site_editor/store/actions.js7
-rw-r--r--app/assets/javascripts/static_site_editor/store/mutation_types.js1
-rw-r--r--app/assets/javascripts/static_site_editor/store/mutations.js7
-rw-r--r--app/assets/javascripts/static_site_editor/store/state.js1
-rw-r--r--app/models/diff_note_position.rb2
-rw-r--r--app/models/project_services/prometheus_service.rb6
-rw-r--r--app/views/projects/commits/_commits.html.haml9
-rw-r--r--app/views/projects/services/_form.html.haml9
-rw-r--r--app/views/projects/services/prometheus/_help.html.haml6
-rw-r--r--app/views/projects/settings/operations/_prometheus.html.haml6
-rw-r--r--changelogs/unreleased/14984-add-text-for-empty-commit-list.yml5
-rw-r--r--changelogs/unreleased/205058-add-env-vars-to-ds.yml5
-rw-r--r--changelogs/unreleased/207233-k8s-cluster-blocks-project-manual-prometheus-configuration.yml5
-rw-r--r--changelogs/unreleased/214108-log-explorer-timestamp-in-the-logs-presented-in-utc-and-should-be-.yml5
-rw-r--r--changelogs/unreleased/dblessing-add-missing-on-delete-fk-constraints.yml5
-rw-r--r--changelogs/unreleased/display-retry-button-in-error-message.yml5
-rw-r--r--changelogs/unreleased/do-not-display-branch-link.yml5
-rw-r--r--changelogs/unreleased/feature-bump-cluster-applications-to-0-15.yml5
-rw-r--r--changelogs/unreleased/multi-line-notes-take-3.yml5
-rw-r--r--config/routes/project.rb4
-rw-r--r--config/routes/repository.rb3
-rw-r--r--config/routes/repository_scoped.rb6
-rw-r--r--db/migrate/20200407171133_add_protected_tag_create_access_levels_user_id_foreign_key.rb31
-rw-r--r--db/migrate/20200407171417_validate_protected_tag_create_access_levels_user_id_foreign_key.rb16
-rw-r--r--db/migrate/20200408154331_add_protected_branch_merge_access_levels_user_id_foreign_key.rb31
-rw-r--r--db/migrate/20200408154349_validate_protected_branch_merge_access_levels_user_id_foreign_key.rb16
-rw-r--r--db/migrate/20200408154411_add_path_locks_user_id_foreign_key.rb31
-rw-r--r--db/migrate/20200408154428_validate_path_locks_user_id_foreign_key.rb16
-rw-r--r--db/migrate/20200408154455_add_protected_branch_push_access_levels_user_id_foreign_key.rb31
-rw-r--r--db/migrate/20200408154533_validate_protected_branch_push_access_levels_user_id_foreign_key.rb16
-rw-r--r--db/migrate/20200408154604_add_u2f_registrations_user_id_foreign_key.rb31
-rw-r--r--db/migrate/20200408154624_validate_u2f_registrations_user_id_foreign_key.rb16
-rw-r--r--db/structure.sql40
-rw-r--r--doc/api/discussions.md49
-rw-r--r--doc/ci/review_apps/index.md16
-rw-r--r--doc/development/architecture.md2
-rw-r--r--doc/subscriptions/index.md5
-rw-r--r--lib/api/discussions.rb5
-rw-r--r--lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml4
-rw-r--r--lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml2
-rw-r--r--lib/gitlab/diff/formatters/text_formatter.rb4
-rw-r--r--locale/gitlab.pot30
-rw-r--r--package.json2
-rw-r--r--spec/factories/diff_position.rb10
-rw-r--r--spec/features/admin/admin_settings_spec.rb15
-rw-r--r--spec/features/projects/environments_pod_logs_spec.rb4
-rw-r--r--spec/features/static_site_editor_spec.rb19
-rw-r--r--spec/frontend/diffs/store/actions_spec.js1
-rw-r--r--spec/frontend/logs/mock_data.js76
-rw-r--r--spec/frontend/static_site_editor/components/saved_changes_message_spec.js7
-rw-r--r--spec/frontend/static_site_editor/components/static_site_editor_spec.js41
-rw-r--r--spec/frontend/static_site_editor/components/submit_changes_error_spec.js48
-rw-r--r--spec/frontend/static_site_editor/store/actions_spec.js19
-rw-r--r--spec/frontend/static_site_editor/store/mutations_spec.js29
-rw-r--r--spec/lib/gitlab/diff/formatters/text_formatter_spec.rb3
-rw-r--r--spec/lib/gitlab/diff/position_spec.rb1
-rw-r--r--spec/lib/gitlab/prometheus/adapter_spec.rb8
-rw-r--r--spec/models/diff_note_position_spec.rb7
-rw-r--r--spec/models/project_services/prometheus_service_spec.rb44
-rw-r--r--spec/routing/project_routing_spec.rb7
-rw-r--r--spec/support/shared_examples/models/diff_positionable_note_shared_examples.rb1
-rw-r--r--spec/support/shared_examples/requests/api/diff_discussions_shared_examples.rb8
-rw-r--r--yarn.lock8
71 files changed, 733 insertions, 191 deletions
diff --git a/app/assets/javascripts/admin/application_settings/setup_metrics_and_profiling.js b/app/assets/javascripts/admin/application_settings/setup_metrics_and_profiling.js
new file mode 100644
index 00000000000..b4803be4d52
--- /dev/null
+++ b/app/assets/javascripts/admin/application_settings/setup_metrics_and_profiling.js
@@ -0,0 +1,8 @@
+import PayloadPreviewer from '~/pages/admin/application_settings/payload_previewer';
+
+export default () => {
+ new PayloadPreviewer(
+ document.querySelector('.js-usage-ping-payload-trigger'),
+ document.querySelector('.js-usage-ping-payload'),
+ ).init();
+};
diff --git a/app/assets/javascripts/diffs/store/utils.js b/app/assets/javascripts/diffs/store/utils.js
index 9c788e283b9..07879ebf7d5 100644
--- a/app/assets/javascripts/diffs/store/utils.js
+++ b/app/assets/javascripts/diffs/store/utils.js
@@ -424,6 +424,7 @@ export function getDiffPositionByLineCode(diffFiles, useSingleDiffStyle) {
old_path: file.old_path,
old_line: line.old_line,
new_line: line.new_line,
+ line_range: null,
line_code: line.line_code,
position_type: 'text',
};
diff --git a/app/assets/javascripts/logs/constants.js b/app/assets/javascripts/logs/constants.js
index 450b83f4827..51770aa7a1c 100644
--- a/app/assets/javascripts/logs/constants.js
+++ b/app/assets/javascripts/logs/constants.js
@@ -1,3 +1,3 @@
-export const dateFormatMask = 'UTC:mmm dd HH:MM:ss.l"Z"';
+export const dateFormatMask = 'mmm dd HH:MM:ss.l';
export const TOKEN_TYPE_POD_NAME = 'TOKEN_TYPE_POD_NAME';
diff --git a/app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/index.js b/app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/index.js
index c40503603be..bbaaeb55c65 100644
--- a/app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/index.js
+++ b/app/assets/javascripts/pages/admin/application_settings/metrics_and_profiling/index.js
@@ -1,8 +1,3 @@
-import UsagePingPayload from './../usage_ping_payload';
+import setup from 'ee_else_ce/admin/application_settings/setup_metrics_and_profiling';
-document.addEventListener('DOMContentLoaded', () => {
- new UsagePingPayload(
- document.querySelector('.js-usage-ping-payload-trigger'),
- document.querySelector('.js-usage-ping-payload'),
- ).init();
-});
+document.addEventListener('DOMContentLoaded', setup);
diff --git a/app/assets/javascripts/pages/admin/application_settings/usage_ping_payload.js b/app/assets/javascripts/pages/admin/application_settings/payload_previewer.js
index 95f4ba28b42..413045d960e 100644
--- a/app/assets/javascripts/pages/admin/application_settings/usage_ping_payload.js
+++ b/app/assets/javascripts/pages/admin/application_settings/payload_previewer.js
@@ -2,7 +2,7 @@ import axios from '../../../lib/utils/axios_utils';
import { __ } from '../../../locale';
import flash from '../../../flash';
-export default class UsagePingPayload {
+export default class PayloadPreviewer {
constructor(trigger, container) {
this.trigger = trigger;
this.container = container;
@@ -38,7 +38,7 @@ export default class UsagePingPayload {
})
.catch(() => {
this.spinner.classList.remove('d-inline-flex');
- flash(__('Error fetching usage ping data.'));
+ flash(__('Error fetching payload data.'));
});
}
diff --git a/app/assets/javascripts/static_site_editor/components/saved_changes_message.vue b/app/assets/javascripts/static_site_editor/components/saved_changes_message.vue
index 13f66551c00..41cb901720c 100644
--- a/app/assets/javascripts/static_site_editor/components/saved_changes_message.vue
+++ b/app/assets/javascripts/static_site_editor/components/saved_changes_message.vue
@@ -60,7 +60,7 @@ export default {
<ul>
<li>
{{ s__('StaticSiteEditor|You created a new branch:') }}
- <gl-link ref="branchLink" :href="branch.url">{{ branch.label }}</gl-link>
+ <span ref="branchLink">{{ branch.label }}</span>
</li>
<li>
{{ s__('StaticSiteEditor|You created a merge request:') }}
diff --git a/app/assets/javascripts/static_site_editor/components/static_site_editor.vue b/app/assets/javascripts/static_site_editor/components/static_site_editor.vue
index 28e10c3c2cb..f8cc6d1630b 100644
--- a/app/assets/javascripts/static_site_editor/components/static_site_editor.vue
+++ b/app/assets/javascripts/static_site_editor/components/static_site_editor.vue
@@ -6,6 +6,7 @@ import EditArea from './edit_area.vue';
import EditHeader from './edit_header.vue';
import Toolbar from './publish_toolbar.vue';
import InvalidContentMessage from './invalid_content_message.vue';
+import SubmitChangesError from './submit_changes_error.vue';
export default {
components: {
@@ -14,6 +15,7 @@ export default {
InvalidContentMessage,
GlSkeletonLoader,
Toolbar,
+ SubmitChangesError,
},
computed: {
...mapState([
@@ -24,6 +26,7 @@ export default {
'isSupportedContent',
'returnUrl',
'title',
+ 'submitChangesError',
]),
...mapGetters(['contentChanged']),
},
@@ -33,7 +36,7 @@ export default {
}
},
methods: {
- ...mapActions(['loadContent', 'setContent', 'submitChanges']),
+ ...mapActions(['loadContent', 'setContent', 'submitChanges', 'dismissSubmitChangesError']),
},
};
</script>
@@ -51,6 +54,13 @@ export default {
</gl-skeleton-loader>
</div>
<div v-if="isContentLoaded" class="d-flex flex-grow-1 flex-column">
+ <submit-changes-error
+ v-if="submitChangesError"
+ class="w-75 align-self-center"
+ :error="submitChangesError"
+ @retry="submitChanges"
+ @dismiss="dismissSubmitChangesError"
+ />
<edit-header class="w-75 align-self-center py-2" :title="title" />
<edit-area
class="w-75 h-100 shadow-none align-self-center"
diff --git a/app/assets/javascripts/static_site_editor/components/submit_changes_error.vue b/app/assets/javascripts/static_site_editor/components/submit_changes_error.vue
new file mode 100644
index 00000000000..c5b6c685124
--- /dev/null
+++ b/app/assets/javascripts/static_site_editor/components/submit_changes_error.vue
@@ -0,0 +1,24 @@
+<script>
+import { GlAlert, GlButton } from '@gitlab/ui';
+
+export default {
+ components: {
+ GlAlert,
+ GlButton,
+ },
+ props: {
+ error: {
+ type: String,
+ required: true,
+ },
+ },
+};
+</script>
+<template>
+ <gl-alert variant="danger" dismissible @dismiss="$emit('dismiss')">
+ {{ s__('StaticSiteEditor|An error occurred while submitting your changes.') }} {{ error }}
+ <template #actions>
+ <gl-button variant="danger" @click="$emit('retry')">{{ __('Retry') }}</gl-button>
+ </template>
+ </gl-alert>
+</template>
diff --git a/app/assets/javascripts/static_site_editor/store/actions.js b/app/assets/javascripts/static_site_editor/store/actions.js
index c57ef86f6ef..9f5e9e8c589 100644
--- a/app/assets/javascripts/static_site_editor/store/actions.js
+++ b/app/assets/javascripts/static_site_editor/store/actions.js
@@ -26,9 +26,12 @@ export const submitChanges = ({ state: { projectId, content, sourcePath, usernam
return submitContentChanges({ content, projectId, sourcePath, username })
.then(data => commit(mutationTypes.SUBMIT_CHANGES_SUCCESS, data))
.catch(error => {
- commit(mutationTypes.SUBMIT_CHANGES_ERROR);
- createFlash(error.message);
+ commit(mutationTypes.SUBMIT_CHANGES_ERROR, error.message);
});
};
+export const dismissSubmitChangesError = ({ commit }) => {
+ commit(mutationTypes.DISMISS_SUBMIT_CHANGES_ERROR);
+};
+
export default () => {};
diff --git a/app/assets/javascripts/static_site_editor/store/mutation_types.js b/app/assets/javascripts/static_site_editor/store/mutation_types.js
index 35eb35ebbe9..9cf356aecc5 100644
--- a/app/assets/javascripts/static_site_editor/store/mutation_types.js
+++ b/app/assets/javascripts/static_site_editor/store/mutation_types.js
@@ -5,3 +5,4 @@ export const SET_CONTENT = 'setContent';
export const SUBMIT_CHANGES = 'submitChanges';
export const SUBMIT_CHANGES_SUCCESS = 'submitChangesSuccess';
export const SUBMIT_CHANGES_ERROR = 'submitChangesError';
+export const DISMISS_SUBMIT_CHANGES_ERROR = 'dismissSubmitChangesError';
diff --git a/app/assets/javascripts/static_site_editor/store/mutations.js b/app/assets/javascripts/static_site_editor/store/mutations.js
index 4727d04439c..72fe71f1c9b 100644
--- a/app/assets/javascripts/static_site_editor/store/mutations.js
+++ b/app/assets/javascripts/static_site_editor/store/mutations.js
@@ -19,13 +19,18 @@ export default {
},
[types.SUBMIT_CHANGES](state) {
state.isSavingChanges = true;
+ state.submitChangesError = '';
},
[types.SUBMIT_CHANGES_SUCCESS](state, meta) {
state.savedContentMeta = meta;
state.isSavingChanges = false;
state.originalContent = state.content;
},
- [types.SUBMIT_CHANGES_ERROR](state) {
+ [types.SUBMIT_CHANGES_ERROR](state, error) {
+ state.submitChangesError = error;
state.isSavingChanges = false;
},
+ [types.DISMISS_SUBMIT_CHANGES_ERROR](state) {
+ state.submitChangesError = '';
+ },
};
diff --git a/app/assets/javascripts/static_site_editor/store/state.js b/app/assets/javascripts/static_site_editor/store/state.js
index 3d9fa9e6303..8c524b4ffe9 100644
--- a/app/assets/javascripts/static_site_editor/store/state.js
+++ b/app/assets/javascripts/static_site_editor/store/state.js
@@ -14,6 +14,7 @@ const createState = (initialState = {}) => ({
content: '',
title: '',
+ submitChangesError: '',
savedContentMeta: null,
...initialState,
diff --git a/app/models/diff_note_position.rb b/app/models/diff_note_position.rb
index 716a56c6430..a25b0def643 100644
--- a/app/models/diff_note_position.rb
+++ b/app/models/diff_note_position.rb
@@ -2,6 +2,7 @@
class DiffNotePosition < ApplicationRecord
belongs_to :note
+ attr_accessor :line_range
enum diff_content_type: {
text: 0,
@@ -42,6 +43,7 @@ class DiffNotePosition < ApplicationRecord
def self.position_to_attrs(position)
position_attrs = position.to_h
position_attrs[:diff_content_type] = position_attrs.delete(:position_type)
+ position_attrs.delete(:line_range)
position_attrs
end
end
diff --git a/app/models/project_services/prometheus_service.rb b/app/models/project_services/prometheus_service.rb
index 1a85289a04f..4a28d1ff2b0 100644
--- a/app/models/project_services/prometheus_service.rb
+++ b/app/models/project_services/prometheus_service.rb
@@ -36,10 +36,6 @@ class PrometheusService < MonitoringService
false
end
- def editable?
- manual_configuration? || !prometheus_available?
- end
-
def title
'Prometheus'
end
@@ -53,8 +49,6 @@ class PrometheusService < MonitoringService
end
def fields
- return [] unless editable?
-
[
{
type: 'checkbox',
diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml
index ec05ff50f25..2e5953bf0a6 100644
--- a/app/views/projects/commits/_commits.html.haml
+++ b/app/views/projects/commits/_commits.html.haml
@@ -4,11 +4,12 @@
- commits = @commits
- hidden = @hidden_commit_count
+- commits_count = @commits.size
- commits.chunk { |c| c.committed_date.in_time_zone.to_date }.each do |day, commits|
%li.commit-header.js-commit-header{ data: { day: day } }
%span.day= l(day, format: '%d %b, %Y')
- %span.commits-count= n_("%d commit", "%d commits", commits.count) % commits.count
+ %span.commits-count= n_("%d commit", "%d commits", commits_count) % commits_count
%li.commits-row{ data: { day: day } }
%ul.content-list.commit-list.flex-list
@@ -17,3 +18,9 @@
- if hidden > 0
%li.alert.alert-warning
= n_('%s additional commit has been omitted to prevent performance issues.', '%s additional commits have been omitted to prevent performance issues.', hidden) % number_with_delimiter(hidden)
+
+- if commits_count == 0
+ .mt-4.text-center
+ .bold
+ = _('Your search didn\'t match any commits.')
+ = _('Try changing or removing filters.')
diff --git a/app/views/projects/services/_form.html.haml b/app/views/projects/services/_form.html.haml
index bd9defe5f74..0dbd6a48ec5 100644
--- a/app/views/projects/services/_form.html.haml
+++ b/app/views/projects/services/_form.html.haml
@@ -12,11 +12,10 @@
.col-lg-9
= form_for(@service, as: :service, url: scoped_integration_path(@service), method: :put, html: { class: 'gl-show-field-errors integration-settings-form js-integration-settings-form', data: { 'can-test' => @service.can_test?, 'test-url' => test_project_service_path(@project, @service) } }) do |form|
= render 'shared/service_settings', form: form, service: @service
- - if @service.editable?
- .footer-block.row-content-block
- = service_save_button(@service)
- &nbsp;
- = link_to _('Cancel'), project_settings_integrations_path(@project), class: 'btn btn-cancel'
+ .footer-block.row-content-block
+ = service_save_button(@service)
+ &nbsp;
+ = link_to _('Cancel'), project_settings_integrations_path(@project), class: 'btn btn-cancel'
- if lookup_context.template_exists?('show', "projects/services/#{@service.to_param}", true)
%hr
diff --git a/app/views/projects/services/prometheus/_help.html.haml b/app/views/projects/services/prometheus/_help.html.haml
index 35d655e4b32..1b5b794a7aa 100644
--- a/app/views/projects/services/prometheus/_help.html.haml
+++ b/app/views/projects/services/prometheus/_help.html.haml
@@ -3,7 +3,5 @@
%h4.append-bottom-default
= s_('PrometheusService|Manual configuration')
-
-- unless @service.editable?
- .info-well
- = s_('PrometheusService|To enable manual configuration, uninstall Prometheus from your clusters')
+%p
+ = s_('PrometheusService|Select the Active checkbox to override the Auto Configuration with custom settings. If unchecked, Auto Configuration settings are used.')
diff --git a/app/views/projects/settings/operations/_prometheus.html.haml b/app/views/projects/settings/operations/_prometheus.html.haml
index 3d7a6b021a8..b0fa750e131 100644
--- a/app/views/projects/settings/operations/_prometheus.html.haml
+++ b/app/views/projects/settings/operations/_prometheus.html.haml
@@ -13,7 +13,5 @@
%b.append-bottom-default
= s_('PrometheusService|Manual configuration')
-
- - unless service.editable?
- .info-well
- = s_('PrometheusService|To enable manual configuration, uninstall Prometheus from your clusters')
+ %p
+ = s_('PrometheusService|Select the Active checkbox to override the Auto Configuration with custom settings. If unchecked, Auto Configuration settings are used.')
diff --git a/changelogs/unreleased/14984-add-text-for-empty-commit-list.yml b/changelogs/unreleased/14984-add-text-for-empty-commit-list.yml
new file mode 100644
index 00000000000..deae5b4fe09
--- /dev/null
+++ b/changelogs/unreleased/14984-add-text-for-empty-commit-list.yml
@@ -0,0 +1,5 @@
+---
+title: Add temporary empty message when no result is found
+merge_request: 29306
+author:
+type: added
diff --git a/changelogs/unreleased/205058-add-env-vars-to-ds.yml b/changelogs/unreleased/205058-add-env-vars-to-ds.yml
new file mode 100644
index 00000000000..b783110e382
--- /dev/null
+++ b/changelogs/unreleased/205058-add-env-vars-to-ds.yml
@@ -0,0 +1,5 @@
+---
+title: Add GRADLE_CLI_OPTS and SBT_CLI_OPTS env vars to dependency scanning orchestrator
+merge_request: 29595
+author:
+type: added
diff --git a/changelogs/unreleased/207233-k8s-cluster-blocks-project-manual-prometheus-configuration.yml b/changelogs/unreleased/207233-k8s-cluster-blocks-project-manual-prometheus-configuration.yml
new file mode 100644
index 00000000000..fe94ee48e97
--- /dev/null
+++ b/changelogs/unreleased/207233-k8s-cluster-blocks-project-manual-prometheus-configuration.yml
@@ -0,0 +1,5 @@
+---
+title: Make manual prometheus configuration section always editable
+merge_request: 29209
+author:
+type: changed
diff --git a/changelogs/unreleased/214108-log-explorer-timestamp-in-the-logs-presented-in-utc-and-should-be-.yml b/changelogs/unreleased/214108-log-explorer-timestamp-in-the-logs-presented-in-utc-and-should-be-.yml
new file mode 100644
index 00000000000..109be757dce
--- /dev/null
+++ b/changelogs/unreleased/214108-log-explorer-timestamp-in-the-logs-presented-in-utc-and-should-be-.yml
@@ -0,0 +1,5 @@
+---
+title: Display local timezone in log explorer
+merge_request: 29409
+author:
+type: changed
diff --git a/changelogs/unreleased/dblessing-add-missing-on-delete-fk-constraints.yml b/changelogs/unreleased/dblessing-add-missing-on-delete-fk-constraints.yml
new file mode 100644
index 00000000000..dc9daa2825f
--- /dev/null
+++ b/changelogs/unreleased/dblessing-add-missing-on-delete-fk-constraints.yml
@@ -0,0 +1,5 @@
+---
+title: Add missing ON DELETE FK constraints referencing users table
+merge_request: 28720
+author:
+type: fixed
diff --git a/changelogs/unreleased/display-retry-button-in-error-message.yml b/changelogs/unreleased/display-retry-button-in-error-message.yml
new file mode 100644
index 00000000000..6b529143310
--- /dev/null
+++ b/changelogs/unreleased/display-retry-button-in-error-message.yml
@@ -0,0 +1,5 @@
+---
+title: Allow to retry submitting changes when an error occurs
+merge_request: 29434
+author:
+type: changed
diff --git a/changelogs/unreleased/do-not-display-branch-link.yml b/changelogs/unreleased/do-not-display-branch-link.yml
new file mode 100644
index 00000000000..4b402820f88
--- /dev/null
+++ b/changelogs/unreleased/do-not-display-branch-link.yml
@@ -0,0 +1,5 @@
+---
+title: Do not display branch link in saved changes message UI
+merge_request: 29611
+author:
+type: changed
diff --git a/changelogs/unreleased/feature-bump-cluster-applications-to-0-15.yml b/changelogs/unreleased/feature-bump-cluster-applications-to-0-15.yml
new file mode 100644
index 00000000000..dbedaf2d97e
--- /dev/null
+++ b/changelogs/unreleased/feature-bump-cluster-applications-to-0-15.yml
@@ -0,0 +1,5 @@
+---
+title: Adds Knative and Fluentd as CI/CD managed applications
+merge_request: 29637
+author:
+type: added
diff --git a/changelogs/unreleased/multi-line-notes-take-3.yml b/changelogs/unreleased/multi-line-notes-take-3.yml
new file mode 100644
index 00000000000..3d290d8c027
--- /dev/null
+++ b/changelogs/unreleased/multi-line-notes-take-3.yml
@@ -0,0 +1,5 @@
+---
+title: Add line range to diff note position
+merge_request: 29135
+author:
+type: added
diff --git a/config/routes/project.rb b/config/routes/project.rb
index ab7c439318f..1ce889dd578 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -26,10 +26,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
scope '-' do
get 'archive/*id', constraints: { format: Gitlab::PathRegex.archive_formats_regex, id: /.+?/ }, to: 'repositories#archive', as: 'archive'
- scope controller: :static_site_editor do
- get '/sse/*id', action: :show, as: :show_sse
- end
-
resources :artifacts, only: [:index, :destroy]
resources :jobs, only: [:index, :show], constraints: { id: /\d+/ } do
diff --git a/config/routes/repository.rb b/config/routes/repository.rb
index 38d6cdbbaf8..eec204f2870 100644
--- a/config/routes/repository.rb
+++ b/config/routes/repository.rb
@@ -21,6 +21,9 @@ resources :commit, only: [:show], constraints: { id: /\h{7,40}/ } do
end
end
+# NOTE: Add new routes to repository_scoped.rb instead (see
+# https://docs.gitlab.com/ee/development/routing.html#project-routes).
+#
# Don't use format parameter as file extension (old 3.0.x behavior)
# See http://guides.rubyonrails.org/routing.html#route-globbing-and-wildcard-segments
scope format: false do
diff --git a/config/routes/repository_scoped.rb b/config/routes/repository_scoped.rb
index c6343039d62..42ec8ca1806 100644
--- a/config/routes/repository_scoped.rb
+++ b/config/routes/repository_scoped.rb
@@ -30,5 +30,11 @@ scope format: false do
resources :protected_branches, only: [:index, :show, :create, :update, :destroy, :patch], constraints: { id: Gitlab::PathRegex.git_reference_regex }
resources :protected_tags, only: [:index, :show, :create, :update, :destroy]
+
+ scope constraints: { id: /[^\0]+/ } do
+ scope controller: :static_site_editor do
+ get '/sse/*id', action: :show, as: :show_sse
+ end
+ end
end
end
diff --git a/db/migrate/20200407171133_add_protected_tag_create_access_levels_user_id_foreign_key.rb b/db/migrate/20200407171133_add_protected_tag_create_access_levels_user_id_foreign_key.rb
new file mode 100644
index 00000000000..d6d6d86a0ad
--- /dev/null
+++ b/db/migrate/20200407171133_add_protected_tag_create_access_levels_user_id_foreign_key.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+# rubocop: disable Migration/AddConcurrentForeignKey
+class AddProtectedTagCreateAccessLevelsUserIdForeignKey < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ CONSTRAINT_NAME = 'fk_protected_tag_create_access_levels_user_id'
+
+ def up
+ with_lock_retries do
+ add_foreign_key(:protected_tag_create_access_levels, :users, on_delete: :cascade, validate: false, name: CONSTRAINT_NAME)
+ remove_foreign_key_if_exists(:protected_tag_create_access_levels, column: :user_id, on_delete: nil)
+ end
+ end
+
+ def down
+ fk_exists = foreign_key_exists?(:protected_tag_create_access_levels, :users, column: :user_id, on_delete: nil)
+
+ unless fk_exists
+ with_lock_retries do
+ add_foreign_key(:protected_tag_create_access_levels, :users, column: :user_id, validate: false)
+ end
+ end
+
+ remove_foreign_key_if_exists(:protected_tag_create_access_levels, column: :user_id, name: CONSTRAINT_NAME)
+
+ fk_name = concurrent_foreign_key_name(:protected_tag_create_access_levels, :user_id, prefix: 'fk_rails_')
+ validate_foreign_key(:protected_tag_create_access_levels, :user_id, name: fk_name)
+ end
+end
diff --git a/db/migrate/20200407171417_validate_protected_tag_create_access_levels_user_id_foreign_key.rb b/db/migrate/20200407171417_validate_protected_tag_create_access_levels_user_id_foreign_key.rb
new file mode 100644
index 00000000000..baba65e0b7d
--- /dev/null
+++ b/db/migrate/20200407171417_validate_protected_tag_create_access_levels_user_id_foreign_key.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class ValidateProtectedTagCreateAccessLevelsUserIdForeignKey < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ CONSTRAINT_NAME = 'fk_protected_tag_create_access_levels_user_id'
+
+ def up
+ validate_foreign_key :protected_tag_create_access_levels, :user_id, name: CONSTRAINT_NAME
+ end
+
+ def down
+ # no op
+ end
+end
diff --git a/db/migrate/20200408154331_add_protected_branch_merge_access_levels_user_id_foreign_key.rb b/db/migrate/20200408154331_add_protected_branch_merge_access_levels_user_id_foreign_key.rb
new file mode 100644
index 00000000000..0d80c095757
--- /dev/null
+++ b/db/migrate/20200408154331_add_protected_branch_merge_access_levels_user_id_foreign_key.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+# rubocop: disable Migration/AddConcurrentForeignKey
+class AddProtectedBranchMergeAccessLevelsUserIdForeignKey < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ CONSTRAINT_NAME = 'fk_protected_branch_merge_access_levels_user_id'
+
+ def up
+ with_lock_retries do
+ add_foreign_key(:protected_branch_merge_access_levels, :users, on_delete: :cascade, validate: false, name: CONSTRAINT_NAME)
+ remove_foreign_key_if_exists(:protected_branch_merge_access_levels, column: :user_id, on_delete: nil)
+ end
+ end
+
+ def down
+ fk_exists = foreign_key_exists?(:protected_branch_merge_access_levels, :users, column: :user_id, on_delete: nil)
+
+ unless fk_exists
+ with_lock_retries do
+ add_foreign_key(:protected_branch_merge_access_levels, :users, column: :user_id, validate: false)
+ end
+ end
+
+ remove_foreign_key_if_exists(:protected_branch_merge_access_levels, column: :user_id, name: CONSTRAINT_NAME)
+
+ fk_name = concurrent_foreign_key_name(:protected_branch_merge_access_levels, :user_id, prefix: 'fk_rails_')
+ validate_foreign_key(:protected_branch_merge_access_levels, :user_id, name: fk_name)
+ end
+end
diff --git a/db/migrate/20200408154349_validate_protected_branch_merge_access_levels_user_id_foreign_key.rb b/db/migrate/20200408154349_validate_protected_branch_merge_access_levels_user_id_foreign_key.rb
new file mode 100644
index 00000000000..c4ec957d607
--- /dev/null
+++ b/db/migrate/20200408154349_validate_protected_branch_merge_access_levels_user_id_foreign_key.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class ValidateProtectedBranchMergeAccessLevelsUserIdForeignKey < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ CONSTRAINT_NAME = 'fk_protected_branch_merge_access_levels_user_id'
+
+ def up
+ validate_foreign_key :protected_branch_merge_access_levels, :user_id, name: CONSTRAINT_NAME
+ end
+
+ def down
+ # no op
+ end
+end
diff --git a/db/migrate/20200408154411_add_path_locks_user_id_foreign_key.rb b/db/migrate/20200408154411_add_path_locks_user_id_foreign_key.rb
new file mode 100644
index 00000000000..8fcfb2615bb
--- /dev/null
+++ b/db/migrate/20200408154411_add_path_locks_user_id_foreign_key.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+# rubocop: disable Migration/AddConcurrentForeignKey
+class AddPathLocksUserIdForeignKey < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ CONSTRAINT_NAME = 'fk_path_locks_user_id'
+
+ def up
+ with_lock_retries do
+ add_foreign_key(:path_locks, :users, on_delete: :cascade, validate: false, name: CONSTRAINT_NAME)
+ remove_foreign_key_if_exists(:path_locks, column: :user_id, on_delete: nil)
+ end
+ end
+
+ def down
+ fk_exists = foreign_key_exists?(:path_locks, :users, column: :user_id, on_delete: nil)
+
+ unless fk_exists
+ with_lock_retries do
+ add_foreign_key(:path_locks, :users, column: :user_id, validate: false)
+ end
+ end
+
+ remove_foreign_key_if_exists(:path_locks, column: :user_id, name: CONSTRAINT_NAME)
+
+ fk_name = concurrent_foreign_key_name(:path_locks, :user_id, prefix: 'fk_rails_')
+ validate_foreign_key(:path_locks, :user_id, name: fk_name)
+ end
+end
diff --git a/db/migrate/20200408154428_validate_path_locks_user_id_foreign_key.rb b/db/migrate/20200408154428_validate_path_locks_user_id_foreign_key.rb
new file mode 100644
index 00000000000..500409ee44a
--- /dev/null
+++ b/db/migrate/20200408154428_validate_path_locks_user_id_foreign_key.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class ValidatePathLocksUserIdForeignKey < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ CONSTRAINT_NAME = 'fk_path_locks_user_id'
+
+ def up
+ validate_foreign_key :path_locks, :user_id, name: CONSTRAINT_NAME
+ end
+
+ def down
+ # no op
+ end
+end
diff --git a/db/migrate/20200408154455_add_protected_branch_push_access_levels_user_id_foreign_key.rb b/db/migrate/20200408154455_add_protected_branch_push_access_levels_user_id_foreign_key.rb
new file mode 100644
index 00000000000..9127e5dea7f
--- /dev/null
+++ b/db/migrate/20200408154455_add_protected_branch_push_access_levels_user_id_foreign_key.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+# rubocop: disable Migration/AddConcurrentForeignKey
+class AddProtectedBranchPushAccessLevelsUserIdForeignKey < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ CONSTRAINT_NAME = 'fk_protected_branch_push_access_levels_user_id'
+
+ def up
+ with_lock_retries do
+ add_foreign_key(:protected_branch_push_access_levels, :users, on_delete: :cascade, validate: false, name: CONSTRAINT_NAME)
+ remove_foreign_key_if_exists(:protected_branch_push_access_levels, column: :user_id, on_delete: nil)
+ end
+ end
+
+ def down
+ fk_exists = foreign_key_exists?(:protected_branch_push_access_levels, :users, column: :user_id, on_delete: nil)
+
+ unless fk_exists
+ with_lock_retries do
+ add_foreign_key(:protected_branch_push_access_levels, :users, column: :user_id, validate: false)
+ end
+ end
+
+ remove_foreign_key_if_exists(:protected_branch_push_access_levels, column: :user_id, name: CONSTRAINT_NAME)
+
+ fk_name = concurrent_foreign_key_name(:protected_branch_push_access_levels, :user_id, prefix: 'fk_rails_')
+ validate_foreign_key(:protected_branch_push_access_levels, :user_id, name: fk_name)
+ end
+end
diff --git a/db/migrate/20200408154533_validate_protected_branch_push_access_levels_user_id_foreign_key.rb b/db/migrate/20200408154533_validate_protected_branch_push_access_levels_user_id_foreign_key.rb
new file mode 100644
index 00000000000..d6f9cab6d7e
--- /dev/null
+++ b/db/migrate/20200408154533_validate_protected_branch_push_access_levels_user_id_foreign_key.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class ValidateProtectedBranchPushAccessLevelsUserIdForeignKey < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ CONSTRAINT_NAME = 'fk_protected_branch_push_access_levels_user_id'
+
+ def up
+ validate_foreign_key :protected_branch_push_access_levels, :user_id, name: CONSTRAINT_NAME
+ end
+
+ def down
+ # no op
+ end
+end
diff --git a/db/migrate/20200408154604_add_u2f_registrations_user_id_foreign_key.rb b/db/migrate/20200408154604_add_u2f_registrations_user_id_foreign_key.rb
new file mode 100644
index 00000000000..92aded750e5
--- /dev/null
+++ b/db/migrate/20200408154604_add_u2f_registrations_user_id_foreign_key.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+# rubocop: disable Migration/AddConcurrentForeignKey
+class AddU2fRegistrationsUserIdForeignKey < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ CONSTRAINT_NAME = 'fk_u2f_registrations_user_id'
+
+ def up
+ with_lock_retries do
+ add_foreign_key(:u2f_registrations, :users, on_delete: :cascade, validate: false, name: CONSTRAINT_NAME)
+ remove_foreign_key_if_exists(:u2f_registrations, column: :user_id, on_delete: nil)
+ end
+ end
+
+ def down
+ fk_exists = foreign_key_exists?(:u2f_registrations, :users, column: :user_id, on_delete: nil)
+
+ unless fk_exists
+ with_lock_retries do
+ add_foreign_key(:u2f_registrations, :users, column: :user_id, validate: false)
+ end
+ end
+
+ remove_foreign_key_if_exists(:u2f_registrations, column: :user_id, name: CONSTRAINT_NAME)
+
+ fk_name = concurrent_foreign_key_name(:u2f_registrations, :user_id, prefix: 'fk_rails_')
+ validate_foreign_key(:u2f_registrations, :user_id, name: fk_name)
+ end
+end
diff --git a/db/migrate/20200408154624_validate_u2f_registrations_user_id_foreign_key.rb b/db/migrate/20200408154624_validate_u2f_registrations_user_id_foreign_key.rb
new file mode 100644
index 00000000000..ff723a4793f
--- /dev/null
+++ b/db/migrate/20200408154624_validate_u2f_registrations_user_id_foreign_key.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+#
+class ValidateU2fRegistrationsUserIdForeignKey < ActiveRecord::Migration[6.0]
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ CONSTRAINT_NAME = 'fk_u2f_registrations_user_id'
+
+ def up
+ validate_foreign_key :u2f_registrations, :user_id, name: CONSTRAINT_NAME
+ end
+
+ def down
+ # no op
+ end
+end
diff --git a/db/structure.sql b/db/structure.sql
index 56efa356123..83b01662530 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -11044,9 +11044,21 @@ ALTER TABLE ONLY public.issues
ALTER TABLE ONLY public.geo_event_log
ADD CONSTRAINT fk_geo_event_log_on_geo_event_id FOREIGN KEY (geo_event_id) REFERENCES public.geo_events(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.path_locks
+ ADD CONSTRAINT fk_path_locks_user_id FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.personal_access_tokens
ADD CONSTRAINT fk_personal_access_tokens_user_id FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.protected_branch_merge_access_levels
+ ADD CONSTRAINT fk_protected_branch_merge_access_levels_user_id FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
+
+ALTER TABLE ONLY public.protected_branch_push_access_levels
+ ADD CONSTRAINT fk_protected_branch_push_access_levels_user_id FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
+
+ALTER TABLE ONLY public.protected_tag_create_access_levels
+ ADD CONSTRAINT fk_protected_tag_create_access_levels_user_id FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
+
ALTER TABLE ONLY public.approval_merge_request_rules
ADD CONSTRAINT fk_rails_004ce82224 FOREIGN KEY (merge_request_id) REFERENCES public.merge_requests(id) ON DELETE CASCADE;
@@ -11191,9 +11203,6 @@ ALTER TABLE ONLY public.clusters_applications_runners
ALTER TABLE ONLY public.service_desk_settings
ADD CONSTRAINT fk_rails_223a296a85 FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
-ALTER TABLE ONLY public.protected_tag_create_access_levels
- ADD CONSTRAINT fk_rails_2349b78b91 FOREIGN KEY (user_id) REFERENCES public.users(id);
-
ALTER TABLE ONLY public.group_custom_attributes
ADD CONSTRAINT fk_rails_246e0db83a FOREIGN KEY (group_id) REFERENCES public.namespaces(id) ON DELETE CASCADE;
@@ -11440,9 +11449,6 @@ ALTER TABLE ONLY public.resource_weight_events
ALTER TABLE ONLY public.approval_project_rules
ADD CONSTRAINT fk_rails_5fb4dd100b FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE;
-ALTER TABLE ONLY public.protected_branch_merge_access_levels
- ADD CONSTRAINT fk_rails_5ffb4f3590 FOREIGN KEY (user_id) REFERENCES public.users(id);
-
ALTER TABLE ONLY public.user_highest_roles
ADD CONSTRAINT fk_rails_60f6c325a6 FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
@@ -11551,9 +11557,6 @@ ALTER TABLE ONLY public.geo_repositories_changed_events
ALTER TABLE ONLY public.resource_label_events
ADD CONSTRAINT fk_rails_75efb0a653 FOREIGN KEY (epic_id) REFERENCES public.epics(id) ON DELETE CASCADE;
-ALTER TABLE ONLY public.path_locks
- ADD CONSTRAINT fk_rails_762cdcf942 FOREIGN KEY (user_id) REFERENCES public.users(id);
-
ALTER TABLE ONLY public.x509_certificates
ADD CONSTRAINT fk_rails_76479fb5b4 FOREIGN KEY (x509_issuer_id) REFERENCES public.x509_issuers(id) ON DELETE CASCADE;
@@ -11629,9 +11632,6 @@ ALTER TABLE ONLY public.vulnerability_feedback
ALTER TABLE ONLY public.approval_merge_request_rules_approved_approvers
ADD CONSTRAINT fk_rails_8dc94cff4d FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
-ALTER TABLE ONLY public.protected_branch_push_access_levels
- ADD CONSTRAINT fk_rails_8dcb712d65 FOREIGN KEY (user_id) REFERENCES public.users(id);
-
ALTER TABLE ONLY public.design_user_mentions
ADD CONSTRAINT fk_rails_8de8c6d632 FOREIGN KEY (note_id) REFERENCES public.notes(id) ON DELETE CASCADE;
@@ -11842,9 +11842,6 @@ ALTER TABLE ONLY public.resource_weight_events
ALTER TABLE ONLY public.design_management_designs
ADD CONSTRAINT fk_rails_bfe283ec3c FOREIGN KEY (issue_id) REFERENCES public.issues(id) ON DELETE CASCADE;
-ALTER TABLE ONLY public.u2f_registrations
- ADD CONSTRAINT fk_rails_bfe6a84544 FOREIGN KEY (user_id) REFERENCES public.users(id);
-
ALTER TABLE ONLY public.serverless_domain_cluster
ADD CONSTRAINT fk_rails_c09009dee1 FOREIGN KEY (pages_domain_id) REFERENCES public.pages_domains(id) ON DELETE CASCADE;
@@ -12079,6 +12076,9 @@ ALTER TABLE ONLY public.timelogs
ALTER TABLE ONLY public.timelogs
ADD CONSTRAINT fk_timelogs_merge_requests_merge_request_id FOREIGN KEY (merge_request_id) REFERENCES public.merge_requests(id) ON DELETE CASCADE;
+ALTER TABLE ONLY public.u2f_registrations
+ ADD CONSTRAINT fk_u2f_registrations_user_id FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE CASCADE;
+
COPY "schema_migrations" (version) FROM STDIN;
20171230123729
20180101160629
@@ -13161,9 +13161,19 @@ COPY "schema_migrations" (version) FROM STDIN;
20200406193427
20200407094005
20200407094923
+20200407171133
+20200407171417
20200408110856
20200408133211
20200408153842
+20200408154331
+20200408154349
+20200408154411
+20200408154428
+20200408154455
+20200408154533
+20200408154604
+20200408154624
20200408175424
20200409211607
20200415160722
diff --git a/doc/api/discussions.md b/doc/api/discussions.md
index f1e8965b336..572e174201d 100644
--- a/doc/api/discussions.md
+++ b/doc/api/discussions.md
@@ -739,7 +739,7 @@ GET /projects/:id/merge_requests/:merge_request_iid/discussions
]
```
-Diff comments contain also position:
+Diff comments also contain position:
```json
[
@@ -774,7 +774,11 @@ Diff comments contain also position:
"new_path": "package.json",
"position_type": "text",
"old_line": 27,
- "new_line": 27
+ "new_line": 27,
+ "line_range": {
+ "start_line_code": "588440f66559714280628a4f9799f0c4eb880a4a_10_10",
+ "end_line_code": "588440f66559714280628a4f9799f0c4eb880a4a_11_11"
+ }
},
"resolved": false,
"resolvable": true,
@@ -820,25 +824,28 @@ POST /projects/:id/merge_requests/:merge_request_iid/discussions
Parameters:
-| Attribute | Type | Required | Description |
-| ------------------------- | -------------- | -------- | ----------- |
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
-| `merge_request_iid` | integer | yes | The IID of a merge request |
-| `body` | string | yes | The content of the thread |
-| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) |
-| `position` | hash | no | Position when creating a diff note |
-| `position[base_sha]` | string | yes | Base commit SHA in the source branch |
-| `position[start_sha]` | string | yes | SHA referencing commit in target branch |
-| `position[head_sha]` | string | yes | SHA referencing HEAD of this merge request |
-| `position[position_type]` | string | yes | Type of the position reference', allowed values: 'text' or 'image' |
-| `position[new_path]` | string | no | File path after change |
-| `position[new_line]` | integer | no | Line number after change (for 'text' diff notes) |
-| `position[old_path]` | string | no | File path before change |
-| `position[old_line]` | integer | no | Line number before change (for 'text' diff notes) |
-| `position[width]` | integer | no | Width of the image (for 'image' diff notes) |
-| `position[height]` | integer | no | Height of the image (for 'image' diff notes) |
-| `position[x]` | integer | no | X coordinate (for 'image' diff notes) |
-| `position[y]` | integer | no | Y coordinate (for 'image' diff notes) |
+| Attribute | Type | Required | Description |
+| --------------------------------------- | -------------- | -------- | ----------- |
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
+| `merge_request_iid` | integer | yes | The IID of a merge request |
+| `body` | string | yes | The content of the thread |
+| `created_at` | string | no | Date time string, ISO 8601 formatted, e.g. 2016-03-11T03:45:40Z (requires admin or project/group owner rights) |
+| `position` | hash | no | Position when creating a diff note |
+| `position[base_sha]` | string | yes | Base commit SHA in the source branch |
+| `position[start_sha]` | string | yes | SHA referencing commit in target branch |
+| `position[head_sha]` | string | yes | SHA referencing HEAD of this merge request |
+| `position[position_type]` | string | yes | Type of the position reference', allowed values: 'text' or 'image' |
+| `position[new_path]` | string | no | File path after change |
+| `position[new_line]` | integer | no | Line number after change (for 'text' diff notes) |
+| `position[old_path]` | string | no | File path before change |
+| `position[old_line]` | integer | no | Line number before change (for 'text' diff notes) |
+| `position[line_range]` | hash | no | Line range for a multi-line diff note |
+| `position[line_range][start_line_code]` | string | yes | Line code for the start line |
+| `position[line_range][end_line_code]` | string | yes | Line code for the end line |
+| `position[width]` | integer | no | Width of the image (for 'image' diff notes) |
+| `position[height]` | integer | no | Height of the image (for 'image' diff notes) |
+| `position[x]` | integer | no | X coordinate (for 'image' diff notes) |
+| `position[y]` | integer | no | Y coordinate (for 'image' diff notes) |
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/5/merge_requests/11/discussions?body=comment
diff --git a/doc/ci/review_apps/index.md b/doc/ci/review_apps/index.md
index 860eab469dd..c3bdd524bff 100644
--- a/doc/ci/review_apps/index.md
+++ b/doc/ci/review_apps/index.md
@@ -188,9 +188,6 @@ With Visual Reviews, you can provide a feedback form to your Review Apps so
that reviewers can post comments directly from the app back to the merge request
that spawned the Review App.
-NOTE: **Note:** Visual Reviews currently only work for public projects. Support for private
-and internal projects [is planned](https://gitlab.com/gitlab-org/gitlab/-/issues/42750).
-
### Configuring Visual Reviews
Ensure that the `anonymous_visual_review_feedback` feature flag is enabled.
@@ -218,6 +215,7 @@ looks like:
data-merge-request-id='1'
data-mr-url='https://gitlab.example.com'
data-project-path='sarah/review-app-tester'
+ data-require-auth='true'
id='review-app-toolbar-script'
src='https://gitlab.example.com/assets/webpack/visual_review_toolbar.js'>
</script>
@@ -235,6 +233,7 @@ to replace those values at runtime when each review app is created:
- `data-mr-url` is the URL of the GitLab instance and will be the same for all
review apps.
- `data-project-path` is the project's path, which can be found by `CI_PROJECT_PATH`.
+- `data-require-auth` is optional for public projects but required for [private and internal ones](#visual-reviews-in-private-or-internal-projects). If this is set to `true`, the user will be required to enter their [personal access token](../../user/profile/personal_access_tokens.md) instead of their name and email.
- `id` is always `review-app-toolbar-script`, you don't need to change that.
- `src` is the source of the review toolbar script, which resides in the
respective GitLab instance and will be the same for all review apps.
@@ -272,6 +271,15 @@ can supply the ID by either:​​
- Dynamically adding the `data-merge-request-id` value during the build of the app.
- Supplying it manually through the visual review form in the app.
+### Visual Reviews in private or internal projects
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/42750#note_317271120) in GitLab 12.10.
+
+To enable visual reviews for private and internal projects, set the
+[`data-require-auth` variable](#configuring-visual-reviews) to `true`. When enabled,
+the user must enter a [personal access token](../../user/profile/personal_access_tokens.md)
+with `read_api` scope before submitting feedback.
+
### Using Visual Reviews
After Visual Reviews has been [enabled](#configuring-visual-reviews) for the
@@ -285,7 +293,7 @@ To use the feedback form:
1. Make a comment on the visual review. You can make use of all the
[Markdown annotations](../../user/markdown.md) that are also available in
merge request comments.
-1. Submit your feedback anonymously or add your name.
+1. If `data-require-auth` is `true`, you must enter your [personal access token](../../user/profile/personal_access_tokens.md). Otherwise, you must enter your name, and optionally, your email.
1. Finally, click **Send feedback**.
After you make and submit a comment in the visual review box, it will appear
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
index 436cb43199e..bbd5ca3c494 100644
--- a/doc/development/architecture.md
+++ b/doc/development/architecture.md
@@ -314,7 +314,7 @@ You can use it either for personal or business websites, such as portfolios, doc
- Layer: Core Service (Processor)
- GitLab.com: [Runner](../user/gitlab_com/index.md#shared-runners)
-GitLab Runner runs tests and sends the results to GitLab.
+GitLab Runner runs jobs and sends the results to GitLab.
GitLab CI/CD is the open-source continuous integration service included with GitLab that coordinates the testing. The old name of this project was `GitLab CI Multi Runner` but please use `GitLab Runner` (without CI) from now on.
diff --git a/doc/subscriptions/index.md b/doc/subscriptions/index.md
index 63a10fdf4be..c81310edc44 100644
--- a/doc/subscriptions/index.md
+++ b/doc/subscriptions/index.md
@@ -308,6 +308,11 @@ Sg0KU1hNMGExaE9SVGR2V2pKQlBUMWNiaUo5DQo=',
</details>
+You can view the exact JSON payload in the administration panel. To view the payload:
+
+1. Navigate to **Admin Area > Settings > Metrics and profiling** and expand **Seat Links**.
+1. Click **Preview payload**.
+
#### Disable Seat Link
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/212375) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.10.
diff --git a/lib/api/discussions.rb b/lib/api/discussions.rb
index 8ff275a3a1b..0dd1850e526 100644
--- a/lib/api/discussions.rb
+++ b/lib/api/discussions.rb
@@ -74,6 +74,11 @@ module API
optional :height, type: Integer, desc: 'Height of the image'
optional :x, type: Integer, desc: 'X coordinate in the image'
optional :y, type: Integer, desc: 'Y coordinate in the image'
+
+ optional :line_range, type: Hash, desc: 'Multi-line start and end' do
+ requires :start_line_code, type: String, desc: 'Start line code for multi-line note'
+ requires :end_line_code, type: String, desc: 'End line code for multi-line note'
+ end
end
end
post ":id/#{noteables_path}/:noteable_id/discussions" do
diff --git a/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml b/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
index 713b11c4d8f..54a29b04d39 100644
--- a/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Managed-Cluster-Applications.gitlab-ci.yml
@@ -1,6 +1,6 @@
apply:
stage: deploy
- image: "registry.gitlab.com/gitlab-org/cluster-integration/cluster-applications:v0.13.1"
+ image: "registry.gitlab.com/gitlab-org/cluster-integration/cluster-applications:v0.15.0"
environment:
name: production
variables:
@@ -17,6 +17,8 @@ apply:
ELASTIC_STACK_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/elastic-stack/values.yaml
VAULT_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/vault/values.yaml
CROSSPLANE_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/crossplane/values.yaml
+ FLUENTD_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/fluentd/values.yaml
+ KNATIVE_VALUES_FILE: $CI_PROJECT_DIR/.gitlab/managed-apps/knative/values.yaml
script:
- gitlab-managed-apps /usr/local/share/gitlab-managed-apps/helmfile.yaml
only:
diff --git a/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml b/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
index 717e91b3ae5..0ecf37b37a3 100644
--- a/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Security/Dependency-Scanning.gitlab-ci.yml
@@ -57,6 +57,8 @@ dependency_scanning:
PIP_EXTRA_INDEX_URL \
PIP_REQUIREMENTS_FILE \
MAVEN_CLI_OPTS \
+ GRADLE_CLI_OPTS \
+ SBT_CLI_OPTS \
BUNDLER_AUDIT_UPDATE_DISABLED \
BUNDLER_AUDIT_ADVISORY_DB_URL \
BUNDLER_AUDIT_ADVISORY_DB_REF_NAME \
diff --git a/lib/gitlab/diff/formatters/text_formatter.rb b/lib/gitlab/diff/formatters/text_formatter.rb
index 5b670b1f83b..728457b3139 100644
--- a/lib/gitlab/diff/formatters/text_formatter.rb
+++ b/lib/gitlab/diff/formatters/text_formatter.rb
@@ -6,10 +6,12 @@ module Gitlab
class TextFormatter < BaseFormatter
attr_reader :old_line
attr_reader :new_line
+ attr_reader :line_range
def initialize(attrs)
@old_line = attrs[:old_line]
@new_line = attrs[:new_line]
+ @line_range = attrs[:line_range]
super(attrs)
end
@@ -23,7 +25,7 @@ module Gitlab
end
def to_h
- super.merge(old_line: old_line, new_line: new_line)
+ super.merge(old_line: old_line, new_line: new_line, line_range: line_range)
end
def line_age
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 3c265774fc6..9f8e24d8696 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -8222,6 +8222,9 @@ msgstr ""
msgid "Error fetching network graph."
msgstr ""
+msgid "Error fetching payload data."
+msgstr ""
+
msgid "Error fetching projects"
msgstr ""
@@ -8231,9 +8234,6 @@ msgstr ""
msgid "Error fetching the dependency list. Please check your network connection and try again."
msgstr ""
-msgid "Error fetching usage ping data."
-msgstr ""
-
msgid "Error loading branch data. Please try again."
msgstr ""
@@ -16342,13 +16342,13 @@ msgstr ""
msgid "PrometheusService|Prometheus is being automatically managed on your clusters"
msgstr ""
-msgid "PrometheusService|These metrics will only be monitored after your first deployment to an environment"
+msgid "PrometheusService|Select the Active checkbox to override the Auto Configuration with custom settings. If unchecked, Auto Configuration settings are used."
msgstr ""
-msgid "PrometheusService|Time-series monitoring service"
+msgid "PrometheusService|These metrics will only be monitored after your first deployment to an environment"
msgstr ""
-msgid "PrometheusService|To enable manual configuration, uninstall Prometheus from your clusters"
+msgid "PrometheusService|Time-series monitoring service"
msgstr ""
msgid "PrometheusService|To enable the installation of Prometheus on your clusters, deactivate the manual configuration below"
@@ -19496,6 +19496,9 @@ msgstr ""
msgid "Static Application Security Testing (SAST)"
msgstr ""
+msgid "StaticSiteEditor|An error occurred while submitting your changes."
+msgstr ""
+
msgid "StaticSiteEditor|Branch could not be created."
msgstr ""
@@ -21861,6 +21864,9 @@ msgstr ""
msgid "Try all GitLab has to offer for 30 days."
msgstr ""
+msgid "Try changing or removing filters."
+msgstr ""
+
msgid "Try to fork again"
msgstr ""
@@ -24114,6 +24120,9 @@ msgstr ""
msgid "Your request for access has been queued for review."
msgstr ""
+msgid "Your search didn't match any commits."
+msgstr ""
+
msgid "Your subscription expired!"
msgstr ""
@@ -24236,6 +24245,9 @@ msgstr ""
msgid "ciReport|%{linkStartTag}Learn more about SAST %{linkEndTag}"
msgstr ""
+msgid "ciReport|%{linkStartTag}Learn more about Secret Scanning %{linkEndTag}"
+msgstr ""
+
msgid "ciReport|%{linkStartTag}Learn more about codequality reports %{linkEndTag}"
msgstr ""
@@ -24399,6 +24411,12 @@ msgstr ""
msgid "ciReport|SAST"
msgstr ""
+msgid "ciReport|Secret scanning"
+msgstr ""
+
+msgid "ciReport|Secret scanning detects secrets and credentials vulnerabilities in your source code."
+msgstr ""
+
msgid "ciReport|Security scanning"
msgstr ""
diff --git a/package.json b/package.json
index 5ddbe10df04..84283e48342 100644
--- a/package.json
+++ b/package.json
@@ -41,7 +41,7 @@
"@gitlab/at.js": "1.5.5",
"@gitlab/svgs": "1.119.0",
"@gitlab/ui": "12.0.0",
- "@gitlab/visual-review-tools": "1.5.1",
+ "@gitlab/visual-review-tools": "1.6.1",
"@sentry/browser": "^5.10.2",
"@sourcegraph/code-host-integration": "0.0.36",
"apollo-cache-inmemory": "^1.6.3",
diff --git a/spec/factories/diff_position.rb b/spec/factories/diff_position.rb
index a43c5afdff4..685272acf5c 100644
--- a/spec/factories/diff_position.rb
+++ b/spec/factories/diff_position.rb
@@ -34,10 +34,20 @@ FactoryBot.define do
position_type { 'text' }
old_line { 10 }
new_line { 10 }
+ line_range { nil }
trait :added do
old_line { nil }
end
+
+ trait :multi_line do
+ line_range do
+ {
+ start_line_code: Gitlab::Git.diff_line_code(file, 10, 10),
+ end_line_code: Gitlab::Git.diff_line_code(file, 12, 13)
+ }
+ end
+ end
end
factory :image_diff_position do
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index 8eb15bb6bf5..1a3da8cb373 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -348,12 +348,19 @@ describe 'Admin updates settings', :clean_gitlab_redis_shared_state, :do_not_moc
it 'loads usage ping payload on click', :js do
allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(false)
- expect(page).to have_button 'Preview payload'
+ page.within('#js-usage-settings') do
+ expected_payload_content = /(?=.*"uuid")(?=.*"hostname")/m
- find('.js-usage-ping-payload-trigger').click
+ expect(page).not_to have_content expected_payload_content
- expect(page).to have_selector '.js-usage-ping-payload'
- expect(page).to have_button 'Hide payload'
+ click_button('Preview payload')
+
+ wait_for_requests
+
+ expect(page).to have_selector '.js-usage-ping-payload'
+ expect(page).to have_button 'Hide payload'
+ expect(page).to have_content expected_payload_content
+ end
end
end
diff --git a/spec/features/projects/environments_pod_logs_spec.rb b/spec/features/projects/environments_pod_logs_spec.rb
index 2b2327940a5..a51f121bf59 100644
--- a/spec/features/projects/environments_pod_logs_spec.rb
+++ b/spec/features/projects/environments_pod_logs_spec.rb
@@ -57,7 +57,9 @@ describe 'Environment > Pod Logs', :js do
expect(item.text).to eq(pod_names[i])
end
end
- expect(page).to have_content("Dec 13 14:04:22.123Z | kube-pod | Log 1 Dec 13 14:04:23.123Z | kube-pod | Log 2 Dec 13 14:04:24.123Z | kube-pod | Log 3")
+ expect(page).to have_content("kube-pod | Log 1")
+ expect(page).to have_content("kube-pod | Log 2")
+ expect(page).to have_content("kube-pod | Log 3")
end
end
end
diff --git a/spec/features/static_site_editor_spec.rb b/spec/features/static_site_editor_spec.rb
new file mode 100644
index 00000000000..c457002f888
--- /dev/null
+++ b/spec/features/static_site_editor_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Static Site Editor' do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :public, :repository) }
+
+ before do
+ project.add_maintainer(user)
+ sign_in(user)
+
+ visit project_show_sse_path(project, 'master/README.md')
+ end
+
+ it 'renders Static Site Editor page' do
+ expect(page).to have_selector('#static-site-editor')
+ end
+end
diff --git a/spec/frontend/diffs/store/actions_spec.js b/spec/frontend/diffs/store/actions_spec.js
index 8a1c3e56e5a..ceccce6312f 100644
--- a/spec/frontend/diffs/store/actions_spec.js
+++ b/spec/frontend/diffs/store/actions_spec.js
@@ -466,6 +466,7 @@ describe('DiffsStoreActions', () => {
old_path: 'file2',
line_code: 'ABC_1_1',
position_type: 'text',
+ line_range: null,
},
},
hash: 'ABC_123',
diff --git a/spec/frontend/logs/mock_data.js b/spec/frontend/logs/mock_data.js
index 537582cff5a..14c8f7a2ba2 100644
--- a/spec/frontend/logs/mock_data.js
+++ b/spec/frontend/logs/mock_data.js
@@ -34,91 +34,31 @@ export const mockPods = [
export const mockLogsResult = [
{
timestamp: '2019-12-13T13:43:18.2760123Z',
- message: '10.36.0.1 - - [16/Oct/2019:06:29:48 UTC] "GET / HTTP/1.1" 200 13',
+ message: 'log line 1',
pod: 'foo',
},
{
timestamp: '2019-12-13T13:43:18.2760123Z',
- message: '- -> /',
+ message: 'log line A',
pod: 'bar',
},
{
timestamp: '2019-12-13T13:43:26.8420123Z',
- message: '10.36.0.1 - - [16/Oct/2019:06:29:57 UTC] "GET / HTTP/1.1" 200 13',
+ message: 'log line 2',
pod: 'foo',
},
{
timestamp: '2019-12-13T13:43:26.8420123Z',
- message: '- -> /',
- pod: 'bar',
- },
- {
- timestamp: '2019-12-13T13:43:28.3710123Z',
- message: '10.36.0.1 - - [16/Oct/2019:06:29:58 UTC] "GET / HTTP/1.1" 200 13',
- pod: 'foo',
- },
- {
- timestamp: '2019-12-13T13:43:28.3710123Z',
- message: '- -> /',
- pod: 'bar',
- },
- {
- timestamp: '2019-12-13T13:43:36.8860123Z',
- message: '10.36.0.1 - - [16/Oct/2019:06:30:07 UTC] "GET / HTTP/1.1" 200 13',
- pod: 'foo',
- },
- {
- timestamp: '2019-12-13T13:43:36.8860123Z',
- message: '- -> /',
- pod: 'bar',
- },
- {
- timestamp: '2019-12-13T13:43:38.4000123Z',
- message: '10.36.0.1 - - [16/Oct/2019:06:30:08 UTC] "GET / HTTP/1.1" 200 13',
- pod: 'foo',
- },
- {
- timestamp: '2019-12-13T13:43:38.4000123Z',
- message: '- -> /',
- pod: 'bar',
- },
- {
- timestamp: '2019-12-13T13:43:46.8420123Z',
- message: '10.36.0.1 - - [16/Oct/2019:06:30:17 UTC] "GET / HTTP/1.1" 200 13',
- pod: 'foo',
- },
- {
- timestamp: '2019-12-13T13:43:46.8430123Z',
- message: '- -> /',
- pod: 'bar',
- },
- {
- timestamp: '2019-12-13T13:43:48.3240123Z',
- message: '10.36.0.1 - - [16/Oct/2019:06:30:18 UTC] "GET / HTTP/1.1" 200 13',
- pod: 'foo',
- },
- {
- timestamp: '2019-12-13T13:43:48.3250123Z',
- message: '- -> /',
+ message: 'log line B',
pod: 'bar',
},
];
export const mockTrace = [
- 'Dec 13 13:43:18.276Z | foo | 10.36.0.1 - - [16/Oct/2019:06:29:48 UTC] "GET / HTTP/1.1" 200 13',
- 'Dec 13 13:43:18.276Z | bar | - -> /',
- 'Dec 13 13:43:26.842Z | foo | 10.36.0.1 - - [16/Oct/2019:06:29:57 UTC] "GET / HTTP/1.1" 200 13',
- 'Dec 13 13:43:26.842Z | bar | - -> /',
- 'Dec 13 13:43:28.371Z | foo | 10.36.0.1 - - [16/Oct/2019:06:29:58 UTC] "GET / HTTP/1.1" 200 13',
- 'Dec 13 13:43:28.371Z | bar | - -> /',
- 'Dec 13 13:43:36.886Z | foo | 10.36.0.1 - - [16/Oct/2019:06:30:07 UTC] "GET / HTTP/1.1" 200 13',
- 'Dec 13 13:43:36.886Z | bar | - -> /',
- 'Dec 13 13:43:38.400Z | foo | 10.36.0.1 - - [16/Oct/2019:06:30:08 UTC] "GET / HTTP/1.1" 200 13',
- 'Dec 13 13:43:38.400Z | bar | - -> /',
- 'Dec 13 13:43:46.842Z | foo | 10.36.0.1 - - [16/Oct/2019:06:30:17 UTC] "GET / HTTP/1.1" 200 13',
- 'Dec 13 13:43:46.843Z | bar | - -> /',
- 'Dec 13 13:43:48.324Z | foo | 10.36.0.1 - - [16/Oct/2019:06:30:18 UTC] "GET / HTTP/1.1" 200 13',
- 'Dec 13 13:43:48.325Z | bar | - -> /',
+ 'Dec 13 13:43:18.276 | foo | log line 1',
+ 'Dec 13 13:43:18.276 | bar | log line A',
+ 'Dec 13 13:43:26.842 | foo | log line 2',
+ 'Dec 13 13:43:26.842 | bar | log line B',
];
export const mockResponse = {
diff --git a/spec/frontend/static_site_editor/components/saved_changes_message_spec.js b/spec/frontend/static_site_editor/components/saved_changes_message_spec.js
index 76ac7de5c32..cac990df40f 100644
--- a/spec/frontend/static_site_editor/components/saved_changes_message_spec.js
+++ b/spec/frontend/static_site_editor/components/saved_changes_message_spec.js
@@ -51,11 +51,14 @@ describe('~/static_site_editor/components/saved_changes_message.vue', () => {
${'branch'} | ${findBranchLink} | ${props.branch}
${'commit'} | ${findCommitLink} | ${props.commit}
${'merge request'} | ${findMergeRequestLink} | ${props.mergeRequest}
- `('renders $desc link', ({ findEl, prop }) => {
+ `('renders $desc link', ({ desc, findEl, prop }) => {
const el = findEl();
expect(el.exists()).toBe(true);
- expect(el.attributes('href')).toBe(prop.url);
expect(el.text()).toBe(prop.label);
+
+ if (desc !== 'branch') {
+ expect(el.attributes('href')).toBe(prop.url);
+ }
});
});
diff --git a/spec/frontend/static_site_editor/components/static_site_editor_spec.js b/spec/frontend/static_site_editor/components/static_site_editor_spec.js
index 19a86de9cd8..14e9fe211ce 100644
--- a/spec/frontend/static_site_editor/components/static_site_editor_spec.js
+++ b/spec/frontend/static_site_editor/components/static_site_editor_spec.js
@@ -10,8 +10,9 @@ import EditArea from '~/static_site_editor/components/edit_area.vue';
import EditHeader from '~/static_site_editor/components/edit_header.vue';
import InvalidContentMessage from '~/static_site_editor/components/invalid_content_message.vue';
import PublishToolbar from '~/static_site_editor/components/publish_toolbar.vue';
+import SubmitChangesError from '~/static_site_editor/components/submit_changes_error.vue';
-import { sourceContent, sourceContentTitle } from '../mock_data';
+import { sourceContent, sourceContentTitle, submitChangesError } from '../mock_data';
const localVue = createLocalVue();
@@ -23,11 +24,13 @@ describe('StaticSiteEditor', () => {
let loadContentActionMock;
let setContentActionMock;
let submitChangesActionMock;
+ let dismissSubmitChangesErrorActionMock;
const buildStore = ({ initialState, getters } = {}) => {
loadContentActionMock = jest.fn();
setContentActionMock = jest.fn();
submitChangesActionMock = jest.fn();
+ dismissSubmitChangesErrorActionMock = jest.fn();
store = new Vuex.Store({
state: createState({
@@ -42,6 +45,7 @@ describe('StaticSiteEditor', () => {
loadContent: loadContentActionMock,
setContent: setContentActionMock,
submitChanges: submitChangesActionMock,
+ dismissSubmitChangesError: dismissSubmitChangesErrorActionMock,
},
});
};
@@ -69,6 +73,7 @@ describe('StaticSiteEditor', () => {
const findInvalidContentMessage = () => wrapper.find(InvalidContentMessage);
const findPublishToolbar = () => wrapper.find(PublishToolbar);
const findSkeletonLoader = () => wrapper.find(GlSkeletonLoader);
+ const findSubmitChangesError = () => wrapper.find(SubmitChangesError);
beforeEach(() => {
buildStore();
@@ -145,6 +150,13 @@ describe('StaticSiteEditor', () => {
expect(findSkeletonLoader().exists()).toBe(true);
});
+ it('does not display submit changes error when an error does not exist', () => {
+ buildContentLoadedStore();
+ buildWrapper();
+
+ expect(findSubmitChangesError().exists()).toBe(false);
+ });
+
it('sets toolbar as saving when saving changes', () => {
buildContentLoadedStore({
initialState: {
@@ -163,6 +175,33 @@ describe('StaticSiteEditor', () => {
expect(findInvalidContentMessage().exists()).toBe(true);
});
+ describe('when submitting changes fail', () => {
+ beforeEach(() => {
+ buildContentLoadedStore({
+ initialState: {
+ submitChangesError,
+ },
+ });
+ buildWrapper();
+ });
+
+ it('displays submit changes error message', () => {
+ expect(findSubmitChangesError().exists()).toBe(true);
+ });
+
+ it('dispatches submitChanges action when error message emits retry event', () => {
+ findSubmitChangesError().vm.$emit('retry');
+
+ expect(submitChangesActionMock).toHaveBeenCalled();
+ });
+
+ it('dispatches dismissSubmitChangesError action when error message emits dismiss event', () => {
+ findSubmitChangesError().vm.$emit('dismiss');
+
+ expect(dismissSubmitChangesErrorActionMock).toHaveBeenCalled();
+ });
+ });
+
it('dispatches load content action', () => {
expect(loadContentActionMock).toHaveBeenCalled();
});
diff --git a/spec/frontend/static_site_editor/components/submit_changes_error_spec.js b/spec/frontend/static_site_editor/components/submit_changes_error_spec.js
new file mode 100644
index 00000000000..7af3014b338
--- /dev/null
+++ b/spec/frontend/static_site_editor/components/submit_changes_error_spec.js
@@ -0,0 +1,48 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlButton, GlAlert } from '@gitlab/ui';
+
+import SubmitChangesError from '~/static_site_editor/components/submit_changes_error.vue';
+
+import { submitChangesError as error } from '../mock_data';
+
+describe('Submit Changes Error', () => {
+ let wrapper;
+
+ const buildWrapper = (propsData = {}) => {
+ wrapper = shallowMount(SubmitChangesError, {
+ propsData: {
+ ...propsData,
+ },
+ stubs: {
+ GlAlert,
+ },
+ });
+ };
+
+ const findRetryButton = () => wrapper.find(GlButton);
+ const findAlert = () => wrapper.find(GlAlert);
+
+ beforeEach(() => {
+ buildWrapper({ error });
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('renders error message', () => {
+ expect(findAlert().text()).toContain(error);
+ });
+
+ it('emits dismiss event when alert emits dismiss event', () => {
+ findAlert().vm.$emit('dismiss');
+
+ expect(wrapper.emitted('dismiss')).toHaveLength(1);
+ });
+
+ it('emits retry event when retry button is clicked', () => {
+ findRetryButton().vm.$emit('click');
+
+ expect(wrapper.emitted('retry')).toHaveLength(1);
+ });
+});
diff --git a/spec/frontend/static_site_editor/store/actions_spec.js b/spec/frontend/static_site_editor/store/actions_spec.js
index a9c039517b7..6b0b77f59b7 100644
--- a/spec/frontend/static_site_editor/store/actions_spec.js
+++ b/spec/frontend/static_site_editor/store/actions_spec.js
@@ -124,24 +124,29 @@ describe('Static Site Editor Store actions', () => {
});
describe('on error', () => {
+ const error = new Error(submitChangesError);
const expectedMutations = [
{ type: mutationTypes.SUBMIT_CHANGES },
- { type: mutationTypes.SUBMIT_CHANGES_ERROR },
+ { type: mutationTypes.SUBMIT_CHANGES_ERROR, payload: error.message },
];
beforeEach(() => {
- submitContentChanges.mockRejectedValueOnce(new Error(submitChangesError));
+ submitContentChanges.mockRejectedValueOnce(error);
});
it('dispatches receiveContentError', () => {
testAction(actions.submitChanges, null, state, expectedMutations);
});
+ });
+ });
- it('displays flash communicating error', () => {
- return testAction(actions.submitChanges, null, state, expectedMutations).then(() => {
- expect(createFlash).toHaveBeenCalledWith(submitChangesError);
- });
- });
+ describe('dismissSubmitChangesError', () => {
+ it('commits dismissSubmitChangesError', () => {
+ testAction(actions.dismissSubmitChangesError, null, state, [
+ {
+ type: mutationTypes.DISMISS_SUBMIT_CHANGES_ERROR,
+ },
+ ]);
});
});
});
diff --git a/spec/frontend/static_site_editor/store/mutations_spec.js b/spec/frontend/static_site_editor/store/mutations_spec.js
index 0b213c11a04..2441f317d90 100644
--- a/spec/frontend/static_site_editor/store/mutations_spec.js
+++ b/spec/frontend/static_site_editor/store/mutations_spec.js
@@ -5,6 +5,7 @@ import {
sourceContentTitle as title,
sourceContent as content,
savedContentMeta,
+ submitChangesError,
} from '../mock_data';
describe('Static Site Editor Store mutations', () => {
@@ -16,19 +17,21 @@ describe('Static Site Editor Store mutations', () => {
});
it.each`
- mutation | stateProperty | payload | expectedValue
- ${types.LOAD_CONTENT} | ${'isLoadingContent'} | ${undefined} | ${true}
- ${types.RECEIVE_CONTENT_SUCCESS} | ${'isLoadingContent'} | ${contentLoadedPayload} | ${false}
- ${types.RECEIVE_CONTENT_SUCCESS} | ${'isContentLoaded'} | ${contentLoadedPayload} | ${true}
- ${types.RECEIVE_CONTENT_SUCCESS} | ${'title'} | ${contentLoadedPayload} | ${title}
- ${types.RECEIVE_CONTENT_SUCCESS} | ${'content'} | ${contentLoadedPayload} | ${content}
- ${types.RECEIVE_CONTENT_SUCCESS} | ${'originalContent'} | ${contentLoadedPayload} | ${content}
- ${types.RECEIVE_CONTENT_ERROR} | ${'isLoadingContent'} | ${undefined} | ${false}
- ${types.SET_CONTENT} | ${'content'} | ${content} | ${content}
- ${types.SUBMIT_CHANGES} | ${'isSavingChanges'} | ${undefined} | ${true}
- ${types.SUBMIT_CHANGES_SUCCESS} | ${'savedContentMeta'} | ${savedContentMeta} | ${savedContentMeta}
- ${types.SUBMIT_CHANGES_SUCCESS} | ${'isSavingChanges'} | ${savedContentMeta} | ${false}
- ${types.SUBMIT_CHANGES_ERROR} | ${'isSavingChanges'} | ${undefined} | ${false}
+ mutation | stateProperty | payload | expectedValue
+ ${types.LOAD_CONTENT} | ${'isLoadingContent'} | ${undefined} | ${true}
+ ${types.RECEIVE_CONTENT_SUCCESS} | ${'isLoadingContent'} | ${contentLoadedPayload} | ${false}
+ ${types.RECEIVE_CONTENT_SUCCESS} | ${'isContentLoaded'} | ${contentLoadedPayload} | ${true}
+ ${types.RECEIVE_CONTENT_SUCCESS} | ${'title'} | ${contentLoadedPayload} | ${title}
+ ${types.RECEIVE_CONTENT_SUCCESS} | ${'content'} | ${contentLoadedPayload} | ${content}
+ ${types.RECEIVE_CONTENT_SUCCESS} | ${'originalContent'} | ${contentLoadedPayload} | ${content}
+ ${types.RECEIVE_CONTENT_ERROR} | ${'isLoadingContent'} | ${undefined} | ${false}
+ ${types.SET_CONTENT} | ${'content'} | ${content} | ${content}
+ ${types.SUBMIT_CHANGES} | ${'isSavingChanges'} | ${undefined} | ${true}
+ ${types.SUBMIT_CHANGES_SUCCESS} | ${'savedContentMeta'} | ${savedContentMeta} | ${savedContentMeta}
+ ${types.SUBMIT_CHANGES_SUCCESS} | ${'isSavingChanges'} | ${savedContentMeta} | ${false}
+ ${types.SUBMIT_CHANGES_ERROR} | ${'isSavingChanges'} | ${undefined} | ${false}
+ ${types.SUBMIT_CHANGES_ERROR} | ${'submitChangesError'} | ${submitChangesError} | ${submitChangesError}
+ ${types.DISMISS_SUBMIT_CHANGES_ERROR} | ${'submitChangesError'} | ${undefined} | ${''}
`(
'$mutation sets $stateProperty to $expectedValue',
({ mutation, stateProperty, payload, expectedValue }) => {
diff --git a/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb b/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb
index 33d4994f5db..e275ebef2c9 100644
--- a/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb
+++ b/spec/lib/gitlab/diff/formatters/text_formatter_spec.rb
@@ -9,7 +9,8 @@ describe Gitlab::Diff::Formatters::TextFormatter do
start_sha: 456,
head_sha: 789,
old_path: 'old_path.txt',
- new_path: 'new_path.txt'
+ new_path: 'new_path.txt',
+ line_range: nil
}
end
diff --git a/spec/lib/gitlab/diff/position_spec.rb b/spec/lib/gitlab/diff/position_spec.rb
index 4b11ff16c38..a83c0f35d92 100644
--- a/spec/lib/gitlab/diff/position_spec.rb
+++ b/spec/lib/gitlab/diff/position_spec.rb
@@ -28,6 +28,7 @@ describe Gitlab::Diff::Position do
new_path: "files/ruby/popen.rb",
old_line: nil,
new_line: 14,
+ line_range: nil,
base_sha: nil,
head_sha: nil,
start_sha: nil,
diff --git a/spec/lib/gitlab/prometheus/adapter_spec.rb b/spec/lib/gitlab/prometheus/adapter_spec.rb
index 202bf65f92b..afee95467fa 100644
--- a/spec/lib/gitlab/prometheus/adapter_spec.rb
+++ b/spec/lib/gitlab/prometheus/adapter_spec.rb
@@ -19,6 +19,14 @@ describe Gitlab::Prometheus::Adapter do
it 'return prometheus service as prometheus adapter' do
expect(subject.prometheus_adapter).to eq(prometheus_service)
end
+
+ context 'with cluster with prometheus available' do
+ let!(:prometheus) { create(:clusters_applications_prometheus, :installed, cluster: cluster) }
+
+ it 'returns prometheus service' do
+ expect(subject.prometheus_adapter).to eq(prometheus_service)
+ end
+ end
end
context "prometheus service can't execute queries" do
diff --git a/spec/models/diff_note_position_spec.rb b/spec/models/diff_note_position_spec.rb
index dedb8a8da4d..d93e0af5526 100644
--- a/spec/models/diff_note_position_spec.rb
+++ b/spec/models/diff_note_position_spec.rb
@@ -40,4 +40,11 @@ describe DiffNotePosition, type: :model do
expect { diff_note_position.save! }.to raise_error(ActiveRecord::RecordNotUnique)
end
+
+ it 'accepts a line_range attribute' do
+ diff_note_position = build(:diff_note_position)
+
+ expect(diff_note_position).to respond_to(:line_range)
+ expect(diff_note_position).to respond_to(:line_range=)
+ end
end
diff --git a/spec/models/project_services/prometheus_service_spec.rb b/spec/models/project_services/prometheus_service_spec.rb
index 5565d30d8c1..a85dbe3a7df 100644
--- a/spec/models/project_services/prometheus_service_spec.rb
+++ b/spec/models/project_services/prometheus_service_spec.rb
@@ -418,4 +418,48 @@ describe PrometheusService, :use_clean_rails_memory_store_caching do
end
end
end
+
+ describe '#editable?' do
+ it 'is editable' do
+ expect(service.editable?).to be(true)
+ end
+
+ context 'when cluster exists with prometheus installed' do
+ let(:cluster) { create(:cluster, projects: [project]) }
+
+ before do
+ service.update!(manual_configuration: false)
+
+ create(:clusters_applications_prometheus, :installed, cluster: cluster)
+ end
+
+ it 'remains editable' do
+ expect(service.editable?).to be(true)
+ end
+ end
+ end
+
+ describe '#fields' do
+ let(:expected_fields) do
+ [
+ {
+ type: 'checkbox',
+ name: 'manual_configuration',
+ title: s_('PrometheusService|Active'),
+ required: true
+ },
+ {
+ type: 'text',
+ name: 'api_url',
+ title: 'API URL',
+ placeholder: s_('PrometheusService|Prometheus API Base URL, like http://prometheus.example.com/'),
+ required: true
+ }
+ ]
+ end
+
+ it 'returns fields' do
+ expect(service.fields).to eq(expected_fields)
+ end
+ end
end
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 0272d269aa4..c1b1150c28b 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -838,6 +838,13 @@ describe 'project routing' do
end
end
+ describe Projects::StaticSiteEditorController, 'routing' do
+ it 'routes to static_site_editor#show', :aggregate_failures do
+ expect(get('/gitlab/gitlabhq/-/sse/master/CONTRIBUTING.md')).to route_to('projects/static_site_editor#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/CONTRIBUTING.md')
+ expect(get('/gitlab/gitlabhq/-/sse/master/README')).to route_to('projects/static_site_editor#show', namespace_id: 'gitlab', project_id: 'gitlabhq', id: 'master/README')
+ end
+ end
+
describe Projects::EnvironmentsController, 'routing' do
describe 'legacy routing' do
it_behaves_like 'redirecting a legacy project path', "/gitlab/gitlabhq/environments", "/gitlab/gitlabhq/-/environments"
diff --git a/spec/support/shared_examples/models/diff_positionable_note_shared_examples.rb b/spec/support/shared_examples/models/diff_positionable_note_shared_examples.rb
index 38a9f1fe098..aa8979603b6 100644
--- a/spec/support/shared_examples/models/diff_positionable_note_shared_examples.rb
+++ b/spec/support/shared_examples/models/diff_positionable_note_shared_examples.rb
@@ -13,6 +13,7 @@ RSpec.shared_examples 'a valid diff positionable note' do |factory_on_commit|
new_path: "files/ruby/popen.rb",
old_line: nil,
new_line: 14,
+ line_range: nil,
diff_refs: diff_refs
)
end
diff --git a/spec/support/shared_examples/requests/api/diff_discussions_shared_examples.rb b/spec/support/shared_examples/requests/api/diff_discussions_shared_examples.rb
index 583475678f1..3d25b9076ad 100644
--- a/spec/support/shared_examples/requests/api/diff_discussions_shared_examples.rb
+++ b/spec/support/shared_examples/requests/api/diff_discussions_shared_examples.rb
@@ -22,12 +22,18 @@ RSpec.shared_examples 'diff discussions API' do |parent_type, noteable_type, id_
expect(json_response['id']).to eq(diff_note.discussion_id)
expect(json_response['notes'].first['body']).to eq(diff_note.note)
expect(json_response['notes'].first['position']).to eq(diff_note.position.to_h.stringify_keys)
+ expect(json_response['notes'].first['line_range']).to eq(nil)
end
end
describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions" do
it "creates a new diff note" do
- position = diff_note.position.to_h
+ line_range = {
+ "start_line_code" => Gitlab::Git.diff_line_code(diff_note.position.file_path, 1, 1),
+ "end_line_code" => Gitlab::Git.diff_line_code(diff_note.position.file_path, 2, 2)
+ }
+
+ position = diff_note.position.to_h.merge({ line_range: line_range })
post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user),
params: { body: 'hi!', position: position }
diff --git a/yarn.lock b/yarn.lock
index 280bc27d183..f5fbd60efb0 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -806,10 +806,10 @@
vue-loader "^15.4.2"
vue-runtime-helpers "^1.1.2"
-"@gitlab/visual-review-tools@1.5.1":
- version "1.5.1"
- resolved "https://registry.yarnpkg.com/@gitlab/visual-review-tools/-/visual-review-tools-1.5.1.tgz#2552927cd7a376f1f06ef3293a69fe2ffcdddb52"
- integrity sha512-8d6xgK4TsLA5gucd78jzaMyginAMJ8cbu/6ghUGws84zzAEsyJsMTstyt/fA5l4toQXVxtOh90BvDzwxSjZ6hQ==
+"@gitlab/visual-review-tools@1.6.1":
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/@gitlab/visual-review-tools/-/visual-review-tools-1.6.1.tgz#0d8f3ff9f51b05f7c80b9a107727703d48997e4e"
+ integrity sha512-vY8K1igwZFoEOmU0h4E7XTLlilsQ4ylPr27O01UsSe6ZTKi6oEMREsRAEpNIUgRlxUARCsf+Opp4pgSFzFkFcw==
"@gitlab/vue-toasted@^1.3.0":
version "1.3.0"