diff options
Diffstat (limited to 'app/assets/javascripts/jobs')
5 files changed, 44 insertions, 17 deletions
diff --git a/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue b/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue index a6eff743ce9..d90377029c5 100644 --- a/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue +++ b/app/assets/javascripts/jobs/components/sidebar_job_details_container.vue @@ -46,7 +46,7 @@ export default { return timeIntervalInWords(this.job.queued); }, runnerHelpUrl() { - return helpPagePath('ci/runners/index.html', { + return helpPagePath('ci/runners/configure_runners.html', { anchor: 'set-maximum-job-timeout-for-a-runner', }); }, diff --git a/app/assets/javascripts/jobs/components/stages_dropdown.vue b/app/assets/javascripts/jobs/components/stages_dropdown.vue index 36b0ad43b14..1780afd39e8 100644 --- a/app/assets/javascripts/jobs/components/stages_dropdown.vue +++ b/app/assets/javascripts/jobs/components/stages_dropdown.vue @@ -2,10 +2,12 @@ import { GlLink, GlDropdown, GlDropdownItem } from '@gitlab/ui'; import { isEmpty } from 'lodash'; import CiIcon from '~/vue_shared/components/ci_icon.vue'; +import clipboardButton from '~/vue_shared/components/clipboard_button.vue'; export default { components: { CiIcon, + clipboardButton, GlDropdown, GlDropdownItem, GlLink, @@ -45,7 +47,7 @@ export default { <template> <div class="dropdown"> <div class="js-pipeline-info" data-testid="pipeline-info"> - <ci-icon :status="pipeline.details.status" class="vertical-align-middle" /> + <ci-icon :status="pipeline.details.status" /> <span class="font-weight-bold">{{ s__('Job|Pipeline') }}</span> <gl-link @@ -85,7 +87,14 @@ export default { </template> <gl-link v-else :href="pipeline.ref.path" class="link-commit ref-name">{{ pipeline.ref.name - }}</gl-link> + }}</gl-link + ><clipboard-button + :text="pipeline.ref.name" + :title="__('Copy reference')" + category="tertiary" + size="small" + data-testid="copy-source-ref-link" + /> </template> </div> diff --git a/app/assets/javascripts/jobs/store/actions.js b/app/assets/javascripts/jobs/store/actions.js index a8be5d8d039..53e3dbbad0d 100644 --- a/app/assets/javascripts/jobs/store/actions.js +++ b/app/assets/javascripts/jobs/store/actions.js @@ -13,6 +13,7 @@ import { scrollUp, } from '~/lib/utils/scroll_utils'; import { __ } from '~/locale'; +import { reportToSentry } from '../utils'; import * as types from './mutation_types'; export const init = ({ dispatch }, { endpoint, logState, pagePath }) => { @@ -175,11 +176,14 @@ export const fetchTrace = ({ dispatch, state }) => dispatch('startPollingTrace'); } }) - .catch((e) => - e.response.status === httpStatusCodes.FORBIDDEN - ? dispatch('receiveTraceUnauthorizedError') - : dispatch('receiveTraceError'), - ); + .catch((e) => { + if (e.response.status === httpStatusCodes.FORBIDDEN) { + dispatch('receiveTraceUnauthorizedError'); + } else { + reportToSentry('job_actions', e); + dispatch('receiveTraceError'); + } + }); export const startPollingTrace = ({ dispatch, commit }) => { const traceTimeout = setTimeout(() => { diff --git a/app/assets/javascripts/jobs/store/utils.js b/app/assets/javascripts/jobs/store/utils.js index 36391a4d433..b64734e29f6 100644 --- a/app/assets/javascripts/jobs/store/utils.js +++ b/app/assets/javascripts/jobs/store/utils.js @@ -132,7 +132,7 @@ export const logLinesParserLegacy = (lines = [], accumulator = []) => ); export const logLinesParser = (lines = [], previousTraceState = {}, prevParsedLines = []) => { - let currentLine = previousTraceState?.prevLineCount ?? 0; + let currentLineCount = previousTraceState?.prevLineCount ?? 0; let currentHeader = previousTraceState?.currentHeader; let isPreviousLineHeader = previousTraceState?.isPreviousLineHeader ?? false; const parsedLines = prevParsedLines.length > 0 ? prevParsedLines : []; @@ -141,27 +141,27 @@ export const logLinesParser = (lines = [], previousTraceState = {}, prevParsedLi for (let i = 0; i < lines.length; i += 1) { const line = lines[i]; // First run we can use the current index, later runs we have to retrieve the last number of lines - currentLine = previousTraceState?.prevLineCount ? currentLine + 1 : i + 1; + currentLineCount = previousTraceState?.prevLineCount ? currentLineCount + 1 : i + 1; if (line.section_header && !isPreviousLineHeader) { // If there's no previous line header that means we're at the root of the log isPreviousLineHeader = true; - parsedLines.push(parseHeaderLine(line, currentLine)); + parsedLines.push(parseHeaderLine(line, currentLineCount)); currentHeader = { index: parsedLines.length - 1 }; } else if (line.section_header && isPreviousLineHeader) { // If there's a current section, we can't push to the parsedLines array sectionsQueue.push(currentHeader); - currentHeader = parseHeaderLine(line, currentLine); // Let's parse the incoming header line + currentHeader = parseHeaderLine(line, currentLineCount); // Let's parse the incoming header line } else if (line.section && !line.section_duration) { // We're inside a collapsible section and want to parse a standard line if (currentHeader?.index) { // If the current section header is only an index, add the line as part of the lines // array of the current collapsible section - parsedLines[currentHeader.index].lines.push(parseLine(line, currentLine)); + parsedLines[currentHeader.index].lines.push(parseLine(line, currentLineCount)); } else { // Otherwise add it to the innermost collapsible section lines array - currentHeader.lines.push(parseLine(line, currentLine)); + currentHeader.lines.push(parseLine(line, currentLineCount)); } } else if (line.section && line.section_duration) { // NOTE: This marks the end of a section_header @@ -174,7 +174,7 @@ export const logLinesParser = (lines = [], previousTraceState = {}, prevParsedLi parsedLines[currentHeader.index].line.section_duration = line.section_duration; isPreviousLineHeader = false; currentHeader = null; - } else { + } else if (currentHeader?.isHeader) { currentHeader.line.section_duration = line.section_duration; if (previousSection && previousSection?.index) { @@ -185,9 +185,14 @@ export const logLinesParser = (lines = [], previousTraceState = {}, prevParsedLi } currentHeader = previousSection; + } else { + // On older job logs, there's no `section_header: true` response, it's just an object + // with the `section_duration` and `section` props, so we just parse it + // as a standard line + parsedLines.push(parseLine(line, currentLineCount)); } } else { - parsedLines.push(parseLine(line, currentLine)); + parsedLines.push(parseLine(line, currentLineCount)); } } @@ -197,7 +202,7 @@ export const logLinesParser = (lines = [], previousTraceState = {}, prevParsedLi isPreviousLineHeader, currentHeader, sectionsQueue, - prevLineCount: lines.length, + prevLineCount: currentLineCount, }, }; }; diff --git a/app/assets/javascripts/jobs/utils.js b/app/assets/javascripts/jobs/utils.js index 1ccecf3eb53..bb27658369f 100644 --- a/app/assets/javascripts/jobs/utils.js +++ b/app/assets/javascripts/jobs/utils.js @@ -1,3 +1,5 @@ +import * as Sentry from '@sentry/browser'; + /** * capture anything starting with http:// or https:// * https?:\/\/ @@ -10,3 +12,10 @@ */ export const linkRegex = /(https?:\/\/[^"<>()\\^`{|}\s]+[^"<>()\\^`{|}\s.,:;!?])/g; export default { linkRegex }; + +export const reportToSentry = (component, failureType) => { + Sentry.withScope((scope) => { + scope.setTag('component', component); + Sentry.captureException(failureType); + }); +}; |