Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-06-12 15:18:07 +00:00
parent bd15a45eeb
commit c8eaa54d71
231 changed files with 2935 additions and 1036 deletions

View File

@ -3509,8 +3509,6 @@ RSpec/FeatureCategory:
- 'spec/models/ci/pipeline_schedule_variable_spec.rb'
- 'spec/models/ci/project_mirror_spec.rb'
- 'spec/models/ci/resource_spec.rb'
- 'spec/models/ci/runner_namespace_spec.rb'
- 'spec/models/ci/runner_project_spec.rb'
- 'spec/models/ci/trigger_request_spec.rb'
- 'spec/models/ci/unit_test_failure_spec.rb'
- 'spec/models/ci/unit_test_spec.rb'

View File

@ -2,6 +2,23 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
## 17.0.2 (2024-06-11)
### Fixed (1 change)
- [Fix instance templates pagination](gitlab-org/security/gitlab@d53fb868885472d0b7645afabee590f416eda0d5) **GitLab Enterprise Edition**
### Changed (1 change)
- [Only query the fields needed](gitlab-org/security/gitlab@74794d45373cf605d7c036cc0ab13a3d5018c616)
### Security (4 changes)
- [XSS and content injection raw XHTML files on IOS devices](gitlab-org/security/gitlab@7459916b867b01581b3422fd065419feb6352180) ([merge request](gitlab-org/security/gitlab!4093))
- [Improve go_package_regex to prevent ReDoS attacks](gitlab-org/security/gitlab@45ccd851058bf319f7795e88afcb27c1440c24e9) ([merge request](gitlab-org/security/gitlab!4096))
- [Fix ReDoS in CI Interpolation](gitlab-org/security/gitlab@11be5651e849441813c022bc492e6549e9ed297d) ([merge request](gitlab-org/security/gitlab!4081))
- [Verify Asana access token when testing Asana integration](gitlab-org/security/gitlab@c35fb1ce0e58b8e90bc61b7d48949572fca6705c) ([merge request](gitlab-org/security/gitlab!4059))
## 17.0.1 (2024-05-21)
### Fixed (2 changes)
@ -880,6 +897,15 @@ entry.
- [Migrate self-managed custom roles to the instance-level roles](gitlab-org/gitlab@46ab664a1877f8b761c2b25e13e01561d56cf6fd) ([merge request](gitlab-org/gitlab!147829))
- [Feature cleanup flag wiki_content_background_job](gitlab-org/gitlab@c39a37db4a6112456052c11bf5fd1afa9c23bd6d) by @ivantedja ([merge request](gitlab-org/gitlab!148820))
## 16.11.4 (2024-06-11)
### Security (4 changes)
- [XSS and content injection raw XHTML files on IOS devices](gitlab-org/security/gitlab@5df472ac0deefe1e59ecfc0ffae7fa489cb6c9ab) ([merge request](gitlab-org/security/gitlab!4094))
- [Improve go_package_regex to prevent ReDoS attacks](gitlab-org/security/gitlab@d0b04b06f59e81bc57f6b33e26a0399b4b86ee80) ([merge request](gitlab-org/security/gitlab!4097))
- [Fix ReDoS in CI Interpolation](gitlab-org/security/gitlab@b013996a0612c9cc1e43bcd0be4b47d98eaf92f4) ([merge request](gitlab-org/security/gitlab!4082))
- [Verify Asana access token when testing Asana integration](gitlab-org/security/gitlab@6db47bd6ace0904869f56f035ff408855f3f4c9b) ([merge request](gitlab-org/security/gitlab!4060))
## 16.11.3 (2024-05-21)
### Fixed (2 changes)
@ -1534,6 +1560,19 @@ entry.
- [Finalize the backfill migration for onboarding status step url](gitlab-org/gitlab@f986c1b1cf00968ff106136893bfe68d47895c69) ([merge request](gitlab-org/gitlab!147278))
- [Remove ClusterRepositoryCache migration helper class](gitlab-org/gitlab@f71a7a94ce8d70d9d378ebc225b802b58f0ae006) ([merge request](gitlab-org/gitlab!147244))
## 16.10.7 (2024-06-11)
### Security (4 changes)
- [XSS and content injection raw XHTML files on IOS devices](gitlab-org/security/gitlab@bd477c1d019b3f758a38a4b7182b86f2d4668df4) ([merge request](gitlab-org/security/gitlab!4095))
- [Improve go_package_regex to prevent ReDoS attacks](gitlab-org/security/gitlab@56f50979b62a982e572d5695a87d19a36e0a9ef6) ([merge request](gitlab-org/security/gitlab!4098))
- [Fix ReDoS in CI Interpolation](gitlab-org/security/gitlab@045cf00aa56d545bdfb828c6131af89c37164946) ([merge request](gitlab-org/security/gitlab!4083))
- [Verify Asana access token when testing Asana integration](gitlab-org/security/gitlab@233b152dfea572b19b1803174c4604f4c0e04851) ([merge request](gitlab-org/security/gitlab!4061))
### Other (1 change)
- [Quarantine a flaky test](gitlab-org/security/gitlab@45242cdf1d36c89aff59e3ce7ee3d2e2f5b16471)
## 16.10.6 (2024-05-21)
### Fixed (1 change)

View File

@ -1 +1 @@
v17.1.0-rc9
8197a694087583b69b30c12f22eac6a9ed2b20eb

View File

@ -349,7 +349,7 @@ gem 'gon', '~> 6.4.0' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'request_store', '~> 1.5.1' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'base32', '~> 0.3.0' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'gitlab-license', '~> 2.4', feature_category: :shared
gem 'gitlab-license', '~> 2.5', feature_category: :shared
# Protect against bruteforcing
gem 'rack-attack', '~> 6.7.0' # rubocop:todo Gemfile/MissingFeatureCategory

View File

@ -2004,7 +2004,7 @@ DEPENDENCIES
gitlab-housekeeper!
gitlab-http!
gitlab-labkit (~> 0.36.0)
gitlab-license (~> 2.4)
gitlab-license (~> 2.5)
gitlab-mail_room (~> 0.0.24)
gitlab-markup (~> 1.9.0)
gitlab-net-dns (~> 0.9.2)

View File

