Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2022-09-09 06:13:24 +00:00
parent baf65ff98e
commit 377c02f959
22 changed files with 540 additions and 284 deletions

View File

@ -320,18 +320,18 @@ export default {
:can-update="canUpdate"
@error="error = $event"
/>
<work-item-assignees
v-if="workItemAssignees"
:can-update="canUpdate"
:work-item-id="workItem.id"
:assignees="workItemAssignees.assignees.nodes"
:allows-multiple-assignees="workItemAssignees.allowsMultipleAssignees"
:work-item-type="workItemType"
:can-invite-members="workItemAssignees.canInviteMembers"
:full-path="fullPath"
@error="error = $event"
/>
<template v-if="workItemsMvc2Enabled">
<work-item-assignees
v-if="workItemAssignees"
:can-update="canUpdate"
:work-item-id="workItem.id"
:assignees="workItemAssignees.assignees.nodes"
:allows-multiple-assignees="workItemAssignees.allowsMultipleAssignees"
:work-item-type="workItemType"
:can-invite-members="workItemAssignees.canInviteMembers"
:full-path="fullPath"
@error="error = $event"
/>
<work-item-labels
v-if="workItemLabels"
:work-item-id="workItem.id"

View File

@ -120,11 +120,13 @@ class Projects::JobsController < Projects::ApplicationController
end
def erase
if @build.erase(erased_by: current_user)
service_response = Ci::BuildEraseService.new(@build, current_user).execute
if service_response.success?
redirect_to project_job_path(project, @build),
notice: _("Job has been successfully erased!")
else
respond_422
head service_response.http_status
end
end

View File

@ -813,26 +813,6 @@ module Ci
destroyed_artifacts
end
def erase(opts = {})
return false unless erasable?
if project.refreshing_build_artifacts_size?
Gitlab::ProjectStatsRefreshConflictsLogger.warn_artifact_deletion_during_stats_refresh(
method: 'Ci::Build#erase',
project_id: project_id
)
end
# TODO: We should use DestroyBatchService here
# See https://gitlab.com/gitlab-org/gitlab/-/issues/369132
destroyed_artifacts = job_artifacts.destroy_all # rubocop: disable Cop/DestroyAll
Gitlab::Ci::Artifacts::Logger.log_deleted(destroyed_artifacts, 'Ci::Build#erase')
erase_trace!
update_erased!(opts[:erased_by])
end
def erasable?
complete? && (artifacts? || has_job_artifacts? || has_trace?)
end
@ -1216,14 +1196,6 @@ module Ci
job_artifacts.select { |artifact| artifact.file_type.in?(report_types) }
end
def erase_trace!
trace.erase!
end
def update_erased!(user = nil)
self.update(erased_by: user, erased_at: Time.current, artifacts_expire_at: nil)
end
def environment_url
options&.dig(:environment, :url) || persisted_environment&.external_url
end

View File

@ -0,0 +1,49 @@
# frozen_string_literal: true
module Ci
class BuildEraseService
include BaseServiceUtility
def initialize(build, current_user)
@build = build
@current_user = current_user
end
def execute
unless build.erasable?
return ServiceResponse.error(message: _('Build cannot be erased'), http_status: :unprocessable_entity)
end
if build.project.refreshing_build_artifacts_size?
Gitlab::ProjectStatsRefreshConflictsLogger.warn_artifact_deletion_during_stats_refresh(
method: 'Ci::BuildEraseService#execute',
project_id: build.project_id
)
end
destroy_artifacts
erase_trace!
update_erased!
ServiceResponse.success(payload: build)
end
private
attr_reader :build, :current_user
def destroy_artifacts
# fix_expire_at is false because in this case we want to explicitly delete the job artifacts
# this flag is a workaround that will be removed with https://gitlab.com/gitlab-org/gitlab/-/issues/355833
Ci::JobArtifacts::DestroyBatchService.new(build.job_artifacts, fix_expire_at: false).execute
end
def erase_trace!
build.trace.erase!
end
def update_erased!
build.update(erased_by: current_user, erased_at: Time.current, artifacts_expire_at: nil)
end
end
end

View File

@ -0,0 +1,8 @@
---
name: markdown_dollar_math
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/94111
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/371180
milestone: '15.4'
type: development
group: group::project management
default_enabled: false

View File

@ -489,7 +489,7 @@ If you need to manually remove **all** job artifacts associated with multiple jo
print "Ci::Build ID #{build.id}... "
if build.erasable?
build.erase(erased_by: admin_user)
Ci::BuildEraseService.new(build, admin_user).execute
puts "Erased"
else
puts "Skipped (Nothing to erase or not erasable)"
@ -497,6 +497,9 @@ If you need to manually remove **all** job artifacts associated with multiple jo
end
```
In [GitLab 15.3 and earlier](https://gitlab.com/gitlab-org/gitlab/-/issues/369132), replace
`Ci::BuildEraseService.new(build, admin_user).execute` with `build.erase(erased_by: admin_user)`.
`1.week.ago` is a Rails `ActiveSupport::Duration` method which calculates a new
date or time in the past. Other valid examples are:

View File

@ -514,7 +514,7 @@ pass this variable to the downstream pipeline using variable inheritance:
needs:
- project: my/upstream_project
job: build_artifacts
ref: UPSTREAM_REF
ref: $UPSTREAM_REF
artifacts: true
```

View File

@ -346,10 +346,13 @@ backslash `\`. Otherwise the diff highlight does not render correctly:
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#math).
Math written in LaTeX syntax is rendered with [KaTeX](https://github.com/KaTeX/KaTeX).
_KaTeX only supports a [subset](https://katex.org/docs/supported.html) of LaTeX._
This syntax also works for the Asciidoctor `:stem: latexmath`. For details, see
the [Asciidoctor user manual](https://asciidoctor.org/docs/user-manual/#activating-stem-support).
Math written between dollar signs `$` is rendered inline with the text. Math written
in a [code block](#code-spans-and-blocks) with the language declared as `math` is rendered
on a separate line:
Math written between dollar signs with backticks (``$`...`$``) is rendered
inline with the text. Math written in a [code block](#code-spans-and-blocks) with
the language declared as `math` is rendered on a separate line:
````markdown
This math is inline: $`a^2+b^2=c^2`$.
@ -369,10 +372,44 @@ This math is on a separate line:
a^2+b^2=c^2
```
_KaTeX only supports a [subset](https://katex.org/docs/supported.html) of LaTeX._
#### LaTeX-compatible fencing
This syntax also works for the Asciidoctor `:stem: latexmath`. For details, see
the [Asciidoctor user manual](https://asciidoctor.org/docs/user-manual/#activating-stem-support).
> Introduced in GitLab 15.4 [with a flag](../administration/feature_flags.md) named `markdown_dollar_math`. Disabled by default.
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#latex-compatible-fencing).
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available,
ask an administrator to [enable the feature flag](../administration/feature_flags.md) named `markdown_dollar_math`.
On GitLab.com, this feature is available.
The feature is not ready for production use.
Math written between dollar signs (`$...$`) is rendered
inline with the text. Math written between double dollar signs (`$$...$$`) is rendered
on a separate line:
````markdown
This math is inline: $a^2+b^2=c^2$.
This math is on a separate line: $$a^2+b^2=c^2$$
This math is on a separate line:
$$
a^2+b^2=c^2
$$
````
<!-- Uncomment the example below when the flag is enabled on GitLab.com -->
<!-- This math is inline: $a^2+b^2=c^2$.
This math is on a separate line: $$a^2+b^2=c^2$$
This math is on a separate line:
$$
a^2+b^2=c^2
$$ -->
### Task lists

View File

@ -99,6 +99,24 @@ To delete a task:
1. In the task window, in the options menu (**{ellipsis_v}**), select **Delete task**.
1. Select **OK**.
## Assign users to a task
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/334810) in GitLab 15.4.
To show who is responsible for a task, you can assign users to it.
Prerequisites:
- You must have at least the Reporter role for the project.
To change the assignee on a task:
1. In the issue description, in the **Tasks** section, select the title of the task you want to edit.
The task window opens.
1. Next to **Assignees**, select **Add assignees**.
1. From the dropdown list, select the user(s) to add as an assignee.
1. Select any area outside the dropdown list.
## Set task weight **(PREMIUM)**
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/362550) in GitLab 15.3.

View File

@ -142,7 +142,8 @@ module API
reject_if_build_artifacts_size_refreshing!(build.project)
build.erase(erased_by: current_user)
::Ci::BuildEraseService.new(build, current_user).execute
present build, with: Entities::Ci::Job
end

View File

@ -7,7 +7,7 @@ require 'uri'
# - app/assets/javascripts/behaviors/markdown/nodes/code_block.js
module Banzai
module Filter
# HTML filter that adds class="code math" and removes the dollar sign in $`2+2`$.
# HTML filter that implements our math syntax, adding class="code math"
#
class MathFilter < HTML::Pipeline::Filter
CSS_MATH = 'pre.code.language-math'
@ -15,14 +15,42 @@ module Banzai
CSS_CODE = 'code'
XPATH_CODE = Gitlab::Utils::Nokogiri.css_to_xpath(CSS_CODE).freeze
# These are based on the Pandoc heuristics,
# https://pandoc.org/MANUAL.html#extension-tex_math_dollars
# Note: at this time, using a dollar sign literal, `\$` inside
# a math statement does not work correctly.
# Corresponds to the "$...$" syntax
DOLLAR_INLINE_PATTERN = %r{
(?<matched>\$(?<math>(?:\S[^$\n]*?\S|[^$\s]))\$)(?:[^\d]|$)
}x.freeze
# Corresponds to the "$$...$$" syntax
DOLLAR_DISPLAY_INLINE_PATTERN = %r{
(?<matched>\$\$\ *(?<math>[^$\n]+?)\ *\$\$)
}x.freeze
# Corresponds to the $$\n...\n$$ syntax
DOLLAR_DISPLAY_BLOCK_PATTERN = %r{
^(?<matched>\$\$\ *\n(?<math>.*)\n\$\$\ *)$
}x.freeze
# Order dependent. Handle the `$$` syntax before the `$` syntax
DOLLAR_MATH_PIPELINE = [
{ pattern: DOLLAR_DISPLAY_INLINE_PATTERN, tag: :code, style: :display },
{ pattern: DOLLAR_DISPLAY_BLOCK_PATTERN, tag: :pre, style: :display },
{ pattern: DOLLAR_INLINE_PATTERN, tag: :code, style: :inline }
].freeze
# Do not recognize math inside these tags
IGNORED_ANCESTOR_TAGS = %w[pre code tt].to_set
# Attribute indicating inline or display math.
STYLE_ATTRIBUTE = 'data-math-style'
# Class used for tagging elements that should be rendered
TAG_CLASS = 'js-render-math'
INLINE_CLASSES = "code math #{TAG_CLASS}"
MATH_CLASSES = "code math #{TAG_CLASS}"
DOLLAR_SIGN = '$'
# Limit to how many nodes can be marked as math elements.
@ -31,8 +59,48 @@ module Banzai
RENDER_NODES_LIMIT = 50
def call
nodes_count = 0
@nodes_count = 0
process_dollar_pipeline if Feature.enabled?(:markdown_dollar_math, group)
process_dollar_backtick_inline
process_math_codeblock
doc
end
def process_dollar_pipeline
doc.xpath('descendant-or-self::text()').each do |node|
next if has_ancestor?(node, IGNORED_ANCESTOR_TAGS)
node_html = node.to_html
next unless node_html.match?(DOLLAR_INLINE_PATTERN) ||
node_html.match?(DOLLAR_DISPLAY_INLINE_PATTERN) ||
node_html.match?(DOLLAR_DISPLAY_BLOCK_PATTERN)
temp_doc = Nokogiri::HTML.fragment(node_html)
DOLLAR_MATH_PIPELINE.each do |pipeline|
temp_doc.xpath('child::text()').each do |temp_node|
html = temp_node.to_html
temp_node.content.scan(pipeline[:pattern]).each do |matched, math|
html.sub!(matched, math_html(tag: pipeline[:tag], style: pipeline[:style], math: math))
@nodes_count += 1
break if @nodes_count >= RENDER_NODES_LIMIT
end
temp_node.replace(html)
break if @nodes_count >= RENDER_NODES_LIMIT
end
end
node.replace(temp_doc)
end
end
# Corresponds to the "$`...`$" syntax
def process_dollar_backtick_inline
doc.xpath(XPATH_CODE).each do |code|
closing = code.next
opening = code.previous
@ -44,22 +112,38 @@ module Banzai
closing.content.first == DOLLAR_SIGN &&
opening.content.last == DOLLAR_SIGN
code[:class] = INLINE_CLASSES
code[:class] = MATH_CLASSES
code[STYLE_ATTRIBUTE] = 'inline'
closing.content = closing.content[1..]
opening.content = opening.content[0..-2]
nodes_count += 1
break if nodes_count >= RENDER_NODES_LIMIT
@nodes_count += 1
break if @nodes_count >= RENDER_NODES_LIMIT
end
end
end
# corresponds to the "```math...```" syntax
def process_math_codeblock
doc.xpath(XPATH_MATH).each do |el|
el[STYLE_ATTRIBUTE] = 'display'
el[:class] += " #{TAG_CLASS}"
end
end
doc
private
def math_html(tag:, math:, style:)
case tag
when :code
"<code class=\"#{MATH_CLASSES}\" data-math-style=\"#{style}\">#{math}</code>"
when :pre
"<pre class=\"#{MATH_CLASSES}\" data-math-style=\"#{style}\"><code>#{math}</code></pre>"
end
end
def group
context[:group] || context[:project]&.group
end
end
end

View File

@ -6910,6 +6910,9 @@ msgstr ""
msgid "Browse templates"
msgstr ""
msgid "Build cannot be erased"
msgstr ""
msgid "BuildArtifacts|An error occurred while fetching the artifacts"
msgstr ""
@ -34544,9 +34547,15 @@ msgstr ""
msgid "ScanExecutionPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require a %{scan} scan to run"
msgstr ""
msgid "ScanExecutionPolicy|%{thenLabelStart}Then%{thenLabelEnd} Require a %{scan} scan to run with site profile %{siteProfile} and scanner profile %{scannerProfile}"
msgstr ""
msgid "ScanExecutionPolicy|A pipeline is run"
msgstr ""
msgid "ScanExecutionPolicy|Scanner profile"
msgstr ""
msgid "ScanExecutionPolicy|Schedule"
msgstr ""
@ -34556,6 +34565,15 @@ msgstr ""
msgid "ScanExecutionPolicy|Select branches"
msgstr ""
msgid "ScanExecutionPolicy|Select scanner profile"
msgstr ""
msgid "ScanExecutionPolicy|Select site profile"
msgstr ""
msgid "ScanExecutionPolicy|Site profile"
msgstr ""
msgid "ScanExecutionPolicy|branch"
msgstr ""

View File

@ -263,6 +263,10 @@ RSpec.describe 'GitLab Markdown', :aggregate_failures do
expect(doc).to parse_task_lists
end
aggregate_failures 'MathFilter' do
expect(doc).to parse_math
end
aggregate_failures 'InlineDiffFilter' do
expect(doc).to parse_inline_diffs
end

View File

@ -283,7 +283,23 @@ References should be parseable even inside _<%= merge_request.to_reference %>_ e
- [x] Complete sub-task 1
- [X] Complete task 2
#### Gollum Tags
### Math
- Dollar math: $a^2 + b^2 = c^2$
- Dollar math and snippet reference: $d^2 + e^2 = f^2$ and <%= snippet.to_reference %>
- Dollar math and snippet in another project: <%= xsnippet.to_reference(project) %> and $g^2 + h^2 = i^2$
- Not dollar math: $20,000 and $30,000
- Dollar-backtick math: $`j^2 + k^2 = l^2`$
- Dollar display math: $$m^2 + n^2 = o^2$$
- Dollar display math and snippet reference: $$p^2 + q^2 = r^2$$ and <%= snippet.to_reference %>
- Dollar math and snippet in another project: <%= xsnippet.to_reference(project) %> and $$s^2 + t^2 = u^2$$
- Display math using a block
```math
v^2 + w^2 = x^2
```
### Gollum Tags
- [[linked-resource]]
- [[link-text|linked-resource]]
@ -326,15 +342,15 @@ However the wrapping tags cannot be mixed as such:
### Colors
`#F00`
`#F00A`
`#FF0000`
`#FF0000AA`
`RGB(0,255,0)`
`RGB(0%,100%,0%)`
`RGBA(0,255,0,0.7)`
`HSL(540,70%,50%)`
`HSLA(540,70%,50%,0.7)`
`#F00`
`#F00A`
`#FF0000`
`#FF0000AA`
`RGB(0,255,0)`
`RGB(0%,100%,0%)`
`RGBA(0,255,0,0.7)`
`HSL(540,70%,50%)`
`HSLA(540,70%,50%,0.7)`
### Mermaid

View File

@ -403,8 +403,8 @@ describe('WorkItemDetail component', () => {
});
});
describe('when work_items_mvc_2 feature flag is enabled', () => {
it('renders assignees component when assignees widget is returned from the API', async () => {
describe('assignees widget', () => {
it('renders assignees component when widget is returned from the API', async () => {
createComponent({
workItemsMvc2Enabled: true,
});
@ -413,7 +413,7 @@ describe('WorkItemDetail component', () => {
expect(findWorkItemAssignees().exists()).toBe(true);
});
it('does not render assignees component when assignees widget is not returned from the API', async () => {
it('does not render assignees component when widget is not returned from the API', async () => {
createComponent({
workItemsMvc2Enabled: true,
handler: jest
@ -426,13 +426,6 @@ describe('WorkItemDetail component', () => {
});
});
it('does not render assignees component when assignees feature flag is disabled', async () => {
createComponent();
await waitForPromises();
expect(findWorkItemAssignees().exists()).toBe(false);
});
describe('labels widget', () => {
it.each`
description | includeWidgets | exists

View File

@ -3,128 +3,179 @@
require 'spec_helper'
RSpec.describe Banzai::Filter::MathFilter do
using RSpec::Parameterized::TableSyntax
include FilterSpecHelper
it 'leaves regular inline code unchanged' do
input = "<code>2+2</code>"
doc = filter(input)
shared_examples 'inline math' do
it 'removes surrounding dollar signs and adds class code, math and js-render-math' do
doc = filter(text)
expected = result_template.gsub('<math>', '<code class="code math js-render-math" data-math-style="inline">')
expected.gsub!('</math>', '</code>')
expect(doc.to_s).to eq input
expect(doc.to_s).to eq expected
end
end
it 'removes surrounding dollar signs and adds class code, math and js-render-math' do
doc = filter("$<code>2+2</code>$")
shared_examples 'display math' do
let_it_be(:template_prefix_with_pre) { '<pre class="code math js-render-math" data-math-style="display"><code>' }
let_it_be(:template_prefix_with_code) { '<code class="code math js-render-math" data-math-style="display">' }
let(:use_pre_tags) { false }
expect(doc.to_s).to eq '<code class="code math js-render-math" data-math-style="inline">2+2</code>'
it 'removes surrounding dollar signs and adds class code, math and js-render-math' do
doc = filter(text)
template_prefix = use_pre_tags ? template_prefix_with_pre : template_prefix_with_code
template_suffix = "</code>#{'</pre>' if use_pre_tags}"
expected = result_template.gsub('<math>', template_prefix)
expected.gsub!('</math>', template_suffix)
expect(doc.to_s).to eq expected
end
end
it 'only removes surrounding dollar signs' do
doc = filter("test $<code>2+2</code>$ test")
before = doc.xpath('descendant-or-self::text()[1]').first
after = doc.xpath('descendant-or-self::text()[3]').first
describe 'inline math using $...$ syntax' do
context 'with valid syntax' do
where(:text, :result_template) do
'$2+2$' | '<math>2+2</math>'
'$22+1$ and $22 + a^2$' | '<math>22+1</math> and <math>22 + a^2</math>'
'$22 and $2+2$' | '$22 and <math>2+2</math>'
'$2+2$ $22 and flightjs/Flight$22 $2+2$' | '<math>2+2</math> $22 and flightjs/Flight$22 <math>2+2</math>'
'$1/2$ &lt;b&gt;test&lt;/b&gt;' | '<math>1/2</math> &lt;b&gt;test&lt;/b&gt;'
'$a!$' | '<math>a!</math>'
'$x$' | '<math>x</math>'
end
expect(before.to_s).to eq 'test '
expect(after.to_s).to eq ' test'
with_them do
it_behaves_like 'inline math'
end
end
it 'does not handle dollar literals properly' do
doc = filter('$20+30\$$')
expected = '<code class="code math js-render-math" data-math-style="inline">20+30\\</code>$'
expect(doc.to_s).to eq expected
end
end
it 'only removes surrounding single dollar sign' do
doc = filter("test $$<code>2+2</code>$$ test")
before = doc.xpath('descendant-or-self::text()[1]').first
after = doc.xpath('descendant-or-self::text()[3]').first
describe 'inline math using $`...`$ syntax' do
context 'with valid syntax' do
where(:text, :result_template) do
'$<code>2+2</code>$' | '<math>2+2</math>'
'$<code>22+1</code>$ and $<code>22 + a^2</code>$' | '<math>22+1</math> and <math>22 + a^2</math>'
'$22 and $<code>2+2</code>$' | '$22 and <math>2+2</math>'
'$<code>2+2</code>$ $22 and flightjs/Flight$22 $<code>2+2</code>$' | '<math>2+2</math> $22 and flightjs/Flight$22 <math>2+2</math>'
'test $$<code>2+2</code>$$ test' | 'test $<math>2+2</math>$ test'
end
expect(before.to_s).to eq 'test $'
expect(after.to_s).to eq '$ test'
with_them do
it_behaves_like 'inline math'
end
end
end
it 'adds data-math-style inline attribute to inline math' do
doc = filter('$<code>2+2</code>$')
code = doc.xpath('descendant-or-self::code').first
describe 'inline display math using $$...$$ syntax' do
context 'with valid syntax' do
where(:text, :result_template) do
'$$2+2$$' | '<math>2+2</math>'
'$$ 2+2 $$' | '<math>2+2</math>'
'$$22+1$$ and $$22 + a^2$$' | '<math>22+1</math> and <math>22 + a^2</math>'
'$22 and $$2+2$$' | '$22 and <math>2+2</math>'
'$$2+2$$ $22 and flightjs/Flight$22 $$2+2$$' | '<math>2+2</math> $22 and flightjs/Flight$22 <math>2+2</math>'
'flightjs/Flight$22 and $$a^2 + b^2 = c^2$$' | 'flightjs/Flight$22 and <math>a^2 + b^2 = c^2</math>'
'$$a!$$' | '<math>a!</math>'
'$$x$$' | '<math>x</math>'
'$$20,000 and $$30,000' | '<math>20,000 and</math>30,000'
end
expect(code['data-math-style']).to eq 'inline'
with_them do
it_behaves_like 'display math'
end
end
end
it 'adds class code and math to inline math' do
doc = filter('$<code>2+2</code>$')
code = doc.xpath('descendant-or-self::code').first
describe 'block display math using $$\n...\n$$ syntax' do
context 'with valid syntax' do
where(:text, :result_template) do
"$$\n2+2\n$$" | "<math>2+2</math>"
end
expect(code[:class]).to include("code")
expect(code[:class]).to include("math")
with_them do
it_behaves_like 'display math' do
let(:use_pre_tags) { true }
end
end
end
end
it 'adds js-render-math class to inline math' do
doc = filter('$<code>2+2</code>$')
code = doc.xpath('descendant-or-self::code').first
describe 'display math using ```math...``` syntax' do
it 'adds data-math-style display attribute to display math' do
doc = filter('<pre class="code highlight js-syntax-highlight language-math" v-pre="true"><code>2+2</code></pre>')
pre = doc.xpath('descendant-or-self::pre').first
expect(code[:class]).to include("js-render-math")
expect(pre['data-math-style']).to eq 'display'
end
it 'adds js-render-math class to display math' do
doc = filter('<pre class="code highlight js-syntax-highlight language-math" v-pre="true"><code>2+2</code></pre>')
pre = doc.xpath('descendant-or-self::pre').first
expect(pre[:class]).to include("js-render-math")
end
it 'ignores code blocks that are not math' do
input = '<pre class="code highlight js-syntax-highlight language-plaintext" v-pre="true"><code>2+2</code></pre>'
doc = filter(input)
expect(doc.to_s).to eq input
end
it 'requires the pre to contain both code and math' do
input = '<pre class="highlight js-syntax-highlight language-plaintext language-math" v-pre="true"><code>2+2</code></pre>'
doc = filter(input)
expect(doc.to_s).to eq input
end
it 'dollar signs around to display math' do
doc = filter('$<pre class="code highlight js-syntax-highlight language-math" v-pre="true"><code>2+2</code></pre>$')
before = doc.xpath('descendant-or-self::text()[1]').first
after = doc.xpath('descendant-or-self::text()[3]').first
expect(before.to_s).to eq '$'
expect(after.to_s).to eq '$'
end
end
# Cases with faulty syntax. Should be a no-op
describe 'unrecognized syntax' do
where(:text) do
[
'<code>2+2</code>',
'test $<code>2+2</code> test',
'test <code>2+2</code>$ test',
'<em>$</em><code>2+2</code><em>$</em>',
'$20,000 and $30,000',
'$20,000 in $USD',
'$ a^2 $',
"test $$\n2+2\n$$",
"$\n$",
'$$$'
]
end
it 'ignores cases with missing dolar sign at the end' do
input = "test $<code>2+2</code> test"
doc = filter(input)
expect(doc.to_s).to eq input
with_them do
it 'is ignored' do
expect(filter(text).to_s).to eq text
end
end
end
it 'ignores cases with missing dolar sign at the beginning' do
input = "test <code>2+2</code>$ test"
doc = filter(input)
it 'handles multiple styles in one text block' do
doc = filter('$<code>2+2</code>$ + $3+3$ + $$4+4$$')
expect(doc.to_s).to eq input
end
it 'ignores dollar signs if it is not adjacent' do
input = '<p>We check strictly $<code>2+2</code> and <code>2+2</code>$ </p>'
doc = filter(input)
expect(doc.to_s).to eq input
end
it 'ignores dollar signs if they are inside another element' do
input = '<p>We check strictly <em>$</em><code>2+2</code><em>$</em></p>'
doc = filter(input)
expect(doc.to_s).to eq input
end
# Display math
it 'adds data-math-style display attribute to display math' do
doc = filter('<pre class="code highlight js-syntax-highlight language-math" v-pre="true"><code>2+2</code></pre>')
pre = doc.xpath('descendant-or-self::pre').first
expect(pre['data-math-style']).to eq 'display'
end
it 'adds js-render-math class to display math' do
doc = filter('<pre class="code highlight js-syntax-highlight language-math" v-pre="true"><code>2+2</code></pre>')
pre = doc.xpath('descendant-or-self::pre').first
expect(pre[:class]).to include("js-render-math")
end
it 'ignores code blocks that are not math' do
input = '<pre class="code highlight js-syntax-highlight language-plaintext" v-pre="true"><code>2+2</code></pre>'
doc = filter(input)
expect(doc.to_s).to eq input
end
it 'requires the pre to contain both code and math' do
input = '<pre class="highlight js-syntax-highlight language-plaintext language-math" v-pre="true"><code>2+2</code></pre>'
doc = filter(input)
expect(doc.to_s).to eq input
end
it 'dollar signs around to display math' do
doc = filter('$<pre class="code highlight js-syntax-highlight language-math" v-pre="true"><code>2+2</code></pre>$')
before = doc.xpath('descendant-or-self::text()[1]').first
after = doc.xpath('descendant-or-self::text()[3]').first
expect(before.to_s).to eq '$'
expect(after.to_s).to eq '$'
expect(doc.search('.js-render-math').count).to eq(3)
expect(doc.search('[data-math-style="inline"]').count).to eq(2)
expect(doc.search('[data-math-style="display"]').count).to eq(1)
end
it 'limits how many elements can be marked as math' do
@ -134,4 +185,11 @@ RSpec.describe Banzai::Filter::MathFilter do
expect(doc.search('.js-render-math').count).to eq(2)
end
it 'does not recognize new syntax when feature flag is off' do
stub_feature_flags(markdown_dollar_math: false)
doc = filter('$1+2$')
expect(doc.to_s).to eq '$1+2$'
end
end

View File

@ -1782,12 +1782,6 @@ RSpec.describe Ci::Build do
context 'build is not erasable' do
let!(:build) { create(:ci_build) }
describe '#erase' do
subject { build.erase }
it { is_expected.to be false }
end
describe '#erasable?' do
subject { build.erasable? }
@ -1796,71 +1790,9 @@ RSpec.describe Ci::Build do
end
context 'build is erasable' do
context 'logging erase' do
let!(:build) { create(:ci_build, :test_reports, :trace_artifact, :success, :artifacts) }
it 'logs erased artifacts' do
expect(Gitlab::Ci::Artifacts::Logger)
.to receive(:log_deleted)
.with(
match_array(build.job_artifacts.to_a),
'Ci::Build#erase'
)
build.erase
end
end
context 'when project is undergoing stats refresh' do
let!(:build) { create(:ci_build, :test_reports, :trace_artifact, :success, :artifacts) }
describe '#erase' do
before do
allow(build.project).to receive(:refreshing_build_artifacts_size?).and_return(true)
end
it 'logs and continues with deleting the artifacts' do
expect(Gitlab::ProjectStatsRefreshConflictsLogger).to receive(:warn_artifact_deletion_during_stats_refresh).with(
method: 'Ci::Build#erase',
project_id: build.project.id
)
build.erase
expect(build.job_artifacts.count).to eq(0)
end
end
end
context 'new artifacts' do
let!(:build) { create(:ci_build, :test_reports, :trace_artifact, :success, :artifacts) }
describe '#erase' do
before do
build.erase(erased_by: erased_by)
end
context 'erased by user' do
let!(:erased_by) { create(:user, username: 'eraser') }
include_examples 'erasable'
it 'records user who erased a build' do
expect(build.erased_by).to eq erased_by
end
end
context 'erased by system' do
let(:erased_by) { nil }
include_examples 'erasable'
it 'does not set user who erased a build' do
expect(build.erased_by).to be_nil
end
end
end
describe '#erasable?' do
subject { build.erasable? }
@ -1878,26 +1810,12 @@ RSpec.describe Ci::Build do
context 'job has been erased' do
before do
build.erase
build.update!(erased_at: 1.minute.ago)
end
it { is_expected.to be_truthy }
end
end
context 'metadata and build trace are not available' do
let!(:build) { create(:ci_build, :success, :artifacts) }
before do
build.erase_erasable_artifacts!
end
describe '#erase' do
it 'does not raise error' do
expect { build.erase }.not_to raise_error
end
end
end
end
end
end
@ -1913,14 +1831,7 @@ RSpec.describe Ci::Build do
end
end
it "erases erasable artifacts and logs them" do
expect(Gitlab::Ci::Artifacts::Logger)
.to receive(:log_deleted)
.with(
match_array(build.job_artifacts.erasable.to_a),
'Ci::Build#erase_erasable_artifacts!'
)
it "erases erasable artifacts" do
subject
expect(build.job_artifacts.erasable).to be_empty
@ -3934,10 +3845,6 @@ RSpec.describe Ci::Build do
context 'when artifacts of depended job has been erased' do
let!(:pre_stage_job) { create(:ci_build, :success, pipeline: pipeline, name: 'test', stage_idx: 0, erased_at: 1.minute.ago) }
before do
pre_stage_job.erase
end
it { expect(job).not_to have_valid_build_dependencies }
end
end
@ -3958,10 +3865,6 @@ RSpec.describe Ci::Build do
context 'when artifacts of depended job has been erased' do
let!(:pre_stage_job) { create(:ci_build, :success, pipeline: pipeline, name: 'test', stage_idx: 0, erased_at: 1.minute.ago) }
before do
pre_stage_job.erase
end
it { expect(job).to have_valid_build_dependencies }
end
end

View File

@ -0,0 +1,88 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::BuildEraseService do
let_it_be(:user) { user }
let(:build) { create(:ci_build, :artifacts, :trace_artifact, artifacts_expire_at: 100.days.from_now) }
subject(:service) { described_class.new(build, user) }
describe '#execute' do
context 'when build is erasable' do
before do
allow(build).to receive(:erasable?).and_return(true)
end
it 'is successful' do
result = service.execute
expect(result).to be_success
end
it 'erases artifacts' do
service.execute
expect(build.artifacts_file).not_to be_present
expect(build.artifacts_metadata).not_to be_present
end
it 'erases trace' do
service.execute
expect(build.trace).not_to exist
end
it 'records erasure detail' do
freeze_time do
service.execute
expect(build.erased_by).to eq(user)
expect(build.erased_at).to eq(Time.current)
expect(build.artifacts_expire_at).to be_nil
end
end
context 'when project is undergoing statistics refresh' do
before do
allow(build.project).to receive(:refreshing_build_artifacts_size?).and_return(true)
end
it 'logs a warning' do
expect(Gitlab::ProjectStatsRefreshConflictsLogger)
.to receive(:warn_artifact_deletion_during_stats_refresh)
.with(method: 'Ci::BuildEraseService#execute', project_id: build.project_id)
service.execute
end
end
end
context 'when build is not erasable' do
before do
allow(build).to receive(:erasable?).and_return(false)
end
it 'is not successful' do
result = service.execute
expect(result).to be_error
expect(result.http_status).to eq(:unprocessable_entity)
end
it 'does not erase artifacts' do
service.execute
expect(build.artifacts_file).to be_present
expect(build.artifacts_metadata).to be_present
end
it 'does not erase trace' do
service.execute
expect(build.trace).to exist
end
end
end
end

View File

@ -571,10 +571,6 @@ module Ci
context 'when artifacts of depended job has been erased' do
let!(:pre_stage_job) { create(:ci_build, :success, pipeline: pipeline, name: 'test', stage_idx: 0, erased_at: 1.minute.ago) }
before do
pre_stage_job.erase
end
it_behaves_like 'not pick'
end
@ -612,10 +608,6 @@ module Ci
context 'when artifacts of depended job has been erased' do
let!(:pre_stage_job) { create(:ci_build, :success, pipeline: pipeline, name: 'test', stage_idx: 0, erased_at: 1.minute.ago) }
before do
pre_stage_job.erase
end
it { expect(subject).to eq(pending_job) }
end
end

View File

@ -134,7 +134,7 @@ module MarkdownMatchers
set_default_markdown_messages
match do |actual|
expect(actual).to have_selector('a.gfm.gfm-snippet', count: 5)
expect(actual).to have_selector('a.gfm.gfm-snippet', count: 9)
end
end
@ -196,6 +196,16 @@ module MarkdownMatchers
end
end
# MathFilter
matcher :parse_math do
set_default_markdown_messages
match do |actual|
expect(actual).to have_selector('[data-math-style="inline"]', count: 4)
expect(actual).to have_selector('[data-math-style="display"]', count: 4)
end
end
# InlineDiffFilter
matcher :parse_inline_diffs do
set_default_markdown_messages

View File

@ -26,7 +26,7 @@ require (
github.com/sirupsen/logrus v1.9.0
github.com/smartystreets/goconvey v1.7.2
github.com/stretchr/testify v1.8.0
gitlab.com/gitlab-org/gitaly/v15 v15.3.2
gitlab.com/gitlab-org/gitaly/v15 v15.3.3
gitlab.com/gitlab-org/golang-archive-zip v0.1.1
gitlab.com/gitlab-org/labkit v1.16.0
gocloud.dev v0.25.0

View File

@ -1126,8 +1126,8 @@ gitlab.com/gitlab-org/gitaly v1.68.0 h1:VlcJs1+PrhW7lqJUU7Fh1q8FMJujmbbivdfde/cw
gitlab.com/gitlab-org/gitaly v1.68.0/go.mod h1:/pCsB918Zu5wFchZ9hLYin9WkJ2yQqdVNz0zlv5HbXg=
gitlab.com/gitlab-org/gitaly/v14 v14.0.0-rc1/go.mod h1:4Cz8tOAyueSZX5o6gYum1F/unupaOclxqETPcg4ODvQ=
gitlab.com/gitlab-org/gitaly/v14 v14.9.0-rc5.0.20220329111719-51da8bc17059/go.mod h1:uX1qhFKBDuPqATlpMcFL2dKDiX8D/tbUg7CYWx7OXt4=
gitlab.com/gitlab-org/gitaly/v15 v15.3.2 h1:H8NoBZil23mZ8Y31XdPWCNp27m2nfFGV+z/pQd5Rsq4=
gitlab.com/gitlab-org/gitaly/v15 v15.3.2/go.mod h1:DPO/d7DnhJ0TTcL6UZNJ6mcRHhdBPg+f/iBA+LEKEq0=
gitlab.com/gitlab-org/gitaly/v15 v15.3.3 h1:BAlskWIiPSBtFrsIZXABaBR6mRCEWyvXoCvnQzKH7xk=
gitlab.com/gitlab-org/gitaly/v15 v15.3.3/go.mod h1:DPO/d7DnhJ0TTcL6UZNJ6mcRHhdBPg+f/iBA+LEKEq0=
gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20201117050822-3f9890ef73dc/go.mod h1:5QSTbpAHY2v0iIH5uHh2KA9w7sPUqPmnLjDApI/sv1U=
gitlab.com/gitlab-org/gitlab-shell v1.9.8-0.20210720163109-50da611814d2/go.mod h1:QWDYBwuy24qGMandtCngLRPzFgnGPg6LSNoJWPKmJMc=
gitlab.com/gitlab-org/gitlab-shell/v14 v14.10.0/go.mod h1:ynuwa2oLLQSOs6Ss6RpLDkAQuFUNreI3NdEOJxfh1ac=