Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2025-03-11 21:09:32 +00:00
parent 08d259cc2b
commit 84f5d32c70
61 changed files with 919 additions and 103 deletions

View File

@ -87,6 +87,7 @@
# by checking code patterns, skip running job on changes that can't affect the outcome # by checking code patterns, skip running job on changes that can't affect the outcome
- *mr-code-patterns - *mr-code-patterns
- *default-branch - *default-branch
- *mr-stable-branch-code-patterns
.rules:test:update-patch: .rules:test:update-patch:
rules: rules:

View File

@ -6,6 +6,15 @@ import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
export default { export default {
i18n: {
addIntegrationTitle: s__('Integrations|Add integration'),
addIntegrationAriaLabel: (title) =>
sprintf(s__('Integrations|Add new %{title} integration'), { title }),
addIntegrationText: __('Add'),
configureIntegrationText: __('Configure'),
configureIntegrationAriaLabel: (title) =>
sprintf(s__('Integrations|Configure %{title}'), { title }),
},
components: { components: {
GlAvatar, GlAvatar,
GlAvatarLink, GlAvatarLink,
@ -50,8 +59,8 @@ export default {
fields.push( fields.push(
{ {
key: 'active', key: 'active',
label: '', label: __('Active'),
thClass: 'gl-w-7', thClass: 'gl-w-7 gl-sr-only',
tdClass: '!gl-border-b-0 !gl-align-middle', tdClass: '!gl-border-b-0 !gl-align-middle',
}, },
{ {
@ -74,8 +83,8 @@ export default {
fields.push({ fields.push({
key: 'edit_path', key: 'edit_path',
label: '', label: __('Actions'),
thClass: 'gl-w-15', thClass: 'gl-w-15 gl-sr-only',
tdClass: '!gl-border-b-0 gl-text-right !gl-align-middle', tdClass: '!gl-border-b-0 gl-text-right !gl-align-middle',
}); });
@ -140,12 +149,15 @@ export default {
:entity-name="item.title" :entity-name="item.title"
:alt="item.title" :alt="item.title"
:size="48" :size="48"
aria-hidden="true"
shape="rect" shape="rect"
class="integration-logo" class="integration-logo"
/> />
<div class="gl-flex gl-flex-col gl-gap-2"> <div class="gl-flex gl-flex-col gl-gap-2">
<h3 class="gl-heading-4 gl-my-1">{{ item.title }}</h3> <h3 class="gl-heading-4 gl-my-1">{{ item.title }}</h3>
<p class="gl-mb-0 gl-text-subtle">{{ item.description }}</p> <p :id="`${item.edit_path}-description`" class="gl-mb-0 gl-text-subtle">
{{ item.description }}
</p>
</div> </div>
</gl-avatar-link> </gl-avatar-link>
</template> </template>
@ -166,8 +178,10 @@ export default {
:href="item.edit_path" :href="item.edit_path"
category="secondary" category="secondary"
icon="plus" icon="plus"
:title="s__('Integrations|Add integration')" :title="$options.i18n.addIntegrationTitle"
>{{ __('Add') }}</gl-button :aria-label="$options.i18n.addIntegrationAriaLabel(item.title)"
:aria-describedby="`${item.edit_path}-description`"
>{{ $options.i18n.addIntegrationText }}</gl-button
> >
<gl-button <gl-button
v-else v-else
@ -175,8 +189,10 @@ export default {
tabindex="-1" tabindex="-1"
:href="item.edit_path" :href="item.edit_path"
category="secondary" category="secondary"
:aria-describedby="`${item.edit_path}-description`"
icon="settings" icon="settings"
:title="__('Configure')" :title="$options.i18n.configureIntegrationText"
:aria-label="$options.i18n.configureIntegrationAriaLabel(item.title)"
/> />
</template> </template>
</gl-table> </gl-table>

View File

@ -23,18 +23,26 @@ export default {
return this.cell.source || ''; return this.cell.source || '';
}, },
hasOutput() { hasOutput() {
return this.cell.outputs.length; return this.cell.outputs?.length;
}, },
outputs() { outputs() {
return this.cell.outputs; return this.cell.outputs;
}, },
language() {
return this.cell.cell_type === 'raw' ? 'txt' : 'python';
},
}, },
}; };
</script> </script>
<template> <template>
<div class="cell"> <div class="cell">
<code-output :raw-code="rawInputCode" :count="cell.execution_count" type="input" /> <code-output
:raw-code="rawInputCode"
:count="cell.execution_count"
type="input"
:language="language"
/>
<output-cell <output-cell
v-if="hasOutput" v-if="hasOutput"
:count="cell.execution_count" :count="cell.execution_count"

View File

@ -27,6 +27,11 @@ export default {
default: () => ({}), default: () => ({}),
required: false, required: false,
}, },
language: {
type: String,
required: false,
default: 'python',
},
}, },
computed: { computed: {
code() { code() {
@ -48,7 +53,7 @@ export default {
<div :class="type"> <div :class="type">
<prompt :type="promptType" :count="count" /> <prompt :type="promptType" :count="count" />
<code-block-highlighted <code-block-highlighted
language="python" :language="language"
:code="code" :code="code"
:max-height="maxHeight" :max-height="maxHeight"
class="gl-border !gl-p-4" class="gl-border !gl-p-4"

View File

@ -35,6 +35,9 @@ export default {
}, },
methods: { methods: {
cellType(type) { cellType(type) {
if (type === 'raw') {
return 'code-cell';
}
return `${type}-cell`; // eslint-disable-line @gitlab/require-i18n-strings return `${type}-cell`; // eslint-disable-line @gitlab/require-i18n-strings
}, },
}, },

View File

@ -332,6 +332,7 @@ export default {
:work-item-type="workItemType" :work-item-type="workItemType"
:full-path="fullPath" :full-path="fullPath"
:can-update="canUpdateMetadata" :can-update="canUpdateMetadata"
:is-group="isGroup"
@error="$emit('error', $event)" @error="$emit('error', $event)"
/> />
<work-item-parent <work-item-parent

View File

@ -15,6 +15,10 @@
# ids: int[] # ids: int[]
# with_issues_enabled: boolean # with_issues_enabled: boolean
# with_merge_requests_enabled: boolean # with_merge_requests_enabled: boolean
# not_aimed_for_deletion: boolean
# include_sibling_projects: boolean
# with_namespace_domain_pages: boolean
# archived_only: boolean
# #
module Namespaces module Namespaces
class ProjectsFinder class ProjectsFinder
@ -64,6 +68,8 @@ module Namespaces
end end
def by_archived(items) def by_archived(items)
return items.archived if Gitlab::Utils.to_boolean(params[:archived_only], default: false)
return items if Gitlab::Utils.to_boolean(params[:include_archived], default: true) return items if Gitlab::Utils.to_boolean(params[:include_archived], default: true)
items.non_archived items.non_archived

View File

@ -50,6 +50,10 @@ module Resolvers
required: false, required: false,
description: "Return only projects that use the namespace domain for pages projects." description: "Return only projects that use the namespace domain for pages projects."
argument :archived_only, GraphQL::Types::Boolean,
required: false,
description: "Return only archived projects."
type Types::ProjectType, null: true type Types::ProjectType, null: true
def resolve(args) def resolve(args)
@ -88,7 +92,8 @@ module Resolvers
ids: parse_gids(args[:ids]), ids: parse_gids(args[:ids]),
with_issues_enabled: args[:with_issues_enabled], with_issues_enabled: args[:with_issues_enabled],
with_merge_requests_enabled: args[:with_merge_requests_enabled], with_merge_requests_enabled: args[:with_merge_requests_enabled],
with_namespace_domain_pages: args[:with_namespace_domain_pages] with_namespace_domain_pages: args[:with_namespace_domain_pages],
archived_only: args[:archived_only]
} }
end end

View File

@ -41,16 +41,13 @@ class BulkImports::Entity < ApplicationRecord
inverse_of: :entity, inverse_of: :entity,
foreign_key: :bulk_import_entity_id foreign_key: :bulk_import_entity_id
validates :project, absence: true, if: :group
validates :group, absence: true, if: :project
validates :source_type, presence: true validates :source_type, presence: true
validates :source_full_path, presence: true validates :source_full_path, presence: true
validates :destination_name, presence: true, if: -> { group || project } validates :destination_name, presence: true, if: -> { group || project }
validates :destination_namespace, exclusion: [nil], if: :group validates :destination_namespace, exclusion: [nil], if: :group
validates :destination_namespace, presence: true, if: :project? validates :destination_namespace, presence: true, if: :project?
# TODO: Remove `on: :create` once the post migration SetOrganizationIdForBulkImportEntities has run validate :validate_only_one_sharding_key_present
validate :validate_only_one_sharding_key_present, on: :create
validate :validate_parent_is_a_group, if: :parent validate :validate_parent_is_a_group, if: :parent
validate :validate_imported_entity_type validate :validate_imported_entity_type
validate :validate_destination_namespace_ascendency, if: :group_entity? validate :validate_destination_namespace_ascendency, if: :group_entity?

View File

@ -0,0 +1,20 @@
# frozen_string_literal: true
# This model stores projects for which any pipeline variables have been set.
# Its purpose is to assist in the migration process of setting pipeline variables.
# The minimum override role is set to `no_one_allowed` for projects that haven't used pipeline variables.
module Ci
class ProjectWithPipelineVariable < ::ApplicationRecord
self.table_name = 'projects_with_pipeline_variables'
self.primary_key = :project_id
belongs_to :project
def self.upsert_for_pipeline(pipeline)
return unless pipeline.variables.any?
upsert({ project_id: pipeline.project_id }, unique_by: :project_id)
end
end
end

View File

@ -17,6 +17,7 @@ module Ci
Ci::UpdateBuildNamesWorker.perform_async(pipeline.id) Ci::UpdateBuildNamesWorker.perform_async(pipeline.id)
Ci::ProcessPipelineService.new(pipeline).execute Ci::ProcessPipelineService.new(pipeline).execute
Ci::ProjectWithPipelineVariable.upsert_for_pipeline(pipeline)
end end
end end
end end

View File

@ -0,0 +1,9 @@
---
name: push_rule_file_size_limit
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/505364
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/183600
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/523497
milestone: '17.10'
type: gitlab_com_derisk
group: group::source code
default_enabled: false

View File

@ -535,6 +535,10 @@ projects_visits:
- table: users - table: users
column: user_id column: user_id
on_delete: async_delete on_delete: async_delete
projects_with_pipeline_variables:
- table: projects
column: project_id
on_delete: async_delete
push_rules: push_rules:
- table: organizations - table: organizations
column: organization_id column: organization_id

View File

@ -0,0 +1,24 @@
- title: "S3 storage driver (AWS SDK v1) for the container registry"
announcement_milestone: "17.10"
removal_milestone: "18.0"
breaking_change: true
reporter: trizzi
stage: Package
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/523095
impact: low
scope: instance
resolution_role: maintainer
manual_task: true
window: "3"
body: |
The S3 storage driver for the container registry that uses AWS SDK v1 is deprecated and will be removed in GitLab 18.0. If you use S3 object storage for your container registry, you'll need to update your configuration to use the new `s3_v2` driver.
The `s3_v2` storage driver is based on AWS SDK v2 and provides improved performance, better security, and continued support from AWS. It will be available starting May 2025 to replace the deprecated [AWS SDK v1](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-go-v1-on-july-31-2025/), which reaches end-of-support on July 31, 2025.
To migrate to the `s3_v2` driver:
1. Update your registry configuration file to use the `s3_v2` configuration instead of `s3`.
1. Move from Signature Version 2 to Signature Version 4 for authentication if you haven't already, as AWS SDK v2 only supports Signature Version 4.
1. Test the configuration in a non-production environment before deploying to production.
For more information about updating your storage driver configuration, see [use object storage](https://docs.gitlab.com/administration/packages/container_registry/#use-object-storage).

View File

@ -0,0 +1,14 @@
---
table_name: projects_with_pipeline_variables
classes:
- Ci::ProjectWithPipelineVariable
feature_categories:
- ci_variables
description: A model that stores projects for which any pipeline variables have been
set.
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176022
milestone: '17.10'
gitlab_schema: gitlab_main_cell
sharding_key:
project_id: projects
table_size: small

View File

@ -12,14 +12,6 @@ schema_inconsistencies:
- type: missing_indexes - type: missing_indexes
object_name: index_vulnerability_state_transitions_resolved_activity object_name: index_vulnerability_state_transitions_resolved_activity
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176561 introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176561
desired_sharding_key:
project_id:
references: projects
backfill_via:
parent:
foreign_key: vulnerability_id
table: vulnerabilities
sharding_key: project_id
belongs_to: vulnerability
desired_sharding_key_migration_job_name: BackfillVulnerabilityStateTransitionsProjectId
table_size: medium table_size: medium
sharding_key:
project_id: projects

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
class AddProjectIdToMergeRequestDiffFiles < Gitlab::Database::Migration[2.2]
include Gitlab::Database::SchemaHelpers
include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
disable_ddl_transaction!
milestone '17.10'
SOURCE_TABLE = :merge_request_diff_files
INDEX_NAME = 'index_merge_request_diff_files_on_project_id'
def up
with_lock_retries do
add_column SOURCE_TABLE, :project_id, :bigint, if_not_exists: true
end
add_concurrent_foreign_key SOURCE_TABLE, :projects, column: :project_id, on_delete: :cascade
end
def down
with_lock_retries do
remove_foreign_key_if_exists :SOURCE_TABLE, column: :parent_id
remove_column SOURCE_TABLE, :project_id
end
end
end

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
class CreateCiProjectsWithPipelineVariables < Gitlab::Database::Migration[2.2]
milestone '17.10'
def change
create_table(:projects_with_pipeline_variables, if_not_exists: true, id: false) do |t| # rubocop:disable Migration/EnsureFactoryForTable -- factory at ci/project_with_pipeline_variable.rb
t.references :project, primary_key: true, default: nil, index: false, foreign_key: { on_delete: :cascade }
end
end
end

View File

@ -0,0 +1,14 @@
# frozen_string_literal: true
class AddVulnerabilityStateTransitionsProjectIdNotNull < Gitlab::Database::Migration[2.2]
milestone '17.10'
disable_ddl_transaction!
def up
add_not_null_constraint :vulnerability_state_transitions, :project_id
end
def down
remove_not_null_constraint :vulnerability_state_transitions, :project_id
end
end

View File

@ -0,0 +1,20 @@
# frozen_string_literal: true
class AddAsyncIndexToMergeRequestDiffFiles < Gitlab::Database::Migration[2.2]
milestone '17.10'
disable_ddl_transaction!
SOURCE_TABLE = :merge_request_diff_files
INDEX_NAME = 'index_merge_request_diff_files_on_project_id'
def up
# TODO: Index to be created synchronously in https://gitlab.com/gitlab-org/gitlab/-/issues/523103
#
prepare_async_index SOURCE_TABLE, :project_id, name: INDEX_NAME
end
def down
unprepare_async_index SOURCE_TABLE, INDEX_NAME
end
end

View File

@ -0,0 +1 @@
5dca226bd37620547046b42f0fcf4aa3fba9e6867b18f8a7770dcc1b5a7495a9

View File

@ -0,0 +1 @@
5a1ff535b4a4b36c1c3a3be15233f01c121ad53085668cc248dec54c7e1c0649

View File

@ -0,0 +1 @@
c5df195c7e77dad61e2bbea848217c868376e1ecea181e83b34d051a3b1085ef

View File

@ -0,0 +1 @@
4230f04b0a07fe3179df158cb7e94d9d343ff26e28e33e51154d141c3ad70710

View File

@ -16299,7 +16299,8 @@ CREATE TABLE merge_request_diff_files (
external_diff_offset integer, external_diff_offset integer,
external_diff_size integer, external_diff_size integer,
generated boolean, generated boolean,
encoded_file_path boolean DEFAULT false NOT NULL encoded_file_path boolean DEFAULT false NOT NULL,
project_id bigint
); );
CREATE TABLE merge_request_diffs ( CREATE TABLE merge_request_diffs (
@ -20554,6 +20555,10 @@ CREATE SEQUENCE projects_visits_id_seq
ALTER SEQUENCE projects_visits_id_seq OWNED BY projects_visits.id; ALTER SEQUENCE projects_visits_id_seq OWNED BY projects_visits.id;
CREATE TABLE projects_with_pipeline_variables (
project_id bigint NOT NULL
);
CREATE TABLE protected_branch_merge_access_levels ( CREATE TABLE protected_branch_merge_access_levels (
id bigint NOT NULL, id bigint NOT NULL,
protected_branch_id bigint NOT NULL, protected_branch_id bigint NOT NULL,
@ -24083,6 +24088,7 @@ CREATE TABLE vulnerability_state_transitions (
comment text, comment text,
dismissal_reason smallint, dismissal_reason smallint,
project_id bigint, project_id bigint,
CONSTRAINT check_b6338547d4 CHECK ((project_id IS NOT NULL)),
CONSTRAINT check_fe2eb6a0f3 CHECK ((char_length(comment) <= 50000)) CONSTRAINT check_fe2eb6a0f3 CHECK ((char_length(comment) <= 50000))
); );
@ -29184,6 +29190,9 @@ ALTER TABLE ONLY projects_sync_events
ALTER TABLE ONLY projects_visits ALTER TABLE ONLY projects_visits
ADD CONSTRAINT projects_visits_pkey PRIMARY KEY (id, visited_at); ADD CONSTRAINT projects_visits_pkey PRIMARY KEY (id, visited_at);
ALTER TABLE ONLY projects_with_pipeline_variables
ADD CONSTRAINT projects_with_pipeline_variables_pkey PRIMARY KEY (project_id);
ALTER TABLE ONLY protected_branch_merge_access_levels ALTER TABLE ONLY protected_branch_merge_access_levels
ADD CONSTRAINT protected_branch_merge_access_levels_pkey PRIMARY KEY (id); ADD CONSTRAINT protected_branch_merge_access_levels_pkey PRIMARY KEY (id);
@ -39314,6 +39323,9 @@ ALTER TABLE ONLY subscription_user_add_on_assignments
ALTER TABLE ONLY approval_project_rules_users ALTER TABLE ONLY approval_project_rules_users
ADD CONSTRAINT fk_0dfcd9e339 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; ADD CONSTRAINT fk_0dfcd9e339 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY merge_request_diff_files
ADD CONSTRAINT fk_0e3ba01603 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY ci_runner_projects ALTER TABLE ONLY ci_runner_projects
ADD CONSTRAINT fk_0e743433ff FOREIGN KEY (runner_id) REFERENCES ci_runners_archived(id) ON DELETE CASCADE; ADD CONSTRAINT fk_0e743433ff FOREIGN KEY (runner_id) REFERENCES ci_runners_archived(id) ON DELETE CASCADE;
@ -43094,6 +43106,9 @@ ALTER TABLE ONLY audit_events_streaming_event_type_filters
ALTER TABLE ONLY description_versions ALTER TABLE ONLY description_versions
ADD CONSTRAINT fk_rails_e8f4caf9c7 FOREIGN KEY (epic_id) REFERENCES epics(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_e8f4caf9c7 FOREIGN KEY (epic_id) REFERENCES epics(id) ON DELETE CASCADE;
ALTER TABLE ONLY projects_with_pipeline_variables
ADD CONSTRAINT fk_rails_e9080b2336 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY merge_request_blocks ALTER TABLE ONLY merge_request_blocks
ADD CONSTRAINT fk_rails_e9387863bc FOREIGN KEY (blocking_merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE; ADD CONSTRAINT fk_rails_e9387863bc FOREIGN KEY (blocking_merge_request_id) REFERENCES merge_requests(id) ON DELETE CASCADE;

View File

@ -539,6 +539,23 @@ Get information about current user.
Returns [`CurrentUser`](#currentuser). Returns [`CurrentUser`](#currentuser).
### `Query.customField`
Find a custom field by its ID. Available only when feature flag `custom_fields_feature` is enabled.
{{< details >}}
**Introduced** in GitLab 17.10.
**Status**: Experiment.
{{< /details >}}
Returns [`CustomField`](#customfield).
#### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="querycustomfieldid"></a>`id` | [`IssuablesCustomFieldID!`](#issuablescustomfieldid) | Global ID of the custom field. |
### `Query.designManagement` ### `Query.designManagement`
Fields related to design management. Fields related to design management.
@ -27803,6 +27820,7 @@ four standard [pagination arguments](#pagination-arguments):
| Name | Type | Description | | Name | Type | Description |
| ---- | ---- | ----------- | | ---- | ---- | ----------- |
| <a id="groupprojectsarchivedonly"></a>`archivedOnly` | [`Boolean`](#boolean) | Return only archived projects. |
| <a id="groupprojectscomplianceframeworkfilters"></a>`complianceFrameworkFilters` | [`ComplianceFrameworkFilters`](#complianceframeworkfilters) | Filters applied when selecting a compliance framework. | | <a id="groupprojectscomplianceframeworkfilters"></a>`complianceFrameworkFilters` | [`ComplianceFrameworkFilters`](#complianceframeworkfilters) | Filters applied when selecting a compliance framework. |
| <a id="groupprojectshascodecoverage"></a>`hasCodeCoverage` | [`Boolean`](#boolean) | Returns only the projects which have code coverage. | | <a id="groupprojectshascodecoverage"></a>`hasCodeCoverage` | [`Boolean`](#boolean) | Returns only the projects which have code coverage. |
| <a id="groupprojectshasvulnerabilities"></a>`hasVulnerabilities` | [`Boolean`](#boolean) | Returns only the projects which have vulnerabilities. | | <a id="groupprojectshasvulnerabilities"></a>`hasVulnerabilities` | [`Boolean`](#boolean) | Returns only the projects which have vulnerabilities. |
@ -28459,6 +28477,7 @@ four standard [pagination arguments](#pagination-arguments):
| Name | Type | Description | | Name | Type | Description |
| ---- | ---- | ----------- | | ---- | ---- | ----------- |
| <a id="groupdoraprojectsarchivedonly"></a>`archivedOnly` | [`Boolean`](#boolean) | Return only archived projects. |
| <a id="groupdoraprojectscomplianceframeworkfilters"></a>`complianceFrameworkFilters` | [`ComplianceFrameworkFilters`](#complianceframeworkfilters) | Filters applied when selecting a compliance framework. | | <a id="groupdoraprojectscomplianceframeworkfilters"></a>`complianceFrameworkFilters` | [`ComplianceFrameworkFilters`](#complianceframeworkfilters) | Filters applied when selecting a compliance framework. |
| <a id="groupdoraprojectsenddate"></a>`endDate` | [`Date!`](#date) | Date range to end DORA lookup at. | | <a id="groupdoraprojectsenddate"></a>`endDate` | [`Date!`](#date) | Date range to end DORA lookup at. |
| <a id="groupdoraprojectshascodecoverage"></a>`hasCodeCoverage` | [`Boolean`](#boolean) | Returns only the projects which have code coverage. | | <a id="groupdoraprojectshascodecoverage"></a>`hasCodeCoverage` | [`Boolean`](#boolean) | Returns only the projects which have code coverage. |
@ -32133,6 +32152,30 @@ four standard [pagination arguments](#pagination-arguments):
| <a id="namespacecomplianceframeworksids"></a>`ids` | [`[ComplianceManagementFrameworkID!]`](#compliancemanagementframeworkid) | List of Global IDs of compliance frameworks to return. | | <a id="namespacecomplianceframeworksids"></a>`ids` | [`[ComplianceManagementFrameworkID!]`](#compliancemanagementframeworkid) | List of Global IDs of compliance frameworks to return. |
| <a id="namespacecomplianceframeworkssearch"></a>`search` | [`String`](#string) | Search framework with most similar names. | | <a id="namespacecomplianceframeworkssearch"></a>`search` | [`String`](#string) | Search framework with most similar names. |
##### `Namespace.customFields`
Custom fields configured for the namespace. Available only when feature flag `custom_fields_feature` is enabled.
{{< details >}}
**Introduced** in GitLab 17.10.
**Status**: Experiment.
{{< /details >}}
Returns [`CustomFieldConnection`](#customfieldconnection).
This field returns a [connection](#connections). It accepts the
four standard [pagination arguments](#pagination-arguments):
`before: String`, `after: String`, `first: Int`, and `last: Int`.
###### Arguments
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="namespacecustomfieldsactive"></a>`active` | [`Boolean`](#boolean) | Filter for active fields. If `false`, excludes active fields. If `true`, returns only active fields. |
| <a id="namespacecustomfieldsfieldtype"></a>`fieldType` | [`CustomFieldType`](#customfieldtype) | Filter for selected field type. |
| <a id="namespacecustomfieldssearch"></a>`search` | [`String`](#string) | Search query for custom field name. |
| <a id="namespacecustomfieldsworkitemtypeids"></a>`workItemTypeIds` | [`[WorkItemsTypeID!]`](#workitemstypeid) | Filter custom fields associated to any of the given work item types. If empty, returns custom fields not associated to any work item type. |
##### `Namespace.importSourceUsers` ##### `Namespace.importSourceUsers`
Import source users of the namespace. This field can only be resolved for one namespace in any single request. Import source users of the namespace. This field can only be resolved for one namespace in any single request.
@ -32205,6 +32248,7 @@ four standard [pagination arguments](#pagination-arguments):
| Name | Type | Description | | Name | Type | Description |
| ---- | ---- | ----------- | | ---- | ---- | ----------- |
| <a id="namespaceprojectsarchivedonly"></a>`archivedOnly` | [`Boolean`](#boolean) | Return only archived projects. |
| <a id="namespaceprojectscomplianceframeworkfilters"></a>`complianceFrameworkFilters` | [`ComplianceFrameworkFilters`](#complianceframeworkfilters) | Filters applied when selecting a compliance framework. | | <a id="namespaceprojectscomplianceframeworkfilters"></a>`complianceFrameworkFilters` | [`ComplianceFrameworkFilters`](#complianceframeworkfilters) | Filters applied when selecting a compliance framework. |
| <a id="namespaceprojectshascodecoverage"></a>`hasCodeCoverage` | [`Boolean`](#boolean) | Returns only the projects which have code coverage. | | <a id="namespaceprojectshascodecoverage"></a>`hasCodeCoverage` | [`Boolean`](#boolean) | Returns only the projects which have code coverage. |
| <a id="namespaceprojectshasvulnerabilities"></a>`hasVulnerabilities` | [`Boolean`](#boolean) | Returns only the projects which have vulnerabilities. | | <a id="namespaceprojectshasvulnerabilities"></a>`hasVulnerabilities` | [`Boolean`](#boolean) | Returns only the projects which have vulnerabilities. |

View File

@ -80,8 +80,8 @@ left side of the documentation website). To do so, open a second MR, against the
[GitLab documentation repository](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/). [GitLab documentation repository](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/).
The global navigation is set in the The global navigation is set in the
[`navigation.yaml`](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/blob/main/data/navigation.yaml) file, [`navigation.yaml`](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/blob/main/data/en-us/navigation.yaml) file,
in the `content/data` subdirectory. You can find the GraphQL section under the in the `content/data/en-us` subdirectory. You can find the GraphQL section under the
following line: following line:
```yaml ```yaml

View File

@ -84,7 +84,7 @@ See the Google [Best practices for creating quality meta descriptions](https://d
## Avoid pages being added to global navigation ## Avoid pages being added to global navigation
If a specific page shouldn't be added to the global navigation (have an entry added to If a specific page shouldn't be added to the global navigation (have an entry added to
[`navigation.yaml`](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/blob/main/data/navigation.yaml), add [`navigation.yaml`](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/blob/main/data/en-us/navigation.yaml), add
the following to the page's metadata: the following to the page's metadata:
```yaml ```yaml

View File

@ -36,7 +36,7 @@ In the Markdown doc for a resource (AKA endpoint):
description also has both offering and tier, combine them. For description also has both offering and tier, combine them. For
example: _GitLab Self-Managed, Premium and Ultimate only._ example: _GitLab Self-Managed, Premium and Ultimate only._
After a new API documentation page is added, [add an entry in the global navigation](site_architecture/global_nav.md#add-a-navigation-entry). [Examples](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/commits/main/data/navigation.yaml). After a new API documentation page is added, [add an entry in the global navigation](site_architecture/global_nav.md#add-a-navigation-entry). [Examples](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/commits/main/data/en-us/navigation.yaml).
## API topic template ## API topic template

View File

@ -40,7 +40,7 @@ as helpful as **Get started with runners**.
## Add a navigation entry ## Add a navigation entry
The global nav is stored in the `gitlab-org/technical-writing/docs-gitlab-com` project, in the The global nav is stored in the `gitlab-org/technical-writing/docs-gitlab-com` project, in the
`data/navigation.yaml` file. The documentation website at `docs.gitlab.com` is built using Hugo and assembles documentation `data/en-us/navigation.yaml` file. The documentation website at `docs.gitlab.com` is built using Hugo and assembles documentation
content from several projects (including `charts`, `gitlab`, `gitlab-runner`, and `omnibus-gitlab`). content from several projects (including `charts`, `gitlab`, `gitlab-runner`, and `omnibus-gitlab`).
**Do not** add items to the global nav without **Do not** add items to the global nav without
@ -48,7 +48,7 @@ the consent of one of the technical writers.
To add a topic to the global navigation: To add a topic to the global navigation:
1. In the [`navigation.yaml`](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/blob/main/data/navigation.yaml) 1. In the [`navigation.yaml`](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/blob/main/data/en-us/navigation.yaml)
file, add the item. file, add the item.
1. Assign the MR to a technical writer for review and merge. 1. Assign the MR to a technical writer for review and merge.
@ -90,7 +90,6 @@ mechanics of what is required is [documented below](#data-file) but, in principl
Exclude these pages from the global nav: Exclude these pages from the global nav:
- Legal notices. - Legal notices.
- Pages in the `architecture/blueprints` directory.
- Pages in the `user/application_security/dast/checks/` directory. - Pages in the `user/application_security/dast/checks/` directory.
The following pages should probably be in the global nav, but the technical writers The following pages should probably be in the global nav, but the technical writers
@ -106,18 +105,6 @@ All other pages should be in the global nav.
The technical writing team runs a report to determine which pages are not in the nav. The technical writing team runs a report to determine which pages are not in the nav.
The team reviews this list each month. The team reviews this list each month.
## Navigation structure
The global nav has five levels:
- Section
- Category
- Doc
- Doc
- Doc
You can view this structure in the [`navigation.yml`](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/blob/main/data/navigation.yaml?ref_type=heads) file.
### Use GitLab section ### Use GitLab section
In addition to feature documentation, each category in the **Use GitLab** section should contain: In addition to feature documentation, each category in the **Use GitLab** section should contain:
@ -148,7 +135,7 @@ The layout organizes the data among the nav in containers properly [styled](#css
### Data file ### Data file
The data file describes the structure of the navigation for the applicable project. The data file describes the structure of the navigation for the applicable project.
It is stored at <https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/blob/main/data/navigation.yaml>. It is stored at <https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/blob/main/data/en-us/navigation.yaml>.
Each entry comprises of three main components: Each entry comprises of three main components:
@ -187,7 +174,7 @@ For all components, **respect the indentation** and the following syntax rules.
- Use sentence case, capitalizing feature names. - Use sentence case, capitalizing feature names.
- There's no need to wrap the titles, unless there's a special character in it. For example, - There's no need to wrap the titles, unless there's a special character in it. For example,
in `GitLab CI/CD`, there's a `/` present, therefore, it must be wrapped in quotes. in `GitLab CI/CD`, there's a `/` present, therefore, it must be wrapped in quotes.
As convention, wrap the titles in double quotes: `category_title: "GitLab CI/CD"`. As convention, wrap the titles in double quotes: `title: "GitLab CI/CD"`.
##### URLs ##### URLs
@ -198,8 +185,7 @@ URLs must be relative. In addition:
- Match the path you see on the website. - Match the path you see on the website.
- As convention, always wrap URLs in single quotes `'url'`. - As convention, always wrap URLs in single quotes `'url'`.
To find the global nav link, from the full URL remove `https://docs.gitlab.com/`. To find the global nav link, from the full URL remove `https://docs.gitlab.com/`.
- Do not link to external URLs. We don't have link checking for external URLs, and - Do not link to external URLs. Leaving the documentation site by clicking the left navigation is a confusing user experience.
leaving the documentation site by clicking the left navigation is a confusing user experience.
Examples of relative URLs: Examples of relative URLs:
@ -230,14 +216,9 @@ The [global nav URL](#urls) has a different prefix depending on the documentatio
### CSS classes ### CSS classes
The nav is styled in the general `stylesheet.scss`. To change The nav is styled in the general `main.css` file. To change
its styles, keep them grouped for better development among the team. its styles, keep them grouped for better development among the team.
The URL components have their unique styles set by the CSS classes `.level-0`,
`.level-1`, and `.level-2`. To adjust the link's font size, padding, color, etc,
use these classes. This way we guarantee that the rules for each link do not conflict
with other rules in the stylesheets.
## Testing ## Testing
We run various checks on `navigation.yaml` in [`check-navigation.sh`](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/main/scripts/check-navigation.sh), We run various checks on `navigation.yaml` in [`check-navigation.sh`](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/main/scripts/check-navigation.sh),

View File

@ -135,7 +135,7 @@ To remove a page:
Use [feature X](link-to-docs.md) instead. Use [feature X](link-to-docs.md) instead.
``` ```
1. Edit the [`navigation.yaml`](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/blob/main/data/navigation.yaml) in `docs-gitlab-com` 1. Edit the [`navigation.yaml`](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/blob/main/data/en-us/navigation.yaml) in `docs-gitlab-com`
to remove the page's entry from the global navigation. to remove the page's entry from the global navigation.
1. Search the [Deprecations and Removals](../../../update/deprecations.md) page for 1. Search the [Deprecations and Removals](../../../update/deprecations.md) page for
links to the removed page. The links use full URLs like: `https://docs.gitlab.com/user/deprecated_page/`. links to the removed page. The links use full URLs like: `https://docs.gitlab.com/user/deprecated_page/`.

View File

@ -460,7 +460,7 @@ Add documentation for the integration:
- Add a page in `doc/user/project/integrations`. - Add a page in `doc/user/project/integrations`.
- Link it from the [Integrations overview](../../user/project/integrations/_index.md). - Link it from the [Integrations overview](../../user/project/integrations/_index.md).
- After the documentation has merged, [add an entry](../documentation/site_architecture/global_nav.md#add-a-navigation-entry) - After the documentation has merged, [add an entry](../documentation/site_architecture/global_nav.md#add-a-navigation-entry)
to the documentation navigation under [Integrations](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/blob/main/data/navigation.yaml?ref_type=heads#L2936). to the documentation navigation under [Integrations](https://gitlab.com/gitlab-org/technical-writing/docs-gitlab-com/-/blob/main/data/en-us/navigation.yaml?ref_type=heads#L2936).
You can also refer to our general [documentation guidelines](../documentation/_index.md). You can also refer to our general [documentation guidelines](../documentation/_index.md).

View File

@ -100,4 +100,5 @@ This window takes place on May 5 - 7, 2025 from 09:00 UTC to 22:00 UTC.
| [Dependency Proxy token scope enforcement](https://gitlab.com/gitlab-org/gitlab/-/issues/426887) | High | Package | Group | | [Dependency Proxy token scope enforcement](https://gitlab.com/gitlab-org/gitlab/-/issues/426887) | High | Package | Group |
| [REST API endpoint `pre_receive_secret_detection_enabled` is deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/514413) | Medium | Application_security_testing | Instance | | [REST API endpoint `pre_receive_secret_detection_enabled` is deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/514413) | Medium | Application_security_testing | Instance |
| [Remove duoProAssignedUsersCount GraphQL field](https://gitlab.com/gitlab-org/gitlab/-/issues/498671) | Low | Plan | Group, project | | [Remove duoProAssignedUsersCount GraphQL field](https://gitlab.com/gitlab-org/gitlab/-/issues/498671) | Low | Plan | Group, project |
| [S3 storage driver (AWS SDK v1) for the container registry](https://gitlab.com/gitlab-org/gitlab/-/issues/523095) | Low | Package | Instance |
| [Remove `previousStageJobsOrNeeds` from GraphQL](https://gitlab.com/gitlab-org/gitlab/-/issues/424417) | Low | Verify | Instance | | [Remove `previousStageJobsOrNeeds` from GraphQL](https://gitlab.com/gitlab-org/gitlab/-/issues/424417) | Low | Verify | Instance |

View File

@ -1853,6 +1853,32 @@ In GitLab 18.0, only the runner registration methods implemented in the new GitL
<div class="deprecation breaking-change" data-milestone="18.0"> <div class="deprecation breaking-change" data-milestone="18.0">
### S3 storage driver (AWS SDK v1) for the container registry
<div class="deprecation-notes">
- Announced in GitLab <span class="milestone">17.10</span>
- Removal in GitLab <span class="milestone">18.0</span> ([breaking change](https://docs.gitlab.com/update/terminology/#breaking-change))
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/523095).
</div>
The S3 storage driver for the container registry that uses AWS SDK v1 is deprecated and will be removed in GitLab 18.0. If you use S3 object storage for your container registry, you'll need to update your configuration to use the new `s3_v2` driver.
The `s3_v2` storage driver is based on AWS SDK v2 and provides improved performance, better security, and continued support from AWS. It will be available starting May 2025 to replace the deprecated [AWS SDK v1](https://aws.amazon.com/blogs/developer/announcing-end-of-support-for-aws-sdk-for-go-v1-on-july-31-2025/), which reaches end-of-support on July 31, 2025.
To migrate to the `s3_v2` driver:
1. Update your registry configuration file to use the `s3_v2` configuration instead of `s3`.
1. Move from Signature Version 2 to Signature Version 4 for authentication if you haven't already, as AWS SDK v2 only supports Signature Version 4.
1. Test the configuration in a non-production environment before deploying to production.
For more information about updating your storage driver configuration, see [use object storage](https://docs.gitlab.com/administration/packages/container_registry/#use-object-storage).
</div>
<div class="deprecation breaking-change" data-milestone="18.0">
### SAST jobs no longer use global cache settings ### SAST jobs no longer use global cache settings
<div class="deprecation-notes"> <div class="deprecation-notes">

View File

@ -0,0 +1,83 @@
---
stage: Application Security Testing
group: Static Analysis
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
title: Remediate
---
Remediation is the fourth phase of the vulnerability management lifecycle: detect, triage, analyze,
remediate.
Remediation is the process of finding the root cause of a vulnerability and fixing the root cause,
reducing the risks, or both. Use information contained in each vulnerability's
[details page](../vulnerabilities/_index.md) to help you understand the nature of the vulnerability
and remediate it.
The objective of the remediation phase is to either resolve or dismiss a vulnerability. A
vulnerability is resolved when either you've remediated the root cause or it's no longer present. A
vulnerability is dismissed when you've decided that no further effort is justified.
<i class="fa-youtube-play" aria-hidden="true"></i>
For a walkthrough of how GitLab Duo can help you analyze and remediate a vulnerability, see
[Use GitLab Duo to remediate an SQL injection](https://youtu.be/EJXAIzXNAWQ?si=IDKtApBH1j5JwdUY).
<!-- Video published on 2023-07-08 -->
## Scope
The scope of the remediation phase is all those vulnerabilities that have been through the analysis
phase and confirmed as needing further action. To list these vulnerabilities, use the following
filter criteria in the vulnerability report:
- **Status:** Confirmed
- **Activity:** Has issue
## Document the vulnerability
If you've not already,
[create an issue](../vulnerabilities/_index.md#create-a-gitlab-issue-for-a-vulnerability)
to document your investigation and remediation work. This documentation provides a reference point
if you discover a similar vulnerability, or if the same vulnerability is detected again.
## Remediate the vulnerability
Use the information gathered in the analysis phase to help guide you to remediate the vulnerability.
It's important to understand the root cause of the vulnerability so that remediation is
effective.
For some vulnerabilities detected by SAST, GitLab can:
- [Explain the vulnerability](../vulnerabilities/_index.md#explaining-a-vulnerability), using GitLab
Duo Chat.
- [Resolve the vulnerability](../vulnerabilities/_index.md#vulnerability-resolution), using GitLab
Duo Chat.
- Provide the complete data path from input to the vulnerable line of code, if you're using
GitLab Advanced SAST.
When the root cause of a vulnerability is remediated, resolve the vulnerability.
To do this:
1. Change the vulnerability's status to **Resolved**.
1. Document in the issue created for the vulnerability how it was remediated, then close the issue.
If a resolved vulnerability is reintroduced and detected again, its record is reinstated and its
status set to **Needs triage**.
## Dismiss the vulnerability
At any point during the remediation phase you might decide to dismiss the vulnerability, possibly
because you have decided:
- The estimated cost of remediation effort is too high.
- The vulnerability poses little to no risk.
- The vulnerability's risk has already been mitigated.
- The vulnerability is not valid in your environment.
When you dismiss the vulnerability:
1. Provide a brief comment that states why you've dismissed it.
1. Change the vulnerability's status to **Dismissed**.
1. If you created an issue for the vulnerability, add a comment noting that you dismissed the
vulnerability, then close the issue.
A dismissed vulnerability is ignored if it's detected in subsequent scans.

View File

@ -0,0 +1,256 @@
---
stage: AI-powered
group: Duo Workflow
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
title: GitLab Duo Workflow use cases
---
{{< details >}}
- Tier: Ultimate
- Offering: GitLab.com
- Status: Experiment
{{< /details >}}
{{< alert type="warning" >}}
This feature is considered [experimental](../../policy/development_stages_support.md) and is not intended for customer usage outside of initial design partners. We expect major changes to this feature.
{{< /alert >}}
The following use case examples demonstrate some of the ways you might use GitLab Duo Workflow.
## Refactor existing code
Use this approach when you need to improve performance, readability, or maintainability of existing code.
### Analyze
Ask Workflow to analyze the current implementation.
- Request identification of complexity issues, performance bottlenecks, and readability concerns.
- Have Workflow suggest applicable design patterns.
Sample prompt:
```plaintext
Analyze the UserPermissions class in app/models/user_permissions.rb. Focus on:
1. Current methods and their complexity
2. Performance bottlenecks
3. Areas where readability can be improved
4. Potential design patterns that could be applied
Provide a summary of your findings and suggestions for refactoring.
Reference any similar refactoring in our codebase if applicable (link existing files if any).
Document your analysis process.
```
### Plan
Then, request a structured refactoring proposal.
- Ask for clear documentation of proposed changes.
- Have Workflow outline potential risks and estimated effort.
Sample prompt:
```plaintext
Based on the analysis of UserPermissions, create a refactoring proposal:
1. Outline the new structure for UserPermissions
2. Suggest new method names and their purposes
3. Propose any new classes or modules if needed
4. Explain how this refactoring will improve performance and readability
Format the proposal as a GitLab issue template, including:
- Problem statement
- Proposed solution
- Potential risks
- Estimated effort
```
### Implement
Now, ask Workflow to create implementation files that follow your coding standards.
- Request detailed comments explaining the changes.
- Ask for test coverage of the new implementation.
Sample prompt:
```plaintext
Implement the refactoring of UserPermissions as proposed:
1. Create a new file app/models/user_permissions_refactored.rb
2. Implement the new UserPermissions class structure
3. Include detailed comments explaining the changes
4. Update one existing method in app/controllers/users_controller.rb to use the new UserPermissions class
5. Write RSpec tests for the new UserPermissions class in spec/models/user_permissions_spec.rb
Follow our Ruby style guide and best practices for testing.
Document any decisions made during implementation.
```
### Evaluate results
Finally, verify the changes work as expected through testing.
- If issues arise, provide specific feedback to guide improvement.
- Document performance gains or other improvements.
## Bootstrap a new project
Use this approach when you start a new application or service from scratch.
### Initialize the project
Request a project structure that follow best practices for your tech stack.
- Ask for recommended dependencies and configurations.
- Have Workflow generate initial documentation.
Sample prompt:
```plaintext
Initialize a new Ruby on Rails project for a team collaboration tool:
1. Generate a project structure following our best practices
2. Include recommended gems for development, testing, and production
3. Set up a basic CI/CD configuration
4. Create an initial README.md with project overview and setup instructions
Use our existing Rails projects as reference. Document your decisions and reasoning.
```
### Plan the feature
Now, ask Workflow to create feature definitions and user stories.
- Request technical approaches for each core feature.
- Have Workflow identify potential challenges.
Sample prompt:
```plaintext
Create an issue template for the core features of our team collaboration tool:
1. User authentication and authorization
2. Team creation and management
3. Task tracking and assignment
4. Real-time chat functionality
5. File sharing and version control
For each feature:
- Provide a brief description
- List key user stories
- Suggest potential technical approaches
- Identify any potential challenges or considerations
Format this as an epic with individual issues for each core feature.
```
### Set up a foundation
Now, ask Workflow to design initial data models and schemas.
- Request setup of testing frameworks and CI/CD configurations.
- Ask for implementation of authentication and core APIs.
Sample prompt:
```plaintext
Design an initial database schema for our team collaboration tool:
1. Create migrations for core models (User, Team, Task, Message, File)
2. Define associations between models
3. Include necessary indexes for performance
4. Add comments explaining design decisions
Use our database best practices and naming conventions.
Generate the migrations in db/migrate/ directory.
Provide a visual representation of the schema (for example, using Mermaid diagram syntax).
```
### Track progress
Finally, request a summary of implemented features.
- Ask for a prioritized list of remaining tasks.
- Have Workflow identify risks or challenges.
Sample prompt:
```plaintext
Create a progress report and next steps plan:
1. Summarize implemented features and their current status
2. Identify any deviations from the initial plan and explain reasons
3. List remaining tasks from the core features epic
4. Suggest a prioritized roadmap for the next development sprint
5. Identify any potential risks or challenges for upcoming work
Format this as an issue with appropriate labels and mentions.
Include relevant metrics (like test coverage and security scan results).
```
## Add a new feature
Use this approach to extend functionality in existing projects.
### Provision the context
First, specify the technology stack and relevant files.
- Clearly define the desired behavior and requirements.
- Point to similar implementations that can serve as reference.
Sample prompt:
```plaintext
In this project, let's add a new page for users to submit feedback.
The current implementation is in Vue and routes are served from a fastify HTTP server,
located at path/to/fastify/server.ts. The new route should be `/feedback` and serve
a new vue component called `feedback.vue`.
The feedback vue component should have 3 fields:
- User email as an input field
- A dropdown with 5 values to ask how they heard about us
- One textarea for the actual feedback
The dropdown field is optional. There should also be a submit button.
When the button is clicked, show a banner to tell users their feedback was sent.
```
### Request implementation
Now, ask for all necessary component parts (UI, logic, data models).
- Request test files for the new functionality.
- Specify expected output formats and integration points.
Sample prompt:
```plaintext
Please implement:
1. The new Vue component at src/components/feedback.vue
2. The route handling in the fastify server at path/to/fastify/server.ts
3. Any necessary backend API endpoints to handle the form submission
4. Unit tests for the Vue component and API endpoints
The implementation should follow our existing patterns for
form validation and API responses. Reference the contact form at
src/components/contact.vue for styling and error handling approaches.
```
### Review and refine
Finally, verify the implementation meets requirements.
- Check for adherence to code standards.
- Test the feature thoroughly.

View File

@ -127,7 +127,7 @@ For example:
display: table display: table
fields: title, state, health, epic, milestone, weight, updated fields: title, state, health, epic, milestone, weight, updated
limit: 5 limit: 5
query: project = "gitlab-org/gitlab" AND assignee = currentUser() AND opened = true query: project = "gitlab-org/gitlab" AND assignee = currentUser() AND state = opened
``` ```
```` ````
@ -156,7 +156,7 @@ project as a list, displaying fields `title`, `health`, and `due`:
display: list display: list
fields: title, health, due fields: title, health, due
limit: 5 limit: 5
query: project = "gitlab-org/gitlab" AND assignee = currentUser() AND opened = true query: project = "gitlab-org/gitlab" AND assignee = currentUser() AND state = opened
``` ```
```` ````

View File

@ -146,6 +146,6 @@ To include the `labels` function in a GLQL view:
display: list display: list
fields: title, health, due, labels("workflow::*"), labels fields: title, health, due, labels("workflow::*"), labels
limit: 5 limit: 5
query: project = "gitlab-org/gitlab" AND assignee = currentUser() AND opened = true query: project = "gitlab-org/gitlab" AND assignee = currentUser() AND state = opened
``` ```
```` ````

View File

@ -82,7 +82,7 @@ Use cases include:
{{< history >}} {{< history >}}
- More granular approver display [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/178005) in GitLab 17.9 [with a flag](../../../../administration/feature_flags.md) named `mr_approvers_filter_hidden_users`. Enabled by default. - More granular approver display [generally available](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/183058) in GitLab 17.10. Feature flag `mr_approvers_filter_hidden_users` removed.
{{< /history >}} {{< /history >}}
@ -110,8 +110,7 @@ The widget displays one of these statuses:
To check if your approval satisfies Code Owner requirements, select **Expand eligible approvers** ({{< icon name="chevron-lg-down" >}}). To check if your approval satisfies Code Owner requirements, select **Expand eligible approvers** ({{< icon name="chevron-lg-down" >}}).
If you have enabled the `mr_approvers_filter_hidden_users` feature flag, introduced in GitLab 17.9, Approver visibility depends on your project membership, and group privacy:
approver visibility depends on your project membership, and group privacy:
- Project members see all approvers. - Project members see all approvers.
- Project non-members see: - Project non-members see:

View File

@ -120,7 +120,7 @@ module Gitlab
def bulk_access_checks! def bulk_access_checks!
Gitlab::Checks::LfsCheck.new(self).validate! Gitlab::Checks::LfsCheck.new(self).validate!
Gitlab::Checks::GlobalFileSizeCheck.new(self).validate! Gitlab::Checks::FileSizeLimitCheck.new(self).validate!
Gitlab::Checks::IntegrationsCheck.new(self).validate! Gitlab::Checks::IntegrationsCheck.new(self).validate!
end end

View File

@ -2,7 +2,7 @@
module Gitlab module Gitlab
module Checks module Checks
class GlobalFileSizeCheck < BaseBulkChecker class FileSizeLimitCheck < BaseBulkChecker
include ActionView::Helpers::NumberHelper include ActionView::Helpers::NumberHelper
LOG_MESSAGE = 'Checking for blobs over the file size limit' LOG_MESSAGE = 'Checking for blobs over the file size limit'
@ -52,3 +52,5 @@ module Gitlab
end end
end end
end end
Gitlab::Checks::FileSizeLimitCheck.prepend_mod

View File

@ -14159,6 +14159,9 @@ msgstr ""
msgid "CodeSuggestions|Enhance your coding experience with intelligent recommendations. %{linkStart}GitLab Duo%{linkEnd} offers features that use generative AI to suggest code." msgid "CodeSuggestions|Enhance your coding experience with intelligent recommendations. %{linkStart}GitLab Duo%{linkEnd} offers features that use generative AI to suggest code."
msgstr "" msgstr ""
msgid "CodeSuggestions|Enterprise"
msgstr ""
msgid "CodeSuggestions|Get started with GitLab Duo Pro today to boost your efficiency and effectiveness by reducing the time required to write and understand code." msgid "CodeSuggestions|Get started with GitLab Duo Pro today to boost your efficiency and effectiveness by reducing the time required to write and understand code."
msgstr "" msgstr ""
@ -14195,6 +14198,9 @@ msgstr ""
msgid "CodeSuggestions|Outbound and inbound connections from clients to the GitLab instance must be allowed." msgid "CodeSuggestions|Outbound and inbound connections from clients to the GitLab instance must be allowed."
msgstr "" msgstr ""
msgid "CodeSuggestions|Pro"
msgstr ""
msgid "CodeSuggestions|Problems detected with setup" msgid "CodeSuggestions|Problems detected with setup"
msgstr "" msgstr ""
@ -31243,6 +31249,9 @@ msgstr ""
msgid "Integrations|Add integration" msgid "Integrations|Add integration"
msgstr "" msgstr ""
msgid "Integrations|Add new %{title} integration"
msgstr ""
msgid "Integrations|All details" msgid "Integrations|All details"
msgstr "" msgstr ""
@ -31279,6 +31288,9 @@ msgstr ""
msgid "Integrations|Comment settings:" msgid "Integrations|Comment settings:"
msgstr "" msgstr ""
msgid "Integrations|Configure %{title}"
msgstr ""
msgid "Integrations|Configure the scope of notifications." msgid "Integrations|Configure the scope of notifications."
msgstr "" msgstr ""
@ -51350,9 +51362,6 @@ msgstr ""
msgid "ScanResultPolicy|Attributes are automatically applied by the scanners" msgid "ScanResultPolicy|Attributes are automatically applied by the scanners"
msgstr "" msgstr ""
msgid "ScanResultPolicy|Automatically make approval rules optional when scan artifacts are missing from the target branch and a scan is required by a scan execution policy. This option only works with an existing scan execution policy that has matching scanners."
msgstr ""
msgid "ScanResultPolicy|Block the merge request until all criteria are met" msgid "ScanResultPolicy|Block the merge request until all criteria are met"
msgstr "" msgstr ""
@ -51455,7 +51464,7 @@ msgstr ""
msgid "ScanResultPolicy|License type" msgid "ScanResultPolicy|License type"
msgstr "" msgstr ""
msgid "ScanResultPolicy|Make approval rules optional using scan execution policies" msgid "ScanResultPolicy|Make approval rules optional using execution policies"
msgstr "" msgstr ""
msgid "ScanResultPolicy|Matching" msgid "ScanResultPolicy|Matching"
@ -51587,6 +51596,9 @@ msgstr ""
msgid "ScanResultPolicy|When a security policy fails for an unspecified reason." msgid "ScanResultPolicy|When a security policy fails for an unspecified reason."
msgstr "" msgstr ""
msgid "ScanResultPolicy|When enabled, approval rules do not block merge requests when a scan is required by a scan execution policy or a pipeline execution policy but a required scan artifact is missing from the target branch. This option only works when the project or group has an existing scan execution policy or pipeline execution policy with matching scanners."
msgstr ""
msgid "ScanResultPolicy|When enabled, if an MR receives all necessary approvals to merge, but then a new commit is added, new approvals are required." msgid "ScanResultPolicy|When enabled, if an MR receives all necessary approvals to merge, but then a new commit is added, new approvals are required."
msgstr "" msgstr ""
@ -54241,9 +54253,6 @@ msgstr ""
msgid "Select" msgid "Select"
msgstr "" msgstr ""
msgid "Select %{name}"
msgstr ""
msgid "Select Git revision" msgid "Select Git revision"
msgstr "" msgstr ""
@ -66089,6 +66098,15 @@ msgstr ""
msgid "Work items" msgid "Work items"
msgstr "" msgstr ""
msgid "WorkItemCustomFields|Options could not be loaded for field: %{dropdownLabel}. Please try again."
msgstr ""
msgid "WorkItemCustomFields|Select one"
msgstr ""
msgid "WorkItemCustomFields|Select one or more"
msgstr ""
msgid "WorkItemCustomField|Add option" msgid "WorkItemCustomField|Add option"
msgstr "" msgstr ""

View File

@ -6,7 +6,7 @@ gem 'gitlab-qa', '~> 15', '>= 15.3.0', require: 'gitlab/qa'
gem 'gitlab_quality-test_tooling', '~> 2.8.0', require: false gem 'gitlab_quality-test_tooling', '~> 2.8.0', require: false
gem 'gitlab-utils', path: '../gems/gitlab-utils' gem 'gitlab-utils', path: '../gems/gitlab-utils'
gem 'activesupport', '~> 7.0.8.7' # This should stay in sync with the root's Gemfile gem 'activesupport', '~> 7.0.8.7' # This should stay in sync with the root's Gemfile
gem 'allure-rspec', '~> 2.25.0' gem 'allure-rspec', '~> 2.26.0'
gem 'capybara', '~> 3.40.0' gem 'capybara', '~> 3.40.0'
gem 'capybara-screenshot', '~> 1.0.26' gem 'capybara-screenshot', '~> 1.0.26'
gem 'rake', '~> 13', '>= 13.2.1' gem 'rake', '~> 13', '>= 13.2.1'

View File

@ -35,10 +35,10 @@ GEM
tzinfo (~> 2.0) tzinfo (~> 2.0)
addressable (2.8.7) addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0) public_suffix (>= 2.0.2, < 7.0)
allure-rspec (2.25.0) allure-rspec (2.26.0)
allure-ruby-commons (= 2.25.0) allure-ruby-commons (= 2.26.0)
rspec-core (>= 3.8, < 4) rspec-core (>= 3.8, < 4)
allure-ruby-commons (2.25.0) allure-ruby-commons (2.26.0)
mime-types (>= 3.3, < 4) mime-types (>= 3.3, < 4)
require_all (>= 2, < 4) require_all (>= 2, < 4)
rspec-expectations (~> 3.12) rspec-expectations (~> 3.12)
@ -357,7 +357,7 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
activesupport (~> 7.0.8.7) activesupport (~> 7.0.8.7)
allure-rspec (~> 2.25.0) allure-rspec (~> 2.26.0)
capybara (~> 3.40.0) capybara (~> 3.40.0)
capybara-screenshot (~> 1.0.26) capybara-screenshot (~> 1.0.26)
deprecation_toolkit (~> 2.2.2) deprecation_toolkit (~> 2.2.2)

View File

@ -0,0 +1,71 @@
# frozen_string_literal: true
module QA
# This test modifies an instance-level setting,
# so skipping on live environments to avoid transient issues.
RSpec.describe 'Create', :requires_admin, :skip_live_env, product_group: :source_code do
describe 'push after setting the file size limit via admin/application_settings using SSH' do
include Support::API
let!(:project) { create(:project, name: 'project-test-push-limit') }
let(:key) { create(:ssh_key, title: "key for ssh tests #{Time.now.to_f}") }
let(:commit_message) { 'Adding a new file' }
after(:context) do
set_file_size_limit(nil)
end
it(
'push is successful when the file size is under the limit',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/523543'
) do
set_file_size_limit(5) # Set a 5MB file size limit
retry_on_fail do
push = push_new_file('oversize_file_1.bin')
push.project.visit!
Page::Project::Show.perform do |project|
expect(project).to have_commit_message(commit_message)
end
end
end
it(
'push fails when the file size is above the limit',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/523544'
) do
set_file_size_limit(2) # Set a 2MB file size limit
retry_on_fail do
expect { push_new_file('oversize_file_2.bin') }
.to raise_error(QA::Support::Run::CommandError, /remote: fatal: pack exceeds maximum allowed size/)
end
end
def set_file_size_limit(limit)
request = Runtime::API::Request.new(Runtime::API::Client.as_admin, '/application/settings')
response = put request.url, receive_max_input_size: limit
expect(response.code).to eq(QA::Support::API::HTTP_STATUS_OK)
expect(parse_body(response)[:receive_max_input_size]).to eq(limit)
end
def push_new_file(file_name)
Resource::Repository::ProjectPush.fabricate! do |p|
p.project = project
p.ssh_key = key
p.file_name = file_name
p.file_content = SecureRandom.random_bytes(3_000_000) # 3MB file
p.commit_message = commit_message
end
end
# Application settings are cached for up to a minute.
# Instead of waiting, retry the attempt to push if it fails.
def retry_on_fail(&block)
Support::Retrier.retry_on_exception(max_attempts: 6, reload_page: false, sleep_interval: 10, &block)
end
end
end
end

View File

@ -166,7 +166,6 @@ spec/frontend/ml/model_registry/apps/show_ml_model_spec.js
spec/frontend/ml/model_registry/components/candidate_detail_spec.js spec/frontend/ml/model_registry/components/candidate_detail_spec.js
spec/frontend/ml/model_registry/components/model_edit_spec.js spec/frontend/ml/model_registry/components/model_edit_spec.js
spec/frontend/ml/model_registry/components/model_version_create_spec.js spec/frontend/ml/model_registry/components/model_version_create_spec.js
spec/frontend/notebook/cells/markdown_spec.js
spec/frontend/notes/components/discussion_notes_spec.js spec/frontend/notes/components/discussion_notes_spec.js
spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_row_spec.js spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_row_spec.js
spec/frontend/packages_and_registries/dependency_proxy/app_spec.js spec/frontend/packages_and_registries/dependency_proxy/app_spec.js

View File

@ -31,6 +31,7 @@ RSpec.describe 'Database schema',
ci_sources_pipelines: [%w[source_partition_id source_pipeline_id], %w[partition_id pipeline_id]], ci_sources_pipelines: [%w[source_partition_id source_pipeline_id], %w[partition_id pipeline_id]],
ci_sources_projects: [%w[partition_id pipeline_id]], # index on pipeline_id is sufficient ci_sources_projects: [%w[partition_id pipeline_id]], # index on pipeline_id is sufficient
ci_stages: [%w[partition_id pipeline_id]], # the index on pipeline_id is sufficient ci_stages: [%w[partition_id pipeline_id]], # the index on pipeline_id is sufficient
merge_request_diff_files: [%w[project_id]], # async index to be created - https://gitlab.com/gitlab-org/gitlab/-/issues/523103
notes: %w[namespace_id], # this index is added in an async manner, hence it needs to be ignored in the first phase. notes: %w[namespace_id], # this index is added in an async manner, hence it needs to be ignored in the first phase.
p_ci_build_trace_metadata: [%w[partition_id build_id], %w[partition_id trace_artifact_id]], # the index on build_id is enough p_ci_build_trace_metadata: [%w[partition_id build_id], %w[partition_id trace_artifact_id]], # the index on build_id is enough
p_ci_builds: [%w[partition_id stage_id], %w[partition_id execution_config_id], %w[auto_canceled_by_partition_id auto_canceled_by_id], %w[upstream_pipeline_partition_id upstream_pipeline_id], %w[partition_id commit_id]], # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/142804#note_1745483081 p_ci_builds: [%w[partition_id stage_id], %w[partition_id execution_config_id], %w[auto_canceled_by_partition_id auto_canceled_by_id], %w[upstream_pipeline_partition_id upstream_pipeline_id], %w[partition_id commit_id]], # https://gitlab.com/gitlab-org/gitlab/-/merge_requests/142804#note_1745483081

View File

@ -110,6 +110,32 @@ RSpec.describe Namespaces::ProjectsFinder, feature_category: :groups_and_project
end end
end end
context 'when archived_only param is present' do
context 'when archived_only is true' do
let(:params) { { archived_only: true } }
it 'returns only archived projects' do
expect(projects).to contain_exactly(project_7)
end
end
context 'when archived_only is false' do
let(:params) { { archived_only: false } }
it 'returns all projects' do
expect(projects).to contain_exactly(project_1, project_2, project_4, project_6, project_7)
end
end
context 'when archived_only is invalid' do
let(:params) { { archived_only: 'invalid' } }
it 'returns all projects' do
expect(projects).to contain_exactly(project_1, project_2, project_4, project_6, project_7)
end
end
end
context 'when ids are provided' do context 'when ids are provided' do
let(:params) { { ids: [project_1.id] } } let(:params) { { ids: [project_1.id] } }

View File

@ -33,6 +33,10 @@ RSpec.describe 'Raw files', '(JavaScript fixtures)' do
blob_at('93ee732', 'files/ipython/math.ipynb') blob_at('93ee732', 'files/ipython/math.ipynb')
end end
it 'blob/notebook/raw-output.json' do
blob_at('9b33108', 'files/ipython/raw-cell.ipynb')
end
it 'blob/pdf/test.pdf' do it 'blob/pdf/test.pdf' do
blob_at('e774ebd33', 'files/pdf/test.pdf') blob_at('e774ebd33', 'files/pdf/test.pdf')
end end

View File

@ -1,6 +1,8 @@
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import rawCellFixture from 'test_fixtures/blob/notebook/raw-output.json';
import fixture from 'test_fixtures/blob/notebook/basic.json'; import fixture from 'test_fixtures/blob/notebook/basic.json';
import Code from '~/notebook/cells/code.vue'; import Code from '~/notebook/cells/code.vue';
import CodeOutput from '~/notebook/cells/code/index.vue';
describe('Code component', () => { describe('Code component', () => {
let wrapper; let wrapper;
@ -23,6 +25,22 @@ describe('Code component', () => {
}); });
}); });
describe('computes the correct language for cell type', () => {
it('returns txt for raw cell type', () => {
json = JSON.parse(JSON.stringify(rawCellFixture));
wrapper = mountComponent(json.cells[0]);
expect(wrapper.findComponent(CodeOutput).props('language')).toBe('txt');
});
it('returns python for non-raw cell type', () => {
json = JSON.parse(JSON.stringify(json));
wrapper = mountComponent(json.cells[0]);
expect(wrapper.findComponent(CodeOutput).props('language')).toBe('python');
});
});
describe('with output', () => { describe('with output', () => {
beforeEach(() => { beforeEach(() => {
wrapper = mountComponent(json.cells[2]); wrapper = mountComponent(json.cells[2]);

View File

@ -80,26 +80,26 @@ describe('Markdown component', () => {
expect(wrapper.vm.$el.querySelector('.markdown h1')).not.toBeNull(); expect(wrapper.vm.$el.querySelector('.markdown h1')).not.toBeNull();
}); });
it('sanitizes Markdown output', async () => { it('sanitizes Markdown output', () => {
Object.assign(cell, { wrapper = buildCellComponent({
cell_type: 'markdown',
source: [ source: [
'[XSS](data:text/html;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5kb21haW4pPC9zY3JpcHQ+Cg==)\n', '[XSS](data:text/html;base64,PHNjcmlwdD5hbGVydChkb2N1bWVudC5kb21haW4pPC9zY3JpcHQ+Cg==)\n',
], ],
}); });
await nextTick(); expect(wrapper.find('a').attributes('href')).toBeUndefined();
expect(wrapper.vm.$el.querySelector('a').getAttribute('href')).toBeNull();
}); });
it('sanitizes HTML', async () => { it('sanitizes HTML', () => {
const findLink = () => wrapper.vm.$el.querySelector('.xss-link'); wrapper = buildCellComponent({
Object.assign(cell, { cell_type: 'markdown',
source: ['<a href="test.js" data-remote=true data-type="script" class="xss-link">XSS</a>\n'], source: ['<a href="test.js" data-remote=true data-type="script" class="xss-link">XSS</a>\n'],
}); });
await nextTick(); const sanitizedLinkAttributes = wrapper.find('.xss-link').attributes();
expect(findLink().dataset.remote).toBeUndefined(); expect(sanitizedLinkAttributes['data-remote']).toBeUndefined();
expect(findLink().dataset.type).toBeUndefined(); expect(sanitizedLinkAttributes['data-type']).toBeUndefined();
}); });
describe('When parsing images', () => { describe('When parsing images', () => {

View File

@ -1,6 +1,7 @@
import { mount } from '@vue/test-utils'; import { mount } from '@vue/test-utils';
import { nextTick } from 'vue'; import { nextTick } from 'vue';
import json from 'test_fixtures/blob/notebook/basic.json'; import json from 'test_fixtures/blob/notebook/basic.json';
import jsonWithRawCell from 'test_fixtures/blob/notebook/raw-output.json';
import jsonWithWorksheet from 'test_fixtures/blob/notebook/worksheets.json'; import jsonWithWorksheet from 'test_fixtures/blob/notebook/worksheets.json';
import Notebook from '~/notebook/index.vue'; import Notebook from '~/notebook/index.vue';
@ -46,6 +47,20 @@ describe('Notebook component', () => {
}); });
}); });
describe('with JSON of raw cell', () => {
beforeEach(() => {
vm = buildComponent(jsonWithRawCell);
return nextTick();
});
it('renders code cell when cell type is raw', () => {
expect(vm.$el.querySelector('.code')).not.toBeNull();
});
it('renders cells', () => {
expect(vm.$el.querySelectorAll('.cell').length).toBe(jsonWithRawCell.cells.length);
});
});
describe('with worksheets', () => { describe('with worksheets', () => {
beforeEach(() => { beforeEach(() => {
vm = buildComponent(jsonWithWorksheet); vm = buildComponent(jsonWithWorksheet);

View File

@ -139,6 +139,29 @@ RSpec.describe Resolvers::NamespaceProjectsResolver, feature_category: :groups_a
it { is_expected.to contain_exactly(*expected_projects) } it { is_expected.to contain_exactly(*expected_projects) }
end end
context 'archived_only argument' do
context 'when archived_only is true' do
let(:args) { default_args.merge(archived_only: true) }
let(:expected_projects) { group_namespaced_projects.second }
it { is_expected.to contain_exactly(*expected_projects) }
end
context 'when archived_only is false' do
let(:args) { default_args.merge(archived_only: false) }
let(:expected_projects) { group_namespaced_projects }
it { is_expected.to contain_exactly(*expected_projects) }
end
context 'when archived_only is not specified' do
let(:args) { default_args.merge(archived_only: nil) }
let(:expected_projects) { group_namespaced_projects }
it { is_expected.to contain_exactly(*expected_projects) }
end
end
end end
context 'with an user namespace' do context 'with an user namespace' do

View File

@ -26,7 +26,7 @@ RSpec.describe Gitlab::Checks::ChangesAccess, feature_category: :source_code_man
end end
it 'calls file size check' do it 'calls file size check' do
expect_next_instance_of(Gitlab::Checks::GlobalFileSizeCheck) do |instance| expect_next_instance_of(Gitlab::Checks::FileSizeLimitCheck) do |instance|
expect(instance).to receive(:validate!) expect(instance).to receive(:validate!)
end end

View File

@ -2,9 +2,11 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Gitlab::Checks::GlobalFileSizeCheck, feature_category: :source_code_management do RSpec.describe Gitlab::Checks::FileSizeLimitCheck, feature_category: :source_code_management do
include_context 'changes access checks context' include_context 'changes access checks context'
subject(:file_size_check) { described_class.new(changes_access) }
describe '#validate!' do describe '#validate!' do
it 'checks for file sizes' do it 'checks for file sizes' do
expect_next_instance_of(Gitlab::Checks::FileSizeCheck::HookEnvironmentAwareAnyOversizedBlobs, expect_next_instance_of(Gitlab::Checks::FileSizeCheck::HookEnvironmentAwareAnyOversizedBlobs,
@ -14,10 +16,10 @@ RSpec.describe Gitlab::Checks::GlobalFileSizeCheck, feature_category: :source_co
) do |check| ) do |check|
expect(check).to receive(:find).and_call_original expect(check).to receive(:find).and_call_original
end end
expect(subject.logger).to receive(:log_timed).with('Checking for blobs over the file size limit') expect(file_size_check.logger).to receive(:log_timed).with('Checking for blobs over the file size limit')
.and_call_original .and_call_original
expect(Gitlab::AppJsonLogger).to receive(:info).with('Checking for blobs over the file size limit') expect(Gitlab::AppJsonLogger).to receive(:info).with('Checking for blobs over the file size limit')
subject.validate! file_size_check.validate!
end end
context 'when there are oversized blobs' do context 'when there are oversized blobs' do
@ -43,7 +45,7 @@ RSpec.describe Gitlab::Checks::GlobalFileSizeCheck, feature_category: :source_co
blob_details: [{ "id" => mock_blob_id, "size" => mock_blob_size }] blob_details: [{ "id" => mock_blob_id, "size" => mock_blob_size }]
) )
expect do expect do
subject.validate! file_size_check.validate!
end.to raise_exception(Gitlab::GitAccess::ForbiddenError, end.to raise_exception(Gitlab::GitAccess::ForbiddenError,
/- #{mock_blob_id} \(#{size_msg} MiB\)/) /- #{mock_blob_id} \(#{size_msg} MiB\)/)
end end

View File

@ -305,27 +305,23 @@ RSpec.describe 'new tables missing sharding_key', feature_category: :cell do
next next
end end
# rubocop:disable Layout/LineLength -- sorry, long URL
expect(fks).to be_empty, expect(fks).to be_empty,
"#{entry.table_name} is exempted from sharding, but has foreign key references to it.\n" \ "#{entry.table_name} is exempted from sharding, but has foreign key references to it.\n" \
"For more information, see " \ "For more information, see " \
"https://docs.gitlab.com/ee/development/database/multiple_databases.html#exempting-certain-tables-from-having-sharding-keys.\n" \ "https://docs.gitlab.com/development/cells/#exempting-certain-tables-from-having-sharding-keys.\n" \
"The tables with foreign key references are:\n\n" \ "The tables with foreign key references are:\n\n" \
"#{fks.map(&:constrained_table_name).join("\n")}" "#{fks.map(&:constrained_table_name).join("\n")}"
# rubocop:enable Layout/LineLength
lfks = referenced_loose_foreign_keys(entry.table_name) lfks = referenced_loose_foreign_keys(entry.table_name)
lfks.reject! { |lfk| lfk.from_table.in?(tables_exempted_from_sharding_table_names) } lfks.reject! { |lfk| lfk.from_table.in?(tables_exempted_from_sharding_table_names) }
lfks.reject! { |lfk| allowed_lfk_to_tables_exempted_from_sharding[lfk.from_table]&.include?(lfk.to_table) } lfks.reject! { |lfk| allowed_lfk_to_tables_exempted_from_sharding[lfk.from_table]&.include?(lfk.to_table) }
# rubocop:disable Layout/LineLength -- sorry, long URL
expect(lfks).to be_empty, expect(lfks).to be_empty,
"#{entry.table_name} is exempted from sharding, but has loose foreign key references to it.\n" \ "#{entry.table_name} is exempted from sharding, but has loose foreign key references to it.\n" \
"For more information, see " \ "For more information, see " \
"https://docs.gitlab.com/ee/development/database/multiple_databases.html#exempting-certain-tables-from-having-sharding-keys.\n" \ "https://docs.gitlab.com/development/cells/#exempting-certain-tables-from-having-sharding-keys.\n" \
"The tables with loose foreign key references are:\n\n" \ "The tables with loose foreign key references are:\n\n" \
"#{lfks.map(&:from_table).join("\n")}" "#{lfks.map(&:from_table).join("\n")}"
# rubocop:enable Layout/LineLength
end end
end end

View File

@ -1531,7 +1531,7 @@ RSpec.describe Gitlab::Git::Repository, feature_category: :source_code_managemen
it "returns the number of commits in the whole repository" do it "returns the number of commits in the whole repository" do
options = { all: true } options = { all: true }
expect(repository.count_commits(options)).to eq(328) expect(repository.count_commits(options)).to eq(330)
end end
end end

View File

@ -43,7 +43,9 @@ RSpec.describe BulkImports::Entity, type: :model, feature_category: :importers d
entity = build(:bulk_import_entity, group: build(:group), project: build(:project)) entity = build(:bulk_import_entity, group: build(:group), project: build(:project))
expect(entity).not_to be_valid expect(entity).not_to be_valid
expect(entity.errors).to include(:base, :project, :group)
expect(entity.errors[:base])
.to include('Import failed: Must have exactly one of organization, group or project.')
end end
end end

View File

@ -0,0 +1,41 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Ci::ProjectWithPipelineVariable, feature_category: :continuous_integration do
describe '.upsert_for_pipeline' do
let_it_be(:project) { create(:project) }
let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
context 'when the pipeline has variables' do
before do
create(:ci_pipeline_variable, pipeline: pipeline, key: 'foo', value: 'bar')
end
it 'creates a corresponding project_with_pipeline_variable record' do
expect { described_class.upsert_for_pipeline(pipeline) }
.to change { described_class.count }.by(1)
expect(described_class.last.project_id).to eq(project.id)
end
context 'when a record already exists for the project' do
before do
described_class.create!(project_id: project.id)
end
it 'does not create a duplicate record' do
expect { described_class.upsert_for_pipeline(pipeline) }
.not_to change { described_class.count }
end
end
end
context 'when the pipeline has no variables' do
it 'does not create a project_with_pipeline_variable record' do
expect { described_class.upsert_for_pipeline(pipeline) }
.not_to change { described_class.count }
end
end
end
end

View File

@ -28,5 +28,13 @@ RSpec.describe Ci::PipelineCreation::StartPipelineService, feature_category: :co
service.execute service.execute
end end
it 'calls ProjectWithPipelineVariablei.upsert_for_pipeline' do
expect(Ci::ProjectWithPipelineVariable)
.to receive(:upsert_for_pipeline)
.with(pipeline).and_call_original
service.execute
end
end end
end end

View File

@ -124,7 +124,8 @@ module TestEnv
'lock-detection' => '1ada92f78a19f27cb442a0a205f1c451a3a15432', 'lock-detection' => '1ada92f78a19f27cb442a0a205f1c451a3a15432',
'expanded-whitespace-target' => '279aa723d4688e711652d230c93f1fc33801dcb8', 'expanded-whitespace-target' => '279aa723d4688e711652d230c93f1fc33801dcb8',
'expanded-whitespace-source' => 'e6f8b802fe2288b1b5e367c5dde736594971ebd1', 'expanded-whitespace-source' => 'e6f8b802fe2288b1b5e367c5dde736594971ebd1',
'submodule-with-dot' => 'b4a4435df7e7605dd9930d0c5402087b37da99bf' 'submodule-with-dot' => 'b4a4435df7e7605dd9930d0c5402087b37da99bf',
'raw-cell-type' => '9b33108'
}.freeze }.freeze
# gitlab-test-fork is a fork of gitlab-fork, but we don't necessarily # gitlab-test-fork is a fork of gitlab-fork, but we don't necessarily