Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-08-28 06:10:17 +00:00
parent c01895daab
commit cf73ed7d11
15 changed files with 187 additions and 75 deletions

View File

@ -1,9 +1,7 @@
/* eslint-disable class-methods-use-this */
/* eslint-disable @gitlab/require-i18n-strings */
import { defaultMarkdownSerializer } from 'prosemirror-markdown';
import { Node } from 'tiptap';
import { HIGHER_PARSE_RULE_PRIORITY } from '../constants';
/**
* Abstract base class for playable media, like video and audio.
@ -32,34 +30,34 @@ export default class Playable extends Node {
const parseDOM = [
{
tag: `.${this.mediaType}-container`,
skip: true,
},
{
tag: `.${this.mediaType}-container p`,
priority: HIGHER_PARSE_RULE_PRIORITY,
ignore: true,
},
{
tag: `${this.mediaType}[src]`,
getAttrs: (el) => ({ src: el.src, alt: el.dataset.title }),
tag: `.media-container`,
getAttrs: (el) => ({
src: el.querySelector('audio,video').src,
alt: el.querySelector('audio,video').dataset.title,
}),
},
];
const toDOM = (node) => [
this.mediaType,
{
src: node.attrs.src,
controls: true,
'data-setup': '{}',
'data-title': node.attrs.alt,
...this.extraElementAttrs,
},
'span',
{ class: 'media-container' },
[
this.options.mediaType,
{
src: node.attrs.src,
controls: true,
'data-setup': '{}',
'data-title': node.attrs.alt,
...this.extraElementAttrs,
},
],
['a', { href: node.attrs.src }, node.attrs.alt],
];
return {
attrs,
group: 'block',
group: 'inline',
inline: true,
draggable: true,
parseDOM,
toDOM,
@ -68,6 +66,5 @@ export default class Playable extends Node {
toMarkdown(state, node) {
defaultMarkdownSerializer.nodes.image(state, node);
state.closeBlock(node);
}
}

View File

@ -0,0 +1,8 @@
import Playable from './playable';
export default Playable.extend({
defaultOptions: {
...Playable.options,
mediaType: 'audio',
},
});

View File

@ -0,0 +1,71 @@
import { Node } from '@tiptap/core';
const queryPlayableElement = (element, mediaType) => element.querySelector(mediaType);
export default Node.create({
name: 'playable',
group: 'inline',
inline: true,
draggable: true,
addAttributes() {
return {
src: {
default: null,
parseHTML: (element) => {
const playable = queryPlayableElement(element, this.options.mediaType);
return {
src: playable.src,
};
},
},
canonicalSrc: {
default: null,
parseHTML: (element) => {
const playable = queryPlayableElement(element, this.options.mediaType);
return {
canonicalSrc: playable.dataset.canonicalSrc,
};
},
},
alt: {
default: null,
parseHTML: (element) => {
const playable = queryPlayableElement(element, this.options.mediaType);
return {
alt: playable.dataset.title,
};
},
},
};
},
parseHTML() {
return [
{
tag: '.media-container',
},
];
},
renderHTML({ node }) {
return [
'span',
{ class: 'media-container' },
[
this.options.mediaType,
{
src: node.attrs.src,
controls: true,
'data-setup': '{}',
'data-title': node.attrs.alt,
...this.extraElementAttrs,
},
],
['a', { href: node.attrs.src }, node.attrs.alt],
];
},
});

View File

@ -2,6 +2,7 @@ import { Editor } from '@tiptap/vue-2';
import { isFunction } from 'lodash';
import { PROVIDE_SERIALIZER_OR_RENDERER_ERROR } from '../constants';
import Attachment from '../extensions/attachment';
import Audio from '../extensions/audio';
import Blockquote from '../extensions/blockquote';
import Bold from '../extensions/bold';
import BulletList from '../extensions/bullet_list';
@ -63,6 +64,7 @@ export const createContentEditor = ({
const builtInContentEditorExtensions = [
Attachment.configure({ uploadsPath, renderMarkdown }),
Audio,
Blockquote,
Bold,
BulletList,

View File

@ -3,6 +3,7 @@ import {
defaultMarkdownSerializer,
} from 'prosemirror-markdown/src/to_markdown';
import { DOMParser as ProseMirrorDOMParser } from 'prosemirror-model';
import Audio from '../extensions/audio';
import Blockquote from '../extensions/blockquote';
import Bold from '../extensions/bold';
import BulletList from '../extensions/bullet_list';
@ -40,6 +41,8 @@ import {
openTag,
closeTag,
renderOrderedList,
renderImage,
renderPlayable,
} from './serialization_helpers';
const defaultSerializerConfig = {
@ -92,6 +95,7 @@ const defaultSerializerConfig = {
},
nodes: {
[Audio.name]: renderPlayable,
[Blockquote.name]: (state, node) => {
if (node.attrs.multiline) {
state.write('>>>');
@ -120,12 +124,7 @@ const defaultSerializerConfig = {
[HardBreak.name]: renderHardBreak,
[Heading.name]: defaultMarkdownSerializer.nodes.heading,
[HorizontalRule.name]: defaultMarkdownSerializer.nodes.horizontal_rule,
[Image.name]: (state, node) => {
const { alt, canonicalSrc, src, title } = node.attrs;
const quotedTitle = title ? ` ${state.quote(title)}` : '';
state.write(`![${state.esc(alt || '')}](${state.esc(canonicalSrc || src)}${quotedTitle})`);
},
[Image.name]: renderImage,
[ListItem.name]: defaultMarkdownSerializer.nodes.list_item,
[OrderedList.name]: renderOrderedList,
[Paragraph.name]: defaultMarkdownSerializer.nodes.paragraph,

View File

@ -286,3 +286,14 @@ export function renderHardBreak(state, node, parent, index) {
}
}
}
export function renderImage(state, node) {
const { alt, canonicalSrc, src, title } = node.attrs;
const quotedTitle = title ? ` ${state.quote(title)}` : '';
state.write(`![${state.esc(alt || '')}](${state.esc(canonicalSrc || src)}${quotedTitle})`);
}
export function renderPlayable(state, node) {
renderImage(state, node);
}

View File

@ -41,6 +41,12 @@
}
}
.media-container {
display: inline-flex;
flex-direction: column;
margin-bottom: $gl-spacing-scale-2;
}
img:not(.emoji) {
margin: 0 0 8px;
}

View File

@ -58,8 +58,8 @@ class CommitStatus < Ci::ApplicationRecord
scope :in_pipelines, ->(pipelines) { where(pipeline: pipelines) }
scope :eager_load_pipeline, -> { eager_load(:pipeline, project: { namespace: :route }) }
scope :with_pipeline, -> { joins(:pipeline) }
scope :updated_at_before, ->(date) { where('ci_builds.updated_at < ?', date) }
scope :created_at_before, ->(date) { where('ci_builds.created_at < ?', date) }
scope :updated_at_before, ->(date) { where('ci_builds.updated_at < ?', date) }
scope :updated_before, ->(lookback:, timeout:) {
where('(ci_builds.created_at BETWEEN ? AND ?) AND (ci_builds.updated_at BETWEEN ? AND ?)', lookback, timeout, lookback, timeout)
}

View File

@ -63,10 +63,12 @@ class StuckCiJobsWorker # rubocop:disable Scalability/IdempotentWorker
end
def running_timed_out_builds
Ci::Build.running.where( # rubocop: disable CodeReuse/ActiveRecord
'ci_builds.updated_at < ?',
BUILD_RUNNING_OUTDATED_TIMEOUT.ago
)
if Feature.enabled?(:ci_new_query_for_running_stuck_jobs)
running_builds = Ci::Build.running.created_at_before(BUILD_RUNNING_OUTDATED_TIMEOUT.ago).order(created_at: :asc, project_id: :asc) # rubocop: disable CodeReuse/ActiveRecord
Ci::Build.id_in(running_builds).updated_at_before(BUILD_RUNNING_OUTDATED_TIMEOUT.ago)
else
Ci::Build.running.updated_at_before(BUILD_RUNNING_OUTDATED_TIMEOUT.ago)
end
end
def try_obtain_lease

View File

@ -0,0 +1,8 @@
---
name: ci_new_query_for_running_stuck_jobs
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68891
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/339264
milestone: '14.3'
type: development
group: group::pipeline execution
default_enabled: false

View File

@ -52,7 +52,7 @@ module Banzai
doc.document.create_element(media_type, media_element_attrs)
end
def download_paragraph(doc, element)
def download_link(doc, element)
link_content = element['title'] || element['alt']
link_element_attrs = {
@ -67,19 +67,15 @@ module Banzai
link_element_attrs['data-canonical-src'] = element['data-canonical-src']
end
link = doc.document.create_element('a', link_content, link_element_attrs)
doc.document.create_element('p').tap do |paragraph|
paragraph.children = link
end
doc.document.create_element('a', link_content, link_element_attrs)
end
def media_node(doc, element)
container_element_attrs = { class: "#{media_type}-container" }
container_element_attrs = { class: "media-container #{media_type}-container" }
doc.document.create_element( "div", container_element_attrs).tap do |container|
doc.document.create_element('span', container_element_attrs).tap do |container|
container.add_child(media_element(doc, element))
container.add_child(download_paragraph(doc, element))
container.add_child(download_link(doc, element))
end
end
end

View File

@ -145,3 +145,15 @@
context: project_wiki
markdown: |-
Hi @gitlab - thank you for reporting this ~bug (#1) we hope to fix it in %1.1 as part of !1
- name: audio
markdown: '![Sample Audio](https://gitlab.com/gitlab.mp3)'
- name: audio_in_lists
markdown: |-
* ![Sample Audio](https://gitlab.com/1.mp3)
* ![Sample Audio](https://gitlab.com/2.mp3)
1. ![Sample Audio](https://gitlab.com/1.mp3)
2. ![Sample Audio](https://gitlab.com/2.mp3)
* [x] ![Sample Audio](https://gitlab.com/1.mp3)
* [x] ![Sample Audio](https://gitlab.com/2.mp3)

View File

@ -25,18 +25,14 @@ RSpec.describe Banzai::Filter::AudioLinkFilter do
it 'replaces the image tag with an audio tag' do
container = filter(image).children.first
expect(container.name).to eq 'div'
expect(container['class']).to eq 'audio-container'
expect(container.name).to eq 'span'
expect(container['class']).to eq 'media-container audio-container'
audio, paragraph = container.children
audio, link = container.children
expect(audio.name).to eq 'audio'
expect(audio['src']).to eq src
expect(paragraph.name).to eq 'p'
link = paragraph.children.first
expect(link.name).to eq 'a'
expect(link['href']).to eq src
expect(link['target']).to eq '_blank'
@ -105,15 +101,13 @@ RSpec.describe Banzai::Filter::AudioLinkFilter do
image = %(<img src="#{proxy_src}" data-canonical-src="#{canonical_src}"/>)
container = filter(image).children.first
expect(container['class']).to eq 'audio-container'
expect(container['class']).to eq 'media-container audio-container'
audio, paragraph = container.children
audio, link = container.children
expect(audio['src']).to eq proxy_src
expect(audio['data-canonical-src']).to eq canonical_src
link = paragraph.children.first
expect(link['href']).to eq proxy_src
end
end

View File

@ -25,20 +25,16 @@ RSpec.describe Banzai::Filter::VideoLinkFilter do
it 'replaces the image tag with a video tag' do
container = filter(image).children.first
expect(container.name).to eq 'div'
expect(container['class']).to eq 'video-container'
expect(container.name).to eq 'span'
expect(container['class']).to eq 'media-container video-container'
video, paragraph = container.children
video, link = container.children
expect(video.name).to eq 'video'
expect(video['src']).to eq src
expect(video['width']).to eq "400"
expect(video['preload']).to eq 'metadata'
expect(paragraph.name).to eq 'p'
link = paragraph.children.first
expect(link.name).to eq 'a'
expect(link['href']).to eq src
expect(link['target']).to eq '_blank'
@ -107,15 +103,13 @@ RSpec.describe Banzai::Filter::VideoLinkFilter do
image = %(<img src="#{proxy_src}" data-canonical-src="#{canonical_src}"/>)
container = filter(image).children.first
expect(container['class']).to eq 'video-container'
expect(container['class']).to eq 'media-container video-container'
video, paragraph = container.children
video, link = container.children
expect(video['src']).to eq proxy_src
expect(video['data-canonical-src']).to eq canonical_src
link = paragraph.children.first
expect(link['href']).to eq proxy_src
end
end

View File

@ -186,20 +186,32 @@ RSpec.describe StuckCiJobsWorker do
end
end
context 'when job is running' do
let(:status) { 'running' }
shared_examples 'job is running' do
context 'when job is running' do
let(:status) { 'running' }
context 'when job was updated_at more than an hour ago' do
let(:updated_at) { 2.hours.ago }
context 'when job was updated_at more than an hour ago' do
let(:updated_at) { 2.hours.ago }
it_behaves_like 'job is dropped'
it_behaves_like 'job is dropped'
end
context 'when job was updated in less than 1 hour ago' do
let(:updated_at) { 30.minutes.ago }
it_behaves_like 'job is unchanged'
end
end
end
it_behaves_like 'job is running'
context 'when ci_new_query_for_running_stuck_jobs feature flag is disabled' do
before do
stub_feature_flags(ci_new_query_for_running_stuck_jobs: false)
end
context 'when job was updated in less than 1 hour ago' do
let(:updated_at) { 30.minutes.ago }
it_behaves_like 'job is unchanged'
end
it_behaves_like 'job is running'
end
%w(success skipped failed canceled).each do |status|