@ -2,6 +2,7 @@ import $ from 'jquery';
import { flatten } from 'lodash';
import Vue from 'vue';
import { InternalEvents } from '~/tracking';
import { FIND_FILE_SHORTCUT_CLICK } from '~/tracking/constants';
import { Mousetrap, addStopCallback } from '~/lib/mousetrap';
import { getCookie, setCookie, parseBoolean } from '~/lib/utils/common_utils';
import { waitForElement } from '~/lib/utils/dom_utils';
@ -268,6 +269,9 @@ export default class Shortcuts {
}
static async focusSearchFile(e) {
if (e?.key) {
InternalEvents.trackEvent(FIND_FILE_SHORTCUT_CLICK);
}
e?.preventDefault();
document.querySelector('#super-sidebar-search')?.click();

View File

@ -23,7 +23,7 @@ export default {
UserAvatarLink,
IssueDueDate,
IssueTimeEstimate,
IssueCardWeight: () => import('ee_component/boards/components/issue_card_weight.vue'),
IssueWeight: () => import('ee_component/issues/components/issue_weight.vue'),
IssueIteration: () => import('ee_component/boards/components/issue_iteration.vue'),
IssuableBlockedIcon,
WorkItemTypeIcon,
@ -320,11 +320,7 @@ export default {
:closed-issues-weight="descendantWeightSum.closedIssues"
/>
<span v-if="!isEpicBoard">
<issue-card-weight
v-if="validIssueWeight(item)"
:weight="item.weight"
@click="filterByWeight(item.weight)"
/>
<issue-weight v-if="validIssueWeight(item)" :weight="item.weight" />
<issue-milestone
v-if="item.milestone"
data-testid="issue-milestone"

View File

@ -3,6 +3,5 @@ export default {
validIssueWeight() {
return false;
},
filterByWeight() {},
},
};

View File

@ -139,7 +139,7 @@ export default {
return `${this.char}${item.username}`;
case 'issue':
case 'merge_request':
return `${this.char}${item.iid}`;
return item.reference || `${this.char}${item.iid}`;
case 'snippet':
return `${this.char}${item.id}`;
case 'milestone':
@ -302,8 +302,13 @@ export default {
</span>
</span>
<span v-if="isIssue || isMergeRequest">
<gl-icon
v-if="item.icon_name"
class="gl-mr-2 gl-text-secondary"
:name="item.icon_name"
/>
<small
v-safe-html:[$options.safeHtmlConfig]="highlight(item.iid)"
v-safe-html:[$options.safeHtmlConfig]="highlight(item.reference || item.iid)"
class="gl-text-gray-500"
></small>
<span v-safe-html:[$options.safeHtmlConfig]="highlight(item.title)"></span>

View File

@ -1,5 +1,5 @@
<script>
import { GlLoadingIcon, GlAlert, GlEmptyState, GlSprintf } from '@gitlab/ui';
import { GlLoadingIcon, GlAlert, GlEmptyState, GlSprintf, GlIcon } from '@gitlab/ui';
import EmptyStateSvg from '@gitlab/svgs/dist/illustrations/Dependency-list-empty-state.svg?url';
import k8sLogsQuery from '~/environments/graphql/queries/k8s_logs.query.graphql';
import environmentClusterAgentQuery from '~/environments/graphql/queries/environment_cluster_agent.query.graphql';
@ -15,6 +15,7 @@ export default {
GlAlert,
GlEmptyState,
GlSprintf,
GlIcon,
},
inject: ['kasTunnelUrl', 'projectPath'],
props: {
@ -109,12 +110,28 @@ export default {
? this.$options.i18n.emptyStateTitleForContainer
: this.$options.i18n.emptyStateTitleForPod;
},
headerData() {
const data = [
{ icon: 'namespace', label: this.$options.i18n.namespace, value: this.namespace },
{ icon: 'pod', label: this.$options.i18n.pod, value: this.podName },
];
const containerData = {
icon: 'container-image',
label: this.$options.i18n.container,
value: this.containerName,
};
if (this.containerName) data.push(containerData);
return data;
},
},
i18n: {
emptyStateTitleForPod: s__('KubernetesLogs|No logs available for pod %{podName}'),
emptyStateTitleForContainer: s__(
'KubernetesLogs|No logs available for container %{containerName} of pod %{podName}',
),
pod: s__('KubernetesLogs|Pod'),
container: s__('KubernetesLogs|Container'),
namespace: s__('KubernetesLogs|Namespace'),
},
EmptyStateSvg,
};
@ -123,11 +140,16 @@ export default {
<div>
<gl-alert v-if="error" variant="danger" :dismissible="false">{{ error }}</gl-alert>
<gl-loading-icon v-if="isLoading" />
<logs-viewer
v-else-if="logLines"
:log-lines="logLines"
:highlighted-line="highlightedLineHash"
/>
<logs-viewer v-else-if="logLines" :log-lines="logLines" :highlighted-line="highlightedLineHash"
><template #header-details
><div class="gl-p-3 gl-ml-auto">
<span v-for="(item, index) of headerData" :key="index" class="gl-mr-4">
<gl-icon :name="item.icon" class="gl-mr-2" />{{ item.label }}: {{ item.value }}</span
>
</div>
</template>
</logs-viewer>
<gl-empty-state v-else :svg-path="$options.EmptyStateSvg">
<template #title>
<h3>

View File

@ -23,7 +23,7 @@ export default {
GlIcon,
GlLink,
GlTooltip,
IssueWeight: () => import('ee_component/boards/components/issue_card_weight.vue'),
IssueWeight: () => import('ee_component/issues/components/issue_weight.vue'),
IssueDueDate,
GlButton,
WorkItemDetailModal,
@ -203,11 +203,7 @@ export default {
<!-- Flex order for slots is defined in the parent component: e.g. related_issues_block.vue -->
<span v-if="weight > 0" class="order-md-1">
<issue-weight
:weight="weight"
class="item-weight gl-display-flex gl-align-items-center"
tag-name="span"
/>
<issue-weight :weight="weight" class="item-weight gl-flex gl-items-center" />
</span>
<span v-if="dueDate" class="order-md-1">

View File

@ -16,7 +16,7 @@ export default {
GlSkeletonLoader,
IssueDueDate,
IssueMilestone,
IssueWeight: () => import('ee_component/boards/components/issue_card_weight.vue'),
IssueWeight: () => import('ee_component/issues/components/issue_weight.vue'),
StatusBadge,
WorkItemTypeIcon,
},
@ -114,12 +114,7 @@ export default {
class="gl-mr-4"
css-class="gl-display-flex gl-whitespace-nowrap"
/>
<issue-weight
v-if="issue.weight"
:weight="issue.weight"
tag-name="span"
class="gl-display-flex gl-mr-4"
/>
<issue-weight v-if="issue.weight" :weight="issue.weight" class="gl-flex gl-mr-4" />
<issue-milestone
v-if="issue.milestone"
:milestone="issue.milestone"

View File

@ -1,8 +1,13 @@
<!-- eslint-disable vue/multi-word-component-names -->
<script>
import { GlFormGroup, GlFormInput } from '@gitlab/ui';
import updateMixin from '../../mixins/update';
export default {
components: {
GlFormGroup,
GlFormInput,
},
mixins: [updateMixin],
props: {
value: {
@ -14,20 +19,24 @@ export default {
</script>
<template>
<fieldset>
<label class="sr-only" for="issuable-title">{{ __('Title') }}</label>
<input
<gl-form-group
:label="__('Title')"
label-for="issuable-title"
label-class="gl-sr-only"
class="gl-mb-0"
>
<gl-form-input
id="issuable-title"
ref="input"
:value="value"
class="form-control gl-border-gray-200"
class="form-control"
dir="auto"
type="text"
:placeholder="__('Title')"
:aria-label="__('Title')"
@input="$emit('input', $event.target.value)"
@keydown.meta.enter="updateIssuable"
@keydown.ctrl.enter="updateIssuable"
@input="(val) => $emit('input', val)"
@keydown.meta.enter.native="updateIssuable"
@keydown.ctrl.enter.native="updateIssuable"
/>
</fieldset>
</gl-form-group>
</template>

View File

@ -164,7 +164,7 @@ export default {
</script>
<template>
<form data-testid="issuable-form">
<form data-testid="issuable-form" class="gl-mt-1">
<locked-warning v-if="showLockedWarning" :issuable-type="issuableType" />
<gl-alert
v-if="showOutdatedDescriptionWarning"

View File

@ -333,7 +333,7 @@ export default {
<template>
<div
class="detail-page-header-actions gl-display-flex gl-align-self-start gl-sm-gap-3 gl-w-full gl-md-w-auto"
class="detail-page-header-actions gl-flex gl-self-start sm:gl-gap-3 gl-w-full md:gl-w-auto gl-mt-1"
>
<div class="md:!gl-hidden gl-w-full">
<gl-disclosure-dropdown

View File

@ -87,7 +87,7 @@ export default {
>
<gl-badge :variant="statusVariant">
<gl-icon :name="statusIcon" />
<span class="gl-hidden sm:gl-block gl-ml-2">{{ statusText }}</span>
<span class="gl-block gl-ml-2">{{ statusText }}</span>
</gl-badge>
<confidentiality-badge
v-if="isConfidential"

View File

@ -53,16 +53,14 @@ export default {
</script>
<template>
<div
class="gl-display-flex gl-align-items-flex-start gl-flex-direction-column gl-md-flex-direction-row gl-gap-3 gl-pt-3"
>
<div class="gl-flex gl-items-start gl-flex-col md:gl-flex-row gl-gap-3 gl-pt-3">
<h1
v-safe-html="titleHtml"
:class="{
'issue-realtime-pre-pulse': preAnimation,
'issue-realtime-trigger-pulse': pulseAnimation,
}"
class="title gl-font-size-h-display gl-m-0!"
class="title gl-heading-1 !gl-m-0"
data-testid="issue-title"
dir="auto"
></h1>

View File

@ -129,7 +129,7 @@ export default {
<td v-if="error" class="js-error-lazy-load-diff diff-loading-error-block">
{{ __('Unable to load the diff') }}
<gl-button
class="btn-link-retry gl-font-regular js-toggle-lazy-diff-retry-button"
class="gl-font-regular js-toggle-lazy-diff-retry-button"
@click="fetchDiff"
>
{{ __('Try again') }}

View File

@ -14,7 +14,13 @@ export default {
WikiEditForm,
WikiAlert,
},
inject: ['isEditingPath', 'isPageHistorical', 'wikiUrl', 'historyUrl', 'error'],
inject: {
isEditingPath: { default: null },
isPageHistorical: { default: null },
wikiUrl: { default: null },
historyUrl: { default: null },
error: { default: null },
},
i18n: {
alertText: s__('WikiHistoricalPage|This is an old version of this page.'),
alertPrimaryButton: s__('WikiHistoricalPage|Go to most recent version'),

View File

@ -359,7 +359,7 @@ export default {
ref="form"
:action="formAction"
method="post"
class="wiki-form common-note-form js-quick-submit gl-mt-4"
class="wiki-form common-note-form js-quick-submit"
:class="{ 'gl-mt-5': !isEditingPath }"
@submit="handleFormSubmit"
@input="isFormDirty = true"

View File

@ -17,18 +17,18 @@ export default {
directives: {
GlTooltip: GlTooltipDirective,
},
inject: [
'pageHeading',
'showEditButton',
'isPageTemplate',
'editButtonUrl',
'lastVersion',
'pageVersion',
'authorUrl',
'isEditingPath',
'wikiUrl',
'pagePersisted',
],
inject: {
pageHeading: { default: null },
showEditButton: { default: null },
isPageTemplate: { default: null },
editButtonUrl: { default: null },
lastVersion: { default: null },
pageVersion: { default: null },
authorUrl: { default: null },
isEditingPath: { default: null },
wikiUrl: { default: null },
pagePersisted: { default: null },
},
computed: {
pageHeadingComputed() {
let { pageHeading } = this;
@ -113,22 +113,20 @@ export default {
/>
<wiki-more-dropdown />
</template>
<template v-if="lastVersion" #description>
<div class="wiki-last-version gl-leading-20" data-testid="wiki-page-last-version">
<gl-sprintf :message="$options.i18n.lastEdited">
<template #author>
<gl-link :href="authorUrl" class="gl-text-black-normal gl-font-bold">{{
pageVersion.author_name
}}</gl-link>
</template>
<template #timeago>
<time-ago :time="pageVersion.authored_date" target="wiki-last-version" />
</template>
</gl-sprintf>
</div>
</template>
</page-heading>
<div
v-if="lastVersion"
class="wiki-last-version gl-leading-20 gl-text-secondary gl-mt-3 gl-mb-5"
data-testid="wiki-page-last-version"
>
<gl-sprintf :message="$options.i18n.lastEdited">
<template #author>
<gl-link :href="authorUrl" class="gl-text-black-normal gl-font-bold">{{
pageVersion.commit.author_name
}}</gl-link>
</template>
<template #timeago>
<time-ago :time="pageVersion.commit.authored_date" target="wiki-last-version" />
</template>
</gl-sprintf>
</div>
</div>
</template>

View File

@ -30,12 +30,6 @@ const mountWikiEditApp = () => {
provide: {
isEditingPath: true,
pageHeading,
contentApi: null,
showEditButton: null,
editButtonUrl: null,
lastVersion: null,
pageVersion: null,
authorUrl: null,
pageInfo: convertObjectPropsToCamelCase(JSON.parse(pageInfo)),
isPageTemplate: parseBoolean(isPageTemplate),
isPageHistorical: false,
@ -43,7 +37,6 @@ const mountWikiEditApp = () => {
csrfToken: csrf.token,
templates: JSON.parse(templates),
drawioUrl: gon.diagramsnet_url,
historyUrl: '',
wikiUrl,
pagePersisted: parseBoolean(pagePersisted),
error,

View File

@ -64,7 +64,6 @@ const mountWikiContentApp = () => {
templates: JSON.parse(templates),
drawioUrl: gon.diagramsnet_url,
pagePersisted: parseBoolean(pagePersisted),
error: null,
},
render(createElement) {
return createElement(WikiContentApp);

View File

@ -177,14 +177,9 @@ export default {
:items="getAddRuleItems"
size="small"
/>
<gl-button
v-else
v-gl-modal="$options.modalId"
size="small"
class="gl-ml-3"
data-testid="add-branch-rule-button"
>{{ $options.i18n.addBranchRule }}</gl-button
>
<gl-button v-else v-gl-modal="$options.modalId" size="small" class="gl-ml-3"
>{{ $options.i18n.addBranchRule }}
</gl-button>
</template>
<ul class="content-list">
<branch-rule

View File

@ -16,6 +16,8 @@ import {
PROJECT_FILES_GO_TO_PERMALINK,
} from '~/behaviors/shortcuts/keybindings';
import { sanitize } from '~/lib/dompurify';
import { InternalEvents } from '~/tracking';
import { FIND_FILE_BUTTON_CLICK } from '~/tracking/constants';
import { updateElementsVisibility } from '../utils/dom';
import blobControlsQuery from '../queries/blob_controls.query.graphql';
@ -146,6 +148,7 @@ export default {
);
},
handleFindFile() {
InternalEvents.trackEvent(FIND_FILE_BUTTON_CLICK);
Shortcuts.focusSearchFile();
},
},

View File

@ -1,21 +1,12 @@
<script>
import { GlToggle, GlLink, GlAlert, GlLoadingIcon } from '@gitlab/ui';
import { GlToggle, GlAlert, GlLoadingIcon } from '@gitlab/ui';
import SetContainerScanningForRegistry from '~/security_configuration/graphql/set_container_scanning_for_registry.graphql';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { __, s__ } from '~/locale';
import { helpPagePath } from '~/helpers/help_page_helper';
export default {
components: { GlToggle, GlLink, GlAlert, GlLoadingIcon },
components: { GlToggle, GlAlert, GlLoadingIcon },
mixins: [glFeatureFlagsMixin()],
inject: ['containerScanningForRegistryEnabled', 'projectFullPath'],
i18n: {
title: s__('CVS|Continuous Container Scanning'),
description: s__(
'CVS|Scan for vulnerabilities when a container image or the advisory database is updated.',
),
learnMore: __('Learn more'),
},
props: {
feature: {
type: Object,
@ -54,7 +45,7 @@ export default {
mutation: SetContainerScanningForRegistry,
variables: {
input: {
projectPath: this.projectFullPath,
namespacePath: this.projectFullPath,
enable: checked,
},
},
@ -72,21 +63,16 @@ export default {
this.toggleValue = oldValue;
this.reportError(error);
} finally {
this.$emit('overrideStatus', this.toggleValue);
this.isRunningMutation = false;
}
},
},
CVSHelpPagePath: helpPagePath(
'user/application_security/continuous_vulnerability_scanning/index',
),
};
</script>
<template>
<div v-if="glFeatures.containerScanningForRegistry">
<h4 class="gl-font-base gl-mt-6">
{{ $options.i18n.title }}
</h4>
<div v-if="glFeatures.containerScanningForRegistryFlag">
<gl-alert
v-if="errorMessage"
class="gl-mb-5 gl-mt-2"
@ -95,9 +81,11 @@ export default {
>{{ errorMessage }}</gl-alert
>
<br />
<div class="gl-display-flex gl-align-items-center">
<gl-toggle
:disabled="!isFeatureConfigured || isRunningMutation"
:disabled="isRunningMutation"
:value="toggleValue"
:label="s__('CVS|Toggle CVS')"
label-position="hidden"
@ -105,13 +93,5 @@ export default {
/>
<gl-loading-icon v-if="isRunningMutation" inline class="gl-ml-3" />
</div>
<p class="gl-mb-0 gl-mt-5">
{{ $options.i18n.description }}
<gl-link :href="$options.CVSHelpPagePath" target="_blank">{{
$options.i18n.learnMore
}}</gl-link>
<br />
</p>
</div>
</template>

View File

@ -23,12 +23,19 @@ export default {
required: true,
},
},
data() {
return {
overrideStatus: null,
};
},
computed: {
available() {
return this.feature.available;
},
enabled() {
return this.available && this.feature.configured;
return !(this.overrideStatus === null)
? this.overrideStatus
: this.available && this.feature.configured;
},
shortName() {
return this.feature.shortName ?? this.feature.name;
@ -100,6 +107,9 @@ export default {
onError(message) {
this.$emit('error', message);
},
onOverrideStatus(status) {
this.overrideStatus = status;
},
},
i18n: {
enabled: s__('SecurityConfiguration|Enabled'),
@ -219,6 +229,11 @@ export default {
</gl-button>
</div>
<component :is="feature.slotComponent" v-if="feature.slotComponent" :feature="feature" />
<component
:is="feature.slotComponent"
v-if="feature.slotComponent"
:feature="feature"
@overrideStatus="onOverrideStatus"
/>
</gl-card>
</template>

View File

@ -8,14 +8,14 @@ import {
REPORT_TYPE_SAST,
REPORT_TYPE_SAST_IAC,
REPORT_TYPE_SECRET_DETECTION,
REPORT_TYPE_CONTAINER_SCANNING,
REPORT_TYPE_CONTAINER_SCANNING_FOR_REGISTRY,
} from '~/vue_shared/security_reports/constants';
import configureSastMutation from './graphql/configure_sast.mutation.graphql';
import configureSastIacMutation from './graphql/configure_iac.mutation.graphql';
import configureSecretDetectionMutation from './graphql/configure_secret_detection.mutation.graphql';
import ContinuousContainerRegistryScan from './components/continous_container_registry_scan.vue';
import ContainerScanningForRegistry from './components/container_scanning_for_registry.vue';
/**
* Translations for Security Configuration Page
@ -42,6 +42,8 @@ export const DEPENDENCY_SCANNING_NAME = __('Dependency Scanning');
export const CONTAINER_SCANNING_NAME = __('Container Scanning');
export const CONTAINER_SCANNING_FOR_REGISTRY_NAME = __('Container Scanning For Registry');
export const COVERAGE_FUZZING_NAME = __('Coverage Fuzzing');
export const CORPUS_MANAGEMENT_NAME = __('Corpus Management');
@ -60,6 +62,7 @@ export const SCANNER_NAMES_MAP = {
DAST: DAST_SHORT_NAME,
API_FUZZING: API_FUZZING_NAME,
CONTAINER_SCANNING: CONTAINER_SCANNING_NAME,
CONTAINER_SCANNING_FOR_REGISTRY: CONTAINER_SCANNING_FOR_REGISTRY_NAME,
COVERAGE_FUZZING: COVERAGE_FUZZING_NAME,
SECRET_DETECTION: SECRET_DETECTION_NAME,
DEPENDENCY_SCANNING: DEPENDENCY_SCANNING_NAME,
@ -70,8 +73,8 @@ export const SCANNER_NAMES_MAP = {
};
export const securityFeatures = {
[REPORT_TYPE_CONTAINER_SCANNING]: {
slotComponent: ContinuousContainerRegistryScan,
[REPORT_TYPE_CONTAINER_SCANNING_FOR_REGISTRY]: {
slotComponent: ContainerScanningForRegistry,
},
};

View File

@ -33,9 +33,14 @@ export const GOOGLE_ANALYTICS_ID_COOKIE_NAME = '_ga';
export const SERVICE_PING_SCHEMA = 'iglu:com.gitlab/gitlab_service_ping/jsonschema/1-0-1';
export const ALLOWED_ADDITIONAL_PROPERTIES = ['label', 'property', 'value'];
// events constants
export const SERVICE_PING_SECURITY_CONFIGURATION_THREAT_MANAGEMENT_VISIT =
'users_visiting_security_configuration_threat_management';
export const SERVICE_PING_PIPELINE_SECURITY_VISIT = 'users_visiting_pipeline_security';
export const ALLOWED_ADDITIONAL_PROPERTIES = ['label', 'property', 'value'];
export const FIND_FILE_BUTTON_CLICK = 'click_find_file_button_on_repository_pages';
export const FIND_FILE_SHORTCUT_CLICK = 'click_go_to_file_shortcut';

View File

@ -266,7 +266,7 @@ export default {
};
</script>
<template>
<div v-if="approvals" class="js-mr-approvals mr-section-container mr-widget-workflow">
<div v-if="approvals" class="js-mr-approvals mr-section-container">
<state-container
:is-loading="isLoading"
:mr="mr"
@ -282,7 +282,7 @@ export default {
<template v-else>
<div class="gl-display-flex gl-flex-direction-column">
<div
class="gl-display-flex gl-flex-direction-column gl-sm-flex-direction-row gl-gap-3 gl-align-items-flex-start"
class="gl-display-flex gl-flex-direction-column gl-sm-flex-direction-row gl-gap-3 gl-align-items-baseline"
>
<div v-if="requireSamlAuthToApprove && showApprove">
<gl-form

View File

@ -138,7 +138,7 @@ export default {
<template>
<div
class="gl-display-flex gl-flex-wrap gl-align-items-center gl-gap-2"
class="gl-display-flex gl-flex-wrap gl-align-items-baseline gl-gap-2"
data-testid="approvals-summary-content"
>
<span class="gl-font-bold">{{ approvalLeftMessage }}</span>

View File

@ -10,14 +10,14 @@ export default {
</script>
<template>
<div class="gl-mt-3">
<div class="mr-widget-heading p-3">
<div class="gl-mt-5">
<div class="mr-section-container gl-p-4">
<gl-skeleton-loader :width="577" :height="12">
<rect width="86" height="12" rx="2" />
<rect x="96" width="300" height="12" rx="2" />
</gl-skeleton-loader>
</div>
<div class="mr-widget-heading mr-widget-workflow p-3">
<div class="mr-section-container gl-p-4">
<gl-skeleton-loader :width="577" :height="72">
<rect width="120" height="12" rx="2" />
<rect y="20" width="300" height="12" rx="2" />

View File

@ -161,7 +161,7 @@ export default {
</script>
<template>
<div class="gl-rounded-0!">
<div>
<state-container
:is-loading="isLoading"
:status="statusIcon"

View File

@ -1,5 +1,5 @@
<template>
<div class="mr-section-container mr-widget-workflow">
<div class="mr-section-container">
<div class="mr-widget-section">
<div class="mr-widget-content"><slot name="default"></slot></div>
<slot name="footer"></slot>

View File

@ -1,42 +0,0 @@
<script>
export default {
data() {
return {
hasChildren: false,
};
},
mounted() {
const setHasChildren = () => {
this.hasChildren = Boolean(this.$el.innerText.trim());
};
// Set initial.
setHasChildren();
if (!this.hasChildren) {
// Observe children changed.
this.observer = new MutationObserver(() => {
setHasChildren();
if (this.hasChildren) {
this.observer.disconnect();
this.observer = undefined;
}
});
this.observer.observe(this.$el, { childList: true, subtree: true });
}
},
beforeUnmount() {
if (this.observer) {
this.observer.disconnect();
}
},
};
</script>
<template>
<div v-show="hasChildren" class="mr-section-container mr-widget-workflow">
<slot></slot>
</div>
</template>

View File

@ -62,7 +62,7 @@ export default {
<div class="mr-widget-body media">
<status-icon :show-disabled-button="true" status="failed" />
<div class="media-body space-children">
<div class="media-body">
<span class="js-branch-text" data-testid="widget-content">
<span class="gl-font-bold">
<gl-sprintf :message="warning">

View File

@ -56,7 +56,7 @@ export default {
role="region"
:aria-label="__('Merge request reports')"
data-testid="mr-widget-app"
class="mr-widget-section"
class="mr-section-container"
>
<component
:is="widget"
@ -64,6 +64,7 @@ export default {
:key="widget.name || index"
:mr="mr"
class="mr-widget-section"
:class="{ 'gl-border-t': index > 0 }"
/>
</section>
</template>

View File

@ -393,7 +393,7 @@ export default {
</div>
<div
v-if="!isCollapsed || contentError"
class="gl-relative gl-bg-gray-10"
class="gl-relative gl-bg-gray-10 gl-border-t"
data-testid="widget-extension-collapsed-section"
>
<div v-if="isLoadingExpandedContent" class="report-block-container gl-text-center">

View File

@ -44,7 +44,6 @@ import eventHub from './event_hub';
import mergeRequestQueryVariablesMixin from './mixins/merge_request_query_variables';
import getStateQuery from './queries/get_state.query.graphql';
import getStateSubscription from './queries/get_state.subscription.graphql';
import ReportWidgetContainer from './components/report_widget_container.vue';
import MrWidgetReadyToMerge from './components/states/new_ready_to_merge.vue';
import MergeChecks from './components/merge_checks.vue';
@ -78,7 +77,6 @@ export default {
SourceBranchRemovalStatus,
MrWidgetApprovals,
ReadyToMerge: ReadyToMergeState,
ReportWidgetContainer,
MergeChecks,
},
apollo: {
@ -510,17 +508,13 @@ export default {
</script>
<template>
<div v-if="!loading" id="widget-state" class="mr-state-widget gl-mt-5">
<header
v-if="shouldRenderCollaborationStatus"
class="gl-rounded-base gl-border-solid gl-border-1 gl-border-gray-100 gl-overflow-hidden mr-widget-workflow gl-mt-0!"
>
<mr-widget-alert-message v-if="shouldRenderCollaborationStatus" type="info">
<header v-if="shouldRenderCollaborationStatus" class="mr-section-container gl-overflow-hidden">
<mr-widget-alert-message type="info">
{{ s__('mrWidget|Members who can merge are allowed to add commits.') }}
</mr-widget-alert-message>
</header>
<mr-widget-suggest-pipeline
v-if="shouldSuggestPipelines"
class="mr-widget-workflow"
:pipeline-path="mr.mergeRequestAddCiConfigPath"
:pipeline-svg-path="mr.pipelinesEmptySvgPath"
:human-access="formattedHumanAccess"
@ -540,16 +534,15 @@ export default {
data-testid="pipeline-container"
/>
<mr-widget-approvals v-if="shouldRenderApprovals" :mr="mr" :service="service" />
<report-widget-container>
<widget-container :mr="mr" />
</report-widget-container>
<div class="mr-section-container mr-widget-workflow">
<div v-if="hasAlerts" class="gl-overflow-hidden mr-widget-alert-container">
<widget-container :mr="mr" />
<div class="mr-section-container">
<template v-if="hasAlerts">
<mr-widget-alert-message
v-if="hasMergeError"
type="danger"
dismissible
data-testid="merge-error"
class="mr-widget-section"
>
<span v-safe-html="mergeError"></span>
</mr-widget-alert-message>
@ -557,6 +550,7 @@ export default {
v-if="showMergePipelineForkWarning"
type="warning"
:help-path="mr.mergeRequestPipelinesHelpPath"
class="mr-widget-section"
data-testid="merge-pipeline-fork-warning"
>
{{
@ -568,7 +562,7 @@ export default {
{{ __('Learn more') }}
</template>
</mr-widget-alert-message>
</div>
</template>
<div class="mr-widget-section" data-testid="mr-widget-content">
<template v-if="mergeBlockedComponentVisible">
@ -586,9 +580,9 @@ export default {
</div>
<mr-widget-pipeline-container
v-if="shouldRenderMergedPipeline"
class="js-post-merge-pipeline mr-widget-workflow"
class="js-post-merge-pipeline"
:mr="mr"
:is-post-merge="true"
is-post-merge
data-testid="merged-pipeline-container"
/>
</div>

View File

@ -41,13 +41,14 @@ export default {
</script>
<template>
<div class="gl-sticky gl-bg-white" :class="headerTopClass">
<div class="gl-border gl-flex gl-flex-row-reverse">
<div class="gl-border gl-flex gl-flex-wrap gl-items-center">
<gl-button
class="gl-m-3"
:icon="toggleFullScreenIcon"
:title="toggleFullScreenText"
:aria-label="toggleFullScreenText"
@click="$emit('toggleFullScreen')"
icon="scroll_down"
:selected="isFollowing"
:title="$options.i18n.scrollToBottom"
:aria-label="$options.i18n.scrollToBottom"
@click="$emit('scrollToBottom')"
/>
<gl-button
class="gl-m-3"
@ -58,12 +59,12 @@ export default {
/>
<gl-button
class="gl-m-3"
icon="scroll_down"
:selected="isFollowing"
:title="$options.i18n.scrollToBottom"
:aria-label="$options.i18n.scrollToBottom"
@click="$emit('scrollToBottom')"
:icon="toggleFullScreenIcon"
:title="toggleFullScreenText"
:aria-label="toggleFullScreenText"
@click="$emit('toggleFullScreen')"
/>
<slot></slot>
</div>
</div>
</template>

View File

@ -113,7 +113,8 @@ export default {
@toggleFullScreen="toggleFullScreen"
@scrollToTop="onScrollToTop"
@scrollToBottom="onScrollToBottom"
/>
><slot name="header-details"></slot>
</logs-top-bar>
<code class="gl-block gl-bg-black gl-text-base gl-pt-3">
<log-line
v-for="logLine in logLines"

View File

@ -166,7 +166,7 @@ export default {
<div class="detail-page-header-body gl-flex-wrap gl-gap-x-2">
<gl-badge :variant="badgeVariant" data-testid="issue-state-badge">
<gl-icon v-if="statusIcon" :name="statusIcon" :class="statusIconClass" />
<span class="gl-hidden sm:gl-block" :class="{ 'gl-ml-2': statusIcon }">
<span class="gl-block" :class="{ 'gl-ml-2': statusIcon }">
<slot name="status-badge">{{ badgeText }}</slot>
</span>
</gl-badge>

View File

@ -24,6 +24,7 @@ export const REPORT_TYPE_BREACH_AND_ATTACK_SIMULATION = 'breach_and_attack_simul
export const REPORT_TYPE_SECRET_DETECTION = 'secret_detection';
export const REPORT_TYPE_DEPENDENCY_SCANNING = 'dependency_scanning';
export const REPORT_TYPE_CONTAINER_SCANNING = 'container_scanning';
export const REPORT_TYPE_CONTAINER_SCANNING_FOR_REGISTRY = 'container_scanning_for_registry';
export const REPORT_TYPE_CLUSTER_IMAGE_SCANNING = 'cluster_image_scanning';
export const REPORT_TYPE_COVERAGE_FUZZING = 'coverage_fuzzing';
export const REPORT_TYPE_CORPUS_MANAGEMENT = 'corpus_management';

View File

@ -37,6 +37,16 @@
> .gl-icon {
margin-left: 0;
// Issuables status adjustments
// Adjust left alignment for issuables
// status open & closed
// We have to rely on the testid
// until Gitlab UI MR !3307 is merged
&[data-testid="issue-open-m-icon"],
&[data-testid="issue-close-icon"] {
@apply -gl-ml-2;
}
}
}

View File

@ -11,18 +11,6 @@ $comparison-empty-state-height: 62px;
}
}
.space-children {
@include clearfix;
> * {
float: left;
}
> *:not(:first-child) {
margin-left: 10px;
}
}
.media-section {
@include media-breakpoint-down(md) {
align-items: flex-start;
@ -267,23 +255,6 @@ $comparison-empty-state-height: 62px;
margin-right: -5px;
}
// Hack alert: we've rewritten `btn` class in a way that
// we've broken it and it is not possible to use with `btn-link`
// which causes a blank button when it's disabled and hovering
// The css in here is the boostrap one
.btn-link-retry {
&[disabled] {
cursor: not-allowed;
box-shadow: none;
opacity: 0.65;
&:hover {
color: var(--gray-500, $gray-500);
text-decoration: none;
}
}
}
.merge-request-details .file-finder-overlay.diff-file-finder {
position: fixed;
z-index: 99999;

View File

@ -1,8 +1,5 @@
@import 'mixins_and_variables_and_functions';
$mr-widget-min-height: 69px;
$tabs-holder-z-index: 250;
.compare-versions-container {
min-width: 0;
}
@ -416,10 +413,6 @@ $tabs-holder-z-index: 250;
background-color: var(--gray-50, $gray-50);
}
.mr-widget-body-loading svg {
vertical-align: middle;
}
.mr-info-list {
clear: left;
position: relative;
@ -469,7 +462,24 @@ $tabs-holder-z-index: 250;
border-radius: $gl-border-radius-base;
background: var(--white, $white);
&:not(:first-child) {
@apply gl-mt-5;
}
&:empty {
display: none;
}
.gl-skeleton-loader {
display: block;
}
> .mr-widget-section {
&:first-child {
border-top-left-radius: $gl-border-radius-base-inner;
border-top-right-radius: $gl-border-radius-base-inner;
}
> :last-child,
.deploy-heading:last-child {
border-bottom-left-radius: $gl-border-radius-base-inner;
@ -482,45 +492,6 @@ $tabs-holder-z-index: 250;
}
}
.mr-source-target {
flex-wrap: wrap;
padding: $gl-padding;
background: var(--white, $white);
min-height: $mr-widget-min-height;
@include media-breakpoint-up(md) {
align-items: center;
}
.git-merge-container {
justify-content: space-between;
flex: 1;
flex-direction: row;
align-items: center;
@include media-breakpoint-down(md) {
flex-direction: column;
align-items: stretch;
.branch-actions {
margin-top: 16px;
}
}
@include media-breakpoint-up(lg) {
.branch-actions {
align-self: center;
margin-left: $gl-padding;
white-space: nowrap;
}
}
}
.diverged-commits-count {
color: var(--gray-500, $gl-text-color-secondary);
}
}
.mr-state-widget {
color: var(--gl-text-color, $gl-text-color);
@ -528,26 +499,10 @@ $tabs-holder-z-index: 250;
border-radius: $gl-border-radius-base;
}
.mr-widget-section:not(:first-child) > div,
.mr-widget-section:not(:first-child) > section,
.mr-widget-section .mr-widget-section > div:not(:first-child) {
border-top: solid 1px var(--border-color, $border-color);
// Avoid two lines being rendered
// instead of exessively adressing those
// edge cases we can use this as a boring
// solution
margin-top: -1px;
}
.mr-widget-alert-container + .mr-widget-section {
border-top: 0;
}
.mr-fast-forward-message {
padding-left: $gl-spacing-scale-9;
padding-bottom: $gl-padding;
}
.commits-list {
> li {
padding: $gl-padding;
@ -778,14 +733,6 @@ $tabs-holder-z-index: 250;
}
}
.mr-widget-alert-container {
border-radius: $gl-border-radius-base-inner $gl-border-radius-base-inner 0 0;
.gl-alert:not(:last-child) {
margin-bottom: 1px;
}
}
.mr-widget-body,
.mr-widget-content {
padding: $gl-padding-12 $gl-padding;
@ -810,11 +757,6 @@ $tabs-holder-z-index: 250;
}
}
.mr-widget-grouped-section .report-block-container {
border-bottom-left-radius: $gl-border-radius-base;
border-bottom-right-radius: $gl-border-radius-base;
}
.mr-widget-extension {
border-top: 1px solid var(--border-color, $border-color);
background-color: var(--gray-10, $gray-10);
@ -859,36 +801,12 @@ $tabs-holder-z-index: 250;
transform: translate(-50%, -50%);
}
.mr-widget-heading {
position: relative;
border: 1px solid var(--border-color, $border-color);
border-radius: $gl-border-radius-base;
background: var(--white, $white);
.gl-skeleton-loader {
display: block;
}
}
.mr-widget-info {
padding-left: $gl-padding;
padding-right: $gl-padding;
}
.mr-widget-section {
.code-text {
flex: 1;
}
}
.mr-widget-workflow {
position: relative;
&:not(:first-child) {
margin-top: $gl-padding;
}
}
.mr-version-controls {
color: var(--gl-text-color, $gl-text-color);
@ -939,10 +857,6 @@ $tabs-holder-z-index: 250;
height: 0;
}
.attention-request-sidebar-popover {
z-index: 999;
}
.merge-request-overview {
@include media-breakpoint-up(lg) {
display: grid;

View File

@ -1,12 +1,5 @@
@import 'mixins_and_variables_and_functions';
.mr-widget-grouped-section {
.report-block-container {
max-height: 170px;
overflow: auto;
}
}
.report-block-container {
border-top: 1px solid var(--border-color, $border-color);
padding: $gl-padding - 2;

View File

@ -61,8 +61,24 @@ module WorkhorseHelper
end
def content_disposition_for_blob(blob, inline)
return 'inline' if inline
return inline_content_disposition(blob) if inline
attachment_content_disposition(blob)
end
def inline_content_disposition(blob)
# We need to validate the .xhtml extension to avoid content sniffing
# since some specific browsers ignore the Content-Disposition header.
#
# Using `split` instead of `File.extname` to handle files with multiple extensions
#
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/458229
filename = blob.name.ends_with?('.xhtml') ? blob.name.split('.')[0] : nil
ActionDispatch::Http::ContentDisposition.format(disposition: 'inline', filename: filename)
end
def attachment_content_disposition(blob)
ActionDispatch::Http::ContentDisposition.format(disposition: 'attachment', filename: blob.name)
end
end

View File

@ -774,9 +774,9 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord
attr_encrypted :telesign_api_key, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false)
attr_encrypted :product_analytics_configurator_connection_string, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false)
attr_encrypted :openai_api_key, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false)
attr_encrypted :anthropic_api_key, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false)
attr_encrypted :vertex_ai_credentials, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false)
attr_encrypted :vertex_ai_access_token, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false)
attr_encrypted :anthropic_api_key, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) # Deprecated. See https://gitlab.com/gitlab-org/gitlab/-/issues/466161
attr_encrypted :vertex_ai_credentials, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) # Deprecated. See https://gitlab.com/gitlab-org/gitlab/-/issues/466161
attr_encrypted :vertex_ai_access_token, encryption_options_base_32_aes_256_gcm.merge(encode: false, encode_iv: false) # Deprecated. See https://gitlab.com/gitlab-org/gitlab/-/issues/466161
# Restricting the validation to `on: :update` only to avoid cyclical dependencies with
# License <--> ApplicationSetting. This method calls a license check when we create

View File

@ -13,6 +13,9 @@ module Ci
belongs_to :group, class_name: '::Group', foreign_key: :namespace_id
validates :runner_id, uniqueness: { scope: :namespace_id }
# NOTE: `on:` hook can be removed the milestone after https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155761
# is merged
validates :namespace, presence: true, on: [:create, :update]
validate :group_runner_type
scope :for_runner, ->(runner_id) { where(runner_id: runner_id) }

View File

@ -15,6 +15,10 @@ module Ci
::Ci::Runner.belonging_to_project(project_id).recent
end
validates :runner, presence: true
validates :runner_id, uniqueness: { scope: :project_id }
# NOTE: `on:` hook can be removed the milestone after https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155760
# is merged
validates :project, presence: true, on: [:create, :update]
end
end

View File

@ -2,6 +2,7 @@
module Integrations
class Asana < Integration
PERSONAL_ACCESS_TOKEN_TEST_URL = 'https://app.asana.com/api/1.0/users/me'
TASK_URL_TEMPLATE = 'https://app.asana.com/api/1.0/tasks/%{task_gid}'
STORY_URL_TEMPLATE = 'https://app.asana.com/api/1.0/tasks/%{task_gid}/stories'
@ -67,20 +68,19 @@ module Integrations
# - fix/ed/es/ing
# - close/s/d
# - closing
issue_finder = %r{(fix\w*|clos[ei]\w*+)?\W*(?:https://app\.asana\.com/\d+/\w+/(\w+)|#(\w+))}i
issue_finder = %r{(?:https://app\.asana\.com/\d+/\w+/(\w+)|#(\w+))}i
proceded_keyword_finder = %r{(fix\w*|clos[ei]\w*+)}i
message.scan(issue_finder).each do |tuple|
# tuple will be
# [ 'fix', 'id_from_url', 'id_from_pound' ]
taskid = tuple[2] || tuple[1]
message.split(issue_finder).each_slice(2) do |prepended_text, task_id|
next unless task_id
begin
story_on_task_url = format(STORY_URL_TEMPLATE, task_gid: taskid)
Gitlab::HTTP.post(story_on_task_url, headers: { "Authorization" => "Bearer #{api_key}" }, body: { text: "#{push_msg} #{message}" })
story_on_task_url = format(STORY_URL_TEMPLATE, task_gid: task_id)
Gitlab::HTTP_V2.post(story_on_task_url, headers: { "Authorization" => "Bearer #{api_key}" }, body: { text: "#{push_msg} #{message}" })
if tuple[0]
task_url = format(TASK_URL_TEMPLATE, task_gid: taskid)
Gitlab::HTTP.put(task_url, headers: { "Authorization" => "Bearer #{api_key}" }, body: { completed: true })
if prepended_text.match?(proceded_keyword_finder)
task_url = format(TASK_URL_TEMPLATE, task_gid: task_id)
Gitlab::HTTP_V2.put(task_url, headers: { "Authorization" => "Bearer #{api_key}" }, body: { completed: true })
end
rescue StandardError => e
log_error(e.message)
@ -89,6 +89,16 @@ module Integrations
end
end
def test(_)
result = Gitlab::HTTP_V2.get(PERSONAL_ACCESS_TOKEN_TEST_URL, headers: { "Authorization" => "Bearer #{api_key}" })
if result.success?
{ success: true }
else
{ success: false, result: result.message }
end
end
private
def branch_allowed?(branch_name)

View File

@ -15,6 +15,8 @@ class MergeRequestContextCommit < ApplicationRecord
attribute :trailers, :ind_jsonb
validates :trailers, json_schema: { filename: 'git_trailers' }
validates :merge_request_id, presence: true
# Sort by committed date in descending order to ensure latest commits comes on the top
scope :order_by_committed_date_desc, -> { order('committed_date DESC') }

View File

@ -66,6 +66,8 @@ module Ml
end
def package_version
return "candidate_#{iid}" if for_model?
iid
end
@ -73,6 +75,10 @@ module Ml
ci_build_id.present?
end
def for_model?
experiment.for_model? && !model_version_id.present?
end
class << self
def with_project_id_and_eid(project_id, eid)
return unless project_id.present? && eid.present?

View File

@ -30,9 +30,15 @@ module Ml
before_destroy :stop_destroy
def package_name
return model.name if for_model?
"#{PACKAGE_PREFIX}#{iid}"
end
def for_model?
model.present?
end
def stop_destroy
return unless model_id

View File

@ -13,7 +13,7 @@ module Packages
length: { maximum: 255 }
validates :version,
format: Gitlab::Regex.semver_regex,
format: Gitlab::Regex.ml_model_version_name_regex,
presence: true,
length: { maximum: 255 }
end

View File

@ -4,7 +4,7 @@ module Packages
module MlModel
class CreatePackageFileService < BaseService
def execute
@package = params[:model_version]&.package
@package = params[:package]
return unless @package

View File

@ -0,0 +1,23 @@
# frozen_string_literal: true
module Packages
module MlModel
class PackageForCandidateService < ::Packages::CreatePackageService
def execute
candidate = params[:candidate]
return unless candidate&.for_model?
package = find_or_create_package!(
::Packages::Package.package_types['ml_model'],
name: candidate.package_name,
version: candidate.package_version
)
candidate.update!(package: package) if candidate.package_id != package.id
package
end
end
end
end

View File

@ -4,7 +4,7 @@ module Packages
module Npm
class ProcessPackageFileService
ExtractionError = Class.new(StandardError)
PACKAGE_JSON_ENTRY_PATH = 'package/package.json'
PACKAGE_JSON_ENTRY_PATH = '*/package.json'
MAX_FILE_SIZE = 4.megabytes
delegate :package, to: :package_file
@ -37,15 +37,12 @@ module Packages
end
def with_package_json_entry
entry = package_file.file.use_open_file(unlink_early: false) do |open_file|
package_file.file.use_open_file(unlink_early: false) do |open_file|
Zlib::GzipReader.open(open_file.file_path) do |gz|
Gem::Package::TarReader.new(gz).seek(PACKAGE_JSON_ENTRY_PATH) do |entry|
next entry
end
entry = Gem::Package::TarReader.new(gz).find { |e| File.fnmatch(PACKAGE_JSON_ENTRY_PATH, e.full_name) }
yield entry
end
end
yield entry
end
end
end

View File

@ -55,6 +55,9 @@
"read_code": {
"type": "boolean"
},
"read_crm_contact": {
"type": "boolean"
},
"read_dependency": {
"type": "boolean"
},

View File

@ -29,7 +29,7 @@
%td.line_content.js-success-lazy-load
.js-code-placeholder
%td.js-error-lazy-load-diff.hidden.diff-loading-error-block
- button = render Pajamas::ButtonComponent.new(variant: :link, button_options: { class: 'btn-link-retry gl-p-0 js-toggle-lazy-diff-retry-button' }) do
- button = render Pajamas::ButtonComponent.new(variant: :link, button_options: { class: 'gl-p-0 js-toggle-lazy-diff-retry-button' }) do
= _("Try again")
= _("Unable to load the diff. %{button_try_again}").html_safe % { button_try_again: button}
= render "discussions/diff_discussion", discussions: [discussion], expanded: true

View File

@ -1,3 +1,3 @@
- find_file_title = "Go to file, press <kbd class='flat ml-1' aria-hidden=true>/~</kbd> or <kbd class='flat ml-1' aria-hidden=true>t</kbd>"
= render Pajamas::ButtonComponent.new(button_options: { class: 'has-tooltip shortcuts-find-file', title: find_file_title, 'aria-keyshortcuts': "/+~ t", 'data-html': true }) do
= render Pajamas::ButtonComponent.new(button_options: { class: 'has-tooltip shortcuts-find-file', title: find_file_title, 'aria-keyshortcuts': "/+~ t", 'data-html': true, 'data-event-tracking': 'click_find_file_button_on_repository_pages' }) do
= _('Find file')

View File

@ -8,7 +8,7 @@
#js-issuable-app{ data: { initial: issuable_initial_data(issuable).to_json,
header_actions_data: issue_header_actions_data(@project, issuable, current_user, @issuable_sidebar).to_json } }
.title-container
%h1.title.page-title.gl-font-size-h-display= markdown_field(issuable, :title)
%h1.gl-heading-1{ class: '!gl-m-0' }= markdown_field(issuable, :title)
- if issuable.description.present?
.description
.md= markdown_field(issuable, :description)

View File

@ -35,7 +35,7 @@
%strong
= commit_author_link(commit, avatar: true, size: 24)
- if commit.description.present?
%pre.commit-description<
%pre.commit-description.gl-white-space-pre-wrap.gl-line-height-normal
= preserve(markdown_field(commit, :description))
= render 'projects/diffs/diffs', diffs: @diffs, diff_page_context: "is-wiki"

View File

@ -20,7 +20,6 @@
clone_ssh_url: ssh_clone_url_to_repo(@wiki),
clone_http_url: http_clone_url_to_repo(@wiki),
wiki_url: wiki_path(@wiki),
new_url: '',
templates_url: wiki_page_path(@wiki, Wiki::TEMPLATES_DIR),
} }

View File

@ -17,7 +17,7 @@
is_page_template: @page.template?.to_s,
is_page_historical: @page.historical?.to_s,
last_version: @page.last_version,
page_version: @page.version.to_json,
page_version: @page.historical? ? @page.version.commit.to_json : @page.last_version.to_json,
wiki_path: @wiki.path,
clone_ssh_url: ssh_clone_url_to_repo(@wiki),
clone_http_url: http_clone_url_to_repo(@wiki),
@ -25,7 +25,7 @@
wiki_url: wiki_page_path(@wiki, @page),
edit_button_url: wiki_page_path(@wiki, @page, action: :edit),
new_url: @page.template? ? wiki_page_path(@wiki, "#{Wiki::TEMPLATES_DIR}/#{SecureRandom.uuid}", random_title: true) : wiki_path(@wiki, action: :new),
author_url: wiki_page_version_author_url(@page.version),
author_url: wiki_page_version_author_url(@page.historical? ? @page.version.commit : @page.last_version),
history_url: page_history,
templates_url: wiki_page_path(@wiki, Wiki::TEMPLATES_DIR),
format_options: wiki_markup_hash_by_name_id.to_json,

View File

@ -406,6 +406,7 @@ class FeatureFlagCreator
end
def execute
assert_clipboard_command!
assert_feature_branch!
assert_name!
assert_existing_feature_flag!
@ -467,6 +468,12 @@ class FeatureFlagCreator
Kernel.exec(*%w[git commit --amend])
end
def assert_clipboard_command!
return if FeatureFlagOptionParser.copy_to_clipboard_command
fail_with "Could not find a copy to clipboard command. On Linux, please install xclip or xsel (or wl-clipboard under Wayland). On macOS, make sure pbcopy is available."
end
def assert_feature_branch!
return unless branch_name == 'master'

View File

@ -256,6 +256,12 @@ domains:
- source_code_management
- gitaly
Sbom:
description: SBOM related ingestion
feature_categories:
- software_composition_analysis
- dependency_management
Search:
description: Code and content global search feature, including RAG, Elasticsearch and Zoekt integrations.
feature_categories:

View File

@ -0,0 +1,18 @@
---
description: Searched for files by triggering Find file button on Repository pages.
internal_events: true
action: click_find_file_button_on_repository_pages
identifiers:
- project
- namespace
- user
product_group: source_code
milestone: '17.1'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155457
distributions:
- ce
- ee
tiers:
- free
- premium
- ultimate

View File

@ -0,0 +1,18 @@
---
description: Searched for files by triggering Go to file shortcut.
internal_events: true
action: click_go_to_file_shortcut
identifiers:
- project
- namespace
- user
product_group: source_code
milestone: '17.1'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155457
distributions:
- ce
- ee
tiers:
- free
- premium
- ultimate

View File

@ -0,0 +1,22 @@
---
description: Agents send the register request to KAS periodically (default every 5 min). KAS registers the agent to keep track of connected agents.
internal_events: true
action: register_agent_at_kas
identifiers:
- project
- namespace
additional_properties:
label:
description: GitLab Agent version
property:
description: CPU architecture of the agent, e.g. x86_64
product_group: environments
milestone: '17.1'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/154883
distributions:
- ce
- ee
tiers:
- free
- premium
- ultimate

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_project_id_from_register_agent_at_kas_monthly
description: Monthly count of unique projects where GitLab agent was registered to KAS
product_group: environments
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/154883
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: register_agent_at_kas
unique: project.id

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_click_find_file_button_on_repository_pages_monthly
description: Monthly count of unique users who searched for files via Find file button.
product_group: source_code
performance_indicator_type: []
value_type: number
status: active
milestone: '17.1'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155457
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: click_find_file_button_on_repository_pages
unique: user.id

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_click_go_to_file_shortcut_monthly
description: Monthly count of unique users who searched for files via shortcut.
product_group: source_code
performance_indicator_type: []
value_type: number
status: active
milestone: '17.1'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155457
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: click_go_to_file_shortcut
unique: user.id

View File

@ -0,0 +1,21 @@
---
key_path: counts.count_total_register_agent_at_kas_monthly
description: Monthly count of GitLab agents registered with KAS
product_group: environments
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/154883
time_frame: 28d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: register_agent_at_kas

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_project_id_from_register_agent_at_kas_weekly
description: Weekly count of unique projects where GitLab agent was registered to KAS
product_group: environments
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/154883
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: register_agent_at_kas
unique: project.id

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_click_find_file_button_on_repository_pages_weekly
description: Weekly count of unique users who searched for files via Find file button.
product_group: source_code
performance_indicator_type: []
value_type: number
status: active
milestone: '17.1'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155457
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: click_find_file_button_on_repository_pages
unique: user.id

View File

@ -0,0 +1,22 @@
---
key_path: redis_hll_counters.count_distinct_user_id_from_click_go_to_file_shortcut_weekly
description: Weekly count of unique users who searched for files via shortcut.
product_group: source_code
performance_indicator_type: []
value_type: number
status: active
milestone: '17.1'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155457
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: click_go_to_file_shortcut
unique: user.id

View File

@ -0,0 +1,21 @@
---
key_path: counts.count_total_register_agent_at_kas_weekly
description: Weekly count of GitLab agents registered with KAS
product_group: environments
performance_indicator_type: []
value_type: number
status: active
milestone: '17.2'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/154883
time_frame: 7d
data_source: internal_events
data_category: optional
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate
events:
- name: register_agent_at_kas

View File

@ -19,4 +19,5 @@ tier:
- free
- premium
- ultimate
performance_indicator_type: []
performance_indicator_type:
- devops_report

View File

@ -14,4 +14,5 @@ tier:
- free
performance_indicator_type:
- customer_health_score
- devops_report
milestone: "<13.9"

View File

@ -16,4 +16,5 @@ tier:
- ultimate
performance_indicator_type:
- customer_health_score
- devops_report
milestone: "<13.9"

View File

@ -17,4 +17,5 @@ tier:
- ultimate
performance_indicator_type:
- customer_health_score
- devops_report
milestone: "<13.9"

View File

@ -13,4 +13,5 @@ tier:
- free
performance_indicator_type:
- customer_health_score
- devops_report
milestone: "<13.9"

View File

@ -17,4 +17,5 @@ tier:
- ultimate
performance_indicator_type:
- customer_health_score
- devops_report
milestone: "<13.9"

View File

@ -14,5 +14,6 @@ tier:
- free
- premium
- ultimate
performance_indicator_type: []
performance_indicator_type:
- devops_report
milestone: "<13.9"

View File

@ -14,5 +14,6 @@ tier:
- free
- premium
- ultimate
performance_indicator_type: []
performance_indicator_type:
- devops_report
milestone: "<13.9"

View File

@ -15,5 +15,6 @@ tier:
- free
- premium
- ultimate
performance_indicator_type: []
performance_indicator_type:
- devops_report
milestone: "<13.9"

View File

@ -16,4 +16,5 @@ tier:
- ultimate
performance_indicator_type:
- customer_health_score
- devops_report
milestone: "<13.9"

View File

@ -131,7 +131,8 @@
"smau",
"paid_gmau",
"umau",
"customer_health_score"
"customer_health_score",
"devops_report"
]
}
},

View File

@ -0,0 +1,10 @@
---
table_name: ai_testing_terms_acceptances
classes:
- Ai::TestingTermsAcceptance
feature_categories:
- custom_models
description: Records that an admin has accepted GitLab Testing Terms for an instance
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/155231
milestone: '17.1'
gitlab_schema: gitlab_main_clusterwide

View File

@ -0,0 +1,9 @@
---
migration_job_name: BackfillEpicUserMentionsGroupId
description: Backfills sharding key `epic_user_mentions.group_id` from `epics`.
feature_category: team_planning
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156119
milestone: '17.1'
queued_migration_version: 20240612071563
finalize_after: '2024-07-22'
finalized_by: # version of the migration that finalized this BBM

View File

@ -0,0 +1,9 @@
---
migration_job_name: BackfillMergeRequestBlocksProjectId
description: Backfills sharding key `merge_request_blocks.project_id` from `merge_requests`.
feature_category: source_code_management
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156120
milestone: '17.1'
queued_migration_version: 20240612072331
finalize_after: '2024-07-22'
finalized_by: # version of the migration that finalized this BBM

View File

@ -0,0 +1,9 @@
---
migration_job_name: BackfillOperationsStrategiesUserListsProjectId
description: Backfills sharding key `operations_strategies_user_lists.project_id` from `operations_user_lists`.
feature_category: feature_flags
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156122
milestone: '17.1'
queued_migration_version: 20240612073059
finalize_after: '2024-07-22'
finalized_by: # version of the migration that finalized this BBM

View File

@ -0,0 +1,9 @@
---
migration_job_name: BackfillPackagesDebianProjectDistributionKeysProjectId
description: Backfills sharding key `packages_debian_project_distribution_keys.project_id` from `packages_debian_project_distributions`.
feature_category: package_registry
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156127
milestone: '17.1'
queued_migration_version: 20240612074837
finalize_after: '2024-07-22'
finalized_by: # version of the migration that finalized this BBM

View File

@ -19,3 +19,4 @@ desired_sharding_key:
table: epics
sharding_key: group_id
belongs_to: epic
desired_sharding_key_migration_job_name: BackfillEpicUserMentionsGroupId

View File

@ -19,3 +19,4 @@ desired_sharding_key:
table: merge_requests
sharding_key: target_project_id
belongs_to: blocking_merge_request
desired_sharding_key_migration_job_name: BackfillMergeRequestBlocksProjectId

View File

@ -19,3 +19,4 @@ desired_sharding_key:
table: operations_user_lists
sharding_key: project_id
belongs_to: user_list
desired_sharding_key_migration_job_name: BackfillOperationsStrategiesUserListsProjectId

View File

@ -19,3 +19,4 @@ desired_sharding_key:
table: packages_debian_project_distributions
sharding_key: project_id
belongs_to: distribution
desired_sharding_key_migration_job_name: BackfillPackagesDebianProjectDistributionKeysProjectId

View File

@ -8,4 +8,5 @@ description: Stores the data needed to notify a user of an upcoming reconciliati
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/63054
milestone: '14.0'
gitlab_schema: gitlab_main_cell
sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/462598
sharding_key:
organization_id: organizations

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