Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-05-04 15:10:36 +00:00
parent 998adcc422
commit be4b3134a2
212 changed files with 1002 additions and 658 deletions

View File

@ -820,14 +820,6 @@ Style/NumericLiteralPrefix:
Style/PercentLiteralDelimiters:
Enabled: false
# Offense count: 247
# Cop supports --auto-correct.
# Configuration parameters: .
# SupportedStyles: compact, exploded
Style/RaiseArgs:
Enabled: false
EnforcedStyle: exploded
# Offense count: 26
# Cop supports --auto-correct.
# Configuration parameters: SafeForConstants.

View File

@ -1 +1 @@
bb763fb573555a0f9714002c2755bdd396cab3dd
9523fe6434ea464a6a16c895222a4b001a5c0bca

View File

@ -77,7 +77,12 @@ export default {
</script>
<template>
<board-editable-item ref="sidebarItem" :title="__('Labels')" :loading="loading">
<board-editable-item
ref="sidebarItem"
:title="__('Labels')"
:loading="loading"
data-testid="sidebar-labels"
>
<template #collapsed>
<gl-label
v-for="label in issueLabels"

View File

@ -100,7 +100,7 @@ export default {
</script>
<template>
<div>
<div class="gl-display-flex gl-flex-direction-column gl-flex-align-items-stretch gl-h-full">
<frequent-items-search-input :namespace="namespace" />
<gl-loading-icon
v-if="isLoadingItems"

View File

@ -59,7 +59,11 @@ export default {
<template>
<div class="frequent-items-list-container">
<ul ref="frequentItemsList" class="list-unstyled">
<li v-if="isListEmpty" :class="{ 'section-failure': isFetchFailed }" class="section-empty">
<li
v-if="isListEmpty"
:class="{ 'section-failure': isFetchFailed }"
class="section-empty gl-mb-3"
>
{{ listEmptyMessage }}
</li>
<frequent-items-list-item

View File

@ -3,7 +3,7 @@ import { GlLink, GlIcon, GlLabel, GlFormCheckbox, GlTooltipDirective } from '@gi
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import { isScopedLabel } from '~/lib/utils/common_utils';
import { getTimeago } from '~/lib/utils/datetime_utility';
import { differenceInSeconds, getTimeago, SECONDS_IN_DAY } from '~/lib/utils/datetime_utility';
import { isExternal, setUrlFragment } from '~/lib/utils/url_utility';
import { __, n__, sprintf } from '~/locale';
import IssuableAssignees from '~/vue_shared/components/issue/issue_assignees.vue';
@ -50,6 +50,10 @@ export default {
},
},
computed: {
createdInPastDay() {
const createdSecondsAgo = differenceInSeconds(new Date(this.issuable.createdAt), new Date());
return createdSecondsAgo < SECONDS_IN_DAY;
},
author() {
return this.issuable.author;
},
@ -152,7 +156,12 @@ export default {
</script>
<template>
<li :id="`issuable_${issuable.id}`" class="issue gl-px-5!" :data-labels="labelIdsString">
<li
:id="`issuable_${issuable.id}`"
class="issue gl-px-5!"
:class="{ closed: issuable.closedAt, today: createdInPastDay }"
:data-labels="labelIdsString"
>
<div class="issuable-info-container">
<div v-if="showCheckbox" class="issue-check">
<gl-form-checkbox

View File

@ -21,7 +21,6 @@ import {
MAX_LIST_SIZE,
PAGE_SIZE,
RELATIVE_POSITION_ASC,
sortOptions,
sortParams,
} from '~/issues_list/constants';
import {
@ -30,6 +29,7 @@ import {
convertToUrlParams,
getFilterTokens,
getSortKey,
getSortOptions,
} from '~/issues_list/utils';
import axios from '~/lib/utils/axios_utils';
import { convertObjectPropsToCamelCase, getParameterByName } from '~/lib/utils/common_utils';
@ -48,7 +48,6 @@ export default {
i18n,
IssuableListTabs,
PAGE_SIZE,
sortOptions,
sortParams,
components: {
CsvImportExportButtons,
@ -87,6 +86,9 @@ export default {
exportCsvPath: {
default: '',
},
hasBlockedIssuesFeature: {
default: false,
},
hasIssues: {
default: false,
},
@ -147,6 +149,9 @@ export default {
};
},
computed: {
isBulkEditButtonDisabled() {
return this.showBulkEditSidebar || !this.issues.length;
},
isManualOrdering() {
return this.sortKey === RELATIVE_POSITION_ASC;
},
@ -252,6 +257,9 @@ export default {
showPaginationControls() {
return this.issues.length > 0;
},
sortOptions() {
return getSortOptions(this.hasIssueWeightsFeature, this.hasBlockedIssuesFeature);
},
tabCounts() {
return Object.values(IssuableStates).reduce(
(acc, state) => ({
@ -346,6 +354,15 @@ export default {
getExportCsvPathWithQuery() {
return `${this.exportCsvPath}${window.location.search}`;
},
getStatus(issue) {
if (issue.closedAt && issue.movedToId) {
return __('CLOSED (MOVED)');
}
if (issue.closedAt) {
return __('CLOSED');
}
return undefined;
},
handleUpdateLegacyBulkEdit() {
// If "select all" checkbox was checked, wait for all checkboxes
// to be checked before updating IssuableBulkUpdateSidebar class
@ -434,7 +451,7 @@ export default {
:search-input-placeholder="__('Search or filter results…')"
:search-tokens="searchTokens"
:initial-filter-value="filterTokens"
:sort-options="$options.sortOptions"
:sort-options="sortOptions"
:initial-sort-by="sortKey"
:issuables="issues"
:tabs="$options.IssuableListTabs"
@ -472,13 +489,14 @@ export default {
:aria-label="$options.i18n.calendarLabel"
/>
<csv-import-export-buttons
v-if="isSignedIn"
class="gl-mr-3"
:export-csv-path="exportCsvPathWithQuery"
:issuable-count="totalIssues"
/>
<gl-button
v-if="canBulkUpdate"
:disabled="showBulkEditSidebar"
:disabled="isBulkEditButtonDisabled"
@click="handleBulkUpdateClick"
>
{{ __('Edit issues') }}
@ -492,6 +510,10 @@ export default {
<issue-card-time-info :issue="issuable" />
</template>
<template #status="{ issuable = {} }">
{{ getStatus(issuable) }}
</template>
<template #statistics="{ issuable = {} }">
<li
v-if="issuable.mergeRequestsCount"

View File

@ -188,89 +188,6 @@ export const sortParams = {
},
};
export const sortOptions = [
{
id: 1,
title: __('Priority'),
sortDirection: {
ascending: PRIORITY_ASC,
descending: PRIORITY_DESC,
},
},
{
id: 2,
title: __('Created date'),
sortDirection: {
ascending: CREATED_ASC,
descending: CREATED_DESC,
},
},
{
id: 3,
title: __('Last updated'),
sortDirection: {
ascending: UPDATED_ASC,
descending: UPDATED_DESC,
},
},
{
id: 4,
title: __('Milestone due date'),
sortDirection: {
ascending: MILESTONE_DUE_ASC,
descending: MILESTONE_DUE_DESC,
},
},
{
id: 5,
title: __('Due date'),
sortDirection: {
ascending: DUE_DATE_ASC,
descending: DUE_DATE_DESC,
},
},
{
id: 6,
title: __('Popularity'),
sortDirection: {
ascending: POPULARITY_ASC,
descending: POPULARITY_DESC,
},
},
{
id: 7,
title: __('Label priority'),
sortDirection: {
ascending: LABEL_PRIORITY_ASC,
descending: LABEL_PRIORITY_DESC,
},
},
{
id: 8,
title: __('Manual'),
sortDirection: {
ascending: RELATIVE_POSITION_ASC,
descending: RELATIVE_POSITION_ASC,
},
},
{
id: 9,
title: __('Weight'),
sortDirection: {
ascending: WEIGHT_ASC,
descending: WEIGHT_DESC,
},
},
{
id: 10,
title: __('Blocking'),
sortDirection: {
ascending: BLOCKING_ISSUES_ASC,
descending: BLOCKING_ISSUES_DESC,
},
},
];
export const MAX_LIST_SIZE = 10;
export const FILTERED_SEARCH_TERM = 'filtered-search-term';

View File

@ -1,10 +1,127 @@
import { FILTERED_SEARCH_TERM, filters, sortParams } from '~/issues_list/constants';
import {
BLOCKING_ISSUES_ASC,
BLOCKING_ISSUES_DESC,
CREATED_ASC,
CREATED_DESC,
DUE_DATE_ASC,
DUE_DATE_DESC,
FILTERED_SEARCH_TERM,
filters,
LABEL_PRIORITY_ASC,
LABEL_PRIORITY_DESC,
MILESTONE_DUE_ASC,
MILESTONE_DUE_DESC,
POPULARITY_ASC,
POPULARITY_DESC,
PRIORITY_ASC,
PRIORITY_DESC,
RELATIVE_POSITION_ASC,
sortParams,
UPDATED_ASC,
UPDATED_DESC,
WEIGHT_ASC,
WEIGHT_DESC,
} from '~/issues_list/constants';
import { __ } from '~/locale';
export const getSortKey = (orderBy, sort) =>
Object.keys(sortParams).find(
(key) => sortParams[key].order_by === orderBy && sortParams[key].sort === sort,
);
export const getSortOptions = (hasIssueWeightsFeature, hasBlockedIssuesFeature) => {
const sortOptions = [
{
id: 1,
title: __('Priority'),
sortDirection: {
ascending: PRIORITY_ASC,
descending: PRIORITY_DESC,
},
},
{
id: 2,
title: __('Created date'),
sortDirection: {
ascending: CREATED_ASC,
descending: CREATED_DESC,
},
},
{
id: 3,
title: __('Last updated'),
sortDirection: {
ascending: UPDATED_ASC,
descending: UPDATED_DESC,
},
},
{
id: 4,
title: __('Milestone due date'),
sortDirection: {
ascending: MILESTONE_DUE_ASC,
descending: MILESTONE_DUE_DESC,
},
},
{
id: 5,
title: __('Due date'),
sortDirection: {
ascending: DUE_DATE_ASC,
descending: DUE_DATE_DESC,
},
},
{
id: 6,
title: __('Popularity'),
sortDirection: {
ascending: POPULARITY_ASC,
descending: POPULARITY_DESC,
},
},
{
id: 7,
title: __('Label priority'),
sortDirection: {
ascending: LABEL_PRIORITY_ASC,
descending: LABEL_PRIORITY_DESC,
},
},
{
id: 8,
title: __('Manual'),
sortDirection: {
ascending: RELATIVE_POSITION_ASC,
descending: RELATIVE_POSITION_ASC,
},
},
];
if (hasIssueWeightsFeature) {
sortOptions.push({
id: 9,
title: __('Weight'),
sortDirection: {
ascending: WEIGHT_ASC,
descending: WEIGHT_DESC,
},
});
}
if (hasBlockedIssuesFeature) {
sortOptions.push({
id: 10,
title: __('Blocking'),
sortDirection: {
ascending: BLOCKING_ISSUES_ASC,
descending: BLOCKING_ISSUES_DESC,
},
});
}
return sortOptions;
};
const tokenTypes = Object.keys(filters);
const urlParamKeys = tokenTypes.flatMap((key) => Object.values(filters[key].urlParam));

View File

@ -16,13 +16,21 @@ export default (containerId = 'js-jobs-table') => {
return false;
}
const { fullPath, jobCounts, jobStatuses } = containerEl.dataset;
const {
fullPath,
jobCounts,
jobStatuses,
pipelineEditorPath,
emptyStateSvgPath,
} = containerEl.dataset;
return new Vue({
el: containerEl,
apolloProvider,
provide: {
emptyStateSvgPath,
fullPath,
pipelineEditorPath,
jobStatuses: JSON.parse(jobStatuses),
jobCounts: JSON.parse(jobCounts),
},

View File

@ -1,6 +1,6 @@
<script>
import { GlTable } from '@gitlab/ui';
import { __ } from '~/locale';
import { s__, __ } from '~/locale';
import CiBadge from '~/vue_shared/components/ci_badge_link.vue';
import ActionsCell from './cells/actions_cell.vue';
import DurationCell from './cells/duration_cell.vue';
@ -13,6 +13,9 @@ const defaultTableClasses = {
};
export default {
i18n: {
emptyText: s__('Jobs|No jobs to show'),
},
fields: [
{
key: 'status',
@ -90,6 +93,8 @@ export default {
:items="jobs"
:fields="$options.fields"
:tbody-tr-attr="{ 'data-testid': 'jobs-table-row' }"
:empty-text="$options.i18n.emptyText"
show-empty
stacked="lg"
fixed
>

View File

@ -3,6 +3,7 @@ import { GlAlert, GlSkeletonLoader } from '@gitlab/ui';
import { __ } from '~/locale';
import GetJobs from './graphql/queries/get_jobs.query.graphql';
import JobsTable from './jobs_table.vue';
import JobsTableEmptyState from './jobs_table_empty_state.vue';
import JobsTableTabs from './jobs_table_tabs.vue';
export default {
@ -13,6 +14,7 @@ export default {
GlAlert,
GlSkeletonLoader,
JobsTable,
JobsTableEmptyState,
JobsTableTabs,
},
inject: {
@ -41,15 +43,21 @@ export default {
jobs: null,
hasError: false,
isAlertDismissed: false,
scope: null,
};
},
computed: {
shouldShowAlert() {
return this.hasError && !this.isAlertDismissed;
},
showEmptyState() {
return this.jobs.length === 0 && !this.scope;
},
},
methods: {
fetchJobsByStatus(scope) {
this.scope = scope;
this.$apollo.queries.jobs.refetch({ statuses: scope });
},
},
@ -80,6 +88,8 @@ export default {
/>
</div>
<jobs-table-empty-state v-else-if="showEmptyState" />
<jobs-table v-else :jobs="jobs" />
</div>
</template>

View File

@ -0,0 +1,35 @@
<script>
import { GlEmptyState } from '@gitlab/ui';
import { s__ } from '~/locale';
export default {
i18n: {
title: s__('Jobs|Use jobs to automate your tasks'),
description: s__(
'Jobs|Jobs are the building blocks of a GitLab CI/CD pipeline. Each job has a specific task, like testing code. To set up jobs in a CI/CD pipeline, add a CI/CD configuration file to your project.',
),
buttonText: s__('Jobs|Create CI/CD configuration file'),
},
components: {
GlEmptyState,
},
inject: {
pipelineEditorPath: {
default: '',
},
emptyStateSvgPath: {
default: '',
},
},
};
</script>
<template>
<gl-empty-state
:title="$options.i18n.title"
:description="$options.i18n.description"
:svg-path="emptyStateSvgPath"
:primary-button-link="pipelineEditorPath"
:primary-button-text="$options.i18n.buttonText"
/>
</template>

View File

@ -4,6 +4,8 @@ import { isString, mapValues, isNumber, reduce } from 'lodash';
import * as timeago from 'timeago.js';
import { languageCode, s__, __, n__ } from '../../locale';
export const SECONDS_IN_DAY = 86400;
const DAYS_IN_WEEK = 7;
window.timeago = timeago;

View File

@ -1,4 +1,5 @@
<script>
import { GlButton } from '@gitlab/ui';
import { debounce } from 'lodash';
import { mapActions } from 'vuex';
import { deprecatedCreateFlash as flash } from '~/flash';
@ -7,6 +8,9 @@ import { __ } from '~/locale';
import { INTERACTIVE_RESOLVE_MODE } from '../constants';
export default {
components: {
GlButton,
},
props: {
file: {
type: Object,
@ -100,21 +104,21 @@ export default {
};
</script>
<template>
<div v-show="file.showEditor" class="diff-editor-wrap">
<div v-if="file.promptDiscardConfirmation" class="discard-changes-alert-wrap">
<div class="discard-changes-alert">
{{ __('Are you sure you want to discard your changes?') }}
<div class="discard-actions">
<button
class="btn btn-sm btn-danger-secondary gl-button"
@click="acceptDiscardConfirmation(file)"
>
{{ __('Discard changes') }}
</button>
<button class="btn btn-default btn-sm gl-button" @click="cancelDiscardConfirmation(file)">
{{ __('Cancel') }}
</button>
</div>
<div v-show="file.showEditor">
<div v-if="file.promptDiscardConfirmation" class="discard-changes-alert">
{{ __('Are you sure you want to discard your changes?') }}
<div class="gl-ml-3 gl-display-inline-block">
<gl-button
size="small"
variant="danger"
category="secondary"
@click="acceptDiscardConfirmation(file)"
>
{{ __('Discard changes') }}
</gl-button>
<gl-button size="small" @click="cancelDiscardConfirmation(file)">
{{ __('Cancel') }}
</gl-button>
</div>
</div>
<div :class="classObject" class="editor-wrap">

View File

@ -35,7 +35,7 @@ export default {
<td :class="lineCssClass(line)" class="diff-line-num header"></td>
<td :class="lineCssClass(line)" class="line_content header">
<strong>{{ line.richText }}</strong>
<button class="btn" @click="handleSelected({ file, line })">
<button type="button" @click="handleSelected({ file, line })">
{{ line.buttonTitle }}
</button>
</td>

View File

@ -35,7 +35,7 @@ export default {
<td class="diff-line-num header" :class="lineCssClass(line)"></td>
<td class="line_content header" :class="lineCssClass(line)">
<strong>{{ line.richText }}</strong>
<button class="btn" @click="handleSelected({ file, line })">
<button type="button" @click="handleSelected({ file, line })">
{{ line.buttonTitle }}
</button>
</td>

View File

@ -1,5 +1,5 @@
<script>
import { GlSprintf } from '@gitlab/ui';
import { GlSprintf, GlButton, GlButtonGroup } from '@gitlab/ui';
import { mapGetters, mapState, mapActions } from 'vuex';
import { __ } from '~/locale';
import FileIcon from '~/vue_shared/components/file_icon.vue';
@ -20,6 +20,8 @@ import { INTERACTIVE_RESOLVE_MODE } from './constants';
*/
export default {
components: {
GlButton,
GlButtonGroup,
GlSprintf,
FileIcon,
DiffFileEditor,
@ -77,28 +79,23 @@ export default {
{{ conflictsData.errorMessage }}
</div>
<template v-if="!isLoading && !hasError">
<div class="content-block oneline-block files-changed">
<div v-if="fileTextTypePresent" class="inline-parallel-buttons">
<div class="btn-group">
<button
:class="{ active: !isParallel }"
class="btn gl-button"
@click="setViewType('inline')"
>
<div class="gl-border-b-0 gl-py-5 gl-line-height-32">
<div v-if="fileTextTypePresent" class="gl-float-right">
<gl-button-group>
<gl-button :selected="!isParallel" @click="setViewType('inline')">
{{ __('Inline') }}
</button>
<button
:class="{ active: isParallel }"
class="btn gl-button"
</gl-button>
<gl-button
:selected="isParallel"
data-testid="side-by-side"
@click="setViewType('parallel')"
>
{{ __('Side-by-side') }}
</button>
</div>
</gl-button>
</gl-button-group>
</div>
<div class="js-toggle-container">
<div class="commit-stat-summary" data-testid="conflicts-count">
<div data-testid="conflicts-count">
<gl-sprintf :message="$options.i18n.commitStatSummary">
<template #conflict>
<strong class="cred">{{ getConflictsCountText }}</strong>
@ -127,47 +124,43 @@ export default {
<strong class="file-title-name">{{ file.filePath }}</strong>
</div>
<div class="file-actions d-flex align-items-center gl-ml-auto gl-align-self-start">
<div v-if="file.type === 'text'" class="btn-group gl-mr-3">
<button
:class="{ active: file.resolveMode === 'interactive' }"
class="btn gl-button"
type="button"
<gl-button-group v-if="file.type === 'text'" class="gl-mr-3">
<gl-button
:selected="file.resolveMode === 'interactive'"
data-testid="interactive-button"
@click="onClickResolveModeButton(file, 'interactive')"
>
{{ __('Interactive mode') }}
</button>
<button
:class="{ active: file.resolveMode === 'edit' }"
class="btn gl-button"
type="button"
</gl-button>
<gl-button
:selected="file.resolveMode === 'edit'"
data-testid="inline-button"
@click="onClickResolveModeButton(file, 'edit')"
>
{{ __('Edit inline') }}
</button>
</div>
<a :href="file.blobPath" class="btn gl-button view-file">
</gl-button>
</gl-button-group>
<gl-button :href="file.blobPath">
<gl-sprintf :message="__('View file @ %{commitSha}')">
<template #commitSha>
{{ conflictsData.shortCommitSha }}
</template>
</gl-sprintf>
</a>
</gl-button>
</div>
</div>
<div class="diff-content diff-wrap-lines">
<template v-if="file.resolveMode === 'interactive' && file.type === 'text'">
<div v-if="!isParallel" class="file-content">
<inline-conflict-lines :file="file" />
</div>
<div v-if="isParallel" class="file-content">
<parallel-conflict-lines :file="file" />
</div>
</template>
<div v-if="file.resolveMode === 'edit' || file.type === 'text-editor'">
<diff-file-editor :file="file" />
<div
v-if="file.resolveMode === 'interactive' && file.type === 'text'"
class="file-content"
>
<parallel-conflict-lines v-if="isParallel" :file="file" />
<inline-conflict-lines v-else :file="file" />
</div>
<diff-file-editor
v-if="file.resolveMode === 'edit' || file.type === 'text-editor'"
:file="file"
/>
</div>
</div>
</div>
@ -176,10 +169,10 @@ export default {
<div class="resolve-conflicts-form">
<div class="form-group row">
<div class="col-md-4">
<h4>
<h4 class="gl-mt-0">
{{ __('Resolve conflicts on source branch') }}
</h4>
<div class="resolve-info">
<div class="gl-mb-5" data-testid="resolve-info">
<gl-sprintf :message="$options.i18n.resolveInfo">
<template #use_ours>
<code>{{ s__('MergeConflict|Use ours') }}</code>
@ -199,7 +192,7 @@ export default {
<label class="label-bold" for="commit-message">
{{ __('Commit message') }}
</label>
<div class="commit-message-container">
<div class="commit-message-container gl-mb-4">
<div class="max-width-marker"></div>
<textarea
id="commit-message"
@ -209,27 +202,17 @@ export default {
rows="5"
></textarea>
</div>
</div>
</div>
<div class="form-group row">
<div class="offset-md-4 col-md-8">
<div class="row">
<div class="col-6">
<button
:disabled="!isReadyToCommit"
class="btn gl-button btn-success js-submit-button"
type="button"
@click="submitResolvedConflicts(resolveConflictsPath)"
>
<span>{{ getCommitButtonText }}</span>
</button>
</div>
<div class="col-6 text-right">
<a :href="mergeRequestPath" class="gl-button btn btn-default">
{{ __('Cancel') }}
</a>
</div>
</div>
<gl-button
:disabled="!isReadyToCommit"
variant="confirm"
class="js-submit-button"
@click="submitResolvedConflicts(resolveConflictsPath)"
>
{{ getCommitButtonText }}
</gl-button>
<gl-button :href="mergeRequestPath">
{{ __('Cancel') }}
</gl-button>
</div>
</div>
</div>

View File

@ -284,7 +284,7 @@ export default {
<gl-datepicker
ref="datePicker"
class="gl-relative"
:value="parsedDate"
:default-date="parsedDate"
show-clear-button
@input="setDate"
@clear="setDate(null)"

View File

@ -670,10 +670,6 @@ table.code {
float: right;
}
.files-changed {
border-bottom: 0;
}
.merge-request-details .file-content.image_file img {
max-height: 50vh;
}

View File

@ -853,7 +853,7 @@ header.header-content .dropdown-menu.frequent-items-dropdown-menu {
.frequent-items-dropdown-sidebar,
.frequent-items-dropdown-content {
padding: 8px 0;
@include gl-pt-3;
}
.loading-animation {
@ -895,7 +895,6 @@ header.header-content .dropdown-menu.frequent-items-dropdown-menu {
}
.frequent-items-list-container {
height: 304px;
padding: 8px 0;
overflow-y: auto;

View File

@ -5,16 +5,7 @@
*/
.status-box {
/* Extra small devices (phones, less than 768px) */
/* No media query since this is the default in Bootstrap */
padding: 5px 11px;
margin-top: 4px;
/* Small devices (tablets, 768px and up) */
@include media-breakpoint-up(sm) {
padding: 0 $gl-btn-padding;
margin-top: 5px;
}
padding: 0 $gl-btn-padding;
border-radius: $border-radius-default;
display: block;

View File

@ -173,22 +173,5 @@
text-align: right;
padding: $gl-padding-top $gl-padding;
color: var(--gl-text-color, $gl-text-color);
.discard-actions {
display: inline-block;
margin-left: 10px;
}
}
.resolve-conflicts-form {
h4 {
margin-top: 0;
}
.resolve-info {
@media(max-width: map-get($grid-breakpoints, lg)-1) {
margin-bottom: $gl-padding;
}
}
}
}

View File

@ -38,18 +38,6 @@ $status-box-line-height: 26px;
color: var(--blue-600, $blue-600);
}
}
.status-box {
font-size: $tooltip-font-size;
margin-top: 0;
margin-right: $gl-padding-4;
line-height: $status-box-line-height;
@include media-breakpoint-down(xs) {
line-height: unset;
padding: $gl-padding-4 $gl-input-padding;
}
}
}
}
@ -199,11 +187,6 @@ $status-box-line-height: 26px;
align-items: center;
flex-wrap: wrap;
.status-box {
margin-top: 0;
order: 1;
}
.milestone-buttons {
margin-left: auto;
order: 2;

View File

@ -46,7 +46,7 @@ module PageLimiter
if params[:page].present? && params[:page].to_i > max_page_number
record_page_limit_interception
raise PageOutOfBoundsError.new(max_page_number)
raise PageOutOfBoundsError, max_page_number
end
end

View File

@ -37,7 +37,7 @@ module Packages
@mod.version_by(commit: target)
else
raise ArgumentError.new 'not a valid target'
raise ArgumentError, 'not a valid target'
end
end
end

View File

@ -18,7 +18,7 @@ module TimeZoneHelper
def timezone_data(format: :short)
attrs = TIME_ZONE_FORMAT_ATTRS.fetch(format) do
valid_formats = TIME_ZONE_FORMAT_ATTRS.keys.map { |k| ":#{k}"}.join(", ")
raise ArgumentError.new("Invalid format :#{format}. Valid formats are #{valid_formats}.")
raise ArgumentError, "Invalid format :#{format}. Valid formats are #{valid_formats}."
end
ActiveSupport::TimeZone.all.map do |timezone|

View File

@ -35,7 +35,7 @@ class BulkImports::Tracker < ApplicationRecord
def pipeline_class
unless BulkImports::Stage.pipeline_exists?(pipeline_name)
raise NameError.new("'#{pipeline_name}' is not a valid BulkImport Pipeline")
raise NameError, "'#{pipeline_name}' is not a valid BulkImport Pipeline"
end
pipeline_name.constantize

View File

@ -26,7 +26,7 @@ module CacheMarkdownField
# Returns the default Banzai render context for the cached markdown field.
def banzai_render_context(field)
raise ArgumentError.new("Unknown field: #{field.inspect}") unless
raise ArgumentError, "Unknown field: #{field.inspect}" unless
cached_markdown_fields.markdown_fields.include?(field)
# Always include a project key, or Banzai complains
@ -99,7 +99,7 @@ module CacheMarkdownField
end
def cached_html_for(markdown_field)
raise ArgumentError.new("Unknown field: #{markdown_field}") unless
raise ArgumentError, "Unknown field: #{markdown_field}" unless
cached_markdown_fields.markdown_fields.include?(markdown_field)
__send__(cached_markdown_fields.html_field(markdown_field)) # rubocop:disable GitlabSecurity/PublicSend

View File

@ -22,7 +22,7 @@ module GroupDescendant
return [] if descendants.empty?
unless descendants.all? { |hierarchy| hierarchy.is_a?(GroupDescendant) }
raise ArgumentError.new(_('element is not a hierarchy'))
raise ArgumentError, _('element is not a hierarchy')
end
all_hierarchies = descendants.map do |descendant|
@ -56,7 +56,7 @@ module GroupDescendant
end
if parent.nil? && hierarchy_top.present?
raise ArgumentError.new(_('specified top is not part of the tree'))
raise ArgumentError, _('specified top is not part of the tree')
end
if parent && parent != hierarchy_top

View File

@ -59,7 +59,7 @@ module HasWikiPageMetaAttributes
if conflict.present?
meta.errors.add(:canonical_slug, 'Duplicate value found')
raise CanonicalSlugConflictError.new(meta)
raise CanonicalSlugConflictError, meta
end
meta

View File

@ -168,7 +168,7 @@ module ReactiveCaching
data_deep_size = Gitlab::Utils::DeepSize.new(data, max_size: self.class.reactive_cache_hard_limit)
raise ExceededReactiveCacheLimit.new unless data_deep_size.valid?
raise ExceededReactiveCacheLimit unless data_deep_size.valid?
end
end
end

View File

@ -31,7 +31,7 @@ module Sha256Attribute
end
unless column.type == :binary
raise ArgumentError.new("sha256_attribute #{name.inspect} is invalid since the column type is not :binary")
raise ArgumentError, "sha256_attribute #{name.inspect} is invalid since the column type is not :binary"
end
rescue StandardError => error
Gitlab::AppLogger.error "Sha256Attribute initialization: #{error.message}"

View File

@ -24,7 +24,7 @@ module ShaAttribute
return unless column
unless column.type == :binary
raise ArgumentError.new("sha_attribute #{name.inspect} is invalid since the column type is not :binary")
raise ArgumentError, "sha_attribute #{name.inspect} is invalid since the column type is not :binary"
end
rescue StandardError => error
Gitlab::AppLogger.error "ShaAttribute initialization: #{error.message}"

View File

@ -10,7 +10,7 @@ module Storage
proj_with_tags = first_project_with_container_registry_tags
if proj_with_tags
raise Gitlab::UpdatePathError.new("Namespace #{name} (#{id}) cannot be moved because at least one project (e.g. #{proj_with_tags.name} (#{proj_with_tags.id})) has tags in container registry")
raise Gitlab::UpdatePathError, "Namespace #{name} (#{id}) cannot be moved because at least one project (e.g. #{proj_with_tags.name} (#{proj_with_tags.id})) has tags in container registry"
end
parent_was = if saved_change_to_parent? && parent_id_before_last_save.present?
@ -83,7 +83,7 @@ module Storage
# if we cannot move namespace directory we should rollback
# db changes in order to prevent out of sync between db and fs
raise Gitlab::UpdatePathError.new('namespace directory cannot be moved')
raise Gitlab::UpdatePathError, 'namespace directory cannot be moved'
end
end
end

View File

@ -12,7 +12,7 @@ module TokenAuthenticatable
def add_authentication_token_field(token_field, options = {})
if token_authenticatable_fields.include?(token_field)
raise ArgumentError.new("#{token_field} already configured via add_authentication_token_field")
raise ArgumentError, "#{token_field} already configured via add_authentication_token_field"
end
token_authenticatable_fields.push(token_field)

View File

@ -31,7 +31,7 @@ module X509SerialNumberAttribute
end
unless column.type == :binary
raise ArgumentError.new("x509_serial_number_attribute #{name.inspect} is invalid since the column type is not :binary")
raise ArgumentError, "x509_serial_number_attribute #{name.inspect} is invalid since the column type is not :binary"
end
rescue StandardError => error
Gitlab::AppLogger.error "X509SerialNumberAttribute initialization: #{error.message}"

View File

@ -20,7 +20,7 @@ class Namespace
end
def initialize(root)
raise StandardError.new('Must specify a root node') if root.parent_id
raise StandardError, 'Must specify a root node' if root.parent_id
@root = root
end

View File

@ -85,7 +85,7 @@ module Namespaces
# Search this namespace's lineage. Bound inclusively by top node.
def lineage(top)
raise UnboundedSearch.new('Must bound search by a top') unless top
raise UnboundedSearch, 'Must bound search by a top' unless top
without_sti_condition
.traversal_ids_contains("{#{top.id}}")

View File

@ -18,8 +18,8 @@ module Packages
end
def version_by(ref: nil, commit: nil)
raise ArgumentError.new 'no filter specified' unless ref || commit
raise ArgumentError.new 'ref and commit are mutually exclusive' if ref && commit
raise ArgumentError, 'no filter specified' unless ref || commit
raise ArgumentError, 'ref and commit are mutually exclusive' if ref && commit
if commit
return version_by_sha(commit) if commit.is_a? String

View File

@ -17,15 +17,15 @@ module Packages
delegate :build, to: :@semver, allow_nil: true
def initialize(mod, type, commit, name: nil, semver: nil, ref: nil)
raise ArgumentError.new("invalid type '#{type}'") unless VALID_TYPES.include? type
raise ArgumentError.new("mod is required") unless mod
raise ArgumentError.new("commit is required") unless commit
raise ArgumentError, "invalid type '#{type}'" unless VALID_TYPES.include? type
raise ArgumentError, "mod is required" unless mod
raise ArgumentError, "commit is required" unless commit
if type == :ref
raise ArgumentError.new("ref is required") unless ref
raise ArgumentError, "ref is required" unless ref
elsif type == :pseudo
raise ArgumentError.new("name is required") unless name
raise ArgumentError.new("semver is required") unless semver
raise ArgumentError, "name is required" unless name
raise ArgumentError, "semver is required" unless semver
end
@mod = mod

View File

@ -1004,7 +1004,7 @@ class Project < ApplicationRecord
end
def latest_successful_build_for_ref!(job_name, ref = default_branch)
latest_successful_build_for_ref(job_name, ref) || raise(ActiveRecord::RecordNotFound.new("Couldn't find job #{job_name}"))
latest_successful_build_for_ref(job_name, ref) || raise(ActiveRecord::RecordNotFound, "Couldn't find job #{job_name}")
end
def latest_pipeline(ref = default_branch, sha = nil)

View File

@ -5,7 +5,7 @@ module Releases
include ShaAttribute
include Presentable
belongs_to :release, inverse_of: :evidences
belongs_to :release, inverse_of: :evidences, touch: true
default_scope { order(created_at: :asc) } # rubocop:disable Cop/DefaultScope

View File

@ -4,7 +4,7 @@ module Releases
class Link < ApplicationRecord
self.table_name = 'release_links'
belongs_to :release
belongs_to :release, touch: true
# See https://gitlab.com/gitlab-org/gitlab/-/issues/218753
# Regex modified to prevent catastrophic backtracking

View File

@ -128,10 +128,10 @@ class SshHostKey
def normalize_url(url)
full_url = ::Addressable::URI.parse(url)
raise ArgumentError.new("Invalid URL") unless full_url&.scheme == 'ssh'
raise ArgumentError, "Invalid URL" unless full_url&.scheme == 'ssh'
Addressable::URI.parse("ssh://#{full_url.host}:#{full_url.inferred_port}")
rescue Addressable::URI::InvalidURIError
raise ArgumentError.new("Invalid URL")
raise ArgumentError, "Invalid URL"
end
end

View File

@ -25,13 +25,6 @@ module AlertManagement
attr_reader :project, :payload
override :process_new_alert
def process_new_alert
return if resolving_alert?
super
end
override :incoming_payload
def incoming_payload
strong_memoize(:incoming_payload) do

View File

@ -14,7 +14,7 @@ module Clusters
end
def execute
raise MissingRoleError.new('AWS provisioning role not configured') unless provision_role.present?
raise MissingRoleError, 'AWS provisioning role not configured' unless provision_role.present?
::Aws::AssumeRoleCredentials.new(
client: client,

View File

@ -19,11 +19,7 @@ module AlertManagement
# Updates or creates alert from payload for project
# including system notes
def process_alert
if alert.persisted?
process_existing_alert
else
process_new_alert
end
alert.persisted? ? process_existing_alert : process_new_alert
end
# Creates or closes issue for alert and notifies stakeholders
@ -33,22 +29,16 @@ module AlertManagement
end
def process_existing_alert
if resolving_alert?
process_resolved_alert
else
process_firing_alert
end
resolving_alert? ? process_resolved_alert : process_firing_alert
end
def process_resolved_alert
SystemNoteService.log_resolving_alert(alert, alert_source)
return unless auto_close_incident?
if alert.resolve(incoming_payload.ends_at)
SystemNoteService.change_alert_status(alert, User.alert_bot)
close_issue(alert.issue)
close_issue(alert.issue) if auto_close_incident?
else
logger.warn(
message: 'Unable to update AlertManagement::Alert status to resolved',
@ -76,6 +66,8 @@ module AlertManagement
if alert.save
alert.execute_services
SystemNoteService.create_new_alert(alert, alert_source)
process_resolved_alert if resolving_alert?
else
logger.warn(
message: "Unable to create AlertManagement::Alert from #{alert_source}",
@ -128,7 +120,7 @@ module AlertManagement
end
def alert_source
alert.monitoring_tool
incoming_payload.monitoring_tool
end
def logger

View File

@ -96,7 +96,7 @@ module Groups
def notify_error!
notify_error
raise Gitlab::ImportExport::Error.new(shared.errors.to_sentence)
raise Gitlab::ImportExport::Error, shared.errors.to_sentence
end
def notify_success

View File

@ -114,7 +114,7 @@ module Groups
def notify_error!
notify_error
raise Gitlab::ImportExport::Error.new(shared.errors.to_sentence)
raise Gitlab::ImportExport::Error, shared.errors.to_sentence
end
def remove_base_tmp_dir

View File

@ -80,7 +80,7 @@ module Metrics
def fetch_dashboard
uid = GrafanaUidParser.new(grafana_url, project).parse
raise DashboardProcessingError.new(_('Dashboard uid not found')) unless uid
raise DashboardProcessingError, _('Dashboard uid not found') unless uid
response = client.get_dashboard(uid: uid)
@ -89,7 +89,7 @@ module Metrics
def fetch_datasource(dashboard)
name = DatasourceNameParser.new(grafana_url, dashboard).parse
raise DashboardProcessingError.new(_('Datasource name not found')) unless name
raise DashboardProcessingError, _('Datasource name not found') unless name
response = client.get_datasource(name: name)
@ -115,7 +115,7 @@ module Metrics
def parse_json(json)
Gitlab::Json.parse(json, symbolize_names: true)
rescue JSON::ParserError
raise DashboardProcessingError.new(_('Grafana response contains invalid json'))
raise DashboardProcessingError, _('Grafana response contains invalid json')
end
end

View File

@ -39,7 +39,7 @@ module Metrics
end
def invalid_embed_json!(message)
raise DashboardProcessingError.new(_("Parsing error for param :embed_json. %{message}") % { message: message })
raise DashboardProcessingError, _("Parsing error for param :embed_json. %{message}") % { message: message }
end
end
end

View File

@ -9,7 +9,7 @@ module Namespaces
root_storage_statistics.recalculate!
rescue ActiveRecord::ActiveRecordError => e
raise RefresherError.new(e.message)
raise RefresherError, e.message
end
private

View File

@ -172,6 +172,8 @@ module NotificationRecipients
# Get project users with WATCH notification level
# rubocop: disable CodeReuse/ActiveRecord
def project_watchers
return new_project_watchers if Feature.enabled?(:notification_setting_recipient_refactor, project)
project_members_ids = user_ids_notifiable_on(project)
user_ids_with_project_global = user_ids_notifiable_on(project, :global)
@ -184,16 +186,38 @@ module NotificationRecipients
user_scope.where(id: user_ids_with_project_setting.concat(user_ids_with_group_setting).uniq)
end
def new_project_watchers
notification_by_sources = related_notification_settings_sources(:watch)
return if notification_by_sources.blank?
user_ids = NotificationSetting.from_union(notification_by_sources).select(:user_id)
user_scope.where(id: user_ids)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def group_watchers
return new_group_watchers if Feature.enabled?(:notification_setting_recipient_refactor, project)
user_ids_with_group_global = user_ids_notifiable_on(group, :global)
user_ids = user_ids_with_global_level_watch(user_ids_with_group_global)
user_ids_with_group_setting = select_group_members_ids(group, [], user_ids_with_group_global, user_ids)
user_scope.where(id: user_ids_with_group_setting)
end
def new_group_watchers
return [] unless group
user_ids = group
.notification_settings
.where(source_or_global_setting_by_level_query(:watch)).select(:user_id)
user_scope.where(id: user_ids)
end
# rubocop: enable CodeReuse/ActiveRecord
def add_subscribed_users

View File

@ -20,7 +20,7 @@ module Packages
files: files
}
rescue ActiveModel::ValidationError => e
raise ExtractionError.new(e.message)
raise ExtractionError, e.message
end
private
@ -41,10 +41,10 @@ module Packages
def files
strong_memoize(:files) do
raise ExtractionError.new("is not a changes file") unless file_type == :changes
raise ExtractionError.new("Files field is missing") if fields['Files'].blank?
raise ExtractionError.new("Checksums-Sha1 field is missing") if fields['Checksums-Sha1'].blank?
raise ExtractionError.new("Checksums-Sha256 field is missing") if fields['Checksums-Sha256'].blank?
raise ExtractionError, "is not a changes file" unless file_type == :changes
raise ExtractionError, "Files field is missing" if fields['Files'].blank?
raise ExtractionError, "Checksums-Sha1 field is missing" if fields['Checksums-Sha1'].blank?
raise ExtractionError, "Checksums-Sha256 field is missing" if fields['Checksums-Sha256'].blank?
init_entries_from_files
entries_from_checksums_sha1
@ -73,8 +73,8 @@ module Packages
each_lines_for('Checksums-Sha1') do |line|
sha1sum, size, filename = line.split
entry = @entries[filename]
raise ExtractionError.new("#{filename} is listed in Checksums-Sha1 but not in Files") unless entry
raise ExtractionError.new("Size for #{filename} in Files and Checksums-Sha1 differ") unless entry.size == size.to_i
raise ExtractionError, "#{filename} is listed in Checksums-Sha1 but not in Files" unless entry
raise ExtractionError, "Size for #{filename} in Files and Checksums-Sha1 differ" unless entry.size == size.to_i
entry.sha1sum = sha1sum
end
@ -84,8 +84,8 @@ module Packages
each_lines_for('Checksums-Sha256') do |line|
sha256sum, size, filename = line.split
entry = @entries[filename]
raise ExtractionError.new("#{filename} is listed in Checksums-Sha256 but not in Files") unless entry
raise ExtractionError.new("Size for #{filename} in Files and Checksums-Sha256 differ") unless entry.size == size.to_i
raise ExtractionError, "#{filename} is listed in Checksums-Sha256 but not in Files" unless entry
raise ExtractionError, "Size for #{filename} in Files and Checksums-Sha256 differ" unless entry.size == size.to_i
entry.sha256sum = sha256sum
end
@ -104,7 +104,7 @@ module Packages
entry.package_file = ::Packages::PackageFileFinder.new(@package_file.package, filename).execute!
entry.validate!
rescue ActiveRecord::RecordNotFound
raise ExtractionError.new("#{filename} is listed in Files but was not uploaded")
raise ExtractionError, "#{filename} is listed in Files but was not uploaded"
end
end
end

View File

@ -12,7 +12,7 @@ module Packages
end
def execute
raise ExtractionError.new('invalid package file') unless valid_package_file?
raise ExtractionError, 'invalid package file' unless valid_package_file?
extract_metadata
end

View File

@ -26,7 +26,7 @@ module Packages
end
def execute
raise ExtractionError.new('invalid package file') unless valid_package_file?
raise ExtractionError, 'invalid package file' unless valid_package_file?
extract_metadata(nuspec_file)
end
@ -94,8 +94,8 @@ module Packages
Zip::File.open(file_path) do |zip_file|
entry = zip_file.glob('*.nuspec').first
raise ExtractionError.new('nuspec file not found') unless entry
raise ExtractionError.new('nuspec file too big') if entry.size > MAX_FILE_SIZE
raise ExtractionError, 'nuspec file not found' unless entry
raise ExtractionError, 'nuspec file too big' if entry.size > MAX_FILE_SIZE
entry.get_input_stream.read
end

View File

@ -16,7 +16,7 @@ module Packages
end
def execute
raise InvalidMetadataError.new('package name and/or package version not found in metadata') unless valid_metadata?
raise InvalidMetadataError, 'package name and/or package version not found in metadata' unless valid_metadata?
try_obtain_lease do
@package_file.transaction do
@ -33,7 +33,7 @@ module Packages
end
end
rescue ActiveRecord::RecordInvalid => e
raise InvalidMetadataError.new(e.message)
raise InvalidMetadataError, e.message
end
private

View File

@ -13,7 +13,7 @@ module Packages
)
unless meta.valid?
raise ActiveRecord::RecordInvalid.new(meta)
raise ActiveRecord::RecordInvalid, meta
end
Packages::Pypi::Metadatum.upsert(meta.attributes)

View File

@ -107,7 +107,7 @@ module Packages
Gem::Package.new(File.open(file_path))
end
rescue StandardError
raise ExtractionError.new('Unable to read gem file')
raise ExtractionError, 'Unable to read gem file'
end
# used by ExclusiveLeaseGuard

View File

@ -49,10 +49,8 @@ module Projects
def first_ensure_no_registry_tags_are_present
return unless project.has_container_registry_tags?
raise RenameFailedError.new(
"Project #{full_path_before} cannot be renamed because images are " \
raise RenameFailedError, "Project #{full_path_before} cannot be renamed because images are " \
"present in its container registry"
)
end
def expire_caches_before_rename
@ -144,7 +142,7 @@ module Projects
Gitlab::AppLogger.error(error)
raise RenameFailedError.new(error)
raise RenameFailedError, error
end
end
end

View File

@ -174,7 +174,7 @@ module Projects
end
def raise_error(message)
raise DestroyError.new(message)
raise DestroyError, message
end
def flush_caches(project)

View File

@ -112,7 +112,7 @@ module Projects
def notify_error!
notify_error
raise Gitlab::ImportExport::Error.new(shared.errors.to_sentence)
raise Gitlab::ImportExport::Error, shared.errors.to_sentence
end
def notify_success

View File

@ -47,16 +47,16 @@ module Projects
@old_namespace = project.namespace
if Project.where(namespace_id: @new_namespace.try(:id)).where('path = ? or name = ?', project.path, project.name).exists?
raise TransferError.new(s_("TransferProject|Project with same name or path in target namespace already exists"))
raise TransferError, s_("TransferProject|Project with same name or path in target namespace already exists")
end
if project.has_container_registry_tags?
# We currently don't support renaming repository if it contains tags in container registry
raise TransferError.new(s_('TransferProject|Project cannot be transferred, because tags are present in its container registry'))
raise TransferError, s_('TransferProject|Project cannot be transferred, because tags are present in its container registry')
end
if project.has_packages?(:npm) && !new_namespace_has_same_root?(project)
raise TransferError.new(s_("TransferProject|Root namespace can't be updated if project has NPM packages"))
raise TransferError, s_("TransferProject|Root namespace can't be updated if project has NPM packages")
end
proceed_to_transfer
@ -170,7 +170,7 @@ module Projects
# Move main repository
unless move_repo_folder(@old_path, @new_path)
raise TransferError.new(s_("TransferProject|Cannot move project"))
raise TransferError, s_("TransferProject|Cannot move project")
end
# Disk path is changed; we need to ensure we reload it

View File

@ -49,11 +49,11 @@ module Projects
def validate!
unless valid_visibility_level_change?(project, params[:visibility_level])
raise ValidationError.new(s_('UpdateProject|New visibility level not allowed!'))
raise ValidationError, s_('UpdateProject|New visibility level not allowed!')
end
if renaming_project_with_container_registry_tags?
raise ValidationError.new(s_('UpdateProject|Cannot rename project because it contains container registry tags!'))
raise ValidationError, s_('UpdateProject|Cannot rename project because it contains container registry tags!')
end
validate_default_branch_change
@ -67,7 +67,7 @@ module Projects
if project.change_head(params[:default_branch])
after_default_branch_change(previous_default_branch)
else
raise ValidationError.new(s_("UpdateProject|Could not set the default branch"))
raise ValidationError, s_("UpdateProject|Could not set the default branch")
end
end

View File

@ -67,7 +67,7 @@ module StaticSiteEditor
def check_for_duplicate_keys!(generated_data, file_data)
duplicate_keys = generated_data.keys & file_data.keys
raise ValidationError.new("Duplicate key(s) '#{duplicate_keys}' found.") if duplicate_keys.present?
raise ValidationError, "Duplicate key(s) '#{duplicate_keys}' found." if duplicate_keys.present?
end
def merged_data(generated_data, file_data)

View File

@ -22,7 +22,7 @@ class SubmitUsagePingService
usage_data = Gitlab::UsageData.data(force_refresh: true)
raise SubmissionError.new('Usage data is blank') if usage_data.blank?
raise SubmissionError, 'Usage data is blank' if usage_data.blank?
raw_usage_data = save_raw_usage_data(usage_data)
@ -33,12 +33,12 @@ class SubmitUsagePingService
headers: { 'Content-type' => 'application/json' }
)
raise SubmissionError.new("Unsuccessful response code: #{response.code}") unless response.success?
raise SubmissionError, "Unsuccessful response code: #{response.code}" unless response.success?
version_usage_data_id = response.dig('conv_index', 'usage_data_id') || response.dig('dev_ops_score', 'usage_data_id')
unless version_usage_data_id.is_a?(Integer) && version_usage_data_id > 0
raise SubmissionError.new("Invalid usage_data_id in response: #{version_usage_data_id}")
raise SubmissionError, "Invalid usage_data_id in response: #{version_usage_data_id}"
end
raw_usage_data.update_version_metadata!(usage_data_id: version_usage_data_id)

View File

@ -94,7 +94,7 @@ module Terraform
end
def find_state!(find_params)
find_state(find_params) || raise(ActiveRecord::RecordNotFound.new("Couldn't find state"))
find_state(find_params) || raise(ActiveRecord::RecordNotFound, "Couldn't find state")
end
end
end

View File

@ -9,7 +9,7 @@ module Todos
def initialize(user_id, entity_id, entity_type)
unless %w(Group Project).include?(entity_type)
raise ArgumentError.new("#{entity_type} is not an entity user can leave")
raise ArgumentError, "#{entity_type} is not an entity user can leave"
end
@user = UserFinder.new(user_id).find_by_id

View File

@ -8,7 +8,7 @@ module Users
def initialize(target_user:)
@target_user = target_user
raise ArgumentError.new("Please provide a target user") unless target_user.is_a?(User)
raise ArgumentError, "Please provide a target user" unless target_user.is_a?(User)
end
def execute

View File

@ -7,7 +7,7 @@ module Users
INCLUDED_DOMAINS_PATTERN = [/gmail.com/].freeze
def initialize(user:)
raise ArgumentError.new("Please provide a user") unless user.is_a?(User)
raise ArgumentError, "Please provide a user" unless user.is_a?(User)
@user = user
end

View File

@ -34,7 +34,7 @@ module Users
def execute!(*args, &block)
result = execute(*args, &block)
raise ActiveRecord::RecordInvalid.new(@user) unless result[:status] == :success
raise ActiveRecord::RecordInvalid, @user unless result[:status] == :success
true
end

View File

@ -451,7 +451,7 @@ module ObjectStorage
def with_exclusive_lease
lease_key = exclusive_lease_key
uuid = Gitlab::ExclusiveLease.new(lease_key, timeout: 1.hour.to_i).try_obtain
raise ExclusiveLeaseTaken.new(lease_key) unless uuid
raise ExclusiveLeaseTaken, lease_key unless uuid
yield uuid
ensure

View File

@ -10,7 +10,7 @@ class CronValidator < ActiveModel::EachValidator
cron_parser = Gitlab::Ci::CronParser.new(record.public_send(attribute), record.cron_timezone) # rubocop:disable GitlabSecurity/PublicSend
record.errors.add(attribute, " is invalid syntax") unless cron_parser.cron_valid?
else
raise NonWhitelistedAttributeError.new "Non-whitelisted attribute"
raise NonWhitelistedAttributeError, "Non-whitelisted attribute"
end
end
end

View File

@ -2,7 +2,7 @@
- add_page_specific_style 'page_bundles/ci_status'
- if Feature.enabled?(:jobs_table_vue, @project, default_enabled: :yaml)
#js-jobs-table{ data: { full_path: @project.full_path, job_counts: job_counts.to_json, job_statuses: job_statuses.to_json } }
#js-jobs-table{ data: { full_path: @project.full_path, job_counts: job_counts.to_json, job_statuses: job_statuses.to_json, pipeline_editor_path: project_ci_pipeline_editor_path(@project), empty_state_svg_path: image_path('jobs-empty-state.svg') } }
- else
.top-area
- build_path_proc = ->(scope) { project_jobs_path(@project, scope: scope) }

View File

@ -3,11 +3,10 @@
%h4
= _('Shared runners')
.bs-callout.shared-runners-description
= _('These runners are shared across this GitLab instance.')
%p
.bs-callout{ data: { testid: 'shared-runners-description' } }
%p= _('These runners are shared across this GitLab instance.')
- if Gitlab::CurrentSettings.shared_runners_text.present?
= markdown_field(Gitlab::CurrentSettings.current_application_settings, :shared_runners_text)
= markdown(Gitlab::CurrentSettings.current_application_settings.shared_runners_text)
- else
= _('The same shared runner executes code from multiple projects, unless you configure autoscaling with %{link} set to 1 (which it is on GitLab.com).').html_safe % { link: link }
%p= _('The same shared runner executes code from multiple projects, unless you configure autoscaling with %{link} set to 1 (which it is on GitLab.com).').html_safe % { link: link }
= yield

View File

@ -97,10 +97,10 @@ module GitGarbageCollectMethods
end
rescue GRPC::NotFound => e
Gitlab::GitLogger.error("#{__method__} failed:\nRepository not found")
raise Gitlab::Git::Repository::NoRepository.new(e)
raise Gitlab::Git::Repository::NoRepository, e
rescue GRPC::BadStatus => e
Gitlab::GitLogger.error("#{__method__} failed:\n#{e}")
raise Gitlab::Git::CommandError.new(e)
raise Gitlab::Git::CommandError, e
end
def get_gitaly_client(task, repository)

View File

@ -50,7 +50,7 @@ module ObjectStorage
Gitlab::AppLogger.info header(success, failures)
Gitlab::AppLogger.warn failures(failures)
raise MigrationFailures.new(failures.map(&:error)) if failures.any?
raise MigrationFailures, failures.map(&:error) if failures.any?
end
def header(success, failures)

View File

@ -33,10 +33,10 @@ module Packages
if result.success?
log_extra_metadata_on_done(:message, result.message)
else
raise SyncError.new(result.message)
raise SyncError, result.message
end
raise SyncError.new(result.message) unless result.success?
raise SyncError, result.message unless result.success?
end
private

View File

@ -11,10 +11,10 @@ module Users
def perform(target_user_ids)
target_user_ids = Array.wrap(target_user_ids)
raise ArgumentError.new('No target user ID provided') if target_user_ids.empty?
raise ArgumentError, 'No target user ID provided' if target_user_ids.empty?
target_users = User.id_in(target_user_ids)
raise ArgumentError.new('No valid target user ID provided') if target_users.empty?
raise ArgumentError, 'No valid target user ID provided' if target_users.empty?
target_users.each do |user|
Users::UpdateAssignedOpenIssueCountService.new(target_user: user).execute

View File

@ -0,0 +1,5 @@
---
title: Align UI of Merge Conflicts app with our design system
merge_request: 59400
author:
type: other

View File

@ -0,0 +1,5 @@
---
title: Refactor notification recipients builder for watchers
merge_request: 60572
author:
type: performance

View File

@ -0,0 +1,5 @@
---
title: Fix due date being randomly set in issue page
merge_request: 60917
author:
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Fix XSS vulnerability in shared runner description
merge_request: 60891
author:
type: security

View File

@ -0,0 +1,5 @@
---
title: Resolves offenses Style/RaiseArgs
merge_request: 58009
author: Shubham Kumar @imskr
type: fixed

View File

@ -0,0 +1,5 @@
---
title: Always resolve GitLab alerts when recovery alert payload is received
merge_request: 57302
author:
type: changed

View File

@ -0,0 +1,8 @@
---
name: api_caching_releases
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60194
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/329861
milestone: '13.12'
type: development
group: group::release
default_enabled: false

View File

@ -914,7 +914,7 @@ class BackportEnterpriseSchema < ActiveRecord::Migration[5.0]
MSG
end
raise StandardError.new(message)
raise StandardError, message
end
def create_missing_tables

View File

@ -62,8 +62,7 @@ must disable the **primary** node.
- If you do not have SSH access to the **primary** node, take the machine offline and
prevent it from rebooting by any means at your disposal.
Since there are many ways you may prefer to accomplish this, we will avoid a
single recommendation. You may need to:
You might need to:
- Reconfigure the load balancers.
- Change DNS records (for example, point the primary DNS record to the
@ -240,11 +239,11 @@ an external PostgreSQL database, as it can only perform changes on a **secondary
node with GitLab and the database on the same machine. As a result, a manual process is
required:
1. Promote the replica database associated with the **secondary** site. This will
set the database to read-write. The instructions vary depending on where your database is hosted:
1. Promote the replica database associated with the **secondary** site. This
sets the database to read-write. The instructions vary depending on where your database is hosted:
- [Amazon RDS](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ReadRepl.html#USER_ReadRepl.Promote)
- [Azure PostgreSQL](https://docs.microsoft.com/en-us/azure/postgresql/howto-read-replicas-portal#stop-replication)
- For other external PostgreSQL databases, save the following script in you
- For other external PostgreSQL databases, save the following script in your
secondary node, for example `/tmp/geo_promote.sh`, and modify the connection
parameters to match your environment. Then, execute it to promote the replica:
@ -292,7 +291,7 @@ required:
### Step 4. (Optional) Updating the primary domain DNS record
Updating the DNS records for the primary domain to point to the **secondary** node
will prevent the need to update all references to the primary domain to the
to prevent the need to update all references to the primary domain to the
secondary domain, like changing Git remotes and API URLs.
1. SSH into the **secondary** node and login as root:
@ -311,7 +310,7 @@ secondary domain, like changing Git remotes and API URLs.
```
NOTE:
Changing `external_url` won't prevent access via the old secondary URL, as
Changing `external_url` does not prevent access via the old secondary URL, as
long as the secondary DNS records are still intact.
1. Reconfigure the **secondary** node for the change to take effect:
@ -326,7 +325,7 @@ secondary domain, like changing Git remotes and API URLs.
gitlab-rake geo:update_primary_node_url
```
This command will use the changed `external_url` configuration defined
This command uses the changed `external_url` configuration defined
in `/etc/gitlab/gitlab.rb`.
1. For GitLab 11.11 through 12.7 only, you may need to update the **primary**
@ -334,7 +333,7 @@ secondary domain, like changing Git remotes and API URLs.
To determine if you need to do this, search for the
`gitlab_rails["geo_node_name"]` setting in your `/etc/gitlab/gitlab.rb`
file. If it is commented out with `#` or not found at all, then you will
file. If it is commented out with `#` or not found at all, then you
need to update the **primary** node's name in the database. You can search for it
like so:
@ -444,7 +443,7 @@ and after that you also need two extra steps.
Now we need to make each **secondary** node listen to changes on the new **primary** node. To do that you need
to [initiate the replication process](../setup/database.md#step-3-initiate-the-replication-process) again but this time
for another **primary** node. All the old replication settings will be overwritten.
for another **primary** node. All the old replication settings are overwritten.
## Promoting a secondary Geo cluster in GitLab Cloud Native Helm Charts
@ -479,8 +478,7 @@ must disable the **primary** site:
- If you do not have access to the **primary** Kubernetes cluster, take the cluster offline and
prevent it from coming back online by any means at your disposal.
Since there are many ways you may prefer to accomplish this, we will avoid a
single recommendation. You may need to:
You might need to:
- Reconfigure the load balancers.
- Change DNS records (for example, point the primary DNS record to the

View File

@ -27,7 +27,7 @@ to clone and fetch large repositories, speeding up development.
For a video introduction to Geo, see [Introduction to GitLab Geo - GitLab Features](https://www.youtube.com/watch?v=-HDLxSjEh6w).
To make sure you're using the right version of the documentation, navigate to [this page on GitLab.com](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/administration/geo/index.md) and choose the appropriate release from the **Switch branch/tag** dropdown. For example, [`v11.2.3-ee`](https://gitlab.com/gitlab-org/gitlab/blob/v11.2.3-ee/doc/administration/geo/index.md).
To make sure you're using the right version of the documentation, navigate to [the Geo page on GitLab.com](https://gitlab.com/gitlab-org/gitlab/blob/master/doc/administration/geo/index.md) and choose the appropriate release from the **Switch branch/tag** dropdown. For example, [`v11.2.3-ee`](https://gitlab.com/gitlab-org/gitlab/blob/v11.2.3-ee/doc/administration/geo/index.md).
## Use cases

View File

@ -1304,8 +1304,8 @@ GitLab Rails application, the Docker Registry, or something else. In this
case, since we know that since the login succeeded, we probably need to look
at the communication between the client and the Registry.
The REST API between the Docker client and Registry is [described
here](https://docs.docker.com/registry/spec/api/). Normally, one would just
The REST API between the Docker client and Registry is described
[in the Docker documentation](https://docs.docker.com/registry/spec/api/). Normally, one would just
use Wireshark or tcpdump to capture the traffic and see where things went
wrong. However, since all communications between Docker clients and servers
are done over HTTPS, it's a bit difficult to decrypt the traffic quickly even

View File

@ -71,10 +71,10 @@ Parameters:
| --------- | ---- | -------- | ----------- |
| `action` | string | no | Include only events of a particular [action type](#action-types) |
| `target_type` | string | no | Include only events of a particular [target type](#target-types) |
| `before` | date | no | Include only events created before a particular date. Please see [here for the supported format](#date-formatting) |
| `after` | date | no | Include only events created after a particular date. Please see [here for the supported format](#date-formatting) |
| `before` | date | no | Include only events created before a particular date. [View how to format dates](#date-formatting). |
| `after` | date | no | Include only events created after a particular date. [View how to format dates](#date-formatting). |
| `scope` | string | no | Include all events across a user's projects. |
| `sort` | string | no | Sort events in `asc` or `desc` order by `created_at`. Default is `desc` |
| `sort` | string | no | Sort events in `asc` or `desc` order by `created_at`. Default is `desc`. |
Example request:
@ -148,9 +148,9 @@ Parameters:
| `id` | integer | yes | The ID or Username of the user |
| `action` | string | no | Include only events of a particular [action type](#action-types) |
| `target_type` | string | no | Include only events of a particular [target type](#target-types) |
| `before` | date | no | Include only events created before a particular date. Please see [here for the supported format](#date-formatting) |
| `after` | date | no | Include only events created after a particular date. Please see [here for the supported format](#date-formatting) |
| `sort` | string | no | Sort events in `asc` or `desc` order by `created_at`. Default is `desc` |
| `before` | date | no | Include only events created before a particular date. [View how to format dates](#date-formatting). |
| `after` | date | no | Include only events created after a particular date. [View how to format dates](#date-formatting). |
| `sort` | string | no | Sort events in `asc` or `desc` order by `created_at`. Default is `desc`. |
| `page` | integer | no | The page of results to return. Defaults to 1. |
| `per_page` | integer | no | The number of results per page. Defaults to 20. |
@ -286,9 +286,9 @@ Parameters:
| `project_id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) |
| `action` | string | no | Include only events of a particular [action type](#action-types) |
| `target_type` | string | no | Include only events of a particular [target type](#target-types) |
| `before` | date | no | Include only events created before a particular date. Please see [here for the supported format](#date-formatting) |
| `after` | date | no | Include only events created after a particular date. Please see [here for the supported format](#date-formatting) |
| `sort` | string | no | Sort events in `asc` or `desc` order by `created_at`. Default is `desc` |
| `before` | date | no | Include only events created before a particular date. [View how to format dates](#date-formatting). |
| `after` | date | no | Include only events created after a particular date. [View how to format dates](#date-formatting). |
| `sort` | string | no | Sort events in `asc` or `desc` order by `created_at`. Default is `desc`. |
Example request:

View File

@ -26,7 +26,7 @@ graph LR
R -- Write/read metadata --> B
```
Client applications (e.g. GitLab Rails and Docker CLI) interact with the Container Registry through its [HTTP API](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md). The most common operations are pushing and pulling images to/from the registry, which require a series of HTTP requests in a specific order. The request flow for these operations is detailed [here](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs-gitlab/push-pull-request-flow.md).
Client applications (e.g. GitLab Rails and Docker CLI) interact with the Container Registry through its [HTTP API](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/spec/api.md). The most common operations are pushing and pulling images to/from the registry, which require a series of HTTP requests in a specific order. The request flow for these operations is detailed in the [Request flow](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs-gitlab/push-pull-request-flow.md).
The registry supports multiple [storage backends](https://gitlab.com/gitlab-org/container-registry/-/blob/master/docs/configuration.md#storage), including Google Cloud Storage (GCS) which is used for the GitLab.com registry. In the storage backend, images are stored as blobs, deduplicated, and shared across repositories. These are then linked (like a symlink) to each repository that relies on them, giving them access to the central storage location.
@ -156,7 +156,7 @@ Running *online* and [*post deployment*](../../../development/post_deployment_mi
The registry database will be partitioned from start to achieve greater performance (by limiting the amount of data to act upon and enable parallel execution), easier maintenance (by splitting tables and indexes into smaller units), and high availability (with partition independence). By partitioning the database from start we can also facilitate a sharding implementation later on if necessary.
Although blobs are shared across repositories, manifest and tag metadata are scoped by repository. This is also visible at the API level, where all write and read requests (except [listing repositories](https://gitlab.com/gitlab-org/container-registry/-/blob/a113d0f0ab29b49cf88e173ee871893a9fc56a90/docs/spec/api.md#listing-repositories)) are scoped by repository, with its namespace being part of the request URI. For this reason, after [identifying access patterns](https://gitlab.com/gitlab-org/gitlab/-/issues/234255), we decided to partition manifests and tags by repository and blobs by digest, ensuring that lookups are always performed by partition key for optimal performance. The initial version of the partitioned schema was documented [here](https://gitlab.com/gitlab-com/www-gitlab-com/-/merge_requests/60918).
Although blobs are shared across repositories, manifest and tag metadata are scoped by repository. This is also visible at the API level, where all write and read requests (except [listing repositories](https://gitlab.com/gitlab-org/container-registry/-/blob/a113d0f0ab29b49cf88e173ee871893a9fc56a90/docs/spec/api.md#listing-repositories)) are scoped by repository, with its namespace being part of the request URI. For this reason, after [identifying access patterns](https://gitlab.com/gitlab-org/gitlab/-/issues/234255), we decided to partition manifests and tags by repository and blobs by digest, ensuring that lookups are always performed by partition key for optimal performance. The initial version of the partitioned schema was documented [in a merge request](https://gitlab.com/gitlab-com/www-gitlab-com/-/merge_requests/60918).
#### GitLab.com

View File

@ -35,10 +35,10 @@ sequenceDiagram
Content image resizing is a more complex problem to tackle. There are no set size restrictions and there are additional features or requirements to consider.
- Dynamic WebP support - the WebP format typically achieves an average of 30% more compression than JPEG without the loss of image quality. More details [here](https://developers.google.com/speed/webp/docs/c_study)
- Dynamic WebP support - the WebP format typically achieves an average of 30% more compression than JPEG without the loss of image quality. More details are in [this Google Comparative Study](https://developers.google.com/speed/webp/docs/c_study)
- Extract first image of GIF's so we can prevent from loading 10MB pixels
- Check Device Pixel Ratio to deliver nice images on High DPI screens
- Progressive image loading, similar to what is described [here](https://www.sitepoint.com/how-to-build-your-own-progressive-image-loader/)
- Progressive image loading, similar to what is described in [this article about how to build a progressive image loader](https://www.sitepoint.com/how-to-build-your-own-progressive-image-loader/)
- Resizing recommendations (size, clarity, etc.)
- Storage

View File

@ -266,7 +266,7 @@ Changes to the issue format can be submitted in the
Any feature flag change that affects any GitLab instance is automatically logged in
[features_json.log](../../administration/logs.md#features_jsonlog).
You can search the change history in [Kibana](https://about.gitlab.com/handbook/support/workflows/kibana.html).
You can access the feature flag change history for GitLab.com [here](https://log.gprd.gitlab.net/goto/d060337c017723084c6d97e09e591fc6).
You can also access the feature flag change history for GitLab.com [in Kibana](https://log.gprd.gitlab.net/goto/d060337c017723084c6d97e09e591fc6).
## Cleaning up

View File

@ -65,7 +65,7 @@ Let's see how we can handle them safely.
### Route changes
When changing routing we should pay attention to make sure a route generated from the new version can be served by the old one and vice versa.
As you can see in [this page](#some-links-to-issues-and-mrs-were-broken), not doing it can lead to an outage.
[As you can see](#some-links-to-issues-and-mrs-were-broken), not doing it can lead to an outage.
This type of change may look like an immediate switch between the two implementations. However,
especially with the canary stage, there is an extended period of time where both version of the code
coexists in production.

View File

@ -219,8 +219,8 @@ demonstrates adding an instance-level endpoint for Conan to workhorse. You can a
implemented in the same file.
Once the route has been added, you must add an additional `/authorize` version of the upload endpoint to your API file.
[Here is an example](https://gitlab.com/gitlab-org/gitlab/blob/398fef1ca26ae2b2c3dc89750f6b20455a1e5507/ee/lib/api/maven_packages.rb#L164)
of the additional endpoint added for Maven. The `/authorize` endpoint verifies and authorizes the request from workhorse,
[This example](https://gitlab.com/gitlab-org/gitlab/blob/398fef1ca26ae2b2c3dc89750f6b20455a1e5507/ee/lib/api/maven_packages.rb#L164)
shows the additional endpoint added for Maven. The `/authorize` endpoint verifies and authorizes the request from workhorse,
then the normal upload endpoint is implemented below, consuming the metadata that workhorse provides in order to
create the package record. Workhorse provides a variety of file metadata such as type, size, and different checksum formats.

View File

@ -4,12 +4,12 @@ group: Ecosystem
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
---
# GitLab for Jira app **(FREE SAAS)**
# GitLab.com for Jira Cloud app **(FREE SAAS)**
You can integrate GitLab.com and Jira Cloud using the
[GitLab for Jira](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud)
app in the Atlassian Marketplace. The user configuring GitLab for Jira must have
[Maintainer](../../user/permissions.md) permissions in the GitLab namespace.
[GitLab.com for Jira Cloud](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud)
app in the Atlassian Marketplace. The user configuring GitLab.com for Jira Cloud must have
[Maintainer](../../user/permissions.md) permissions in the GitLab.com namespace.
This integration method supports [smart commits](dvcs.md#smart-commits).
@ -18,30 +18,30 @@ synchronized in real-time. The DVCS connector updates data only once per hour.
If you are not using both of these environments, use the [Jira DVCS Connector](dvcs.md) method.
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i>
For a walkthrough of the integration with GitLab for Jira, watch
[Configure GitLab Jira Integration using Marketplace App](https://youtu.be/SwR-g1s1zTo) on YouTube.
For a walkthrough of the integration with GitLab.com for Jira Cloud, watch
[Configure GitLab.com Jira Could Integration using Marketplace App](https://youtu.be/SwR-g1s1zTo) on YouTube.
1. Go to **Jira Settings > Apps > Find new apps**, then search for GitLab.
1. Click **GitLab for Jira**, then click **Get it now**, or go to the
1. Click **GitLab.com for Jira Cloud**, then click **Get it now**, or go to the
[App in the marketplace directly](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud).
![Install GitLab App on Jira](img/jira_dev_panel_setup_com_1.png)
![Install GitLab.com app on Jira Cloud](img/jira_dev_panel_setup_com_1.png)
1. After installing, click **Get started** to go to the configurations page.
This page is always available under **Jira Settings > Apps > Manage apps**.
![Start GitLab App configuration on Jira](img/jira_dev_panel_setup_com_2.png)
![Start GitLab.com app configuration on Jira Cloud](img/jira_dev_panel_setup_com_2.png)
1. If not already signed in to GitLab.com, you must sign in as a user with
[Maintainer](../../user/permissions.md) permissions to add namespaces.
![Sign in to GitLab.com in GitLab Jira App](img/jira_dev_panel_setup_com_3_v13_9.png)
![Sign in to GitLab.com in GitLab.com for Jira Cloud app](img/jira_dev_panel_setup_com_3_v13_9.png)
1. Select **Add namespace** to open the list of available namespaces.
1. Identify the namespace you want to link, and select **Link**.
![Link namespace in GitLab Jira App](img/jira_dev_panel_setup_com_4_v13_9.png)
![Link namespace in GitLab.com for Jira Cloud app](img/jira_dev_panel_setup_com_4_v13_9.png)
NOTE:
The GitLab user only needs access when adding a new namespace. For syncing with
The GitLab.com user only needs access when adding a new namespace. For syncing with
Jira, we do not depend on the user's token.
After a namespace is added:
@ -52,10 +52,10 @@ After a namespace is added:
Support for syncing past branch and commit data [is planned](https://gitlab.com/gitlab-org/gitlab/-/issues/263240).
## Install the GitLab Jira Cloud application for self-managed instances **(FREE SELF)**
## Install the GitLab.com for Jira Cloud application for self-managed instances **(FREE SELF)**
If your GitLab instance is self-managed, you must follow some
extra steps to install the GitLab Jira Cloud application.
extra steps to install the GitLab.com for Jira Cloud application.
Each Jira Cloud application must be installed from a single location. Jira fetches
a [manifest file](https://developer.atlassian.com/cloud/jira/platform/connect-app-descriptor/)
@ -91,7 +91,7 @@ from outside the Marketplace, which allows you to install the application:
1. Disable [development mode](https://developer.atlassian.com/cloud/jira/platform/getting-started-with-connect/#step-2--enable-development-mode) on your Jira instance.
The **GitLab for Jira** app now displays under **Manage apps**. You can also
The **GitLab.com for Jira Cloud** app now displays under **Manage apps**. You can also
click **Get started** to open the configuration page rendered from your GitLab instance.
NOTE:
@ -121,9 +121,9 @@ for details.
NOTE:
DVCS means distributed version control system.
## Troubleshooting GitLab for Jira
## Troubleshooting GitLab.com for Jira Cloud
The GitLab for Jira App uses an iframe to add namespaces on the settings page. Some browsers block cross-site cookies. This can lead to a message saying that the user needs to log in on GitLab.com even though the user is already logged in.
The GitLab.com for Jira Cloud app uses an iframe to add namespaces on the settings page. Some browsers block cross-site cookies. This can lead to a message saying that the user needs to log in on GitLab.com even though the user is already logged in.
> "You need to sign in or sign up before continuing."

View File

@ -52,7 +52,7 @@ self-managed GitLab) set up the integration to simplify administration.
| If you use Jira on: | GitLab.com customers need: | GitLab self-managed customers need: |
|-|-|-|
| [Atlassian cloud](https://www.atlassian.com/cloud) | The [GitLab.com for Jira Cloud](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud?hosting=cloud&tab=overview) application installed from the [Atlassian Marketplace](https://marketplace.atlassian.com). This offers real-time sync between GitLab and Jira. | The [GitLab.com for Jira Cloud](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud?hosting=cloud&tab=overview), using a workaround process. See the documentation for [installing the GitLab Jira Cloud application for self-managed instances](connect-app.md#install-the-gitlab-jira-cloud-application-for-self-managed-instances) for more information. |
| [Atlassian cloud](https://www.atlassian.com/cloud) | The [GitLab.com for Jira Cloud](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud?hosting=cloud&tab=overview) application installed from the [Atlassian Marketplace](https://marketplace.atlassian.com). This offers real-time sync between GitLab and Jira. | The [GitLab.com for Jira Cloud](https://marketplace.atlassian.com/apps/1221011/gitlab-com-for-jira-cloud?hosting=cloud&tab=overview), using a workaround process. See the documentation for [installing the GitLab Jira Cloud application for self-managed instances](connect-app.md#install-the-gitlabcom-for-jira-cloud-application-for-self-managed-instances) for more information. |
| Your own server | The Jira DVCS (distributed version control system) connector. This syncs data hourly. | The [Jira DVCS Connector](dvcs.md). |
Each GitLab project can be configured to connect to an entire Jira instance. That means one GitLab

View File

@ -31,7 +31,7 @@ Cloudwatch exporter retrieves and parses the specified Cloudwatch metrics, and
translates them into a Prometheus monitoring endpoint.
The only supported AWS resource is the Elastic Load Balancer, whose Cloudwatch
metrics are [documented here](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-cloudwatch-metrics.html).
metrics are listed in [this AWS documentation](https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-cloudwatch-metrics.html).
You can [download a sample Cloudwatch Exporter configuration file](../samples/cloudwatch.yml)
that's configured for basic AWS ELB monitoring.

Some files were not shown because too many files have changed in this diff Show More