Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
bd15a45eeb
commit
c8eaa54d71
|
|
@ -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'
|
||||
|
|
|
|||
39
CHANGELOG.md
39
CHANGELOG.md
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
v17.1.0-rc9
|
||||
8197a694087583b69b30c12f22eac6a9ed2b20eb
|
||||
|
|
|
|||
2
Gemfile
2
Gemfile
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -3,6 +3,5 @@ export default {
|
|||
validIssueWeight() {
|
||||
return false;
|
||||
},
|
||||
filterByWeight() {},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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') }}
|
||||
|
|
|
|||
|
|
@ -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'),
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -64,7 +64,6 @@ const mountWikiContentApp = () => {
|
|||
templates: JSON.parse(templates),
|
||||
drawioUrl: gon.diagramsnet_url,
|
||||
pagePersisted: parseBoolean(pagePersisted),
|
||||
error: null,
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement(WikiContentApp);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -161,7 +161,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div class="gl-rounded-0!">
|
||||
<div>
|
||||
<state-container
|
||||
:is-loading="isLoading"
|
||||
:status="statusIcon"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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';
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) }
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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') }
|
||||
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ module Packages
|
|||
module MlModel
|
||||
class CreatePackageFileService < BaseService
|
||||
def execute
|
||||
@package = params[:model_version]&.package
|
||||
@package = params[:package]
|
||||
|
||||
return unless @package
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@
|
|||
"read_code": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"read_crm_contact": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"read_dependency": {
|
||||
"type": "boolean"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
} }
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -19,4 +19,5 @@ tier:
|
|||
- free
|
||||
- premium
|
||||
- ultimate
|
||||
performance_indicator_type: []
|
||||
performance_indicator_type:
|
||||
- devops_report
|
||||
|
|
|
|||
|
|
@ -14,4 +14,5 @@ tier:
|
|||
- free
|
||||
performance_indicator_type:
|
||||
- customer_health_score
|
||||
- devops_report
|
||||
milestone: "<13.9"
|
||||
|
|
|
|||
|
|
@ -16,4 +16,5 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type:
|
||||
- customer_health_score
|
||||
- devops_report
|
||||
milestone: "<13.9"
|
||||
|
|
|
|||
|
|
@ -17,4 +17,5 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type:
|
||||
- customer_health_score
|
||||
- devops_report
|
||||
milestone: "<13.9"
|
||||
|
|
|
|||
|
|
@ -13,4 +13,5 @@ tier:
|
|||
- free
|
||||
performance_indicator_type:
|
||||
- customer_health_score
|
||||
- devops_report
|
||||
milestone: "<13.9"
|
||||
|
|
|
|||
|
|
@ -17,4 +17,5 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type:
|
||||
- customer_health_score
|
||||
- devops_report
|
||||
milestone: "<13.9"
|
||||
|
|
|
|||
|
|
@ -14,5 +14,6 @@ tier:
|
|||
- free
|
||||
- premium
|
||||
- ultimate
|
||||
performance_indicator_type: []
|
||||
performance_indicator_type:
|
||||
- devops_report
|
||||
milestone: "<13.9"
|
||||
|
|
|
|||
|
|
@ -14,5 +14,6 @@ tier:
|
|||
- free
|
||||
- premium
|
||||
- ultimate
|
||||
performance_indicator_type: []
|
||||
performance_indicator_type:
|
||||
- devops_report
|
||||
milestone: "<13.9"
|
||||
|
|
|
|||
|
|
@ -15,5 +15,6 @@ tier:
|
|||
- free
|
||||
- premium
|
||||
- ultimate
|
||||
performance_indicator_type: []
|
||||
performance_indicator_type:
|
||||
- devops_report
|
||||
milestone: "<13.9"
|
||||
|
|
|
|||
|
|
@ -16,4 +16,5 @@ tier:
|
|||
- ultimate
|
||||
performance_indicator_type:
|
||||
- customer_health_score
|
||||
- devops_report
|
||||
milestone: "<13.9"
|
||||
|
|
|
|||
|
|
@ -131,7 +131,8 @@
|
|||
"smau",
|
||||
"paid_gmau",
|
||||
"umau",
|
||||
"customer_health_score"
|
||||
"customer_health_score",
|
||||
"devops_report"
|
||||
]
|
||||
}
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -19,3 +19,4 @@ desired_sharding_key:
|
|||
table: epics
|
||||
sharding_key: group_id
|
||||
belongs_to: epic
|
||||
desired_sharding_key_migration_job_name: BackfillEpicUserMentionsGroupId
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Reference in New Issue