Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-03-18 18:09:04 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-03-18 18:09:04 +0300
commitdfda8b7e77835fc54d469eda336b13b415365703 (patch)
treeb94d991d464dc1e98f0f365e1e15e94c3ee8c9ca
parent19d46f60a3699232458357111365e63a8c71f20d (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/blob/file_template_selector.js11
-rw-r--r--app/assets/javascripts/design_management/pages/index.vue4
-rw-r--r--app/assets/javascripts/emoji/index.js5
-rw-r--r--app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue24
-rw-r--r--app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/lib/utils/props_utils.js35
-rw-r--r--app/finders/notes_finder.rb12
-rw-r--r--app/models/bulk_imports/entity.rb19
-rw-r--r--app/models/bulk_imports/tracker.rb6
-rw-r--r--app/models/concerns/sortable.rb1
-rw-r--r--app/models/note.rb13
-rw-r--r--app/models/wiki.rb47
-rw-r--r--app/services/ci/register_job_service.rb16
-rw-r--r--app/services/concerns/integrations/project_test_data.rb2
-rw-r--r--app/views/projects/blob/_template_selectors.html.haml2
-rw-r--r--app/views/projects/jobs/index.html.haml6
-rw-r--r--app/views/projects/logs/empty_logs.html.haml2
-rw-r--r--app/views/projects/tracings/_tracing_button.html.haml2
-rw-r--r--changelogs/unreleased/232887-add-created_at-to-job-webhooks.yml5
-rw-r--r--changelogs/unreleased/btn-confirm-logs.yml5
-rw-r--r--changelogs/unreleased/btn-confirm-pipeline_new.yml5
-rw-r--r--changelogs/unreleased/btn-confirm-tracing.yml5
-rw-r--r--changelogs/unreleased/kassio-bulkimports-track-pipeline-work.yml5
-rw-r--r--changelogs/unreleased/lm-deep-stringify-merged-yaml.yml5
-rw-r--r--changelogs/unreleased/nicolasdular-apply-ci-template-via-param.yml5
-rw-r--r--changelogs/unreleased/pb-remove-jobs-page-ci-lint-button.yml5
-rw-r--r--changelogs/unreleased/pb-ux-ci-cd-toggle-setting.yml5
-rw-r--r--config/feature_flags/development/ci_runner_builds_queue_on_replicas.yml8
-rw-r--r--config/feature_flags/development/gitaly_replace_wiki_delete_page.yml8
-rw-r--r--doc/administration/logs.md2
-rw-r--r--doc/administration/monitoring/github_imports.md2
-rw-r--r--doc/administration/monitoring/gitlab_self_monitoring_project/index.md2
-rw-r--r--doc/administration/monitoring/index.md2
-rw-r--r--doc/administration/monitoring/ip_whitelist.md2
-rw-r--r--doc/administration/monitoring/performance/gitlab_configuration.md2
-rw-r--r--doc/administration/monitoring/performance/grafana_configuration.md2
-rw-r--r--doc/administration/monitoring/performance/index.md2
-rw-r--r--doc/administration/monitoring/performance/performance_bar.md2
-rw-r--r--doc/administration/monitoring/performance/request_profiling.md2
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_exporter.md2
-rw-r--r--doc/administration/monitoring/prometheus/gitlab_metrics.md2
-rw-r--r--doc/administration/monitoring/prometheus/index.md2
-rw-r--r--doc/administration/monitoring/prometheus/node_exporter.md2
-rw-r--r--doc/administration/monitoring/prometheus/pgbouncer_exporter.md2
-rw-r--r--doc/administration/monitoring/prometheus/postgres_exporter.md2
-rw-r--r--doc/administration/monitoring/prometheus/redis_exporter.md2
-rw-r--r--doc/administration/monitoring/prometheus/registry_exporter.md2
-rw-r--r--doc/api/error_tracking.md2
-rw-r--r--doc/api/metrics_dashboard_annotations.md2
-rw-r--r--doc/api/metrics_user_starred_dashboards.md2
-rw-r--r--doc/development/agent/identity.md12
-rw-r--r--doc/development/distributed_tracing.md2
-rw-r--r--doc/development/fe_guide/performance.md2
-rw-r--r--doc/development/i18n/externalization.md92
-rw-r--r--doc/development/instrumentation.md2
-rw-r--r--doc/development/logging.md2
-rw-r--r--doc/development/prometheus_metrics.md2
-rw-r--r--doc/operations/error_tracking.md2
-rw-r--r--doc/operations/incident_management/alerts.md2
-rw-r--r--doc/operations/incident_management/incidents.md2
-rw-r--r--doc/operations/incident_management/index.md2
-rw-r--r--doc/operations/incident_management/integrations.md2
-rw-r--r--doc/operations/incident_management/paging.md2
-rw-r--r--doc/operations/incident_management/status_page.md2
-rw-r--r--doc/operations/index.md2
-rw-r--r--doc/operations/metrics/alerts.md2
-rw-r--r--doc/operations/metrics/dashboards/default.md2
-rw-r--r--doc/operations/metrics/dashboards/develop.md2
-rw-r--r--doc/operations/metrics/dashboards/index.md2
-rw-r--r--doc/operations/metrics/dashboards/panel_types.md2
-rw-r--r--doc/operations/metrics/dashboards/settings.md2
-rw-r--r--doc/operations/metrics/dashboards/templating_variables.md2
-rw-r--r--doc/operations/metrics/dashboards/variables.md2
-rw-r--r--doc/operations/metrics/dashboards/yaml.md2
-rw-r--r--doc/operations/metrics/dashboards/yaml_number_format.md2
-rw-r--r--doc/operations/metrics/embed.md2
-rw-r--r--doc/operations/metrics/embed_grafana.md2
-rw-r--r--doc/operations/metrics/index.md2
-rw-r--r--doc/operations/tracing.md2
-rw-r--r--doc/raketasks/generate_sample_prometheus_data.md2
-rw-r--r--doc/user/clusters/agent/index.md18
-rw-r--r--doc/user/project/clusters/index.md2
-rw-r--r--doc/user/project/clusters/kubernetes_pod_logs.md2
-rw-r--r--doc/user/project/integrations/prometheus.md2
-rw-r--r--doc/user/project/integrations/prometheus_library/cloudwatch.md2
-rw-r--r--doc/user/project/integrations/prometheus_library/haproxy.md2
-rw-r--r--doc/user/project/integrations/prometheus_library/index.md2
-rw-r--r--doc/user/project/integrations/prometheus_library/kubernetes.md2
-rw-r--r--doc/user/project/integrations/prometheus_library/nginx.md2
-rw-r--r--doc/user/project/integrations/prometheus_library/nginx_ingress.md2
-rw-r--r--doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md2
-rw-r--r--doc/user/project/integrations/webhooks.md1
-rw-r--r--lib/bulk_imports/groups/graphql/get_labels_query.rb2
-rw-r--r--lib/bulk_imports/groups/graphql/get_members_query.rb2
-rw-r--r--lib/bulk_imports/groups/graphql/get_milestones_query.rb2
-rw-r--r--lib/bulk_imports/groups/pipelines/labels_pipeline.rb3
-rw-r--r--lib/bulk_imports/groups/pipelines/members_pipeline.rb3
-rw-r--r--lib/bulk_imports/groups/pipelines/milestones_pipeline.rb3
-rw-r--r--lib/bulk_imports/importers/group_importer.rb13
-rw-r--r--lib/bulk_imports/pipeline.rb4
-rw-r--r--lib/bulk_imports/pipeline/context.rb22
-rw-r--r--lib/bulk_imports/pipeline/extracted_data.rb7
-rw-r--r--lib/bulk_imports/pipeline/runner.rb17
-rw-r--r--lib/gitlab/ci/queue/metrics.rb27
-rw-r--r--lib/gitlab/ci/yaml_processor/result.rb2
-rw-r--r--lib/gitlab/data_builder/build.rb1
-rw-r--r--lib/gitlab/updated_notes_paginator.rb2
-rw-r--r--locale/gitlab.pot3
-rw-r--r--spec/features/issues/markdown_toolbar_spec.rb28
-rw-r--r--spec/features/issues/user_comments_on_issue_spec.rb18
-rw-r--r--spec/features/issues/user_edits_issue_spec.rb6
-rw-r--r--spec/features/merge_request/user_posts_notes_spec.rb4
-rw-r--r--spec/features/merge_request/user_sees_notes_from_forked_project_spec.rb4
-rw-r--r--spec/features/participants_autocomplete_spec.rb44
-rw-r--r--spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb42
-rw-r--r--spec/features/projects/jobs/user_browses_jobs_spec.rb8
-rw-r--r--spec/features/projects/snippets/user_comments_on_snippet_spec.rb1
-rw-r--r--spec/features/snippets/notes_on_personal_snippets_spec.rb3
-rw-r--r--spec/finders/notes_finder_spec.rb18
-rw-r--r--spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js2
-rw-r--r--spec/frontend/vue_shared/components/lib/utils/props_utils_spec.js91
-rw-r--r--spec/lib/bulk_imports/common/transformers/user_reference_transformer_spec.rb3
-rw-r--r--spec/lib/bulk_imports/groups/extractors/subgroups_extractor_spec.rb3
-rw-r--r--spec/lib/bulk_imports/groups/graphql/get_group_query_spec.rb6
-rw-r--r--spec/lib/bulk_imports/groups/graphql/get_labels_query_spec.rb4
-rw-r--r--spec/lib/bulk_imports/groups/graphql/get_members_query_spec.rb4
-rw-r--r--spec/lib/bulk_imports/groups/graphql/get_milestones_query_spec.rb4
-rw-r--r--spec/lib/bulk_imports/groups/loaders/group_loader_spec.rb11
-rw-r--r--spec/lib/bulk_imports/groups/pipelines/group_pipeline_spec.rb14
-rw-r--r--spec/lib/bulk_imports/groups/pipelines/labels_pipeline_spec.rb18
-rw-r--r--spec/lib/bulk_imports/groups/pipelines/members_pipeline_spec.rb3
-rw-r--r--spec/lib/bulk_imports/groups/pipelines/milestones_pipeline_spec.rb9
-rw-r--r--spec/lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline_spec.rb12
-rw-r--r--spec/lib/bulk_imports/groups/transformers/group_attributes_transformer_spec.rb23
-rw-r--r--spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb3
-rw-r--r--spec/lib/bulk_imports/importers/group_importer_spec.rb22
-rw-r--r--spec/lib/bulk_imports/pipeline/context_spec.rb45
-rw-r--r--spec/lib/bulk_imports/pipeline/runner_spec.rb19
-rw-r--r--spec/lib/bulk_imports/pipeline_spec.rb10
-rw-r--r--spec/lib/gitlab/ci/lint_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/yaml_processor/result_spec.rb2
-rw-r--r--spec/lib/gitlab/data_builder/build_spec.rb3
-rw-r--r--spec/models/bulk_imports/entity_spec.rb64
-rw-r--r--spec/models/concerns/sortable_spec.rb25
-rw-r--r--spec/models/note_spec.rb95
-rw-r--r--spec/requests/api/lint_spec.rb12
-rw-r--r--spec/support/shared_examples/models/wiki_shared_examples.rb53
147 files changed, 846 insertions, 516 deletions
diff --git a/app/assets/javascripts/blob/file_template_selector.js b/app/assets/javascripts/blob/file_template_selector.js
index a5c8050b772..21c23495315 100644
--- a/app/assets/javascripts/blob/file_template_selector.js
+++ b/app/assets/javascripts/blob/file_template_selector.js
@@ -19,6 +19,17 @@ export default class FileTemplateSelector {
this.$dropdownToggleText = this.$wrapper.find('.dropdown-toggle-text');
this.initDropdown();
+ this.selectInitialTemplate();
+ }
+
+ selectInitialTemplate() {
+ const template = this.$dropdown.data('selected');
+
+ if (!template) {
+ return;
+ }
+
+ this.mediator.selectTemplateFile(this, template);
}
show() {
diff --git a/app/assets/javascripts/design_management/pages/index.vue b/app/assets/javascripts/design_management/pages/index.vue
index 99ac38fc554..3cc22e1519b 100644
--- a/app/assets/javascripts/design_management/pages/index.vue
+++ b/app/assets/javascripts/design_management/pages/index.vue
@@ -485,9 +485,7 @@ export default {
<template #upload-text="{ openFileUpload }">
<gl-sprintf :message="$options.i18n.dropzoneDescriptionText">
<template #link="{ content }">
- <gl-link @click.stop="openFileUpload">
- {{ content }}
- </gl-link>
+ <gl-link @click.stop="openFileUpload">{{ content }}</gl-link>
</template>
</gl-sprintf>
</template>
diff --git a/app/assets/javascripts/emoji/index.js b/app/assets/javascripts/emoji/index.js
index d3b658a4020..7faf0fe5f08 100644
--- a/app/assets/javascripts/emoji/index.js
+++ b/app/assets/javascripts/emoji/index.js
@@ -2,7 +2,7 @@ import { escape, minBy } from 'lodash';
import emojiAliases from 'emojis/aliases.json';
import AccessorUtilities from '../lib/utils/accessor';
import axios from '../lib/utils/axios_utils';
-import { CATEGORY_ICON_MAP } from './constants';
+import { CATEGORY_ICON_MAP, FREQUENTLY_USED_KEY } from './constants';
let emojiMap = null;
let validEmojiNames = null;
@@ -162,6 +162,9 @@ let emojiCategoryMap;
export function getEmojiCategoryMap() {
if (!emojiCategoryMap) {
emojiCategoryMap = CATEGORY_NAMES.reduce((acc, category) => {
+ if (category === FREQUENTLY_USED_KEY) {
+ return acc;
+ }
return { ...acc, [category]: [] };
}, {});
Object.keys(emojiMap).forEach((name) => {
diff --git a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
index 0b58cb4731d..419e98dad50 100644
--- a/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
+++ b/app/assets/javascripts/pages/projects/shared/permissions/components/settings_panel.vue
@@ -482,18 +482,6 @@ export default {
/>
</project-setting-row>
<project-setting-row
- ref="pipeline-settings"
- :label="s__('ProjectSettings|Pipelines')"
- :help-text="s__('ProjectSettings|Build, test, and deploy your changes.')"
- >
- <project-feature-setting
- v-model="buildsAccessLevel"
- :options="repoFeatureAccessLevelOptions"
- :disabled-input="!repositoryEnabled"
- name="project[project_feature_attributes][builds_access_level]"
- />
- </project-setting-row>
- <project-setting-row
v-if="registryAvailable"
ref="container-registry-settings"
:help-path="registryHelpPath"
@@ -567,6 +555,18 @@ export default {
</project-setting-row>
</div>
<project-setting-row
+ ref="pipeline-settings"
+ :label="__('CI/CD')"
+ :help-text="s__('ProjectSettings|Build, test, and deploy your changes.')"
+ >
+ <project-feature-setting
+ v-model="buildsAccessLevel"
+ :options="repoFeatureAccessLevelOptions"
+ :disabled-input="!repositoryEnabled"
+ name="project[project_feature_attributes][builds_access_level]"
+ />
+ </project-setting-row>
+ <project-setting-row
ref="analytics-settings"
:label="s__('ProjectSettings|Analytics')"
:help-text="s__('ProjectSettings|View project analytics.')"
diff --git a/app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue b/app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue
index ff6a354f673..772fe178b24 100644
--- a/app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue
+++ b/app/assets/javascripts/pipeline_new/components/pipeline_new_form.vue
@@ -447,7 +447,7 @@ export default {
<gl-button
type="submit"
category="primary"
- variant="success"
+ variant="confirm"
class="js-no-auto-disable"
data-qa-selector="run_pipeline_button"
data-testid="run_pipeline_button"
diff --git a/app/assets/javascripts/vue_shared/components/lib/utils/props_utils.js b/app/assets/javascripts/vue_shared/components/lib/utils/props_utils.js
new file mode 100644
index 00000000000..b115b1fb34b
--- /dev/null
+++ b/app/assets/javascripts/vue_shared/components/lib/utils/props_utils.js
@@ -0,0 +1,35 @@
+/**
+ * Return the union of the given components' props options. Required props take
+ * precendence over non-required props of the same name.
+ *
+ * This makes two assumptions:
+ * - All given components define their props in verbose object format.
+ * - The components all agree on the `type` of a common prop.
+ *
+ * @param {object[]} components The components to derive the union from.
+ * @returns {object} The union of the props of the given components.
+ */
+export const propsUnion = (components) =>
+ components.reduce((acc, component) => {
+ Object.entries(component.props ?? {}).forEach(([propName, propOptions]) => {
+ if (process.env.NODE_ENV !== 'production') {
+ if (typeof propOptions !== 'object' || !('type' in propOptions)) {
+ throw new Error(
+ `Cannot create props union: expected verbose prop options for prop "${propName}"`,
+ );
+ }
+
+ if (propName in acc && acc[propName]?.type !== propOptions?.type) {
+ throw new Error(
+ `Cannot create props union: incompatible prop types for prop "${propName}"`,
+ );
+ }
+ }
+
+ if (!(propName in acc) || propOptions.required) {
+ acc[propName] = propOptions;
+ }
+ });
+
+ return acc;
+ }, {});
diff --git a/app/finders/notes_finder.rb b/app/finders/notes_finder.rb
index 1a3f011d9eb..96966001e85 100644
--- a/app/finders/notes_finder.rb
+++ b/app/finders/notes_finder.rb
@@ -17,6 +17,7 @@ class NotesFinder
# target_id: integer
# last_fetched_at: time
# search: string
+ # sort: string
#
def initialize(current_user, params = {})
@project = params[:project]
@@ -29,8 +30,7 @@ class NotesFinder
notes = init_collection
notes = since_fetch_at(notes)
notes = notes.with_notes_filter(@params[:notes_filter]) if notes_filter?
-
- notes.fresh
+ sort(notes)
end
def target
@@ -173,6 +173,14 @@ class NotesFinder
def notes_filter?
@params[:notes_filter].present?
end
+
+ def sort(notes)
+ sort = @params[:sort].presence
+
+ return notes.fresh unless sort
+
+ notes.order_by(sort)
+ end
end
NotesFinder.prepend_if_ee('EE::NotesFinder')
diff --git a/app/models/bulk_imports/entity.rb b/app/models/bulk_imports/entity.rb
index 9127dab56a6..04af1145769 100644
--- a/app/models/bulk_imports/entity.rb
+++ b/app/models/bulk_imports/entity.rb
@@ -68,25 +68,6 @@ class BulkImports::Entity < ApplicationRecord
end
end
- def update_tracker_for(relation:, has_next_page:, next_page: nil)
- attributes = {
- relation: relation,
- has_next_page: has_next_page,
- next_page: next_page,
- bulk_import_entity_id: id
- }
-
- trackers.upsert(attributes, unique_by: %i[bulk_import_entity_id relation])
- end
-
- def has_next_page?(relation)
- trackers.find_by(relation: relation)&.has_next_page
- end
-
- def next_page_for(relation)
- trackers.find_by(relation: relation)&.next_page
- end
-
private
def validate_parent_is_a_group
diff --git a/app/models/bulk_imports/tracker.rb b/app/models/bulk_imports/tracker.rb
index 182c0bbaa8a..8d16edccd5b 100644
--- a/app/models/bulk_imports/tracker.rb
+++ b/app/models/bulk_imports/tracker.rb
@@ -3,6 +3,8 @@
class BulkImports::Tracker < ApplicationRecord
self.table_name = 'bulk_import_trackers'
+ alias_attribute :pipeline_name, :relation
+
belongs_to :entity,
class_name: 'BulkImports::Entity',
foreign_key: :bulk_import_entity_id,
@@ -28,6 +30,10 @@ class BulkImports::Tracker < ApplicationRecord
end
event :finish do
+ # When applying the concurrent model,
+ # remove the created => finished transaction
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/323384
+ transition created: :finished
transition started: :finished
transition failed: :failed
transition skipped: :skipped
diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb
index 4fe2a0e1827..9f5e9b2bb57 100644
--- a/app/models/concerns/sortable.rb
+++ b/app/models/concerns/sortable.rb
@@ -9,6 +9,7 @@ module Sortable
included do
scope :with_order_id_desc, -> { order(self.arel_table['id'].desc) }
+ scope :with_order_id_asc, -> { order(self.arel_table['id'].asc) }
scope :order_id_desc, -> { reorder(self.arel_table['id'].desc) }
scope :order_id_asc, -> { reorder(self.arel_table['id'].asc) }
scope :order_created_desc, -> { reorder(self.arel_table['created_at'].desc) }
diff --git a/app/models/note.rb b/app/models/note.rb
index fb540d692d1..c75d6aa77e6 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -19,6 +19,7 @@ class Note < ApplicationRecord
include Gitlab::SQL::Pattern
include ThrottledTouch
include FromUnion
+ include Sortable
cache_markdown_field :note, pipeline: :note, issuable_state_filter_enabled: true
@@ -103,10 +104,9 @@ class Note < ApplicationRecord
scope :system, -> { where(system: true) }
scope :user, -> { where(system: false) }
scope :common, -> { where(noteable_type: ["", nil]) }
- scope :fresh, -> { order(created_at: :asc, id: :asc) }
+ scope :fresh, -> { order_created_asc.with_order_id_asc }
scope :updated_after, ->(time) { where('updated_at > ?', time) }
scope :with_updated_at, ->(time) { where(updated_at: time) }
- scope :by_updated_at, -> { reorder(:updated_at, :id) }
scope :inc_author_project, -> { includes(:project, :author) }
scope :inc_author, -> { includes(:author) }
scope :inc_relations_for_view, -> do
@@ -148,6 +148,8 @@ class Note < ApplicationRecord
after_commit :notify_after_destroy, on: :destroy
class << self
+ extend Gitlab::Utils::Override
+
def model_name
ActiveModel::Name.new(self, nil, 'note')
end
@@ -204,6 +206,13 @@ class Note < ApplicationRecord
def search(query)
fuzzy_search(query, [:note])
end
+
+ # Override the `Sortable` module's `.simple_sorts` to remove name sorting,
+ # as a `Note` does not have any property that correlates to a "name".
+ override :simple_sorts
+ def simple_sorts
+ super.except('name_asc', 'name_desc')
+ end
end
# rubocop: disable CodeReuse/ServiceClass
diff --git a/app/models/wiki.rb b/app/models/wiki.rb
index df31c54bd0f..3445e7180e6 100644
--- a/app/models/wiki.rb
+++ b/app/models/wiki.rb
@@ -196,10 +196,20 @@ class Wiki
def delete_page(page, message = nil)
return unless page
- wiki.delete_page(page.path, commit_details(:deleted, message, page.title))
- after_wiki_activity
+ if Feature.enabled?(:gitaly_replace_wiki_delete_page, user, default_enabled: :yaml)
+ capture_git_error(:deleted) do
+ repository.delete_file(user, page.path, **multi_commit_options(:deleted, message, page.title))
- true
+ after_wiki_activity
+
+ true
+ end
+ else
+ wiki.delete_page(page.path, commit_details(:deleted, message, page.title))
+ after_wiki_activity
+
+ true
+ end
end
def page_title_and_dir(title)
@@ -276,8 +286,20 @@ class Wiki
private
+ def multi_commit_options(action, message = nil, title = nil)
+ commit_message = build_commit_message(action, message, title)
+ git_user = Gitlab::Git::User.from_gitlab(user)
+
+ {
+ branch_name: repository.root_ref,
+ message: commit_message,
+ author_email: git_user.email,
+ author_name: git_user.name
+ }
+ end
+
def commit_details(action, message = nil, title = nil)
- commit_message = message.presence || default_message(action, title)
+ commit_message = build_commit_message(action, message, title)
git_user = Gitlab::Git::User.from_gitlab(user)
Gitlab::Git::Wiki::CommitDetails.new(user.id,
@@ -287,9 +309,26 @@ class Wiki
commit_message)
end
+ def build_commit_message(action, message, title)
+ message.presence || default_message(action, title)
+ end
+
def default_message(action, title)
"#{user.username} #{action} page: #{title}"
end
+
+ def capture_git_error(action, &block)
+ yield block
+ rescue Gitlab::Git::Index::IndexError,
+ Gitlab::Git::CommitError,
+ Gitlab::Git::PreReceiveError,
+ Gitlab::Git::CommandError,
+ ArgumentError => error
+
+ Gitlab::ErrorTracking.log_exception(error, action: action, wiki_id: id)
+
+ false
+ end
end
Wiki.prepend_if_ee('EE::Wiki')
diff --git a/app/services/ci/register_job_service.rb b/app/services/ci/register_job_service.rb
index 7f42ec0b750..f6978c76058 100644
--- a/app/services/ci/register_job_service.rb
+++ b/app/services/ci/register_job_service.rb
@@ -24,7 +24,7 @@ module Ci
def execute(params = {})
@metrics.increment_queue_operation(:queue_attempt)
- @metrics.observe_queue_time do
+ @metrics.observe_queue_time(:process) do
process_queue(params)
end
end
@@ -110,7 +110,7 @@ module Ci
end
if Feature.enabled?(:ci_register_job_service_one_by_one, runner, default_enabled: true)
- build_ids = builds.pluck(:id)
+ build_ids = retrieve_queue(-> { builds.pluck(:id) })
@metrics.observe_queue_size(-> { build_ids.size })
@@ -118,13 +118,21 @@ module Ci
yield Ci::Build.find(build_id)
end
else
- @metrics.observe_queue_size(-> { builds.to_a.size })
+ builds_array = retrieve_queue(-> { builds.to_a })
- builds.each(&blk)
+ @metrics.observe_queue_size(-> { builds_array.size })
+
+ builds_array.each(&blk)
end
end
# rubocop: enable CodeReuse/ActiveRecord
+ def retrieve_queue(queue_query_proc)
+ @metrics.observe_queue_time(:retrieve) do
+ queue_query_proc.call
+ end
+ end
+
def process_build(build, params)
unless build.pending?
@metrics.increment_queue_operation(:build_not_pending)
diff --git a/app/services/concerns/integrations/project_test_data.rb b/app/services/concerns/integrations/project_test_data.rb
index 57bcba98b49..5968b90f8fe 100644
--- a/app/services/concerns/integrations/project_test_data.rb
+++ b/app/services/concerns/integrations/project_test_data.rb
@@ -9,7 +9,7 @@ module Integrations
end
def note_events_data
- note = NotesFinder.new(current_user, project: project, target: project).execute.reorder(nil).last # rubocop: disable CodeReuse/ActiveRecord
+ note = NotesFinder.new(current_user, project: project, target: project, sort: 'id_desc').execute.first
return { error: s_('TestHooks|Ensure the project has notes.') } unless note.present?
diff --git a/app/views/projects/blob/_template_selectors.html.haml b/app/views/projects/blob/_template_selectors.html.haml
index 717c03ad27d..24a4db010c8 100644
--- a/app/views/projects/blob/_template_selectors.html.haml
+++ b/app/views/projects/blob/_template_selectors.html.haml
@@ -10,7 +10,7 @@
.metrics-dashboard-selector.js-metrics-dashboard-selector-wrap.js-template-selector-wrap.hidden
= dropdown_tag(_("Apply a template"), options: { toggle_class: 'js-metrics-dashboard-selector qa-metrics-dashboard-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: metrics_dashboard_ymls(@project) } } )
#gitlab-ci-yml-selector.gitlab-ci-yml-selector.js-gitlab-ci-yml-selector-wrap.js-template-selector-wrap.hidden
- = dropdown_tag(_("Apply a template"), options: { toggle_class: 'js-gitlab-ci-yml-selector qa-gitlab-ci-yml-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: gitlab_ci_ymls(@project) } } )
+ = dropdown_tag(_("Apply a template"), options: { toggle_class: 'js-gitlab-ci-yml-selector qa-gitlab-ci-yml-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: gitlab_ci_ymls(@project), selected: params[:template] } } )
- if experiment_enabled?(:ci_syntax_templates_b, subject: current_user) && @project.namespace.recent?
.gitlab-ci-syntax-yml-selector.js-gitlab-ci-syntax-yml-selector-wrap.js-template-selector-wrap.hidden
= dropdown_tag(_("Learn CI/CD syntax"), options: { toggle_class: 'js-gitlab-ci-syntax-yml-selector qa-gitlab-ci-syntax-yml-dropdown', dropdown_class: 'dropdown-menu-selectable', filter: true, placeholder: "Filter", data: { data: gitlab_ci_syntax_ymls(@project) } } )
diff --git a/app/views/projects/jobs/index.html.haml b/app/views/projects/jobs/index.html.haml
index a0ec6002db7..0f9cf1c511e 100644
--- a/app/views/projects/jobs/index.html.haml
+++ b/app/views/projects/jobs/index.html.haml
@@ -5,11 +5,5 @@
- build_path_proc = ->(scope) { project_jobs_path(@project, scope: scope) }
= render "shared/builds/tabs", build_path_proc: build_path_proc, all_builds: @all_builds, scope: @scope
- .nav-controls
- - if can?(current_user, :update_build, @project)
- = link_to project_ci_lint_path(@project), class: 'btn gl-button btn-default' do
- %span
- = _('CI Lint')
-
.content-list.builds-content-list
= render "table", builds: @builds, project: @project
diff --git a/app/views/projects/logs/empty_logs.html.haml b/app/views/projects/logs/empty_logs.html.haml
index 5e3db401d79..48403f5e55e 100644
--- a/app/views/projects/logs/empty_logs.html.haml
+++ b/app/views/projects/logs/empty_logs.html.haml
@@ -11,4 +11,4 @@
%p.state-description.text-center
= s_('Logs|To see the logs, deploy your code to an environment.')
.text-center
- = link_to s_('Environments|Learn about environments'), help_page_path('ci/environments/index.md'), class: 'gl-button btn btn-success'
+ = link_to s_('Environments|Learn about environments'), help_page_path('ci/environments/index.md'), class: 'gl-button btn btn-confirm'
diff --git a/app/views/projects/tracings/_tracing_button.html.haml b/app/views/projects/tracings/_tracing_button.html.haml
index b0ab6fa21e1..fe3af1c6a1a 100644
--- a/app/views/projects/tracings/_tracing_button.html.haml
+++ b/app/views/projects/tracings/_tracing_button.html.haml
@@ -1,2 +1,2 @@
-= link_to project_settings_operations_path(@project), title: _('Configure Tracing'), class: 'gl-button btn btn-success' do
+= link_to project_settings_operations_path(@project), title: _('Configure Tracing'), class: 'gl-button btn btn-confirm' do
= _('Add Jaeger URL')
diff --git a/changelogs/unreleased/232887-add-created_at-to-job-webhooks.yml b/changelogs/unreleased/232887-add-created_at-to-job-webhooks.yml
new file mode 100644
index 00000000000..4ece4ba2f9b
--- /dev/null
+++ b/changelogs/unreleased/232887-add-created_at-to-job-webhooks.yml
@@ -0,0 +1,5 @@
+---
+title: Add created_at to job webhooks
+merge_request: 56835
+author:
+type: changed
diff --git a/changelogs/unreleased/btn-confirm-logs.yml b/changelogs/unreleased/btn-confirm-logs.yml
new file mode 100644
index 00000000000..8da1dddbad2
--- /dev/null
+++ b/changelogs/unreleased/btn-confirm-logs.yml
@@ -0,0 +1,5 @@
+---
+title: Move from btn-success to btn-confirm in logs directory
+merge_request: 56211
+author: Yogi (@yo)
+type: changed
diff --git a/changelogs/unreleased/btn-confirm-pipeline_new.yml b/changelogs/unreleased/btn-confirm-pipeline_new.yml
new file mode 100644
index 00000000000..d38b582ec07
--- /dev/null
+++ b/changelogs/unreleased/btn-confirm-pipeline_new.yml
@@ -0,0 +1,5 @@
+---
+title: Move to confirm variant from success in pipeline_new directory
+merge_request: 56199
+author: Yogi (@yo)
+type: changed
diff --git a/changelogs/unreleased/btn-confirm-tracing.yml b/changelogs/unreleased/btn-confirm-tracing.yml
new file mode 100644
index 00000000000..3b3f84ce73f
--- /dev/null
+++ b/changelogs/unreleased/btn-confirm-tracing.yml
@@ -0,0 +1,5 @@
+---
+title: Move from btn-success to btn-confirm in tracings directory
+merge_request: 56209
+author: Yogi (@yo)
+type: changed
diff --git a/changelogs/unreleased/kassio-bulkimports-track-pipeline-work.yml b/changelogs/unreleased/kassio-bulkimports-track-pipeline-work.yml
new file mode 100644
index 00000000000..3665f0c995f
--- /dev/null
+++ b/changelogs/unreleased/kassio-bulkimports-track-pipeline-work.yml
@@ -0,0 +1,5 @@
+---
+title: 'BulkImports: Track pipeline worker with BulkImports::Tracker#status'
+merge_request: 56242
+author:
+type: changed
diff --git a/changelogs/unreleased/lm-deep-stringify-merged-yaml.yml b/changelogs/unreleased/lm-deep-stringify-merged-yaml.yml
new file mode 100644
index 00000000000..0640c45060d
--- /dev/null
+++ b/changelogs/unreleased/lm-deep-stringify-merged-yaml.yml
@@ -0,0 +1,5 @@
+---
+title: Returns deep stringified keys for merged_yaml in linting endpoint
+merge_request: 54336
+author:
+type: changed
diff --git a/changelogs/unreleased/nicolasdular-apply-ci-template-via-param.yml b/changelogs/unreleased/nicolasdular-apply-ci-template-via-param.yml
new file mode 100644
index 00000000000..72d4384b323
--- /dev/null
+++ b/changelogs/unreleased/nicolasdular-apply-ci-template-via-param.yml
@@ -0,0 +1,5 @@
+---
+title: Allow selecting a CI template by providing the template name as a URL param gitlab_ci_yml
+merge_request: 56861
+author:
+type: added
diff --git a/changelogs/unreleased/pb-remove-jobs-page-ci-lint-button.yml b/changelogs/unreleased/pb-remove-jobs-page-ci-lint-button.yml
new file mode 100644
index 00000000000..42b0e909150
--- /dev/null
+++ b/changelogs/unreleased/pb-remove-jobs-page-ci-lint-button.yml
@@ -0,0 +1,5 @@
+---
+title: Remove CI lint button from Jobs page nav
+merge_request: 56854
+author:
+type: removed
diff --git a/changelogs/unreleased/pb-ux-ci-cd-toggle-setting.yml b/changelogs/unreleased/pb-ux-ci-cd-toggle-setting.yml
new file mode 100644
index 00000000000..1c283abced7
--- /dev/null
+++ b/changelogs/unreleased/pb-ux-ci-cd-toggle-setting.yml
@@ -0,0 +1,5 @@
+---
+title: Rename pipelines setting to CI/CD and move out from under repository section
+merge_request: 56857
+author:
+type: changed
diff --git a/config/feature_flags/development/ci_runner_builds_queue_on_replicas.yml b/config/feature_flags/development/ci_runner_builds_queue_on_replicas.yml
new file mode 100644
index 00000000000..edd16781a14
--- /dev/null
+++ b/config/feature_flags/development/ci_runner_builds_queue_on_replicas.yml
@@ -0,0 +1,8 @@
+---
+name: ci_runner_builds_queue_on_replicas
+introduced_by_url:
+rollout_issue_url:
+milestone: '13.10'
+type: development
+group: group::continuous integration
+default_enabled: false
diff --git a/config/feature_flags/development/gitaly_replace_wiki_delete_page.yml b/config/feature_flags/development/gitaly_replace_wiki_delete_page.yml
new file mode 100644
index 00000000000..40100bb2fe6
--- /dev/null
+++ b/config/feature_flags/development/gitaly_replace_wiki_delete_page.yml
@@ -0,0 +1,8 @@
+---
+name: gitaly_replace_wiki_delete_page
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/56495
+rollout_issue_url:
+milestone: '13.10'
+type: development
+group: group::editor
+default_enabled: false
diff --git a/doc/administration/logs.md b/doc/administration/logs.md
index 1950403ce35..289e2cb5362 100644
--- a/doc/administration/logs.md
+++ b/doc/administration/logs.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/github_imports.md b/doc/administration/monitoring/github_imports.md
index 736ff299a86..cd35b8b3f9e 100644
--- a/doc/administration/monitoring/github_imports.md
+++ b/doc/administration/monitoring/github_imports.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/gitlab_self_monitoring_project/index.md b/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
index ca8daf4dc22..8d3c8555660 100644
--- a/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
+++ b/doc/administration/monitoring/gitlab_self_monitoring_project/index.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/index.md b/doc/administration/monitoring/index.md
index 4ebe3d420b5..4c49efd6bd5 100644
--- a/doc/administration/monitoring/index.md
+++ b/doc/administration/monitoring/index.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/ip_whitelist.md b/doc/administration/monitoring/ip_whitelist.md
index 91f9c5d560f..522267ce362 100644
--- a/doc/administration/monitoring/ip_whitelist.md
+++ b/doc/administration/monitoring/ip_whitelist.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/performance/gitlab_configuration.md b/doc/administration/monitoring/performance/gitlab_configuration.md
index a0f170e93d9..6e7557854ad 100644
--- a/doc/administration/monitoring/performance/gitlab_configuration.md
+++ b/doc/administration/monitoring/performance/gitlab_configuration.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/performance/grafana_configuration.md b/doc/administration/monitoring/performance/grafana_configuration.md
index 62d4f3c2625..ac322f3e1ef 100644
--- a/doc/administration/monitoring/performance/grafana_configuration.md
+++ b/doc/administration/monitoring/performance/grafana_configuration.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/performance/index.md b/doc/administration/monitoring/performance/index.md
index cdf78811092..15c54a36f6c 100644
--- a/doc/administration/monitoring/performance/index.md
+++ b/doc/administration/monitoring/performance/index.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/performance/performance_bar.md b/doc/administration/monitoring/performance/performance_bar.md
index 39e5e4f6c00..f6aa60b36a1 100644
--- a/doc/administration/monitoring/performance/performance_bar.md
+++ b/doc/administration/monitoring/performance/performance_bar.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/performance/request_profiling.md b/doc/administration/monitoring/performance/request_profiling.md
index ee035c6ad7a..15a58456e05 100644
--- a/doc/administration/monitoring/performance/request_profiling.md
+++ b/doc/administration/monitoring/performance/request_profiling.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/prometheus/gitlab_exporter.md b/doc/administration/monitoring/prometheus/gitlab_exporter.md
index 589fa799cca..4ba4cad9143 100644
--- a/doc/administration/monitoring/prometheus/gitlab_exporter.md
+++ b/doc/administration/monitoring/prometheus/gitlab_exporter.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/prometheus/gitlab_metrics.md b/doc/administration/monitoring/prometheus/gitlab_metrics.md
index 3c6c984cbe3..f56349fc9e6 100644
--- a/doc/administration/monitoring/prometheus/gitlab_metrics.md
+++ b/doc/administration/monitoring/prometheus/gitlab_metrics.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/prometheus/index.md b/doc/administration/monitoring/prometheus/index.md
index 23bffae99cf..035c5b3ee7e 100644
--- a/doc/administration/monitoring/prometheus/index.md
+++ b/doc/administration/monitoring/prometheus/index.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/prometheus/node_exporter.md b/doc/administration/monitoring/prometheus/node_exporter.md
index 6efc9d67e8d..68d997d7596 100644
--- a/doc/administration/monitoring/prometheus/node_exporter.md
+++ b/doc/administration/monitoring/prometheus/node_exporter.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/prometheus/pgbouncer_exporter.md b/doc/administration/monitoring/prometheus/pgbouncer_exporter.md
index df2aa08efaa..d42c471ac71 100644
--- a/doc/administration/monitoring/prometheus/pgbouncer_exporter.md
+++ b/doc/administration/monitoring/prometheus/pgbouncer_exporter.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/prometheus/postgres_exporter.md b/doc/administration/monitoring/prometheus/postgres_exporter.md
index 8b6d3d82018..783030a9220 100644
--- a/doc/administration/monitoring/prometheus/postgres_exporter.md
+++ b/doc/administration/monitoring/prometheus/postgres_exporter.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/prometheus/redis_exporter.md b/doc/administration/monitoring/prometheus/redis_exporter.md
index e9d656a6493..6cc262842a1 100644
--- a/doc/administration/monitoring/prometheus/redis_exporter.md
+++ b/doc/administration/monitoring/prometheus/redis_exporter.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/administration/monitoring/prometheus/registry_exporter.md b/doc/administration/monitoring/prometheus/registry_exporter.md
index d2bd86aa908..87b51aaed08 100644
--- a/doc/administration/monitoring/prometheus/registry_exporter.md
+++ b/doc/administration/monitoring/prometheus/registry_exporter.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/api/error_tracking.md b/doc/api/error_tracking.md
index c737edbdc44..306383c2de7 100644
--- a/doc/api/error_tracking.md
+++ b/doc/api/error_tracking.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/api/metrics_dashboard_annotations.md b/doc/api/metrics_dashboard_annotations.md
index 896420ed0fb..b2f1e52f194 100644
--- a/doc/api/metrics_dashboard_annotations.md
+++ b/doc/api/metrics_dashboard_annotations.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: concepts, howto
---
diff --git a/doc/api/metrics_user_starred_dashboards.md b/doc/api/metrics_user_starred_dashboards.md
index 9178291181e..6f360cddd61 100644
--- a/doc/api/metrics_user_starred_dashboards.md
+++ b/doc/api/metrics_user_starred_dashboards.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
type: concepts, howto
---
diff --git a/doc/development/agent/identity.md b/doc/development/agent/identity.md
index 49d20d2fd87..83af4318de9 100644
--- a/doc/development/agent/identity.md
+++ b/doc/development/agent/identity.md
@@ -92,3 +92,15 @@ GitLab provides the following information in its response for a given Agent acce
- Agent configuration Git repository. (The agent doesn't support per-folder authorization.)
- Agent name.
+
+## Create an agent
+
+You can create an agent by following the [user documentation](../../user/clusters/agent/index.md#create-an-agent-record-in-gitlab), or via Rails console:
+
+```ruby
+project = ::Project.find_by_full_path("path-to/your-configuration-project")
+# agent-name should be the same as specified above in the config.yaml
+agent = ::Clusters::Agent.create(name: "<agent-name>", project: project)
+token = ::Clusters::AgentToken.create(agent: agent)
+token.token # this will print out the token you need to use on the next step
+```
diff --git a/doc/development/distributed_tracing.md b/doc/development/distributed_tracing.md
index 17967c5f63c..4f53d6b7385 100644
--- a/doc/development/distributed_tracing.md
+++ b/doc/development/distributed_tracing.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/development/fe_guide/performance.md b/doc/development/fe_guide/performance.md
index 28f958e2604..b6130335654 100644
--- a/doc/development/fe_guide/performance.md
+++ b/doc/development/fe_guide/performance.md
@@ -381,7 +381,7 @@ Use `webpackChunkName` when generating dynamic imports as
it provides a deterministic filename for the chunk which can then be cached
in the browser across GitLab versions.
-More information is available in [webpack's code splitting documentation](https://webpack.js.org/guides/code-splitting/#dynamic-imports).
+More information is available in [webpack's code splitting documentation](https://webpack.js.org/guides/code-splitting/#dynamic-imports) and [vue's dynamic component documentation](https://vuejs.org/v2/guide/components-dynamic-async.html).
### Minimizing page size
diff --git a/doc/development/i18n/externalization.md b/doc/development/i18n/externalization.md
index 90355e1cccb..6d848934a17 100644
--- a/doc/development/i18n/externalization.md
+++ b/doc/development/i18n/externalization.md
@@ -255,7 +255,44 @@ For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript. Make s
- In Vue:
- See the section on [Vue component interpolation](#vue-components-interpolation).
+ Use the [`GlSprintf`](https://gitlab-org.gitlab.io/gitlab-ui/?path=/docs/utilities-sprintf--sentence-with-link) component if:
+ - you need to include child components in the translation string.
+ - you need to include HTML in your translation string.
+ - you are using `sprintf` and need to pass `false` as the third argument to
+ prevent it from escaping placeholder values.
+
+ For example:
+
+ ```html
+ <gl-sprintf :message="s__('ClusterIntegration|Learn more about %{linkStart}zones%{linkEnd}')">
+ <template #link="{ content }">
+ <gl-link :href="somePath">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ ```
+
+ In other cases it may be simpler to use `sprintf`, perhaps in a computed
+ property. For example:
+
+ ```html
+ <script>
+ import { __, sprintf } from '~/locale';
+
+ export default {
+ ...
+ computed: {
+ userWelcome() {
+ sprintf(__('Hello %{username}'), { username: this.user.name });
+ }
+ }
+ ...
+ }
+ </script>
+
+ <template>
+ <span>{{ userWelcome }}</span>
+ </template>
+ ```
- In JavaScript (when Vue cannot be used):
@@ -265,12 +302,10 @@ For example use `%{created_at}` in Ruby but `%{createdAt}` in JavaScript. Make s
sprintf(__('Hello %{username}'), { username: 'Joe' }); // => 'Hello Joe'
```
- If you want to use markup within the translation and are using Vue, you
- **must** use the [`gl-sprintf`](#vue-components-interpolation) component. If
- for some reason you cannot use Vue, use `sprintf` and stop it from escaping
- placeholder values by passing `false` as its third argument. You **must**
- escape any interpolated dynamic values yourself, for instance using
- `escape` from `lodash`.
+ If you need to use markup within the translation, use `sprintf` and stop it
+ from escaping placeholder values by passing `false` as its third argument.
+ You **must** escape any interpolated dynamic values yourself, for instance
+ using `escape` from `lodash`.
```javascript
import { escape } from 'lodash';
@@ -632,7 +667,7 @@ This also applies when using links in between translated sentences, otherwise th
{{
sprintf(s__("ClusterIntegration|Learn more about %{link}"), {
link: '<a href="https://cloud.google.com/compute/docs/regions-zones/regions-zones" target="_blank" rel="noopener noreferrer">zones</a>'
- })
+ }, false)
}}
```
@@ -643,7 +678,7 @@ This also applies when using links in between translated sentences, otherwise th
sprintf(s__("ClusterIntegration|Learn more about %{linkStart}zones%{linkEnd}"), {
linkStart: '<a href="https://cloud.google.com/compute/docs/regions-zones/regions-zones" target="_blank" rel="noopener noreferrer">',
linkEnd: '</a>',
- })
+ }, false)
}}
```
@@ -652,45 +687,6 @@ The reasoning behind this is that in some languages words change depending on co
When in doubt, try to follow the best practices described in this [Mozilla
Developer documentation](https://developer.mozilla.org/en-US/docs/Mozilla/Localization/Localization_content_best_practices#Splitting).
-##### Vue components interpolation
-
-When translating UI text in Vue components, you might want to include child components inside
-the translation string.
-You could not use a JavaScript-only solution to render the translation,
-because Vue would not be aware of the child components and would render them as plain text.
-
-For this use case, you should use the `gl-sprintf` component which is maintained
-in **GitLab UI**.
-
-The `gl-sprintf` component accepts a `message` property, which is the translatable string,
-and it exposes a named slot for every placeholder in the string, which lets you include Vue
-components easily.
-
-Assume you want to print the translatable string
-`Pipeline %{pipelineId} triggered %{timeago} by %{author}`. To replace the `%{timeago}` and
-`%{author}` placeholders with Vue components, here's how you would do that with `gl-sprintf`:
-
-```html
-<template>
- <div>
- <gl-sprintf :message="__('Pipeline %{pipelineId} triggered %{timeago} by %{author}')">
- <template #pipelineId>{{ pipeline.id }}</template>
- <template #timeago>
- <timeago :time="pipeline.triggerTime" />
- </template>
- <template #author>
- <gl-avatar-labeled
- :src="pipeline.triggeredBy.avatarPath"
- :label="pipeline.triggeredBy.name"
- />
- </template>
- </gl-sprintf>
- </div>
-</template>
-```
-
-For more information, see the [`gl-sprintf`](https://gitlab-org.gitlab.io/gitlab-ui/?path=/story/base-sprintf--default) documentation.
-
## Updating the PO files with the new content
Now that the new content is marked for translation, we need to update
diff --git a/doc/development/instrumentation.md b/doc/development/instrumentation.md
index 338ad76d414..83e7444bb1f 100644
--- a/doc/development/instrumentation.md
+++ b/doc/development/instrumentation.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/development/logging.md b/doc/development/logging.md
index 30398eb87a1..88ae3950f1a 100644
--- a/doc/development/logging.md
+++ b/doc/development/logging.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/development/prometheus_metrics.md b/doc/development/prometheus_metrics.md
index 05a623448bf..51c5c4954e4 100644
--- a/doc/development/prometheus_metrics.md
+++ b/doc/development/prometheus_metrics.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/error_tracking.md b/doc/operations/error_tracking.md
index 60c576a44e5..a6173548042 100644
--- a/doc/operations/error_tracking.md
+++ b/doc/operations/error_tracking.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/incident_management/alerts.md b/doc/operations/incident_management/alerts.md
index 3c60c737309..276009ac200 100644
--- a/doc/operations/incident_management/alerts.md
+++ b/doc/operations/incident_management/alerts.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/incident_management/incidents.md b/doc/operations/incident_management/incidents.md
index 317797376fc..e4d9a87e39d 100644
--- a/doc/operations/incident_management/incidents.md
+++ b/doc/operations/incident_management/incidents.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/incident_management/index.md b/doc/operations/incident_management/index.md
index 6e285300b12..eb931b3eec5 100644
--- a/doc/operations/incident_management/index.md
+++ b/doc/operations/incident_management/index.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/incident_management/integrations.md b/doc/operations/incident_management/integrations.md
index 62a50255dd8..bdb16b1f88a 100644
--- a/doc/operations/incident_management/integrations.md
+++ b/doc/operations/incident_management/integrations.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/incident_management/paging.md b/doc/operations/incident_management/paging.md
index dbd90cf5847..1588cb96218 100644
--- a/doc/operations/incident_management/paging.md
+++ b/doc/operations/incident_management/paging.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/incident_management/status_page.md b/doc/operations/incident_management/status_page.md
index 46f0a6f278c..1e11a9c62e0 100644
--- a/doc/operations/incident_management/status_page.md
+++ b/doc/operations/incident_management/status_page.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/index.md b/doc/operations/index.md
index 8d0aaaf7cb2..934634562fc 100644
--- a/doc/operations/index.md
+++ b/doc/operations/index.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/metrics/alerts.md b/doc/operations/metrics/alerts.md
index 98beb8d6773..472892c77f9 100644
--- a/doc/operations/metrics/alerts.md
+++ b/doc/operations/metrics/alerts.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/metrics/dashboards/default.md b/doc/operations/metrics/dashboards/default.md
index 3c151586f12..2ba7a4e0d87 100644
--- a/doc/operations/metrics/dashboards/default.md
+++ b/doc/operations/metrics/dashboards/default.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/metrics/dashboards/develop.md b/doc/operations/metrics/dashboards/develop.md
index 76ad609870c..28a4488014a 100644
--- a/doc/operations/metrics/dashboards/develop.md
+++ b/doc/operations/metrics/dashboards/develop.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/metrics/dashboards/index.md b/doc/operations/metrics/dashboards/index.md
index a0ac4fe6226..7b056020a99 100644
--- a/doc/operations/metrics/dashboards/index.md
+++ b/doc/operations/metrics/dashboards/index.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/metrics/dashboards/panel_types.md b/doc/operations/metrics/dashboards/panel_types.md
index 4b942ffcf4f..dc96e2556ac 100644
--- a/doc/operations/metrics/dashboards/panel_types.md
+++ b/doc/operations/metrics/dashboards/panel_types.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/metrics/dashboards/settings.md b/doc/operations/metrics/dashboards/settings.md
index 18cfd6c53b8..e998db6b51b 100644
--- a/doc/operations/metrics/dashboards/settings.md
+++ b/doc/operations/metrics/dashboards/settings.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/metrics/dashboards/templating_variables.md b/doc/operations/metrics/dashboards/templating_variables.md
index 72541f7ced5..20071300dec 100644
--- a/doc/operations/metrics/dashboards/templating_variables.md
+++ b/doc/operations/metrics/dashboards/templating_variables.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/metrics/dashboards/variables.md b/doc/operations/metrics/dashboards/variables.md
index df2dd0939bb..31782b5c95f 100644
--- a/doc/operations/metrics/dashboards/variables.md
+++ b/doc/operations/metrics/dashboards/variables.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/metrics/dashboards/yaml.md b/doc/operations/metrics/dashboards/yaml.md
index 138d9b28c76..45803598a40 100644
--- a/doc/operations/metrics/dashboards/yaml.md
+++ b/doc/operations/metrics/dashboards/yaml.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/metrics/dashboards/yaml_number_format.md b/doc/operations/metrics/dashboards/yaml_number_format.md
index dd652a0cc2b..3b6e10e647e 100644
--- a/doc/operations/metrics/dashboards/yaml_number_format.md
+++ b/doc/operations/metrics/dashboards/yaml_number_format.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/metrics/embed.md b/doc/operations/metrics/embed.md
index 87d84bfdfc0..d773d04f1cc 100644
--- a/doc/operations/metrics/embed.md
+++ b/doc/operations/metrics/embed.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/metrics/embed_grafana.md b/doc/operations/metrics/embed_grafana.md
index 2548e81813b..3b509f7c4c6 100644
--- a/doc/operations/metrics/embed_grafana.md
+++ b/doc/operations/metrics/embed_grafana.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/metrics/index.md b/doc/operations/metrics/index.md
index ca7bce347d3..8ff45ac4015 100644
--- a/doc/operations/metrics/index.md
+++ b/doc/operations/metrics/index.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/operations/tracing.md b/doc/operations/tracing.md
index a4aae05c46d..bf9e0d2390e 100644
--- a/doc/operations/tracing.md
+++ b/doc/operations/tracing.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/raketasks/generate_sample_prometheus_data.md b/doc/raketasks/generate_sample_prometheus_data.md
index 41e31c0b817..f014b82cca1 100644
--- a/doc/raketasks/generate_sample_prometheus_data.md
+++ b/doc/raketasks/generate_sample_prometheus_data.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/user/clusters/agent/index.md b/doc/user/clusters/agent/index.md
index 38d95ccd0be..fa0f32a8fb0 100644
--- a/doc/user/clusters/agent/index.md
+++ b/doc/user/clusters/agent/index.md
@@ -176,23 +176,9 @@ documentation on the [Kubernetes Agent configuration repository](repository.md).
### Create an Agent record in GitLab
-Next, create an GitLab Rails Agent record so the Agent can associate itself with
+Next, create a GitLab Rails Agent record to associate it with
the configuration repository project. Creating this record also creates a Secret needed to configure
-the Agent in subsequent steps. You can create an Agent record either:
-
-- Through the Rails console:
-
- ```ruby
- project = ::Project.find_by_full_path("path-to/your-configuration-project")
- # agent-name should be the same as specified above in the config.yaml
- agent = ::Clusters::Agent.create(name: "<agent-name>", project: project)
- token = ::Clusters::AgentToken.create(agent: agent)
- token.token # this will print out the token you need to use on the next step
- ```
-
- For full details, read [Starting a Rails console session](../../../administration/operations/rails_console.md#starting-a-rails-console-session).
-
-- Through GraphQL: **(PREMIUM SELF)**
+the Agent in subsequent steps. You can create an Agent record with GraphQL:
```graphql
mutation createAgent {
diff --git a/doc/user/project/clusters/index.md b/doc/user/project/clusters/index.md
index 1af452d75da..6b144556e05 100644
--- a/doc/user/project/clusters/index.md
+++ b/doc/user/project/clusters/index.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/user/project/clusters/kubernetes_pod_logs.md b/doc/user/project/clusters/kubernetes_pod_logs.md
index 349040e0bf6..bafb7d472c6 100644
--- a/doc/user/project/clusters/kubernetes_pod_logs.md
+++ b/doc/user/project/clusters/kubernetes_pod_logs.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/user/project/integrations/prometheus.md b/doc/user/project/integrations/prometheus.md
index c307fd8d628..05dd4da88fc 100644
--- a/doc/user/project/integrations/prometheus.md
+++ b/doc/user/project/integrations/prometheus.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/user/project/integrations/prometheus_library/cloudwatch.md b/doc/user/project/integrations/prometheus_library/cloudwatch.md
index 04abb922175..0eaa9cae7c0 100644
--- a/doc/user/project/integrations/prometheus_library/cloudwatch.md
+++ b/doc/user/project/integrations/prometheus_library/cloudwatch.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/user/project/integrations/prometheus_library/haproxy.md b/doc/user/project/integrations/prometheus_library/haproxy.md
index 290313ac1af..11b74c35a74 100644
--- a/doc/user/project/integrations/prometheus_library/haproxy.md
+++ b/doc/user/project/integrations/prometheus_library/haproxy.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/user/project/integrations/prometheus_library/index.md b/doc/user/project/integrations/prometheus_library/index.md
index 998300e255f..584c0898fec 100644
--- a/doc/user/project/integrations/prometheus_library/index.md
+++ b/doc/user/project/integrations/prometheus_library/index.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/user/project/integrations/prometheus_library/kubernetes.md b/doc/user/project/integrations/prometheus_library/kubernetes.md
index 2a6bc810f71..e14c1c0f6fd 100644
--- a/doc/user/project/integrations/prometheus_library/kubernetes.md
+++ b/doc/user/project/integrations/prometheus_library/kubernetes.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/user/project/integrations/prometheus_library/nginx.md b/doc/user/project/integrations/prometheus_library/nginx.md
index dcaef1e2ae6..3f888a89b1b 100644
--- a/doc/user/project/integrations/prometheus_library/nginx.md
+++ b/doc/user/project/integrations/prometheus_library/nginx.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/user/project/integrations/prometheus_library/nginx_ingress.md b/doc/user/project/integrations/prometheus_library/nginx_ingress.md
index f7e6b6e76d6..8846aadd420 100644
--- a/doc/user/project/integrations/prometheus_library/nginx_ingress.md
+++ b/doc/user/project/integrations/prometheus_library/nginx_ingress.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md b/doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md
index 0c86c4921b3..4752fec976c 100644
--- a/doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md
+++ b/doc/user/project/integrations/prometheus_library/nginx_ingress_vts.md
@@ -1,6 +1,6 @@
---
stage: Monitor
-group: Health
+group: Monitor
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
diff --git a/doc/user/project/integrations/webhooks.md b/doc/user/project/integrations/webhooks.md
index bf289c9707c..dc63a32ed10 100644
--- a/doc/user/project/integrations/webhooks.md
+++ b/doc/user/project/integrations/webhooks.md
@@ -1297,6 +1297,7 @@ X-Gitlab-Event: Job Hook
"build_name": "test",
"build_stage": "test",
"build_status": "created",
+ "build_created_at": "2021-02-23T02:41:37.886Z",
"build_started_at": null,
"build_finished_at": null,
"build_duration": null,
diff --git a/lib/bulk_imports/groups/graphql/get_labels_query.rb b/lib/bulk_imports/groups/graphql/get_labels_query.rb
index 23efbc33581..2d246a217a7 100644
--- a/lib/bulk_imports/groups/graphql/get_labels_query.rb
+++ b/lib/bulk_imports/groups/graphql/get_labels_query.rb
@@ -31,7 +31,7 @@ module BulkImports
def variables(context)
{
full_path: context.entity.source_full_path,
- cursor: context.entity.next_page_for(:labels)
+ cursor: context.tracker.next_page
}
end
diff --git a/lib/bulk_imports/groups/graphql/get_members_query.rb b/lib/bulk_imports/groups/graphql/get_members_query.rb
index e3a78124a47..f3a0d77acc2 100644
--- a/lib/bulk_imports/groups/graphql/get_members_query.rb
+++ b/lib/bulk_imports/groups/graphql/get_members_query.rb
@@ -34,7 +34,7 @@ module BulkImports
def variables(context)
{
full_path: context.entity.source_full_path,
- cursor: context.entity.next_page_for(:group_members)
+ cursor: context.tracker.next_page
}
end
diff --git a/lib/bulk_imports/groups/graphql/get_milestones_query.rb b/lib/bulk_imports/groups/graphql/get_milestones_query.rb
index 2ade87e6fa0..c254b35054a 100644
--- a/lib/bulk_imports/groups/graphql/get_milestones_query.rb
+++ b/lib/bulk_imports/groups/graphql/get_milestones_query.rb
@@ -33,7 +33,7 @@ module BulkImports
def variables(context)
{
full_path: context.entity.source_full_path,
- cursor: context.entity.next_page_for(:milestones)
+ cursor: context.tracker.next_page
}
end
diff --git a/lib/bulk_imports/groups/pipelines/labels_pipeline.rb b/lib/bulk_imports/groups/pipelines/labels_pipeline.rb
index 9f8b8682751..61d3e6c700e 100644
--- a/lib/bulk_imports/groups/pipelines/labels_pipeline.rb
+++ b/lib/bulk_imports/groups/pipelines/labels_pipeline.rb
@@ -16,8 +16,7 @@ module BulkImports
end
def after_run(extracted_data)
- context.entity.update_tracker_for(
- relation: :labels,
+ tracker.update(
has_next_page: extracted_data.has_next_page?,
next_page: extracted_data.next_page
)
diff --git a/lib/bulk_imports/groups/pipelines/members_pipeline.rb b/lib/bulk_imports/groups/pipelines/members_pipeline.rb
index 32fc931e8c3..d29bd74c5ae 100644
--- a/lib/bulk_imports/groups/pipelines/members_pipeline.rb
+++ b/lib/bulk_imports/groups/pipelines/members_pipeline.rb
@@ -19,8 +19,7 @@ module BulkImports
end
def after_run(extracted_data)
- context.entity.update_tracker_for(
- relation: :group_members,
+ tracker.update(
has_next_page: extracted_data.has_next_page?,
next_page: extracted_data.next_page
)
diff --git a/lib/bulk_imports/groups/pipelines/milestones_pipeline.rb b/lib/bulk_imports/groups/pipelines/milestones_pipeline.rb
index 8497162e0e7..eb51424c14a 100644
--- a/lib/bulk_imports/groups/pipelines/milestones_pipeline.rb
+++ b/lib/bulk_imports/groups/pipelines/milestones_pipeline.rb
@@ -20,8 +20,7 @@ module BulkImports
end
def after_run(extracted_data)
- context.entity.update_tracker_for(
- relation: :milestones,
+ tracker.update(
has_next_page: extracted_data.has_next_page?,
next_page: extracted_data.next_page
)
diff --git a/lib/bulk_imports/importers/group_importer.rb b/lib/bulk_imports/importers/group_importer.rb
index f016b552fd4..ccc61ee787d 100644
--- a/lib/bulk_imports/importers/group_importer.rb
+++ b/lib/bulk_imports/importers/group_importer.rb
@@ -8,9 +8,18 @@ module BulkImports
end
def execute
- context = BulkImports::Pipeline::Context.new(entity)
+ pipelines.each.with_index do |pipeline, stage|
+ pipeline_tracker = entity.trackers.create!(
+ pipeline_name: pipeline,
+ stage: stage
+ )
- pipelines.each { |pipeline| pipeline.new(context).run }
+ context = BulkImports::Pipeline::Context.new(pipeline_tracker)
+
+ pipeline.new(context).run
+
+ pipeline_tracker.finish!
+ end
entity.finish!
end
diff --git a/lib/bulk_imports/pipeline.rb b/lib/bulk_imports/pipeline.rb
index 14445162737..df4f020d6b2 100644
--- a/lib/bulk_imports/pipeline.rb
+++ b/lib/bulk_imports/pipeline.rb
@@ -15,6 +15,10 @@ module BulkImports
@context = context
end
+ def tracker
+ @tracker ||= context.tracker
+ end
+
included do
private
diff --git a/lib/bulk_imports/pipeline/context.rb b/lib/bulk_imports/pipeline/context.rb
index dd121b2dbed..3c69c729f36 100644
--- a/lib/bulk_imports/pipeline/context.rb
+++ b/lib/bulk_imports/pipeline/context.rb
@@ -3,25 +3,33 @@
module BulkImports
module Pipeline
class Context
- attr_reader :entity, :bulk_import
attr_accessor :extra
- def initialize(entity, extra = {})
- @entity = entity
- @bulk_import = entity.bulk_import
+ attr_reader :tracker
+
+ def initialize(tracker, extra = {})
+ @tracker = tracker
@extra = extra
end
+ def entity
+ @entity ||= tracker.entity
+ end
+
def group
- entity.group
+ @group ||= entity.group
+ end
+
+ def bulk_import
+ @bulk_import ||= entity.bulk_import
end
def current_user
- bulk_import.user
+ @current_user ||= bulk_import.user
end
def configuration
- bulk_import.configuration
+ @configuration ||= bulk_import.configuration
end
end
end
diff --git a/lib/bulk_imports/pipeline/extracted_data.rb b/lib/bulk_imports/pipeline/extracted_data.rb
index 685a91a4afe..15b5caa1a47 100644
--- a/lib/bulk_imports/pipeline/extracted_data.rb
+++ b/lib/bulk_imports/pipeline/extracted_data.rb
@@ -11,11 +11,14 @@ module BulkImports
end
def has_next_page?
- @page_info['has_next_page']
+ Gitlab::Utils.to_boolean(
+ @page_info&.dig('has_next_page'),
+ default: false
+ )
end
def next_page
- @page_info['end_cursor']
+ @page_info&.dig('end_cursor')
end
def each(&block)
diff --git a/lib/bulk_imports/pipeline/runner.rb b/lib/bulk_imports/pipeline/runner.rb
index e3535e585cc..588d2c87209 100644
--- a/lib/bulk_imports/pipeline/runner.rb
+++ b/lib/bulk_imports/pipeline/runner.rb
@@ -26,7 +26,7 @@ module BulkImports
end
end
- if respond_to?(:after_run)
+ if extracted_data && respond_to?(:after_run)
run_pipeline_step(:after_run) do
after_run(extracted_data)
end
@@ -34,7 +34,7 @@ module BulkImports
info(message: 'Pipeline finished')
rescue MarkedAsFailedError
- log_skip
+ skip!('Skipping pipeline due to failed entity')
end
private # rubocop:disable Lint/UselessAccessModifier
@@ -46,7 +46,11 @@ module BulkImports
yield
rescue MarkedAsFailedError
- log_skip(step => class_name)
+ skip!(
+ 'Skipping pipeline due to failed entity',
+ pipeline_step: step,
+ step_class: class_name
+ )
rescue => e
log_import_failure(e, step)
@@ -65,10 +69,13 @@ module BulkImports
warn(message: 'Pipeline failed')
context.entity.fail_op!
+ tracker.fail_op!
end
- def log_skip(extra = {})
- info({ message: 'Skipping due to failed pipeline status' }.merge(extra))
+ def skip!(message, extra = {})
+ warn({ message: message }.merge(extra))
+
+ tracker.skip!
end
def log_import_failure(exception, step)
diff --git a/lib/gitlab/ci/queue/metrics.rb b/lib/gitlab/ci/queue/metrics.rb
index 5398c19e536..b25e715bc00 100644
--- a/lib/gitlab/ci/queue/metrics.rb
+++ b/lib/gitlab/ci/queue/metrics.rb
@@ -10,7 +10,7 @@ module Gitlab
QUEUE_ACTIVE_RUNNERS_BUCKETS = [1, 3, 10, 30, 60, 300, 900, 1800, 3600].freeze
QUEUE_DEPTH_TOTAL_BUCKETS = [1, 2, 3, 5, 8, 16, 32, 50, 100, 250, 500, 1000, 2000, 5000].freeze
QUEUE_SIZE_TOTAL_BUCKETS = [1, 5, 10, 50, 100, 500, 1000, 2000, 5000].freeze
- QUEUE_ITERATION_DURATION_SECONDS_BUCKETS = [0.1, 0.3, 0.5, 1, 5, 10, 30, 60, 180, 300].freeze
+ QUEUE_PROCESSING_DURATION_SECONDS_BUCKETS = [0.01, 0.05, 0.1, 0.3, 0.5, 1, 5, 10, 30, 60, 180, 300].freeze
METRICS_SHARD_TAG_PREFIX = 'metrics_shard::'
DEFAULT_METRICS_SHARD = 'default'
@@ -100,7 +100,7 @@ module Gitlab
self.class.queue_size_total.observe({}, size_proc.call.to_f)
end
- def observe_queue_time
+ def observe_queue_time(metric)
start_time = ::Gitlab::Metrics::System.monotonic_time
result = yield
@@ -108,7 +108,15 @@ module Gitlab
return result unless Feature.enabled?(:gitlab_ci_builds_queuing_metrics, default_enabled: false)
seconds = ::Gitlab::Metrics::System.monotonic_time - start_time
- self.class.queue_iteration_duration_seconds.observe({}, seconds.to_f)
+
+ case metric
+ when :process
+ self.class.queue_iteration_duration_seconds.observe({}, seconds.to_f)
+ when :retrieve
+ self.class.queue_retrieval_duration_seconds.observe({}, seconds.to_f)
+ else
+ raise ArgumentError unless Rails.env.production?
+ end
result
end
@@ -187,7 +195,18 @@ module Gitlab
strong_memoize(:queue_iteration_duration_seconds) do
name = :gitlab_ci_queue_iteration_duration_seconds
comment = 'Time it takes to find a build in CI/CD queue'
- buckets = QUEUE_ITERATION_DURATION_SECONDS_BUCKETS
+ buckets = QUEUE_PROCESSING_DURATION_SECONDS_BUCKETS
+ labels = {}
+
+ Gitlab::Metrics.histogram(name, comment, labels, buckets)
+ end
+ end
+
+ def self.queue_retrieval_duration_seconds
+ strong_memoize(:queue_retrieval_duration_seconds) do
+ name = :gitlab_ci_queue_retrieval_duration_seconds
+ comment = 'Time it takes to execute a SQL query to retrieve builds queue'
+ buckets = QUEUE_PROCESSING_DURATION_SECONDS_BUCKETS
labels = {}
Gitlab::Metrics.histogram(name, comment, labels, buckets)
diff --git a/lib/gitlab/ci/yaml_processor/result.rb b/lib/gitlab/ci/yaml_processor/result.rb
index 3459b69bebc..f2c75227002 100644
--- a/lib/gitlab/ci/yaml_processor/result.rb
+++ b/lib/gitlab/ci/yaml_processor/result.rb
@@ -101,7 +101,7 @@ module Gitlab
end
def merged_yaml
- @ci_config&.to_hash&.to_yaml
+ @ci_config&.to_hash&.deep_stringify_keys&.to_yaml
end
def variables_with_data
diff --git a/lib/gitlab/data_builder/build.rb b/lib/gitlab/data_builder/build.rb
index c4af5e6608e..8ce71558ab3 100644
--- a/lib/gitlab/data_builder/build.rb
+++ b/lib/gitlab/data_builder/build.rb
@@ -26,6 +26,7 @@ module Gitlab
build_name: build.name,
build_stage: build.stage,
build_status: build.status,
+ build_created_at: build.created_at,
build_started_at: build.started_at,
build_finished_at: build.finished_at,
build_duration: build.duration,
diff --git a/lib/gitlab/updated_notes_paginator.rb b/lib/gitlab/updated_notes_paginator.rb
index 511d6dccf7c..d5c01bde6b3 100644
--- a/lib/gitlab/updated_notes_paginator.rb
+++ b/lib/gitlab/updated_notes_paginator.rb
@@ -37,7 +37,7 @@ module Gitlab
end
def fetch_page(relation)
- relation = relation.by_updated_at
+ relation = relation.order_updated_asc.with_order_id_asc
notes = relation.limit(LIMIT + 1).to_a
return [notes, false] unless notes.size > LIMIT
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 79def8448fb..22f146e0d06 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -24052,9 +24052,6 @@ msgstr ""
msgid "ProjectSettings|Pages for project documentation."
msgstr ""
-msgid "ProjectSettings|Pipelines"
-msgstr ""
-
msgid "ProjectSettings|Pipelines must succeed"
msgstr ""
diff --git a/spec/features/issues/markdown_toolbar_spec.rb b/spec/features/issues/markdown_toolbar_spec.rb
index 6dc1cbfb2d7..aad5d319bc4 100644
--- a/spec/features/issues/markdown_toolbar_spec.rb
+++ b/spec/features/issues/markdown_toolbar_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
RSpec.describe 'Issue markdown toolbar', :js do
- let(:project) { create(:project, :public) }
- let(:issue) { create(:issue, project: project) }
- let(:user) { create(:user) }
+ let_it_be(:project) { create(:project, :public) }
+ let_it_be(:issue) { create(:issue, project: project) }
+ let_it_be(:user) { create(:user) }
before do
sign_in(user)
@@ -14,28 +14,22 @@ RSpec.describe 'Issue markdown toolbar', :js do
end
it "doesn't include first new line when adding bold" do
- find('#note-body').native.send_keys('test')
- find('#note-body').native.send_key(:enter)
- find('#note-body').native.send_keys('bold')
+ fill_in 'Comment', with: "test\nbold"
- find('.js-main-target-form #note-body')
- page.evaluate_script('document.querySelectorAll(".js-main-target-form #note-body")[0].setSelectionRange(4, 9)')
+ page.evaluate_script('document.getElementById("note-body").setSelectionRange(4, 9)')
- first('.toolbar-btn').click
+ click_button 'Add bold text'
- expect(find('#note-body')[:value]).to eq("test\n**bold**\n")
+ expect(find_field('Comment').value).to eq("test\n**bold**\n")
end
it "doesn't include first new line when adding underline" do
- find('#note-body').native.send_keys('test')
- find('#note-body').native.send_key(:enter)
- find('#note-body').native.send_keys('underline')
+ fill_in 'Comment', with: "test\nunderline"
- find('.js-main-target-form #note-body')
- page.evaluate_script('document.querySelectorAll(".js-main-target-form #note-body")[0].setSelectionRange(4, 50)')
+ page.evaluate_script('document.getElementById("note-body").setSelectionRange(4, 50)')
- all('.toolbar-btn')[1].click
+ click_button 'Add italic text'
- expect(find('#note-body')[:value]).to eq("test\n_underline_\n")
+ expect(find_field('Comment').value).to eq("test\n_underline_\n")
end
end
diff --git a/spec/features/issues/user_comments_on_issue_spec.rb b/spec/features/issues/user_comments_on_issue_spec.rb
index 004488f2f64..09d3ad15641 100644
--- a/spec/features/issues/user_comments_on_issue_spec.rb
+++ b/spec/features/issues/user_comments_on_issue_spec.rb
@@ -57,17 +57,9 @@ RSpec.describe "User comments on issue", :js do
project.add_maintainer(user)
create(:label, project: project, title: 'label')
- page.within '.timeline-content-form' do
- find('#note-body').native.send_keys('/l')
- end
-
- wait_for_requests
-
- expect(page).to have_selector('.atwho-container')
+ fill_in 'Comment', with: '/l'
- page.within '.atwho-container #at-view-commands' do
- expect(find('li', match: :first)).to have_content('/label')
- end
+ expect(find_highlighted_autocomplete_item).to have_content('/label')
end
end
@@ -110,4 +102,10 @@ RSpec.describe "User comments on issue", :js do
end
end
end
+
+ private
+
+ def find_highlighted_autocomplete_item
+ find('.atwho-view li.cur', visible: true)
+ end
end
diff --git a/spec/features/issues/user_edits_issue_spec.rb b/spec/features/issues/user_edits_issue_spec.rb
index 9d4a6cdb522..b8e35c9afa3 100644
--- a/spec/features/issues/user_edits_issue_spec.rb
+++ b/spec/features/issues/user_edits_issue_spec.rb
@@ -142,10 +142,8 @@ RSpec.describe "Issues > User edits issue", :js do
it 'can remove label without removing label added via quick action', :aggregate_failures do
# Add `syzygy` label with a quick action
- note = find('#note-body')
- page.within '.timeline-content-form' do
- note.native.send_keys('/label ~syzygy')
- end
+ fill_in 'Comment', with: '/label ~syzygy'
+
click_button 'Comment'
wait_for_requests
diff --git a/spec/features/merge_request/user_posts_notes_spec.rb b/spec/features/merge_request/user_posts_notes_spec.rb
index 3099a893dc2..b6ec5b72d28 100644
--- a/spec/features/merge_request/user_posts_notes_spec.rb
+++ b/spec/features/merge_request/user_posts_notes_spec.rb
@@ -182,9 +182,9 @@ RSpec.describe 'Merge request > User posts notes', :js do
find('.js-note-edit').click
page.within('.current-note-edit-form') do
- expect(find('#note_note').value).to include('This is the new content')
+ expect(find_field('note[note]').value).to include('This is the new content')
first('.js-md').click
- expect(find('#note_note').value).to include('This is the new content****')
+ expect(find_field('note[note]').value).to include('This is the new content****')
end
end
diff --git a/spec/features/merge_request/user_sees_notes_from_forked_project_spec.rb b/spec/features/merge_request/user_sees_notes_from_forked_project_spec.rb
index ea46ae06329..b8b7fc2009f 100644
--- a/spec/features/merge_request/user_sees_notes_from_forked_project_spec.rb
+++ b/spec/features/merge_request/user_sees_notes_from_forked_project_spec.rb
@@ -28,8 +28,8 @@ RSpec.describe 'Merge request > User sees notes from forked project', :js do
page.within('.discussion-notes') do
find_field('Reply…').click
- scroll_to(page.find('#note_note', visible: false))
- find('#note_note').send_keys('A reply comment')
+ scroll_to(find_field('note[note]', visible: false))
+ fill_in 'note[note]', with: 'A reply comment'
find('.js-comment-button').click
end
diff --git a/spec/features/participants_autocomplete_spec.rb b/spec/features/participants_autocomplete_spec.rb
index b22778012a8..2781cfffbaf 100644
--- a/spec/features/participants_autocomplete_spec.rb
+++ b/spec/features/participants_autocomplete_spec.rb
@@ -3,9 +3,9 @@
require 'spec_helper'
RSpec.describe 'Member autocomplete', :js do
- let(:project) { create(:project, :public) }
- let(:user) { create(:user) }
- let(:author) { create(:user) }
+ let_it_be(:project) { create(:project, :public, :repository) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:author) { create(:user) }
let(:note) { create(:note, noteable: noteable, project: noteable.project) }
before do
@@ -15,20 +15,16 @@ RSpec.describe 'Member autocomplete', :js do
shared_examples "open suggestions when typing @" do |resource_name|
before do
- page.within('.new-note') do
- if resource_name == 'commit'
- find('#note_note').send_keys('@')
- else
- find('#note-body').send_keys('@')
- end
+ if resource_name == 'commit'
+ fill_in 'note[note]', with: '@'
+ else
+ fill_in 'Comment', with: '@'
end
end
it 'suggests noteable author and note author' do
- page.within('.atwho-view', visible: true) do
- expect(page).to have_content(author.username)
- expect(page).to have_content(note.author.username)
- end
+ expect(find_autocomplete_menu).to have_text(author.username)
+ expect(find_autocomplete_menu).to have_text(note.author.username)
end
end
@@ -51,22 +47,17 @@ RSpec.describe 'Member autocomplete', :js do
stub_feature_flags(tribute_autocomplete: true)
visit project_issue_path(project, noteable)
- page.within('.new-note') do
- find('#note-body').send_keys('@')
- end
+ fill_in 'Comment', with: '@'
end
it 'suggests noteable author and note author' do
- page.within('.tribute-container', visible: true) do
- expect(page).to have_content(author.username)
- expect(page).to have_content(note.author.username)
- end
+ expect(find_tribute_autocomplete_menu).to have_content(author.username)
+ expect(find_tribute_autocomplete_menu).to have_content(note.author.username)
end
end
end
context 'adding a new note on a Merge Request' do
- let(:project) { create(:project, :public, :repository) }
let(:noteable) do
create(:merge_request, source_project: project,
target_project: project, author: author)
@@ -80,7 +71,6 @@ RSpec.describe 'Member autocomplete', :js do
end
context 'adding a new note on a Commit' do
- let(:project) { create(:project, :public, :repository) }
let(:noteable) { project.commit }
let(:note) { create(:note_on_commit, project: project, commit_id: project.commit.id) }
@@ -94,4 +84,14 @@ RSpec.describe 'Member autocomplete', :js do
include_examples "open suggestions when typing @", 'commit'
end
+
+ private
+
+ def find_autocomplete_menu
+ find('.atwho-view ul', visible: true)
+ end
+
+ def find_tribute_autocomplete_menu
+ find('.tribute-container ul', visible: true)
+ end
end
diff --git a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
index 55b9f38d8e7..b0ccb5fca94 100644
--- a/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
+++ b/spec/features/projects/files/gitlab_ci_yml_dropdown_spec.rb
@@ -5,10 +5,14 @@ require 'spec_helper'
RSpec.describe 'Projects > Files > User wants to add a .gitlab-ci.yml file', :js do
include Spec::Support::Helpers::Features::EditorLiteSpecHelpers
+ let(:params) { {} }
+ let(:filename) { '.gitlab-ci.yml' }
+
+ let_it_be(:project) { create(:project, :repository) }
+
before do
- project = create(:project, :repository)
sign_in project.owner
- visit project_new_blob_path(project, 'master', file_name: '.gitlab-ci.yml')
+ visit project_new_blob_path(project, 'master', file_name: filename, **params)
end
it 'user can pick a template from the dropdown' do
@@ -29,4 +33,38 @@ RSpec.describe 'Projects > Files > User wants to add a .gitlab-ci.yml file', :js
expect(editor_get_value).to have_content('This file is a template, and might need editing before it works on your project')
expect(editor_get_value).to have_content('jekyll build -d test')
end
+
+ context 'when template param is provided' do
+ let(:params) { { template: 'Jekyll' } }
+
+ it 'uses the given template' do
+ wait_for_requests
+
+ expect(page).to have_css('.gitlab-ci-yml-selector .dropdown-toggle-text', text: 'Apply a template')
+ expect(editor_get_value).to have_content('This file is a template, and might need editing before it works on your project')
+ expect(editor_get_value).to have_content('jekyll build -d test')
+ end
+ end
+
+ context 'when provided template param is not a valid template name' do
+ let(:params) { { template: 'non-existing-template' } }
+
+ it 'leaves the editor empty' do
+ wait_for_requests
+
+ expect(page).to have_css('.gitlab-ci-yml-selector .dropdown-toggle-text', text: 'Apply a template')
+ expect(editor_get_value).to have_content('')
+ end
+ end
+
+ context 'when template is not available for the given file' do
+ let(:filename) { 'Dockerfile' }
+ let(:params) { { template: 'Jekyll' } }
+
+ it 'leaves the editor empty' do
+ wait_for_requests
+
+ expect(editor_get_value).to have_content('')
+ end
+ end
end
diff --git a/spec/features/projects/jobs/user_browses_jobs_spec.rb b/spec/features/projects/jobs/user_browses_jobs_spec.rb
index 5abebf2320e..345bceeed31 100644
--- a/spec/features/projects/jobs/user_browses_jobs_spec.rb
+++ b/spec/features/projects/jobs/user_browses_jobs_spec.rb
@@ -24,14 +24,6 @@ RSpec.describe 'User browses jobs' do
end
end
- it 'shows the "CI Lint" button' do
- page.within('.nav-controls') do
- ci_lint_tool_link = page.find_link('CI Lint')
-
- expect(ci_lint_tool_link[:href]).to end_with(project_ci_lint_path(project))
- end
- end
-
context 'with a failed job' do
let!(:build) { create(:ci_build, :coverage, :failed, pipeline: pipeline) }
diff --git a/spec/features/projects/snippets/user_comments_on_snippet_spec.rb b/spec/features/projects/snippets/user_comments_on_snippet_spec.rb
index b37d40c0eed..3ccb73c88ef 100644
--- a/spec/features/projects/snippets/user_comments_on_snippet_spec.rb
+++ b/spec/features/projects/snippets/user_comments_on_snippet_spec.rb
@@ -29,7 +29,6 @@ RSpec.describe 'Projects > Snippets > User comments on a snippet', :js do
end
it 'has autocomplete' do
- find('#note_note').native.send_keys('')
fill_in 'note[note]', with: '@'
expect(page).to have_selector('.atwho-view')
diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb
index ce9a2d1461e..47dad9bd88e 100644
--- a/spec/features/snippets/notes_on_personal_snippets_spec.rb
+++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb
@@ -108,9 +108,6 @@ RSpec.describe 'Comments on personal snippets', :js do
end
it 'does not have autocomplete' do
- wait_for_requests
-
- find('#note_note').native.send_keys('')
fill_in 'note[note]', with: '@'
wait_for_requests
diff --git a/spec/finders/notes_finder_spec.rb b/spec/finders/notes_finder_spec.rb
index 868b126dc28..11de19cfdbc 100644
--- a/spec/finders/notes_finder_spec.rb
+++ b/spec/finders/notes_finder_spec.rb
@@ -213,6 +213,24 @@ RSpec.describe NotesFinder do
expect { described_class.new(user, params).execute }.to raise_error(RuntimeError)
end
end
+
+ describe 'sorting' do
+ it 'allows sorting' do
+ params = { project: project, sort: 'id_desc' }
+
+ expect(Note).to receive(:order_id_desc).once
+
+ described_class.new(user, params).execute
+ end
+
+ it 'defaults to sort by .fresh' do
+ params = { project: project }
+
+ expect(Note).to receive(:fresh).once
+
+ described_class.new(user, params).execute
+ end
+ end
end
describe '.search' do
diff --git a/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js b/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js
index bee628c3a56..0934dde8230 100644
--- a/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js
+++ b/spec/frontend/pages/projects/shared/permissions/components/settings_panel_spec.js
@@ -228,7 +228,7 @@ describe('Settings Panel', () => {
});
});
- describe('Pipelines', () => {
+ describe('CI/CD', () => {
it('should enable the builds access level input when the repository is enabled', () => {
wrapper = mountComponent({
currentSettings: { repositoryAccessLevel: featureAccessLevel.EVERYONE },
diff --git a/spec/frontend/vue_shared/components/lib/utils/props_utils_spec.js b/spec/frontend/vue_shared/components/lib/utils/props_utils_spec.js
new file mode 100644
index 00000000000..f1c9fbb00c9
--- /dev/null
+++ b/spec/frontend/vue_shared/components/lib/utils/props_utils_spec.js
@@ -0,0 +1,91 @@
+import { propsUnion } from '~/vue_shared/components/lib/utils/props_utils';
+
+describe('propsUnion', () => {
+ const stringRequired = {
+ type: String,
+ required: true,
+ };
+
+ const stringOptional = {
+ type: String,
+ required: false,
+ };
+
+ const numberOptional = {
+ type: Number,
+ required: false,
+ };
+
+ const booleanRequired = {
+ type: Boolean,
+ required: true,
+ };
+
+ const FooComponent = {
+ props: { foo: stringRequired },
+ };
+
+ const BarComponent = {
+ props: { bar: numberOptional },
+ };
+
+ const FooBarComponent = {
+ props: {
+ foo: stringRequired,
+ bar: numberOptional,
+ },
+ };
+
+ const FooOptionalComponent = {
+ props: {
+ foo: stringOptional,
+ },
+ };
+
+ const QuxComponent = {
+ props: {
+ foo: booleanRequired,
+ qux: stringRequired,
+ },
+ };
+
+ it('returns an empty object given no components', () => {
+ expect(propsUnion([])).toEqual({});
+ });
+
+ it('merges non-overlapping props', () => {
+ expect(propsUnion([FooComponent, BarComponent])).toEqual({
+ ...FooComponent.props,
+ ...BarComponent.props,
+ });
+ });
+
+ it('merges overlapping props', () => {
+ expect(propsUnion([FooComponent, BarComponent, FooBarComponent])).toEqual({
+ ...FooComponent.props,
+ ...BarComponent.props,
+ ...FooBarComponent.props,
+ });
+ });
+
+ it.each`
+ components
+ ${[FooComponent, FooOptionalComponent]}
+ ${[FooOptionalComponent, FooComponent]}
+ `('prefers required props over non-required props', ({ components }) => {
+ expect(propsUnion(components)).toEqual(FooComponent.props);
+ });
+
+ it('throws if given props with conflicting types', () => {
+ expect(() => propsUnion([FooComponent, QuxComponent])).toThrow(/incompatible prop types/);
+ });
+
+ it.each`
+ components
+ ${[{ props: ['foo', 'bar'] }]}
+ ${[{ props: { foo: String, bar: Number } }]}
+ ${[{ props: { foo: {}, bar: {} } }]}
+ `('throw if given a non-verbose props object', ({ components }) => {
+ expect(() => propsUnion(components)).toThrow(/expected verbose prop/);
+ });
+});
diff --git a/spec/lib/bulk_imports/common/transformers/user_reference_transformer_spec.rb b/spec/lib/bulk_imports/common/transformers/user_reference_transformer_spec.rb
index ff11a10bfe9..e86a584d38a 100644
--- a/spec/lib/bulk_imports/common/transformers/user_reference_transformer_spec.rb
+++ b/spec/lib/bulk_imports/common/transformers/user_reference_transformer_spec.rb
@@ -8,7 +8,8 @@ RSpec.describe BulkImports::Common::Transformers::UserReferenceTransformer do
let_it_be(:group) { create(:group) }
let_it_be(:bulk_import) { create(:bulk_import) }
let_it_be(:entity) { create(:bulk_import_entity, bulk_import: bulk_import, group: group) }
- let_it_be(:context) { BulkImports::Pipeline::Context.new(entity) }
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
let(:hash) do
{
diff --git a/spec/lib/bulk_imports/groups/extractors/subgroups_extractor_spec.rb b/spec/lib/bulk_imports/groups/extractors/subgroups_extractor_spec.rb
index 627247c04ab..ac8786440e9 100644
--- a/spec/lib/bulk_imports/groups/extractors/subgroups_extractor_spec.rb
+++ b/spec/lib/bulk_imports/groups/extractors/subgroups_extractor_spec.rb
@@ -8,8 +8,9 @@ RSpec.describe BulkImports::Groups::Extractors::SubgroupsExtractor do
bulk_import = create(:bulk_import)
create(:bulk_import_configuration, bulk_import: bulk_import)
entity = create(:bulk_import_entity, bulk_import: bulk_import)
+ tracker = create(:bulk_import_tracker, entity: entity)
response = [{ 'test' => 'group' }]
- context = BulkImports::Pipeline::Context.new(entity)
+ context = BulkImports::Pipeline::Context.new(tracker)
allow_next_instance_of(BulkImports::Clients::Http) do |client|
allow(client).to receive(:each_page).and_return(response)
diff --git a/spec/lib/bulk_imports/groups/graphql/get_group_query_spec.rb b/spec/lib/bulk_imports/groups/graphql/get_group_query_spec.rb
index ef46da7062b..b0f8f74783b 100644
--- a/spec/lib/bulk_imports/groups/graphql/get_group_query_spec.rb
+++ b/spec/lib/bulk_imports/groups/graphql/get_group_query_spec.rb
@@ -4,10 +4,10 @@ require 'spec_helper'
RSpec.describe BulkImports::Groups::Graphql::GetGroupQuery do
describe '#variables' do
- let(:entity) { double(source_full_path: 'test', bulk_import: nil) }
- let(:context) { BulkImports::Pipeline::Context.new(entity) }
-
it 'returns query variables based on entity information' do
+ entity = double(source_full_path: 'test', bulk_import: nil)
+ tracker = double(entity: entity)
+ context = BulkImports::Pipeline::Context.new(tracker)
expected = { full_path: entity.source_full_path }
expect(described_class.variables(context)).to eq(expected)
diff --git a/spec/lib/bulk_imports/groups/graphql/get_labels_query_spec.rb b/spec/lib/bulk_imports/groups/graphql/get_labels_query_spec.rb
index 85f82be7d18..61db644a372 100644
--- a/spec/lib/bulk_imports/groups/graphql/get_labels_query_spec.rb
+++ b/spec/lib/bulk_imports/groups/graphql/get_labels_query_spec.rb
@@ -4,8 +4,8 @@ require 'spec_helper'
RSpec.describe BulkImports::Groups::Graphql::GetLabelsQuery do
it 'has a valid query' do
- entity = create(:bulk_import_entity)
- context = BulkImports::Pipeline::Context.new(entity)
+ tracker = create(:bulk_import_tracker)
+ context = BulkImports::Pipeline::Context.new(tracker)
query = GraphQL::Query.new(
GitlabSchema,
diff --git a/spec/lib/bulk_imports/groups/graphql/get_members_query_spec.rb b/spec/lib/bulk_imports/groups/graphql/get_members_query_spec.rb
index 5d05f5a2d30..d0c4bb817b2 100644
--- a/spec/lib/bulk_imports/groups/graphql/get_members_query_spec.rb
+++ b/spec/lib/bulk_imports/groups/graphql/get_members_query_spec.rb
@@ -4,8 +4,8 @@ require 'spec_helper'
RSpec.describe BulkImports::Groups::Graphql::GetMembersQuery do
it 'has a valid query' do
- entity = create(:bulk_import_entity)
- context = BulkImports::Pipeline::Context.new(entity)
+ tracker = create(:bulk_import_tracker)
+ context = BulkImports::Pipeline::Context.new(tracker)
query = GraphQL::Query.new(
GitlabSchema,
diff --git a/spec/lib/bulk_imports/groups/graphql/get_milestones_query_spec.rb b/spec/lib/bulk_imports/groups/graphql/get_milestones_query_spec.rb
index a38505fbf85..7a0f964c5f3 100644
--- a/spec/lib/bulk_imports/groups/graphql/get_milestones_query_spec.rb
+++ b/spec/lib/bulk_imports/groups/graphql/get_milestones_query_spec.rb
@@ -4,8 +4,8 @@ require 'spec_helper'
RSpec.describe BulkImports::Groups::Graphql::GetMilestonesQuery do
it 'has a valid query' do
- entity = create(:bulk_import_entity)
- context = BulkImports::Pipeline::Context.new(entity)
+ tracker = create(:bulk_import_tracker)
+ context = BulkImports::Pipeline::Context.new(tracker)
query = GraphQL::Query.new(
GitlabSchema,
diff --git a/spec/lib/bulk_imports/groups/loaders/group_loader_spec.rb b/spec/lib/bulk_imports/groups/loaders/group_loader_spec.rb
index 183292722d2..533955b057c 100644
--- a/spec/lib/bulk_imports/groups/loaders/group_loader_spec.rb
+++ b/spec/lib/bulk_imports/groups/loaders/group_loader_spec.rb
@@ -4,12 +4,13 @@ require 'spec_helper'
RSpec.describe BulkImports::Groups::Loaders::GroupLoader do
describe '#load' do
- let(:user) { create(:user) }
- let(:data) { { foo: :bar } }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:bulk_import) { create(:bulk_import, user: user) }
+ let_it_be(:entity) { create(:bulk_import_entity, bulk_import: bulk_import) }
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
let(:service_double) { instance_double(::Groups::CreateService) }
- let(:bulk_import) { create(:bulk_import, user: user) }
- let(:entity) { create(:bulk_import_entity, bulk_import: bulk_import) }
- let(:context) { BulkImports::Pipeline::Context.new(entity) }
+ let(:data) { { foo: :bar } }
subject { described_class.new }
diff --git a/spec/lib/bulk_imports/groups/pipelines/group_pipeline_spec.rb b/spec/lib/bulk_imports/groups/pipelines/group_pipeline_spec.rb
index 61950cdd9b0..39e782dc093 100644
--- a/spec/lib/bulk_imports/groups/pipelines/group_pipeline_spec.rb
+++ b/spec/lib/bulk_imports/groups/pipelines/group_pipeline_spec.rb
@@ -4,10 +4,11 @@ require 'spec_helper'
RSpec.describe BulkImports::Groups::Pipelines::GroupPipeline do
describe '#run' do
- let(:user) { create(:user) }
- let(:parent) { create(:group) }
- let(:bulk_import) { create(:bulk_import, user: user) }
- let(:entity) do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:parent) { create(:group) }
+ let_it_be(:bulk_import) { create(:bulk_import, user: user) }
+
+ let_it_be(:entity) do
create(
:bulk_import_entity,
bulk_import: bulk_import,
@@ -17,7 +18,8 @@ RSpec.describe BulkImports::Groups::Pipelines::GroupPipeline do
)
end
- let(:context) { BulkImports::Pipeline::Context.new(entity) }
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
let(:group_data) do
{
@@ -37,7 +39,7 @@ RSpec.describe BulkImports::Groups::Pipelines::GroupPipeline do
before do
allow_next_instance_of(BulkImports::Common::Extractors::GraphqlExtractor) do |extractor|
- allow(extractor).to receive(:extract).and_return([group_data])
+ allow(extractor).to receive(:extract).and_return(BulkImports::Pipeline::ExtractedData.new(data: group_data))
end
parent.add_owner(user)
diff --git a/spec/lib/bulk_imports/groups/pipelines/labels_pipeline_spec.rb b/spec/lib/bulk_imports/groups/pipelines/labels_pipeline_spec.rb
index 3327a30f1d5..80ad5b69a61 100644
--- a/spec/lib/bulk_imports/groups/pipelines/labels_pipeline_spec.rb
+++ b/spec/lib/bulk_imports/groups/pipelines/labels_pipeline_spec.rb
@@ -3,11 +3,12 @@
require 'spec_helper'
RSpec.describe BulkImports::Groups::Pipelines::LabelsPipeline do
- let(:user) { create(:user) }
- let(:group) { create(:group) }
- let(:cursor) { 'cursor' }
- let(:timestamp) { Time.new(2020, 01, 01).utc }
- let(:entity) do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:cursor) { 'cursor' }
+ let_it_be(:timestamp) { Time.new(2020, 01, 01).utc }
+
+ let_it_be(:entity) do
create(
:bulk_import_entity,
source_full_path: 'source/full/path',
@@ -17,7 +18,8 @@ RSpec.describe BulkImports::Groups::Pipelines::LabelsPipeline do
)
end
- let(:context) { BulkImports::Pipeline::Context.new(entity) }
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
subject { described_class.new(context) }
@@ -72,8 +74,6 @@ RSpec.describe BulkImports::Groups::Pipelines::LabelsPipeline do
subject.after_run(data)
- tracker = entity.trackers.find_by(relation: :labels)
-
expect(tracker.has_next_page).to eq(true)
expect(tracker.next_page).to eq(cursor)
end
@@ -87,8 +87,6 @@ RSpec.describe BulkImports::Groups::Pipelines::LabelsPipeline do
subject.after_run(data)
- tracker = entity.trackers.find_by(relation: :labels)
-
expect(tracker.has_next_page).to eq(false)
expect(tracker.next_page).to be_nil
end
diff --git a/spec/lib/bulk_imports/groups/pipelines/members_pipeline_spec.rb b/spec/lib/bulk_imports/groups/pipelines/members_pipeline_spec.rb
index 74d3e09d263..5c82a028751 100644
--- a/spec/lib/bulk_imports/groups/pipelines/members_pipeline_spec.rb
+++ b/spec/lib/bulk_imports/groups/pipelines/members_pipeline_spec.rb
@@ -11,7 +11,8 @@ RSpec.describe BulkImports::Groups::Pipelines::MembersPipeline do
let_it_be(:cursor) { 'cursor' }
let_it_be(:bulk_import) { create(:bulk_import, user: user) }
let_it_be(:entity) { create(:bulk_import_entity, bulk_import: bulk_import, group: group) }
- let_it_be(:context) { BulkImports::Pipeline::Context.new(entity) }
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
subject { described_class.new(context) }
diff --git a/spec/lib/bulk_imports/groups/pipelines/milestones_pipeline_spec.rb b/spec/lib/bulk_imports/groups/pipelines/milestones_pipeline_spec.rb
index f0c34c65257..15a64a70ff3 100644
--- a/spec/lib/bulk_imports/groups/pipelines/milestones_pipeline_spec.rb
+++ b/spec/lib/bulk_imports/groups/pipelines/milestones_pipeline_spec.rb
@@ -9,7 +9,7 @@ RSpec.describe BulkImports::Groups::Pipelines::MilestonesPipeline do
let_it_be(:timestamp) { Time.new(2020, 01, 01).utc }
let_it_be(:bulk_import) { create(:bulk_import, user: user) }
- let(:entity) do
+ let_it_be(:entity) do
create(
:bulk_import_entity,
bulk_import: bulk_import,
@@ -20,7 +20,8 @@ RSpec.describe BulkImports::Groups::Pipelines::MilestonesPipeline do
)
end
- let(:context) { BulkImports::Pipeline::Context.new(entity) }
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
subject { described_class.new(context) }
@@ -84,8 +85,6 @@ RSpec.describe BulkImports::Groups::Pipelines::MilestonesPipeline do
subject.after_run(data)
- tracker = entity.trackers.find_by(relation: :milestones)
-
expect(tracker.has_next_page).to eq(true)
expect(tracker.next_page).to eq(cursor)
end
@@ -99,8 +98,6 @@ RSpec.describe BulkImports::Groups::Pipelines::MilestonesPipeline do
subject.after_run(data)
- tracker = entity.trackers.find_by(relation: :milestones)
-
expect(tracker.has_next_page).to eq(false)
expect(tracker.next_page).to be_nil
end
diff --git a/spec/lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline_spec.rb b/spec/lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline_spec.rb
index 2a99646bb4a..fd7265aea34 100644
--- a/spec/lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline_spec.rb
+++ b/spec/lib/bulk_imports/groups/pipelines/subgroup_entities_pipeline_spec.rb
@@ -6,19 +6,13 @@ RSpec.describe BulkImports::Groups::Pipelines::SubgroupEntitiesPipeline do
let_it_be(:user) { create(:user) }
let_it_be(:group) { create(:group, path: 'group') }
let_it_be(:parent) { create(:group, name: 'imported-group', path: 'imported-group') }
- let(:context) { BulkImports::Pipeline::Context.new(parent_entity) }
+ let_it_be(:parent_entity) { create(:bulk_import_entity, destination_namespace: parent.full_path, group: parent) }
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: parent_entity) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
subject { described_class.new(context) }
describe '#run' do
- let!(:parent_entity) do
- create(
- :bulk_import_entity,
- destination_namespace: parent.full_path,
- group: parent
- )
- end
-
let(:subgroup_data) do
[
{
diff --git a/spec/lib/bulk_imports/groups/transformers/group_attributes_transformer_spec.rb b/spec/lib/bulk_imports/groups/transformers/group_attributes_transformer_spec.rb
index b3fe8a2ba25..75d8c15088a 100644
--- a/spec/lib/bulk_imports/groups/transformers/group_attributes_transformer_spec.rb
+++ b/spec/lib/bulk_imports/groups/transformers/group_attributes_transformer_spec.rb
@@ -4,11 +4,12 @@ require 'spec_helper'
RSpec.describe BulkImports::Groups::Transformers::GroupAttributesTransformer do
describe '#transform' do
- let(:user) { create(:user) }
- let(:parent) { create(:group) }
- let(:group) { create(:group, name: 'My Source Group', parent: parent) }
- let(:bulk_import) { create(:bulk_import, user: user) }
- let(:entity) do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:parent) { create(:group) }
+ let_it_be(:group) { create(:group, name: 'My Source Group', parent: parent) }
+ let_it_be(:bulk_import) { create(:bulk_import, user: user) }
+
+ let_it_be(:entity) do
create(
:bulk_import_entity,
bulk_import: bulk_import,
@@ -18,7 +19,8 @@ RSpec.describe BulkImports::Groups::Transformers::GroupAttributesTransformer do
)
end
- let(:context) { BulkImports::Pipeline::Context.new(entity) }
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
let(:data) do
{
@@ -82,14 +84,7 @@ RSpec.describe BulkImports::Groups::Transformers::GroupAttributesTransformer do
context 'when destination namespace is empty' do
it 'does not set parent id' do
- entity = create(
- :bulk_import_entity,
- bulk_import: bulk_import,
- source_full_path: 'source/full/path',
- destination_name: group.name,
- destination_namespace: ''
- )
- context = BulkImports::Pipeline::Context.new(entity)
+ entity.update!(destination_namespace: '')
transformed_data = subject.transform(context, data)
diff --git a/spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb b/spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb
index f66c67fc6a2..f3905a4b6e4 100644
--- a/spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb
+++ b/spec/lib/bulk_imports/groups/transformers/member_attributes_transformer_spec.rb
@@ -8,7 +8,8 @@ RSpec.describe BulkImports::Groups::Transformers::MemberAttributesTransformer do
let_it_be(:group) { create(:group) }
let_it_be(:bulk_import) { create(:bulk_import, user: user) }
let_it_be(:entity) { create(:bulk_import_entity, bulk_import: bulk_import, group: group) }
- let_it_be(:context) { BulkImports::Pipeline::Context.new(entity) }
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
it 'returns nil when receives no data' do
expect(subject.transform(context, nil)).to eq(nil)
diff --git a/spec/lib/bulk_imports/importers/group_importer_spec.rb b/spec/lib/bulk_imports/importers/group_importer_spec.rb
index 5d501b49e41..9579ee53251 100644
--- a/spec/lib/bulk_imports/importers/group_importer_spec.rb
+++ b/spec/lib/bulk_imports/importers/group_importer_spec.rb
@@ -3,18 +3,18 @@
require 'spec_helper'
RSpec.describe BulkImports::Importers::GroupImporter do
- let(:user) { create(:user) }
- let(:group) { create(:group) }
- let(:bulk_import) { create(:bulk_import) }
- let(:bulk_import_entity) { create(:bulk_import_entity, :started, bulk_import: bulk_import, group: group) }
- let(:bulk_import_configuration) { create(:bulk_import_configuration, bulk_import: bulk_import) }
- let(:context) { BulkImports::Pipeline::Context.new(bulk_import_entity) }
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:bulk_import) { create(:bulk_import) }
+ let_it_be(:entity) { create(:bulk_import_entity, :started, group: group) }
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity, pipeline_name: described_class.name) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) }
before do
allow(BulkImports::Pipeline::Context).to receive(:new).and_return(context)
end
- subject { described_class.new(bulk_import_entity) }
+ subject { described_class.new(entity) }
describe '#execute' do
it 'starts the entity and run its pipelines' do
@@ -33,18 +33,18 @@ RSpec.describe BulkImports::Importers::GroupImporter do
subject.execute
- expect(bulk_import_entity.reload).to be_finished
+ expect(entity).to be_finished
end
context 'when failed' do
- let(:bulk_import_entity) { create(:bulk_import_entity, :failed, bulk_import: bulk_import, group: group) }
+ let(:entity) { create(:bulk_import_entity, :failed, bulk_import: bulk_import, group: group) }
it 'does not transition entity to finished state' do
- allow(bulk_import_entity).to receive(:start!)
+ allow(entity).to receive(:start!)
subject.execute
- expect(bulk_import_entity.reload).to be_failed
+ expect(entity.reload).to be_failed
end
end
end
diff --git a/spec/lib/bulk_imports/pipeline/context_spec.rb b/spec/lib/bulk_imports/pipeline/context_spec.rb
index c8c3fe3a861..5b7711ad5d7 100644
--- a/spec/lib/bulk_imports/pipeline/context_spec.rb
+++ b/spec/lib/bulk_imports/pipeline/context_spec.rb
@@ -3,29 +3,52 @@
require 'spec_helper'
RSpec.describe BulkImports::Pipeline::Context do
- let(:group) { instance_double(Group) }
- let(:user) { instance_double(User) }
- let(:bulk_import) { instance_double(BulkImport, user: user, configuration: :config) }
-
- let(:entity) do
- instance_double(
- BulkImports::Entity,
- bulk_import: bulk_import,
- group: group
+ let_it_be(:user) { create(:user) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:bulk_import) { create(:bulk_import, user: user) }
+
+ let_it_be(:entity) do
+ create(
+ :bulk_import_entity,
+ source_full_path: 'source/full/path',
+ destination_name: 'My Destination Group',
+ destination_namespace: group.full_path,
+ group: group,
+ bulk_import: bulk_import
+ )
+ end
+
+ let_it_be(:tracker) do
+ create(
+ :bulk_import_tracker,
+ entity: entity,
+ pipeline_name: described_class.name
)
end
- subject { described_class.new(entity) }
+ subject { described_class.new(tracker, extra: :data) }
+
+ describe '#entity' do
+ it { expect(subject.entity).to eq(entity) }
+ end
describe '#group' do
it { expect(subject.group).to eq(group) }
end
+ describe '#bulk_import' do
+ it { expect(subject.bulk_import).to eq(bulk_import) }
+ end
+
describe '#current_user' do
it { expect(subject.current_user).to eq(user) }
end
- describe '#current_user' do
+ describe '#configuration' do
it { expect(subject.configuration).to eq(bulk_import.configuration) }
end
+
+ describe '#extra' do
+ it { expect(subject.extra).to eq(extra: :data) }
+ end
end
diff --git a/spec/lib/bulk_imports/pipeline/runner_spec.rb b/spec/lib/bulk_imports/pipeline/runner_spec.rb
index 59f01c9caaa..29fd1ee3ffc 100644
--- a/spec/lib/bulk_imports/pipeline/runner_spec.rb
+++ b/spec/lib/bulk_imports/pipeline/runner_spec.rb
@@ -45,8 +45,9 @@ RSpec.describe BulkImports::Pipeline::Runner do
stub_const('BulkImports::MyPipeline', pipeline)
end
- let_it_be_with_refind(:entity) { create(:bulk_import_entity) }
- let(:context) { BulkImports::Pipeline::Context.new(entity, extra: :data) }
+ let_it_be_with_reload(:entity) { create(:bulk_import_entity) }
+ let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) }
+ let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker, extra: :data) }
subject { BulkImports::MyPipeline.new(context) }
@@ -170,12 +171,7 @@ RSpec.describe BulkImports::Pipeline::Runner do
BulkImports::MyPipeline.abort_on_failure!
end
- it 'marks entity as failed' do
- expect { subject.run }
- .to change(entity, :status_name).to(:failed)
- end
-
- it 'logs warn message' do
+ it 'logs a warn message and marks entity as failed' do
expect_next_instance_of(Gitlab::Import::Logger) do |logger|
expect(logger).to receive(:warn)
.with(
@@ -188,6 +184,9 @@ RSpec.describe BulkImports::Pipeline::Runner do
end
subject.run
+
+ expect(entity.status_name).to eq(:failed)
+ expect(tracker.status_name).to eq(:failed)
end
end
@@ -206,11 +205,11 @@ RSpec.describe BulkImports::Pipeline::Runner do
entity.fail_op!
expect_next_instance_of(Gitlab::Import::Logger) do |logger|
- expect(logger).to receive(:info)
+ expect(logger).to receive(:warn)
.with(
log_params(
context,
- message: 'Skipping due to failed pipeline status',
+ message: 'Skipping pipeline due to failed entity',
pipeline_class: 'BulkImports::MyPipeline'
)
)
diff --git a/spec/lib/bulk_imports/pipeline_spec.rb b/spec/lib/bulk_imports/pipeline_spec.rb
index c882e3d26ea..dda2e41f06c 100644
--- a/spec/lib/bulk_imports/pipeline_spec.rb
+++ b/spec/lib/bulk_imports/pipeline_spec.rb
@@ -3,6 +3,8 @@
require 'spec_helper'
RSpec.describe BulkImports::Pipeline do
+ let(:context) { instance_double(BulkImports::Pipeline::Context, tracker: nil) }
+
before do
stub_const('BulkImports::Extractor', Class.new)
stub_const('BulkImports::Transformer', Class.new)
@@ -44,7 +46,7 @@ RSpec.describe BulkImports::Pipeline do
end
it 'returns itself when retrieving extractor & loader' do
- pipeline = BulkImports::AnotherPipeline.new(nil)
+ pipeline = BulkImports::AnotherPipeline.new(context)
expect(pipeline.send(:extractor)).to eq(pipeline)
expect(pipeline.send(:loader)).to eq(pipeline)
@@ -83,7 +85,7 @@ RSpec.describe BulkImports::Pipeline do
expect(BulkImports::Transformer).to receive(:new).with(foo: :bar)
expect(BulkImports::Loader).to receive(:new).with(foo: :bar)
- pipeline = BulkImports::MyPipeline.new(nil)
+ pipeline = BulkImports::MyPipeline.new(context)
pipeline.send(:extractor)
pipeline.send(:transformers)
@@ -109,7 +111,7 @@ RSpec.describe BulkImports::Pipeline do
expect(BulkImports::Transformer).to receive(:new).with(no_args)
expect(BulkImports::Loader).to receive(:new).with(no_args)
- pipeline = BulkImports::NoOptionsPipeline.new(nil)
+ pipeline = BulkImports::NoOptionsPipeline.new(context)
pipeline.send(:extractor)
pipeline.send(:transformers)
@@ -135,7 +137,7 @@ RSpec.describe BulkImports::Pipeline do
transformer = double
allow(BulkImports::Transformer).to receive(:new).and_return(transformer)
- pipeline = BulkImports::TransformersPipeline.new(nil)
+ pipeline = BulkImports::TransformersPipeline.new(context)
expect(pipeline.send(:transformers)).to eq([pipeline, transformer])
end
diff --git a/spec/lib/gitlab/ci/lint_spec.rb b/spec/lib/gitlab/ci/lint_spec.rb
index 67324c09d86..aaa3a7a8b9d 100644
--- a/spec/lib/gitlab/ci/lint_spec.rb
+++ b/spec/lib/gitlab/ci/lint_spec.rb
@@ -92,7 +92,7 @@ RSpec.describe Gitlab::Ci::Lint do
it 'sets merged_config' do
root_config = YAML.safe_load(content, [Symbol])
included_config = YAML.safe_load(included_content, [Symbol])
- expected_config = included_config.merge(root_config).except(:include)
+ expected_config = included_config.merge(root_config).except(:include).deep_stringify_keys
expect(subject.merged_yaml).to eq(expected_config.to_yaml)
end
diff --git a/spec/lib/gitlab/ci/yaml_processor/result_spec.rb b/spec/lib/gitlab/ci/yaml_processor/result_spec.rb
index 7e3cd7ec254..e345cd4de9b 100644
--- a/spec/lib/gitlab/ci/yaml_processor/result_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor/result_spec.rb
@@ -24,7 +24,7 @@ module Gitlab
let(:included_yml) do
YAML.dump(
- another_test: { stage: 'test', script: 'echo 2' }
+ { another_test: { stage: 'test', script: 'echo 2' } }.deep_stringify_keys
)
end
diff --git a/spec/lib/gitlab/data_builder/build_spec.rb b/spec/lib/gitlab/data_builder/build_spec.rb
index ab1728414bb..932238f281e 100644
--- a/spec/lib/gitlab/data_builder/build_spec.rb
+++ b/spec/lib/gitlab/data_builder/build_spec.rb
@@ -19,6 +19,9 @@ RSpec.describe Gitlab::DataBuilder::Build do
it { expect(data[:tag]).to eq(build.tag) }
it { expect(data[:build_id]).to eq(build.id) }
it { expect(data[:build_status]).to eq(build.status) }
+ it { expect(data[:build_created_at]).to eq(build.created_at) }
+ it { expect(data[:build_started_at]).to eq(build.started_at) }
+ it { expect(data[:build_finished_at]).to eq(build.finished_at) }
it { expect(data[:build_allow_failure]).to eq(false) }
it { expect(data[:build_failure_reason]).to eq(build.failure_reason) }
it { expect(data[:project_id]).to eq(build.project.id) }
diff --git a/spec/models/bulk_imports/entity_spec.rb b/spec/models/bulk_imports/entity_spec.rb
index 17ab4d5954c..652ea431696 100644
--- a/spec/models/bulk_imports/entity_spec.rb
+++ b/spec/models/bulk_imports/entity_spec.rb
@@ -125,68 +125,4 @@ RSpec.describe BulkImports::Entity, type: :model do
end
end
end
-
- describe "#update_tracker_for" do
- let(:entity) { create(:bulk_import_entity) }
-
- it "inserts new tracker when it does not exist" do
- expect do
- entity.update_tracker_for(relation: :relation, has_next_page: false)
- end.to change(BulkImports::Tracker, :count).by(1)
-
- tracker = entity.trackers.last
-
- expect(tracker.relation).to eq('relation')
- expect(tracker.has_next_page).to eq(false)
- expect(tracker.next_page).to eq(nil)
- end
-
- it "updates the tracker if it already exist" do
- create(
- :bulk_import_tracker,
- relation: :relation,
- has_next_page: false,
- entity: entity
- )
-
- expect do
- entity.update_tracker_for(relation: :relation, has_next_page: true, next_page: 'nextPage')
- end.not_to change(BulkImports::Tracker, :count)
-
- tracker = entity.trackers.last
-
- expect(tracker.relation).to eq('relation')
- expect(tracker.has_next_page).to eq(true)
- expect(tracker.next_page).to eq('nextPage')
- end
- end
-
- describe "#has_next_page?" do
- it "queries for the given relation if it has more pages to be fetched" do
- entity = create(:bulk_import_entity)
- create(
- :bulk_import_tracker,
- relation: :relation,
- has_next_page: false,
- entity: entity
- )
-
- expect(entity.has_next_page?(:relation)).to eq(false)
- end
- end
-
- describe "#next_page_for" do
- it "queries for the next page of the given relation" do
- entity = create(:bulk_import_entity)
- create(
- :bulk_import_tracker,
- relation: :relation,
- has_next_page: false,
- next_page: 'nextPage',
- entity: entity
- )
-
- expect(entity.next_page_for(:relation)).to eq('nextPage')
- end
- end
end
diff --git a/spec/models/concerns/sortable_spec.rb b/spec/models/concerns/sortable_spec.rb
index bbfdaeec64c..cfa00bab025 100644
--- a/spec/models/concerns/sortable_spec.rb
+++ b/spec/models/concerns/sortable_spec.rb
@@ -3,6 +3,31 @@
require 'spec_helper'
RSpec.describe Sortable do
+ describe 'scopes' do
+ describe 'secondary ordering by id' do
+ let(:sorted_relation) { Group.all.order_created_asc }
+
+ def arel_orders(relation)
+ relation.arel.orders
+ end
+
+ it 'allows secondary ordering by id ascending' do
+ orders = arel_orders(sorted_relation.with_order_id_asc)
+
+ expect(orders.map { |arel| arel.expr.name }).to eq(%w(created_at id))
+ expect(orders).to all(be_kind_of(Arel::Nodes::Ascending))
+ end
+
+ it 'allows secondary ordering by id descending' do
+ orders = arel_orders(sorted_relation.with_order_id_desc)
+
+ expect(orders.map { |arel| arel.expr.name }).to eq(%w(created_at id))
+ expect(orders.first).to be_kind_of(Arel::Nodes::Ascending)
+ expect(orders.last).to be_kind_of(Arel::Nodes::Descending)
+ end
+ end
+ end
+
describe '.order_by' do
let(:arel_table) { Group.arel_table }
let(:relation) { Group.all }
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index 590acfc0ac1..fec932ee339 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -20,6 +20,7 @@ RSpec.describe Note do
it { is_expected.to include_module(Participable) }
it { is_expected.to include_module(Mentionable) }
it { is_expected.to include_module(Awardable) }
+ it { is_expected.to include_module(Sortable) }
end
describe 'validation' do
@@ -856,6 +857,12 @@ RSpec.describe Note do
end
end
+ describe '.simple_sorts' do
+ it 'does not contain name sorts' do
+ expect(described_class.simple_sorts.grep(/name/)).to be_empty
+ end
+ end
+
describe '#for_project_snippet?' do
it 'returns true for a project snippet note' do
expect(build(:note_on_project_snippet).for_project_snippet?).to be true
@@ -1322,7 +1329,7 @@ RSpec.describe Note do
let_it_be(:note1) { create(:note, note: 'Test 345') }
let_it_be(:note2) { create(:note, note: 'Test 789') }
- describe '#for_note_or_capitalized_note' do
+ describe '.for_note_or_capitalized_note' do
it 'returns the expected matching note' do
notes = described_class.for_note_or_capitalized_note('Test 345')
@@ -1344,7 +1351,7 @@ RSpec.describe Note do
end
end
- describe '#like_note_or_capitalized_note' do
+ describe '.like_note_or_capitalized_note' do
it 'returns the expected matching note' do
notes = described_class.like_note_or_capitalized_note('Test 345')
@@ -1367,69 +1374,69 @@ RSpec.describe Note do
expect(notes.second.id).to eq(note2.id)
end
end
+ end
- describe '#noteable_assignee_or_author' do
- let(:user) { create(:user) }
- let(:noteable) { create(:issue) }
- let(:note) { create(:note, project: noteable.project, noteable: noteable) }
+ describe '#noteable_assignee_or_author?' do
+ let(:user) { create(:user) }
+ let(:noteable) { create(:issue) }
+ let(:note) { create(:note, project: noteable.project, noteable: noteable) }
- subject { note.noteable_assignee_or_author?(user) }
+ subject { note.noteable_assignee_or_author?(user) }
- shared_examples 'assignee check' do
- context 'when the provided user is one of the assignees' do
- before do
- note.noteable.update(assignees: [user, create(:user)])
- end
+ shared_examples 'assignee check' do
+ context 'when the provided user is one of the assignees' do
+ before do
+ note.noteable.update(assignees: [user, create(:user)])
+ end
- it 'returns true' do
- expect(subject).to be_truthy
- end
+ it 'returns true' do
+ expect(subject).to be_truthy
end
end
+ end
- shared_examples 'author check' do
- context 'when the provided user is the author' do
- before do
- note.noteable.update(author: user)
- end
-
- it 'returns true' do
- expect(subject).to be_truthy
- end
+ shared_examples 'author check' do
+ context 'when the provided user is the author' do
+ before do
+ note.noteable.update(author: user)
end
- context 'when the provided user is neither author nor assignee' do
- it 'returns true' do
- expect(subject).to be_falsey
- end
+ it 'returns true' do
+ expect(subject).to be_truthy
end
end
- context 'when user is nil' do
- let(:user) { nil }
-
- it 'returns false' do
+ context 'when the provided user is neither author nor assignee' do
+ it 'returns true' do
expect(subject).to be_falsey
end
end
+ end
+
+ context 'when user is nil' do
+ let(:user) { nil }
- context 'when noteable is an issue' do
- it_behaves_like 'author check'
- it_behaves_like 'assignee check'
+ it 'returns false' do
+ expect(subject).to be_falsey
end
+ end
- context 'when noteable is a merge request' do
- let(:noteable) { create(:merge_request) }
+ context 'when noteable is an issue' do
+ it_behaves_like 'author check'
+ it_behaves_like 'assignee check'
+ end
- it_behaves_like 'author check'
- it_behaves_like 'assignee check'
- end
+ context 'when noteable is a merge request' do
+ let(:noteable) { create(:merge_request) }
- context 'when noteable is a snippet' do
- let(:noteable) { create(:personal_snippet) }
+ it_behaves_like 'author check'
+ it_behaves_like 'assignee check'
+ end
- it_behaves_like 'author check'
- end
+ context 'when noteable is a snippet' do
+ let(:noteable) { create(:personal_snippet) }
+
+ it_behaves_like 'author check'
end
end
diff --git a/spec/requests/api/lint_spec.rb b/spec/requests/api/lint_spec.rb
index cf8cac773f5..f26236e0253 100644
--- a/spec/requests/api/lint_spec.rb
+++ b/spec/requests/api/lint_spec.rb
@@ -166,7 +166,7 @@ RSpec.describe API::Lint do
included_config = YAML.safe_load(included_content, [Symbol])
root_config = YAML.safe_load(yaml_content, [Symbol])
- expected_yaml = included_config.merge(root_config).except(:include).to_yaml
+ expected_yaml = included_config.merge(root_config).except(:include).deep_stringify_keys.to_yaml
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Hash
@@ -246,7 +246,7 @@ RSpec.describe API::Lint do
let(:dry_run) { false }
let(:included_content) do
- { another_test: { stage: 'test', script: 'echo 1' } }.to_yaml
+ { another_test: { stage: 'test', script: 'echo 1' } }.deep_stringify_keys.to_yaml
end
before do
@@ -299,7 +299,7 @@ RSpec.describe API::Lint do
end
let(:included_content) do
- { another_test: { stage: 'test', script: 'echo 1' } }.to_yaml
+ { another_test: { stage: 'test', script: 'echo 1' } }.deep_stringify_keys.to_yaml
end
before do
@@ -341,7 +341,7 @@ RSpec.describe API::Lint do
context 'with invalid .gitlab-ci.yml content' do
let(:yaml_content) do
- { image: 'ruby:2.7', services: ['postgres'] }.to_yaml
+ { image: 'ruby:2.7', services: ['postgres'] }.deep_stringify_keys.to_yaml
end
before do
@@ -385,7 +385,7 @@ RSpec.describe API::Lint do
included_config = YAML.safe_load(included_content, [Symbol])
root_config = YAML.safe_load(yaml_content, [Symbol])
- expected_yaml = included_config.merge(root_config).except(:include).to_yaml
+ expected_yaml = included_config.merge(root_config).except(:include).deep_stringify_keys.to_yaml
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to be_an Hash
@@ -539,7 +539,7 @@ RSpec.describe API::Lint do
context 'with invalid .gitlab-ci.yml content' do
let(:yaml_content) do
- { image: 'ruby:2.7', services: ['postgres'] }.to_yaml
+ { image: 'ruby:2.7', services: ['postgres'] }.deep_stringify_keys.to_yaml
end
context 'when running as dry run' do
diff --git a/spec/support/shared_examples/models/wiki_shared_examples.rb b/spec/support/shared_examples/models/wiki_shared_examples.rb
index abc6e3ecce8..50d50bee727 100644
--- a/spec/support/shared_examples/models/wiki_shared_examples.rb
+++ b/spec/support/shared_examples/models/wiki_shared_examples.rb
@@ -481,28 +481,53 @@ RSpec.shared_examples 'wiki model' do
end
describe '#delete_page' do
- let(:page) { create(:wiki_page, wiki: wiki) }
+ shared_examples 'delete_page operations' do
+ let(:page) { create(:wiki_page, wiki: wiki) }
- it 'deletes the page' do
- subject.delete_page(page)
+ it 'deletes the page' do
+ subject.delete_page(page)
- expect(subject.list_pages.count).to eq(0)
- end
+ expect(subject.list_pages.count).to eq(0)
+ end
- it 'sets the correct commit email' do
- subject.delete_page(page)
+ it 'sets the correct commit email' do
+ subject.delete_page(page)
- expect(user.commit_email).not_to eq(user.email)
- expect(commit.author_email).to eq(user.commit_email)
- expect(commit.committer_email).to eq(user.commit_email)
+ expect(user.commit_email).not_to eq(user.email)
+ expect(commit.author_email).to eq(user.commit_email)
+ expect(commit.committer_email).to eq(user.commit_email)
+ end
+
+ it 'runs after_wiki_activity callbacks' do
+ page
+
+ expect(subject).to receive(:after_wiki_activity)
+
+ subject.delete_page(page)
+ end
end
- it 'runs after_wiki_activity callbacks' do
- page
+ it_behaves_like 'delete_page operations'
- expect(subject).to receive(:after_wiki_activity)
+ context 'when an error is raised' do
+ it 'logs the error and returns false' do
+ page = build(:wiki_page, wiki: wiki)
+ exception = Gitlab::Git::Index::IndexError.new('foo')
+
+ allow(subject.repository).to receive(:delete_file).and_raise(exception)
+
+ expect(Gitlab::ErrorTracking).to receive(:log_exception).with(exception, action: :deleted, wiki_id: wiki.id)
+
+ expect(subject.delete_page(page)).to be_falsey
+ end
+ end
+
+ context 'when feature flag :gitaly_replace_wiki_delete_page is disabled' do
+ before do
+ stub_feature_flags(gitaly_replace_wiki_delete_page: false)
+ end
- subject.delete_page(page)
+ it_behaves_like 'delete_page operations'
end
end