summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-02-10 15:11:01 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2023-02-10 15:11:01 +0000
commitae1b3d982482280f22a907faba2c9ba02f4d1db1 (patch)
tree5c3312879a2c554e1e73a175878ea7eb7a87ac10
parente1bfa7aef2346a8c2d4e0ae0c69bf7649896f556 (diff)
downloadgitlab-ce-ae1b3d982482280f22a907faba2c9ba02f4d1db1.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--Gemfile.checksum2
-rw-r--r--Gemfile.lock2
-rw-r--r--app/assets/javascripts/artifacts/graphql/queries/get_job_artifacts.query.graphql3
-rw-r--r--app/assets/javascripts/contributors/components/contributors.vue1
-rw-r--r--app/assets/javascripts/ref/components/ref_selector.vue3
-rw-r--r--app/assets/stylesheets/startup/startup-dark.scss6
-rw-r--r--app/assets/stylesheets/startup/startup-general.scss6
-rw-r--r--app/finders/ci/jobs_finder.rb2
-rw-r--r--app/models/ci/build.rb6
-rw-r--r--app/models/issue.rb2
-rw-r--r--app/views/layouts/header/_default.html.haml2
-rw-r--r--app/views/projects/tree/_tree_header.html.haml2
-rw-r--r--app/workers/all_queues.yml2
-rw-r--r--app/workers/ci/parse_secure_file_metadata_worker.rb2
-rw-r--r--config/feature_categories.yml2
-rw-r--r--db/migrate/20230126110439_change_default_value_for_inbound_job_token_scope_enabled.rb11
-rw-r--r--db/schema_migrations/202301261104391
-rw-r--r--db/structure.sql2
-rw-r--r--glfm_specification/output_example_snapshots/html.yml22
-rw-r--r--lib/api/ci/secure_files.rb2
-rw-r--r--lib/banzai/filter/markdown_post_escape_filter.rb65
-rw-r--r--lib/banzai/filter/sanitization_filter.rb1
-rw-r--r--lib/bulk_imports/projects/pipelines/references_pipeline.rb9
-rw-r--r--locale/gitlab.pot33
-rw-r--r--spec/features/projects/artifacts/user_views_project_artifacts_page_spec.rb40
-rw-r--r--spec/frontend/contributors/component/__snapshots__/contributors_spec.js.snap1
-rw-r--r--spec/lib/banzai/pipeline/full_pipeline_spec.rb36
-rw-r--r--spec/lib/banzai/pipeline/plain_markdown_pipeline_spec.rb13
-rw-r--r--spec/lib/bulk_imports/projects/pipelines/references_pipeline_spec.rb51
-rw-r--r--spec/models/ci/build_spec.rb28
-rw-r--r--spec/models/integrations/apple_app_store_spec.rb2
-rw-r--r--spec/models/project_ci_cd_setting_spec.rb14
-rw-r--r--spec/requests/api/ci/secure_files_spec.rb2
-rw-r--r--spec/rubocop/cop/scalability/file_uploads_spec.rb2
-rw-r--r--spec/tooling/danger/stable_branch_spec.rb16
-rw-r--r--tooling/danger/stable_branch.rb6
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>!&quot;#$%&amp;'()*+,-./:;&lt;=&gt;?@[\]^_`{|}~</p>
static: |-
- <p data-sourcepos="1:1-1:295" dir="auto"><span>!</span>"<span>#</span><span>$</span><span>%</span><span>&amp;</span>'()*+,-./:;&lt;=&gt;?<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>&amp;</span>'()*+,-./:;&lt;=&gt;?<span data-escaped-char>@</span>[\]<span data-escaped-char>^</span>_`{|}<span data-escaped-char>~</span></p>
wysiwyg: |-
<p>!"#$%&amp;'()*+,-./:;&lt;=&gt;?@[\]^_`{|}~</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>&amp;</span>ouml; not a character entity</p>
+ <span data-escaped-char>&amp;</span>ouml; not a character entity</p>
wysiwyg: |-
<p>*not emphasized*
&lt;br/&gt; 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 = '&amp;' if char == '&'
-
- expect(output).to include("<span>#{char}</span>")
+ Banzai::Filter::MarkdownPreEscapeFilter::ESCAPABLE_CHARS.each do |item|
+ char = item[:char] == '&' ? '&amp;' : 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