Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-04-03 18:10:00 +00:00
parent e6120ad6ed
commit 6d63ea6f1b
30 changed files with 401 additions and 84 deletions

View File

@ -263,9 +263,9 @@ RSpec/BeforeAllRoleAssignment:
- 'ee/spec/graphql/types/vulnerability_type_spec.rb'
- 'ee/spec/helpers/ee/ci/pipeline_editor_helper_spec.rb'
- 'ee/spec/helpers/ee/groups_helper_spec.rb'
- 'ee/spec/helpers/ee/merge_requests_helper_spec.rb'
- 'ee/spec/helpers/ee/projects/pipeline_helper_spec.rb'
- 'ee/spec/helpers/gitlab_subscriptions/upcoming_reconciliation_helper_spec.rb'
- 'ee/spec/helpers/merge_requests_helper_spec.rb'
- 'ee/spec/helpers/projects/on_demand_scans_helper_spec.rb'
- 'ee/spec/helpers/projects/project_members_helper_spec.rb'
- 'ee/spec/helpers/projects_helper_spec.rb'

View File

@ -463,7 +463,6 @@ RSpec/FeatureCategory:
- 'ee/spec/helpers/license_monitoring_helper_spec.rb'
- 'ee/spec/helpers/manual_quarterly_co_term_banner_helper_spec.rb'
- 'ee/spec/helpers/markup_helper_spec.rb'
- 'ee/spec/helpers/merge_requests_helper_spec.rb'
- 'ee/spec/helpers/notes_helper_spec.rb'
- 'ee/spec/helpers/path_locks_helper_spec.rb'
- 'ee/spec/helpers/preferences_helper_spec.rb'

View File

@ -12,7 +12,6 @@ RSpec/FilePath:
- 'ee/spec/frontend/fixtures/analytics/value_streams_staging_stage.rb'
- 'ee/spec/frontend/fixtures/analytics/value_streams_test_stage.rb'
- 'ee/spec/frontend/fixtures/dora/metrics.rb'
- 'ee/spec/helpers/merge_requests_helper_spec.rb'
- 'ee/spec/models/merge_request/blocking_spec.rb'
- 'ee/spec/requests/api/ci/runner/jobs_put_spec.rb'
- 'ee/spec/requests/api/ci/runner/jobs_trace_spec.rb'

View File

@ -199,6 +199,7 @@ RSpec/NamedSubject:
- 'ee/spec/helpers/ee/groups/group_members_helper_spec.rb'
- 'ee/spec/helpers/ee/groups_helper_spec.rb'
- 'ee/spec/helpers/ee/lock_helper_spec.rb'
- 'ee/spec/helpers/ee/merge_requests_helper_spec.rb'
- 'ee/spec/helpers/ee/operations_helper_spec.rb'
- 'ee/spec/helpers/ee/projects/incidents_helper_spec.rb'
- 'ee/spec/helpers/ee/projects/pipeline_helper_spec.rb'
@ -207,7 +208,6 @@ RSpec/NamedSubject:
- 'ee/spec/helpers/groups/sso_helper_spec.rb'
- 'ee/spec/helpers/kerberos_helper_spec.rb'
- 'ee/spec/helpers/license_helper_spec.rb'
- 'ee/spec/helpers/merge_requests_helper_spec.rb'
- 'ee/spec/helpers/nav/new_dropdown_helper_spec.rb'
- 'ee/spec/helpers/projects/security/dast_profiles_helper_spec.rb'
- 'ee/spec/helpers/projects_helper_spec.rb'

View File

@ -55,6 +55,9 @@
"ExternalAuditEventDestination",
"InstanceExternalAuditEventDestination"
],
"AuditEventStreamingDestinationInterface": [
"GroupAuditEventStreamingDestination"
],
"GoogleCloudArtifactRegistryArtifact": [
"GoogleCloudArtifactRegistryDockerImage"
],

View File

