diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-10 15:11:01 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-10 15:11:01 +0000 |
commit | ae1b3d982482280f22a907faba2c9ba02f4d1db1 (patch) | |
tree | 5c3312879a2c554e1e73a175878ea7eb7a87ac10 | |
parent | e1bfa7aef2346a8c2d4e0ae0c69bf7649896f556 (diff) | |
download | gitlab-ce-ae1b3d982482280f22a907faba2c9ba02f4d1db1.tar.gz |
Add latest changes from gitlab-org/gitlab@master
36 files changed, 325 insertions, 75 deletions
diff --git a/Gemfile.checksum b/Gemfile.checksum index 14be8b71f25..2ba745a2e60 100644 --- a/Gemfile.checksum +++ b/Gemfile.checksum @@ -200,7 +200,7 @@ {"name":"gitaly","version":"15.9.0.pre.rc1","platform":"ruby","checksum":"c5ebbe6b1f2770020b0857a6a03bf1f52cd0be9ae05dbbb296316b3e7d75b42b"}, {"name":"gitlab","version":"4.19.0","platform":"ruby","checksum":"3f645e3e195dbc24f0834fbf83e8ccfb2056d8e9712b01a640aad418a6949679"}, {"name":"gitlab-chronic","version":"0.10.5","platform":"ruby","checksum":"f80f18dc699b708870a80685243331290bc10cfeedb6b99c92219722f729c875"}, -{"name":"gitlab-dangerfiles","version":"3.6.6","platform":"ruby","checksum":"cabfe23490120188a653c827a32121bdd4abf4e9e91d1754bf170dd7e93781f1"}, +{"name":"gitlab-dangerfiles","version":"3.6.7","platform":"ruby","checksum":"ebd898ec0e8ed3edea281b2f703000c502c6b412cbcadc1265ddbc31ffb0c579"}, {"name":"gitlab-experiment","version":"0.7.1","platform":"ruby","checksum":"166dddb3aa83428bcaa93c35684ed01dc4d61f321fd2ae40b020806dc54a7824"}, {"name":"gitlab-fog-azure-rm","version":"1.4.0","platform":"ruby","checksum":"af4163c32b028aa5208814a3f4765a5817d50527e6c61931f766bf18a2e0eb7e"}, {"name":"gitlab-labkit","version":"0.29.0","platform":"ruby","checksum":"eb19ac5c11698683775ab847a3441d7af87d72fbaec38d635149fb65c5d9b427"}, diff --git a/Gemfile.lock b/Gemfile.lock index be3cd068e5d..556647fbac4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -570,7 +570,7 @@ GEM terminal-table (>= 1.5.1) gitlab-chronic (0.10.5) numerizer (~> 0.2) - gitlab-dangerfiles (3.6.6) + gitlab-dangerfiles (3.6.7) danger (>= 8.4.5) danger-gitlab (>= 8.0.0) rake diff --git a/app/assets/javascripts/artifacts/graphql/queries/get_job_artifacts.query.graphql b/app/assets/javascripts/artifacts/graphql/queries/get_job_artifacts.query.graphql index 89a24d7891e..5737f9f8e8d 100644 --- a/app/assets/javascripts/artifacts/graphql/queries/get_job_artifacts.query.graphql +++ b/app/assets/javascripts/artifacts/graphql/queries/get_job_artifacts.query.graphql @@ -10,13 +10,12 @@ query getJobArtifacts( project(fullPath: $projectPath) { id jobs( - statuses: [SUCCESS, FAILED] + withArtifacts: true first: $firstPageSize last: $lastPageSize after: $nextPageCursor before: $prevPageCursor ) { - count nodes { id name diff --git a/app/assets/javascripts/contributors/components/contributors.vue b/app/assets/javascripts/contributors/components/contributors.vue index 6d94af66092..17e6cc87ff8 100644 --- a/app/assets/javascripts/contributors/components/contributors.vue +++ b/app/assets/javascripts/contributors/components/contributors.vue @@ -238,7 +238,6 @@ export default { :project-id="projectId" :enabled-ref-types="$options.refTypes" :translations="$options.i18n.refSelectorTranslations" - toggle-button-class="gl-max-w-26" @input="visitBranch" /> </div> diff --git a/app/assets/javascripts/ref/components/ref_selector.vue b/app/assets/javascripts/ref/components/ref_selector.vue index 70b8604b3f1..2f5b5bcebd6 100644 --- a/app/assets/javascripts/ref/components/ref_selector.vue +++ b/app/assets/javascripts/ref/components/ref_selector.vue @@ -142,6 +142,7 @@ export default { 'gl-inset-border-1-red-500!': !this.state, 'gl-font-monospace': Boolean(this.selectedRef), }, + 'gl-max-w-26', ]; if (Array.isArray(this.toggleButtonClass)) { @@ -257,7 +258,7 @@ export default { :header-text="i18n.dropdownHeader" :toggle-class="extendedToggleButtonClass" :text="buttonText" - class="ref-selector gl-w-full" + class="ref-selector" v-bind="$attrs" v-on="$listeners" @shown="focusSearchBox" diff --git a/app/assets/stylesheets/startup/startup-dark.scss b/app/assets/stylesheets/startup/startup-dark.scss index 1ff3d183b82..df81d9fbbd0 100644 --- a/app/assets/stylesheets/startup/startup-dark.scss +++ b/app/assets/stylesheets/startup/startup-dark.scss @@ -1839,9 +1839,15 @@ body.gl-dark .navbar-gitlab .search form .search-input { .gl-align-items-stretch { align-items: stretch; } +.gl-flex-grow-0\! { + flex-grow: 0 !important; +} .gl-flex-grow-1 { flex-grow: 1; } +.gl-flex-basis-half\! { + flex-basis: 50% !important; +} .gl-justify-content-end { justify-content: flex-end; } diff --git a/app/assets/stylesheets/startup/startup-general.scss b/app/assets/stylesheets/startup/startup-general.scss index 4850195065c..adafe719892 100644 --- a/app/assets/stylesheets/startup/startup-general.scss +++ b/app/assets/stylesheets/startup/startup-general.scss @@ -1668,9 +1668,15 @@ svg.s16 { .gl-align-items-stretch { align-items: stretch; } +.gl-flex-grow-0\! { + flex-grow: 0 !important; +} .gl-flex-grow-1 { flex-grow: 1; } +.gl-flex-basis-half\! { + flex-basis: 50% !important; +} .gl-justify-content-end { justify-content: flex-end; } diff --git a/app/finders/ci/jobs_finder.rb b/app/finders/ci/jobs_finder.rb index 1627e41a02d..8620dff6973 100644 --- a/app/finders/ci/jobs_finder.rb +++ b/app/finders/ci/jobs_finder.rb @@ -75,7 +75,7 @@ module Ci def filter_by_with_artifacts(builds) if params[:with_artifacts] - builds.with_erasable_artifacts + builds.with_any_artifacts else builds end diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb index 4dffaa06364..f8b3777841d 100644 --- a/app/models/ci/build.rb +++ b/app/models/ci/build.rb @@ -90,6 +90,12 @@ module Ci scope :unstarted, -> { where(runner_id: nil) } + scope :with_any_artifacts, -> do + where('EXISTS (?)', + Ci::JobArtifact.select(1).where("#{Ci::Build.quoted_table_name}.id = #{Ci::JobArtifact.quoted_table_name}.job_id") + ) + end + scope :with_downloadable_artifacts, -> do where('EXISTS (?)', Ci::JobArtifact.select(1) diff --git a/app/models/issue.rb b/app/models/issue.rb index 6e0d228ab8c..bea86168c8d 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -181,7 +181,7 @@ class Issue < ApplicationRecord scope :confidential_only, -> { where(confidential: true) } scope :without_hidden, -> { - where.not(author_id: Users::BannedUser.select(:user_id)) + where('NOT EXISTS (?)', Users::BannedUser.select(1).where('issues.author_id = banned_users.user_id')) } scope :counts_by_state, -> { reorder(nil).group(:state_id).count } diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml index 5c7010bf523..6d000c3e9ad 100644 --- a/app/views/layouts/header/_default.html.haml +++ b/app/views/layouts/header/_default.html.haml @@ -133,7 +133,7 @@ %li.nav-item = render Pajamas::ButtonComponent.new(href: new_user_registration_path) do = _('Register') - %li.nav-item + %li.nav-item{ class: 'gl-flex-grow-0! gl-flex-basis-half!' } = link_to _('Sign in'), new_session_path(:user, redirect_to_referer: 'yes') %button.navbar-toggler.d-block.d-sm-none{ type: 'button', class: 'gl-border-none!', data: { testid: 'top-nav-responsive-toggle', qa_selector: 'mobile_navbar_button' } } diff --git a/app/views/projects/tree/_tree_header.html.haml b/app/views/projects/tree/_tree_header.html.haml index fd807350245..51555293bfb 100644 --- a/app/views/projects/tree/_tree_header.html.haml +++ b/app/views/projects/tree/_tree_header.html.haml @@ -1,6 +1,6 @@ - is_project_overview = local_assigns.fetch(:is_project_overview, false) -.tree-ref-container.gl-display-flex.mb-2.mb-md-0 +.tree-ref-container.gl-display-flex.gl-flex-wrap.gl-gap-2.mb-2.mb-md-0 .tree-ref-holder #js-tree-ref-switcher{ data: { project_id: @project.id, project_root_path: project_path(@project) } } diff --git a/app/workers/all_queues.yml b/app/workers/all_queues.yml index e5d78aa9039..2a16004e743 100644 --- a/app/workers/all_queues.yml +++ b/app/workers/all_queues.yml @@ -2336,7 +2336,7 @@ :tags: [] - :name: ci_parse_secure_file_metadata :worker_name: Ci::ParseSecureFileMetadataWorker - :feature_category: :mobile_signing_deployment + :feature_category: :mobile_devops :has_external_dependencies: false :urgency: :low :resource_boundary: :unknown diff --git a/app/workers/ci/parse_secure_file_metadata_worker.rb b/app/workers/ci/parse_secure_file_metadata_worker.rb index 0d2495d3155..8703bb13776 100644 --- a/app/workers/ci/parse_secure_file_metadata_worker.rb +++ b/app/workers/ci/parse_secure_file_metadata_worker.rb @@ -4,7 +4,7 @@ module Ci class ParseSecureFileMetadataWorker include ::ApplicationWorker - feature_category :mobile_signing_deployment + feature_category :mobile_devops urgency :low idempotent! diff --git a/config/feature_categories.yml b/config/feature_categories.yml index 31a71913f4f..64a4eeaaea3 100644 --- a/config/feature_categories.yml +++ b/config/feature_categories.yml @@ -85,7 +85,7 @@ - merge_trains - metrics - mlops -- mobile_signing_deployment +- mobile_devops - navigation - no_code_automation - omnibus_package diff --git a/db/migrate/20230126110439_change_default_value_for_inbound_job_token_scope_enabled.rb b/db/migrate/20230126110439_change_default_value_for_inbound_job_token_scope_enabled.rb new file mode 100644 index 00000000000..9b9de65d423 --- /dev/null +++ b/db/migrate/20230126110439_change_default_value_for_inbound_job_token_scope_enabled.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +class ChangeDefaultValueForInboundJobTokenScopeEnabled < Gitlab::Database::Migration[2.1] + def up + change_column_default :project_ci_cd_settings, :inbound_job_token_scope_enabled, from: false, to: true + end + + def down + change_column_default :project_ci_cd_settings, :inbound_job_token_scope_enabled, from: true, to: false + end +end diff --git a/db/schema_migrations/20230126110439 b/db/schema_migrations/20230126110439 new file mode 100644 index 00000000000..92153a67a50 --- /dev/null +++ b/db/schema_migrations/20230126110439 @@ -0,0 +1 @@ +14bc260de13fb0a42e13777183c5977ff66a01dac4670767f9aabec975c9171e
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index e01791b7fe0..5a937446086 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -20285,7 +20285,7 @@ CREATE TABLE project_ci_cd_settings ( separated_caches boolean DEFAULT true NOT NULL, opt_in_jwt boolean DEFAULT false NOT NULL, allow_fork_pipelines_to_run_in_parent_project boolean DEFAULT true NOT NULL, - inbound_job_token_scope_enabled boolean DEFAULT false NOT NULL + inbound_job_token_scope_enabled boolean DEFAULT true NOT NULL ); CREATE SEQUENCE project_ci_cd_settings_id_seq diff --git a/glfm_specification/output_example_snapshots/html.yml b/glfm_specification/output_example_snapshots/html.yml index 03dd9894def..d02dd64b6e5 100644 --- a/glfm_specification/output_example_snapshots/html.yml +++ b/glfm_specification/output_example_snapshots/html.yml @@ -423,7 +423,7 @@ canonical: | <p>## foo</p> static: |- - <p data-sourcepos="1:1-1:28" dir="auto"><span>#</span># foo</p> + <p data-sourcepos="1:1-1:28" dir="auto"><span data-escaped-char>#</span># foo</p> wysiwyg: |- <p>## foo</p> 04_02_00__leaf_blocks__atx_headings__005: @@ -534,11 +534,11 @@ <h1>foo #</h1> static: |- <h3 data-sourcepos="1:1-1:33" dir="auto"> - <a id="user-content-foo-" class="anchor" href="#foo-" aria-hidden="true"></a>foo <span>#</span>##</h3> + <a id="user-content-foo-" class="anchor" href="#foo-" aria-hidden="true"></a>foo <span data-escaped-char>#</span>##</h3> <h2 data-sourcepos="2:1-2:32" dir="auto"> - <a id="user-content-foo--1" class="anchor" href="#foo--1" aria-hidden="true"></a>foo #<span>#</span>#</h2> + <a id="user-content-foo--1" class="anchor" href="#foo--1" aria-hidden="true"></a>foo #<span data-escaped-char>#</span>#</h2> <h1 data-sourcepos="3:1-3:29" dir="auto"> - <a id="user-content-foo--2" class="anchor" href="#foo--2" aria-hidden="true"></a>foo <span>#</span> + <a id="user-content-foo--2" class="anchor" href="#foo--2" aria-hidden="true"></a>foo <span data-escaped-char>#</span> </h1> wysiwyg: |- <h3>foo ###</h3> @@ -4785,7 +4785,7 @@ canonical: | <p>!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~</p> static: |- - <p data-sourcepos="1:1-1:295" dir="auto"><span>!</span>"<span>#</span><span>$</span><span>%</span><span>&</span>'()*+,-./:;<=>?<span>@</span>[\]<span>^</span><span>_</span>`<span>{</span>|<span>}</span><span>~</span></p> + <p data-sourcepos="1:1-1:295" dir="auto"><span data-escaped-char>!</span>"<span data-escaped-char>#</span><span data-escaped-char>$</span><span data-escaped-char>%</span><span data-escaped-char>&</span>'()*+,-./:;<=>?<span data-escaped-char>@</span>[\]<span data-escaped-char>^</span>_`{|}<span data-escaped-char>~</span></p> wysiwyg: |- <p>!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~</p> 06_02_00__inlines__backslash_escapes__002: @@ -4810,9 +4810,9 @@ `not code` 1. not a list * not a list - <span>#</span> not a heading + <span data-escaped-char>#</span> not a heading [foo]: /url "not a reference" - <span>&</span>ouml; not a character entity</p> + <span data-escaped-char>&</span>ouml; not a character entity</p> wysiwyg: |- <p>*not emphasized* <br/> not a tag @@ -5929,7 +5929,7 @@ canonical: | <p>foo <em>_</em></p> static: |- - <p data-sourcepos="1:1-1:29" dir="auto">foo <em><span>_</span></em></p> + <p data-sourcepos="1:1-1:29" dir="auto">foo <em>_</em></p> wysiwyg: |- <p>foo <em>_</em></p> 06_05_00__inlines__emphasis_and_strong_emphasis__100: @@ -5950,7 +5950,7 @@ canonical: | <p>foo <strong>_</strong></p> static: |- - <p data-sourcepos="1:1-1:31" dir="auto">foo <strong><span>_</span></strong></p> + <p data-sourcepos="1:1-1:31" dir="auto">foo <strong>_</strong></p> wysiwyg: |- <p>foo <strong>_</strong></p> 06_05_00__inlines__emphasis_and_strong_emphasis__103: @@ -6639,7 +6639,7 @@ canonical: | <p>[bar][foo!]</p> static: |- - <p data-sourcepos="1:1-1:33" dir="auto">[bar][foo<span>!</span>]</p> + <p data-sourcepos="1:1-1:33" dir="auto">[bar][foo<span data-escaped-char>!</span>]</p> wysiwyg: |- <p>[bar][foo!]</p> <pre>[foo!]: /url</pre> @@ -7043,7 +7043,7 @@ canonical: | <p>!<a href="/url" title="title">foo</a></p> static: |- - <p data-sourcepos="1:1-1:28" dir="auto"><span>!</span><a href="/url" title="title">foo</a></p> + <p data-sourcepos="1:1-1:28" dir="auto"><span data-escaped-char>!</span><a href="/url" title="title">foo</a></p> wysiwyg: |- <p>!<a target="_blank" rel="noopener noreferrer nofollow" href="/url" title="title">foo</a></p> <pre>[foo]: /url "title"</pre> diff --git a/lib/api/ci/secure_files.rb b/lib/api/ci/secure_files.rb index 6483abcc74e..41faaf80c82 100644 --- a/lib/api/ci/secure_files.rb +++ b/lib/api/ci/secure_files.rb @@ -10,7 +10,7 @@ module API authorize! :read_secure_files, user_project end - feature_category :pipeline_authoring + feature_category :mobile_devops default_format :json diff --git a/lib/banzai/filter/markdown_post_escape_filter.rb b/lib/banzai/filter/markdown_post_escape_filter.rb index 8c0bd62f80a..4d37fba33aa 100644 --- a/lib/banzai/filter/markdown_post_escape_filter.rb +++ b/lib/banzai/filter/markdown_post_escape_filter.rb @@ -7,11 +7,11 @@ module Banzai LITERAL_KEYWORD = MarkdownPreEscapeFilter::LITERAL_KEYWORD LITERAL_REGEX = %r{#{LITERAL_KEYWORD}-(.*?)-#{LITERAL_KEYWORD}}.freeze NOT_LITERAL_REGEX = %r{#{LITERAL_KEYWORD}-((%5C|\\).+?)-#{LITERAL_KEYWORD}}.freeze - SPAN_REGEX = %r{<span>(.*?)</span>}.freeze + SPAN_REGEX = %r{<span data-escaped-char>(.*?)</span>}.freeze - XPATH_A = Gitlab::Utils::Nokogiri.css_to_xpath('a').freeze - XPATH_LANG_TAG = Gitlab::Utils::Nokogiri.css_to_xpath('pre').freeze - XPATH_CODE_SPAN = Gitlab::Utils::Nokogiri.css_to_xpath('code > span').freeze + XPATH_A = Gitlab::Utils::Nokogiri.css_to_xpath('a').freeze + XPATH_LANG_TAG = Gitlab::Utils::Nokogiri.css_to_xpath('pre').freeze + XPATH_ESCAPED_CHAR = Gitlab::Utils::Nokogiri.css_to_xpath('span[data-escaped-char]').freeze def call return doc unless result[:escaped_literals] @@ -22,7 +22,7 @@ module Banzai @doc = parse_html(new_html) remove_spans_in_certain_attributes - remove_spans_in_code + remove_unnecessary_escapes doc end @@ -57,7 +57,7 @@ module Banzai escaped_item = Banzai::Filter::MarkdownPreEscapeFilter::ESCAPABLE_CHARS.find { |item| item[:token] == last_match_token } escaped_char = escaped_item ? escaped_item[:char] : ::Regexp.last_match(1) - "<span>#{escaped_char}</span>" + "<span data-escaped-char>#{escaped_char}</span>" end html @@ -75,14 +75,55 @@ module Banzai end end - # Any `<span>` that makes it into a `<code>` element is from the math processing, - # convert back to the escaped character, such as `\$` - def remove_spans_in_code - doc.xpath(XPATH_CODE_SPAN).each do |node| - escaped_item = Banzai::Filter::MarkdownPreEscapeFilter::ESCAPABLE_CHARS.find { |item| item[:char] == node.content && item[:latex] } + def remove_unnecessary_escapes + doc.xpath(XPATH_ESCAPED_CHAR).each do |node| + escaped_item = Banzai::Filter::MarkdownPreEscapeFilter::ESCAPABLE_CHARS.find { |item| item[:char] == node.content } + + next unless escaped_item + + if node.parent.name == 'code' + # For any `data-escaped-char` that makes it into a `<code>` element, + # convert back to the escaped character, such as `\$`. Usually this would + # only happen for dollar math + content = +escaped_item[:escaped] + elsif escaped_item[:latex] && !escaped_item[:reference] + # Character only used in latex, since it's outside of a code block we can + # transform into the regular character + content = +escaped_item[:char] + else + # Escaped reference character, so leave as is. This is so that our normal + # reference processing can be short-circuited by escaping the reference, + # like \@username + next + end + + merge_adjacent_text_nodes(node, content) + end + end + + def text_node?(node) + node.is_a?(Nokogiri::XML::Text) + end - node.replace(escaped_item[:escaped]) if escaped_item + # Merge directly adjacent text nodes and replace existing node with + # the merged content. For example, the document could be + # #(Text "~c_bug"), #(Element:0x57724 { name = "span" }, children = [ #(Text "_")] })] + # Our reference processing requires a single string of text to match against. So even if it was + # #(Text "~c_bug"), #(Text "_") + # it wouldn't match. Merging together will give + # #(Text "~c_bug_") + def merge_adjacent_text_nodes(node, content) + if text_node?(node.previous) + content.prepend(node.previous.content) + node.previous.remove end + + if text_node?(node.next) + content.concat(node.next.content) + node.next.remove + end + + node.replace(content) end end end diff --git a/lib/banzai/filter/sanitization_filter.rb b/lib/banzai/filter/sanitization_filter.rb index de9b846efe9..b119c2ffccf 100644 --- a/lib/banzai/filter/sanitization_filter.rb +++ b/lib/banzai/filter/sanitization_filter.rb @@ -20,6 +20,7 @@ module Banzai # Allow the 'data-sourcepos' from CommonMark on all elements allowlist[:attributes][:all].push('data-sourcepos') + allowlist[:attributes][:all].push('data-escaped-char') # Remove any `style` properties not required for table alignment allowlist[:transformers].push(self.class.remove_unsafe_table_style) diff --git a/lib/bulk_imports/projects/pipelines/references_pipeline.rb b/lib/bulk_imports/projects/pipelines/references_pipeline.rb index 9c76f96c7be..8f44f3ffe6a 100644 --- a/lib/bulk_imports/projects/pipelines/references_pipeline.rb +++ b/lib/bulk_imports/projects/pipelines/references_pipeline.rb @@ -12,6 +12,8 @@ module BulkImports data = Enumerator.new do |enum| add_matching_objects(portable.issues, enum) add_matching_objects(portable.merge_requests, enum) + add_notes(portable.issues, enum) + add_notes(portable.merge_requests, enum) end BulkImports::Pipeline::ExtractedData.new(data: data) @@ -39,9 +41,16 @@ module BulkImports collection.each_batch(of: BATCH_SIZE, column: :iid) do |batch| batch.each do |object| enum << object if object_has_reference?(object) + end + end + end + def add_notes(collection, enum) + collection.each_batch(of: BATCH_SIZE, column: :iid) do |batch| + batch.each do |object| object.notes.each_batch(of: BATCH_SIZE) do |notes_batch| notes_batch.each do |note| + note.refresh_markdown_cache! enum << note if object_has_reference?(note) end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 95d2015d78c..a6c4917abf7 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -11198,9 +11198,21 @@ msgstr "" msgid "ContributionAnalytics|%{pushes}, more than %{commits} by %{contributors}." msgstr "" +msgid "ContributionAnalytics|Approved MRs" +msgstr "" + +msgid "ContributionAnalytics|Closed MRs" +msgstr "" + +msgid "ContributionAnalytics|Closed issues" +msgstr "" + msgid "ContributionAnalytics|Contribution analytics for issues, merge requests and push events since %{start_date}" msgstr "" +msgid "ContributionAnalytics|Failed to load the contribution stats" +msgstr "" + msgid "ContributionAnalytics|Issues" msgstr "" @@ -11213,9 +11225,18 @@ msgstr "" msgid "ContributionAnalytics|Last week" msgstr "" +msgid "ContributionAnalytics|Loading contribution stats for group members" +msgstr "" + msgid "ContributionAnalytics|Merge requests" msgstr "" +msgid "ContributionAnalytics|Merged MRs" +msgstr "" + +msgid "ContributionAnalytics|Name" +msgstr "" + msgid "ContributionAnalytics|No issues for the selected time period." msgstr "" @@ -11225,6 +11246,15 @@ msgstr "" msgid "ContributionAnalytics|No pushes for the selected time period." msgstr "" +msgid "ContributionAnalytics|Opened MRs" +msgstr "" + +msgid "ContributionAnalytics|Opened issues" +msgstr "" + +msgid "ContributionAnalytics|Pushed" +msgstr "" + msgid "ContributionAnalytics|The given date range is larger than 31 days" msgstr "" @@ -11234,6 +11264,9 @@ msgstr "" msgid "ContributionAnalytics|There is too much data to calculate. Try lowering the period_limit setting in the insights configuration file." msgstr "" +msgid "ContributionAnalytics|Total Contributions" +msgstr "" + msgid "Contributions for %{calendar_date}" msgstr "" diff --git a/spec/features/projects/artifacts/user_views_project_artifacts_page_spec.rb b/spec/features/projects/artifacts/user_views_project_artifacts_page_spec.rb new file mode 100644 index 00000000000..f1601348e57 --- /dev/null +++ b/spec/features/projects/artifacts/user_views_project_artifacts_page_spec.rb @@ -0,0 +1,40 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe 'User views project artifacts page', :js, feature_category: :build_artifacts do + let_it_be(:project) { create(:project, :public) } + let_it_be(:pipeline) { create(:ci_empty_pipeline, project: project) } + let_it_be(:job_with_artifacts) { create(:ci_build, :artifacts, name: 'test1', pipeline: pipeline) } + let_it_be(:job_with_trace) { create(:ci_build, :trace_artifact, name: 'test3', pipeline: pipeline) } + let_it_be(:job_without_artifacts) { create(:ci_build, name: 'test2', pipeline: pipeline) } + + let(:path) { project_artifacts_path(project) } + + context 'when browsing artifacts page' do + before do + visit(path) + + wait_for_requests + end + + it 'lists the project jobs and their artifacts' do + page.within('main#content-body') do + page.within('table thead') do + expect(page).to have_content('Artifacts') + .and have_content('Job') + .and have_content('Size') + end + + find_all('[data-testid="job-artifacts-count"').each(&:click) + + expect(page).to have_content(job_with_artifacts.name) + expect(page).to have_content(job_with_trace.name) + expect(page).not_to have_content(job_without_artifacts.name) + + expect(page).to have_content('archive').and have_content('metadata') + expect(page).to have_content('trace') + end + end + end +end diff --git a/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap b/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap index 50cbef21fd5..2f441f0f747 100644 --- a/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap +++ b/spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap @@ -16,7 +16,6 @@ exports[`Contributors charts should render charts and a RefSelector when loading name="" projectid="23" state="true" - togglebuttonclass="gl-max-w-26" translations="[object Object]" value="main" /> diff --git a/spec/lib/banzai/pipeline/full_pipeline_spec.rb b/spec/lib/banzai/pipeline/full_pipeline_spec.rb index c1d5f16b562..ca05a353d47 100644 --- a/spec/lib/banzai/pipeline/full_pipeline_spec.rb +++ b/spec/lib/banzai/pipeline/full_pipeline_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe Banzai::Pipeline::FullPipeline, feature_category: :team_planning do + using RSpec::Parameterized::TableSyntax + describe 'References' do let(:project) { create(:project, :public) } let(:issue) { create(:issue, project: project) } @@ -157,14 +159,44 @@ RSpec.describe Banzai::Pipeline::FullPipeline, feature_category: :team_planning markdown = "\\#{issue.to_reference}" output = described_class.to_html(markdown, project: project) - expect(output).to include("<span>#</span>#{issue.iid}") + expect(output).to include("<span data-escaped-char>#</span>#{issue.iid}") end it 'converts user reference with escaped underscore because of italics' do markdown = '_@test\__' output = described_class.to_html(markdown, project: project) - expect(output).to include('<em>@test<span>_</span></em>') + expect(output).to include('<em>@test_</em>') + end + + context 'when a reference (such as a label name) is autocompleted with characters that require escaping' do + # Labels are fairly representative of the type of characters that can be in a reference + # and aligns with the testing in spec/frontend/gfm_auto_complete_spec.js + where(:valid, :label_name, :markdown) do + # These are currently not supported + # true | 'a~bug' | '~"a\~bug"' + # true | 'b~~bug~~' | '~"b\~\~bug\~\~"' + + true | 'c_bug_' | '~c_bug\_' + true | 'c_bug_' | 'Label ~c_bug\_ and _more_ text' + true | 'd _bug_' | '~"d \_bug\_"' + true | 'e*bug*' | '~"e\*bug\*"' + true | 'f *bug*' | '~"f \*bug\*"' + true | 'f *bug*' | 'Label ~"f \*bug\*" **with** more text' + true | 'g`bug`' | '~"g\`bug\`" ' + true | 'h `bug`' | '~"h \`bug\`"' + end + + with_them do + it 'detects valid escaped reference' do + create(:label, name: label_name, project: project) + + result = Banzai::Pipeline::FullPipeline.call(markdown, project: project) + + expect(result[:output].css('a').first.attr('class')).to eq 'gfm gfm-label has-tooltip gl-link gl-label-link' + expect(result[:output].css('a').first.content).to eq label_name + end + end end end diff --git a/spec/lib/banzai/pipeline/plain_markdown_pipeline_spec.rb b/spec/lib/banzai/pipeline/plain_markdown_pipeline_spec.rb index 0e4a4e4492e..e7c15ed9cf6 100644 --- a/spec/lib/banzai/pipeline/plain_markdown_pipeline_spec.rb +++ b/spec/lib/banzai/pipeline/plain_markdown_pipeline_spec.rb @@ -15,10 +15,15 @@ RSpec.describe Banzai::Pipeline::PlainMarkdownPipeline, feature_category: :team_ result = described_class.call(markdown, project: project) output = result[:output].to_html - Banzai::Filter::MarkdownPreEscapeFilter::ESCAPABLE_CHARS.pluck(:char).each do |char| - char = '&' if char == '&' - - expect(output).to include("<span>#{char}</span>") + Banzai::Filter::MarkdownPreEscapeFilter::ESCAPABLE_CHARS.each do |item| + char = item[:char] == '&' ? '&' : item[:char] + + if item[:reference] + expect(output).to include("<span data-escaped-char>#{char}</span>") + else + expect(output).not_to include("<span data-escaped-char>#{char}</span>") + expect(output).to include(char) + end end expect(result[:escaped_literals]).to be_truthy diff --git a/spec/lib/bulk_imports/projects/pipelines/references_pipeline_spec.rb b/spec/lib/bulk_imports/projects/pipelines/references_pipeline_spec.rb index 3c3d0a6d1c4..8cc128860e0 100644 --- a/spec/lib/bulk_imports/projects/pipelines/references_pipeline_spec.rb +++ b/spec/lib/bulk_imports/projects/pipelines/references_pipeline_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe BulkImports::Projects::Pipelines::ReferencesPipeline do +RSpec.describe BulkImports::Projects::Pipelines::ReferencesPipeline, feature_category: :importers do let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project) } let_it_be(:bulk_import) { create(:bulk_import, user: user) } @@ -19,11 +19,44 @@ RSpec.describe BulkImports::Projects::Pipelines::ReferencesPipeline do let_it_be(:tracker) { create(:bulk_import_tracker, entity: entity) } let_it_be(:context) { BulkImports::Pipeline::Context.new(tracker) } - let(:issue) { create(:issue, project: project, description: 'https://my.gitlab.com/source/full/path/-/issues/1') } - let(:mr) { create(:merge_request, source_project: project, description: 'https://my.gitlab.com/source/full/path/-/merge_requests/1') } - let(:issue_note) { create(:note, project: project, noteable: issue, note: 'https://my.gitlab.com/source/full/path/-/issues/1') } - let(:mr_note) { create(:note, project: project, noteable: mr, note: 'https://my.gitlab.com/source/full/path/-/merge_requests/1') } + let(:mr) do + create( + :merge_request, + source_project: project, + description: 'https://my.gitlab.com/source/full/path/-/merge_requests/1' + ) + end + + let(:issue_note) do + create( + :note, + project: project, + noteable: issue, + note: 'https://my.gitlab.com/source/full/path/-/issues/1' + ) + end + + let(:mr_note) do + create( + :note, + project: project, + noteable: mr, + note: 'https://my.gitlab.com/source/full/path/-/merge_requests/1' + ) + end + + let(:old_note_html) { 'old note_html' } + let(:system_note) do + create( + :note, + project: project, + system: true, + noteable: issue, + note: "mentioned in merge request !#{mr.iid}", + note_html: old_note_html + ) + end subject(:pipeline) { described_class.new(context) } @@ -32,7 +65,7 @@ RSpec.describe BulkImports::Projects::Pipelines::ReferencesPipeline do end def create_project_data - [issue, mr, issue_note, mr_note] + [issue, mr, issue_note, mr_note, system_note] end describe '#extract' do @@ -43,6 +76,10 @@ RSpec.describe BulkImports::Projects::Pipelines::ReferencesPipeline do expect(extracted_data).to be_instance_of(BulkImports::Pipeline::ExtractedData) expect(extracted_data.data).to contain_exactly(issue_note, mr, issue, mr_note) + expect(system_note.note_html).not_to eq(old_note_html) + expect(system_note.note_html) + .to include("class=\"gfm gfm-merge_request\">!#{mr.iid}</a></p>") + .and include("<a href=\"/namespace1/project") end end @@ -122,9 +159,11 @@ RSpec.describe BulkImports::Projects::Pipelines::ReferencesPipeline do it 'does not save the object' do expect(mr).not_to receive(:save!) expect(mr_note).not_to receive(:save!) + expect(system_note).not_to receive(:save!) subject.load(context, mr) subject.load(context, mr_note) + subject.load(context, system_note) end end end diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb index cbbd1f5cf54..7b358e35d3a 100644 --- a/spec/models/ci/build_spec.rb +++ b/spec/models/ci/build_spec.rb @@ -202,6 +202,34 @@ RSpec.describe Ci::Build, feature_category: :continuous_integration, factory_def end end + describe '.with_any_artifacts' do + subject { described_class.with_any_artifacts } + + context 'when job does not have any artifacts' do + it 'does not return the job' do + job = create(:ci_build, project: project) + + is_expected.not_to include(job) + end + end + + ::Ci::JobArtifact.file_types.each_key do |type| + context "when job has a #{type} artifact" do + it 'returns the job' do + job = create(:ci_build, project: project) + create( + :ci_job_artifact, + file_format: ::Ci::JobArtifact::TYPE_AND_FORMAT_PAIRS[type.to_sym], + file_type: type, + job: job + ) + + is_expected.to include(job) + end + end + end + end + describe '.with_live_trace' do subject { described_class.with_live_trace } diff --git a/spec/models/integrations/apple_app_store_spec.rb b/spec/models/integrations/apple_app_store_spec.rb index e35daa4ae77..1a57f556895 100644 --- a/spec/models/integrations/apple_app_store_spec.rb +++ b/spec/models/integrations/apple_app_store_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Integrations::AppleAppStore, feature_category: :mobile_signing_deployment do +RSpec.describe Integrations::AppleAppStore, feature_category: :mobile_devops do describe 'Validations' do context 'when active' do before do diff --git a/spec/models/project_ci_cd_setting_spec.rb b/spec/models/project_ci_cd_setting_spec.rb index 47e0ef56844..2c490c33747 100644 --- a/spec/models/project_ci_cd_setting_spec.rb +++ b/spec/models/project_ci_cd_setting_spec.rb @@ -33,12 +33,7 @@ RSpec.describe ProjectCiCdSetting do stub_feature_flags(ci_inbound_job_token_scope: true) end - it 'sets inbound_job_token_scope_enabled to true' do - project = build(:project) - setting = project.build_ci_cd_settings - - expect(setting.inbound_job_token_scope_enabled).to eq(true) - end + it { is_expected.to be_inbound_job_token_scope_enabled } end context 'when feature flag ci_inbound_job_token_scope is disabled' do @@ -46,12 +41,7 @@ RSpec.describe ProjectCiCdSetting do stub_feature_flags(ci_inbound_job_token_scope: false) end - it 'sets inbound_job_token_scope_enabled to false' do - project = build(:project) - setting = project.build_ci_cd_settings - - expect(setting.inbound_job_token_scope_enabled).to eq(false) - end + it { is_expected.not_to be_inbound_job_token_scope_enabled } end end diff --git a/spec/requests/api/ci/secure_files_spec.rb b/spec/requests/api/ci/secure_files_spec.rb index 0e9ee4822ef..fc988800b56 100644 --- a/spec/requests/api/ci/secure_files_spec.rb +++ b/spec/requests/api/ci/secure_files_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe API::Ci::SecureFiles, feature_category: :pipeline_authoring do +RSpec.describe API::Ci::SecureFiles, feature_category: :mobile_devops do before do stub_ci_secure_file_object_storage stub_feature_flags(ci_secure_files_read_only: false) diff --git a/spec/rubocop/cop/scalability/file_uploads_spec.rb b/spec/rubocop/cop/scalability/file_uploads_spec.rb index 1395615479f..43ac9457ed6 100644 --- a/spec/rubocop/cop/scalability/file_uploads_spec.rb +++ b/spec/rubocop/cop/scalability/file_uploads_spec.rb @@ -3,7 +3,7 @@ require 'rubocop_spec_helper' require_relative '../../../../rubocop/cop/scalability/file_uploads' -RSpec.describe RuboCop::Cop::Scalability::FileUploads do +RSpec.describe RuboCop::Cop::Scalability::FileUploads, feature_category: :scalability do let(:message) { 'Do not upload files without workhorse acceleration. Please refer to https://docs.gitlab.com/ee/development/uploads.html' } context 'with required params' do diff --git a/spec/tooling/danger/stable_branch_spec.rb b/spec/tooling/danger/stable_branch_spec.rb index 08fd25b30e0..87c69a3f9f8 100644 --- a/spec/tooling/danger/stable_branch_spec.rb +++ b/spec/tooling/danger/stable_branch_spec.rb @@ -34,6 +34,14 @@ RSpec.describe Tooling::Danger::StableBranch, feature_category: :delivery do end end + shared_examples 'with a warning' do |failure_message| + it 'fails' do + expect(stable_branch).to receive(:warn).with(failure_message) + + subject + end + end + context 'when not applicable' do where(:stable_branch?, :security_mr?) do true | true @@ -103,17 +111,13 @@ RSpec.describe Tooling::Danger::StableBranch, feature_category: :delivery do context 'when not an applicable version' do let(:target_branch) { '14-9-stable-ee' } - it_behaves_like 'with a failure', described_class::VERSION_ERROR_MESSAGE + it_behaves_like 'with a warning', described_class::VERSION_ERROR_MESSAGE end context 'when the version API request fails' do let(:response_success) { false } - it 'adds a warning' do - expect(stable_branch).to receive(:warn).with(described_class::FAILED_VERSION_REQUEST_MESSAGE) - - subject - end + it_behaves_like 'with a warning', described_class::FAILED_VERSION_REQUEST_MESSAGE end context 'when more than one page of versions is needed' do diff --git a/tooling/danger/stable_branch.rb b/tooling/danger/stable_branch.rb index 6c0b94b4f06..034e31bb0cc 100644 --- a/tooling/danger/stable_branch.rb +++ b/tooling/danger/stable_branch.rb @@ -33,7 +33,7 @@ module Tooling MSG VERSION_ERROR_MESSAGE = <<~MSG - Patches are only being accepted on the most recent 3 minor versions of GitLab. #{MAINTENANCE_POLICY_MESSAGE} + Patches are generally only accepted on the most recent 3 minor versions of GitLab. #{MAINTENANCE_POLICY_MESSAGE} MSG FAILED_VERSION_REQUEST_MESSAGE = <<~MSG @@ -46,7 +46,8 @@ module Tooling fail FEATURE_ERROR_MESSAGE if has_feature_label? fail BUG_ERROR_MESSAGE unless has_bug_label? - fail VERSION_ERROR_MESSAGE unless targeting_patchable_version? + + warn VERSION_ERROR_MESSAGE unless targeting_patchable_version? end # rubocop:enable Style/SignalException @@ -69,7 +70,6 @@ module Tooling last_three_minor_versions.include?(targeted_version) rescue VersionApiError - # don't fail the job since we do not know the recent versions warn FAILED_VERSION_REQUEST_MESSAGE true end |