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>2022-01-14 00:14:07 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-01-14 00:14:07 +0300
commit3e64e1af8dfcad514151335813daa31601332676 (patch)
tree4cb9faef9035c8df6d702982047b2b8ad7da58f4
parentaa072fd68cfe366c0d5968c65e9b42aecb2a75b5 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/assets/javascripts/content_editor/constants.js7
-rw-r--r--app/assets/javascripts/content_editor/extensions/code.js13
-rw-r--r--app/assets/javascripts/content_editor/extensions/frontmatter.js11
-rw-r--r--app/assets/javascripts/content_editor/services/markdown_serializer.js2
-rw-r--r--app/assets/javascripts/labels/index.js2
-rw-r--r--app/assets/javascripts/projects/project_visibility.js21
-rw-r--r--app/assets/stylesheets/pages/labels.scss5
-rw-r--r--app/models/ci/secure_file.rb33
-rw-r--r--app/models/project.rb1
-rw-r--r--app/uploaders/ci/secure_file_uploader.rb46
-rw-r--r--app/views/shared/_label.html.haml32
-rw-r--r--config/gitlab.yml.example12
-rw-r--r--config/initializers/1_settings.rb8
-rw-r--r--config/object_store_settings.rb2
-rw-r--r--data/removals/14_0/remove_optimize_api.yml2
-rw-r--r--db/migrate/20211223125921_add_temp_index_to_members_state.rb16
-rw-r--r--db/migrate/20220110170953_create_ci_secure_files.rb19
-rw-r--r--db/schema_migrations/202112231259211
-rw-r--r--db/schema_migrations/202201101709531
-rw-r--r--db/structure.sql32
-rw-r--r--doc/administration/logs.md2
-rw-r--r--doc/administration/package_information/defaults.md4
-rw-r--r--doc/administration/sidekiq.md3
-rw-r--r--doc/administration/sidekiq_health_check.md2
-rw-r--r--doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md7
-rw-r--r--doc/api/members.md2
-rw-r--r--doc/ci/cloud_services/aws/index.md8
-rw-r--r--doc/ci/cloud_services/index.md14
-rw-r--r--doc/ci/runners/configure_runners.md3
-rw-r--r--doc/development/database_review.md2
-rw-r--r--doc/development/documentation/styleguide/word_list.md4
-rw-r--r--doc/development/event_store.md2
-rw-r--r--doc/development/feature_flags/controls.md2
-rw-r--r--doc/development/integrations/secure.md2
-rw-r--r--doc/install/aws/index.md2
-rw-r--r--doc/security/reset_user_password.md6
-rw-r--r--doc/subscriptions/self_managed/index.md8
-rw-r--r--doc/system_hooks/system_hooks.md2
-rw-r--r--doc/update/removals.md2
-rw-r--r--doc/user/admin_area/analytics/dev_ops_report.md2
-rw-r--r--doc/user/admin_area/img/license_upload_v13_12.pngbin39998 -> 0 bytes
-rw-r--r--doc/user/admin_area/license.md46
-rw-r--r--doc/user/admin_area/settings/third_party_offers.md2
-rw-r--r--doc/user/admin_area/settings/visibility_and_access_controls.md2
-rw-r--r--doc/user/application_security/sast/index.md32
-rw-r--r--doc/user/application_security/security_dashboard/index.md2
-rw-r--r--doc/user/clusters/agent/index.md4
-rw-r--r--doc/user/infrastructure/iac/index.md4
-rw-r--r--doc/user/packages/dependency_proxy/index.md4
-rw-r--r--doc/user/project/code_owners.md4
-rw-r--r--doc/user/project/integrations/discord_notifications.md2
-rw-r--r--doc/user/project/merge_requests/accessibility_testing.md2
-rw-r--r--doc/user/project/merge_requests/commit_templates.md2
-rw-r--r--doc/user/project/working_with_projects.md4
-rw-r--r--doc/user/search/index.md2
-rw-r--r--lib/banzai/filter/syntax_highlight_filter.rb4
-rw-r--r--lib/gitlab/database/gitlab_loose_foreign_keys.yml4
-rw-r--r--lib/gitlab/database/gitlab_schemas.yml1
-rw-r--r--locale/gitlab.pot3
-rw-r--r--spec/factories/ci/secure_files.rb10
-rw-r--r--spec/fixtures/ci_secure_files/upload-keystore.jksbin0 -> 2760 bytes
-rw-r--r--spec/frontend/content_editor/extensions/code_spec.js8
-rw-r--r--spec/frontend/content_editor/extensions/frontmatter_spec.js25
-rw-r--r--spec/frontend/content_editor/services/markdown_serializer_spec.js11
-rw-r--r--spec/lib/banzai/filter/syntax_highlight_filter_spec.rb8
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml1
-rw-r--r--spec/models/ci/secure_file_spec.rb55
-rw-r--r--spec/support/helpers/stub_object_storage.rb6
-rw-r--r--spec/uploaders/ci/secure_file_uploader_spec.rb72
69 files changed, 532 insertions, 133 deletions
diff --git a/app/assets/javascripts/content_editor/constants.js b/app/assets/javascripts/content_editor/constants.js
index 4af9dc8e405..5e56078df01 100644
--- a/app/assets/javascripts/content_editor/constants.js
+++ b/app/assets/javascripts/content_editor/constants.js
@@ -49,3 +49,10 @@ export const LOADING_ERROR_EVENT = 'loadingError';
export const PARSE_HTML_PRIORITY_LOWEST = 1;
export const PARSE_HTML_PRIORITY_DEFAULT = 50;
export const PARSE_HTML_PRIORITY_HIGHEST = 100;
+
+export const EXTENSION_PRIORITY_LOWER = 75;
+/**
+ * 100 is the default priority in Tiptap
+ * https://tiptap.dev/guide/custom-extensions/#priority
+ */
+export const EXTENSION_PRIORITY_DEFAULT = 100;
diff --git a/app/assets/javascripts/content_editor/extensions/code.js b/app/assets/javascripts/content_editor/extensions/code.js
index f93c22ad10e..53f6d9b995c 100644
--- a/app/assets/javascripts/content_editor/extensions/code.js
+++ b/app/assets/javascripts/content_editor/extensions/code.js
@@ -1 +1,12 @@
-export { Code as default } from '@tiptap/extension-code';
+import Code from '@tiptap/extension-code';
+import { EXTENSION_PRIORITY_LOWER } from '../constants';
+
+export default Code.extend({
+ excludes: null,
+ /**
+ * Reduce the rendering priority of the code mark to
+ * ensure the bold, italic, and strikethrough marks
+ * are rendered first.
+ */
+ priority: EXTENSION_PRIORITY_LOWER,
+});
diff --git a/app/assets/javascripts/content_editor/extensions/frontmatter.js b/app/assets/javascripts/content_editor/extensions/frontmatter.js
index c09c10bc524..9842027e192 100644
--- a/app/assets/javascripts/content_editor/extensions/frontmatter.js
+++ b/app/assets/javascripts/content_editor/extensions/frontmatter.js
@@ -14,9 +14,20 @@ export default CodeBlockHighlight.extend({
},
];
},
+ addCommands() {
+ return {
+ setFrontmatter: (attributes) => ({ commands }) => {
+ return commands.setNode(this.name, attributes);
+ },
+ toggleFrontmatter: (attributes) => ({ commands }) => {
+ return commands.toggleNode(this.name, 'paragraph', attributes);
+ },
+ };
+ },
addNodeView() {
return new VueNodeViewRenderer(FrontmatterWrapper);
},
+
addInputRules() {
return [];
},
diff --git a/app/assets/javascripts/content_editor/services/markdown_serializer.js b/app/assets/javascripts/content_editor/services/markdown_serializer.js
index 278ef326c7a..d54fb7cded2 100644
--- a/app/assets/javascripts/content_editor/services/markdown_serializer.js
+++ b/app/assets/javascripts/content_editor/services/markdown_serializer.js
@@ -65,8 +65,8 @@ import {
const defaultSerializerConfig = {
marks: {
[Bold.name]: defaultMarkdownSerializer.marks.strong,
- [Code.name]: defaultMarkdownSerializer.marks.code,
[Italic.name]: { open: '_', close: '_', mixable: true, expelEnclosingWhitespace: true },
+ [Code.name]: defaultMarkdownSerializer.marks.code,
[Subscript.name]: { open: '<sub>', close: '</sub>', mixable: true },
[Superscript.name]: { open: '<sup>', close: '</sup>', mixable: true },
[InlineDiff.name]: {
diff --git a/app/assets/javascripts/labels/index.js b/app/assets/javascripts/labels/index.js
index 22a9c0a89c0..e87ad8d9a06 100644
--- a/app/assets/javascripts/labels/index.js
+++ b/app/assets/javascripts/labels/index.js
@@ -26,7 +26,7 @@ export function initLabels() {
if ($('.prioritized-labels').length) {
new LabelManager(); // eslint-disable-line no-new
}
- $('.label-subscription').each((i, el) => {
+ $('.js-label-subscription').each((i, el) => {
const $el = $(el);
if ($el.find('.dropdown-group-label').length) {
diff --git a/app/assets/javascripts/projects/project_visibility.js b/app/assets/javascripts/projects/project_visibility.js
index 1b57a69d464..c962554c9f4 100644
--- a/app/assets/javascripts/projects/project_visibility.js
+++ b/app/assets/javascripts/projects/project_visibility.js
@@ -1,4 +1,6 @@
import $ from 'jquery';
+import { escape } from 'lodash';
+import { __, sprintf } from '~/locale';
import eventHub from '~/projects/new/event_hub';
// Values are from lib/gitlab/visibility_level.rb
@@ -25,10 +27,21 @@ function setVisibilityOptions({ name, visibility, showPath, editPath }) {
if (reason) {
const optionTitle = option.querySelector('.option-title');
const optionName = optionTitle ? optionTitle.innerText.toLowerCase() : '';
- reason.innerHTML = `This project cannot be ${optionName} because the visibility of
- <a href="${showPath}">${name}</a> is ${visibility}. To make this project
- ${optionName}, you must first <a href="${editPath}">change the visibility</a>
- of the parent group.`;
+ reason.innerHTML = sprintf(
+ __(
+ 'This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group.',
+ ),
+ {
+ visibilityLevel: optionName,
+ name: escape(name),
+ visibility,
+ openShowLink: `<a href="${showPath}">`,
+ closeShowLink: '</a>',
+ openEditLink: `<a href="${editPath}">`,
+ closeEditLink: '</a>',
+ },
+ false,
+ );
}
} else {
option.classList.remove('disabled');
diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss
index 08949578f46..82216b8d5c5 100644
--- a/app/assets/stylesheets/pages/labels.scss
+++ b/app/assets/stylesheets/pages/labels.scss
@@ -107,9 +107,8 @@
display: none;
}
-.label-subscribe-button {
- width: 105px;
- font-weight: 200;
+.label-subscription {
+ width: 109px;
}
.labels-container {
diff --git a/app/models/ci/secure_file.rb b/app/models/ci/secure_file.rb
new file mode 100644
index 00000000000..56f632b6232
--- /dev/null
+++ b/app/models/ci/secure_file.rb
@@ -0,0 +1,33 @@
+# frozen_string_literal: true
+
+module Ci
+ class SecureFile < Ci::ApplicationRecord
+ include FileStoreMounter
+
+ FILE_SIZE_LIMIT = 5.megabytes.freeze
+ CHECKSUM_ALGORITHM = 'sha256'
+
+ belongs_to :project, optional: false
+
+ validates :file, presence: true, file_size: { maximum: FILE_SIZE_LIMIT }
+ validates :checksum, :file_store, :name, :permissions, :project_id, presence: true
+
+ before_validation :assign_checksum
+
+ enum permissions: { read_only: 0, read_write: 1, execute: 2 }
+
+ default_value_for(:file_store) { Ci::SecureFileUploader.default_store }
+
+ mount_file_store_uploader Ci::SecureFileUploader
+
+ def checksum_algorithm
+ CHECKSUM_ALGORITHM
+ end
+
+ private
+
+ def assign_checksum
+ self.checksum = file.checksum if file.present? && file_changed?
+ end
+ end
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index 7e2c98c85b3..81ee1c1fe55 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -340,6 +340,7 @@ class Project < ApplicationRecord
has_many :runners, through: :runner_projects, source: :runner, class_name: 'Ci::Runner'
has_many :variables, class_name: 'Ci::Variable'
has_many :triggers, class_name: 'Ci::Trigger'
+ has_many :secure_files, class_name: 'Ci::SecureFile'
has_many :environments
has_many :environments_for_dashboard, -> { from(with_rank.unfoldered.available, :environments).where('rank <= 3') }, class_name: 'Environment'
has_many :deployments
diff --git a/app/uploaders/ci/secure_file_uploader.rb b/app/uploaders/ci/secure_file_uploader.rb
new file mode 100644
index 00000000000..514d88dd177
--- /dev/null
+++ b/app/uploaders/ci/secure_file_uploader.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+module Ci
+ class SecureFileUploader < GitlabUploader
+ include ObjectStorage::Concern
+
+ storage_options Gitlab.config.ci_secure_files
+
+ # Use Lockbox to encrypt/decrypt the stored file (registers CarrierWave callbacks)
+ encrypt(key: :key)
+
+ def key
+ OpenSSL::HMAC.digest('SHA256', Gitlab::Application.secrets.db_key_base, model.project_id.to_s)
+ end
+
+ def checksum
+ @checksum ||= Digest::SHA256.hexdigest(model.file.read)
+ end
+
+ def store_dir
+ dynamic_segment
+ end
+
+ private
+
+ def dynamic_segment
+ Gitlab::HashedPath.new('secure_files', model.id, root_hash: model.project_id)
+ end
+
+ class << self
+ # direct upload is disabled since the file
+ # must always be encrypted
+ def direct_upload_enabled?
+ false
+ end
+
+ def background_upload_enabled?
+ false
+ end
+
+ def default_store
+ object_store_enabled? ? ObjectStorage::Store::REMOTE : ObjectStorage::Store::LOCAL
+ end
+ end
+ end
+end
diff --git a/app/views/shared/_label.html.haml b/app/views/shared/_label.html.haml
index e4ef0a52eba..9428813f6b0 100644
--- a/app/views/shared/_label.html.haml
+++ b/app/views/shared/_label.html.haml
@@ -10,18 +10,18 @@
= render "shared/label_row", label: label, force_priority: force_priority
%ul.label-actions-list
- if can?(current_user, :admin_label, @project)
- %li.inline.js-toggle-priority{ data: { url: remove_priority_project_label_path(@project, label),
+ %li.gl-display-inline-block.js-toggle-priority.gl-ml-3{ data: { url: remove_priority_project_label_path(@project, label),
dom_id: dom_id(label), type: label.type } }
- %button.add-priority.btn.gl-button.btn-default-tertiary.btn-sm.has-tooltip.gl-ml-3{ title: _('Prioritize'), type: 'button', data: { placement: 'bottom' }, aria_label: _('Prioritize label') }
+ %button.add-priority.btn.gl-button.btn-default-tertiary.btn-sm.has-tooltip{ title: _('Prioritize'), type: 'button', data: { placement: 'bottom' }, aria_label: _('Prioritize label') }
= sprite_icon('star-o')
- %button.remove-priority.btn.gl-button.btn-default-tertiary.btn-sm.has-tooltip.gl-ml-3{ title: _('Remove priority'), type: 'button', data: { placement: 'bottom' }, aria_label: _('Deprioritize label') }
+ %button.remove-priority.btn.gl-button.btn-default-tertiary.btn-sm.has-tooltip{ title: _('Remove priority'), type: 'button', data: { placement: 'bottom' }, aria_label: _('Deprioritize label') }
= sprite_icon('star')
- if can?(current_user, :admin_label, label)
- %li.inline
+ %li.gl-display-inline-block
= link_to label.edit_path, class: 'btn gl-button btn-default-tertiary btn-sm edit has-tooltip', title: _('Edit'), data: { placement: 'bottom' }, aria_label: _('Edit') do
= sprite_icon('pencil')
- if can?(current_user, :admin_label, label)
- %li.inline
+ %li.gl-display-inline-block
.dropdown
%button{ type: 'button', class: 'btn gl-button btn-default-tertiary btn-sm js-label-options-dropdown', data: { toggle: 'dropdown' }, aria_label: _('Label actions dropdown') }
= sprite_icon('ellipsis_v')
@@ -41,23 +41,23 @@
%button.text-danger.js-delete-label-modal-button{ type: 'button', data: { label_name: label.name, subject_name: label.subject_name, destroy_path: label.destroy_path } }
= _('Delete')
- if current_user
- %li.inline.label-subscription
+ %li.gl-display-inline-block.label-subscription.js-label-subscription.gl-ml-3
- if label.can_subscribe_to_label_in_different_levels?
- %button.js-unsubscribe-button.gl-button.label-subscribe-button.btn.btn-default.gl-ml-3{ class: ('hidden' if status.unsubscribed?), data: { url: toggle_subscription_path, toggle: 'tooltip' }, title: tooltip_title }
- %span= _('Unsubscribe')
+ %button.js-unsubscribe-button.gl-button.btn.btn-default.gl-w-full{ class: ('hidden' if status.unsubscribed?), data: { url: toggle_subscription_path, toggle: 'tooltip' }, title: tooltip_title }
+ %span.gl-button-text= _('Unsubscribe')
.dropdown.dropdown-group-label{ class: ('hidden' unless status.unsubscribed?) }
- %button.gl-button.label-subscribe-button.btn.btn-default.gl-ml-3{ data: { toggle: 'dropdown' } }
- %span
+ %button.gl-button.btn.btn-default.gl-w-full{ data: { toggle: 'dropdown' } }
+ %span.gl-button-text
= _('Subscribe')
= sprite_icon('chevron-down')
.dropdown-menu.dropdown-open-left
%ul
%li
- %button.js-subscribe-button.label-subscribe-button.gl-button.btn.btn-default{ class: ('hidden' unless status.unsubscribed?), data: { status: status, url: toggle_subscription_project_label_path(@project, label) } }
- %span= _('Subscribe at project level')
+ %button.js-subscribe-button{ class: ('hidden' unless status.unsubscribed?), data: { status: status, url: toggle_subscription_project_label_path(@project, label) } }
+ %span.gl-button-text= _('Subscribe at project level')
%li
- %button.js-subscribe-button.js-group-level.label-subscribe-button.gl-button.btn.btn-default{ class: ('hidden' unless status.unsubscribed?), data: { status: status, url: toggle_subscription_group_label_path(label.group, label) } }
- %span= _('Subscribe at group level')
+ %button.js-subscribe-button.js-group-level{ class: ('hidden' unless status.unsubscribed?), data: { status: status, url: toggle_subscription_group_label_path(label.group, label) } }
+ %span.gl-button-text= _('Subscribe at group level')
- else
- %button.gl-button.js-subscribe-button.label-subscribe-button.btn.btn-default.gl-ml-3{ data: { status: status, url: toggle_subscription_path, toggle: 'tooltip' }, title: tooltip_title }
- %span= label_subscription_toggle_button_text(label, @project)
+ %button.gl-button.js-subscribe-button.btn.btn-default.gl-w-full{ data: { status: status, url: toggle_subscription_path, toggle: 'tooltip' }, title: tooltip_title }
+ %span.gl-button-text= label_subscription_toggle_button_text(label, @project)
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 4ff5c3b5179..2b67572c470 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -1425,6 +1425,18 @@ test:
aws_secret_access_key: AWS_SECRET_ACCESS_KEY
region: us-east-1
+ ci_secure_files:
+ enabled: true
+ storage_path: tmp/tests/ci_secure_files
+ object_store:
+ enabled: false
+ remote_directory: ci_secure_files
+ connection:
+ provider: AWS # Only AWS supported at the moment
+ aws_access_key_id: AWS_ACCESS_KEY_ID
+ aws_secret_access_key: AWS_SECRET_ACCESS_KEY
+ region: us-east-1
+
gitlab:
host: localhost
port: 80
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 2587347719a..f65c76d8b6b 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -247,6 +247,14 @@ Settings.gitlab_ci['builds_path'] = Settings.absolute(Settings.gitlab_
Settings.gitlab_ci['url'] ||= Settings.__send__(:build_gitlab_ci_url)
#
+# CI Secure Files
+#
+Settings['ci_secure_files'] ||= Settingslogic.new({})
+Settings.ci_secure_files['enabled'] = true if Settings.ci_secure_files['enabled'].nil?
+Settings.ci_secure_files['storage_path'] = Settings.absolute(Settings.ci_secure_files['storage_path'] || File.join(Settings.shared['path'], "ci_secure_files"))
+Settings.ci_secure_files['object_store'] = ObjectStoreSettings.legacy_parse(Settings.ci_secure_files['object_store'])
+
+#
# Reply by email
#
Settings['incoming_email'] ||= Settingslogic.new({})
diff --git a/config/object_store_settings.rb b/config/object_store_settings.rb
index 8cbb3451a16..53fbfb088db 100644
--- a/config/object_store_settings.rb
+++ b/config/object_store_settings.rb
@@ -2,7 +2,7 @@
# Set default values for object_store settings
class ObjectStoreSettings
- SUPPORTED_TYPES = %w(artifacts external_diffs lfs uploads packages dependency_proxy terraform_state pages).freeze
+ SUPPORTED_TYPES = %w(artifacts external_diffs lfs uploads packages dependency_proxy terraform_state pages secure_files).freeze
ALLOWED_OBJECT_STORE_OVERRIDES = %w(bucket enabled proxy_download).freeze
# To ensure the one Workhorse credential matches the Rails config, we
diff --git a/data/removals/14_0/remove_optimize_api.yml b/data/removals/14_0/remove_optimize_api.yml
index b0c7c0101df..5df120858c6 100644
--- a/data/removals/14_0/remove_optimize_api.yml
+++ b/data/removals/14_0/remove_optimize_api.yml
@@ -1,4 +1,4 @@
-- name: "Segments removed from DevOps Adoption API "
+- name: "Segments removed from DevOps Adoption API"
removal_date: "2021-06-22"
removal_milestone: "14.0"
reporter: ljlane
diff --git a/db/migrate/20211223125921_add_temp_index_to_members_state.rb b/db/migrate/20211223125921_add_temp_index_to_members_state.rb
new file mode 100644
index 00000000000..7dd2ec1a8aa
--- /dev/null
+++ b/db/migrate/20211223125921_add_temp_index_to_members_state.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+class AddTempIndexToMembersState < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ INDEX_NAME = 'tmp_index_members_on_state'
+
+ def up
+ # Temporary index to be removed in 14.9 https://gitlab.com/gitlab-org/gitlab/-/issues/349960
+ add_concurrent_index :members, :state, name: INDEX_NAME, where: 'state = 2'
+ end
+
+ def down
+ remove_concurrent_index_by_name :members, INDEX_NAME
+ end
+end
diff --git a/db/migrate/20220110170953_create_ci_secure_files.rb b/db/migrate/20220110170953_create_ci_secure_files.rb
new file mode 100644
index 00000000000..1498a2d0212
--- /dev/null
+++ b/db/migrate/20220110170953_create_ci_secure_files.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+class CreateCiSecureFiles < Gitlab::Database::Migration[1.0]
+ def up
+ create_table :ci_secure_files do |t|
+ t.bigint :project_id, index: true, null: false
+ t.timestamps_with_timezone null: false
+ t.integer :file_store, limit: 2, null: false, default: 1
+ t.integer :permissions, null: false, default: 0, limit: 2
+ t.text :name, null: false, limit: 255
+ t.text :file, null: false, limit: 255
+ t.binary :checksum, null: false
+ end
+ end
+
+ def down
+ drop_table :ci_secure_files, if_exists: true
+ end
+end
diff --git a/db/schema_migrations/20211223125921 b/db/schema_migrations/20211223125921
new file mode 100644
index 00000000000..b4e3a1583df
--- /dev/null
+++ b/db/schema_migrations/20211223125921
@@ -0,0 +1 @@
+e08c1634376ed78b78c4a54d874bed66c1ce40c7c509b67cfda00d1a8657f127 \ No newline at end of file
diff --git a/db/schema_migrations/20220110170953 b/db/schema_migrations/20220110170953
new file mode 100644
index 00000000000..d4c2aa5fcf2
--- /dev/null
+++ b/db/schema_migrations/20220110170953
@@ -0,0 +1 @@
+da1c6f2db7cee1e4cb8b477d1892fa7206a95157a84864ad3d6022ab6cffbd1f \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 10ae1ab0012..f9e1c638087 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -12209,6 +12209,29 @@ CREATE SEQUENCE ci_running_builds_id_seq
ALTER SEQUENCE ci_running_builds_id_seq OWNED BY ci_running_builds.id;
+CREATE TABLE ci_secure_files (
+ id bigint NOT NULL,
+ project_id bigint NOT NULL,
+ created_at timestamp with time zone NOT NULL,
+ updated_at timestamp with time zone NOT NULL,
+ file_store smallint DEFAULT 1 NOT NULL,
+ permissions smallint DEFAULT 0 NOT NULL,
+ name text NOT NULL,
+ file text NOT NULL,
+ checksum bytea NOT NULL,
+ CONSTRAINT check_320790634d CHECK ((char_length(file) <= 255)),
+ CONSTRAINT check_402c7b4a56 CHECK ((char_length(name) <= 255))
+);
+
+CREATE SEQUENCE ci_secure_files_id_seq
+ START WITH 1
+ INCREMENT BY 1
+ NO MINVALUE
+ NO MAXVALUE
+ CACHE 1;
+
+ALTER SEQUENCE ci_secure_files_id_seq OWNED BY ci_secure_files.id;
+
CREATE TABLE ci_sources_pipelines (
id integer NOT NULL,
project_id integer,
@@ -21440,6 +21463,8 @@ ALTER TABLE ONLY ci_runners ALTER COLUMN id SET DEFAULT nextval('ci_runners_id_s
ALTER TABLE ONLY ci_running_builds ALTER COLUMN id SET DEFAULT nextval('ci_running_builds_id_seq'::regclass);
+ALTER TABLE ONLY ci_secure_files ALTER COLUMN id SET DEFAULT nextval('ci_secure_files_id_seq'::regclass);
+
ALTER TABLE ONLY ci_sources_pipelines ALTER COLUMN id SET DEFAULT nextval('ci_sources_pipelines_id_seq'::regclass);
ALTER TABLE ONLY ci_sources_projects ALTER COLUMN id SET DEFAULT nextval('ci_sources_projects_id_seq'::regclass);
@@ -22930,6 +22955,9 @@ ALTER TABLE ONLY ci_runners
ALTER TABLE ONLY ci_running_builds
ADD CONSTRAINT ci_running_builds_pkey PRIMARY KEY (id);
+ALTER TABLE ONLY ci_secure_files
+ ADD CONSTRAINT ci_secure_files_pkey PRIMARY KEY (id);
+
ALTER TABLE ONLY ci_sources_pipelines
ADD CONSTRAINT ci_sources_pipelines_pkey PRIMARY KEY (id);
@@ -25627,6 +25655,8 @@ CREATE INDEX index_ci_running_builds_on_project_id ON ci_running_builds USING bt
CREATE INDEX index_ci_running_builds_on_runner_id ON ci_running_builds USING btree (runner_id);
+CREATE INDEX index_ci_secure_files_on_project_id ON ci_secure_files USING btree (project_id);
+
CREATE INDEX index_ci_sources_pipelines_on_pipeline_id ON ci_sources_pipelines USING btree (pipeline_id);
CREATE INDEX index_ci_sources_pipelines_on_project_id ON ci_sources_pipelines USING btree (project_id);
@@ -28035,6 +28065,8 @@ CREATE INDEX tmp_idx_deduplicate_vulnerability_occurrences ON vulnerability_occu
CREATE INDEX tmp_idx_vulnerability_occurrences_on_id_where_report_type_7_99 ON vulnerability_occurrences USING btree (id) WHERE (report_type = ANY (ARRAY[7, 99]));
+CREATE INDEX tmp_index_members_on_state ON members USING btree (state) WHERE (state = 2);
+
CREATE INDEX tmp_index_namespaces_empty_traversal_ids_with_child_namespaces ON namespaces USING btree (id) WHERE ((parent_id IS NOT NULL) AND (traversal_ids = '{}'::integer[]));
CREATE INDEX tmp_index_namespaces_empty_traversal_ids_with_root_namespaces ON namespaces USING btree (id) WHERE ((parent_id IS NULL) AND (traversal_ids = '{}'::integer[]));
diff --git a/doc/administration/logs.md b/doc/administration/logs.md
index dee0378b5cd..92167953441 100644
--- a/doc/administration/logs.md
+++ b/doc/administration/logs.md
@@ -21,7 +21,7 @@ switching logs from JSON to plain text logging, and more.
- [How to parse and analyze JSON logs](troubleshooting/log_parsing.md).
## Log Levels
-
+
Each log message has an assigned log level that indicates its importance and verbosity.
Each logger has an assigned minimum log level.
A logger emits a log message only if its log level is equal to or above the minimum log level.
diff --git a/doc/administration/package_information/defaults.md b/doc/administration/package_information/defaults.md
index bc385563e18..54e68392aa5 100644
--- a/doc/administration/package_information/defaults.md
+++ b/doc/administration/package_information/defaults.md
@@ -1,7 +1,7 @@
---
stage: Enablement
group: Distribution
-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/#designated-technical-writers
+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
---
# Package defaults **(FREE SELF)**
@@ -71,5 +71,5 @@ NOTE:
In some cases, the GitLab Registry will be automatically enabled by default. Please see [our documentation](../packages/container_registry.md) for more details
[^Consul-notes]: If using additional Consul functionality, more ports may need to be opened. See the [official documentation](https://www.consul.io/docs/install/ports#ports-table) for the list.
-
+
[^Sidekiq-health]: If Sidekiq health check settings are not set, they will default to the Sidekiq metrics exporter settings. This default is deprecated and is set to be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/347509).
diff --git a/doc/administration/sidekiq.md b/doc/administration/sidekiq.md
index 236f264edde..989a024d6ab 100644
--- a/doc/administration/sidekiq.md
+++ b/doc/administration/sidekiq.md
@@ -2,7 +2,6 @@
stage: Enablement
group: Distribution
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: reference
---
# Configuring Sidekiq **(FREE SELF)**
@@ -152,7 +151,7 @@ you want using steps 1 and 2 from the GitLab downloads page.
NOTE:
If health check settings are not set, they will default to the metrics exporter settings.
- This default is deprecated and is set to be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/347509).
+ This default is deprecated and is set to be removed in [GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/347509).
1. Run `gitlab-ctl reconfigure`.
diff --git a/doc/administration/sidekiq_health_check.md b/doc/administration/sidekiq_health_check.md
index 28bc670d8a7..2ed736bac2c 100644
--- a/doc/administration/sidekiq_health_check.md
+++ b/doc/administration/sidekiq_health_check.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Sidekiq Health Check **(FREE SELF)**
GitLab provides liveness and readiness probes to indicate service health and
-reachability to the Sidekiq cluster. These endpoints
+reachability to the Sidekiq cluster. These endpoints
[can be provided to schedulers like Kubernetes](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/)
to hold traffic until the system is ready or restart the container as needed.
diff --git a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
index a78744810e7..33a81c12811 100644
--- a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
+++ b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md
@@ -2,7 +2,6 @@
stage: Enablement
group: Distribution
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: reference
---
# GitLab Rails Console Cheat Sheet **(FREE SELF)**
@@ -1282,8 +1281,8 @@ Gitlab::GitalyClient::ServerService.new("default").storage_disk_statistics
## Generate Service Ping
-The [Service Ping Guide](../../development/service_ping/index.md) in our developer documentation
-has more information about Service Ping.
+The [Service Ping Guide](../../development/service_ping/index.md) in our developer documentation
+has more information about Service Ping.
### Generate or get the cached Service Ping
@@ -1309,7 +1308,7 @@ rake gitlab:usage_data:generate
Generates Service Ping data in YAML format:
-```shell
+```shell
rake gitlab:usage_data:dump_sql_in_yaml
```
diff --git a/doc/api/members.md b/doc/api/members.md
index 94dd0a0736b..ab3c1fd1315 100644
--- a/doc/api/members.md
+++ b/doc/api/members.md
@@ -88,7 +88,7 @@ Example response:
]
```
-## List all members of a group or project including inherited and invited members
+## List all members of a group or project including inherited and invited members
Gets a list of group or project members viewable by the authenticated user, including inherited members, invited users, and permissions through ancestor groups.
diff --git a/doc/ci/cloud_services/aws/index.md b/doc/ci/cloud_services/aws/index.md
index 2a9f6830285..f09b23db2c5 100644
--- a/doc/ci/cloud_services/aws/index.md
+++ b/doc/ci/cloud_services/aws/index.md
@@ -21,8 +21,8 @@ Create GitLab as a IAM OIDC provider in AWS following these [instructions](https
Include the following information:
-- **Provider URL**: The address of your GitLab instance, such as `https://gitlab.com` or `http://gitlab.example.com`.
-- **Audience**: The address of your GitLab instance, such as `https://gitlab.com` or `http://gitlab.example.com`.
+- **Provider URL**: The address of your GitLab instance, such as `https://gitlab.com` or `http://gitlab.example.com`.
+- **Audience**: The address of your GitLab instance, such as `https://gitlab.com` or `http://gitlab.example.com`.
- The address must include `https://`.
- Do not include a trailing slash.
@@ -56,7 +56,7 @@ After the role is created, attach a policy defining permissions to an AWS servic
## Retrieve temporary credentials
-After you configure the OIDC and role, the GitLab CI/CD job can retrieve a temporary credential from [AWS Security Token Service (STS)](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html).
+After you configure the OIDC and role, the GitLab CI/CD job can retrieve a temporary credential from [AWS Security Token Service (STS)](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html).
```yaml
assume role:
@@ -78,7 +78,7 @@ assume role:
- `CI_JOB_JWT_V2`: Predefined variable.
- `ROLE_ARN`: The role ARN defined in this [step](#configure-a-role-and-trust).
-## Working example
+## Working example
See this [reference project](https://gitlab.com/guided-explorations/aws/configure-openid-connect-in-aws) for provisioning OIDC in AWS using Terraform and a sample script to retrieve temporary credentials.
diff --git a/doc/ci/cloud_services/index.md b/doc/ci/cloud_services/index.md
index 126e5def983..73e726ea8a9 100644
--- a/doc/ci/cloud_services/index.md
+++ b/doc/ci/cloud_services/index.md
@@ -7,7 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Connect to cloud services
> - `CI_JOB_JWT` variable for reading secrets from Vault [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/207125) in GitLab 12.10.
-> - `CI_JOB_JWT_V2` variable to support additional OIDC providers [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346737) in GitLab 14.7.
+> - `CI_JOB_JWT_V2` variable to support additional OIDC providers [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/346737) in GitLab 14.7.
GitLab CI/CD supports [OpenID Connect (OIDC)](https://openid.net/connect/faq/) that allows your build and deployment job access to cloud credentials and services. Historically, teams stored secrets in projects or applied permissions on the GitLab Runner instance to build and deploy. To support this, a predefined variable named `CI_JOB_JWT_V2` is included in the CI/CD job allowing you to follow a scalable and least-privilege security approach.
@@ -19,7 +19,7 @@ GitLab CI/CD supports [OpenID Connect (OIDC)](https://openid.net/connect/faq/) t
The original implementation of `CI_JOB_JWT` supports [HashiCorp Vault integration](../examples/authenticating-with-hashicorp-vault/). The updated implementation of `CI_JOB_JWT_V2` supports additional cloud providers with OIDC including AWS, GCP, and Vault.
WARNING:
-The `CI_JOB_JWT_V2` variable is under development [(alpha)](https://about.gitlab.com/handbook/product/gitlab-the-product/#alpha) and is not yet suitable for production use.
+The `CI_JOB_JWT_V2` variable is under development [(alpha)](https://about.gitlab.com/handbook/product/gitlab-the-product/#alpha) and is not yet suitable for production use.
## Use cases
@@ -29,7 +29,7 @@ The `CI_JOB_JWT_V2` variable is under development [(alpha)](https://about.gitlab
- Allows shared runners to securely access multiple cloud accounts. The access is determined by the JWT token, which is specific to the user running the pipeline.
- Removes the need to create logic to rotate secrets by retrieving temporary credentials by default.
-## How it works
+## How it works
Each job has a JSON web token (JWT) provided as a CI/CD [predefined variable](../variables/predefined_variables.md) named `CI_JOB_JWT` or `CI_JOB_JWT_V2`. This JWT can be used to authenticate with the OIDC-supported cloud provider such as AWS, GCP, or Vault.
@@ -87,7 +87,7 @@ The following fields are included in the JWT:
}
```
-### Authorization workflow
+### Authorization workflow
```mermaid
sequenceDiagram
@@ -107,8 +107,8 @@ sequenceDiagram
1. Create an OIDC identity provider in the cloud (for example, AWS, GCP, Vault).
1. Create a conditional role in the cloud service that filters to a group, project, branch, or tag.
-1. The CI/CD job includes a predefined variable `CI_JOB_JWT_V2` that is a JWT token. You can use this token for authorization with your cloud API.
-1. The cloud verifies the token, validates the conditional role from the payload, and returns a temporary credential.
+1. The CI/CD job includes a predefined variable `CI_JOB_JWT_V2` that is a JWT token. You can use this token for authorization with your cloud API.
+1. The cloud verifies the token, validates the conditional role from the payload, and returns a temporary credential.
## Configure a conditional role with OIDC claims
@@ -116,7 +116,7 @@ To configure the trust between GitLab and OIDC, you must create a conditional ro
- Audience or `aud`: The URL of the GitLab instance. This is defined when the identity provider is first configured in your cloud provider.
- Subject or `sub`: A concatenation of metadata describing the GitLab CI/CD workflow including the group, project, branch, and tag. The `sub` field is in the following format:
- - `project_path:{group}/{project}:ref_type:{type}:ref:{branch_name}`
+ - `project_path:{group}/{project}:ref_type:{type}:ref:{branch_name}`
| Filter type | Example |
| ------------------------------------ | ------------------------------------------------------------ |
diff --git a/doc/ci/runners/configure_runners.md b/doc/ci/runners/configure_runners.md
index b2885262e9d..d826b28acce 100644
--- a/doc/ci/runners/configure_runners.md
+++ b/doc/ci/runners/configure_runners.md
@@ -2,7 +2,6 @@
stage: Verify
group: Runner
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: reference
---
# Configuring runners **(FREE)**
@@ -640,7 +639,7 @@ support this feature.
A meter can be enabled to provide the rate of transfer for uploads and downloads.
-You can set a maximum time for cache upload and download with the `CACHE_REQUEST_TIMEOUT` setting.
+You can set a maximum time for cache upload and download with the `CACHE_REQUEST_TIMEOUT` setting.
This setting can be useful when slow cache uploads substantially increase the duration of your job.
```yaml
diff --git a/doc/development/database_review.md b/doc/development/database_review.md
index e3ebac8d821..082c843a12c 100644
--- a/doc/development/database_review.md
+++ b/doc/development/database_review.md
@@ -140,7 +140,7 @@ of error that would result in corruption or loss of production data.
Include in the MR description:
- If the migration itself is not reversible, details of how data changes could be reverted in the event of an incident. For example, in the case of a migration that deletes records (an operation that most of the times is not automatically revertable), how _could_ the deleted records be recovered.
-- If the migration deletes data apply the label `~data-deletion`
+- If the migration deletes data, apply the label `~data-deletion`.
- Concise descriptions of possible user experience impact of an error; for example, "Issues would unexpectedly go missing from Epics".
- Relevant data from the [query plans](#query-plans) that indicate the query works as expected; such as the approximate number of records that will be modified/deleted.
diff --git a/doc/development/documentation/styleguide/word_list.md b/doc/development/documentation/styleguide/word_list.md
index b6264addbdd..6d069dad8af 100644
--- a/doc/development/documentation/styleguide/word_list.md
+++ b/doc/development/documentation/styleguide/word_list.md
@@ -647,6 +647,10 @@ Use **press** when talking about keyboard keys. For example:
Do not use profanity. Doing so may negatively affect other users and contributors, which is contrary to the GitLab value of [Diversity, Inclusion, and Belonging](https://about.gitlab.com/handbook/values/#diversity-inclusion).
+## push rules
+
+Use lowercase for **push rules**.
+
## Reporter
When writing about the Reporter role:
diff --git a/doc/development/event_store.md b/doc/development/event_store.md
index 85dfdf8b8ef..7f2b9c86d27 100644
--- a/doc/development/event_store.md
+++ b/doc/development/event_store.md
@@ -285,7 +285,7 @@ This technique can avoid scheduling Sidekiq jobs if the subscriber is interested
small subset of events.
WARNING:
-When using conditional dispatch it must contain only cheap conditions because they are
+When using conditional dispatch it must contain only cheap conditions because they are
executed synchronously every time the given event is published.
For complex conditions it's best to subscribe to all the events and then handle the logic
diff --git a/doc/development/feature_flags/controls.md b/doc/development/feature_flags/controls.md
index 91e27a3838c..6bf5be23ace 100644
--- a/doc/development/feature_flags/controls.md
+++ b/doc/development/feature_flags/controls.md
@@ -69,7 +69,7 @@ Slack channel for the stage the feature is relevant to. For example, use the
`#s_monitor` channel for features developed by the Monitor stage, Health
group.
-To enable a feature for 25% of all users, run the following in Slack:
+To enable a feature for 25% of the time, run the following in Slack:
```shell
/chatops run feature set new_navigation_bar 25 --dev
diff --git a/doc/development/integrations/secure.md b/doc/development/integrations/secure.md
index b362beab100..147d379cec7 100644
--- a/doc/development/integrations/secure.md
+++ b/doc/development/integrations/secure.md
@@ -331,7 +331,7 @@ You can find the schemas for these scanners here:
In GitLab 14.10 and later, report validation against the schemas is enabled. To enable report validation for versions earlier than 14.10,
set [`VALIDATE_SCHEMA`](../../user/application_security/#enable-security-report-validation) to
-`"true"`.
+`"true"`.
Reports that don't pass validation are not ingested by GitLab, and an error message
displays on the corresponding pipeline.
diff --git a/doc/install/aws/index.md b/doc/install/aws/index.md
index cf5ee2fa643..8dbda7420b0 100644
--- a/doc/install/aws/index.md
+++ b/doc/install/aws/index.md
@@ -63,7 +63,7 @@ When deploying a GitLab instance using the official AMI, the root password to th
Instances running on Community Edition (CE) require a migration to Enterprise Edition (EE) in order to subscribe to the GitLab Premium or Ultimate plan. If you want to pursue a subscription, using the Free-forever plan of Enterprise Edition is the least disruptive method.
NOTE:
-Since any given GitLab upgrade might involve data disk updates or database schema upgrades, simply swapping out the AMI is not sufficent for taking upgrades.
+Since any given GitLab upgrade might involve data disk updates or database schema upgrades, simply swapping out the AMI is not sufficent for taking upgrades.
1. Log in to the AWS Web Console, so that clicking the links in the following step take you directly to the AMI list.
1. Pick the edition you want:
diff --git a/doc/security/reset_user_password.md b/doc/security/reset_user_password.md
index ec03fe5bf7e..f67b1934dc5 100644
--- a/doc/security/reset_user_password.md
+++ b/doc/security/reset_user_password.md
@@ -68,12 +68,12 @@ If you know the username, user ID, or email address, you can use the Rails conso
user = User.find(123)
```
- - By email address:
+ - By email address:
```ruby
user = User.find_by(email: 'user@example.com')
```
-
+
1. Reset the password:
```ruby
@@ -105,7 +105,7 @@ To reset the root password, follow the steps listed previously.
- If the root account name hasn't changed, use the username `root`.
- If the root account name has changed and you don't know the new username,
- you might be able to use a Rails console with user ID `1`. In almost all
+ you might be able to use a Rails console with user ID `1`. In almost all
cases, the first user is the default administrator account.
## Troubleshooting
diff --git a/doc/subscriptions/self_managed/index.md b/doc/subscriptions/self_managed/index.md
index 0e2754bcc77..24ae97e185d 100644
--- a/doc/subscriptions/self_managed/index.md
+++ b/doc/subscriptions/self_managed/index.md
@@ -254,7 +254,7 @@ To subscribe to GitLab through a GitLab self-managed installation:
1. Go to the [Customers Portal](https://customers.gitlab.com/) and purchase a GitLab self-managed plan.
1. After purchase, a license file is sent to the email address associated to the Customers Portal account,
- which must be [uploaded to your GitLab instance](../../user/admin_area/license.md#uploading-your-license).
+ which must be [uploaded to your GitLab instance](../../user/admin_area/license.md#upload-your-license).
NOTE:
If you're purchasing a subscription for an existing **Free** GitLab self-managed
@@ -373,7 +373,7 @@ To add seats to a subscription:
The following items are emailed to you:
- A payment receipt. You can also access this information in the Customers Portal under [**View invoices**](https://customers.gitlab.com/receipts).
-- A new license. [Upload this license](../../user/admin_area/license.md#uploading-your-license) to your instance to use it.
+- A new license. [Upload this license](../../user/admin_area/license.md#upload-your-license) to your instance to use it.
### Renew a subscription
@@ -394,7 +394,7 @@ You can hover your mouse on the **Renew** button to see the date when it will be
1. Enter the number of [users over license](#users-over-license) in the second box for the user overage incurred in your previous subscription term.
1. Review your renewal details and complete the payment process.
1. A license for the renewal term is available for download on the [Manage Purchases](https://customers.gitlab.com/subscriptions) page on the relevant subscription card. Select **Copy license to clipboard** or **Download license** to get a copy.
-1. [Upload](../../user/admin_area/license.md#uploading-your-license) your new license to your instance.
+1. [Upload](../../user/admin_area/license.md#upload-your-license) your new license to your instance.
An invoice is generated for the renewal and available for viewing or download on the [View invoices](https://customers.gitlab.com/receipts) page. If you have difficulty during the renewal process, contact our [support team](https://support.gitlab.com/hc/en-us/requests/new?ticket_form_id=360000071293) for assistance.
@@ -416,7 +416,7 @@ The following is emailed to you:
[**View invoices**](https://customers.gitlab.com/receipts).
- A new license.
-[Upload the new license](../../user/admin_area/license.md#uploading-your-license) to your instance.
+[Upload the new license](../../user/admin_area/license.md#upload-your-license) to your instance.
The new tier takes effect when the new license is uploaded.
## Subscription expiry
diff --git a/doc/system_hooks/system_hooks.md b/doc/system_hooks/system_hooks.md
index 72106a00191..44429754747 100644
--- a/doc/system_hooks/system_hooks.md
+++ b/doc/system_hooks/system_hooks.md
@@ -45,7 +45,7 @@ System hooks can be used, for example, for logging or changing information in an
LDAP server.
In addition to these default events, you can enable triggers for other events,
-such as push events, and disable the `repository_update` event
+such as push events, and disable the `repository_update` event
when you create a system hook.
NOTE:
diff --git a/doc/update/removals.md b/doc/update/removals.md
index 68c43a691ad..e66e2397b73 100644
--- a/doc/update/removals.md
+++ b/doc/update/removals.md
@@ -292,7 +292,7 @@ To better support the latest versions of Ruby, the template is changed to use `r
Relevant Issue: [Updates Ruby version 2.5 to 3.0](https://gitlab.com/gitlab-org/gitlab/-/issues/329160)
-### Segments removed from DevOps Adoption API
+### Segments removed from DevOps Adoption API
The first release of the DevOps Adoption report had a concept of **Segments**. Segments were [quickly removed from the report](https://gitlab.com/groups/gitlab-org/-/epics/5251) because they introduced an additional layer of complexity on top of **Groups** and **Projects**. Subsequent iterations of the DevOps Adoption report focus on comparing adoption across groups rather than segments. GitLab 14.0 removes all references to **Segments** [from the GraphQL API](https://gitlab.com/gitlab-org/gitlab/-/issues/324414) and replaces them with **Enabled groups**.
diff --git a/doc/user/admin_area/analytics/dev_ops_report.md b/doc/user/admin_area/analytics/dev_ops_report.md
index ede9e342a2e..df34cd03d71 100644
--- a/doc/user/admin_area/analytics/dev_ops_report.md
+++ b/doc/user/admin_area/analytics/dev_ops_report.md
@@ -59,7 +59,7 @@ You can use Group DevOps Adoption to:
- Identify specific subgroups that are lagging in their adoption of GitLab features, so you can guide them on
their DevOps journey.
-- Find subgroups that have adopted certain features, and provide guidance to other subgroups on
+- Find subgroups that have adopted certain features, and provide guidance to other subgroups on
how to use those features.
- Verify if you are getting the return on investment that you expected from GitLab.
diff --git a/doc/user/admin_area/img/license_upload_v13_12.png b/doc/user/admin_area/img/license_upload_v13_12.png
deleted file mode 100644
index 81dc162c1f0..00000000000
--- a/doc/user/admin_area/img/license_upload_v13_12.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/license.md b/doc/user/admin_area/license.md
index 4358878c861..d5087c20e6f 100644
--- a/doc/user/admin_area/license.md
+++ b/doc/user/admin_area/license.md
@@ -42,38 +42,30 @@ To activate your instance with an activation code:
1. Read and accept the terms of service.
1. Select **Activate**.
-## Activate GitLab EE with a License File
+## Activate GitLab EE with a license file
-If you receive a license file from GitLab (for example a new trial), you can upload it by signing into your GitLab instance as an administrator or adding it during installation. The license is a base64-encoded ASCII text file with a `.gitlab-license` extension.
+If you receive a license file from GitLab (for example, for a trial), you can
+upload it to your instance or add it during installation. The license file is
+a base64-encoded ASCII text file with a `.gitlab-license` extension.
-## Uploading your license
+## Upload your license
-The first time you visit your GitLab EE installation signed in as an administrator,
-you should see a note urging you to upload a license with a link that takes you
-to the **Upload license** page.
+The first time you sign in to your GitLab instance, a note with a
+link to the **Upload license** page should be displayed.
-Otherwise, to manually go to the **Upload license** page:
+Otherwise, to upload your license:
-1. Sign in to your GitLab self-managed instance.
-1. From the top menu, select the Admin Area **{admin}**.
+1. Sign in to GitLab as an administrator.
+1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings**.
-1. In the **License file** section, select **Upload a license**.
-
- - *If you've received a `.gitlab-license` file:*
- 1. Download the license file to your local machine.
- 1. Select **Upload `.gitlab-license` file**.
- 1. Select **Choose file** and select the license file.
- In this example the license file is named `GitLab.gitlab-license`.
- 1. Select the **Terms of Service** checkbox.
- 1. Select **Upload License**.
-
- ![Upload license](img/license_upload_v13_12.png)
-
- - *If you've received your license as plain text:*
- 1. Select **Enter license key**.
- 1. Copy the license and paste it into the **License key** field.
- 1. Select the **Terms of Service** checkbox.
- 1. Select **Upload License**.
+1. In the **License file** area, select **Upload a license**.
+1. Upload a license:
+ - For a file, select **Upload `.gitlab-license` file**, **Choose file**, and
+ select the license file from your local machine.
+ - For plain text, select **Enter license key** and paste the contents in
+ **License key**.
+1. Select the **Terms of Service** checkbox.
+1. Select **Upload License**.
## Add your license during installation
@@ -110,7 +102,7 @@ and issue creation. Your instance becomes read-only and
an expiration message displays to all administrators. You have a 14-day grace period
before this occurs.
-To resume functionality, [upload a new license](#uploading-your-license).
+To resume functionality, [upload a new license](#upload-your-license).
To go back to Free features, [delete all expired licenses](#remove-a-license-file).
diff --git a/doc/user/admin_area/settings/third_party_offers.md b/doc/user/admin_area/settings/third_party_offers.md
index 8db34ddb89f..04ec9ed652f 100644
--- a/doc/user/admin_area/settings/third_party_offers.md
+++ b/doc/user/admin_area/settings/third_party_offers.md
@@ -13,7 +13,7 @@ Within GitLab, we inform users of available third-party offers they might find v
to enhance the development of their projects. An example is the Google Cloud Platform free credit
for using [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine/).
-Furthermore, we use content to improve customer experience. An example are the personalization
+Furthermore, we use content to improve customer experience. An example are the personalization
questions when creating a group.
To toggle the display of customer experience improvement content and third-party offers:
diff --git a/doc/user/admin_area/settings/visibility_and_access_controls.md b/doc/user/admin_area/settings/visibility_and_access_controls.md
index c6de9a3dd5b..82e0d3d27d4 100644
--- a/doc/user/admin_area/settings/visibility_and_access_controls.md
+++ b/doc/user/admin_area/settings/visibility_and_access_controls.md
@@ -190,7 +190,7 @@ To restrict visibility levels for projects, snippets, and selected pages:
1. In the **Restricted visibility levels** section, select the desired visibility levels to restrict.
If you restrict the **Public** level:
- User profiles are only visible to logged in users via the Web interface.
- - User attributes are only visible to authenticated users via the GraphQL API.
+ - User attributes are only visible to authenticated users via the GraphQL API.
1. Select **Save changes**.
For more details on project visibility, see
diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md
index fe285f3bfae..ab47cfc8ea1 100644
--- a/doc/user/application_security/sast/index.md
+++ b/doc/user/application_security/sast/index.md
@@ -310,9 +310,9 @@ To disable analyzer rules:
1. Set the `disabled` flag to `true` in the context of a `ruleset` section
-1. In one or more `ruleset.identifier` sub sections, list the rules that you want disabled. Every `ruleset.identifier` section has:
+1. In one or more `ruleset.identifier` sub sections, list the rules that you want disabled. Every `ruleset.identifier` section has:
-- a `type` field, to name the predefined rule identifier that the targeted analyzer uses.
+- a `type` field, to name the predefined rule identifier that the targeted analyzer uses.
- a `value` field, to name the rule to be disabled.
@@ -345,7 +345,7 @@ and `sobelow` by matching the `type` and `value` of identifiers:
#### Synthesize a custom configuration
-To create a custom configuration, you can use passthrough chains.
+To create a custom configuration, you can use passthrough chains.
A passthrough is a single step in a passthrough chain. The passthrough is evaluated
in a sequence to incrementally build a configuration. The configuration is then
@@ -359,8 +359,8 @@ parameters:
| `description` | Description about the analyzer configuration section. |
| `targetdir` | The `targetdir` parameter defines the directory where the final configuration is located. If `targetdir` is empty, the analyzer uses a random directory. The maximum size of `targetdir` is 100MB. |
| `validate` | If set to `true`, the target files for passthroughs (`raw`, `file` and `url`) are validated. The validation works for `yaml`, `xml`, `json` and `toml` files. The proper validator is identified based on the extension of the target file. By default, `validate` is set to `false`. |
-| `interpolate` | If set to `true`, environment variable interpolation is enabled so that the configuration uses secrets/tokens. We advise using this feature with caution to not leak any secrets. By default, `interpolate` is set to `false`. |
-| `timeout` | The total `timeout` for the evaluation of a passthrough chain is set to 60 seconds. If `timeout` is not set, the default timeout is 60 seconds. The timeout cannot exceed 300 seconds. |
+| `interpolate` | If set to `true`, environment variable interpolation is enabled so that the configuration uses secrets/tokens. We advise using this feature with caution to not leak any secrets. By default, `interpolate` is set to `false`. |
+| `timeout` | The total `timeout` for the evaluation of a passthrough chain is set to 60 seconds. If `timeout` is not set, the default timeout is 60 seconds. The timeout cannot exceed 300 seconds. |
A configuration section can include one or more passthrough sections. The maximum number of passthrough sections is 20.
There are several types of passthroughs:
@@ -373,12 +373,12 @@ There are several types of passthroughs:
| `url` | Fetch the analyzer configuration through HTTP. |
If multiple passthrough sections are defined in a passthrough chain, their
-position in the chain defines the order in which they are evaluated.
+position in the chain defines the order in which they are evaluated.
-- Passthroughs listed later in the chain sequence have a higher precedence.
+- Passthroughs listed later in the chain sequence have a higher precedence.
- Passthroughs with a higher precedence overwrite (default) and append data
yielded by previous passthroughs. This is useful for cases where you need to
- use or modify an existing configuration.
+ use or modify an existing configuration.
Configure a passthrough these parameters:
@@ -453,7 +453,7 @@ file `gosec-config.json`:
##### Passthrough chain for semgrep
In the below example, we generate a custom configuration under the `/sgrules`
-target directory with a total `timeout` of 60 seconds.
+target directory with a total `timeout` of 60 seconds.
Several passthrouh types generate a configuration for the target analyzer:
@@ -462,17 +462,17 @@ Several passthrouh types generate a configuration for the target analyzer:
`97f7686` from the `sast-rules` Git repostory. From the `sast-rules` Git
repository, only data from the `go` subdirectory is considered.
- The `sast-rules` entry has a higher precedence because it appears later in
- the configuration.
+ the configuration.
- If there is a filename collision between files in both repositories, files
from the `sast` repository overwrite files from the `myrules` repository,
as `sast-rules` has higher precedence.
- The `raw` entry creates a file named `insecure.yml` under `/sgrules`. The
- full path is `/sgrules/insecure.yml`.
+ full path is `/sgrules/insecure.yml`.
- The `url` entry fetches a configuration made available through a URL and
- stores it in the `/sgrules/gosec.yml` file.
+ stores it in the `/sgrules/gosec.yml` file.
Afterwards, semgrep is invoked with the final configuration located under
-`/sgrules`.
+`/sgrules`.
```toml
[semgrep]
@@ -536,17 +536,17 @@ It does not explicitly store credentials in the configuration file. To reduce th
##### Configure the append mode for passthroughs
To append data to previous passthroughs, use the `append` mode for the
-passthrough types `file`, `url`, and `raw`.
+passthrough types `file`, `url`, and `raw`.
Passthroughs in `override` mode overwrite files
created when preceding passthroughs in the chain find a naming
collision. If `mode` is set to `append`, a passthrough appends data to the
-files created by its predecessors instead of overwriting.
+files created by its predecessors instead of overwriting.
In the below semgrep configuration,`/sgrules/insecure.yml` assembles two passthroughs. The rules are:
- `insecure`
-- `secret`
+- `secret`
These rules add a search pattern to the analyzer and extends semgrep capabilities.
diff --git a/doc/user/application_security/security_dashboard/index.md b/doc/user/application_security/security_dashboard/index.md
index 6d214c90dd2..937ca33c3a1 100644
--- a/doc/user/application_security/security_dashboard/index.md
+++ b/doc/user/application_security/security_dashboard/index.md
@@ -128,7 +128,7 @@ To view vulnerabilities over time for a group:
1. Select **Security > Security Dashboard**.
1. Hover over the chart to get more details about vulnerabilities.
- You can display the vulnerability trends over a 30, 60, or 90-day time frame (the default is 90 days).
- - To view aggregated data beyond a 90-day time frame, use the
+ - To view aggregated data beyond a 90-day time frame, use the
[VulnerabilitiesCountByDay GraphQL API](../../../api/graphql/reference/index.md#vulnerabilitiescountbyday).
GitLab retains the data for 365 days.
diff --git a/doc/user/clusters/agent/index.md b/doc/user/clusters/agent/index.md
index 2c6b8ce470c..a235c0ef6f8 100644
--- a/doc/user/clusters/agent/index.md
+++ b/doc/user/clusters/agent/index.md
@@ -142,8 +142,8 @@ To remove an agent from the UI:
1. Go to your agent's configuration repository.
1. From your project's sidebar, select **Infrastructure > Kubernetes clusters**.
-1. Select your agent from the table, and then in the **Options** column, click the vertical ellipsis
-(**{ellipsis_v}**) button and select **Delete agent**.
+1. Select your agent from the table, and then in the **Options** column, click the vertical ellipsis
+(**{ellipsis_v}**) button and select **Delete agent**.
### Remove an agent with the GitLab GraphQL API
diff --git a/doc/user/infrastructure/iac/index.md b/doc/user/infrastructure/iac/index.md
index 89bc17816eb..ceb6101688b 100644
--- a/doc/user/infrastructure/iac/index.md
+++ b/doc/user/infrastructure/iac/index.md
@@ -41,10 +41,10 @@ This template includes the following parameters that you can override:
`test`, `validate`, `build`, and `deploy`. These stages
[run the Terraform commands](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml)
`test`, `validate`, `plan`, `plan-json`, and `apply`. The `apply` command only runs on the default branch.
-- Runs the [Terraform SAST scanner](../../application_security/iac_scanning/index.md#configure-iac-scanning-manually),
+- Runs the [Terraform SAST scanner](../../application_security/iac_scanning/index.md#configure-iac-scanning-manually),
that you can disable by creating a `SAST_DISABLED` environment variable and setting it to `1`.
-The latest template described above might contain breaking changes between major GitLab releases. For users requiring more stable setups, we
+The latest template described above might contain breaking changes between major GitLab releases. For users requiring more stable setups, we
recommend using the stable templates:
- [A ready to use version](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Terraform.gitlab-ci.yml)
diff --git a/doc/user/packages/dependency_proxy/index.md b/doc/user/packages/dependency_proxy/index.md
index 4e296f5e21c..52f5a1fcc0d 100644
--- a/doc/user/packages/dependency_proxy/index.md
+++ b/doc/user/packages/dependency_proxy/index.md
@@ -231,7 +231,7 @@ You can enable an automatic time-to-live (TTL) policy for the Dependency Proxy f
interface. To do this, navigate to your group's **Settings > Packages & Registries > Dependency Proxy**
and enable the setting to automatically clear items from the cache after 90 days.
-#### Enable cleanup policies with GraphQL
+#### Enable cleanup policies with GraphQL
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/294187) in GitLab 14.4.
@@ -263,7 +263,7 @@ mutation {
```
See the [Getting started with GraphQL](../../../api/graphql/getting_started.md)
-guide to learn how to make GraphQL queries.
+guide to learn how to make GraphQL queries.
When the policy is initially enabled, the default TTL setting is 90 days. Once enabled, stale
dependency proxy files are queued for deletion each day. Deletion may not occur right away due to
diff --git a/doc/user/project/code_owners.md b/doc/user/project/code_owners.md
index 1f73cf938e7..4068d8e056c 100644
--- a/doc/user/project/code_owners.md
+++ b/doc/user/project/code_owners.md
@@ -289,12 +289,12 @@ A Code Owner approval rule is optional if these conditions are not met:
### Approvals do not show
-Code Owner approval rules only update when the merge request is created.
+Code Owner approval rules only update when the merge request is created.
If you update the `CODEOWNERS` file, close the merge request and create a new one.
### User not shown as possible approver
-A user might not show as an approver on the Code Owner merge request approval rules.
+A user might not show as an approver on the Code Owner merge request approval rules.
This result occurs when a rule prevents the specific user from approving the merge request.
Check the project
diff --git a/doc/user/project/integrations/discord_notifications.md b/doc/user/project/integrations/discord_notifications.md
index 7ffc9d9c50a..ad7719f0e5b 100644
--- a/doc/user/project/integrations/discord_notifications.md
+++ b/doc/user/project/integrations/discord_notifications.md
@@ -16,7 +16,7 @@ and configure it in GitLab.
1. Open the Discord channel you want to receive GitLab event notifications.
1. From the channel menu, select **Edit channel**.
1. Select **Integrations**.
-1. If there are no existing webhooks, select **Create Webhook**. Otherwise, select **View Webhooks** then **New Webhook**.
+1. If there are no existing webhooks, select **Create Webhook**. Otherwise, select **View Webhooks** then **New Webhook**.
1. Enter the name of the bot to post the message.
1. Optional. Edit the avatar.
1. Copy the URL from the **WEBHOOK URL** field.
diff --git a/doc/user/project/merge_requests/accessibility_testing.md b/doc/user/project/merge_requests/accessibility_testing.md
index 2f1aed1474e..e67af8dc936 100644
--- a/doc/user/project/merge_requests/accessibility_testing.md
+++ b/doc/user/project/merge_requests/accessibility_testing.md
@@ -73,5 +73,5 @@ link to the [current template in the default branch](https://gitlab.com/gitlab-o
NOTE:
The job definition provided by the template does not support Kubernetes.
-You cannot pass configurations into Pa11y via CI configuration.
+You cannot pass configurations into Pa11y via CI configuration.
To change the configuration, edit a copy of the template in your CI file.
diff --git a/doc/user/project/merge_requests/commit_templates.md b/doc/user/project/merge_requests/commit_templates.md
index f8775b96b3b..0cc18d2117b 100644
--- a/doc/user/project/merge_requests/commit_templates.md
+++ b/doc/user/project/merge_requests/commit_templates.md
@@ -88,7 +88,7 @@ Commit message templates support these variables:
| `%{co_authored_by}` | Names and emails of commit authors in a `Co-authored-by` Git commit trailer format. Limited to authors of 100 most recent commits in merge request. | `Co-authored-by: Zane Doe <zdoe@example.com>` <br> `Co-authored-by: Blake Smith <bsmith@example.com>` |
Any line containing only an empty variable is removed. If the line to be removed is both
-preceded and followed by an empty line, the preceding empty line is also removed.
+preceded and followed by an empty line, the preceding empty line is also removed.
## Related topics
diff --git a/doc/user/project/working_with_projects.md b/doc/user/project/working_with_projects.md
index b5b3f2d2085..61eca19a67b 100644
--- a/doc/user/project/working_with_projects.md
+++ b/doc/user/project/working_with_projects.md
@@ -16,7 +16,7 @@ To explore projects:
1. On the top bar, select **Menu > Projects**.
1. Select **Explore projects**.
-The **Projects** page shows a list of projects, sorted by last updated date.
+The **Projects** page shows a list of projects, sorted by last updated date.
- To view projects with the most [stars](#star-a-project), select **Most stars**.
- To view projects with the largest number of comments in the past month, select **Trending**.
@@ -326,7 +326,7 @@ on the project dashboard when a project is part of a group under a
Prerequisites:
- Contact your administrator to enable the [GitLab Go Proxy](../packages/go_proxy/index.md).
-- To use a private project in a subgroup as a Go package, you must [authenticate Go requests](#authenticate-go-requests-to-private-projects). Go requests that are not authenticated cause
+- To use a private project in a subgroup as a Go package, you must [authenticate Go requests](#authenticate-go-requests-to-private-projects). Go requests that are not authenticated cause
`go get` to fail. You don't need to authenticate Go requests for projects that are not in subgroups.
To use a project as a Go package, use the `go get` and `godoc.org` discovery requests. You can use the meta tags:
diff --git a/doc/user/search/index.md b/doc/user/search/index.md
index 3eb68c6d95a..46c14860956 100644
--- a/doc/user/search/index.md
+++ b/doc/user/search/index.md
@@ -141,7 +141,7 @@ you can choose from:
![Filter MRs by their environment](img/filtering_merge_requests_by_environment_v14_6.png)
-When filtering by `Deployed-before` or `Deployed-after`, the date refers to when
+When filtering by `Deployed-before` or `Deployed-after`, the date refers to when
the deployment to an environment (triggered by the merge commit) completed successfully.
You must enter the deploy date manually. Deploy dates
use the format `YYYY-MM-DD`, and must be quoted if you wish to specify
diff --git a/lib/banzai/filter/syntax_highlight_filter.rb b/lib/banzai/filter/syntax_highlight_filter.rb
index f6cde6dc66f..07f82c98666 100644
--- a/lib/banzai/filter/syntax_highlight_filter.rb
+++ b/lib/banzai/filter/syntax_highlight_filter.rb
@@ -14,7 +14,7 @@ module Banzai
LANG_PARAMS_DELIMITER = ':'
LANG_PARAMS_ATTR = 'data-lang-params'
- CSS = 'pre:not([data-math-style]):not([data-mermaid-style]):not([data-kroki-style]) > code'
+ CSS = 'pre:not([data-math-style]):not([data-mermaid-style]):not([data-kroki-style]) > code:only-child'
XPATH = Gitlab::Utils::Nokogiri.css_to_xpath(CSS).freeze
def call
@@ -106,8 +106,8 @@ module Banzai
(Rouge::Lexer.find(language) || Rouge::Lexers::PlainText).new
end
+ # Replace the parent `pre` element with the entire highlighted block
def replace_parent_pre_element(node, highlighted)
- # Replace the parent `pre` element with the entire highlighted block
node.parent.replace(highlighted)
end
diff --git a/lib/gitlab/database/gitlab_loose_foreign_keys.yml b/lib/gitlab/database/gitlab_loose_foreign_keys.yml
index 82d81652765..d30715fcfde 100644
--- a/lib/gitlab/database/gitlab_loose_foreign_keys.yml
+++ b/lib/gitlab/database/gitlab_loose_foreign_keys.yml
@@ -143,3 +143,7 @@ security_scans:
- table: ci_builds
column: build_id
on_delete: async_delete
+ci_secure_files:
+ - table: projects
+ column: project_id
+ on_delete: async_delete
diff --git a/lib/gitlab/database/gitlab_schemas.yml b/lib/gitlab/database/gitlab_schemas.yml
index beabca812a5..f4cb49c20fc 100644
--- a/lib/gitlab/database/gitlab_schemas.yml
+++ b/lib/gitlab/database/gitlab_schemas.yml
@@ -107,6 +107,7 @@ ci_runner_projects: :gitlab_ci
ci_runners: :gitlab_ci
ci_running_builds: :gitlab_ci
ci_sources_pipelines: :gitlab_ci
+ci_secure_files: :gitlab_ci
ci_sources_projects: :gitlab_ci
ci_stages: :gitlab_ci
ci_subscriptions_projects: :gitlab_ci
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 5e1466c6efa..eef2ca6eaaf 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -36533,6 +36533,9 @@ msgstr ""
msgid "This project"
msgstr ""
+msgid "This project cannot be %{visibilityLevel} because the visibility of %{openShowLink}%{name}%{closeShowLink} is %{visibility}. To make this project %{visibilityLevel}, you must first %{openEditLink}change the visibility%{closeEditLink} of the parent group."
+msgstr ""
+
msgid "This project does not belong to a group and cannot make use of group runners."
msgstr ""
diff --git a/spec/factories/ci/secure_files.rb b/spec/factories/ci/secure_files.rb
new file mode 100644
index 00000000000..9198ea61d14
--- /dev/null
+++ b/spec/factories/ci/secure_files.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+FactoryBot.define do
+ factory :ci_secure_file, class: 'Ci::SecureFile' do
+ name { 'filename' }
+ file { fixture_file_upload('spec/fixtures/ci_secure_files/upload-keystore.jks', 'application/octet-stream') }
+ checksum { 'foo1234' }
+ project
+ end
+end
diff --git a/spec/fixtures/ci_secure_files/upload-keystore.jks b/spec/fixtures/ci_secure_files/upload-keystore.jks
new file mode 100644
index 00000000000..715adad4a89
--- /dev/null
+++ b/spec/fixtures/ci_secure_files/upload-keystore.jks
Binary files differ
diff --git a/spec/frontend/content_editor/extensions/code_spec.js b/spec/frontend/content_editor/extensions/code_spec.js
new file mode 100644
index 00000000000..0a54ac6a96b
--- /dev/null
+++ b/spec/frontend/content_editor/extensions/code_spec.js
@@ -0,0 +1,8 @@
+import Code from '~/content_editor/extensions/code';
+import { EXTENSION_PRIORITY_LOWER } from '~/content_editor/constants';
+
+describe('content_editor/extensions/code', () => {
+ it('has a lower loading priority', () => {
+ expect(Code.config.priority).toBe(EXTENSION_PRIORITY_LOWER);
+ });
+});
diff --git a/spec/frontend/content_editor/extensions/frontmatter_spec.js b/spec/frontend/content_editor/extensions/frontmatter_spec.js
index 517f6947b9a..a8cbad6ef81 100644
--- a/spec/frontend/content_editor/extensions/frontmatter_spec.js
+++ b/spec/frontend/content_editor/extensions/frontmatter_spec.js
@@ -1,30 +1,47 @@
import Frontmatter from '~/content_editor/extensions/frontmatter';
+import CodeBlockHighlight from '~/content_editor/extensions/code_block_highlight';
import { createTestEditor, createDocBuilder, triggerNodeInputRule } from '../test_utils';
describe('content_editor/extensions/frontmatter', () => {
let tiptapEditor;
let doc;
- let p;
+ let frontmatter;
+ let codeBlock;
beforeEach(() => {
- tiptapEditor = createTestEditor({ extensions: [Frontmatter] });
+ tiptapEditor = createTestEditor({ extensions: [Frontmatter, CodeBlockHighlight] });
({
- builders: { doc, p },
+ builders: { doc, codeBlock, frontmatter },
} = createDocBuilder({
tiptapEditor,
names: {
frontmatter: { nodeType: Frontmatter.name },
+ codeBlock: { nodeType: CodeBlockHighlight.name },
},
}));
});
it('does not insert a frontmatter block when executing code block input rule', () => {
- const expectedDoc = doc(p(''));
+ const expectedDoc = doc(codeBlock(''));
const inputRuleText = '``` ';
triggerNodeInputRule({ tiptapEditor, inputRuleText });
expect(tiptapEditor.getJSON()).toEqual(expectedDoc.toJSON());
});
+
+ it.each`
+ command | result | resultDesc
+ ${'toggleCodeBlock'} | ${() => doc(codeBlock(''))} | ${'code block element'}
+ ${'setCodeBlock'} | ${() => doc(codeBlock(''))} | ${'code block element'}
+ ${'setFrontmatter'} | ${() => doc(frontmatter(''))} | ${'frontmatter element'}
+ ${'toggleFrontmatter'} | ${() => doc(frontmatter(''))} | ${'frontmatter element'}
+ `('executing $command should generate a document with a $resultDesc', ({ command, result }) => {
+ const expectedDoc = result();
+
+ tiptapEditor.commands[command]();
+
+ expect(tiptapEditor.getJSON()).toEqual(expectedDoc.toJSON());
+ });
});
diff --git a/spec/frontend/content_editor/services/markdown_serializer_spec.js b/spec/frontend/content_editor/services/markdown_serializer_spec.js
index 97f6d8f6334..68ccb01ddd1 100644
--- a/spec/frontend/content_editor/services/markdown_serializer_spec.js
+++ b/spec/frontend/content_editor/services/markdown_serializer_spec.js
@@ -164,6 +164,17 @@ describe('markdownSerializer', () => {
expect(serialize(paragraph(italic('italics')))).toBe('_italics_');
});
+ it('correctly serializes code blocks wrapped by italics and bold marks', () => {
+ const text = 'code block';
+
+ expect(serialize(paragraph(italic(code(text))))).toBe(`_\`${text}\`_`);
+ expect(serialize(paragraph(code(italic(text))))).toBe(`_\`${text}\`_`);
+ expect(serialize(paragraph(bold(code(text))))).toBe(`**\`${text}\`**`);
+ expect(serialize(paragraph(code(bold(text))))).toBe(`**\`${text}\`**`);
+ expect(serialize(paragraph(strike(code(text))))).toBe(`~~\`${text}\`~~`);
+ expect(serialize(paragraph(code(strike(text))))).toBe(`~~\`${text}\`~~`);
+ });
+
it('correctly serializes inline diff', () => {
expect(
serialize(
diff --git a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
index 83df8328791..aee4bd93207 100644
--- a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
+++ b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb
@@ -37,6 +37,14 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do
end
end
+ context "when <pre> contains multiple <code> tags" do
+ it "ignores the block" do
+ result = filter('<pre><code>one</code> and <code>two</code></pre>')
+
+ expect(result.to_html).to eq('<pre><code>one</code> and <code>two</code></pre>')
+ end
+ end
+
context "when a valid language is specified" do
it "highlights as that language" do
result = filter('<pre lang="ruby"><code>def fun end</code></pre>')
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index fb7eb4668b9..625e94e3d77 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -602,6 +602,7 @@ project:
- bulk_import_exports
- ci_project_mirror
- sync_events
+- secure_files
award_emoji:
- awardable
- user
diff --git a/spec/models/ci/secure_file_spec.rb b/spec/models/ci/secure_file_spec.rb
new file mode 100644
index 00000000000..ae57b63e7a4
--- /dev/null
+++ b/spec/models/ci/secure_file_spec.rb
@@ -0,0 +1,55 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::SecureFile do
+ let(:sample_file) { fixture_file('ci_secure_files/upload-keystore.jks') }
+
+ subject { create(:ci_secure_file) }
+
+ before do
+ stub_ci_secure_file_object_storage
+ end
+
+ it { is_expected.to be_a FileStoreMounter }
+
+ it { is_expected.to belong_to(:project).required }
+
+ it_behaves_like 'having unique enum values'
+
+ describe 'validations' do
+ it { is_expected.to validate_presence_of(:checksum) }
+ it { is_expected.to validate_presence_of(:file_store) }
+ it { is_expected.to validate_presence_of(:name) }
+ it { is_expected.to validate_presence_of(:permissions) }
+ it { is_expected.to validate_presence_of(:project_id) }
+ end
+
+ describe '#permissions' do
+ it 'defaults to read_only file permssions' do
+ expect(subject.permissions).to eq('read_only')
+ end
+ end
+
+ describe '#checksum' do
+ it 'computes SHA256 checksum on the file before encrypted' do
+ subject.file = CarrierWaveStringFile.new(sample_file)
+ subject.save!
+ expect(subject.checksum).to eq(Digest::SHA256.hexdigest(sample_file))
+ end
+ end
+
+ describe '#checksum_algorithm' do
+ it 'returns the configured checksum_algorithm' do
+ expect(subject.checksum_algorithm).to eq('sha256')
+ end
+ end
+
+ describe '#file' do
+ it 'returns the saved file' do
+ subject.file = CarrierWaveStringFile.new(sample_file)
+ subject.save!
+ expect(Base64.encode64(subject.file.read)).to eq(Base64.encode64(sample_file))
+ end
+ end
+end
diff --git a/spec/support/helpers/stub_object_storage.rb b/spec/support/helpers/stub_object_storage.rb
index 5e86b08aa45..d49a14f7f5b 100644
--- a/spec/support/helpers/stub_object_storage.rb
+++ b/spec/support/helpers/stub_object_storage.rb
@@ -91,6 +91,12 @@ module StubObjectStorage
**params)
end
+ def stub_ci_secure_file_object_storage(**params)
+ stub_object_storage_uploader(config: Gitlab.config.ci_secure_files.object_store,
+ uploader: Ci::SecureFileUploader,
+ **params)
+ end
+
def stub_terraform_state_object_storage(**params)
stub_object_storage_uploader(config: Gitlab.config.terraform_state.object_store,
uploader: Terraform::StateUploader,
diff --git a/spec/uploaders/ci/secure_file_uploader_spec.rb b/spec/uploaders/ci/secure_file_uploader_spec.rb
new file mode 100644
index 00000000000..3be4f742a24
--- /dev/null
+++ b/spec/uploaders/ci/secure_file_uploader_spec.rb
@@ -0,0 +1,72 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::SecureFileUploader do
+ subject { ci_secure_file.file }
+
+ let(:project) { create(:project) }
+ let(:ci_secure_file) { create(:ci_secure_file) }
+ let(:sample_file) { fixture_file('ci_secure_files/upload-keystore.jks') }
+
+ before do
+ stub_ci_secure_file_object_storage
+ end
+
+ describe '#key' do
+ it 'creates a digest with a secret key and the project id' do
+ expect(OpenSSL::HMAC)
+ .to receive(:digest)
+ .with('SHA256', Gitlab::Application.secrets.db_key_base, ci_secure_file.project_id.to_s)
+ .and_return('digest')
+
+ expect(subject.key).to eq('digest')
+ end
+ end
+
+ describe '.checksum' do
+ it 'returns a SHA256 checksum for the unencrypted file' do
+ expect(subject.checksum).to eq(Digest::SHA256.hexdigest(sample_file))
+ end
+ end
+
+ describe 'encryption' do
+ it 'encrypts the stored file' do
+ expect(Base64.encode64(subject.file.read)).not_to eq(Base64.encode64(sample_file))
+ end
+
+ it 'decrypts the file when reading' do
+ expect(Base64.encode64(subject.read)).to eq(Base64.encode64(sample_file))
+ end
+ end
+
+ describe '.direct_upload_enabled?' do
+ it 'returns false' do
+ expect(described_class.direct_upload_enabled?).to eq(false)
+ end
+ end
+
+ describe '.background_upload_enabled?' do
+ it 'returns false' do
+ expect(described_class.background_upload_enabled?).to eq(false)
+ end
+ end
+
+ describe '.default_store' do
+ context 'when object storage is enabled' do
+ it 'returns REMOTE' do
+ expect(described_class.default_store).to eq(ObjectStorage::Store::REMOTE)
+ end
+ end
+
+ context 'when object storage is disabled' do
+ before do
+ stub_ci_secure_file_object_storage(enabled: false)
+ end
+
+ it 'returns LOCAL' do
+ expect(described_class.default_store).to eq(ObjectStorage::Store::LOCAL)
+ end
+ end
+ end
+end