diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-29 12:10:13 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-04-29 12:10:13 +0000 |
commit | 4ef4c552f3b1a5c25ec716f0f2c4e3c92a078e2b (patch) | |
tree | f2b8ca0c0d2e342ada86aed7f00a1647c838c45a | |
parent | 7510fe06eba02c3cee247f8ceb4ee6f6a4de54f6 (diff) | |
download | gitlab-ce-4ef4c552f3b1a5c25ec716f0f2c4e3c92a078e2b.tar.gz |
Add latest changes from gitlab-org/gitlab@master
48 files changed, 506 insertions, 36 deletions
diff --git a/app/assets/javascripts/content_editor/components/bubble_menus/code_block.vue b/app/assets/javascripts/content_editor/components/bubble_menus/code_block.vue index e467053cd73..c42f06664cc 100644 --- a/app/assets/javascripts/content_editor/components/bubble_menus/code_block.vue +++ b/app/assets/javascripts/content_editor/components/bubble_menus/code_block.vue @@ -77,19 +77,11 @@ export default { this.tiptapEditor.commands.setCodeBlock({ language: this.selectedLanguage.syntax }); }, - tippyOnBeforeUpdate(tippy, props) { - if (props.getReferenceClientRect) { - // eslint-disable-next-line no-param-reassign - props.getReferenceClientRect = () => { - const { view } = this.tiptapEditor; - const { from } = this.tiptapEditor.state.selection; - - const node = getParentByTagName(view.domAtPos(from).node, 'pre'); - if (node) return node.getBoundingClientRect(); - - return new DOMRect(-1000, -1000, 0, 0); - }; - } + getReferenceClientRect() { + const { view } = this.tiptapEditor; + const { from } = this.tiptapEditor.state.selection; + const node = getParentByTagName(view.domAtPos(from).node, 'pre'); + return node?.getBoundingClientRect() || new DOMRect(-1000, -1000, 0, 0); }, deleteCodeBlock() { @@ -105,7 +97,7 @@ export default { :editor="tiptapEditor" plugin-key="bubbleMenuCodeBlock" :should-show="shouldShow" - :tippy-options="{ onBeforeUpdate: tippyOnBeforeUpdate }" + :tippy-options="{ getReferenceClientRect }" > <editor-state-observer @transaction="updateSelectedLanguage"> <gl-button-group> diff --git a/app/assets/javascripts/content_editor/services/code_block_language_loader.js b/app/assets/javascripts/content_editor/services/code_block_language_loader.js index 74018d7e1e3..0d5a8c91907 100644 --- a/app/assets/javascripts/content_editor/services/code_block_language_loader.js +++ b/app/assets/javascripts/content_editor/services/code_block_language_loader.js @@ -1,6 +1,7 @@ import { lowlight } from 'lowlight/lib/core'; import { __, sprintf } from '~/locale'; import CODE_BLOCK_LANGUAGES from '../constants/code_block_languages'; +import languageLoader from './highlight_js_language_loader'; const codeBlockLanguageLoader = { lowlight, @@ -46,11 +47,11 @@ const codeBlockLanguageLoader = { loadLanguages(languageList = []) { const loaders = languageList - .filter((languageName) => !this.isLanguageLoaded(languageName)) + .filter( + (languageName) => !this.isLanguageLoaded(languageName) && languageName in languageLoader, + ) .map((languageName) => { - return import( - /* webpackChunkName: 'highlight.language.js' */ `highlight.js/lib/languages/${languageName}` - ) + return languageLoader[languageName]() .then(({ default: language }) => { this.lowlight.registerLanguage(languageName, language); }) diff --git a/app/assets/javascripts/content_editor/services/highlight_js_language_loader.js b/app/assets/javascripts/content_editor/services/highlight_js_language_loader.js new file mode 100644 index 00000000000..a0ebbebed4e --- /dev/null +++ b/app/assets/javascripts/content_editor/services/highlight_js_language_loader.js @@ -0,0 +1,248 @@ +/** + * This file is generated based on the contents of highlight.js/lib/languages to avoid + * utilizing dynamic expressions within `import()` which were the source of some + * confusion when attempting to produce deterministic webpack compilations across + * multiple build environments. + * + * This list of highlight-able languages will need to be updated as new options are + * introduced within the highlight.js dependency. + */ + +export default { + '1c': () => import(/* webpackChunkName: 'hl-1c' */ 'highlight.js/lib/languages/1c'), + abnf: () => import(/* webpackChunkName: 'hl-abnf' */ 'highlight.js/lib/languages/abnf'), + accesslog: () => + import(/* webpackChunkName: 'hl-accesslog' */ 'highlight.js/lib/languages/accesslog'), + actionscript: () => + import(/* webpackChunkName: 'hl-actionscript' */ 'highlight.js/lib/languages/actionscript'), + ada: () => import(/* webpackChunkName: 'hl-ada' */ 'highlight.js/lib/languages/ada'), + angelscript: () => + import(/* webpackChunkName: 'hl-angelscript' */ 'highlight.js/lib/languages/angelscript'), + apache: () => import(/* webpackChunkName: 'hl-apache' */ 'highlight.js/lib/languages/apache'), + applescript: () => + import(/* webpackChunkName: 'hl-applescript' */ 'highlight.js/lib/languages/applescript'), + arcade: () => import(/* webpackChunkName: 'hl-arcade' */ 'highlight.js/lib/languages/arcade'), + arduino: () => import(/* webpackChunkName: 'hl-arduino' */ 'highlight.js/lib/languages/arduino'), + armasm: () => import(/* webpackChunkName: 'hl-armasm' */ 'highlight.js/lib/languages/armasm'), + asciidoc: () => + import(/* webpackChunkName: 'hl-asciidoc' */ 'highlight.js/lib/languages/asciidoc'), + aspectj: () => import(/* webpackChunkName: 'hl-aspectj' */ 'highlight.js/lib/languages/aspectj'), + autohotkey: () => + import(/* webpackChunkName: 'hl-autohotkey' */ 'highlight.js/lib/languages/autohotkey'), + autoit: () => import(/* webpackChunkName: 'hl-autoit' */ 'highlight.js/lib/languages/autoit'), + avrasm: () => import(/* webpackChunkName: 'hl-avrasm' */ 'highlight.js/lib/languages/avrasm'), + awk: () => import(/* webpackChunkName: 'hl-awk' */ 'highlight.js/lib/languages/awk'), + axapta: () => import(/* webpackChunkName: 'hl-axapta' */ 'highlight.js/lib/languages/axapta'), + bash: () => import(/* webpackChunkName: 'hl-bash' */ 'highlight.js/lib/languages/bash'), + basic: () => import(/* webpackChunkName: 'hl-basic' */ 'highlight.js/lib/languages/basic'), + bnf: () => import(/* webpackChunkName: 'hl-bnf' */ 'highlight.js/lib/languages/bnf'), + brainfuck: () => + import(/* webpackChunkName: 'hl-brainfuck' */ 'highlight.js/lib/languages/brainfuck'), + c: () => import(/* webpackChunkName: 'hl-c' */ 'highlight.js/lib/languages/c'), + cal: () => import(/* webpackChunkName: 'hl-cal' */ 'highlight.js/lib/languages/cal'), + capnproto: () => + import(/* webpackChunkName: 'hl-capnproto' */ 'highlight.js/lib/languages/capnproto'), + ceylon: () => import(/* webpackChunkName: 'hl-ceylon' */ 'highlight.js/lib/languages/ceylon'), + clean: () => import(/* webpackChunkName: 'hl-clean' */ 'highlight.js/lib/languages/clean'), + 'clojure-repl': () => + import(/* webpackChunkName: 'hl-clojure-repl' */ 'highlight.js/lib/languages/clojure-repl'), + clojure: () => import(/* webpackChunkName: 'hl-clojure' */ 'highlight.js/lib/languages/clojure'), + cmake: () => import(/* webpackChunkName: 'hl-cmake' */ 'highlight.js/lib/languages/cmake'), + coffeescript: () => + import(/* webpackChunkName: 'hl-coffeescript' */ 'highlight.js/lib/languages/coffeescript'), + coq: () => import(/* webpackChunkName: 'hl-coq' */ 'highlight.js/lib/languages/coq'), + cos: () => import(/* webpackChunkName: 'hl-cos' */ 'highlight.js/lib/languages/cos'), + cpp: () => import(/* webpackChunkName: 'hl-cpp' */ 'highlight.js/lib/languages/cpp'), + crmsh: () => import(/* webpackChunkName: 'hl-crmsh' */ 'highlight.js/lib/languages/crmsh'), + crystal: () => import(/* webpackChunkName: 'hl-crystal' */ 'highlight.js/lib/languages/crystal'), + csharp: () => import(/* webpackChunkName: 'hl-csharp' */ 'highlight.js/lib/languages/csharp'), + csp: () => import(/* webpackChunkName: 'hl-csp' */ 'highlight.js/lib/languages/csp'), + css: () => import(/* webpackChunkName: 'hl-css' */ 'highlight.js/lib/languages/css'), + d: () => import(/* webpackChunkName: 'hl-d' */ 'highlight.js/lib/languages/d'), + dart: () => import(/* webpackChunkName: 'hl-dart' */ 'highlight.js/lib/languages/dart'), + delphi: () => import(/* webpackChunkName: 'hl-delphi' */ 'highlight.js/lib/languages/delphi'), + diff: () => import(/* webpackChunkName: 'hl-diff' */ 'highlight.js/lib/languages/diff'), + django: () => import(/* webpackChunkName: 'hl-django' */ 'highlight.js/lib/languages/django'), + dns: () => import(/* webpackChunkName: 'hl-dns' */ 'highlight.js/lib/languages/dns'), + dockerfile: () => + import(/* webpackChunkName: 'hl-dockerfile' */ 'highlight.js/lib/languages/dockerfile'), + dos: () => import(/* webpackChunkName: 'hl-dos' */ 'highlight.js/lib/languages/dos'), + dsconfig: () => + import(/* webpackChunkName: 'hl-dsconfig' */ 'highlight.js/lib/languages/dsconfig'), + dts: () => import(/* webpackChunkName: 'hl-dts' */ 'highlight.js/lib/languages/dts'), + dust: () => import(/* webpackChunkName: 'hl-dust' */ 'highlight.js/lib/languages/dust'), + ebnf: () => import(/* webpackChunkName: 'hl-ebnf' */ 'highlight.js/lib/languages/ebnf'), + elixir: () => import(/* webpackChunkName: 'hl-elixir' */ 'highlight.js/lib/languages/elixir'), + elm: () => import(/* webpackChunkName: 'hl-elm' */ 'highlight.js/lib/languages/elm'), + erb: () => import(/* webpackChunkName: 'hl-erb' */ 'highlight.js/lib/languages/erb'), + 'erlang-repl': () => + import(/* webpackChunkName: 'hl-erlang-repl' */ 'highlight.js/lib/languages/erlang-repl'), + erlang: () => import(/* webpackChunkName: 'hl-erlang' */ 'highlight.js/lib/languages/erlang'), + excel: () => import(/* webpackChunkName: 'hl-excel' */ 'highlight.js/lib/languages/excel'), + fix: () => import(/* webpackChunkName: 'hl-fix' */ 'highlight.js/lib/languages/fix'), + flix: () => import(/* webpackChunkName: 'hl-flix' */ 'highlight.js/lib/languages/flix'), + fortran: () => import(/* webpackChunkName: 'hl-fortran' */ 'highlight.js/lib/languages/fortran'), + fsharp: () => import(/* webpackChunkName: 'hl-fsharp' */ 'highlight.js/lib/languages/fsharp'), + gams: () => import(/* webpackChunkName: 'hl-gams' */ 'highlight.js/lib/languages/gams'), + gauss: () => import(/* webpackChunkName: 'hl-gauss' */ 'highlight.js/lib/languages/gauss'), + gcode: () => import(/* webpackChunkName: 'hl-gcode' */ 'highlight.js/lib/languages/gcode'), + gherkin: () => import(/* webpackChunkName: 'hl-gherkin' */ 'highlight.js/lib/languages/gherkin'), + glsl: () => import(/* webpackChunkName: 'hl-glsl' */ 'highlight.js/lib/languages/glsl'), + gml: () => import(/* webpackChunkName: 'hl-gml' */ 'highlight.js/lib/languages/gml'), + go: () => import(/* webpackChunkName: 'hl-go' */ 'highlight.js/lib/languages/go'), + golo: () => import(/* webpackChunkName: 'hl-golo' */ 'highlight.js/lib/languages/golo'), + gradle: () => import(/* webpackChunkName: 'hl-gradle' */ 'highlight.js/lib/languages/gradle'), + groovy: () => import(/* webpackChunkName: 'hl-groovy' */ 'highlight.js/lib/languages/groovy'), + haml: () => import(/* webpackChunkName: 'hl-haml' */ 'highlight.js/lib/languages/haml'), + handlebars: () => + import(/* webpackChunkName: 'hl-handlebars' */ 'highlight.js/lib/languages/handlebars'), + haskell: () => import(/* webpackChunkName: 'hl-haskell' */ 'highlight.js/lib/languages/haskell'), + haxe: () => import(/* webpackChunkName: 'hl-haxe' */ 'highlight.js/lib/languages/haxe'), + hsp: () => import(/* webpackChunkName: 'hl-hsp' */ 'highlight.js/lib/languages/hsp'), + http: () => import(/* webpackChunkName: 'hl-http' */ 'highlight.js/lib/languages/http'), + hy: () => import(/* webpackChunkName: 'hl-hy' */ 'highlight.js/lib/languages/hy'), + inform7: () => import(/* webpackChunkName: 'hl-inform7' */ 'highlight.js/lib/languages/inform7'), + ini: () => import(/* webpackChunkName: 'hl-ini' */ 'highlight.js/lib/languages/ini'), + irpf90: () => import(/* webpackChunkName: 'hl-irpf90' */ 'highlight.js/lib/languages/irpf90'), + isbl: () => import(/* webpackChunkName: 'hl-isbl' */ 'highlight.js/lib/languages/isbl'), + java: () => import(/* webpackChunkName: 'hl-java' */ 'highlight.js/lib/languages/java'), + javascript: () => + import(/* webpackChunkName: 'hl-javascript' */ 'highlight.js/lib/languages/javascript'), + 'jboss-cli': () => + import(/* webpackChunkName: 'hl-jboss-cli' */ 'highlight.js/lib/languages/jboss-cli'), + json: () => import(/* webpackChunkName: 'hl-json' */ 'highlight.js/lib/languages/json'), + 'julia-repl': () => + import(/* webpackChunkName: 'hl-julia-repl' */ 'highlight.js/lib/languages/julia-repl'), + julia: () => import(/* webpackChunkName: 'hl-julia' */ 'highlight.js/lib/languages/julia'), + kotlin: () => import(/* webpackChunkName: 'hl-kotlin' */ 'highlight.js/lib/languages/kotlin'), + lasso: () => import(/* webpackChunkName: 'hl-lasso' */ 'highlight.js/lib/languages/lasso'), + latex: () => import(/* webpackChunkName: 'hl-latex' */ 'highlight.js/lib/languages/latex'), + ldif: () => import(/* webpackChunkName: 'hl-ldif' */ 'highlight.js/lib/languages/ldif'), + leaf: () => import(/* webpackChunkName: 'hl-leaf' */ 'highlight.js/lib/languages/leaf'), + less: () => import(/* webpackChunkName: 'hl-less' */ 'highlight.js/lib/languages/less'), + lisp: () => import(/* webpackChunkName: 'hl-lisp' */ 'highlight.js/lib/languages/lisp'), + livecodeserver: () => + import(/* webpackChunkName: 'hl-livecodeserver' */ 'highlight.js/lib/languages/livecodeserver'), + livescript: () => + import(/* webpackChunkName: 'hl-livescript' */ 'highlight.js/lib/languages/livescript'), + llvm: () => import(/* webpackChunkName: 'hl-llvm' */ 'highlight.js/lib/languages/llvm'), + lsl: () => import(/* webpackChunkName: 'hl-lsl' */ 'highlight.js/lib/languages/lsl'), + lua: () => import(/* webpackChunkName: 'hl-lua' */ 'highlight.js/lib/languages/lua'), + makefile: () => + import(/* webpackChunkName: 'hl-makefile' */ 'highlight.js/lib/languages/makefile'), + markdown: () => + import(/* webpackChunkName: 'hl-markdown' */ 'highlight.js/lib/languages/markdown'), + mathematica: () => + import(/* webpackChunkName: 'hl-mathematica' */ 'highlight.js/lib/languages/mathematica'), + matlab: () => import(/* webpackChunkName: 'hl-matlab' */ 'highlight.js/lib/languages/matlab'), + maxima: () => import(/* webpackChunkName: 'hl-maxima' */ 'highlight.js/lib/languages/maxima'), + mel: () => import(/* webpackChunkName: 'hl-mel' */ 'highlight.js/lib/languages/mel'), + mercury: () => import(/* webpackChunkName: 'hl-mercury' */ 'highlight.js/lib/languages/mercury'), + mipsasm: () => import(/* webpackChunkName: 'hl-mipsasm' */ 'highlight.js/lib/languages/mipsasm'), + mizar: () => import(/* webpackChunkName: 'hl-mizar' */ 'highlight.js/lib/languages/mizar'), + mojolicious: () => + import(/* webpackChunkName: 'hl-mojolicious' */ 'highlight.js/lib/languages/mojolicious'), + monkey: () => import(/* webpackChunkName: 'hl-monkey' */ 'highlight.js/lib/languages/monkey'), + moonscript: () => + import(/* webpackChunkName: 'hl-moonscript' */ 'highlight.js/lib/languages/moonscript'), + n1ql: () => import(/* webpackChunkName: 'hl-n1ql' */ 'highlight.js/lib/languages/n1ql'), + nestedtext: () => + import(/* webpackChunkName: 'hl-nestedtext' */ 'highlight.js/lib/languages/nestedtext'), + nginx: () => import(/* webpackChunkName: 'hl-nginx' */ 'highlight.js/lib/languages/nginx'), + nim: () => import(/* webpackChunkName: 'hl-nim' */ 'highlight.js/lib/languages/nim'), + nix: () => import(/* webpackChunkName: 'hl-nix' */ 'highlight.js/lib/languages/nix'), + 'node-repl': () => + import(/* webpackChunkName: 'hl-node-repl' */ 'highlight.js/lib/languages/node-repl'), + nsis: () => import(/* webpackChunkName: 'hl-nsis' */ 'highlight.js/lib/languages/nsis'), + objectivec: () => + import(/* webpackChunkName: 'hl-objectivec' */ 'highlight.js/lib/languages/objectivec'), + ocaml: () => import(/* webpackChunkName: 'hl-ocaml' */ 'highlight.js/lib/languages/ocaml'), + openscad: () => + import(/* webpackChunkName: 'hl-openscad' */ 'highlight.js/lib/languages/openscad'), + oxygene: () => import(/* webpackChunkName: 'hl-oxygene' */ 'highlight.js/lib/languages/oxygene'), + parser3: () => import(/* webpackChunkName: 'hl-parser3' */ 'highlight.js/lib/languages/parser3'), + perl: () => import(/* webpackChunkName: 'hl-perl' */ 'highlight.js/lib/languages/perl'), + pf: () => import(/* webpackChunkName: 'hl-pf' */ 'highlight.js/lib/languages/pf'), + pgsql: () => import(/* webpackChunkName: 'hl-pgsql' */ 'highlight.js/lib/languages/pgsql'), + 'php-template': () => + import(/* webpackChunkName: 'hl-php-template' */ 'highlight.js/lib/languages/php-template'), + php: () => import(/* webpackChunkName: 'hl-php' */ 'highlight.js/lib/languages/php'), + plaintext: () => + import(/* webpackChunkName: 'hl-plaintext' */ 'highlight.js/lib/languages/plaintext'), + pony: () => import(/* webpackChunkName: 'hl-pony' */ 'highlight.js/lib/languages/pony'), + powershell: () => + import(/* webpackChunkName: 'hl-powershell' */ 'highlight.js/lib/languages/powershell'), + processing: () => + import(/* webpackChunkName: 'hl-processing' */ 'highlight.js/lib/languages/processing'), + profile: () => import(/* webpackChunkName: 'hl-profile' */ 'highlight.js/lib/languages/profile'), + prolog: () => import(/* webpackChunkName: 'hl-prolog' */ 'highlight.js/lib/languages/prolog'), + properties: () => + import(/* webpackChunkName: 'hl-properties' */ 'highlight.js/lib/languages/properties'), + protobuf: () => + import(/* webpackChunkName: 'hl-protobuf' */ 'highlight.js/lib/languages/protobuf'), + puppet: () => import(/* webpackChunkName: 'hl-puppet' */ 'highlight.js/lib/languages/puppet'), + purebasic: () => + import(/* webpackChunkName: 'hl-purebasic' */ 'highlight.js/lib/languages/purebasic'), + 'python-repl': () => + import(/* webpackChunkName: 'hl-python-repl' */ 'highlight.js/lib/languages/python-repl'), + python: () => import(/* webpackChunkName: 'hl-python' */ 'highlight.js/lib/languages/python'), + q: () => import(/* webpackChunkName: 'hl-q' */ 'highlight.js/lib/languages/q'), + qml: () => import(/* webpackChunkName: 'hl-qml' */ 'highlight.js/lib/languages/qml'), + r: () => import(/* webpackChunkName: 'hl-r' */ 'highlight.js/lib/languages/r'), + reasonml: () => + import(/* webpackChunkName: 'hl-reasonml' */ 'highlight.js/lib/languages/reasonml'), + rib: () => import(/* webpackChunkName: 'hl-rib' */ 'highlight.js/lib/languages/rib'), + roboconf: () => + import(/* webpackChunkName: 'hl-roboconf' */ 'highlight.js/lib/languages/roboconf'), + routeros: () => + import(/* webpackChunkName: 'hl-routeros' */ 'highlight.js/lib/languages/routeros'), + rsl: () => import(/* webpackChunkName: 'hl-rsl' */ 'highlight.js/lib/languages/rsl'), + ruby: () => import(/* webpackChunkName: 'hl-ruby' */ 'highlight.js/lib/languages/ruby'), + ruleslanguage: () => + import(/* webpackChunkName: 'hl-ruleslanguage' */ 'highlight.js/lib/languages/ruleslanguage'), + rust: () => import(/* webpackChunkName: 'hl-rust' */ 'highlight.js/lib/languages/rust'), + sas: () => import(/* webpackChunkName: 'hl-sas' */ 'highlight.js/lib/languages/sas'), + scala: () => import(/* webpackChunkName: 'hl-scala' */ 'highlight.js/lib/languages/scala'), + scheme: () => import(/* webpackChunkName: 'hl-scheme' */ 'highlight.js/lib/languages/scheme'), + scilab: () => import(/* webpackChunkName: 'hl-scilab' */ 'highlight.js/lib/languages/scilab'), + scss: () => import(/* webpackChunkName: 'hl-scss' */ 'highlight.js/lib/languages/scss'), + shell: () => import(/* webpackChunkName: 'hl-shell' */ 'highlight.js/lib/languages/shell'), + smali: () => import(/* webpackChunkName: 'hl-smali' */ 'highlight.js/lib/languages/smali'), + smalltalk: () => + import(/* webpackChunkName: 'hl-smalltalk' */ 'highlight.js/lib/languages/smalltalk'), + sml: () => import(/* webpackChunkName: 'hl-sml' */ 'highlight.js/lib/languages/sml'), + sqf: () => import(/* webpackChunkName: 'hl-sqf' */ 'highlight.js/lib/languages/sqf'), + sql: () => import(/* webpackChunkName: 'hl-sql' */ 'highlight.js/lib/languages/sql'), + stan: () => import(/* webpackChunkName: 'hl-stan' */ 'highlight.js/lib/languages/stan'), + stata: () => import(/* webpackChunkName: 'hl-stata' */ 'highlight.js/lib/languages/stata'), + step21: () => import(/* webpackChunkName: 'hl-step21' */ 'highlight.js/lib/languages/step21'), + stylus: () => import(/* webpackChunkName: 'hl-stylus' */ 'highlight.js/lib/languages/stylus'), + subunit: () => import(/* webpackChunkName: 'hl-subunit' */ 'highlight.js/lib/languages/subunit'), + swift: () => import(/* webpackChunkName: 'hl-swift' */ 'highlight.js/lib/languages/swift'), + taggerscript: () => + import(/* webpackChunkName: 'hl-taggerscript' */ 'highlight.js/lib/languages/taggerscript'), + tap: () => import(/* webpackChunkName: 'hl-tap' */ 'highlight.js/lib/languages/tap'), + tcl: () => import(/* webpackChunkName: 'hl-tcl' */ 'highlight.js/lib/languages/tcl'), + thrift: () => import(/* webpackChunkName: 'hl-thrift' */ 'highlight.js/lib/languages/thrift'), + tp: () => import(/* webpackChunkName: 'hl-tp' */ 'highlight.js/lib/languages/tp'), + twig: () => import(/* webpackChunkName: 'hl-twig' */ 'highlight.js/lib/languages/twig'), + typescript: () => + import(/* webpackChunkName: 'hl-typescript' */ 'highlight.js/lib/languages/typescript'), + vala: () => import(/* webpackChunkName: 'hl-vala' */ 'highlight.js/lib/languages/vala'), + vbnet: () => import(/* webpackChunkName: 'hl-vbnet' */ 'highlight.js/lib/languages/vbnet'), + 'vbscript-html': () => + import(/* webpackChunkName: 'hl-vbscript-html' */ 'highlight.js/lib/languages/vbscript-html'), + vbscript: () => + import(/* webpackChunkName: 'hl-vbscript' */ 'highlight.js/lib/languages/vbscript'), + verilog: () => import(/* webpackChunkName: 'hl-verilog' */ 'highlight.js/lib/languages/verilog'), + vhdl: () => import(/* webpackChunkName: 'hl-vhdl' */ 'highlight.js/lib/languages/vhdl'), + vim: () => import(/* webpackChunkName: 'hl-vim' */ 'highlight.js/lib/languages/vim'), + wasm: () => import(/* webpackChunkName: 'hl-wasm' */ 'highlight.js/lib/languages/wasm'), + wren: () => import(/* webpackChunkName: 'hl-wren' */ 'highlight.js/lib/languages/wren'), + x86asm: () => import(/* webpackChunkName: 'hl-x86asm' */ 'highlight.js/lib/languages/x86asm'), + xl: () => import(/* webpackChunkName: 'hl-xl' */ 'highlight.js/lib/languages/xl'), + xml: () => import(/* webpackChunkName: 'hl-xml' */ 'highlight.js/lib/languages/xml'), + xquery: () => import(/* webpackChunkName: 'hl-xquery' */ 'highlight.js/lib/languages/xquery'), + yaml: () => import(/* webpackChunkName: 'hl-yaml' */ 'highlight.js/lib/languages/yaml'), + zephir: () => import(/* webpackChunkName: 'hl-zephir' */ 'highlight.js/lib/languages/zephir'), +}; diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue index 722df3cc58b..765bd146a03 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/field.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue @@ -111,6 +111,16 @@ export default { required: false, default: false, }, + showCommentToolBar: { + type: Boolean, + required: false, + default: true, + }, + restrictedToolBarItems: { + type: Array, + required: false, + default: () => [], + }, }, data() { return { @@ -331,7 +341,7 @@ export default { :enable-preview="enablePreview" :show-suggest-popover="showSuggestPopover" :suggestion-start-index="suggestionsStartIndex" - data-testid="markdownHeader" + :restricted-tool-bar-items="restrictedToolBarItems" @preview-markdown="showPreviewTab" @write-markdown="showWriteTab" @handleSuggestDismissed="() => $emit('handleSuggestDismissed')" @@ -350,6 +360,7 @@ export default { :markdown-docs-path="markdownDocsPath" :quick-actions-docs-path="quickActionsDocsPath" :can-attach-file="canAttachFile" + :show-comment-tool-bar="showCommentToolBar" /> </div> </div> diff --git a/app/assets/javascripts/vue_shared/components/markdown/header.vue b/app/assets/javascripts/vue_shared/components/markdown/header.vue index d0bd5046bf0..7993910ec12 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/header.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/header.vue @@ -54,6 +54,11 @@ export default { required: false, default: true, }, + restrictedToolBarItems: { + type: Array, + required: false, + default: () => [], + }, }, data() { return { @@ -207,6 +212,7 @@ export default { icon="italic" /> <toolbar-button + v-if="!restrictedToolBarItems.includes('strikethrough')" tag="~~" :button-title=" sprintf(s__('MarkdownEditor|Add strikethrough text (%{modifierKey}⇧X)'), { @@ -217,6 +223,7 @@ export default { icon="strikethrough" /> <toolbar-button + v-if="!restrictedToolBarItems.includes('quote')" :prepend="true" :tag="tag" :button-title="__('Insert a quote')" @@ -272,24 +279,28 @@ export default { icon="link" /> <toolbar-button + v-if="!restrictedToolBarItems.includes('bullet-list')" :prepend="true" tag="- " :button-title="__('Add a bullet list')" icon="list-bulleted" /> <toolbar-button + v-if="!restrictedToolBarItems.includes('numbered-list')" :prepend="true" tag="1. " :button-title="__('Add a numbered list')" icon="list-numbered" /> <toolbar-button + v-if="!restrictedToolBarItems.includes('task-list')" :prepend="true" tag="- [ ] " :button-title="__('Add a task list')" icon="list-task" /> <toolbar-button + v-if="!restrictedToolBarItems.includes('collapsible-section')" :tag="mdCollapsibleSection" :prepend="true" tag-select="Click to expand" @@ -297,12 +308,14 @@ export default { icon="details-block" /> <toolbar-button + v-if="!restrictedToolBarItems.includes('table')" :tag="mdTable" :prepend="true" :button-title="__('Add a table')" icon="table" /> <toolbar-button + v-if="!restrictedToolBarItems.includes('full-screen')" class="js-zen-enter" :prepend="true" :button-title="__('Go full screen')" diff --git a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue index f1c293c87f4..1d83a61f2ae 100644 --- a/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue +++ b/app/assets/javascripts/vue_shared/components/markdown/toolbar.vue @@ -24,6 +24,11 @@ export default { required: false, default: true, }, + showCommentToolBar: { + type: Boolean, + required: false, + default: true, + }, }, computed: { hasQuickActionsDocsPath() { @@ -34,7 +39,7 @@ export default { </script> <template> - <div class="comment-toolbar clearfix"> + <div v-if="showCommentToolBar" class="comment-toolbar clearfix"> <div class="toolbar-text"> <template v-if="!hasQuickActionsDocsPath && markdownDocsPath"> <gl-link :href="markdownDocsPath" target="_blank"> diff --git a/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue b/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue index edf2229a9a1..ed87a202b15 100644 --- a/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue +++ b/app/assets/javascripts/vue_shared/components/source_viewer/source_viewer.vue @@ -2,6 +2,7 @@ import { GlSafeHtmlDirective, GlLoadingIcon } from '@gitlab/ui'; import LineHighlighter from '~/blob/line_highlighter'; import eventHub from '~/notes/event_hub'; +import languageLoader from '~/content_editor/services/highlight_js_language_loader'; import { ROUGE_TO_HLJS_LANGUAGE_MAP, LINES_PER_CHUNK } from './constants'; import Chunk from './components/chunk.vue'; @@ -129,7 +130,7 @@ export default { let languageDefinition; try { - languageDefinition = await import(`highlight.js/lib/languages/${this.language}`); + languageDefinition = await languageLoader[this.language](); this.hljs.registerLanguage(this.language, languageDefinition.default); } catch (message) { this.$emit('error', message); diff --git a/app/controllers/admin/deploy_keys_controller.rb b/app/controllers/admin/deploy_keys_controller.rb index ed63e65d4df..b24b25446b0 100644 --- a/app/controllers/admin/deploy_keys_controller.rb +++ b/app/controllers/admin/deploy_keys_controller.rb @@ -5,6 +5,7 @@ class Admin::DeployKeysController < Admin::ApplicationController before_action :deploy_key, only: [:destroy, :edit, :update] feature_category :continuous_delivery + urgency :low def index end diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index eb6cedb5d4a..db793106aad 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -12,7 +12,7 @@ class AutocompleteController < ApplicationController feature_category :code_review, [:merge_request_target_branches] feature_category :continuous_delivery, [:deploy_keys_with_owners] - urgency :low, [:merge_request_target_branches] + urgency :low, [:merge_request_target_branches, :deploy_keys_with_owners] urgency :default, [:users] urgency :medium, [:projects] diff --git a/app/controllers/groups/deploy_tokens_controller.rb b/app/controllers/groups/deploy_tokens_controller.rb index 9ef22aa33dc..5bab6f59a42 100644 --- a/app/controllers/groups/deploy_tokens_controller.rb +++ b/app/controllers/groups/deploy_tokens_controller.rb @@ -4,6 +4,7 @@ class Groups::DeployTokensController < Groups::ApplicationController before_action :authorize_destroy_deploy_token! feature_category :continuous_delivery + urgency :low def revoke Groups::DeployTokens::RevokeService.new(@group, current_user, params).execute diff --git a/app/controllers/groups/releases_controller.rb b/app/controllers/groups/releases_controller.rb index e87135cc104..3fa6023a78c 100644 --- a/app/controllers/groups/releases_controller.rb +++ b/app/controllers/groups/releases_controller.rb @@ -3,6 +3,7 @@ module Groups class ReleasesController < Groups::ApplicationController feature_category :release_evidence + urgency :low def index respond_to do |format| diff --git a/app/controllers/groups/settings/repository_controller.rb b/app/controllers/groups/settings/repository_controller.rb index 7404075985b..b0431c31179 100644 --- a/app/controllers/groups/settings/repository_controller.rb +++ b/app/controllers/groups/settings/repository_controller.rb @@ -12,6 +12,7 @@ module Groups end feature_category :continuous_delivery + urgency :low def create_deploy_token result = Groups::DeployTokens::CreateService.new(@group, current_user, deploy_token_params).execute diff --git a/app/controllers/projects/deploy_keys_controller.rb b/app/controllers/projects/deploy_keys_controller.rb index ce25f86d692..96afe9dbb9f 100644 --- a/app/controllers/projects/deploy_keys_controller.rb +++ b/app/controllers/projects/deploy_keys_controller.rb @@ -11,6 +11,7 @@ class Projects::DeployKeysController < Projects::ApplicationController layout 'project_settings' feature_category :continuous_delivery + urgency :low def index respond_to do |format| diff --git a/app/controllers/projects/deploy_tokens_controller.rb b/app/controllers/projects/deploy_tokens_controller.rb index 42c2d8b17f1..ed77fa2fee6 100644 --- a/app/controllers/projects/deploy_tokens_controller.rb +++ b/app/controllers/projects/deploy_tokens_controller.rb @@ -4,6 +4,7 @@ class Projects::DeployTokensController < Projects::ApplicationController before_action :authorize_admin_project! feature_category :continuous_delivery + urgency :low def revoke @token = @project.deploy_tokens.find(params[:id]) diff --git a/app/controllers/projects/deployments_controller.rb b/app/controllers/projects/deployments_controller.rb index 231684427fb..bebade1b21b 100644 --- a/app/controllers/projects/deployments_controller.rb +++ b/app/controllers/projects/deployments_controller.rb @@ -4,6 +4,7 @@ class Projects::DeploymentsController < Projects::ApplicationController before_action :authorize_read_deployment! feature_category :continuous_delivery + urgency :low # rubocop: disable CodeReuse/ActiveRecord def index diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 92db849015a..a100afd3488 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -27,6 +27,7 @@ class Projects::EnvironmentsController < Projects::ApplicationController after_action :expire_etag_cache, only: [:cancel_auto_stop] feature_category :continuous_delivery + urgency :low def index @project = ProjectPresenter.new(project, current_user: current_user) diff --git a/app/controllers/projects/feature_flags_clients_controller.rb b/app/controllers/projects/feature_flags_clients_controller.rb index 9a1f8932a27..2652345fc5a 100644 --- a/app/controllers/projects/feature_flags_clients_controller.rb +++ b/app/controllers/projects/feature_flags_clients_controller.rb @@ -5,6 +5,7 @@ class Projects::FeatureFlagsClientsController < Projects::ApplicationController before_action :feature_flags_client feature_category :feature_flags + urgency :low def reset_token feature_flags_client.reset_token! diff --git a/app/controllers/projects/feature_flags_controller.rb b/app/controllers/projects/feature_flags_controller.rb index 7c0da8f8a24..1d1fe91ad70 100644 --- a/app/controllers/projects/feature_flags_controller.rb +++ b/app/controllers/projects/feature_flags_controller.rb @@ -11,6 +11,7 @@ class Projects::FeatureFlagsController < Projects::ApplicationController before_action :feature_flag, only: [:edit, :update, :destroy] feature_category :feature_flags + urgency :low def index @feature_flags = FeatureFlagsFinder diff --git a/app/controllers/projects/feature_flags_user_lists_controller.rb b/app/controllers/projects/feature_flags_user_lists_controller.rb index fd81321924a..023eb51cc94 100644 --- a/app/controllers/projects/feature_flags_user_lists_controller.rb +++ b/app/controllers/projects/feature_flags_user_lists_controller.rb @@ -5,6 +5,7 @@ class Projects::FeatureFlagsUserListsController < Projects::ApplicationControlle before_action :user_list, only: [:edit, :show] feature_category :feature_flags + urgency :low def index end diff --git a/app/controllers/projects/releases/evidences_controller.rb b/app/controllers/projects/releases/evidences_controller.rb index 41e2ce81eb8..9f59898878c 100644 --- a/app/controllers/projects/releases/evidences_controller.rb +++ b/app/controllers/projects/releases/evidences_controller.rb @@ -8,6 +8,7 @@ module Projects before_action :authorize_read_release_evidence! feature_category :release_evidence + urgency :low def show respond_to do |format| diff --git a/app/controllers/projects/releases_controller.rb b/app/controllers/projects/releases_controller.rb index 19413d97d9d..84c763088e5 100644 --- a/app/controllers/projects/releases_controller.rb +++ b/app/controllers/projects/releases_controller.rb @@ -10,6 +10,7 @@ class Projects::ReleasesController < Projects::ApplicationController before_action :validate_suffix_path, :fetch_latest_tag, only: :latest_permalink feature_category :release_orchestration + urgency :low def index respond_to do |format| diff --git a/app/controllers/projects/settings/repository_controller.rb b/app/controllers/projects/settings/repository_controller.rb index a28c08e87cb..0fd2d56229a 100644 --- a/app/controllers/projects/settings/repository_controller.rb +++ b/app/controllers/projects/settings/repository_controller.rb @@ -12,7 +12,7 @@ module Projects feature_category :source_code_management, [:show, :cleanup] feature_category :continuous_delivery, [:create_deploy_token] - urgency :low, [:show] + urgency :low, [:show, :create_deploy_token] def show render_show diff --git a/app/controllers/projects/tags/releases_controller.rb b/app/controllers/projects/tags/releases_controller.rb index 8e5539f546b..b852673d82a 100644 --- a/app/controllers/projects/tags/releases_controller.rb +++ b/app/controllers/projects/tags/releases_controller.rb @@ -9,6 +9,7 @@ class Projects::Tags::ReleasesController < Projects::ApplicationController before_action :release feature_category :release_evidence + urgency :low def edit end diff --git a/app/views/projects/merge_requests/_code_dropdown.html.haml b/app/views/projects/merge_requests/_code_dropdown.html.haml index ab5716d5485..0bd28e315d9 100644 --- a/app/views/projects/merge_requests/_code_dropdown.html.haml +++ b/app/views/projects/merge_requests/_code_dropdown.html.haml @@ -1,6 +1,6 @@ .float-left.gl-md-ml-3.dropdown.gl-new-dropdown{ class: "gl-display-none! gl-md-display-flex!" } #js-check-out-modal{ data: how_merge_modal_data(@merge_request) } - = button_tag type: 'button', class: "btn dropdown-toggle btn-confirm gl-button gl-dropdown-toggle", data: { toggle: 'dropdown', qa_selector: 'mr_code_drodpown' } do + = button_tag type: 'button', class: "btn dropdown-toggle btn-confirm gl-button gl-dropdown-toggle", data: { toggle: 'dropdown', qa_selector: 'mr_code_dropdown' } do %span.gl-new-dropdown-button-text= _('Code') = sprite_icon "chevron-down", size: 16, css_class: "dropdown-icon gl-icon gl-ml-2 gl-mr-0!" .dropdown-menu.dropdown-menu-right @@ -29,11 +29,11 @@ %li.gl-new-dropdown-section-header %header.dropdown-header = _('Download') - %li.gl-new-dropdown-item{ data: { qa_selector: 'download_email_patches_menu_item' } } - = link_to merge_request_path(@merge_request, format: :patch), class: 'dropdown-item', download: '' do + %li.gl-new-dropdown-item + = link_to merge_request_path(@merge_request, format: :patch), class: 'dropdown-item', download: '', data: { qa_selector: 'download_email_patches_menu_item' } do .gl-new-dropdown-item-text-wrapper = _('Email patches') - %li.gl-new-dropdown-item{ data: { qa_selector: 'download_plain_diff_menu_item' } } - = link_to merge_request_path(@merge_request, format: :diff), class: 'dropdown-item' do + %li.gl-new-dropdown-item + = link_to merge_request_path(@merge_request, format: :diff), class: 'dropdown-item', data: { qa_selector: 'download_plain_diff_menu_item' } do .gl-new-dropdown-item-text-wrapper = _('Plain diff') diff --git a/doc/api/plan_limits.md b/doc/api/plan_limits.md index 75c8d241513..760f64894bb 100644 --- a/doc/api/plan_limits.md +++ b/doc/api/plan_limits.md @@ -35,6 +35,14 @@ Example response: ```json { + "ci_pipeline_size": 0, + "ci_active_jobs": 0, + "ci_active_pipelines": 0, + "ci_project_subscriptions": 2, + "ci_pipeline_schedules": 10, + "ci_needs_size_limit": 50, + "ci_registered_group_runners": 1000, + "ci_registered_project_runners": 1000, "conan_max_file_size": 3221225472, "generic_packages_max_file_size": 5368709120, "helm_max_file_size": 5242880, @@ -57,6 +65,14 @@ PUT /application/plan_limits | Attribute | Type | Required | Description | | --------------------------------- | ------- | -------- | ----------- | | `plan_name` | string | yes | Name of the plan to update. | +| `ci_pipeline_size` | integer | no | Maximum number of jobs in a single pipeline. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895) in GitLab 15.0. | +| `ci_active_jobs` | integer | no | Total number of jobs in currently active pipelines. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895) in GitLab 15.0. | +| `ci_active_pipelines` | integer | no | Maximum number of active pipelines per project. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895) in GitLab 15.0. | +| `ci_project_subscriptions` | integer | no | Maximum number of pipeline subscriptions to and from a project. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895) in GitLab 15.0. | +| `ci_pipeline_schedules` | integer | no | Maximum number of pipeline schedules. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895) in GitLab 15.0. | +| `ci_needs_size_limit` | integer | no | Maximum number of [DAG](../ci/directed_acyclic_graph/index.md) dependencies that a job can have. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895) in GitLab 15.0. | +| `ci_registered_group_runners` | integer | no | Maximum number of runners registered per group. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895) in GitLab 15.0. | +| `ci_registered_project_runners` | integer | no | Maximum number of runners registered per project. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85895) in GitLab 15.0. | | `conan_max_file_size` | integer | no | Maximum Conan package file size in bytes. | | `generic_packages_max_file_size` | integer | no | Maximum generic package file size in bytes. | | `helm_max_file_size` | integer | no | Maximum Helm chart file size in bytes. | @@ -74,6 +90,14 @@ Example response: ```json { + "ci_pipeline_size": 0, + "ci_active_jobs": 0, + "ci_active_pipelines": 0, + "ci_project_subscriptions": 2, + "ci_pipeline_schedules": 10, + "ci_needs_size_limit": 50, + "ci_registered_group_runners": 1000, + "ci_registered_project_runners": 1000, "conan_max_file_size": 3221225472, "generic_packages_max_file_size": 5368709120, "helm_max_file_size": 5242880, diff --git a/doc/development/testing_guide/testing_migrations_guide.md b/doc/development/testing_guide/testing_migrations_guide.md index 4092c1a2f6d..d71788e21f3 100644 --- a/doc/development/testing_guide/testing_migrations_guide.md +++ b/doc/development/testing_guide/testing_migrations_guide.md @@ -227,6 +227,18 @@ expect('MigrationClass').to have_scheduled_batched_migration( ) ``` +#### `be_finalize_background_migration_of` + +Verifies that a migration calls `finalize_background_migration` with the expected background migration class. + +```ruby +# Migration +finalize_background_migration('MigrationClass') + +# Spec +expect(described_class).to be_finalize_background_migration_of('MigrationClass') +``` + ### Examples of migration tests Migration tests depend on what the migration does exactly, the most common types are data migrations and scheduling background migrations. diff --git a/lib/api/admin/plan_limits.rb b/lib/api/admin/plan_limits.rb index 99be30809d2..1dbcf812085 100644 --- a/lib/api/admin/plan_limits.rb +++ b/lib/api/admin/plan_limits.rb @@ -35,6 +35,14 @@ module API params do requires :plan_name, type: String, values: Plan.all_plans, desc: 'Name of the plan' + optional :ci_pipeline_size, type: Integer, desc: 'Maximum number of jobs in a single pipeline' + optional :ci_active_jobs, type: Integer, desc: 'Total number of jobs in currently active pipelines' + optional :ci_active_pipelines, type: Integer, desc: 'Maximum number of active pipelines per project' + optional :ci_project_subscriptions, type: Integer, desc: 'Maximum number of pipeline subscriptions to and from a project' + optional :ci_pipeline_schedules, type: Integer, desc: 'Maximum number of pipeline schedules' + optional :ci_needs_size_limit, type: Integer, desc: 'Maximum number of DAG dependencies that a job can have' + optional :ci_registered_group_runners, type: Integer, desc: 'Maximum number of runners registered per group' + optional :ci_registered_project_runners, type: Integer, desc: 'Maximum number of runners registered per project' optional :conan_max_file_size, type: Integer, desc: 'Maximum Conan package file size in bytes' optional :generic_packages_max_file_size, type: Integer, desc: 'Maximum generic package file size in bytes' optional :helm_max_file_size, type: Integer, desc: 'Maximum Helm chart file size in bytes' diff --git a/lib/api/ci/resource_groups.rb b/lib/api/ci/resource_groups.rb index 616bec499d4..3c8c68caeae 100644 --- a/lib/api/ci/resource_groups.rb +++ b/lib/api/ci/resource_groups.rb @@ -6,6 +6,7 @@ module API before { authenticate! } feature_category :continuous_delivery + urgency :low params do requires :id, type: String, desc: 'The ID of a project' diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb index 0ab9fe6644c..ca13db8701e 100644 --- a/lib/api/deploy_keys.rb +++ b/lib/api/deploy_keys.rb @@ -7,6 +7,7 @@ module API before { authenticate! } feature_category :continuous_delivery + urgency :low helpers do def add_deploy_keys_project(project, attrs = {}) diff --git a/lib/api/deploy_tokens.rb b/lib/api/deploy_tokens.rb index 074c307e881..3e0411d2e91 100644 --- a/lib/api/deploy_tokens.rb +++ b/lib/api/deploy_tokens.rb @@ -5,6 +5,7 @@ module API include PaginationParams feature_category :continuous_delivery + urgency :low helpers do def scope_params diff --git a/lib/api/deployments.rb b/lib/api/deployments.rb index 6939853c06b..8db5f54b45a 100644 --- a/lib/api/deployments.rb +++ b/lib/api/deployments.rb @@ -8,6 +8,7 @@ module API before { authenticate! } feature_category :continuous_delivery + urgency :low params do requires :id, type: String, desc: 'The project ID' diff --git a/lib/api/entities/plan_limit.rb b/lib/api/entities/plan_limit.rb index 9f4d1635998..33d59a4207c 100644 --- a/lib/api/entities/plan_limit.rb +++ b/lib/api/entities/plan_limit.rb @@ -3,6 +3,14 @@ module API module Entities class PlanLimit < Grape::Entity + expose :ci_pipeline_size + expose :ci_active_jobs + expose :ci_active_pipelines + expose :ci_project_subscriptions + expose :ci_pipeline_schedules + expose :ci_needs_size_limit + expose :ci_registered_group_runners + expose :ci_registered_project_runners expose :conan_max_file_size expose :generic_packages_max_file_size expose :helm_max_file_size diff --git a/lib/api/environments.rb b/lib/api/environments.rb index 19b48c1e3cf..646b7e5eedb 100644 --- a/lib/api/environments.rb +++ b/lib/api/environments.rb @@ -8,6 +8,7 @@ module API before { authenticate! } feature_category :continuous_delivery + urgency :low params do requires :id, type: String, desc: 'The project ID' diff --git a/lib/api/feature_flags.rb b/lib/api/feature_flags.rb index c1f958ac007..42050888c14 100644 --- a/lib/api/feature_flags.rb +++ b/lib/api/feature_flags.rb @@ -8,6 +8,7 @@ module API .merge(name: API::NO_SLASH_URL_PART_REGEX) feature_category :feature_flags + urgency :low before do authorize_read_feature_flags! diff --git a/lib/api/feature_flags_user_lists.rb b/lib/api/feature_flags_user_lists.rb index 8577da173b1..854719db4a1 100644 --- a/lib/api/feature_flags_user_lists.rb +++ b/lib/api/feature_flags_user_lists.rb @@ -9,6 +9,7 @@ module API } feature_category :feature_flags + urgency :low before do authorize_admin_feature_flags_user_lists! diff --git a/lib/api/features.rb b/lib/api/features.rb index 398e57794c8..51d1e5b4628 100644 --- a/lib/api/features.rb +++ b/lib/api/features.rb @@ -5,6 +5,7 @@ module API before { authenticated_as_admin! } feature_category :feature_flags + urgency :low helpers do def gate_value(params) diff --git a/lib/api/freeze_periods.rb b/lib/api/freeze_periods.rb index d001ced8581..e69baeee97f 100644 --- a/lib/api/freeze_periods.rb +++ b/lib/api/freeze_periods.rb @@ -7,6 +7,7 @@ module API before { authenticate! } feature_category :continuous_delivery + urgency :low params do requires :id, type: String, desc: 'The ID of a project' diff --git a/lib/api/release/links.rb b/lib/api/release/links.rb index 52c73104bb4..bc5ffe5b21f 100644 --- a/lib/api/release/links.rb +++ b/lib/api/release/links.rb @@ -11,6 +11,7 @@ module API before { authorize! :read_release, user_project } feature_category :release_orchestration + urgency :low params do requires :id, type: String, desc: 'The ID of a project' diff --git a/lib/api/releases.rb b/lib/api/releases.rb index 9e085a91a7c..048cbf3ad83 100644 --- a/lib/api/releases.rb +++ b/lib/api/releases.rb @@ -9,6 +9,7 @@ module API RELEASE_CLI_USER_AGENT = 'GitLab-release-cli' feature_category :release_orchestration + urgency :low params do requires :id, type: String, desc: 'The ID of a group' diff --git a/lib/api/unleash.rb b/lib/api/unleash.rb index 6dadaf4fc54..37fe540cde1 100644 --- a/lib/api/unleash.rb +++ b/lib/api/unleash.rb @@ -30,7 +30,7 @@ module API end desc 'Get a list of features' - get 'client/features', urgency: :medium do + get 'client/features' do present :version, 1 present :features, feature_flags, with: ::API::Entities::UnleashFeature end diff --git a/qa/qa/page/merge_request/show.rb b/qa/qa/page/merge_request/show.rb index 6aa2d4b407a..8f5ac62d127 100644 --- a/qa/qa/page/merge_request/show.rb +++ b/qa/qa/page/merge_request/show.rb @@ -50,8 +50,9 @@ module QA end view 'app/views/projects/merge_requests/_code_dropdown.html.haml' do - element :mr_code_drodpown + element :mr_code_dropdown element :download_email_patches_menu_item + element :download_plain_diff_menu_item element :open_in_web_ide_button end @@ -342,12 +343,12 @@ module QA end def view_email_patches - click_element(:mr_code_drodpown) + click_element(:mr_code_dropdown) visit_link_in_element(:download_email_patches_menu_item) end def view_plain_diff - click_element(:mr_code_drodpown) + click_element(:mr_code_dropdown) visit_link_in_element(:download_plain_diff_menu_item) end diff --git a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap index 2b26c306c68..fec300ddd7e 100644 --- a/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap +++ b/spec/frontend/snippets/components/__snapshots__/snippet_description_edit_spec.js.snap @@ -28,9 +28,9 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] = data-uploads-path="" > <markdown-header-stub - data-testid="markdownHeader" enablepreview="true" linecontent="" + restrictedtoolbaritems="" suggestionstartindex="0" /> @@ -81,6 +81,7 @@ exports[`Snippet Description Edit component rendering matches the snapshot 1`] = canattachfile="true" markdowndocspath="help/" quickactionsdocspath="" + showcommenttoolbar="true" /> </div> </div> diff --git a/spec/frontend/vue_shared/components/markdown/field_spec.js b/spec/frontend/vue_shared/components/markdown/field_spec.js index ab74ea868a2..b3376f26a25 100644 --- a/spec/frontend/vue_shared/components/markdown/field_spec.js +++ b/spec/frontend/vue_shared/components/markdown/field_spec.js @@ -5,12 +5,14 @@ import { TEST_HOST, FIXTURES_PATH } from 'spec/test_constants'; import axios from '~/lib/utils/axios_utils'; import MarkdownField from '~/vue_shared/components/markdown/field.vue'; import MarkdownFieldHeader from '~/vue_shared/components/markdown/header.vue'; +import MarkdownToolbar from '~/vue_shared/components/markdown/toolbar.vue'; import { mountExtended } from 'helpers/vue_test_utils_helper'; const markdownPreviewPath = `${TEST_HOST}/preview`; const markdownDocsPath = `${TEST_HOST}/docs`; const textareaValue = 'testing\n123'; const uploadsPath = 'test/uploads'; +const restrictedToolBarItems = ['quote']; function assertMarkdownTabs(isWrite, writeLink, previewLink, wrapper) { expect(writeLink.element.children[0].classList.contains('active')).toBe(isWrite); @@ -63,6 +65,7 @@ describe('Markdown field component', () => { textareaValue, lines, enablePreview, + restrictedToolBarItems, }, provide: { glFeatures: { @@ -81,6 +84,8 @@ describe('Markdown field component', () => { const getAttachButton = () => subject.find('.button-attach-file'); const clickAttachButton = () => getAttachButton().trigger('click'); const findDropzone = () => subject.find('.div-dropzone'); + const findMarkdownHeader = () => subject.findComponent(MarkdownFieldHeader); + const findMarkdownToolbar = () => subject.findComponent(MarkdownToolbar); describe('mounted', () => { const previewHTML = ` @@ -184,6 +189,15 @@ describe('Markdown field component', () => { assertMarkdownTabs(false, writeLink, previewLink, subject); }); + + it('passes correct props to MarkdownToolbar', () => { + expect(findMarkdownToolbar().props()).toEqual({ + canAttachFile: true, + markdownDocsPath, + quickActionsDocsPath: '', + showCommentToolBar: true, + }); + }); }); describe('markdown buttons', () => { @@ -314,9 +328,7 @@ describe('Markdown field component', () => { it('escapes new line characters', () => { createSubject({ lines: [{ rich_text: 'hello world\\n' }] }); - expect(subject.find('[data-testid="markdownHeader"]').props('lineContent')).toBe( - 'hello world%br', - ); + expect(findMarkdownHeader().props('lineContent')).toBe('hello world%br'); }); }); @@ -330,4 +342,12 @@ describe('Markdown field component', () => { expect(subject.findComponent(MarkdownFieldHeader).props('enablePreview')).toBe(true); }); + + it('passess restricted tool bar items', () => { + createSubject(); + + expect(subject.findComponent(MarkdownFieldHeader).props('restrictedToolBarItems')).toBe( + restrictedToolBarItems, + ); + }); }); diff --git a/spec/frontend/vue_shared/components/markdown/header_spec.js b/spec/frontend/vue_shared/components/markdown/header_spec.js index fa4ca63f910..67222cab247 100644 --- a/spec/frontend/vue_shared/components/markdown/header_spec.js +++ b/spec/frontend/vue_shared/components/markdown/header_spec.js @@ -166,4 +166,26 @@ describe('Markdown field header component', () => { expect(wrapper.findByTestId('preview-tab').exists()).toBe(false); }); + + describe('restricted tool bar items', () => { + let defaultCount; + + beforeEach(() => { + defaultCount = findToolbarButtons().length; + }); + + it('restricts items as per input', () => { + createWrapper({ + restrictedToolBarItems: ['quote'], + }); + + expect(findToolbarButtons().length).toBe(defaultCount - 1); + }); + + it('shows all items by default', () => { + createWrapper(); + + expect(findToolbarButtons().length).toBe(defaultCount); + }); + }); }); diff --git a/spec/frontend/vue_shared/components/markdown/toolbar_spec.js b/spec/frontend/vue_shared/components/markdown/toolbar_spec.js index 8bff85b0bda..f698794b951 100644 --- a/spec/frontend/vue_shared/components/markdown/toolbar_spec.js +++ b/spec/frontend/vue_shared/components/markdown/toolbar_spec.js @@ -33,4 +33,18 @@ describe('toolbar', () => { expect(wrapper.vm.$el.querySelector('.uploading-container')).toBeNull(); }); }); + + describe('comment tool bar settings', () => { + it('does not show comment tool bar div', () => { + createMountedWrapper({ showCommentToolBar: false }); + + expect(wrapper.find('.comment-toolbar').exists()).toBe(false); + }); + + it('shows comment tool bar by default', () => { + createMountedWrapper(); + + expect(wrapper.find('.comment-toolbar').exists()).toBe(true); + }); + }); }); diff --git a/spec/lib/api/entities/plan_limit_spec.rb b/spec/lib/api/entities/plan_limit_spec.rb index 1b8b21d47f3..0f38d119088 100644 --- a/spec/lib/api/entities/plan_limit_spec.rb +++ b/spec/lib/api/entities/plan_limit_spec.rb @@ -9,6 +9,14 @@ RSpec.describe API::Entities::PlanLimit do it 'exposes correct attributes' do expect(subject).to include( + :ci_pipeline_size, + :ci_active_jobs, + :ci_active_pipelines, + :ci_project_subscriptions, + :ci_pipeline_schedules, + :ci_needs_size_limit, + :ci_registered_group_runners, + :ci_registered_project_runners, :conan_max_file_size, :generic_packages_max_file_size, :helm_max_file_size, diff --git a/spec/requests/api/admin/plan_limits_spec.rb b/spec/requests/api/admin/plan_limits_spec.rb index 03642ad617e..855a0ae0c0a 100644 --- a/spec/requests/api/admin/plan_limits_spec.rb +++ b/spec/requests/api/admin/plan_limits_spec.rb @@ -23,6 +23,14 @@ RSpec.describe API::Admin::PlanLimits, 'PlanLimits' do expect(response).to have_gitlab_http_status(:ok) expect(json_response).to be_an Hash + expect(json_response['ci_pipeline_size']).to eq(Plan.default.actual_limits.ci_pipeline_size) + expect(json_response['ci_active_jobs']).to eq(Plan.default.actual_limits.ci_active_jobs) + expect(json_response['ci_active_pipelines']).to eq(Plan.default.actual_limits.ci_active_pipelines) + expect(json_response['ci_project_subscriptions']).to eq(Plan.default.actual_limits.ci_project_subscriptions) + expect(json_response['ci_pipeline_schedules']).to eq(Plan.default.actual_limits.ci_pipeline_schedules) + expect(json_response['ci_needs_size_limit']).to eq(Plan.default.actual_limits.ci_needs_size_limit) + expect(json_response['ci_registered_group_runners']).to eq(Plan.default.actual_limits.ci_registered_group_runners) + expect(json_response['ci_registered_project_runners']).to eq(Plan.default.actual_limits.ci_registered_project_runners) expect(json_response['conan_max_file_size']).to eq(Plan.default.actual_limits.conan_max_file_size) expect(json_response['generic_packages_max_file_size']).to eq(Plan.default.actual_limits.generic_packages_max_file_size) expect(json_response['helm_max_file_size']).to eq(Plan.default.actual_limits.helm_max_file_size) @@ -44,6 +52,14 @@ RSpec.describe API::Admin::PlanLimits, 'PlanLimits' do expect(response).to have_gitlab_http_status(:ok) expect(json_response).to be_an Hash + expect(json_response['ci_pipeline_size']).to eq(Plan.default.actual_limits.ci_pipeline_size) + expect(json_response['ci_active_jobs']).to eq(Plan.default.actual_limits.ci_active_jobs) + expect(json_response['ci_active_pipelines']).to eq(Plan.default.actual_limits.ci_active_pipelines) + expect(json_response['ci_project_subscriptions']).to eq(Plan.default.actual_limits.ci_project_subscriptions) + expect(json_response['ci_pipeline_schedules']).to eq(Plan.default.actual_limits.ci_pipeline_schedules) + expect(json_response['ci_needs_size_limit']).to eq(Plan.default.actual_limits.ci_needs_size_limit) + expect(json_response['ci_registered_group_runners']).to eq(Plan.default.actual_limits.ci_registered_group_runners) + expect(json_response['ci_registered_project_runners']).to eq(Plan.default.actual_limits.ci_registered_project_runners) expect(json_response['conan_max_file_size']).to eq(Plan.default.actual_limits.conan_max_file_size) expect(json_response['generic_packages_max_file_size']).to eq(Plan.default.actual_limits.generic_packages_max_file_size) expect(json_response['helm_max_file_size']).to eq(Plan.default.actual_limits.helm_max_file_size) @@ -84,6 +100,14 @@ RSpec.describe API::Admin::PlanLimits, 'PlanLimits' do it 'updates multiple plan limits' do put api('/application/plan_limits', admin), params: { 'plan_name': 'default', + 'ci_pipeline_size': 101, + 'ci_active_jobs': 102, + 'ci_active_pipelines': 103, + 'ci_project_subscriptions': 104, + 'ci_pipeline_schedules': 105, + 'ci_needs_size_limit': 106, + 'ci_registered_group_runners': 107, + 'ci_registered_project_runners': 108, 'conan_max_file_size': 10, 'generic_packages_max_file_size': 20, 'helm_max_file_size': 25, @@ -96,6 +120,14 @@ RSpec.describe API::Admin::PlanLimits, 'PlanLimits' do expect(response).to have_gitlab_http_status(:ok) expect(json_response).to be_an Hash + expect(json_response['ci_pipeline_size']).to eq(101) + expect(json_response['ci_active_jobs']).to eq(102) + expect(json_response['ci_active_pipelines']).to eq(103) + expect(json_response['ci_project_subscriptions']).to eq(104) + expect(json_response['ci_pipeline_schedules']).to eq(105) + expect(json_response['ci_needs_size_limit']).to eq(106) + expect(json_response['ci_registered_group_runners']).to eq(107) + expect(json_response['ci_registered_project_runners']).to eq(108) expect(json_response['conan_max_file_size']).to eq(10) expect(json_response['generic_packages_max_file_size']).to eq(20) expect(json_response['helm_max_file_size']).to eq(25) @@ -131,6 +163,14 @@ RSpec.describe API::Admin::PlanLimits, 'PlanLimits' do it 'fails to update plan limits' do put api('/application/plan_limits', admin), params: { 'plan_name': 'default', + 'ci_pipeline_size': 'z', + 'ci_active_jobs': 'y', + 'ci_active_pipelines': 'x', + 'ci_project_subscriptions': 'w', + 'ci_pipeline_schedules': 'v', + 'ci_needs_size_limit': 'u', + 'ci_registered_group_runners': 't', + 'ci_registered_project_runners': 's', 'conan_max_file_size': 'a', 'generic_packages_max_file_size': 'b', 'helm_max_file_size': 'h', @@ -143,6 +183,14 @@ RSpec.describe API::Admin::PlanLimits, 'PlanLimits' do expect(response).to have_gitlab_http_status(:bad_request) expect(json_response['error']).to include( + 'ci_pipeline_size is invalid', + 'ci_active_jobs is invalid', + 'ci_active_pipelines is invalid', + 'ci_project_subscriptions is invalid', + 'ci_pipeline_schedules is invalid', + 'ci_needs_size_limit is invalid', + 'ci_registered_group_runners is invalid', + 'ci_registered_project_runners is invalid', 'conan_max_file_size is invalid', 'generic_packages_max_file_size is invalid', 'helm_max_file_size is invalid', diff --git a/spec/support/matchers/background_migrations_matchers.rb b/spec/support/matchers/background_migrations_matchers.rb index b20bc1f1329..b471323dd72 100644 --- a/spec/support/matchers/background_migrations_matchers.rb +++ b/spec/support/matchers/background_migrations_matchers.rb @@ -83,3 +83,11 @@ RSpec::Matchers.define :have_scheduled_batched_migration do |table_name: nil, co expect(batched_migrations.count).to be(0) end end + +RSpec::Matchers.define :be_finalize_background_migration_of do |migration| + define_method :matches? do |klass| + expect_next_instance_of(klass) do |instance| + expect(instance).to receive(:finalize_background_migration).with(migration) + end + end +end |