@ -76,7 +76,7 @@ export default {
<gl-icon name="external-link" class="gl-ml-2 gl-flex-shrink-0 gl-flex-grow-0" />
</gl-link>
<expand-button>
<expand-button class="gl-ml-4">
<template #short>
<span class="js-short monospace">{{ shortSha(index) }}</span>
</template>

View File

@ -102,7 +102,7 @@ export default {
<gl-button
data-testid="accordion-button"
variant="link"
class="gl-font-weight-bold"
class="gl-font-weight-bold gl-text-black-normal!"
@click="toggleAssetsExpansion"
>
<gl-icon

View File

@ -85,36 +85,37 @@ export default {
};
</script>
<template>
<div>
<div
v-if="commit"
class="gl-float-left gl-mr-5 gl-display-flex gl-align-items-center js-commit-info"
>
<gl-icon ref="commitIcon" name="commit" class="gl-mr-2" />
<div class="gl-display-flex gl-gap-5">
<div v-if="commit" class="gl-display-flex gl-align-items-center js-commit-info">
<gl-icon ref="commitIcon" name="commit" class="gl-mr-2 gl-text-gray-700" />
<div v-gl-tooltip.bottom :title="commit.title">
<gl-link v-if="commitPath" :href="commitPath">
<gl-link
v-if="commitPath"
:href="commitPath"
class="gl-font-sm gl-font-monospace gl-mr-0 gl-text-gray-700"
>
{{ commit.shortId }}
</gl-link>
<span v-else>{{ commit.shortId }}</span>
</div>
</div>
<div
v-if="tagName"
class="gl-float-left gl-mr-5 gl-display-flex gl-align-items-center js-tag-info"
>
<gl-icon name="tag" class="gl-mr-2" />
<div v-if="tagName" class="gl-display-flex gl-align-items-center js-tag-info">
<gl-icon name="tag" class="gl-mr-2 gl-text-gray-700" />
<div v-gl-tooltip.bottom :title="__('Tag')">
<gl-link v-if="tagPath" :href="tagPath">
<gl-link
v-if="tagPath"
:href="tagPath"
class="gl-font-sm gl-font-monospace gl-mr-0 gl-text-gray-700"
>
{{ tagName }}
</gl-link>
<span v-else>{{ tagName }}</span>
</div>
</div>
<div
v-if="timeAt || author"
class="gl-float-left gl-display-flex gl-align-items-center js-author-date-info"
class="gl-display-flex gl-align-items-center js-author-date-info gl-font-sm"
>
<span class="gl-text-secondary">{{ createdTime }}&nbsp;</span>
<template v-if="timeAt">
@ -130,11 +131,10 @@ export default {
<div v-if="author" class="gl-display-flex">
<span class="gl-text-secondary">{{ __('by') }}&nbsp;</span>
<user-avatar-link
class="gl-my-n1 gl-display-flex"
:link-href="author.webUrl"
:img-src="author.avatarUrl"
:img-alt="userImageAltDescription"
:img-size="24"
:img-size="16"
:tooltip-text="author.username"
tooltip-placement="bottom"
/>

View File

@ -6,7 +6,7 @@ import { BACK_URL_PARAM } from '~/releases/constants';
export default {
i18n: {
editButton: __('Edit this release'),
editButton: __('Edit release'),
historical: __('Historical release'),
historicalTooltip: __(
'This release was created with a date in the past. Evidence collection at the moment of the release is unavailable.',
@ -49,12 +49,12 @@ export default {
<template>
<div class="card-header d-flex gl-align-items-center bg-white pr-0">
<h2 class="card-title my-2 mr-auto">
<gl-link v-if="selfLink" :href="selfLink">
<h2 class="card-title gl-my-2 mr-auto gl-font-size-h2">
<gl-link v-if="selfLink" class="gl-text-black-normal" :href="selfLink">
{{ release.name }}
</gl-link>
<template v-else>
{{ release.name }}
<span class="gl-text-black-normal">{{ release.name }}</span>
<gl-icon
v-gl-tooltip
name="lock"
@ -80,14 +80,13 @@ export default {
</h2>
<gl-button
v-if="editLink"
v-gl-tooltip
category="primary"
size="small"
variant="default"
icon="pencil"
class="gl-mr-3 js-edit-button gl-ml-3 gl-pb-3"
:title="$options.i18n.editButton"
:aria-label="$options.i18n.editButton"
:href="editLink"
/>
>
{{ $options.i18n.editButton }}
</gl-button>
</div>
</template>

View File

@ -0,0 +1,16 @@
- button_path = local_assigns[:button_path]
- button_text = _('New merge request')
= render Pajamas::EmptyStateComponent.new(svg_path: 'illustrations/empty-state/empty-merge-requests-md.svg',
empty_state_options: { data: { testid: 'issuable-empty-state' } },
title: _("Merge requests are a place to propose changes you've made to a project and discuss those changes with others")) do |c|
- c.with_description do
= _('Interested parties can even contribute by pushing commits if they want to.')
- if button_path
.gl-mt-5
= link_button_to button_text, button_path,
title: button_text,
id: 'new_merge_request_link',
variant: :confirm,
data: { testid: 'new-merge-request-button', event_tracking: 'click_new_merge_request_empty_list' }

View File

@ -35,15 +35,4 @@
title: _("There are no closed merge requests"))
- else
= render Pajamas::EmptyStateComponent.new(svg_path: 'illustrations/empty-state/empty-merge-requests-md.svg',
empty_state_options: { data: { testid: 'issuable-empty-state' } },
title: _("Merge requests are a place to propose changes you've made to a project and discuss those changes with others")) do |c|
- c.with_description do
= _("Interested parties can even contribute by pushing commits if they want to.")
- if button_path
.gl-mt-5= link_button_to button_text, button_path,
title: button_text,
id: 'new_merge_request_link',
variant: :confirm,
data: { testid: "new-merge-request-button", **tracking_data }
= render_if_exists 'shared/empty_states/empty_merge_requests_without_filters', button_path: button_path

View File

@ -0,0 +1,54 @@
# frozen_string_literal: true
class CreateCodeSuggestionTables < ClickHouse::Migration
def up
execute <<~SQL
CREATE TABLE IF NOT EXISTS code_suggestion_usages
(
user_id UInt64 DEFAULT 0,
event UInt8 DEFAULT 0,
namespace_path String DEFAULT '0/',
timestamp DateTime64(6, 'UTC') DEFAULT now64()
) ENGINE = ReplacingMergeTree
PARTITION BY toYear(timestamp)
ORDER BY (user_id, event, timestamp)
SQL
execute <<~SQL
CREATE TABLE IF NOT EXISTS code_suggestion_daily_usages
(
user_id UInt64 DEFAULT 0,
timestamp Date32 DEFAULT toDate(now64()),
) ENGINE = ReplacingMergeTree
PARTITION BY toYear(timestamp)
ORDER BY (user_id, timestamp)
SETTINGS index_granularity = 64
SQL
execute <<~SQL
CREATE MATERIALIZED VIEW IF NOT EXISTS code_suggestion_daily_usages_mv
TO code_suggestion_daily_usages
AS
SELECT
user_id,
timestamp
FROM code_suggestion_usages
WHERE event = 1
GROUP BY user_id, timestamp
SQL
end
def down
execute <<~SQL
DROP VIEW IF EXISTS code_suggestion_daily_usages_mv
SQL
execute <<~SQL
DROP TABLE IF EXISTS code_suggestion_daily_usages
SQL
execute <<~SQL
DROP TABLE IF EXISTS code_suggestion_usages
SQL
end
end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class AddIndexApprovalMrRulesOnConfigIdAndIdAndUpdatedAt < Gitlab::Database::Migration[2.2]
milestone '16.11'
disable_ddl_transaction!
INDEX_NAME = :idx_approval_mr_rules_on_config_id_and_id_and_updated_at
TABLE_NAME = :approval_merge_request_rules
def up
add_concurrent_index(TABLE_NAME, %i[security_orchestration_policy_configuration_id id updated_at], name: INDEX_NAME)
end
def down
remove_concurrent_index_by_name(TABLE_NAME, INDEX_NAME)
end
end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class AddIndexMergeRequestsOnUnmergedStateId < Gitlab::Database::Migration[2.2]
milestone '16.11'
disable_ddl_transaction!
INDEX_NAME = :idx_merge_requests_on_unmerged_state_id
TABLE_NAME = :merge_requests
def up
add_concurrent_index(TABLE_NAME, :id, name: INDEX_NAME, where: "state_id <> 3")
end
def down
remove_concurrent_index_by_name(TABLE_NAME, INDEX_NAME)
end
end

View File

@ -0,0 +1,18 @@
# frozen_string_literal: true
class RemoveIndexApprovalMergeRequestRulesOnSecOrchestrationConfigId < Gitlab::Database::Migration[2.2]
milestone '16.11'
disable_ddl_transaction!
TABLE_NAME = :approval_merge_request_rules
INDEX_NAME = :idx_approval_merge_request_rules_on_sec_orchestration_config_id
def up
remove_concurrent_index_by_name(TABLE_NAME, INDEX_NAME)
end
def down
add_concurrent_index(TABLE_NAME, :security_orchestration_policy_configuration_id, name: INDEX_NAME)
end
end

View File

@ -0,0 +1 @@
2fde7e5b0316ff8da3ac960ab02a04d4b6de12bba79c604ed27b2d06f490c16a

View File

@ -0,0 +1 @@
d5b27c90336e128f4c7af2b02b71e62a245a9866bc52f0a737efd2289fb161c4

View File

@ -0,0 +1 @@
852b7b1774d1d309a5dfcce99426656bf783aada37efda766f2e590a849e60d5

View File

@ -23807,7 +23807,7 @@ CREATE INDEX idx_analytics_devops_adoption_snapshots_finalized ON analytics_devo
CREATE INDEX idx_approval_merge_request_rules_on_scan_result_policy_id ON approval_merge_request_rules USING btree (scan_result_policy_id);
CREATE INDEX idx_approval_merge_request_rules_on_sec_orchestration_config_id ON approval_merge_request_rules USING btree (security_orchestration_policy_configuration_id);
CREATE INDEX idx_approval_mr_rules_on_config_id_and_id_and_updated_at ON approval_merge_request_rules USING btree (security_orchestration_policy_configuration_id, id, updated_at);
CREATE INDEX idx_approval_project_rules_on_configuration_id_and_id ON approval_project_rules USING btree (security_orchestration_policy_configuration_id, id);
@ -23907,6 +23907,8 @@ CREATE INDEX idx_merge_requests_on_target_project_id_and_iid_opened ON merge_req
CREATE INDEX idx_merge_requests_on_target_project_id_and_locked_state ON merge_requests USING btree (target_project_id) WHERE (state_id = 4);
CREATE INDEX idx_merge_requests_on_unmerged_state_id ON merge_requests USING btree (id) WHERE (state_id <> 3);
CREATE UNIQUE INDEX idx_metrics_users_starred_dashboard_on_user_project_dashboard ON metrics_users_starred_dashboards USING btree (user_id, project_id, dashboard_path);
CREATE INDEX idx_mr_cc_diff_files_on_mr_cc_id_and_sha ON merge_request_context_commit_diff_files USING btree (merge_request_context_commit_id, sha);

View File

@ -58,6 +58,7 @@ Audit event types belong to the following product categories.
| [`audit_events_streaming_instance_headers_destroy`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/127228) | Triggered when a streaming header for instance level external audit event destination is deleted| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.3](https://gitlab.com/gitlab-org/gitlab/-/issues/417433) | Instance |
| [`audit_events_streaming_instance_headers_update`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/127228) | Triggered when a streaming header for instance level external audit event destination is updated| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.3](https://gitlab.com/gitlab-org/gitlab/-/issues/417433) | Instance |
| [`create_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74632) | Event triggered when an external audit event destination is created| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [14.6](https://gitlab.com/gitlab-org/gitlab/-/issues/344664) | Group |
| [`create_group_audit_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/147888) | Event triggered when an external audit event destination for a top-level group is created.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.11](https://gitlab.com/gitlab-org/gitlab/-/issues/436610) | Group |
| [`create_http_namespace_filter`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136047) | Event triggered when a namespace filter for an external audit event destination for a top-level group is created.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.6](https://gitlab.com/gitlab-org/gitlab/-/issues/424176) | Group |
| [`create_instance_event_streaming_destination`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123882) | Event triggered when an instance level external audit event destination is created| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.2](https://gitlab.com/gitlab-org/gitlab/-/issues/404730) | Instance |
| [`delete_http_namespace_filter`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136302) | Event triggered when a namespace filter for an external audit event destination for a top-level group is deleted.| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.7](https://gitlab.com/gitlab-org/gitlab/-/issues/424177) | Group |

View File

@ -4719,6 +4719,33 @@ Input type: `GoogleCloudLoggingConfigurationUpdateInput`
| <a id="mutationgooglecloudloggingconfigurationupdateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationgooglecloudloggingconfigurationupdategooglecloudloggingconfiguration"></a>`googleCloudLoggingConfiguration` | [`GoogleCloudLoggingConfigurationType`](#googlecloudloggingconfigurationtype) | configuration updated. |
### `Mutation.groupAuditEventStreamingDestinationsCreate`
DETAILS:
**Introduced** in GitLab 16.11.
**Status**: Experiment.
Input type: `GroupAuditEventStreamingDestinationsCreateInput`
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationgroupauditeventstreamingdestinationscreatecategory"></a>`category` | [`String!`](#string) | Destination category. |
| <a id="mutationgroupauditeventstreamingdestinationscreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationgroupauditeventstreamingdestinationscreateconfig"></a>`config` | [`JSON!`](#json) | Destination config. |
| <a id="mutationgroupauditeventstreamingdestinationscreategrouppath"></a>`groupPath` | [`ID!`](#id) | Group path. |
| <a id="mutationgroupauditeventstreamingdestinationscreatename"></a>`name` | [`String`](#string) | Destination name. |
| <a id="mutationgroupauditeventstreamingdestinationscreatesecrettoken"></a>`secretToken` | [`String!`](#string) | Secret token. |
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationgroupauditeventstreamingdestinationscreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationgroupauditeventstreamingdestinationscreateerrors"></a>`errors` | [`[String!]!`](#string) | Errors encountered during execution of the mutation. |
| <a id="mutationgroupauditeventstreamingdestinationscreateexternalauditeventdestination"></a>`externalAuditEventDestination` | [`GroupAuditEventStreamingDestination`](#groupauditeventstreamingdestination) | Destination created. |
### `Mutation.groupMemberBulkUpdate`
Input type: `GroupMemberBulkUpdateInput`
@ -11645,6 +11672,29 @@ The edge type for [`GoogleCloudLoggingConfigurationType`](#googlecloudloggingcon
| <a id="googlecloudloggingconfigurationtypeedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="googlecloudloggingconfigurationtypeedgenode"></a>`node` | [`GoogleCloudLoggingConfigurationType`](#googlecloudloggingconfigurationtype) | The item at the end of the edge. |
#### `GroupAuditEventStreamingDestinationConnection`
The connection type for [`GroupAuditEventStreamingDestination`](#groupauditeventstreamingdestination).
##### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="groupauditeventstreamingdestinationconnectionedges"></a>`edges` | [`[GroupAuditEventStreamingDestinationEdge]`](#groupauditeventstreamingdestinationedge) | A list of edges. |
| <a id="groupauditeventstreamingdestinationconnectionnodes"></a>`nodes` | [`[GroupAuditEventStreamingDestination]`](#groupauditeventstreamingdestination) | A list of nodes. |
| <a id="groupauditeventstreamingdestinationconnectionpageinfo"></a>`pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
#### `GroupAuditEventStreamingDestinationEdge`
The edge type for [`GroupAuditEventStreamingDestination`](#groupauditeventstreamingdestination).
##### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="groupauditeventstreamingdestinationedgecursor"></a>`cursor` | [`String!`](#string) | A cursor for use in pagination. |
| <a id="groupauditeventstreamingdestinationedgenode"></a>`node` | [`GroupAuditEventStreamingDestination`](#groupauditeventstreamingdestination) | The item at the end of the edge. |
#### `GroupConnection`
The connection type for [`Group`](#group).
@ -20249,6 +20299,7 @@ GPG signature for a signed commit.
| <a id="groupepicboards"></a>`epicBoards` | [`EpicBoardConnection`](#epicboardconnection) | Find epic boards. (see [Connections](#connections)) |
| <a id="groupepicsenabled"></a>`epicsEnabled` | [`Boolean`](#boolean) | Indicates if Epics are enabled for namespace. |
| <a id="groupexternalauditeventdestinations"></a>`externalAuditEventDestinations` | [`ExternalAuditEventDestinationConnection`](#externalauditeventdestinationconnection) | External locations that receive audit events belonging to the group. (see [Connections](#connections)) |
| <a id="groupexternalauditeventstreamingdestinations"></a>`externalAuditEventStreamingDestinations` **{warning-solid}** | [`GroupAuditEventStreamingDestinationConnection`](#groupauditeventstreamingdestinationconnection) | **Introduced** in GitLab 16.11. **Status**: Experiment. External destinations that receive audit events belonging to the group. |
| <a id="groupflowmetrics"></a>`flowMetrics` **{warning-solid}** | [`GroupValueStreamAnalyticsFlowMetrics`](#groupvaluestreamanalyticsflowmetrics) | **Introduced** in GitLab 15.10. **Status**: Experiment. Flow metrics for value stream analytics. |
| <a id="groupfullname"></a>`fullName` | [`String!`](#string) | Full name of the namespace. |
| <a id="groupfullpath"></a>`fullPath` | [`ID!`](#id) | Full path of the namespace. |
@ -21479,6 +21530,20 @@ four standard [pagination arguments](#pagination-arguments):
| <a id="groupworkitemsstatuswidget"></a>`statusWidget` | [`StatusFilterInput`](#statusfilterinput) | Input for status widget filter. Ignored if `work_items_mvc_2` is disabled. |
| <a id="groupworkitemstypes"></a>`types` | [`[IssueType!]`](#issuetype) | Filter work items by the given work item types. |
### `GroupAuditEventStreamingDestination`
Represents an external destination to stream group level audit events.
#### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="groupauditeventstreamingdestinationcategory"></a>`category` | [`String!`](#string) | Category of the external destination to send audit events to. |
| <a id="groupauditeventstreamingdestinationconfig"></a>`config` | [`JSON!`](#json) | Config of the external destination. |
| <a id="groupauditeventstreamingdestinationgroup"></a>`group` | [`Group!`](#group) | Group to which the destination belongs. |
| <a id="groupauditeventstreamingdestinationid"></a>`id` | [`ID!`](#id) | ID of the destination. |
| <a id="groupauditeventstreamingdestinationname"></a>`name` | [`String!`](#string) | Name of the external destination to send audit events to. |
### `GroupDataTransfer`
#### Fields
@ -34757,6 +34822,21 @@ Implementations:
| <a id="amazons3configurationinterfaceid"></a>`id` | [`ID!`](#id) | ID of the configuration. |
| <a id="amazons3configurationinterfacename"></a>`name` | [`String!`](#string) | Name of the external destination to send audit events to. |
#### `AuditEventStreamingDestinationInterface`
Implementations:
- [`GroupAuditEventStreamingDestination`](#groupauditeventstreamingdestination)
##### Fields
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="auditeventstreamingdestinationinterfacecategory"></a>`category` | [`String!`](#string) | Category of the external destination to send audit events to. |
| <a id="auditeventstreamingdestinationinterfaceconfig"></a>`config` | [`JSON!`](#json) | Config of the external destination. |
| <a id="auditeventstreamingdestinationinterfaceid"></a>`id` | [`ID!`](#id) | ID of the destination. |
| <a id="auditeventstreamingdestinationinterfacename"></a>`name` | [`String!`](#string) | Name of the external destination to send audit events to. |
#### `BaseHeaderInterface`
Implementations:

View File

@ -235,6 +235,21 @@ flowchart LR
<sup>*</sup>: Front end obscures many unexplored phases. It is likely that the front end will need caches, databases, API abstractions (over sub-modules like network connectivity, etc.), and more. While these have not been expanded on, "Front end" stands in for all of that complexity here.
###### Gitaly
For fetching Diffs, Gitaly provides two basic utilities:
1. Retrieve a list of modified files with associated pre- and post-image blob IDs for a set of revisions.
1. Retrieve a set of Git diffs for an arbitrary set of specified files using pre- and post-image blob IDs.
```mermaid
sequenceDiagram
Back end ->> Gitaly: "What files were modified between<br />this pair of/in this single revision?"
Gitaly ->> Back end: List of paths
Back end ->> Gitaly: "What are the diffs for this set of paths<br /> between this pair of/in this single revision?"
Gitaly ->> Back end: List of diffs
```
### Accessibility
Reusable Rapid Diffs should be displayed in a way that is compliant with [Web Content Accessibility Guidelines 2.1](https://www.w3.org/TR/WCAG21/) level AA for web-based content and [Authoring Tool Accessibility Guidelines 2.0](https://www.w3.org/TR/ATAG20/) level AA for user interface.

View File

@ -566,17 +566,22 @@ You can learn more by following a practical example for [migrating the Go CI/CD
## Use a GitLab.com component in a self-managed instance
To use a component from GitLab.com in a self-managed instance, you can mirror the GitLab.com
component in your self-managed instance:
The CI/CD catalog of a fresh install of a GitLab instance starts with no published CI/CD components.
To populate your instance's catalog, you can:
- [Publish your own components](#publish-a-component-project).
- Mirror components from GitLab.com in your self-managed instance.
To mirror a GitLab.com component in your self-managed instance:
1. Make sure that [network outbound requests](../../security/webhooks.md) are allowed for `gitlab.com`.
1. [Create a group](../../user/group/index.md#create-a-group) to host the component projects (recommended group: `components`).
1. [Create a mirror of the component project](../../user/project/repository/mirror/index.md) in the new group.
1. Write a [project description](../../user/project/working_with_projects.md#edit-project-name-and-description)
for the component project mirror because mirroring repositories does not copy the description.
for the component project mirror because mirroring repositories does not copy the description.
1. [Set the self-hosted component project as a catalog resource](#set-a-component-project-as-a-catalog-project).
1. Publish [a new release](../../user/project/releases/index.md) in the self-hosted component project by
[running a pipeline](../pipelines/index.md#run-a-pipeline-manually) for a tag (usually the latest tag).
[running a pipeline](../pipelines/index.md#run-a-pipeline-manually) for a tag (usually the latest tag).
## Troubleshooting

View File

@ -14,6 +14,15 @@ in the backend. This allows the frontend to simply consume the API and display t
## Add a new check
When adding a new merge check, we must make a few choices:
- Is this check skippable, and part of the **Merge when checks pass** feature?
- Is this check cacheable?
- If so, what is an appropriate cache key?
- Does this check have a setting to turn this check on or off?
After we answer these questions, we can create the new check.
The mergeability checks live under `app/services/merge_requests/mergeability/`.
1. To create a new check, we can use this as a base:
@ -23,8 +32,8 @@ The mergeability checks live under `app/services/merge_requests/mergeability/`.
module MergeRequests
module Mergeability
class CheckCiStatusService < CheckBaseService
identifier :ci_must_pass
description 'Checks whether CI has passed'
identifier :ci_must_pass # Identifier used to state which check failed
description 'Checks whether CI has passed' # Description of the check returned through GraphQL
def execute
# If the merge check is behind a setting, we return inactive if the setting is false
@ -43,6 +52,8 @@ The mergeability checks live under `app/services/merge_requests/mergeability/`.
params[:skip_ci_check].present?
end
# If we return true here, we need to create the method def cache_key and provide
# an approriate cache key that will invalidate correctly.
def cacheable?
false
end
@ -78,6 +89,13 @@ The mergeability checks live under `app/services/merge_requests/mergeability/`.
1. These methods call the `RunChecksService` class which handles the iterating
of the mergeability checks, caching and instrumentation.
## Merge when checks pass
When we want to add the check to the Merge When Checks Pass feature, we must:
1. Allow the check to be skipped in the class.
1. Add the parameter to the list in the method `skipped_mergeable_checks`.
## Future work
1. At the moment, the slow performance of the approval check is the main area of

View File

@ -119,3 +119,7 @@ Style/RegexpLiteralMixedPreserve:
# See https://gitlab.com/gitlab-org/gitlab/-/issues/435940#note_1703307479
Style/HashSyntax:
EnforcedShorthandSyntax: never
# This cop doesn't make sense in the context of gems
Migration/EnsureFactoryForTable:
Enabled: false

View File

@ -1891,6 +1891,9 @@ msgstr ""
msgid "A member of the abuse team will review your report as soon as possible."
msgstr ""
msgid "A merge request (MR) is a proposal to incorporate changes from a source branch to a target branch."
msgstr ""
msgid "A new Auto DevOps pipeline has been created, go to the Pipelines page for details"
msgstr ""
@ -14881,6 +14884,9 @@ msgstr ""
msgid "Create a new issue"
msgstr ""
msgid "Create a new merge request"
msgstr ""
msgid "Create a new project"
msgstr ""
@ -19071,6 +19077,9 @@ msgstr ""
msgid "Edit public deploy key"
msgstr ""
msgid "Edit release"
msgstr ""
msgid "Edit sidebar"
msgstr ""
@ -19086,9 +19095,6 @@ msgstr ""
msgid "Edit this file only."
msgstr ""
msgid "Edit this release"
msgstr ""
msgid "Edit title and description"
msgstr ""
@ -29731,6 +29737,9 @@ msgstr ""
msgid "Learn more about max seats used"
msgstr ""
msgid "Learn more about merge requests"
msgstr ""
msgid "Learn more about seats owed"
msgstr ""
@ -57331,6 +57340,9 @@ msgstr ""
msgid "When using the %{code_open}ssh://%{code_close} protocol, please use the following format: %{code_open}ssh://username@example.com/group/project.git%{code_close}."
msgstr ""
msgid "When you open a merge request, you can visualize and collaborate on the changes before merge."
msgstr ""
msgid "When you transfer your project to a group, you can easily manage multiple projects, view usage quotas for storage, pipeline minutes, and users, and start a trial or upgrade to a paid tier."
msgstr ""

View File

@ -4,7 +4,7 @@ module QA
module Page
module MergeRequest
class Index < Page::Base
view 'app/views/shared/empty_states/_merge_requests.html.haml' do
view 'app/views/shared/empty_states/_empty_merge_requests_without_filters.html.haml' do
element 'new-merge-request-button'
end

View File

@ -1,10 +1,14 @@
# frozen_string_literal: true
require_relative '../../code_reuse_helpers'
module RuboCop
module Cop
module Migration
# Checks for `create_table` calls without a corresponding factory.
#
# This check is skipped when `ee/` directory is not present.
#
# @example
#
# # bad
@ -25,26 +29,38 @@ module RuboCop
# end
# # spec/factories/users.rb exists
class EnsureFactoryForTable < RuboCop::Cop::Base
MSG = %(No factory found for the table `%s`.)
include CodeReuseHelpers
def_node_matcher :table_definition?, <<~PATTERN
(send nil? :create_table ...)
MSG = 'No factory found for the table `%{name}`.'
RESTRICT_ON_SEND = %i[create_table].to_set.freeze
def_node_matcher :table_definition, <<~PATTERN
(send nil? RESTRICT_ON_SEND ${(sym $_) (str $_)} ...)
PATTERN
def on_send(node)
return unless table_definition?(node)
# Migrations for EE models don't have factories in CE.
return unless ee?
table_name_node = node.arguments.first
return unless table_name_node.str_type? || table_name_node.sym_type?
table_definition(node) do |table_name_node, table_name|
unless factory?(table_name.to_s)
msg = format(MSG, name: table_name)
add_offense(table_name_node, message: msg)
end
end
end
table_name = table_name_node.value
factory_file_name = "#{table_name}.rb"
factories_directory = File.join('spec', 'factories')
return unless Dir.exist?(factories_directory)
private
return if Dir.glob("{,ee/,jh/}spec/factories/**/#{factory_file_name}").any?
def factory?(table_name)
end_with = "/#{table_name}.rb"
add_offense(node, message: MSG % table_name)
self.class.factories.any? { |path| path.end_with?(end_with) }
end
def self.factories
@factories ||= Dir.glob("{,ee/,jh/}spec/factories/**/*.rb")
end
end
end

View File

@ -4,26 +4,75 @@ require 'rubocop_spec_helper'
require_relative '../../../../rubocop/cop/migration/ensure_factory_for_table'
RSpec.describe RuboCop::Cop::Migration::EnsureFactoryForTable, feature_category: :database do
it 'registers an offense when a table does not have a corresponding factory' do
allow(Dir).to receive(:glob).and_return([])
context 'with faked factories' do
let(:ee) { true }
expect_offense(<<~RUBY)
create_table :users do |t|
^^^^^^^^^^^^^^^^^^^ No factory found for the table `users`.
t.string :name
t.timestamps
before do
allow(described_class).to receive(:factories).and_return(factories)
allow(cop).to receive(:ee?).and_return(ee)
end
context 'without matching factories' do
let(:factories) { [] }
it 'registers an offense when a table does not have a corresponding factory' do
expect_offense(<<~RUBY)
create_table :users do |t|
^^^^^^ No factory found for the table `users`.
t.string :name
t.timestamps
end
create_table "users" do |t|
^^^^^^^ No factory found for the table `users`.
t.string :name
t.timestamps
end
RUBY
end
RUBY
it 'does not register an offense for non-string and non-symbol table name' do
expect_no_offenses(<<~RUBY)
TABLE = :users
create_table TABLE do |t|
t.string :name
t.timestamps
end
RUBY
end
context 'when non-EE' do
let(:ee) { false }
it 'does not register an offense' do
expect_no_offenses(<<~RUBY)
create_table :users do |t|
t.string :name
t.timestamps
end
RUBY
end
end
end
context 'with matching factories' do
let(:factories) { ['spec/factories/users.rb'] }
it 'does not register an offense when a table has a corresponding factory' do
expect_no_offenses(<<~RUBY)
create_table :users do |t|
t.string :name
t.timestamps
end
RUBY
end
end
end
it 'does not register an offense when a table has a corresponding factory' do
allow(Dir).to receive(:glob).and_return(['users.rb'])
describe '.factories' do
subject { described_class.factories }
expect_no_offenses(<<~RUBY)
create_table :users do |t|
t.string :name
t.timestamps
end
RUBY
it { is_expected.not_to be_empty }
end
end

View File

@ -917,7 +917,6 @@
- './ee/spec/helpers/license_monitoring_helper_spec.rb'
- './ee/spec/helpers/manual_quarterly_co_term_banner_helper_spec.rb'
- './ee/spec/helpers/markup_helper_spec.rb'
- './ee/spec/helpers/merge_requests_helper_spec.rb'
- './ee/spec/helpers/notes_helper_spec.rb'
- './ee/spec/helpers/path_locks_helper_spec.rb'
- './ee/spec/helpers/preferences_helper_spec.rb'