Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
11df4bf91b
commit
fdc26e021b
|
|
@ -108,6 +108,8 @@ rules:
|
|||
message: 'Migrate to GlSkeletonLoader, or import GlDeprecatedSkeletonLoading.'
|
||||
# See https://gitlab.com/gitlab-org/gitlab/-/issues/360551
|
||||
vue/multi-word-component-names: off
|
||||
unicorn/prefer-dom-node-dataset:
|
||||
- error
|
||||
overrides:
|
||||
- files:
|
||||
- '{,ee/,jh/}spec/frontend*/**/*'
|
||||
|
|
|
|||
|
|
@ -1,25 +1,19 @@
|
|||
---
|
||||
Database/MultipleDatabases:
|
||||
Exclude:
|
||||
- 'config/application.rb'
|
||||
- 'config/initializers/active_record_data_types.rb'
|
||||
- 'config/initializers/active_record_force_reconnects.rb'
|
||||
- 'config/initializers/active_record_lifecycle.rb'
|
||||
- 'config/initializers/sidekiq.rb'
|
||||
- 'config/initializers/validate_database_config.rb'
|
||||
- 'db/post_migrate/20210317104032_set_iteration_cadence_automatic_to_false.rb'
|
||||
- 'db/post_migrate/20210811122206_update_external_project_bots.rb'
|
||||
- 'db/post_migrate/20210812013042_remove_duplicate_project_authorizations.rb'
|
||||
- 'ee/lib/tasks/geo.rake'
|
||||
- 'ee/spec/services/ee/merge_requests/update_service_spec.rb'
|
||||
- 'lib/backup/database.rb'
|
||||
- 'lib/backup/manager.rb'
|
||||
- lib/gitlab/background_migration/backfill_projects_with_coverage.rb
|
||||
- lib/gitlab/background_migration/copy_ci_builds_columns_to_security_scans.rb
|
||||
- 'lib/gitlab/background_migration/backfill_projects_with_coverage.rb'
|
||||
- 'lib/gitlab/background_migration/copy_ci_builds_columns_to_security_scans.rb'
|
||||
- 'lib/gitlab/database.rb'
|
||||
- 'lib/gitlab/database/load_balancing/load_balancer.rb'
|
||||
- 'lib/gitlab/database/migrations/observers/query_log.rb'
|
||||
- 'lib/tasks/dev.rake'
|
||||
- 'lib/tasks/gitlab/db/validate_config.rake'
|
||||
- 'spec/db/schema_spec.rb'
|
||||
- 'spec/initializers/database_config_spec.rb'
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ export function renderKroki(krokiImages) {
|
|||
|
||||
// A single Kroki image is processed multiple times for some reason,
|
||||
// so this condition ensures we only create one alert per Kroki image
|
||||
if (!parent.hasAttribute('data-kroki-processed')) {
|
||||
parent.setAttribute('data-kroki-processed', 'true');
|
||||
if (!Object.hasOwn(parent.dataset, 'krokiProcessed')) {
|
||||
parent.dataset.krokiProcessed = 'true';
|
||||
parent.after(createAlert(krokiImage));
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ class SafeMathRenderer {
|
|||
|
||||
try {
|
||||
displayContainer.innerHTML = this.katex.renderToString(text, {
|
||||
displayMode: el.getAttribute('data-math-style') === 'display',
|
||||
displayMode: el.dataset.mathStyle === 'display',
|
||||
throwOnError: true,
|
||||
maxSize: 20,
|
||||
maxExpand: 20,
|
||||
|
|
@ -143,7 +143,7 @@ class SafeMathRenderer {
|
|||
this.elements.forEach((el) => {
|
||||
const placeholder = document.createElement('span');
|
||||
placeholder.style.display = 'none';
|
||||
placeholder.setAttribute('data-math-style', el.getAttribute('data-math-style'));
|
||||
placeholder.dataset.mathStyle = el.dataset.mathStyle;
|
||||
placeholder.textContent = el.textContent;
|
||||
el.parentNode.replaceChild(placeholder, el);
|
||||
this.queue.push(placeholder);
|
||||
|
|
|
|||
|
|
@ -9,10 +9,11 @@ const updateLineNumbersOnBlobPermalinks = (linksToUpdate) => {
|
|||
|
||||
[].concat(Array.prototype.slice.call(linksToUpdate)).forEach((permalinkButton) => {
|
||||
const baseHref =
|
||||
permalinkButton.getAttribute('data-original-href') ||
|
||||
permalinkButton.dataset.originalHref ||
|
||||
(() => {
|
||||
const href = permalinkButton.getAttribute('href');
|
||||
permalinkButton.setAttribute('data-original-href', href);
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
permalinkButton.dataset.originalHref = href;
|
||||
return href;
|
||||
})();
|
||||
permalinkButton.setAttribute('href', `${baseHref}${hashUrlString}`);
|
||||
|
|
|
|||
|
|
@ -36,19 +36,19 @@ const loadRichBlobViewer = (type) => {
|
|||
|
||||
const loadViewer = (viewerParam) => {
|
||||
const viewer = viewerParam;
|
||||
const url = viewer.getAttribute('data-url');
|
||||
const { url } = viewer.dataset;
|
||||
|
||||
if (!url || viewer.getAttribute('data-loaded') || viewer.getAttribute('data-loading')) {
|
||||
if (!url || viewer.dataset.loaded || viewer.dataset.loading) {
|
||||
return Promise.resolve(viewer);
|
||||
}
|
||||
|
||||
viewer.setAttribute('data-loading', 'true');
|
||||
viewer.dataset.loading = 'true';
|
||||
|
||||
return axios.get(url).then(({ data }) => {
|
||||
viewer.innerHTML = data.html;
|
||||
|
||||
window.requestIdleCallback(() => {
|
||||
viewer.removeAttribute('data-loading');
|
||||
delete viewer.dataset.loading;
|
||||
});
|
||||
|
||||
return viewer;
|
||||
|
|
@ -108,7 +108,7 @@ export class BlobViewer {
|
|||
|
||||
switchToInitialViewer() {
|
||||
const initialViewer = this.$fileHolder[0].querySelector('.blob-viewer:not(.hidden)');
|
||||
let initialViewerName = initialViewer.getAttribute('data-type');
|
||||
let initialViewerName = initialViewer.dataset.type;
|
||||
|
||||
if (this.switcher && window.location.hash.indexOf('#L') === 0) {
|
||||
initialViewerName = 'simple';
|
||||
|
|
@ -138,12 +138,12 @@ export class BlobViewer {
|
|||
|
||||
e.preventDefault();
|
||||
|
||||
this.switchToViewer(target.getAttribute('data-viewer'));
|
||||
this.switchToViewer(target.dataset.viewer);
|
||||
}
|
||||
|
||||
toggleCopyButtonState() {
|
||||
if (!this.copySourceBtn) return;
|
||||
if (this.simpleViewer.getAttribute('data-loaded')) {
|
||||
if (this.simpleViewer.dataset.loaded) {
|
||||
this.copySourceBtnTooltip.setAttribute('title', __('Copy file contents'));
|
||||
this.copySourceBtn.classList.remove('disabled');
|
||||
} else if (this.activeViewer === this.simpleViewer) {
|
||||
|
|
@ -199,7 +199,8 @@ export class BlobViewer {
|
|||
this.$fileHolder.trigger('highlight:line');
|
||||
handleLocationHash();
|
||||
|
||||
viewer.setAttribute('data-loaded', 'true');
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
viewer.dataset.loaded = 'true';
|
||||
this.toggleCopyButtonState();
|
||||
eventHub.$emit('showBlobInteractionZones', viewer.dataset.path);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ export const addTooltipToEl = (el) => {
|
|||
|
||||
if (textEl && textEl.scrollWidth > textEl.offsetWidth) {
|
||||
el.setAttribute('title', el.textContent);
|
||||
el.setAttribute('data-container', 'body');
|
||||
el.dataset.container = 'body';
|
||||
el.classList.add('has-tooltip');
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ export const addInteractionClass = ({ path, d, wrapTextNodes }) => {
|
|||
});
|
||||
|
||||
if (el && !isTextNode(el)) {
|
||||
el.setAttribute('data-char-index', d.start_char);
|
||||
el.setAttribute('data-line-index', d.start_line);
|
||||
el.dataset.charIndex = d.start_char;
|
||||
el.dataset.lineIndex = d.start_line;
|
||||
el.classList.add('cursor-pointer', 'code-navigation', 'js-code-navigation');
|
||||
el.closest('.line').classList.add('code-navigation-line');
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,10 +107,10 @@ function createLink(data, selected, options, index) {
|
|||
}
|
||||
|
||||
if (options.trackSuggestionClickedLabel) {
|
||||
link.setAttribute('data-track-action', 'click_text');
|
||||
link.setAttribute('data-track-label', options.trackSuggestionClickedLabel);
|
||||
link.setAttribute('data-track-value', index);
|
||||
link.setAttribute('data-track-property', slugify(data.category || 'no-category'));
|
||||
link.dataset.trackAction = 'click_text';
|
||||
link.dataset.trackLabel = options.trackSuggestionClickedLabel;
|
||||
link.dataset.trackValue = index;
|
||||
link.dataset.trackProperty = slugify(data.category || 'no-category');
|
||||
}
|
||||
|
||||
link.classList.toggle('is-active', selected);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ export default class Diff {
|
|||
FilesCommentButton.init($diffFile);
|
||||
|
||||
const firstFile = $('.files').first().get(0);
|
||||
const canCreateNote = firstFile && firstFile.hasAttribute('data-can-create-note');
|
||||
const canCreateNote = firstFile && Object.hasOwn(firstFile.dataset, 'canCreateNote');
|
||||
$diffFile.each((index, file) => initImageDiffHelper.initImageDiff(file, canCreateNote));
|
||||
|
||||
if (!isBound) {
|
||||
|
|
|
|||
|
|
@ -197,10 +197,10 @@ export default class AvailableDropdownMappings {
|
|||
}
|
||||
|
||||
getGroupId() {
|
||||
return this.filteredSearchInput.getAttribute('data-group-id') || '';
|
||||
return this.filteredSearchInput.dataset.groupId || '';
|
||||
}
|
||||
|
||||
getProjectId() {
|
||||
return this.filteredSearchInput.getAttribute('data-project-id') || '';
|
||||
return this.filteredSearchInput.dataset.projectId || '';
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,9 @@ export default class DropdownHint extends FilteredSearchDropdown {
|
|||
const { selected } = e.detail;
|
||||
|
||||
if (selected.tagName === 'LI') {
|
||||
if (selected.hasAttribute('data-value')) {
|
||||
if (Object.hasOwn(selected.dataset, 'value')) {
|
||||
this.dismissDropdown();
|
||||
} else if (selected.getAttribute('data-action') === 'submit') {
|
||||
} else if (selected.dataset.action === 'submit') {
|
||||
this.dismissDropdown();
|
||||
this.dispatchFormSubmitEvent();
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ export default class DropdownOperator extends FilteredSearchDropdown {
|
|||
const { selected } = e.detail;
|
||||
|
||||
if (selected.tagName === 'LI') {
|
||||
if (selected.hasAttribute('data-value')) {
|
||||
if (Object.hasOwn(selected.dataset, 'value')) {
|
||||
const name = FilteredSearchVisualTokens.getLastTokenPartial();
|
||||
const operator = selected.dataset.value;
|
||||
|
||||
|
|
|
|||
|
|
@ -31,11 +31,11 @@ export default class DropdownUser extends DropdownAjaxFilter {
|
|||
}
|
||||
|
||||
getGroupId() {
|
||||
return this.input.getAttribute('data-group-id');
|
||||
return this.input.dataset.groupId;
|
||||
}
|
||||
|
||||
getProjectId() {
|
||||
return this.input.getAttribute('data-project-id');
|
||||
return this.input.dataset.projectId;
|
||||
}
|
||||
|
||||
projectOrGroupId() {
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ export default class DropdownUtils {
|
|||
}
|
||||
|
||||
static setDataValueIfSelected(filter, operator, selected) {
|
||||
// eslint-disable-next-line unicorn/prefer-dom-node-dataset
|
||||
const dataValue = selected.getAttribute('data-value');
|
||||
|
||||
if (dataValue) {
|
||||
|
|
@ -96,6 +97,7 @@ export default class DropdownUtils {
|
|||
tokenValue: dataValue,
|
||||
clicked: true,
|
||||
options: {
|
||||
// eslint-disable-next-line unicorn/prefer-dom-node-dataset
|
||||
capitalizeTokenValue: selected.hasAttribute('data-capitalize'),
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -165,8 +165,8 @@ class DropDown {
|
|||
images.forEach((image) => {
|
||||
const img = image;
|
||||
|
||||
img.src = img.getAttribute('data-src');
|
||||
img.removeAttribute('data-src');
|
||||
img.src = img.dataset.src;
|
||||
delete img.dataset.src;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -814,7 +814,7 @@ export default class FilteredSearchManager {
|
|||
getUsernameParams() {
|
||||
const usernamesById = {};
|
||||
try {
|
||||
const attribute = this.filteredSearchInput.getAttribute('data-username-params');
|
||||
const attribute = this.filteredSearchInput.dataset.usernameParams;
|
||||
JSON.parse(attribute).forEach((user) => {
|
||||
usernamesById[user.id] = user.username;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ export function setPositionDataAttribute(el, options) {
|
|||
|
||||
const positionObject = { ...JSON.parse(position), x, y, width, height };
|
||||
|
||||
el.setAttribute('data-position', JSON.stringify(positionObject));
|
||||
el.dataset.position = JSON.stringify(positionObject);
|
||||
}
|
||||
|
||||
export function updateDiscussionAvatarBadgeNumber(discussionEl, newBadgeNumber) {
|
||||
|
|
|
|||
|
|
@ -81,10 +81,7 @@ export default class CreateMergeRequestDropdown {
|
|||
this.init();
|
||||
|
||||
if (isConfidentialIssue()) {
|
||||
this.createMergeRequestButton.setAttribute(
|
||||
'data-dropdown-trigger',
|
||||
'#create-merge-request-dropdown',
|
||||
);
|
||||
this.createMergeRequestButton.dataset.dropdownTrigger = '#create-merge-request-dropdown';
|
||||
initConfidentialMergeRequest();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ export default {
|
|||
},
|
||||
setActiveTask(el) {
|
||||
const { parentElement } = el;
|
||||
const lineNumbers = parentElement.getAttribute('data-sourcepos').match(/\b\d+(?=:)/g);
|
||||
const lineNumbers = parentElement.dataset.sourcepos.match(/\b\d+(?=:)/g);
|
||||
this.activeTask = {
|
||||
title: parentElement.innerText,
|
||||
lineNumberStart: lineNumbers[0],
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ export default class LazyLoader {
|
|||
|
||||
// Loading Images which are in the current viewport or close to them
|
||||
this.lazyImages = this.lazyImages.filter((selectedImage) => {
|
||||
if (selectedImage.getAttribute('data-src')) {
|
||||
if (selectedImage.dataset.src) {
|
||||
const imgBoundRect = selectedImage.getBoundingClientRect();
|
||||
const imgTop = scrollTop + imgBoundRect.top;
|
||||
const imgBound = imgTop + imgBoundRect.height;
|
||||
|
|
@ -156,16 +156,17 @@ export default class LazyLoader {
|
|||
}
|
||||
|
||||
static loadImage(img) {
|
||||
if (img.getAttribute('data-src')) {
|
||||
if (img.dataset.src) {
|
||||
img.setAttribute('loading', 'lazy');
|
||||
let imgUrl = img.getAttribute('data-src');
|
||||
let imgUrl = img.dataset.src;
|
||||
// Only adding width + height for avatars for now
|
||||
if (imgUrl.indexOf('/avatar/') > -1 && imgUrl.indexOf('?') === -1) {
|
||||
const targetWidth = img.getAttribute('width') || img.width;
|
||||
imgUrl += `?width=${targetWidth}`;
|
||||
}
|
||||
img.setAttribute('src', imgUrl);
|
||||
img.removeAttribute('data-src');
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
delete img.dataset.src;
|
||||
img.classList.remove('lazy');
|
||||
img.classList.add('js-lazy-loaded');
|
||||
img.classList.add('qa-js-lazy-loaded');
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ export function confirmAction(
|
|||
export function confirmViaGlModal(message, element) {
|
||||
const primaryBtnConfig = {};
|
||||
|
||||
const confirmBtnVariant = element.getAttribute('data-confirm-btn-variant');
|
||||
const { confirmBtnVariant } = element.dataset;
|
||||
|
||||
if (confirmBtnVariant) {
|
||||
primaryBtnConfig.primaryBtnVariant = confirmBtnVariant;
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ export default {
|
|||
const dropdownToggle = this.$refs.glDropdown.$el.querySelector('.dropdown-toggle');
|
||||
|
||||
if (dropdownToggle) {
|
||||
dropdownToggle.setAttribute('data-qa-selector', 'access_level_dropdown');
|
||||
dropdownToggle.dataset.qaSelector = 'access_level_dropdown';
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
|||
|
|
@ -3,9 +3,14 @@ import { trackNewRegistrations } from '~/google_tag_manager';
|
|||
import NoEmojiValidator from '~/emoji/no_emoji_validator';
|
||||
import LengthValidator from '~/pages/sessions/new/length_validator';
|
||||
import UsernameValidator from '~/pages/sessions/new/username_validator';
|
||||
import Tracking from '~/tracking';
|
||||
|
||||
new UsernameValidator(); // eslint-disable-line no-new
|
||||
new LengthValidator(); // eslint-disable-line no-new
|
||||
new NoEmojiValidator(); // eslint-disable-line no-new
|
||||
|
||||
trackNewRegistrations();
|
||||
|
||||
Tracking.enableFormTracking({
|
||||
forms: { allow: ['new_user'] },
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
function onSidebarLinkClick() {
|
||||
const setDataTrackAction = (element, action) => {
|
||||
element.setAttribute('data-track-action', action);
|
||||
element.dataset.trackAction = action;
|
||||
};
|
||||
|
||||
const setDataTrackExtra = (element, value) => {
|
||||
|
|
@ -12,10 +12,10 @@ function onSidebarLinkClick() {
|
|||
? SIDEBAR_COLLAPSED
|
||||
: SIDEBAR_EXPANDED;
|
||||
|
||||
element.setAttribute(
|
||||
'data-track-extra',
|
||||
JSON.stringify({ sidebar_display: sidebarCollapsed, menu_display: value }),
|
||||
);
|
||||
element.dataset.trackExtra = JSON.stringify({
|
||||
sidebar_display: sidebarCollapsed,
|
||||
menu_display: value,
|
||||
});
|
||||
};
|
||||
|
||||
const EXPANDED = 'Expanded';
|
||||
|
|
|
|||
|
|
@ -298,7 +298,7 @@ export default class ActivityCalendar {
|
|||
.querySelector(this.activitiesContainer)
|
||||
.querySelectorAll('.js-localtime')
|
||||
.forEach((el) => {
|
||||
el.setAttribute('title', formatDate(el.getAttribute('data-datetime')));
|
||||
el.setAttribute('title', formatDate(el.dataset.datetime));
|
||||
});
|
||||
})
|
||||
.catch(() =>
|
||||
|
|
|
|||
|
|
@ -47,6 +47,12 @@ export default {
|
|||
downstreamPipelines() {
|
||||
return this.linkedPipelines?.downstream?.nodes || [];
|
||||
},
|
||||
hasDownstreamPipelines() {
|
||||
return this.downstreamPipelines.length > 0;
|
||||
},
|
||||
hasPipelineStages() {
|
||||
return this.pipelineStages.length > 0;
|
||||
},
|
||||
pipelinePath() {
|
||||
return this.pipeline.detailedStatus?.detailsPath || '';
|
||||
},
|
||||
|
|
@ -73,9 +79,6 @@ export default {
|
|||
};
|
||||
});
|
||||
},
|
||||
showDownstreamPipelines() {
|
||||
return this.downstreamPipelines.length > 0;
|
||||
},
|
||||
upstreamPipeline() {
|
||||
return this.linkedPipelines?.upstream;
|
||||
},
|
||||
|
|
@ -84,7 +87,10 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="pipelineStages.length > 0" class="stage-cell gl-mr-5">
|
||||
<div
|
||||
v-if="hasPipelineStages"
|
||||
class="gl-align-items-center gl-display-inline-flex gl-flex-wrap stage-cell gl-mr-5"
|
||||
>
|
||||
<linked-pipelines-mini-list
|
||||
v-if="upstreamPipeline"
|
||||
:triggered-by="/* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ [
|
||||
|
|
@ -92,9 +98,9 @@ export default {
|
|||
] /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */"
|
||||
data-testid="pipeline-editor-mini-graph-upstream"
|
||||
/>
|
||||
<pipeline-mini-graph class="gl-display-inline" :stages="pipelineStages" />
|
||||
<pipeline-mini-graph :stages="pipelineStages" />
|
||||
<linked-pipelines-mini-list
|
||||
v-if="showDownstreamPipelines"
|
||||
v-if="hasDownstreamPipelines"
|
||||
:triggered="downstreamPipelines"
|
||||
:pipeline-path="pipelinePath"
|
||||
data-testid="pipeline-editor-mini-graph-downstream"
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<div data-testid="pipeline-mini-graph">
|
||||
<div data-testid="pipeline-mini-graph" class="gl-display-inline-flex gl-flex-wrap gl-my-1">
|
||||
<div
|
||||
v-for="stage in stages"
|
||||
:key="stage.name"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,8 @@
|
|||
* 4. Commit widget
|
||||
*/
|
||||
|
||||
import { GlDropdown, GlLoadingIcon, GlTooltipDirective, GlIcon } from '@gitlab/ui';
|
||||
import { GlDropdown, GlLoadingIcon, GlTooltipDirective } from '@gitlab/ui';
|
||||
import CiIcon from '~/vue_shared/components/ci_icon.vue';
|
||||
import createFlash from '~/flash';
|
||||
import axios from '~/lib/utils/axios_utils';
|
||||
import { __, sprintf } from '~/locale';
|
||||
|
|
@ -21,7 +22,7 @@ import JobItem from './job_item.vue';
|
|||
|
||||
export default {
|
||||
components: {
|
||||
GlIcon,
|
||||
CiIcon,
|
||||
GlLoadingIcon,
|
||||
GlDropdown,
|
||||
JobItem,
|
||||
|
|
@ -51,14 +52,6 @@ export default {
|
|||
dropdownContent: [],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
triggerButtonClass() {
|
||||
return `ci-status-icon-${this.stage.status.group}`;
|
||||
},
|
||||
borderlessIcon() {
|
||||
return `${this.stage.status.icon}_borderless`;
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
updateDropdown() {
|
||||
if (this.updateDropdown && this.isDropdownOpen() && !this.isLoading) {
|
||||
|
|
@ -117,14 +110,18 @@ export default {
|
|||
:popper-opts="/* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ {
|
||||
placement: 'bottom',
|
||||
} /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */"
|
||||
:toggle-class="['mini-pipeline-graph-dropdown-toggle', triggerButtonClass]"
|
||||
:toggle-class="['gl-rounded-full!']"
|
||||
menu-class="mini-pipeline-graph-dropdown-menu"
|
||||
@show="onShowDropdown"
|
||||
>
|
||||
<template #button-content>
|
||||
<span class="gl-pointer-events-none">
|
||||
<gl-icon :name="borderlessIcon" />
|
||||
</span>
|
||||
<ci-icon
|
||||
is-interactive
|
||||
css-classes="gl-rounded-full"
|
||||
:size="24"
|
||||
:status="stage.status"
|
||||
class="gl-align-items-center gl-display-inline-flex"
|
||||
/>
|
||||
</template>
|
||||
<gl-loading-icon v-if="isLoading" size="sm" />
|
||||
<ul
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ export default {
|
|||
</template>
|
||||
|
||||
<template #cell(stages)="{ item }">
|
||||
<div class="stage-cell">
|
||||
<div class="gl-align-items-center gl-display-inline-flex gl-flex-wrap stage-cell">
|
||||
<!-- This empty div should be removed, see https://gitlab.com/gitlab-org/gitlab/-/issues/323488 -->
|
||||
<div></div>
|
||||
<linked-pipelines-mini-list
|
||||
|
|
@ -181,7 +181,6 @@ export default {
|
|||
/>
|
||||
<pipeline-mini-graph
|
||||
v-if="item.details && item.details.stages && item.details.stages.length > 0"
|
||||
class="gl-display-inline"
|
||||
:stages="item.details.stages"
|
||||
:update-dropdown="updateGraphDropdown"
|
||||
@pipelineActionRequestComplete="onPipelineActionRequestComplete"
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ export default {
|
|||
<template>
|
||||
<div>
|
||||
<gl-loading-icon v-if="$apollo.queries.pipeline.loading" />
|
||||
<div v-else>
|
||||
<div v-else class="gl-align-items-center gl-display-flex">
|
||||
<linked-pipelines-mini-list
|
||||
v-if="upstreamPipeline"
|
||||
:triggered-by="/* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ [
|
||||
|
|
@ -132,11 +132,7 @@ export default {
|
|||
data-testid="commit-box-mini-graph-upstream"
|
||||
/>
|
||||
|
||||
<pipeline-mini-graph
|
||||
:stages="formattedStages"
|
||||
class="gl-display-inline"
|
||||
data-testid="commit-box-mini-graph"
|
||||
/>
|
||||
<pipeline-mini-graph :stages="formattedStages" data-testid="commit-box-mini-graph" />
|
||||
|
||||
<linked-pipelines-mini-list
|
||||
v-if="hasDownstream"
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ export default {
|
|||
|
||||
if (authorParam) {
|
||||
commitsSearchInput.setAttribute('disabled', true);
|
||||
commitsSearchInput.setAttribute('data-toggle', 'tooltip');
|
||||
commitsSearchInput.dataset.toggle = 'tooltip';
|
||||
commitsSearchInput.setAttribute('title', tooltipMessage);
|
||||
this.currentAuthor = authorParam;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ function mountAssigneesComponentDeprecated(mediator) {
|
|||
issuableIid: String(iid),
|
||||
projectPath: fullPath,
|
||||
field: el.dataset.field,
|
||||
signedIn: el.hasAttribute('data-signed-in'),
|
||||
signedIn: Object.hasOwn(el.dataset, 'signedIn'),
|
||||
issuableType:
|
||||
isInIssuePage() || isInIncidentPage() || isInDesignPage()
|
||||
? IssuableType.Issue
|
||||
|
|
@ -149,7 +149,7 @@ function mountAssigneesComponent() {
|
|||
},
|
||||
provide: {
|
||||
canUpdate: editable,
|
||||
directlyInviteMembers: el.hasAttribute('data-directly-invite-members'),
|
||||
directlyInviteMembers: Object.hasOwn(el.dataset, 'directlyInviteMembers'),
|
||||
},
|
||||
render: (createElement) =>
|
||||
createElement('sidebar-assignees-widget', {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ export default () => {
|
|||
props: {
|
||||
emptyStateImage,
|
||||
projectPath,
|
||||
terraformAdmin: el.hasAttribute('data-terraform-admin'),
|
||||
terraformAdmin: Object.hasOwn(el.dataset, 'terraformAdmin'),
|
||||
},
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -276,12 +276,11 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span class="mr-widget-pipeline-graph">
|
||||
<span class="stage-cell">
|
||||
<span class="gl-align-items-center gl-display-inline-flex mr-widget-pipeline-graph">
|
||||
<span class="gl-align-items-center gl-display-inline-flex gl-flex-wrap stage-cell">
|
||||
<linked-pipelines-mini-list v-if="triggeredBy.length" :triggered-by="triggeredBy" />
|
||||
<pipeline-mini-graph
|
||||
v-if="hasStages"
|
||||
class="gl-display-inline-block"
|
||||
stages-class="mr-widget-pipeline-stages"
|
||||
:stages="pipeline.details.stages"
|
||||
:is-merge-train="isMergeTrain"
|
||||
|
|
|
|||
|
|
@ -11,17 +11,22 @@ import { GlIcon } from '@gitlab/ui';
|
|||
* }
|
||||
*
|
||||
* Used in:
|
||||
* - Pipelines table Badge
|
||||
* - Pipelines table mini graph
|
||||
* - Pipeline graph
|
||||
* - Pipeline show view badge
|
||||
* - Jobs table
|
||||
* - Extended MR Popover
|
||||
* - Jobs show view header
|
||||
* - Jobs show view sidebar
|
||||
* - Jobs table
|
||||
* - Linked pipelines
|
||||
* - Extended MR Popover
|
||||
* - Pipeline graph
|
||||
* - Pipeline mini graph
|
||||
* - Pipeline show view badge
|
||||
* - Pipelines table Badge
|
||||
*/
|
||||
const validSizes = [8, 12, 16, 18, 24, 32, 48, 72];
|
||||
|
||||
/*
|
||||
* These sizes are defined in gitlab-ui/src/scss/variables.scss
|
||||
* under '$gl-icon-sizes'
|
||||
*/
|
||||
const validSizes = [8, 12, 14, 16, 24, 32, 48, 72];
|
||||
|
||||
export default {
|
||||
components: {
|
||||
|
|
@ -45,6 +50,11 @@ export default {
|
|||
required: false,
|
||||
default: false,
|
||||
},
|
||||
isInteractive: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
cssClasses: {
|
||||
type: String,
|
||||
required: false,
|
||||
|
|
@ -52,9 +62,9 @@ export default {
|
|||
},
|
||||
},
|
||||
computed: {
|
||||
cssClass() {
|
||||
wrapperStyleClasses() {
|
||||
const status = this.status.group;
|
||||
return `ci-status-icon ci-status-icon-${status} js-ci-status-icon-${status}`;
|
||||
return `ci-status-icon ci-status-icon-${status} js-ci-status-icon-${status} gl-rounded-full gl-justify-content-center`;
|
||||
},
|
||||
icon() {
|
||||
return this.borderless ? `${this.status.icon}_borderless` : this.status.icon;
|
||||
|
|
@ -63,7 +73,10 @@ export default {
|
|||
};
|
||||
</script>
|
||||
<template>
|
||||
<span :class="cssClass">
|
||||
<span
|
||||
:class="[wrapperStyleClasses, { interactive: isInteractive }]"
|
||||
:style="{ height: `${size}px`, width: `${size}px` }"
|
||||
>
|
||||
<gl-icon :name="icon" :size="size" :class="cssClasses" :aria-label="status.icon" />
|
||||
</span>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ export default {
|
|||
this.fetchFreshItems();
|
||||
|
||||
const body = document.querySelector('body');
|
||||
const namespaceId = body.getAttribute('data-namespace-id');
|
||||
const { namespaceId } = body.dataset;
|
||||
|
||||
this.track('click_whats_new_drawer', { label: 'namespace_id', value: namespaceId });
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
export const STORAGE_KEY = 'display-whats-new-notification';
|
||||
|
||||
export const getVersionDigest = (appEl) => appEl.getAttribute('data-version-digest');
|
||||
export const getVersionDigest = (appEl) => appEl.dataset.versionDigest;
|
||||
|
||||
export const setNotification = (appEl) => {
|
||||
const versionDigest = getVersionDigest(appEl);
|
||||
|
|
|
|||
|
|
@ -118,7 +118,14 @@ input[type='file'] {
|
|||
margin-bottom: 16px;
|
||||
|
||||
.well-segment {
|
||||
padding: 16px;
|
||||
padding: 1rem;
|
||||
|
||||
&.pipeline-info {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
&:not(:last-of-type) {
|
||||
border-bottom: 1px solid $well-inner-border;
|
||||
|
|
|
|||
|
|
@ -3,6 +3,17 @@
|
|||
svg {
|
||||
fill: $green-500;
|
||||
}
|
||||
|
||||
&.interactive {
|
||||
&:hover {
|
||||
background: $green-500;
|
||||
|
||||
svg {
|
||||
--svg-status-bg: #{$green-100};
|
||||
box-shadow: 0 0 0 1px $green-500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ci-status-icon-error,
|
||||
|
|
@ -10,6 +21,17 @@
|
|||
svg {
|
||||
fill: $red-500;
|
||||
}
|
||||
|
||||
&.interactive {
|
||||
&:hover {
|
||||
background: $red-500;
|
||||
|
||||
svg {
|
||||
--svg-status-bg: #{$red-100};
|
||||
box-shadow: 0 0 0 1px $red-500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ci-status-icon-pending,
|
||||
|
|
@ -19,11 +41,33 @@
|
|||
svg {
|
||||
fill: $orange-500;
|
||||
}
|
||||
|
||||
&.interactive {
|
||||
&:hover {
|
||||
background: $orange-500;
|
||||
|
||||
svg {
|
||||
--svg-status-bg: #{$orange-100};
|
||||
box-shadow: 0 0 0 1px $orange-500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.ci-status-icon-running {
|
||||
svg {
|
||||
fill: $blue-400;
|
||||
fill: $blue-500;
|
||||
}
|
||||
|
||||
&.interactive {
|
||||
&:hover {
|
||||
background: $blue-500;
|
||||
|
||||
svg {
|
||||
--svg-status-bg: #{$blue-100};
|
||||
box-shadow: 0 0 0 1px $blue-500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +76,18 @@
|
|||
.ci-status-icon-scheduled,
|
||||
.ci-status-icon-manual {
|
||||
svg {
|
||||
fill: $gl-text-color;
|
||||
fill: $gray-900;
|
||||
}
|
||||
|
||||
&.interactive {
|
||||
&:hover {
|
||||
background: $gray-900;
|
||||
|
||||
svg {
|
||||
--svg-status-bg: #{$gray-100};
|
||||
box-shadow: 0 0 0 1px $gray-900;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -42,7 +97,18 @@
|
|||
.ci-status-icon-skipped,
|
||||
.ci-status-icon-notfound {
|
||||
svg {
|
||||
fill: var(--gray-400, $gray-400);
|
||||
fill: $gray-500;
|
||||
}
|
||||
|
||||
&.interactive {
|
||||
&:hover {
|
||||
background: $gray-500;
|
||||
|
||||
svg {
|
||||
--svg-status-bg: #{$gray-100};
|
||||
box-shadow: 0 0 0 1px $gray-500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
.icon-container {
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
margin: 0 0.5rem 0 0.25rem;
|
||||
|
||||
svg {
|
||||
position: relative;
|
||||
|
|
|
|||
|
|
@ -13,105 +13,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
@mixin mini-pipeline-graph-color(
|
||||
$color-background-default,
|
||||
$color-background-hover-focus,
|
||||
$color-background-active,
|
||||
$color-foreground-default,
|
||||
$color-foreground-hover-focus,
|
||||
$color-foreground-active
|
||||
) {
|
||||
background-color: $color-background-default;
|
||||
border-color: $color-foreground-default;
|
||||
|
||||
svg {
|
||||
fill: $color-foreground-default;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: $color-background-hover-focus;
|
||||
border-color: $color-foreground-hover-focus;
|
||||
|
||||
svg {
|
||||
fill: $color-foreground-hover-focus;
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: $color-background-active;
|
||||
border-color: $color-foreground-active;
|
||||
|
||||
svg {
|
||||
fill: $color-foreground-active;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
box-shadow: 0 0 4px 1px $blue-300;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin mini-pipeline-item() {
|
||||
border-radius: 100px;
|
||||
background-color: var(--white, $white);
|
||||
border-width: 1px;
|
||||
border-style: solid;
|
||||
width: $ci-action-icon-size;
|
||||
height: $ci-action-icon-size;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-width: 2px;
|
||||
}
|
||||
|
||||
// Dropdown button animation in mini pipeline graph
|
||||
&.ci-status-icon-success {
|
||||
@include mini-pipeline-graph-color(var(--white, $white), $green-100, $green-200, $green-500, $green-600, $green-700);
|
||||
}
|
||||
|
||||
&.ci-status-icon-failed {
|
||||
@include mini-pipeline-graph-color(var(--white, $white), $red-100, $red-200, $red-500, $red-600, $red-700);
|
||||
}
|
||||
|
||||
&.ci-status-icon-pending,
|
||||
&.ci-status-icon-waiting-for-resource,
|
||||
&.ci-status-icon-success-with-warnings {
|
||||
@include mini-pipeline-graph-color(var(--white, $white), $orange-50, $orange-100, $orange-500, $orange-600, $orange-700);
|
||||
}
|
||||
|
||||
&.ci-status-icon-running {
|
||||
@include mini-pipeline-graph-color(var(--white, $white), $blue-100, $blue-200, $blue-500, $blue-600, $blue-700);
|
||||
}
|
||||
|
||||
&.ci-status-icon-canceled,
|
||||
&.ci-status-icon-scheduled,
|
||||
&.ci-status-icon-disabled,
|
||||
&.ci-status-icon-manual {
|
||||
@include mini-pipeline-graph-color(
|
||||
var(--white, $white),
|
||||
var(--gray-500, $gray-500),
|
||||
var(--gray-700, $gray-700),
|
||||
var(--gray-900, $gray-900),
|
||||
var(--gray-950, $gray-950),
|
||||
var(--black, $black)
|
||||
);
|
||||
}
|
||||
|
||||
&.ci-status-icon-preparing,
|
||||
&.ci-status-icon-created,
|
||||
&.ci-status-icon-not-found,
|
||||
&.ci-status-icon-skipped {
|
||||
@include mini-pipeline-graph-color(var(--white, $white), var(--gray-100, $gray-100), var(--gray-200, $gray-200), var(--gray-400, $gray-400), var(--gray-500, $gray-500), var(--gray-600, $gray-600));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Action icons inside dropdowns:
|
||||
- mini graph in pipelines table
|
||||
|
|
|
|||
|
|
@ -121,10 +121,6 @@ $tabs-holder-z-index: 250;
|
|||
@include media-breakpoint-down(sm) {
|
||||
flex-direction: column;
|
||||
|
||||
.stage-cell .stage-container {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.dropdown .mini-pipeline-graph-dropdown-menu.dropdown-menu {
|
||||
transform: initial;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,36 +73,12 @@
|
|||
// Mini Pipelines
|
||||
|
||||
.stage-cell {
|
||||
.mini-pipeline-graph-dropdown-toggle {
|
||||
svg {
|
||||
height: $ci-action-icon-size;
|
||||
width: $ci-action-icon-size;
|
||||
position: absolute;
|
||||
top: -1px;
|
||||
left: -1px;
|
||||
z-index: 2;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:active,
|
||||
&:focus {
|
||||
svg {
|
||||
top: -2px;
|
||||
left: -2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.stage-container {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
height: $ci-action-icon-size;
|
||||
margin: 3px 0;
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
|
||||
+ .stage-container {
|
||||
margin-left: 6px;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
// Hack to show a button tooltip inline
|
||||
|
|
@ -118,44 +94,15 @@
|
|||
&:not(:last-child) {
|
||||
&::after {
|
||||
content: '';
|
||||
width: 7px;
|
||||
width: 4px;
|
||||
position: absolute;
|
||||
right: -7px;
|
||||
top: 11px;
|
||||
border-bottom: 2px solid var(--border-color, $border-color);
|
||||
}
|
||||
}
|
||||
|
||||
//delete when all pipelines are updated to new size
|
||||
&.mr-widget-pipeline-stages {
|
||||
+ .stage-container {
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
&::after {
|
||||
width: 4px;
|
||||
right: -4px;
|
||||
top: 11px;
|
||||
}
|
||||
right: -4px;
|
||||
border-bottom: 2px solid $gray-200;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Commit mini pipeline (HAML)
|
||||
button.mini-pipeline-graph-dropdown-toggle,
|
||||
// GlDropdown mini pipeline (Vue)
|
||||
// As the `mini-pipeline-item` mixin specificity is lower
|
||||
// than the toggle of dropdown with 'variant="link"' we add
|
||||
// classes ".gl-button.btn-link" to make it more specific
|
||||
// and avoid having the size overriden
|
||||
//
|
||||
// See https://gitlab.com/gitlab-org/gitlab/-/issues/320737
|
||||
button.gl-button.btn-link.mini-pipeline-graph-dropdown-toggle {
|
||||
@include mini-pipeline-item();
|
||||
}
|
||||
|
||||
// Action icons inside dropdowns:
|
||||
// mini graph in pipelines table
|
||||
// mini graph in MR widget pipeline
|
||||
|
|
|
|||
|
|
@ -35,9 +35,6 @@
|
|||
}
|
||||
|
||||
.mr-widget-pipeline-graph {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
.dropdown-menu {
|
||||
margin-top: 11px;
|
||||
}
|
||||
|
|
@ -45,8 +42,6 @@
|
|||
}
|
||||
|
||||
.branch-info .commit-icon {
|
||||
margin-right: 8px;
|
||||
|
||||
svg {
|
||||
top: 3px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,46 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ErrorTracking
|
||||
class ErrorsFinder
|
||||
def initialize(current_user, project, params)
|
||||
@current_user = current_user
|
||||
@project = project
|
||||
@params = params
|
||||
end
|
||||
|
||||
def execute
|
||||
return ErrorTracking::Error.none unless authorized?
|
||||
|
||||
collection = project.error_tracking_errors
|
||||
collection = by_status(collection)
|
||||
collection = sort(collection)
|
||||
|
||||
collection.keyset_paginate(cursor: params[:cursor], per_page: limit)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :current_user, :project, :params
|
||||
|
||||
def by_status(collection)
|
||||
if params[:status].present? && ErrorTracking::Error.statuses.key?(params[:status])
|
||||
collection.for_status(params[:status])
|
||||
else
|
||||
collection
|
||||
end
|
||||
end
|
||||
|
||||
def authorized?
|
||||
Ability.allowed?(current_user, :read_sentry_issue, project)
|
||||
end
|
||||
|
||||
def sort(collection)
|
||||
params[:sort] ? collection.sort_by_attribute(params[:sort]) : collection.order_id_desc
|
||||
end
|
||||
|
||||
def limit
|
||||
# Restrict the maximum limit at 100 records.
|
||||
[(params[:limit] || 20).to_i, 100].min
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -36,13 +36,8 @@ module Types
|
|||
description: "Runner that has not contacted this instance within the last #{::Ci::Runner::STALE_TIMEOUT.inspect}. Only available if legacyMode is null. Will be a possible return value starting in 15.0.",
|
||||
value: :stale
|
||||
|
||||
value 'NOT_CONNECTED',
|
||||
description: 'Runner that has never contacted this instance.',
|
||||
deprecated: { reason: "Use NEVER_CONTACTED instead. NEVER_CONTACTED will have a slightly different scope starting in 15.0, with STALE being returned instead after #{::Ci::Runner::STALE_TIMEOUT.inspect} of no contact", milestone: '14.6' },
|
||||
value: :not_connected
|
||||
|
||||
value 'NEVER_CONTACTED',
|
||||
description: 'Runner that has never contacted this instance. Set legacyMode to null to utilize this value. Will replace NOT_CONNECTED starting in 15.0.',
|
||||
description: 'Runner that has never contacted this instance.',
|
||||
value: :never_contacted
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -19,8 +19,7 @@ module Types
|
|||
field :title, GraphQL::Types::String, null: false,
|
||||
description: 'Title of the work item.'
|
||||
field :work_item_type, Types::WorkItems::TypeType, null: false,
|
||||
description: 'Type assigned to the work item.',
|
||||
method: :work_item_type_with_fallback # necessary until we validate the not null constraint
|
||||
description: 'Type assigned to the work item.'
|
||||
|
||||
markdown_field :title_html, null: true
|
||||
markdown_field :description_html, null: true
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ module Ci
|
|||
title = s_("Runners|Runner is online; last contact was %{runner_contact} ago") % { runner_contact: time_ago_in_words(contacted_at) }
|
||||
icon = 'status-active'
|
||||
span_class = 'gl-text-green-500'
|
||||
when :not_connected, :never_contacted
|
||||
when :never_contacted
|
||||
title = s_("Runners|Runner has never contacted this instance")
|
||||
icon = 'warning-solid'
|
||||
when :offline
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ module Ci
|
|||
has_one :runtime_metadata, class_name: 'Ci::RunningBuild', foreign_key: :build_id
|
||||
has_many :trace_chunks, class_name: 'Ci::BuildTraceChunk', foreign_key: :build_id, inverse_of: :build
|
||||
has_many :report_results, class_name: 'Ci::BuildReportResult', inverse_of: :build
|
||||
has_one :namespace, through: :project
|
||||
|
||||
# Projects::DestroyService destroys Ci::Pipelines, which use_fast_destroy on :job_artifacts
|
||||
# before we delete builds. By doing this, the relation should be empty and not fire any
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# CI::NamespaceSettings mixin
|
||||
#
|
||||
# This module is intended to encapsulate CI/CD settings-specific logic
|
||||
# and be prepended in the `Namespace` model
|
||||
module Ci
|
||||
module NamespaceSettings
|
||||
# Overridden in EE::Namespace
|
||||
def allow_stale_runner_pruning?
|
||||
false
|
||||
end
|
||||
|
||||
# Overridden in EE::Namespace
|
||||
def allow_stale_runner_pruning=(_value)
|
||||
raise NotImplementedError
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -12,6 +12,7 @@ module Ci
|
|||
include Gitlab::Utils::StrongMemoize
|
||||
include TaggableQueries
|
||||
include Presentable
|
||||
include EachBatch
|
||||
|
||||
add_authentication_token_field :token, encrypted: :optional, expires_at: :compute_token_expiration, expiration_enforced?: :token_expiration_enforced?
|
||||
|
||||
|
|
@ -59,7 +60,7 @@ module Ci
|
|||
|
||||
AVAILABLE_TYPES_LEGACY = %w[specific shared].freeze
|
||||
AVAILABLE_TYPES = runner_types.keys.freeze
|
||||
AVAILABLE_STATUSES = %w[active paused online offline not_connected never_contacted stale].freeze # TODO: Remove in %15.0: not_connected. In %16.0: active, paused. Relevant issues: https://gitlab.com/gitlab-org/gitlab/-/issues/347303, https://gitlab.com/gitlab-org/gitlab/-/issues/347305, https://gitlab.com/gitlab-org/gitlab/-/issues/344648
|
||||
AVAILABLE_STATUSES = %w[active paused online offline never_contacted stale].freeze # TODO: Remove in %16.0: active, paused. Relevant issues: https://gitlab.com/gitlab-org/gitlab/-/issues/347303, https://gitlab.com/gitlab-org/gitlab/-/issues/344648
|
||||
AVAILABLE_SCOPES = (AVAILABLE_TYPES_LEGACY + AVAILABLE_TYPES + AVAILABLE_STATUSES).freeze
|
||||
|
||||
FORM_EDITABLE = %i[description tag_list active run_untagged locked access_level maximum_timeout_human_readable].freeze
|
||||
|
|
@ -83,7 +84,6 @@ module Ci
|
|||
scope :recent, -> { where('ci_runners.created_at >= :date OR ci_runners.contacted_at >= :date', date: stale_deadline) }
|
||||
scope :stale, -> { where('ci_runners.created_at < :date AND (ci_runners.contacted_at IS NULL OR ci_runners.contacted_at < :date)', date: stale_deadline) }
|
||||
scope :offline, -> { where(arel_table[:contacted_at].lteq(online_contact_time_deadline)) }
|
||||
scope :not_connected, -> { where(contacted_at: nil) } # TODO: Remove in 15.0
|
||||
scope :never_contacted, -> { where(contacted_at: nil) }
|
||||
scope :ordered, -> { order(id: :desc) }
|
||||
|
||||
|
|
@ -337,7 +337,7 @@ module Ci
|
|||
# TODO Remove in %16.0 in favor of `status` for REST calls, see https://gitlab.com/gitlab-org/gitlab/-/issues/344648
|
||||
def deprecated_rest_status
|
||||
if contacted_at.nil?
|
||||
:not_connected
|
||||
:never_contacted
|
||||
elsif active?
|
||||
online? ? :online : :offline
|
||||
else
|
||||
|
|
|
|||
|
|
@ -186,8 +186,6 @@ class Issue < ApplicationRecord
|
|||
after_save :ensure_metrics, unless: :importing?
|
||||
after_create_commit :record_create_action, unless: :importing?
|
||||
|
||||
before_validation :ensure_work_item_type
|
||||
|
||||
attr_spammable :title, spam_title: true
|
||||
attr_spammable :description, spam_description: true
|
||||
|
||||
|
|
@ -611,20 +609,12 @@ class Issue < ApplicationRecord
|
|||
end
|
||||
|
||||
# Necessary until all issues are backfilled and we add a NOT NULL constraint on the DB
|
||||
def work_item_type_with_fallback
|
||||
work_item_type || WorkItems::Type.default_by_type(issue_type)
|
||||
def work_item_type
|
||||
super || WorkItems::Type.default_by_type(issue_type)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Issue create/update service provide a work item type
|
||||
# adding this callback as there might be other mechanisms to create/update issues we are not handling
|
||||
def ensure_work_item_type
|
||||
return if work_item_type
|
||||
|
||||
self.work_item_type = WorkItems::Type.default_by_type(issue_type)
|
||||
end
|
||||
|
||||
override :persist_pg_full_text_search_vector
|
||||
def persist_pg_full_text_search_vector(search_vector)
|
||||
Issues::SearchData.upsert({ project_id: project_id, issue_id: id, search_vector: search_vector }, unique_by: %i(project_id issue_id))
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ class Namespace < ApplicationRecord
|
|||
include Namespaces::Traversal::Linear
|
||||
include EachBatch
|
||||
include BlocksUnsafeSerialization
|
||||
include Ci::NamespaceSettings
|
||||
|
||||
# Temporary column used for back-filling project namespaces.
|
||||
# Remove it once the back-filling of all project namespaces is done.
|
||||
|
|
|
|||
|
|
@ -5,3 +5,5 @@ class NamespaceCiCdSetting < ApplicationRecord # rubocop:disable Gitlab/Namespac
|
|||
|
||||
self.primary_key = :namespace_id
|
||||
end
|
||||
|
||||
NamespaceCiCdSetting.prepend_mod
|
||||
|
|
|
|||
|
|
@ -412,7 +412,6 @@ class Project < ApplicationRecord
|
|||
has_one :operations_feature_flags_client, class_name: 'Operations::FeatureFlagsClient'
|
||||
has_many :operations_feature_flags_user_lists, class_name: 'Operations::FeatureFlags::UserList'
|
||||
|
||||
has_many :error_tracking_errors, inverse_of: :project, class_name: 'ErrorTracking::Error'
|
||||
has_many :error_tracking_client_keys, inverse_of: :project, class_name: 'ErrorTracking::ClientKey'
|
||||
|
||||
has_many :timelogs
|
||||
|
|
|
|||
|
|
@ -71,5 +71,15 @@ module ErrorTracking
|
|||
def can_update?
|
||||
can?(current_user, :update_sentry_issue, project)
|
||||
end
|
||||
|
||||
def error_repository
|
||||
Gitlab::ErrorTracking::ErrorRepository.build(project)
|
||||
end
|
||||
|
||||
def handle_error_repository_exceptions
|
||||
yield
|
||||
rescue Gitlab::ErrorTracking::ErrorRepository::DatabaseError => e
|
||||
{ error: e.message }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,30 +5,24 @@ module ErrorTracking
|
|||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
def execute
|
||||
# Error is a way to group events based on common data like name or cause
|
||||
# of exception. We need to keep a sane balance here between taking too little
|
||||
# and too much data into group logic.
|
||||
error = project.error_tracking_errors.report_error(
|
||||
name: exception['type'], # Example: ActionView::MissingTemplate
|
||||
description: exception['value'], # Example: Missing template posts/show in...
|
||||
actor: actor, # Example: PostsController#show
|
||||
platform: event['platform'], # Example: ruby
|
||||
timestamp: timestamp
|
||||
)
|
||||
|
||||
# The payload field contains all the data on error including stacktrace in jsonb.
|
||||
# Together with occurred_at these are 2 main attributes that we need to save here.
|
||||
error.events.create!(
|
||||
environment: event['environment'],
|
||||
error_repository.report_error(
|
||||
name: exception['type'],
|
||||
description: exception['value'],
|
||||
level: event['level'],
|
||||
actor: actor,
|
||||
platform: event['platform'],
|
||||
occurred_at: timestamp,
|
||||
environment: event['environment'],
|
||||
level: event['level'],
|
||||
payload: event
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def error_repository
|
||||
Gitlab::ErrorTracking::ErrorRepository.build(project)
|
||||
end
|
||||
|
||||
def event
|
||||
@event ||= format_event(params[:event])
|
||||
end
|
||||
|
|
|
|||
|
|
@ -49,13 +49,10 @@ module ErrorTracking
|
|||
# Issue https://gitlab.com/gitlab-org/gitlab/-/issues/329596
|
||||
#
|
||||
if project_error_tracking_setting.integrated_client?
|
||||
error = project.error_tracking_errors.find(issue_id)
|
||||
|
||||
# We use the same response format as project_error_tracking_setting
|
||||
# method below for compatibility with existing code.
|
||||
{
|
||||
issue: error.to_sentry_detailed_error
|
||||
}
|
||||
handle_error_repository_exceptions do
|
||||
error = error_repository.find_error(issue_id)
|
||||
{ issue: error }
|
||||
end
|
||||
else
|
||||
project_error_tracking_setting.issue_details(issue_id: issue_id)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -26,14 +26,13 @@ module ErrorTracking
|
|||
# Issue https://gitlab.com/gitlab-org/gitlab/-/issues/329596
|
||||
#
|
||||
if project_error_tracking_setting.integrated_client?
|
||||
error = project.error_tracking_errors.find(issue_id)
|
||||
event = error.events.last
|
||||
handle_error_repository_exceptions do
|
||||
event = error_repository.last_event_for(issue_id)
|
||||
|
||||
# We use the same response format as project_error_tracking_setting
|
||||
# method below for compatibility with existing code.
|
||||
{
|
||||
latest_event: event.to_sentry_error_event
|
||||
}
|
||||
# We use the same response format as project_error_tracking_setting
|
||||
# method below for compatibility with existing code.
|
||||
{ latest_event: event }
|
||||
end
|
||||
else
|
||||
project_error_tracking_setting.issue_latest_event(issue_id: issue_id)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -84,14 +84,12 @@ module ErrorTracking
|
|||
# Issue https://gitlab.com/gitlab-org/gitlab/-/issues/329596
|
||||
#
|
||||
if project_error_tracking_setting.integrated_client?
|
||||
error = project.error_tracking_errors.find(opts[:issue_id])
|
||||
error.status = opts[:params][:status]
|
||||
error.save!
|
||||
updated = error_repository.update_error(opts[:issue_id], status: opts[:params][:status])
|
||||
|
||||
# We use the same response format as project_error_tracking_setting
|
||||
# method below for compatibility with existing code.
|
||||
{
|
||||
updated: true
|
||||
updated: updated
|
||||
}
|
||||
else
|
||||
project_error_tracking_setting.update_issue(**opts)
|
||||
|
|
|
|||
|
|
@ -73,24 +73,24 @@ module ErrorTracking
|
|||
if project_error_tracking_setting.integrated_client?
|
||||
# We are going to support more options in the future.
|
||||
# For now we implement the bare minimum for rendering the list in UI.
|
||||
filter_opts = {
|
||||
status: opts[:issue_status],
|
||||
list_opts = {
|
||||
filters: { status: opts[:issue_status] },
|
||||
sort: opts[:sort],
|
||||
limit: opts[:limit],
|
||||
cursor: opts[:cursor]
|
||||
}
|
||||
|
||||
errors = ErrorTracking::ErrorsFinder.new(current_user, project, filter_opts).execute
|
||||
errors, pagination = error_repository.list_errors(**list_opts)
|
||||
|
||||
pagination = {}
|
||||
pagination[:next] = { cursor: errors.cursor_for_next_page } if errors.has_next_page?
|
||||
pagination[:previous] = { cursor: errors.cursor_for_previous_page } if errors.has_previous_page?
|
||||
pagination_hash = {}
|
||||
pagination_hash[:next] = { cursor: pagination.next } if pagination.next
|
||||
pagination_hash[:previous] = { cursor: pagination.prev } if pagination.prev
|
||||
|
||||
# We use the same response format as project_error_tracking_setting
|
||||
# method below for compatibility with existing code.
|
||||
{
|
||||
issues: errors.map(&:to_sentry_error),
|
||||
pagination: pagination
|
||||
issues: errors,
|
||||
pagination: pagination_hash
|
||||
}
|
||||
else
|
||||
project_error_tracking_setting.list_sentry_issues(**opts)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
%b= s_('ProjectSettings|Merge method')
|
||||
%p.text-secondary
|
||||
= s_('ProjectSettings|Determine what happens to the commit history when you merge a merge request.')
|
||||
= link_to s_('ProjectSettings|Learn about commit history.'), help_page_path('user/project/merge_requests/commits.md'), target: '_blank', rel: 'noopener noreferrer'
|
||||
= link_to s_('ProjectSettings|How do they differ?'), help_page_path('user/project/merge_requests/methods/index.md'), target: '_blank', rel: 'noopener noreferrer'
|
||||
.form-check.mb-2
|
||||
= form.radio_button :merge_method, :merge, class: "js-merge-method-radio form-check-input"
|
||||
= label_tag :project_merge_method_merge, class: 'form-check-label' do
|
||||
|
|
|
|||
|
|
@ -536,8 +536,10 @@ module Gitlab
|
|||
# because we connect to database from routes
|
||||
# https://github.com/rails/rails/blob/fdf840f69a2e33d78a9d40b91d9b7fddb76711e9/activerecord/lib/active_record/railtie.rb#L308
|
||||
initializer :clear_active_connections_again, after: :set_routes_reloader_hook do
|
||||
# rubocop:disable Database/MultipleDatabases
|
||||
ActiveRecord::Base.clear_active_connections!
|
||||
ActiveRecord::Base.flush_idle_connections!
|
||||
# rubocop:enable Database/MultipleDatabases
|
||||
end
|
||||
|
||||
# DO NOT PLACE ANY INITIALIZERS AFTER THIS.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
name: enhanced_notify_css
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78604
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/355907
|
||||
milestone: '14.8'
|
||||
milestone: '14.9'
|
||||
type: development
|
||||
group: group::project management
|
||||
default_enabled: false
|
||||
default_enabled: true
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: ci_runner_separation_by_plan
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83780
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/361639
|
||||
milestone: '15.0'
|
||||
type: ops
|
||||
group: group::runner
|
||||
default_enabled: false
|
||||
|
|
@ -607,6 +607,10 @@ production: &base
|
|||
elastic_index_initial_bulk_cron_worker:
|
||||
cron: "*/10 * * * *"
|
||||
|
||||
# Periodically prune stale runners from namespaces having opted-in.
|
||||
ci_runners_stale_group_runners_prune_worker_cron:
|
||||
cron: "30 * * * *"
|
||||
|
||||
registry:
|
||||
# enabled: true
|
||||
# host: registry.example.com
|
||||
|
|
|
|||
|
|
@ -772,6 +772,9 @@ Gitlab.ee do
|
|||
Settings.cron_jobs['arkose_blocked_users_report_worker'] ||= Settingslogic.new({})
|
||||
Settings.cron_jobs['arkose_blocked_users_report_worker']['cron'] ||= '0 6 * * *'
|
||||
Settings.cron_jobs['arkose_blocked_users_report_worker']['job_class'] = 'Arkose::BlockedUsersReportWorker'
|
||||
Settings.cron_jobs['ci_runners_stale_group_runners_prune_worker_cron'] ||= Settingslogic.new({})
|
||||
Settings.cron_jobs['ci_runners_stale_group_runners_prune_worker_cron']['cron'] ||= '30 * * * *'
|
||||
Settings.cron_jobs['ci_runners_stale_group_runners_prune_worker_cron']['job_class'] = 'Ci::Runners::StaleGroupRunnersPruneCronWorker'
|
||||
end
|
||||
|
||||
#
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
- name: "Runner status `not_connected` API value"
|
||||
announcement_milestone: "14.6" # The milestone when this feature was first announced as deprecated.
|
||||
removal_milestone: "15.0" # the milestone when this feature is planned to be removed
|
||||
removal_date: "2022-05-22"
|
||||
breaking_change: true
|
||||
body: | # Do not modify this line, instead modify the lines below.
|
||||
The GitLab Runner REST and GraphQL [API](https://docs.gitlab.com/ee/api/runners.html#runners-api) endpoints
|
||||
deprecated the `not_connected` status value in GitLab 14.6 and will start returning `never_contacted` in its place
|
||||
starting in GitLab 15.0.
|
||||
|
||||
Runners that have never contacted the GitLab instance will also return `stale` if created more than 3 months ago.
|
||||
stage: Verify
|
||||
tiers: [Core, Premium, Ultimate]
|
||||
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/347305
|
||||
documentation_url: https://docs.gitlab.com/ee/api/runners.html
|
||||
announcement_date: "2021-12-22"
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddAllowedPlansToCiRunners < Gitlab::Database::Migration[1.0]
|
||||
def change
|
||||
# rubocop:disable Migration/AddLimitToTextColumns
|
||||
add_column :ci_runners, :allowed_plans, :text, array: true, null: false, default: []
|
||||
# rubocop:enable Migration/AddLimitToTextColumns
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddAllowStaleRunnerPruningIndexToNamespaceCiCdSettings < Gitlab::Database::Migration[2.0]
|
||||
INDEX_NAME = 'index_cicd_settings_on_namespace_id_where_stale_pruning_enabled'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_index :namespace_ci_cd_settings,
|
||||
:namespace_id,
|
||||
where: '(allow_stale_runner_pruning = true)',
|
||||
name: INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name :namespace_ci_cd_settings, INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveNotNullConstraintFromWorkItemType < Gitlab::Database::Migration[2.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85866 introduced a NOT NULL constraint on
|
||||
# `issues` which caused QA failures (https://gitlab.com/gitlab-org/gitlab/-/issues/362023), and
|
||||
# Helm database issues resulting in broken tests after restoring the database.
|
||||
def up
|
||||
remove_not_null_constraint :issues, :work_item_type_id, constraint_name: 'check_2addf801cd'
|
||||
end
|
||||
|
||||
def down
|
||||
add_not_null_constraint :issues, :work_item_type_id, validate: false
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
cd332bdb33335750855cd0d6e49bed12a841defa24bc5ffb14ad49a39bd663aa
|
||||
|
|
@ -0,0 +1 @@
|
|||
d37359ba5f697c4aaec738073c7705a64b54b97d2548f72571f3cb33848cfc3b
|
||||
|
|
@ -0,0 +1 @@
|
|||
ef899952453ddd870c45f2b4eded754152972944037309cf96701fe27a5db6cb
|
||||
|
|
@ -13036,6 +13036,7 @@ CREATE TABLE ci_runners (
|
|||
executor_type smallint,
|
||||
maintainer_note text,
|
||||
token_expires_at timestamp with time zone,
|
||||
allowed_plans text[] DEFAULT '{}'::text[] NOT NULL,
|
||||
CONSTRAINT check_ce275cee06 CHECK ((char_length(maintainer_note) <= 1024))
|
||||
);
|
||||
|
||||
|
|
@ -24112,9 +24113,6 @@ ALTER TABLE ONLY chat_names
|
|||
ALTER TABLE ONLY chat_teams
|
||||
ADD CONSTRAINT chat_teams_pkey PRIMARY KEY (id);
|
||||
|
||||
ALTER TABLE issues
|
||||
ADD CONSTRAINT check_2addf801cd CHECK ((work_item_type_id IS NOT NULL)) NOT VALID;
|
||||
|
||||
ALTER TABLE vulnerability_scanners
|
||||
ADD CONSTRAINT check_37608c9db5 CHECK ((char_length(vendor) <= 255)) NOT VALID;
|
||||
|
||||
|
|
@ -27330,6 +27328,8 @@ CREATE INDEX index_ci_variables_on_key ON ci_variables USING btree (key);
|
|||
|
||||
CREATE UNIQUE INDEX index_ci_variables_on_project_id_and_key_and_environment_scope ON ci_variables USING btree (project_id, key, environment_scope);
|
||||
|
||||
CREATE INDEX index_cicd_settings_on_namespace_id_where_stale_pruning_enabled ON namespace_ci_cd_settings USING btree (namespace_id) WHERE (allow_stale_runner_pruning = true);
|
||||
|
||||
CREATE INDEX index_cluster_agent_tokens_on_agent_id_status_last_used_at ON cluster_agent_tokens USING btree (agent_id, status, last_used_at DESC NULLS LAST);
|
||||
|
||||
CREATE INDEX index_cluster_agent_tokens_on_created_by_user_id ON cluster_agent_tokens USING btree (created_by_user_id);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ Bamboo
|
|||
Bazel
|
||||
Bhyve
|
||||
Bitbucket
|
||||
Bitnami
|
||||
blockquote
|
||||
blockquoted
|
||||
blockquotes
|
||||
|
|
@ -93,8 +94,12 @@ Camo
|
|||
canonicalization
|
||||
canonicalized
|
||||
captcha
|
||||
Casdoor
|
||||
CentOS
|
||||
Ceph
|
||||
Certbot
|
||||
cgroup
|
||||
cgroups
|
||||
chai
|
||||
changeset
|
||||
changesets
|
||||
|
|
@ -109,6 +114,7 @@ Citus
|
|||
clonable
|
||||
Cloudwatch
|
||||
Cobertura
|
||||
Codeception
|
||||
Codepen
|
||||
Cognito
|
||||
colocated
|
||||
|
|
@ -174,6 +180,7 @@ disambiguates
|
|||
discoverability
|
||||
dismissable
|
||||
Disqus
|
||||
Distroless
|
||||
Divio
|
||||
Dockerfile
|
||||
Dockerfiles
|
||||
|
|
@ -206,6 +213,7 @@ failovers
|
|||
failsafe
|
||||
Falco
|
||||
falsy
|
||||
Fargate
|
||||
fastlane
|
||||
Fastzip
|
||||
favicon
|
||||
|
|
@ -254,7 +262,9 @@ Gradle
|
|||
Grafana
|
||||
Grafonnet
|
||||
gravatar
|
||||
Grype
|
||||
Gzip
|
||||
Hackathon
|
||||
Haml
|
||||
hardcode
|
||||
hardcoded
|
||||
|
|
@ -333,6 +343,7 @@ Leiningen
|
|||
libFuzzer
|
||||
Libravatar
|
||||
liveness
|
||||
lockfiles
|
||||
Lodash
|
||||
Lograge
|
||||
logrotate
|
||||
|
|
@ -352,6 +363,7 @@ Makefile
|
|||
Makefiles
|
||||
Markdown
|
||||
markdownlint
|
||||
Marketo
|
||||
matcher
|
||||
matchers
|
||||
Matomo
|
||||
|
|
@ -364,6 +376,7 @@ memoizing
|
|||
Memorystore
|
||||
mergeability
|
||||
mergeable
|
||||
metaprogramming
|
||||
Microsoft
|
||||
middleware
|
||||
middlewares
|
||||
|
|
@ -386,6 +399,7 @@ ModSecurity
|
|||
Monokai
|
||||
monorepo
|
||||
monorepos
|
||||
monospace
|
||||
multiline
|
||||
mutex
|
||||
nameserver
|
||||
|
|
@ -399,6 +413,7 @@ Nanoc
|
|||
negatable
|
||||
Netlify
|
||||
Nokogiri
|
||||
nosniff
|
||||
noteable
|
||||
noteables
|
||||
npm
|
||||
|
|
@ -472,6 +487,7 @@ proxies
|
|||
proxyable
|
||||
proxying
|
||||
pseudocode
|
||||
pseudonymization
|
||||
pseudonymized
|
||||
pseudonymizer
|
||||
Puma
|
||||
|
|
@ -484,6 +500,7 @@ Rackspace
|
|||
Raspbian
|
||||
rbenv
|
||||
rbtrace
|
||||
Rclone
|
||||
Rdoc
|
||||
reachability
|
||||
Realplayer
|
||||
|
|
@ -592,10 +609,12 @@ Slony
|
|||
smartcard
|
||||
smartcards
|
||||
snapshotting
|
||||
Snyk
|
||||
Sobelow
|
||||
Solargraph
|
||||
Solarized
|
||||
Sourcegraph
|
||||
Spamcheck
|
||||
spammable
|
||||
sparkline
|
||||
sparklines
|
||||
|
|
@ -660,6 +679,7 @@ Sysbench
|
|||
syscall
|
||||
syscalls
|
||||
syslog
|
||||
systemd
|
||||
tanuki
|
||||
tcpdump
|
||||
templated
|
||||
|
|
@ -700,6 +720,7 @@ Twilio
|
|||
Twitter
|
||||
TypeScript
|
||||
Ubuntu
|
||||
Udemy
|
||||
unapplied
|
||||
unapprove
|
||||
unapproved
|
||||
|
|
@ -828,6 +849,7 @@ wireframes
|
|||
wireframing
|
||||
Wireshark
|
||||
Wordpress
|
||||
Workato
|
||||
worktree
|
||||
worktrees
|
||||
Worldline
|
||||
|
|
@ -836,6 +858,7 @@ Xeon
|
|||
YouTrack
|
||||
ytt
|
||||
Yubico
|
||||
Zabbix
|
||||
Zeitwerk
|
||||
Zendesk
|
||||
ZenTao
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ The tables lists features on the left and provides their capabilities to the rig
|
|||
|
||||
## Geo Capabilities
|
||||
|
||||
If your availabity needs to span multiple zones or multiple locations, please read about [Geo](geo/index.md).
|
||||
If your availability needs to span multiple zones or multiple locations, please read about [Geo](geo/index.md).
|
||||
|
||||
| | Availability | Recoverability | Data Resiliency | Performance | Risks/Trade-offs|
|
||||
|-|--------------|----------------|-----------------|-------------|-----------------|
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ follow these steps to avoid unnecessary data loss:
|
|||
1. On the **primary** site:
|
||||
1. On the top bar, select **Menu > Admin**.
|
||||
1. On the left sidebar, select **Monitoring > Background Jobs**.
|
||||
1. On the Sidekiq dhasboard, select **Cron**.
|
||||
1. On the Sidekiq dashboard, select **Cron**.
|
||||
1. Select `Disable All` to disable any non-Geo periodic background jobs.
|
||||
1. Select `Enable` for the `geo_sidekiq_cron_config_worker` cron job.
|
||||
This job re-enables several other cron jobs that are essential for planned
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ full list of reference architectures, see
|
|||
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
|
||||
<!-- markdownlint-disable MD029 -->
|
||||
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work, however Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However it is also used optionally by Prometheus for Omnibus auto host discovery.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS Elasticache are known to work.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
|
||||
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
|
||||
4. Should be run on reputable third-party object storage (storage PaaS) for cloud implementations. Google Cloud Storage and AWS S3 are known to work.
|
||||
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
|
||||
|
|
@ -2333,7 +2333,7 @@ services where applicable):
|
|||
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
|
||||
<!-- markdownlint-disable MD029 -->
|
||||
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work, however Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However it is also used optionally by Prometheus for Omnibus auto host discovery.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS Elasticache are known to work.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
|
||||
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
|
||||
4. Should be run on reputable third-party object storage (storage PaaS) for cloud implementations. Google Cloud Storage and AWS S3 are known to work.
|
||||
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ full list of reference architectures, see
|
|||
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
|
||||
<!-- markdownlint-disable MD029 -->
|
||||
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work, however Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However it is also used optionally by Prometheus for Omnibus auto host discovery.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS Elasticache are known to work.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
|
||||
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
|
||||
4. Should be run on reputable third-party object storage (storage PaaS) for cloud implementations. Google Cloud Storage and AWS S3 are known to work.
|
||||
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
|
||||
|
|
@ -2331,7 +2331,7 @@ services where applicable):
|
|||
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
|
||||
<!-- markdownlint-disable MD029 -->
|
||||
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work, however Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However it is also used optionally by Prometheus for Omnibus auto host discovery.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS Elasticache are known to work.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
|
||||
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
|
||||
4. Should be run on reputable third-party object storage (storage PaaS) for cloud implementations. Google Cloud Storage and AWS S3 are known to work.
|
||||
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ For a full list of reference architectures, see
|
|||
|
||||
<!-- markdownlint-disable MD029 -->
|
||||
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work, however Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However it is also used optionally by Prometheus for Omnibus auto host discovery.
|
||||
2. Can be optionally run as reputable third-party external PaaS Redis solutions. Google Memorystore and AWS Elasticache are known to work.
|
||||
2. Can be optionally run as reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
|
||||
3. Can be optionally run as reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
|
||||
4. Should be run on reputable third-party object storage (storage PaaS) for cloud implementations. Google Cloud Storage and AWS S3 are known to work.
|
||||
<!-- markdownlint-enable MD029 -->
|
||||
|
|
@ -1030,7 +1030,7 @@ services where applicable):
|
|||
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
|
||||
<!-- markdownlint-disable MD029 -->
|
||||
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work, however Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However it is also used optionally by Prometheus for Omnibus auto host discovery.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS Elasticache are known to work.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
|
||||
3. Should be run on reputable third-party object storage (storage PaaS) for cloud implementations. Google Cloud Storage and AWS S3 are known to work.
|
||||
<!-- markdownlint-enable MD029 -->
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ For a full list of reference architectures, see
|
|||
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
|
||||
<!-- markdownlint-disable MD029 -->
|
||||
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work, however Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However it is also used optionally by Prometheus for Omnibus auto host discovery.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS Elasticache are known to work.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
|
||||
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
|
||||
4. Should be run on reputable third-party object storage (storage PaaS) for cloud implementations. Google Cloud Storage and AWS S3 are known to work.
|
||||
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
|
||||
|
|
@ -2290,7 +2290,7 @@ services where applicable):
|
|||
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
|
||||
<!-- markdownlint-disable MD029 -->
|
||||
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work, however Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However it is also used optionally by Prometheus for Omnibus auto host discovery.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS Elasticache are known to work.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
|
||||
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
|
||||
4. Should be run on reputable third-party object storage (storage PaaS) for cloud implementations. Google Cloud Storage and AWS S3 are known to work.
|
||||
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ full list of reference architectures, see
|
|||
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
|
||||
<!-- markdownlint-disable MD029 -->
|
||||
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work, however Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However it is also used optionally by Prometheus for Omnibus auto host discovery.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS Elasticache are known to work.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
|
||||
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
|
||||
4. Should be run on reputable third-party object storage (storage PaaS) for cloud implementations. Google Cloud Storage and AWS S3 are known to work.
|
||||
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
|
||||
|
|
@ -2347,7 +2347,7 @@ services where applicable):
|
|||
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
|
||||
<!-- markdownlint-disable MD029 -->
|
||||
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work, however Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However it is also used optionally by Prometheus for Omnibus auto host discovery.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS Elasticache are known to work.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
|
||||
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
|
||||
4. Should be run on reputable third-party object storage (storage PaaS) for cloud implementations. Google Cloud Storage and AWS S3 are known to work.
|
||||
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ costly-to-operate environment by using the
|
|||
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
|
||||
<!-- markdownlint-disable MD029 -->
|
||||
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work, however Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However it is also used optionally by Prometheus for Omnibus auto host discovery.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS Elasticache are known to work.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
|
||||
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
|
||||
4. Should be run on reputable third-party object storage (storage PaaS) for cloud implementations. Google Cloud Storage and AWS S3 are known to work.
|
||||
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
|
||||
|
|
@ -2265,7 +2265,7 @@ services where applicable):
|
|||
<!-- Disable ordered list rule https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md#md029---ordered-list-item-prefix -->
|
||||
<!-- markdownlint-disable MD029 -->
|
||||
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. [Google Cloud SQL](https://cloud.google.com/sql/docs/postgres/high-availability#normal) and [Amazon RDS](https://aws.amazon.com/rds/) are known to work, however Azure Database for PostgreSQL is **not recommended** due to [performance issues](https://gitlab.com/gitlab-org/quality/reference-architectures/-/issues/61). Consul is primarily used for PostgreSQL high availability so can be ignored when using a PostgreSQL PaaS setup. However it is also used optionally by Prometheus for Omnibus auto host discovery.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS Elasticache are known to work.
|
||||
2. Can be optionally run on reputable third-party external PaaS Redis solutions. Google Memorystore and AWS ElastiCache are known to work.
|
||||
3. Can be optionally run on reputable third-party load balancing services (LB PaaS). AWS ELB is known to work.
|
||||
4. Should be run on reputable third-party object storage (storage PaaS) for cloud implementations. Google Cloud Storage and AWS S3 are known to work.
|
||||
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management. Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
|
||||
|
|
|
|||
|
|
@ -358,7 +358,7 @@ Additionally, the following cloud provider services are validated and supported
|
|||
<tr>
|
||||
<td>Redis</td>
|
||||
<td></td>
|
||||
<td>✅ <a href="https://aws.amazon.com/elasticache/" target="_blank" rel="noopener noreferrer">Elasticache</a></td>
|
||||
<td>✅ <a href="https://aws.amazon.com/elasticache/" target="_blank" rel="noopener noreferrer">ElastiCache</a></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
|||
|
|
@ -26,4 +26,4 @@ and summarize raw `strace` data.
|
|||
|
||||
## kubesos
|
||||
|
||||
The [`kubesos`](https://gitlab.com/gitlab-com/support/toolbox/kubesos/) utiltity retrieves GitLab cluster configuration and logs from GitLab Cloud Native chart deployments.
|
||||
The [`kubesos`](https://gitlab.com/gitlab-com/support/toolbox/kubesos/) utility retrieves GitLab cluster configuration and logs from GitLab Cloud Native chart deployments.
|
||||
|
|
|
|||
|
|
@ -753,7 +753,7 @@ group.members_with_parents.count
|
|||
parent.members_with_descendants.count
|
||||
```
|
||||
|
||||
### Find gropus that are pending deletion
|
||||
### Find groups that are pending deletion
|
||||
|
||||
```ruby
|
||||
#
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ but if they are not available you can still quickly parse
|
|||
(the default in GitLab 12.0 and later) using [`jq`](https://stedolan.github.io/jq/).
|
||||
|
||||
NOTE:
|
||||
Spefically for summarising error events and basic usage statistics,
|
||||
Specifically for summarizing error events and basic usage statistics,
|
||||
the GitLab Support Team provides the specialised
|
||||
[`fast-stats` tool](https://gitlab.com/gitlab-com/support/toolbox/fast-stats/#when-to-use-it).
|
||||
|
||||
|
|
|
|||
|
|
@ -17993,8 +17993,7 @@ Values for sorting runners.
|
|||
| Value | Description |
|
||||
| ----- | ----------- |
|
||||
| <a id="cirunnerstatusactive"></a>`ACTIVE` **{warning-solid}** | **Deprecated** in 14.6. This was renamed. Use: [`CiRunner.paused`](#cirunnerpaused). |
|
||||
| <a id="cirunnerstatusnever_contacted"></a>`NEVER_CONTACTED` | Runner that has never contacted this instance. Set legacyMode to null to utilize this value. Will replace NOT_CONNECTED starting in 15.0. |
|
||||
| <a id="cirunnerstatusnot_connected"></a>`NOT_CONNECTED` **{warning-solid}** | **Deprecated** in 14.6. Use NEVER_CONTACTED instead. NEVER_CONTACTED will have a slightly different scope starting in 15.0, with STALE being returned instead after 3 months of no contact. |
|
||||
| <a id="cirunnerstatusnever_contacted"></a>`NEVER_CONTACTED` | Runner that has never contacted this instance. |
|
||||
| <a id="cirunnerstatusoffline"></a>`OFFLINE` **{warning-solid}** | **Deprecated** in 14.6. This field will have a slightly different scope starting in 15.0, with STALE being returned after a certain period offline. |
|
||||
| <a id="cirunnerstatusonline"></a>`ONLINE` | Runner that contacted this instance within the last 2 hours. |
|
||||
| <a id="cirunnerstatuspaused"></a>`PAUSED` **{warning-solid}** | **Deprecated** in 14.6. This was renamed. Use: [`CiRunner.paused`](#cirunnerpaused). |
|
||||
|
|
|
|||
|
|
@ -483,6 +483,35 @@ DELETE /groups/:id/billable_members/:user_id
|
|||
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/billable_members/:user_id"
|
||||
```
|
||||
|
||||
## Change membership state of a user in a group
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/86705) in GitLab 15.0.
|
||||
|
||||
Changes the membership state of a user in a group. The state is applied to
|
||||
all subgroups and projects.
|
||||
|
||||
```plaintext
|
||||
PUT /groups/:id/members/:user_id/state
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ---- | -------- | ----------- |
|
||||
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](index.md#namespaced-path-encoding) owned by the authenticated user. |
|
||||
| `user_id` | integer | yes | The user ID of the member. |
|
||||
| `state` | string | yes | The new state for the user. State is either `awaiting` or `active`. |
|
||||
|
||||
```shell
|
||||
curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/:id/members/:user_id/state?state=active"
|
||||
```
|
||||
|
||||
Example response:
|
||||
|
||||
```json
|
||||
{
|
||||
"success":true
|
||||
}
|
||||
```
|
||||
|
||||
## Add a member to a group or project
|
||||
|
||||
Adds a member to a group or project.
|
||||
|
|
|
|||
|
|
@ -44,13 +44,13 @@ GET /runners?paused=true
|
|||
GET /runners?tag_list=tag1,tag2
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
|------------|--------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online` and `offline`; showing all runners if none provided |
|
||||
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
|
||||
| `status` | string | no | The status of runners to show, one of: `online`, `offline` and `not_connected`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 16.0 |
|
||||
| `paused` | boolean | no | Whether to include only runners that are accepting or ignoring new jobs |
|
||||
| `tag_list` | string array | no | List of the runner's tags |
|
||||
| Attribute | Type | Required | Description |
|
||||
|------------|--------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| `scope` | string | no | Deprecated: Use `type` or `status` instead. The scope of specific runners to show, one of: `active`, `paused`, `online` and `offline`; showing all runners if none provided |
|
||||
| `type` | string | no | The type of runners to show, one of: `instance_type`, `group_type`, `project_type` |
|
||||
| `status` | string | no | The status of runners to show, one of: `online`, `offline` and `never_contacted`. `active` and `paused` are also possible values which were deprecated in GitLab 14.8 and will be removed in GitLab 16.0 |
|
||||
| `paused` | boolean | no | Whether to include only runners that are accepting or ignoring new jobs |
|
||||
| `tag_list` | string array | no | List of the runner's tags |
|
||||
|
||||
```shell
|
||||
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/runners"
|
||||
|
|
@ -610,7 +610,7 @@ Example response:
|
|||
"runner_type": "instance_type",
|
||||
"name": "gitlab-runner",
|
||||
"online": null,
|
||||
"status": "not_connected"
|
||||
"status": "never_contacted"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
|
|
@ -634,7 +634,7 @@ Example response:
|
|||
"runner_type": "group_type",
|
||||
"name": "gitlab-runner",
|
||||
"online": null,
|
||||
"status": "not_connected"
|
||||
"status": "never_contacted"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ In order to maintain and improve operational stability and lessen development bu
|
|||
|
||||
This target is *pragmatic*: We understand table sizes depend on feature usage, code changes and other factors - which all change over time. We may not always find solutions where we can tightly limit the size of physical tables once and for all. That is acceptable though and we primarily aim to keep the situation on GitLab.com under control. We adapt our efforts to the situation present on GitLab.com and will re-evaluate frequently.
|
||||
|
||||
While there are changes we can make that lead to a constant maximum physical table size over time, this doesn't need to be the case necessarily. Consider for example hash partitioniong, which breaks a table down into a static number of partitions. With data growth over time, individual partitions will also grow in size and may eventually reach the threshold size again. We strive to get constant table sizes, but it is acceptable to ship easier solutions that don't have this characteristic but improve the situation for a considerable amount of time.
|
||||
While there are changes we can make that lead to a constant maximum physical table size over time, this doesn't need to be the case necessarily. Consider for example hash partitioning, which breaks a table down into a static number of partitions. With data growth over time, individual partitions will also grow in size and may eventually reach the threshold size again. We strive to get constant table sizes, but it is acceptable to ship easier solutions that don't have this characteristic but improve the situation for a considerable amount of time.
|
||||
|
||||
As such, the target size of a physical table after refactoring depends on the situation and there is no hard rule for it. We suggest to consider historic data growth and forecast when physical tables will reach the threshold of 100 GB again. This allows us to understand how long a particular solution is expected to last until the model has to be revisited.
|
||||
|
||||
|
|
|
|||
|
|
@ -87,12 +87,14 @@ workflow:
|
|||
- if: $CI_COMMIT_BRANCH
|
||||
```
|
||||
|
||||
If the pipeline is triggered by:
|
||||
If GitLab attempts to trigger:
|
||||
|
||||
- A merge request, run a merge request pipeline. For example, a merge request pipeline
|
||||
- A merge request pipeline, start the pipeline. For example, a merge request pipeline
|
||||
can be triggered by a push to a branch with an associated open merge request.
|
||||
- A change to a branch, but a merge request is open for that branch, do not run a branch pipeline.
|
||||
- A change to a branch, but without any open merge requests, run a branch pipeline.
|
||||
- A branch pipeline, but a merge request is open for that branch, do not run the branch pipeline.
|
||||
For example, a branch pipeline can be triggered by a change to a branch, an API call,
|
||||
a scheduled pipeline, and so on.
|
||||
- A branch pipeline, but there is no merge request open for the branch, run the branch pipeline.
|
||||
|
||||
You can also add a rule to an existing `workflow` section to switch from branch pipelines
|
||||
to merge request pipelines when a merge request is created.
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ with all possible
|
|||
label-combinations](https://prometheus.io/docs/practices/instrumentation/#avoid-missing-metrics). This
|
||||
avoid confusing results when using these counters in calculations.
|
||||
|
||||
To initialize an SLI, use the `.inilialize_sli` class method, for
|
||||
To initialize an SLI, use the `.initialize_sli` class method, for
|
||||
example:
|
||||
|
||||
```ruby
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ To instrument an audit event, the following attributes should be provided:
|
|||
| `scope` | User, Project, Group | true | Scope which the audit event belongs to |
|
||||
| `target` | Object | true | Target object being audited |
|
||||
| `message` | String | true | Message describing the action |
|
||||
| `created_at` | DateTime | false | The time when the action occured. Defaults to `DateTime.current` |
|
||||
| `created_at` | DateTime | false | The time when the action occurred. Defaults to `DateTime.current` |
|
||||
|
||||
## How to instrument new Audit Events
|
||||
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ end
|
|||
```
|
||||
|
||||
Similarly the usage of `ActiveRecord::Base.connection` is disallowed and needs to be
|
||||
replaced preferrably with the usage of model connection.
|
||||
replaced preferably with the usage of model connection.
|
||||
|
||||
```ruby
|
||||
# good
|
||||
|
|
|
|||
|
|
@ -593,7 +593,7 @@ Partitions: gitlab_partitions_dynamic.loose_foreign_keys_deleted_records_84 FOR
|
|||
The `partition` column controls the insert direction, the `partition` value determines which
|
||||
partition will get the deleted rows inserted via the trigger. Notice that the default value of
|
||||
the `partition` table matches with the value of the list partition (84). In `INSERT` query
|
||||
within the trigger thevalue of the `partition` is omitted, the trigger always relies on the
|
||||
within the trigger the value of the `partition` is omitted, the trigger always relies on the
|
||||
default value of the column.
|
||||
|
||||
Example `INSERT` query for the trigger:
|
||||
|
|
@ -605,7 +605,7 @@ SELECT TG_TABLE_SCHEMA || '.' || TG_TABLE_NAME, old_table.id FROM old_table;
|
|||
```
|
||||
|
||||
The partition "sliding" process is controlled by two, regularly executed callbacks. These
|
||||
callbackes are defined within the `LooseForeignKeys::DeletedRecord` model.
|
||||
callbacks are defined within the `LooseForeignKeys::DeletedRecord` model.
|
||||
|
||||
The `next_partition_if` callback controls when to create a new partition. A new partition will
|
||||
be created when the current partition has at least one record older than 24 hours. A new partition
|
||||
|
|
@ -805,7 +805,7 @@ Possible solutions:
|
|||
- Long-term: invoke the worker more frequently. Parallelize the worker
|
||||
|
||||
For a one-time fix, we can run the cleanup worker several times from the rails console. The worker
|
||||
can run parallelly however, this can introduce lock contention and it could increase the worker
|
||||
can run in parallel however, this can introduce lock contention and it could increase the worker
|
||||
runtime.
|
||||
|
||||
```ruby
|
||||
|
|
|
|||
|
|
@ -346,7 +346,7 @@ To configure Vale in your editor, install one of the following as appropriate:
|
|||
- Visual Studio Code [`errata-ai.vale-server` extension](https://marketplace.visualstudio.com/items?itemName=errata-ai.vale-server).
|
||||
You can configure the plugin to [display only a subset of alerts](#show-subset-of-vale-alerts).
|
||||
- Vim [ALE plugin](https://github.com/dense-analysis/ale).
|
||||
- Jetbrains IDEs - No plugin exists, but
|
||||
- JetBrains IDEs - No plugin exists, but
|
||||
[this issue comment](https://github.com/errata-ai/vale-server/issues/39#issuecomment-751714451)
|
||||
contains tips for configuring an external tool.
|
||||
- Emacs [Flycheck extension](https://github.com/flycheck/flycheck).
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ in the container components when needed. This makes it easier to:
|
|||
[`delete_package.vue`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/packages_and_registries/package_registry/components/functional/delete_package.vue)).
|
||||
- Leverage [startup for GraphQL calls](graphql.md#making-initial-queries-early-with-graphql-startup-calls).
|
||||
|
||||
## Shared compoenents library
|
||||
## Shared components library
|
||||
|
||||
Inside `vue_shared/components/registry` and `packages_and_registries/shared`, there's a set of
|
||||
shared components that you can use to implement registry functionality. These components build the
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue