Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/jobs/components/log/duration_badge.vue13
-rw-r--r--app/assets/javascripts/jobs/components/log/line.vue2
-rw-r--r--app/assets/javascripts/jobs/components/log/line_header.vue16
-rw-r--r--app/assets/javascripts/jobs/components/log/line_number.vue9
-rw-r--r--app/assets/javascripts/jobs/components/log/log.vue11
-rw-r--r--app/assets/javascripts/jobs/store/utils.js35
-rw-r--r--app/assets/javascripts/test_utils/simulate_drag.js8
-rw-r--r--app/assets/stylesheets/framework/job_log.scss49
-rw-r--r--app/assets/stylesheets/framework/sortable.scss18
-rw-r--r--app/assets/stylesheets/framework/variables.scss3
-rw-r--r--app/assets/stylesheets/pages/boards.scss14
-rw-r--r--app/assets/stylesheets/pages/projects.scss10
-rw-r--r--app/helpers/version_check_helper.rb2
-rw-r--r--app/models/ci/build.rb6
-rw-r--r--app/models/ci/build_metadata.rb3
-rw-r--r--app/services/ci/create_pipeline_service.rb2
-rw-r--r--app/views/shared/projects/_project.html.haml9
17 files changed, 155 insertions, 55 deletions
diff --git a/app/assets/javascripts/jobs/components/log/duration_badge.vue b/app/assets/javascripts/jobs/components/log/duration_badge.vue
new file mode 100644
index 00000000000..83f62703d27
--- /dev/null
+++ b/app/assets/javascripts/jobs/components/log/duration_badge.vue
@@ -0,0 +1,13 @@
+<script>
+export default {
+ props: {
+ duration: {
+ type: String,
+ required: true,
+ },
+ },
+};
+</script>
+<template>
+ <div class="duration rounded align-self-start px-2 ml-2 flex-shrink-0">{{ duration }}</div>
+</template>
diff --git a/app/assets/javascripts/jobs/components/log/line.vue b/app/assets/javascripts/jobs/components/log/line.vue
index 86d0fcc3b74..336ae623f0f 100644
--- a/app/assets/javascripts/jobs/components/log/line.vue
+++ b/app/assets/javascripts/jobs/components/log/line.vue
@@ -21,7 +21,7 @@ export default {
<template>
<div class="line">
<line-number :line-number="line.lineNumber" :path="path" />
- <span v-for="(content, i) in line.content" :key="i" class="line-text" :class="content.style">{{
+ <span v-for="(content, i) in line.content" :key="i" :class="content.style">{{
content.text
}}</span>
</div>
diff --git a/app/assets/javascripts/jobs/components/log/line_header.vue b/app/assets/javascripts/jobs/components/log/line_header.vue
index 4ec212d2333..af8de9ec0fa 100644
--- a/app/assets/javascripts/jobs/components/log/line_header.vue
+++ b/app/assets/javascripts/jobs/components/log/line_header.vue
@@ -1,11 +1,13 @@
<script>
import Icon from '~/vue_shared/components/icon.vue';
import LineNumber from './line_number.vue';
+import DurationBadge from './duration_badge.vue';
export default {
components: {
Icon,
LineNumber,
+ DurationBadge,
},
props: {
line: {
@@ -20,6 +22,11 @@ export default {
type: String,
required: true,
},
+ duration: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
computed: {
iconName() {
@@ -35,11 +42,16 @@ export default {
</script>
<template>
- <div class="line collapsible-line" role="button" @click="handleOnClick">
- <icon :name="iconName" class="arrow" />
+ <div
+ class="line collapsible-line d-flex justify-content-between"
+ role="button"
+ @click="handleOnClick"
+ >
+ <icon :name="iconName" class="arrow position-absolute" />
<line-number :line-number="line.lineNumber" :path="path" />
<span v-for="(content, i) in line.content" :key="i" class="line-text" :class="content.style">{{
content.text
}}</span>
+ <duration-badge v-if="duration" :duration="duration" />
</div>
</template>
diff --git a/app/assets/javascripts/jobs/components/log/line_number.vue b/app/assets/javascripts/jobs/components/log/line_number.vue
index e06836e2e97..6c76bef13d3 100644
--- a/app/assets/javascripts/jobs/components/log/line_number.vue
+++ b/app/assets/javascripts/jobs/components/log/line_number.vue
@@ -46,7 +46,10 @@ export default {
};
</script>
<template>
- <gl-link :id="lineNumberId" class="line-number" :href="buildLineNumber">{{
- parsedLineNumber
- }}</gl-link>
+ <gl-link
+ :id="lineNumberId"
+ class="d-inline-block text-right position-absolute line-number"
+ :href="buildLineNumber"
+ >{{ parsedLineNumber }}</gl-link
+ >
</template>
diff --git a/app/assets/javascripts/jobs/components/log/log.vue b/app/assets/javascripts/jobs/components/log/log.vue
index 5db866afe5a..429796aeb4e 100644
--- a/app/assets/javascripts/jobs/components/log/log.vue
+++ b/app/assets/javascripts/jobs/components/log/log.vue
@@ -9,7 +9,7 @@ export default {
LogLineHeader,
},
computed: {
- ...mapState(['traceEndpoint', 'trace']),
+ ...mapState(['traceEndpoint', 'trace', 'isTraceComplete']),
},
methods: {
...mapActions(['toggleCollapsibleLine']),
@@ -20,12 +20,13 @@ export default {
};
</script>
<template>
- <code class="job-log">
+ <code class="job-log d-block">
<template v-for="(section, index) in trace">
<template v-if="section.isHeader">
<log-line-header
:key="`collapsible-${index}`"
:line="section.line"
+ :duration="section.section_duration"
:path="traceEndpoint"
:is-closed="section.isClosed"
@toggleLine="handleOnClickCollapsibleLine(section)"
@@ -41,5 +42,11 @@ export default {
</template>
<log-line v-else :key="section.offset" :line="section" :path="traceEndpoint" />
</template>
+
+ <div v-if="!isTraceComplete" class="js-log-animation loader-animation pt-3 pl-3">
+ <div class="dot"></div>
+ <div class="dot"></div>
+ <div class="dot"></div>
+ </div>
</code>
</template>
diff --git a/app/assets/javascripts/jobs/store/utils.js b/app/assets/javascripts/jobs/store/utils.js
index f6a87b9a212..261ec90cd12 100644
--- a/app/assets/javascripts/jobs/store/utils.js
+++ b/app/assets/javascripts/jobs/store/utils.js
@@ -1,10 +1,21 @@
/**
+ * Adds the line number property
+ * @param Object line
+ * @param Number lineNumber
+ */
+export const parseLine = (line = {}, lineNumber) => ({
+ ...line,
+ lineNumber,
+});
+
+/**
* Parses the job log content into a structure usable by the template
*
* For collaspible lines (section_header = true):
* - creates a new array to hold the lines that are collpasible,
* - adds a isClosed property to handle toggle
* - adds a isHeader property to handle template logic
+ * - adds the section_duration
* For each line:
* - adds the index as lineNumber
*
@@ -14,27 +25,21 @@
export const logLinesParser = (lines = [], lineNumberStart) =>
lines.reduce((acc, line, index) => {
const lineNumber = lineNumberStart ? lineNumberStart + index : index;
+ const last = acc[acc.length - 1];
+
if (line.section_header) {
acc.push({
isClosed: true,
isHeader: true,
- line: {
- ...line,
- lineNumber,
- },
-
+ line: parseLine(line, lineNumber),
lines: [],
});
- } else if (acc.length && acc[acc.length - 1].isHeader) {
- acc[acc.length - 1].lines.push({
- ...line,
- lineNumber,
- });
- } else {
- acc.push({
- ...line,
- lineNumber,
- });
+ } else if (acc.length && last.isHeader && !line.section_duration && line.content.length) {
+ last.lines.push(parseLine(line, lineNumber));
+ } else if (acc.length && last.isHeader && line.section_duration) {
+ last.section_duration = line.section_duration;
+ } else if (line.content.length) {
+ acc.push(parseLine(line, lineNumber));
}
return acc;
diff --git a/app/assets/javascripts/test_utils/simulate_drag.js b/app/assets/javascripts/test_utils/simulate_drag.js
index c9bf234fcce..f4090de3f1e 100644
--- a/app/assets/javascripts/test_utils/simulate_drag.js
+++ b/app/assets/javascripts/test_utils/simulate_drag.js
@@ -2,8 +2,8 @@ function simulateEvent(el, type, options = {}) {
let event;
if (!el) return null;
- if (/^mouse/.test(type)) {
- event = el.ownerDocument.createEvent('MouseEvents');
+ if (/^(pointer|mouse)/.test(type)) {
+ event = el.ownerDocument.createEvent('MouseEvent');
event.initMouseEvent(
type,
true,
@@ -125,7 +125,7 @@ export default function simulateDrag(options) {
const startTime = new Date().getTime();
const duration = options.duration || 1000;
- simulateEvent(fromEl, 'mousedown', {
+ simulateEvent(fromEl, 'pointerdown', {
button: 0,
clientX: fromRect.cx,
clientY: fromRect.cy,
@@ -146,7 +146,7 @@ export default function simulateDrag(options) {
const y = fromRect.cy + (toRect.cy - fromRect.cy) * progress;
const overEl = fromEl.ownerDocument.elementFromPoint(x, y);
- simulateEvent(overEl, 'mousemove', {
+ simulateEvent(overEl, 'pointermove', {
clientX: x,
clientY: y,
});
diff --git a/app/assets/stylesheets/framework/job_log.scss b/app/assets/stylesheets/framework/job_log.scss
new file mode 100644
index 00000000000..5c2491c8233
--- /dev/null
+++ b/app/assets/stylesheets/framework/job_log.scss
@@ -0,0 +1,49 @@
+.job-log {
+ font-family: $monospace-font;
+ padding: $gl-padding-8 $input-horizontal-padding;
+ margin: 0 0 $gl-padding-8;
+ font-size: 13px;
+ word-break: break-all;
+ word-wrap: break-word;
+ color: $gl-text-color-inverted;
+ border-radius: $border-radius-small;
+ min-height: 42px;
+ background-color: $builds-trace-bg;
+}
+
+.line {
+ padding: 1px $gl-padding 1px $job-log-line-padding;
+}
+
+.line-number {
+ color: $gl-text-color-inverted;
+ padding: 0 $gl-padding-8;
+ min-width: $job-line-number-width;
+ margin-left: -$job-line-number-width;
+ padding-right: 1em;
+
+ &:hover,
+ &:active,
+ &:visited {
+ text-decoration: underline;
+ color: $gl-text-color-inverted;
+ }
+}
+
+.collapsible-line {
+ &:hover {
+ background-color: rgba($white-light, 0.2);
+ }
+
+ .arrow {
+ margin-left: -$job-arrow-margin;
+ }
+}
+
+.duration {
+ background: $gl-gray-400;
+}
+
+.loader-animation {
+ @include build-loader-animation;
+}
diff --git a/app/assets/stylesheets/framework/sortable.scss b/app/assets/stylesheets/framework/sortable.scss
index 8c070200135..25868061d04 100644
--- a/app/assets/stylesheets/framework/sortable.scss
+++ b/app/assets/stylesheets/framework/sortable.scss
@@ -90,3 +90,21 @@
padding: 0;
}
}
+
+.is-dragging {
+ // Important because plugin sets inline CSS
+ opacity: 1 !important;
+
+ * {
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ // !important to make sure no style can override this when dragging
+ cursor: grabbing !important;
+ }
+
+ &.no-drop * {
+ cursor: no-drop !important;
+ }
+}
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index faa0a9909d5..e77527ac130 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -606,6 +606,9 @@ $blame-blue: #254e77;
*/
$builds-trace-bg: #111;
$job-log-highlight-height: 18px;
+$job-log-line-padding: 62px;
+$job-line-number-width: 40px;
+$job-arrow-margin: 50px;
/*
* Commit Page
diff --git a/app/assets/stylesheets/pages/boards.scss b/app/assets/stylesheets/pages/boards.scss
index e77a2d1e333..4bf0abccd00 100644
--- a/app/assets/stylesheets/pages/boards.scss
+++ b/app/assets/stylesheets/pages/boards.scss
@@ -2,20 +2,6 @@
cursor: grab;
}
-.is-dragging {
- // Important because plugin sets inline CSS
- opacity: 1 !important;
-
- * {
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
- // !important to make sure no style can override this when dragging
- cursor: grabbing !important;
- }
-}
-
.is-ghost {
opacity: 0.3;
pointer-events: none;
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index c80beceae52..801e9e7204c 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -889,11 +889,7 @@ pre.light-well {
@include basic-list-stats;
display: flex;
align-items: center;
- padding: $gl-padding 0;
-
- @include media-breakpoint-up(lg) {
- padding: $gl-padding 0;
- }
+ padding: $gl-padding-12 0;
&.no-description {
@include media-breakpoint-up(sm) {
@@ -909,7 +905,7 @@ pre.light-well {
}
h2 {
- font-size: $gl-font-size-large;
+ font-size: $gl-font-size;
font-weight: $gl-font-weight-bold;
margin-bottom: 0;
@@ -951,6 +947,7 @@ pre.light-well {
.description {
line-height: 1.5;
+ color: $gl-text-color-secondary;
}
@include media-breakpoint-down(md) {
@@ -1096,7 +1093,6 @@ pre.light-well {
&:not(.explore) {
.forks {
display: none;
-
}
}
diff --git a/app/helpers/version_check_helper.rb b/app/helpers/version_check_helper.rb
index 9e1204738c1..bac3c99e3e5 100644
--- a/app/helpers/version_check_helper.rb
+++ b/app/helpers/version_check_helper.rb
@@ -19,7 +19,7 @@ module VersionCheckHelper
end
def source_code_project
- 'gitlab-ce'
+ 'gitlab-foss'
end
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 71c4501f57b..2393540b04c 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -88,7 +88,11 @@ module Ci
validates :coverage, numericality: true, allow_blank: true
validates :ref, presence: true
- scope :not_interruptible, -> { joins(:metadata).where(ci_builds_metadata: { interruptible: false }) }
+ scope :not_interruptible, -> do
+ joins(:metadata).where('ci_builds_metadata.id NOT IN (?)',
+ Ci::BuildMetadata.scoped_build.with_interruptible.select(:id))
+ end
+
scope :unstarted, ->() { where(runner_id: nil) }
scope :ignore_failures, ->() { where(allow_failure: false) }
scope :with_artifacts_archive, ->() do
diff --git a/app/models/ci/build_metadata.rb b/app/models/ci/build_metadata.rb
index 89cdd8c64f8..3097e40dd3b 100644
--- a/app/models/ci/build_metadata.rb
+++ b/app/models/ci/build_metadata.rb
@@ -25,6 +25,9 @@ module Ci
chronic_duration_attr_reader :timeout_human_readable, :timeout
+ scope :scoped_build, -> { where('ci_builds_metadata.build_id = ci_builds.id') }
+ scope :with_interruptible, -> { where(interruptible: true) }
+
enum timeout_source: {
unknown_timeout_source: 1,
project_timeout_source: 2,
diff --git a/app/services/ci/create_pipeline_service.rb b/app/services/ci/create_pipeline_service.rb
index 3278a87c576..539576147f3 100644
--- a/app/services/ci/create_pipeline_service.rb
+++ b/app/services/ci/create_pipeline_service.rb
@@ -95,7 +95,7 @@ module Ci
# rubocop: disable CodeReuse/ActiveRecord
def auto_cancelable_pipelines
# TODO: Introduced by https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/23464
- if Feature.enabled?(:ci_support_interruptible_pipelines, project, default_enabled: false)
+ if Feature.enabled?(:ci_support_interruptible_pipelines, project, default_enabled: true)
project.ci_pipelines
.where(ref: pipeline.ref)
.where.not(id: pipeline.id)
diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml
index 573ed36d7f4..bcce7cb52fb 100644
--- a/app/views/shared/projects/_project.html.haml
+++ b/app/views/shared/projects/_project.html.haml
@@ -60,6 +60,11 @@
.controls.d-flex.flex-sm-column.align-items-center.align-items-sm-end.flex-wrap.flex-shrink-0.text-secondary{ class: css_controls_class }
.icon-container.d-flex.align-items-center
+ - if pipeline_status && can?(current_user, :read_cross_project) && project.pipeline_status.has_status? && can?(current_user, :read_build, project)
+ - pipeline_path = pipelines_project_commit_path(project.pipeline_status.project, project.pipeline_status.sha, ref: project.pipeline_status.ref)
+ %span.icon-wrapper.pipeline-status
+ = render 'ci/status/icon', status: project.commit.last_pipeline.detailed_status(current_user), tooltip_placement: 'top', path: pipeline_path
+
- if project.archived
%span.d-flex.icon-wrapper.badge.badge-warning archived
- if stars
@@ -86,10 +91,6 @@
title: _('Issues'), data: { container: 'body', placement: 'top' } do
= sprite_icon('issues', size: 14, css_class: 'append-right-4')
= number_with_delimiter(project.open_issues_count)
- - if pipeline_status && can?(current_user, :read_cross_project) && project.pipeline_status.has_status? && can?(current_user, :read_build, project)
- - pipeline_path = pipelines_project_commit_path(project.pipeline_status.project, project.pipeline_status.sha, ref: project.pipeline_status.ref)
- %span.icon-wrapper.pipeline-status
- = render 'ci/status/icon', status: project.commit.last_pipeline.detailed_status(current_user), tooltip_placement: 'top', path: pipeline_path
.updated-note
%span
= _('Updated')