diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-06 18:14:39 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-12-06 18:14:39 +0300 |
commit | 55242833f832095a6fcff00b1ccacbc5900ee52a (patch) | |
tree | 6e17b16638e60099533473b540fe8f635d2f25da /app | |
parent | 7c31b0312ba0eae4e4ebe54125b13aa2ae5f5db4 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/editor/extensions/source_editor_markdown_ext.js | 155 | ||||
-rw-r--r-- | app/assets/javascripts/editor/extensions/source_editor_markdown_livepreview_ext.js | 154 | ||||
-rw-r--r-- | app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue | 2 | ||||
-rw-r--r-- | app/assets/javascripts/vue_merge_request_widget/constants.js | 3 | ||||
-rw-r--r-- | app/assets/javascripts/vue_shared/components/file_row.vue | 1 | ||||
-rw-r--r-- | app/controllers/concerns/one_trust_csp.rb | 4 | ||||
-rw-r--r-- | app/controllers/invites_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/projects/tree_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/registrations_controller.rb | 1 | ||||
-rw-r--r-- | app/helpers/notify_helper.rb | 9 | ||||
-rw-r--r-- | app/mailers/emails/members.rb | 29 | ||||
-rw-r--r-- | app/models/ci/pipeline.rb | 6 | ||||
-rw-r--r-- | app/models/user.rb | 6 | ||||
-rw-r--r-- | app/services/ci/create_pipeline_service.rb | 3 |
14 files changed, 178 insertions, 199 deletions
diff --git a/app/assets/javascripts/editor/extensions/source_editor_markdown_ext.js b/app/assets/javascripts/editor/extensions/source_editor_markdown_ext.js index 57de21c933e..bec7fe7e25f 100644 --- a/app/assets/javascripts/editor/extensions/source_editor_markdown_ext.js +++ b/app/assets/javascripts/editor/extensions/source_editor_markdown_ext.js @@ -1,157 +1,6 @@ -import { debounce } from 'lodash'; -import { BLOB_PREVIEW_ERROR } from '~/blob_edit/constants'; -import createFlash from '~/flash'; -import { sanitize } from '~/lib/dompurify'; -import axios from '~/lib/utils/axios_utils'; -import { __ } from '~/locale'; -import syntaxHighlight from '~/syntax_highlight'; -import { - EXTENSION_MARKDOWN_PREVIEW_PANEL_CLASS, - EXTENSION_MARKDOWN_PREVIEW_ACTION_ID, - EXTENSION_MARKDOWN_PREVIEW_PANEL_WIDTH, - EXTENSION_MARKDOWN_PREVIEW_PANEL_PARENT_CLASS, - EXTENSION_MARKDOWN_PREVIEW_UPDATE_DELAY, -} from '../constants'; -import { SourceEditorExtension } from './source_editor_extension_base'; - -const getPreview = (text, previewMarkdownPath) => { - return axios - .post(previewMarkdownPath, { - text, - }) - .then(({ data }) => { - return data.body; - }); -}; - -const setupDomElement = ({ injectToEl = null } = {}) => { - const previewEl = document.createElement('div'); - previewEl.classList.add(EXTENSION_MARKDOWN_PREVIEW_PANEL_CLASS); - previewEl.style.display = 'none'; - if (injectToEl) { - injectToEl.appendChild(previewEl); - } - return previewEl; -}; - -export class EditorMarkdownExtension extends SourceEditorExtension { - constructor({ instance, previewMarkdownPath, ...args } = {}) { - super({ instance, ...args }); - Object.assign(instance, { - previewMarkdownPath, - preview: { - el: undefined, - action: undefined, - shown: false, - modelChangeListener: undefined, - }, - }); - this.setupPreviewAction.call(instance); - - instance.getModel().onDidChangeLanguage(({ newLanguage, oldLanguage } = {}) => { - if (newLanguage === 'markdown' && oldLanguage !== newLanguage) { - instance.setupPreviewAction(); - } else { - instance.cleanup(); - } - }); - - instance.onDidChangeModel(() => { - const model = instance.getModel(); - if (model) { - const { language } = model.getLanguageIdentifier(); - instance.cleanup(); - if (language === 'markdown') { - instance.setupPreviewAction(); - } - } - }); - } - - static togglePreviewLayout() { - const { width, height } = this.getLayoutInfo(); - const newWidth = this.preview.shown - ? width / EXTENSION_MARKDOWN_PREVIEW_PANEL_WIDTH - : width * EXTENSION_MARKDOWN_PREVIEW_PANEL_WIDTH; - this.layout({ width: newWidth, height }); - } - - static togglePreviewPanel() { - const parentEl = this.getDomNode().parentElement; - const { el: previewEl } = this.preview; - parentEl.classList.toggle(EXTENSION_MARKDOWN_PREVIEW_PANEL_PARENT_CLASS); - - if (previewEl.style.display === 'none') { - // Show the preview panel - this.fetchPreview(); - } else { - // Hide the preview panel - previewEl.style.display = 'none'; - } - } - - cleanup() { - if (this.preview.modelChangeListener) { - this.preview.modelChangeListener.dispose(); - } - this.preview.action.dispose(); - if (this.preview.shown) { - EditorMarkdownExtension.togglePreviewPanel.call(this); - EditorMarkdownExtension.togglePreviewLayout.call(this); - } - this.preview.shown = false; - } - - fetchPreview() { - const { el: previewEl } = this.preview; - getPreview(this.getValue(), this.previewMarkdownPath) - .then((data) => { - previewEl.innerHTML = sanitize(data); - syntaxHighlight(previewEl.querySelectorAll('.js-syntax-highlight')); - previewEl.style.display = 'block'; - }) - .catch(() => createFlash(BLOB_PREVIEW_ERROR)); - } - - setupPreviewAction() { - if (this.getAction(EXTENSION_MARKDOWN_PREVIEW_ACTION_ID)) return; - - this.preview.action = this.addAction({ - id: EXTENSION_MARKDOWN_PREVIEW_ACTION_ID, - label: __('Preview Markdown'), - keybindings: [ - // eslint-disable-next-line no-bitwise,no-undef - monaco.KeyMod.chord(monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.KEY_P), - ], - contextMenuGroupId: 'navigation', - contextMenuOrder: 1.5, - - // Method that will be executed when the action is triggered. - // @param ed The editor instance is passed in as a convenience - run(instance) { - instance.togglePreview(); - }, - }); - } - - togglePreview() { - if (!this.preview?.el) { - this.preview.el = setupDomElement({ injectToEl: this.getDomNode().parentElement }); - } - EditorMarkdownExtension.togglePreviewLayout.call(this); - EditorMarkdownExtension.togglePreviewPanel.call(this); - - if (!this.preview?.shown) { - this.preview.modelChangeListener = this.onDidChangeModelContent( - debounce(this.fetchPreview.bind(this), EXTENSION_MARKDOWN_PREVIEW_UPDATE_DELAY), - ); - } else { - this.preview.modelChangeListener.dispose(); - } - - this.preview.shown = !this.preview?.shown; - } +import { EditorMarkdownPreviewExtension } from '~/editor/extensions/source_editor_markdown_livepreview_ext'; +export class EditorMarkdownExtension extends EditorMarkdownPreviewExtension { getSelectedText(selection = this.getSelection()) { const { startLineNumber, endLineNumber, startColumn, endColumn } = selection; const valArray = this.getValue().split('\n'); diff --git a/app/assets/javascripts/editor/extensions/source_editor_markdown_livepreview_ext.js b/app/assets/javascripts/editor/extensions/source_editor_markdown_livepreview_ext.js new file mode 100644 index 00000000000..526de7f8932 --- /dev/null +++ b/app/assets/javascripts/editor/extensions/source_editor_markdown_livepreview_ext.js @@ -0,0 +1,154 @@ +import { debounce } from 'lodash'; +import { BLOB_PREVIEW_ERROR } from '~/blob_edit/constants'; +import createFlash from '~/flash'; +import { sanitize } from '~/lib/dompurify'; +import axios from '~/lib/utils/axios_utils'; +import { __ } from '~/locale'; +import syntaxHighlight from '~/syntax_highlight'; +import { + EXTENSION_MARKDOWN_PREVIEW_PANEL_CLASS, + EXTENSION_MARKDOWN_PREVIEW_ACTION_ID, + EXTENSION_MARKDOWN_PREVIEW_PANEL_WIDTH, + EXTENSION_MARKDOWN_PREVIEW_PANEL_PARENT_CLASS, + EXTENSION_MARKDOWN_PREVIEW_UPDATE_DELAY, +} from '../constants'; +import { SourceEditorExtension } from './source_editor_extension_base'; + +const getPreview = (text, previewMarkdownPath) => { + return axios + .post(previewMarkdownPath, { + text, + }) + .then(({ data }) => { + return data.body; + }); +}; + +const setupDomElement = ({ injectToEl = null } = {}) => { + const previewEl = document.createElement('div'); + previewEl.classList.add(EXTENSION_MARKDOWN_PREVIEW_PANEL_CLASS); + previewEl.style.display = 'none'; + if (injectToEl) { + injectToEl.appendChild(previewEl); + } + return previewEl; +}; + +export class EditorMarkdownPreviewExtension extends SourceEditorExtension { + constructor({ instance, previewMarkdownPath, ...args } = {}) { + super({ instance, ...args }); + Object.assign(instance, { + previewMarkdownPath, + preview: { + el: undefined, + action: undefined, + shown: false, + modelChangeListener: undefined, + }, + }); + this.setupPreviewAction.call(instance); + + instance.getModel().onDidChangeLanguage(({ newLanguage, oldLanguage } = {}) => { + if (newLanguage === 'markdown' && oldLanguage !== newLanguage) { + instance.setupPreviewAction(); + } else { + instance.cleanup(); + } + }); + + instance.onDidChangeModel(() => { + const model = instance.getModel(); + if (model) { + const { language } = model.getLanguageIdentifier(); + instance.cleanup(); + if (language === 'markdown') { + instance.setupPreviewAction(); + } + } + }); + } + + static togglePreviewLayout() { + const { width, height } = this.getLayoutInfo(); + const newWidth = this.preview.shown + ? width / EXTENSION_MARKDOWN_PREVIEW_PANEL_WIDTH + : width * EXTENSION_MARKDOWN_PREVIEW_PANEL_WIDTH; + this.layout({ width: newWidth, height }); + } + + static togglePreviewPanel() { + const parentEl = this.getDomNode().parentElement; + const { el: previewEl } = this.preview; + parentEl.classList.toggle(EXTENSION_MARKDOWN_PREVIEW_PANEL_PARENT_CLASS); + + if (previewEl.style.display === 'none') { + // Show the preview panel + this.fetchPreview(); + } else { + // Hide the preview panel + previewEl.style.display = 'none'; + } + } + + cleanup() { + if (this.preview.modelChangeListener) { + this.preview.modelChangeListener.dispose(); + } + this.preview.action.dispose(); + if (this.preview.shown) { + EditorMarkdownPreviewExtension.togglePreviewPanel.call(this); + EditorMarkdownPreviewExtension.togglePreviewLayout.call(this); + } + this.preview.shown = false; + } + + fetchPreview() { + const { el: previewEl } = this.preview; + getPreview(this.getValue(), this.previewMarkdownPath) + .then((data) => { + previewEl.innerHTML = sanitize(data); + syntaxHighlight(previewEl.querySelectorAll('.js-syntax-highlight')); + previewEl.style.display = 'block'; + }) + .catch(() => createFlash(BLOB_PREVIEW_ERROR)); + } + + setupPreviewAction() { + if (this.getAction(EXTENSION_MARKDOWN_PREVIEW_ACTION_ID)) return; + + this.preview.action = this.addAction({ + id: EXTENSION_MARKDOWN_PREVIEW_ACTION_ID, + label: __('Preview Markdown'), + keybindings: [ + // eslint-disable-next-line no-bitwise,no-undef + monaco.KeyMod.chord(monaco.KeyMod.CtrlCmd | monaco.KeyMod.Shift | monaco.KeyCode.KEY_P), + ], + contextMenuGroupId: 'navigation', + contextMenuOrder: 1.5, + + // Method that will be executed when the action is triggered. + // @param ed The editor instance is passed in as a convenience + run(instance) { + instance.togglePreview(); + }, + }); + } + + togglePreview() { + if (!this.preview?.el) { + this.preview.el = setupDomElement({ injectToEl: this.getDomNode().parentElement }); + } + EditorMarkdownPreviewExtension.togglePreviewLayout.call(this); + EditorMarkdownPreviewExtension.togglePreviewPanel.call(this); + + if (!this.preview?.shown) { + this.preview.modelChangeListener = this.onDidChangeModelContent( + debounce(this.fetchPreview.bind(this), EXTENSION_MARKDOWN_PREVIEW_UPDATE_DELAY), + ); + } else { + this.preview.modelChangeListener.dispose(); + } + + this.preview.shown = !this.preview?.shown; + } +} diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue index d15619a78b0..ba831a33b73 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/work_in_progress.vue @@ -165,7 +165,7 @@ export default { <div class="mr-widget-body media"> <status-icon :show-disabled-button="canUpdate" status="warning" /> <div class="media-body"> - <div class="gl-ml-3 float-left"> + <div class="float-left"> <span class="gl-font-weight-bold"> {{ __("Merge blocked: merge request must be marked as ready. It's still marked as draft.") diff --git a/app/assets/javascripts/vue_merge_request_widget/constants.js b/app/assets/javascripts/vue_merge_request_widget/constants.js index 19ac198964a..2edccce7f4e 100644 --- a/app/assets/javascripts/vue_merge_request_widget/constants.js +++ b/app/assets/javascripts/vue_merge_request_widget/constants.js @@ -158,4 +158,7 @@ export const EXTENSION_ICON_CLASS = { severityUnknown: 'gl-text-gray-400', }; +export const EXTENSION_SUMMARY_FAILED_CLASS = 'gl-text-red-500'; +export const EXTENSION_SUMMARY_NEUTRAL_CLASS = 'gl-text-gray-700'; + export { STATE_MACHINE }; diff --git a/app/assets/javascripts/vue_shared/components/file_row.vue b/app/assets/javascripts/vue_shared/components/file_row.vue index 0b0a416b7ef..2227047a909 100644 --- a/app/assets/javascripts/vue_shared/components/file_row.vue +++ b/app/assets/javascripts/vue_shared/components/file_row.vue @@ -146,6 +146,7 @@ export default { ref="textOutput" :style="levelIndentation" class="file-row-name" + :title="file.name" data-qa-selector="file_name_content" :data-qa-file-name="file.name" data-testid="file-row-name-container" diff --git a/app/controllers/concerns/one_trust_csp.rb b/app/controllers/concerns/one_trust_csp.rb index fbd44f52590..cd35eeb587c 100644 --- a/app/controllers/concerns/one_trust_csp.rb +++ b/app/controllers/concerns/one_trust_csp.rb @@ -8,11 +8,11 @@ module OneTrustCSP next unless helpers.one_trust_enabled? || policy.directives.present? default_script_src = policy.directives['script-src'] || policy.directives['default-src'] - script_src_values = Array.wrap(default_script_src) | ["'unsafe-eval'", 'https://cdn.cookielaw.org https://*.onetrust.com'] + script_src_values = Array.wrap(default_script_src) | ["'unsafe-eval'", 'https://cdn.cookielaw.org', 'https://*.onetrust.com'] policy.script_src(*script_src_values) default_connect_src = policy.directives['connect-src'] || policy.directives['default-src'] - connect_src_values = Array.wrap(default_connect_src) | ['https://cdn.cookielaw.org'] + connect_src_values = Array.wrap(default_connect_src) | ['https://cdn.cookielaw.org', 'https://*.onetrust.com'] policy.connect_src(*connect_src_values) end end diff --git a/app/controllers/invites_controller.rb b/app/controllers/invites_controller.rb index d4b1306cc5e..eb89fe58cc0 100644 --- a/app/controllers/invites_controller.rb +++ b/app/controllers/invites_controller.rb @@ -79,8 +79,6 @@ class InvitesController < ApplicationController if params[:experiment_name] == 'invite_email_preview_text' experiment(:invite_email_preview_text, actor: member).track(:join_clicked) - elsif params[:experiment_name] == 'invite_email_from' - experiment(:invite_email_from, actor: member).track(:join_clicked) end Gitlab::Tracking.event(self.class.name, 'join_clicked', label: 'invite_email', property: member.id.to_s) diff --git a/app/controllers/projects/tree_controller.rb b/app/controllers/projects/tree_controller.rb index f8f2c1f0836..660ebcc30d3 100644 --- a/app/controllers/projects/tree_controller.rb +++ b/app/controllers/projects/tree_controller.rb @@ -60,3 +60,5 @@ class Projects::TreeController < Projects::ApplicationController } end end + +Projects::TreeController.prepend_mod diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 450c12a233b..6dc5cf57a9e 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -212,7 +212,6 @@ class RegistrationsController < Devise::RegistrationsController experiment_name = session.delete(:invite_email_experiment_name) experiment(:invite_email_preview_text, actor: member).track(:accepted) if experiment_name == 'invite_email_preview_text' - experiment(:invite_email_from, actor: member).track(:accepted) if experiment_name == 'invite_email_from' Gitlab::Tracking.event(self.class.name, 'accepted', label: 'invite_email', property: member.id.to_s) end diff --git a/app/helpers/notify_helper.rb b/app/helpers/notify_helper.rb index ed96f3cef4f..da42740f993 100644 --- a/app/helpers/notify_helper.rb +++ b/app/helpers/notify_helper.rb @@ -24,14 +24,7 @@ module NotifyHelper def invited_join_url(token, member) additional_params = { invite_type: Emails::Members::INITIAL_INVITE } - # order important below to our scheduled testing of these - # `from` experiment will be after the `text` on, but we may not cleanup - # from the `text` one by the time we run the `from` experiment, - # therefore we want to support `text` being fully enabled - # but if `from` is also enabled, then we only care about `from` - if experiment(:invite_email_from, actor: member).enabled? - additional_params[:experiment_name] = 'invite_email_from' - elsif experiment(:invite_email_preview_text, actor: member).enabled? + if experiment(:invite_email_preview_text, actor: member).enabled? additional_params[:experiment_name] = 'invite_email_preview_text' end diff --git a/app/mailers/emails/members.rb b/app/mailers/emails/members.rb index 8a9ed557cc6..ef2220751bf 100644 --- a/app/mailers/emails/members.rb +++ b/app/mailers/emails/members.rb @@ -61,7 +61,7 @@ module Emails Gitlab::Tracking.event(self.class.name, 'invite_email_sent', label: 'invite_email', property: member_id.to_s) - mail(to: member.invite_email, subject: invite_email_subject, **invite_email_headers.merge(additional_invite_settings)) do |format| + mail(to: member.invite_email, subject: invite_email_subject, **invite_email_headers) do |format| format.html { render layout: 'unknown_user_mailer' } format.text { render layout: 'unknown_user_mailer' } end @@ -151,17 +151,7 @@ module Emails def invite_email_subject if member.created_by - experiment(:invite_email_from, actor: member) do |experiment_instance| - experiment_instance.use do - subject(s_("MemberInviteEmail|%{member_name} invited you to join GitLab") % { member_name: member.created_by.name }) - end - - experiment_instance.candidate do - subject(s_("MemberInviteEmail|I've invited you to join me in GitLab")) - end - - experiment_instance.run - end + subject(s_("MemberInviteEmail|%{member_name} invited you to join GitLab") % { member_name: member.created_by.name }) else subject(s_("MemberInviteEmail|Invitation to join the %{project_or_group} %{project_or_group_name}") % { project_or_group: member_source.human_name, project_or_group_name: member_source.model_name.singular }) end @@ -178,21 +168,6 @@ module Emails end end - def additional_invite_settings - return {} unless member.created_by - - experiment(:invite_email_from, actor: member) do |experiment_instance| - experiment_instance.use { {} } - experiment_instance.candidate do - { - from: "#{member.created_by.name} <#{member.created_by.email}>" - } - end - - experiment_instance.run - end - end - def member_exists? Gitlab::AppLogger.info("Tried to send an email invitation for a deleted group. Member id: #{@member_id}") if member.blank? member.present? diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb index a18b760eeb4..6a924c1b576 100644 --- a/app/models/ci/pipeline.rb +++ b/app/models/ci/pipeline.rb @@ -1287,6 +1287,12 @@ module Ci end end + def create_deployment_in_separate_transaction? + strong_memoize(:create_deployment_in_separate_transaction) do + ::Feature.enabled?(:create_deployment_in_separate_transaction, project, default_enabled: :yaml) + end + end + private def add_message(severity, content) diff --git a/app/models/user.rb b/app/models/user.rb index 0435e872c22..5ecf5edb12f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -993,11 +993,7 @@ class User < ApplicationRecord # Returns the groups a user is a member of, either directly or through a parent group def membership_groups - if Feature.enabled?(:linear_user_membership_groups, self, default_enabled: :yaml) - groups.self_and_descendants - else - Gitlab::ObjectHierarchy.new(groups).base_and_descendants - end + groups.self_and_descendants end # Returns a relation of groups the user has access to, including their parent diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb index 0548566c271..c1f35afba40 100644 --- a/app/services/ci/create_pipeline_service.rb +++ b/app/services/ci/create_pipeline_service.rb @@ -28,7 +28,10 @@ module Ci Gitlab::Ci::Pipeline::Chain::Validate::External, Gitlab::Ci::Pipeline::Chain::Populate, Gitlab::Ci::Pipeline::Chain::StopDryRun, + Gitlab::Ci::Pipeline::Chain::EnsureEnvironments, + Gitlab::Ci::Pipeline::Chain::EnsureResourceGroups, Gitlab::Ci::Pipeline::Chain::Create, + Gitlab::Ci::Pipeline::Chain::CreateDeployments, Gitlab::Ci::Pipeline::Chain::CreateCrossDatabaseAssociations, Gitlab::Ci::Pipeline::Chain::Limit::Activity, Gitlab::Ci::Pipeline::Chain::Limit::JobActivity, |