Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2024-01-15 18:08:13 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2024-01-15 18:08:13 +0300
commita29eae68f453c371271641899e00ea24339fb1c6 (patch)
tree5c7d43159cdaee44d3f510db0f42941ed3f3bb90
parentf58a5001b9c4988d8b95178b028a3d82bb346e28 (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.rubocop_todo/layout/empty_line_after_magic_comment.yml2
-rw-r--r--.rubocop_todo/layout/line_length.yml3
-rw-r--r--.rubocop_todo/rspec/context_wording.yml2
-rw-r--r--.rubocop_todo/rspec/verified_doubles.yml2
-rw-r--r--.rubocop_todo/style/guard_clause.yml1
-rw-r--r--app/assets/javascripts/ci/catalog/components/details/ci_resource_readme.vue2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue9
-rw-r--r--app/finders/ci/runners_finder.rb144
-rw-r--r--app/models/merge_request_diff.rb17
-rw-r--r--app/services/import/github_service.rb21
-rw-r--r--config/feature_flags/development/add_policy_approvers_to_rules.yml2
-rw-r--r--config/feature_flags/development/packages_dependency_proxy_maven.yml8
-rw-r--r--doc/api/graphql/reference/index.md19
-rw-r--r--doc/api/group_level_variables.md54
-rw-r--r--doc/api/merge_requests.md9
-rw-r--r--doc/architecture/blueprints/secret_detection/index.md120
-rw-r--r--doc/architecture/blueprints/tailwindcss/index.md172
-rw-r--r--doc/development/internal_analytics/index.md4
-rw-r--r--doc/development/internal_analytics/internal_event_instrumentation/local_setup_and_debugging.md13
-rw-r--r--doc/development/internal_analytics/internal_event_instrumentation/quick_start.md7
-rw-r--r--doc/user/markdown.md189
-rw-r--r--doc/user/packages/package_registry/dependency_proxy/index.md7
-rw-r--r--lib/api/entities/diff.rb1
-rw-r--r--lib/api/group_variables.rb30
-rw-r--r--lib/gitlab/ci/config/external/file/remote.rb2
-rw-r--r--lib/gitlab/diff/file_collection/paginated_merge_request_diff.rb4
-rw-r--r--lib/gitlab/event_store/event.rb2
-rw-r--r--lib/gitlab/tracking/event_definition.rb14
-rw-r--r--lib/gitlab/usage/metric_definition.rb12
-rw-r--r--locale/gitlab.pot60
-rw-r--r--spec/lib/api/entities/diff_spec.rb3
-rw-r--r--spec/lib/gitlab/ci/yaml_processor/test_cases/include_spec.rb80
-rw-r--r--spec/lib/gitlab/ci/yaml_processor/test_cases/interruptible_spec.rb5
-rw-r--r--spec/lib/gitlab/diff/file_collection/paginated_merge_request_diff_spec.rb23
-rw-r--r--spec/lib/gitlab/event_store/event_spec.rb7
-rw-r--r--spec/lib/gitlab/tracking/event_definition_spec.rb10
-rw-r--r--spec/lib/gitlab/tracking/event_definition_validate_all_spec.rb12
-rw-r--r--spec/lib/gitlab/usage/metric_definition_spec.rb56
-rw-r--r--spec/lib/gitlab/usage/metric_definition_validate_all_spec.rb14
-rw-r--r--spec/models/merge_request_diff_spec.rb26
-rw-r--r--spec/requests/api/import_github_spec.rb7
-rw-r--r--spec/services/import/github_service_spec.rb33
-rw-r--r--spec/support/rspec_order_todo.yml6
43 files changed, 842 insertions, 372 deletions
diff --git a/.rubocop_todo/layout/empty_line_after_magic_comment.yml b/.rubocop_todo/layout/empty_line_after_magic_comment.yml
index ba08bc8ae08..3d6266a7438 100644
--- a/.rubocop_todo/layout/empty_line_after_magic_comment.yml
+++ b/.rubocop_todo/layout/empty_line_after_magic_comment.yml
@@ -203,8 +203,6 @@ Layout/EmptyLineAfterMagicComment:
- 'ee/app/services/ee/system_notes/issuables_service.rb'
- 'ee/app/services/gitlab_subscriptions/fetch_subscription_plans_service.rb'
- 'ee/app/services/gitlab_subscriptions/reconciliations/calculate_seat_count_data_service.rb'
- - 'ee/app/services/group_saml/group_managed_accounts/clean_up_members_service.rb'
- - 'ee/app/services/group_saml/sign_up_service.rb'
- 'ee/app/services/merge_trains/create_pipeline_service.rb'
- 'ee/app/services/merge_trains/refresh_merge_request_service.rb'
- 'ee/app/services/merge_trains/refresh_service.rb'
diff --git a/.rubocop_todo/layout/line_length.yml b/.rubocop_todo/layout/line_length.yml
index 060b55f00d0..684681750b4 100644
--- a/.rubocop_todo/layout/line_length.yml
+++ b/.rubocop_todo/layout/line_length.yml
@@ -1012,9 +1012,7 @@ Layout/LineLength:
- 'ee/app/services/geo/request_service.rb'
- 'ee/app/services/geo/verification_state_backfill_service.rb'
- 'ee/app/services/gitlab_subscriptions/plan_upgrade_service.rb'
- - 'ee/app/services/group_saml/group_managed_accounts/transfer_membership_service.rb'
- 'ee/app/services/group_saml/saml_provider/base_service.rb'
- - 'ee/app/services/group_saml/sign_up_service.rb'
- 'ee/app/services/groups/memberships/export_service.rb'
- 'ee/app/services/groups/sync_service.rb'
- 'ee/app/services/incident_management/create_incident_sla_exceeded_label_service.rb'
@@ -1350,7 +1348,6 @@ Layout/LineLength:
- 'ee/spec/features/groups/saml_providers_spec.rb'
- 'ee/spec/features/groups/scim_token_spec.rb'
- 'ee/spec/features/groups/security/compliance_dashboards_spec.rb'
- - 'ee/spec/features/groups/sso_spec.rb'
- 'ee/spec/features/integrations/jira/jira_issues_list_spec.rb'
- 'ee/spec/features/issues/filtered_search/filter_issues_weight_spec.rb'
- 'ee/spec/features/issues/form_spec.rb'
diff --git a/.rubocop_todo/rspec/context_wording.yml b/.rubocop_todo/rspec/context_wording.yml
index d8303d8beb2..7859119eb60 100644
--- a/.rubocop_todo/rspec/context_wording.yml
+++ b/.rubocop_todo/rspec/context_wording.yml
@@ -109,7 +109,6 @@ RSpec/ContextWording:
- 'ee/spec/features/groups/saml_enforcement_spec.rb'
- 'ee/spec/features/groups/saml_providers_spec.rb'
- 'ee/spec/features/groups/security/compliance_dashboards_spec.rb'
- - 'ee/spec/features/groups/sso_spec.rb'
- 'ee/spec/features/groups_spec.rb'
- 'ee/spec/features/ide/user_opens_ide_spec.rb'
- 'ee/spec/features/issues/epic_in_issue_sidebar_spec.rb'
@@ -714,7 +713,6 @@ RSpec/ContextWording:
- 'ee/spec/services/geo/prune_event_log_service_spec.rb'
- 'ee/spec/services/gitlab_subscriptions/create_service_spec.rb'
- 'ee/spec/services/gitlab_subscriptions/preview_billable_user_change_service_spec.rb'
- - 'ee/spec/services/group_saml/group_managed_accounts/transfer_membership_service_spec.rb'
- 'ee/spec/services/groups/destroy_service_spec.rb'
- 'ee/spec/services/groups/mark_for_deletion_service_spec.rb'
- 'ee/spec/services/groups/memberships/export_service_spec.rb'
diff --git a/.rubocop_todo/rspec/verified_doubles.yml b/.rubocop_todo/rspec/verified_doubles.yml
index 4824f2007d3..8178d11a710 100644
--- a/.rubocop_todo/rspec/verified_doubles.yml
+++ b/.rubocop_todo/rspec/verified_doubles.yml
@@ -147,8 +147,6 @@ RSpec/VerifiedDoubles:
- 'ee/spec/services/geo/node_status_request_service_spec.rb'
- 'ee/spec/services/geo/replication_toggle_request_service_spec.rb'
- 'ee/spec/services/gitlab_subscriptions/fetch_subscription_plans_service_spec.rb'
- - 'ee/spec/services/group_saml/group_managed_accounts/clean_up_members_service_spec.rb'
- - 'ee/spec/services/group_saml/sign_up_service_spec.rb'
- 'ee/spec/services/groups/update_repository_storage_service_spec.rb'
- 'ee/spec/services/ide/schemas_config_service_spec.rb'
- 'ee/spec/services/incident_management/oncall_schedules/update_service_spec.rb'
diff --git a/.rubocop_todo/style/guard_clause.yml b/.rubocop_todo/style/guard_clause.yml
index 429eeff3787..65847c093d5 100644
--- a/.rubocop_todo/style/guard_clause.yml
+++ b/.rubocop_todo/style/guard_clause.yml
@@ -347,7 +347,6 @@ Style/GuardClause:
- 'ee/app/services/epics/tree_reorder_service.rb'
- 'ee/app/services/epics/update_service.rb'
- 'ee/app/services/geo/metrics_update_service.rb'
- - 'ee/app/services/group_saml/group_managed_accounts/transfer_membership_service.rb'
- 'ee/app/services/groups/update_repository_storage_service.rb'
- 'ee/app/services/incident_management/oncall_rotations/remove_participant_service.rb'
- 'ee/app/services/iterations/delete_service.rb'
diff --git a/app/assets/javascripts/ci/catalog/components/details/ci_resource_readme.vue b/app/assets/javascripts/ci/catalog/components/details/ci_resource_readme.vue
index 343b555c4d8..ccef50e469d 100644
--- a/app/assets/javascripts/ci/catalog/components/details/ci_resource_readme.vue
+++ b/app/assets/javascripts/ci/catalog/components/details/ci_resource_readme.vue
@@ -50,6 +50,6 @@ export default {
<template>
<div>
<gl-loading-icon v-if="isLoading" class="gl-mt-5" size="lg" />
- <div v-else v-safe-html="readmeHtml"></div>
+ <div v-else v-safe-html="readmeHtml" class="md"></div>
</div>
</template>
diff --git a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue
index 7413e2237c3..afdb9e9ff08 100644
--- a/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue
+++ b/app/assets/javascripts/vue_merge_request_widget/components/widget/widget_content_row.vue
@@ -72,6 +72,11 @@ export default {
return this.actionButtons.length > 0;
},
},
+ methods: {
+ hasHeader() {
+ return Boolean(this.$scopedSlots.header || this.header || this.shouldShowHeaderActions);
+ },
+ },
i18n: {
learnMore: __('Learn more'),
},
@@ -91,9 +96,9 @@ export default {
:icon-name="statusIconName"
/>
<div class="gl-w-full gl-min-w-0">
- <div class="gl-display-flex">
+ <div v-if="hasHeader()" class="gl-display-flex">
<slot name="header">
- <div v-if="header" class="gl-mb-2">
+ <div class="gl-mb-2">
<strong v-safe-html="generatedHeader" class="gl-display-block"></strong
><span
v-if="generatedSubheader"
diff --git a/app/finders/ci/runners_finder.rb b/app/finders/ci/runners_finder.rb
index 88402748083..18be2aec2e2 100644
--- a/app/finders/ci/runners_finder.rb
+++ b/app/finders/ci/runners_finder.rb
@@ -14,18 +14,25 @@ module Ci
end
def execute
- search!
- filter_by_active!
- filter_by_status!
- filter_by_upgrade_status!
- filter_by_runner_type!
- filter_by_tag_list!
- filter_by_creator_id!
- filter_by_version_prefix!
- sort!
- request_tag_list!
-
- @runners
+ items = if @project
+ project_runners
+ elsif @group
+ group_runners
+ else
+ all_runners
+ end
+
+ items = search(items)
+ items = by_active(items)
+ items = by_status(items)
+ items = by_upgrade_status(items)
+ items = by_runner_type(items)
+ items = by_tag_list(items)
+ items = by_creator_id(items)
+ items = by_version_prefix(items)
+ items = request_tag_list(items)
+
+ sort(items)
end
def sort_key
@@ -40,105 +47,104 @@ module Ci
%w[contacted_asc contacted_desc created_at_asc created_at_desc created_date token_expires_at_asc token_expires_at_desc]
end
- def search!
- if @project
- project_runners
- elsif @group
- group_runners
- else
- all_runners
- end
-
- @runners = @runners.search(@params[:search]) if @params[:search].present?
- end
-
def all_runners
raise Gitlab::Access::AccessDeniedError unless @current_user&.can_admin_all_resources?
- @runners = Ci::Runner.all
+ Ci::Runner.all
end
def group_runners
raise Gitlab::Access::AccessDeniedError unless can?(@current_user, :read_group_runners, @group)
- @runners = case @params[:membership]
- when :direct
- Ci::Runner.belonging_to_group(@group.id)
- when :descendants, nil
- Ci::Runner.belonging_to_group_or_project_descendants(@group.id)
- when :all_available
- unless can?(@current_user, :read_group_all_available_runners, @group)
- raise Gitlab::Access::AccessDeniedError
- end
-
- Ci::Runner.usable_from_scope(@group)
- else
- raise ArgumentError, 'Invalid membership filter'
- end
+ case @params[:membership]
+ when :direct
+ Ci::Runner.belonging_to_group(@group.id)
+ when :descendants, nil
+ Ci::Runner.belonging_to_group_or_project_descendants(@group.id)
+ when :all_available
+ unless can?(@current_user, :read_group_all_available_runners, @group)
+ raise Gitlab::Access::AccessDeniedError
+ end
+
+ Ci::Runner.usable_from_scope(@group)
+ else
+ raise ArgumentError, 'Invalid membership filter'
+ end
end
def project_runners
raise Gitlab::Access::AccessDeniedError unless can?(@current_user, :read_project_runners, @project)
- @runners = ::Ci::Runner.owned_or_instance_wide(@project.id)
+ ::Ci::Runner.owned_or_instance_wide(@project.id)
end
- def filter_by_active!
- @runners = @runners.active(@params[:active]) if @params.include?(:active)
+ def search(items)
+ return items unless @params[:search].present?
+
+ items.search(@params[:search])
end
- def filter_by_status!
- @runners = @runners.with_status(@params[:status_status]) if @params[:status_status].present?
+ def by_active(items)
+ return items if @params.exclude?(:active)
+
+ items.active(@params[:active])
end
- def filter_by_upgrade_status!
+ def by_status(items)
+ status = @params[:status_status].presence
+ return items unless status
+
+ items.with_status(status)
+ end
+
+ def by_upgrade_status(items)
upgrade_status = @params[:upgrade_status]
- return unless upgrade_status
+ return items unless upgrade_status
unless Ci::RunnerVersion.statuses.key?(upgrade_status)
raise ArgumentError, "Invalid upgrade status value '#{upgrade_status}'"
end
- @runners = @runners.with_upgrade_status(upgrade_status)
+ items.with_upgrade_status(upgrade_status)
end
- def filter_by_runner_type!
- runner_type = @params[:type_type]
- return if runner_type.blank?
+ def by_runner_type(items)
+ runner_type = @params[:type_type].presence
+ return items unless runner_type
- @runners = @runners.with_runner_type(runner_type)
+ items.with_runner_type(runner_type)
end
- def filter_by_tag_list!
+ def by_tag_list(items)
tag_list = @params[:tag_name].presence
+ return items unless tag_list
- if tag_list
- @runners = @runners.tagged_with(tag_list)
- end
+ items.tagged_with(tag_list)
end
- def filter_by_creator_id!
- creator_id = @params[:creator_id]
- @runners = @runners.with_creator_id(creator_id) if creator_id.present?
- end
-
- def filter_by_version_prefix!
- return @runners unless @params[:version_prefix]
+ def by_creator_id(items)
+ creator_id = @params[:creator_id].presence
+ return items unless creator_id
- sanitized_prefix = @params[:version_prefix][/^[\d+.]+/]
+ items.with_creator_id(creator_id)
+ end
- return @runners unless sanitized_prefix
+ def by_version_prefix(items)
+ sanitized_prefix = @params.fetch(:version_prefix, '')[/^[\d+.]+/]
+ return items unless sanitized_prefix
- @runners = @runners.with_version_prefix(sanitized_prefix)
+ items.with_version_prefix(sanitized_prefix)
end
- def sort!
- @runners = @runners.order_by(sort_key)
+ def sort(items)
+ items.order_by(sort_key)
end
- def request_tag_list!
- @runners = @runners.with_tags if @params.exclude?(:preload) || @params.dig(:preload, :tag_name)
+ def request_tag_list(items)
+ return items if @params.include?(:preload) && !@params.dig(:preload, :tag_name) # Backward-compatible behavior
+
+ items.with_tags
end
end
end
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index f1ce4738015..47102418152 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -461,18 +461,25 @@ class MergeRequestDiff < ApplicationRecord
fetching_repository_diffs({}) do |comparison|
reorder_diff_files!
+ collapse_generated = Feature.enabled?(:collapse_generated_diff_files, project)
+ diff_options = { collapse_generated: collapse_generated }
+
collection = Gitlab::Diff::FileCollection::PaginatedMergeRequestDiff.new(
self,
page,
- per_page
+ per_page,
+ diff_options
)
if comparison
+ diff_options[:generated_files] = comparison.generated_files if collapse_generated
+
comparison.diffs(
- paths: collection.diff_paths,
- page: collection.current_page,
- per_page: collection.limit_value,
- count: collection.total_count
+ diff_options.merge(
+ paths: collection.diff_paths,
+ page: collection.current_page,
+ per_page: collection.limit_value,
+ count: collection.total_count)
)
else
collection
diff --git a/app/services/import/github_service.rb b/app/services/import/github_service.rb
index b8389192b18..ffd26e2aaca 100644
--- a/app/services/import/github_service.rb
+++ b/app/services/import/github_service.rb
@@ -5,6 +5,8 @@ module Import
include ActiveSupport::NumberHelper
include Gitlab::Utils::StrongMemoize
+ COLLAB_IMPORT_SCOPES = %w[admin:org read:org].freeze
+
attr_accessor :client
attr_reader :params, :current_user
@@ -12,6 +14,9 @@ module Import
context_error = validate_context
return context_error if context_error
+ scope_error = validate_collaborators_import_scope
+ return scope_error if scope_error
+
project = create_project(access_params, provider)
track_access_level('github')
@@ -98,6 +103,22 @@ module Import
private
+ def validate_collaborators_import_scope
+ collaborators_import = params.dig(:optional_stages, :collaborators_import)
+ # A value for `collaborators_import` may not be included in POST params
+ # and the default value is `true`
+ return unless collaborators_import == true || collaborators_import.nil?
+
+ # We need to call `#repo` to ensure the `#last_response` from the client has the headers we need.
+ repo
+ scopes = client.octokit.last_response.headers["x-oauth-scopes"]
+ scopes = scopes.split(',').map(&:strip)
+
+ return if (scopes & COLLAB_IMPORT_SCOPES).any?
+
+ log_and_return_error('Invalid scope', _('Your GitHub access token does not have the correct scope to import collaborators.'), :unprocessable_entity)
+ end
+
def validate_context
if blocked_url?
log_and_return_error("Invalid URL: #{url}", _("Invalid URL: %{url}") % { url: url }, :bad_request)
diff --git a/config/feature_flags/development/add_policy_approvers_to_rules.yml b/config/feature_flags/development/add_policy_approvers_to_rules.yml
index 1d5584c5181..c0e8d804840 100644
--- a/config/feature_flags/development/add_policy_approvers_to_rules.yml
+++ b/config/feature_flags/development/add_policy_approvers_to_rules.yml
@@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/434385
milestone: '16.8'
type: development
group: group::security policies
-default_enabled: false
+default_enabled: true
diff --git a/config/feature_flags/development/packages_dependency_proxy_maven.yml b/config/feature_flags/development/packages_dependency_proxy_maven.yml
deleted file mode 100644
index 8cf2f5a2879..00000000000
--- a/config/feature_flags/development/packages_dependency_proxy_maven.yml
+++ /dev/null
@@ -1,8 +0,0 @@
----
-name: packages_dependency_proxy_maven
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123491
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/415218
-milestone: '16.2'
-type: development
-group: group::package registry
-default_enabled: false
diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md
index fd7ff91c6eb..6c6ab0e9f74 100644
--- a/doc/api/graphql/reference/index.md
+++ b/doc/api/graphql/reference/index.md
@@ -7628,11 +7628,6 @@ Input type: `UpdateDependencyProxyImageTtlGroupPolicyInput`
Updates or creates dependency proxy for packages settings.
Requires the packages and dependency proxy to be enabled in the config.
Requires the packages feature to be enabled at the project level.
-Error is raised if `packages_dependency_proxy_maven` feature flag is disabled.
-
-WARNING:
-**Introduced** in 16.5.
-This feature is an Experiment. It can be changed or removed at any time.
Input type: `UpdateDependencyProxyPackagesSettingsInput`
@@ -7641,10 +7636,10 @@ Input type: `UpdateDependencyProxyPackagesSettingsInput`
| Name | Type | Description |
| ---- | ---- | ----------- |
| <a id="mutationupdatedependencyproxypackagessettingsclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
-| <a id="mutationupdatedependencyproxypackagessettingsenabled"></a>`enabled` | [`Boolean`](#boolean) | Indicates whether the dependency proxy for packages is enabled for the project. Introduced in 16.5: This feature is an Experiment. It can be changed or removed at any time. |
+| <a id="mutationupdatedependencyproxypackagessettingsenabled"></a>`enabled` | [`Boolean`](#boolean) | Indicates whether the dependency proxy for packages is enabled for the project. |
| <a id="mutationupdatedependencyproxypackagessettingsmavenexternalregistrypassword"></a>`mavenExternalRegistryPassword` | [`String`](#string) | Password for the external Maven packages registry. Introduced in 16.5: This feature is an Experiment. It can be changed or removed at any time. |
-| <a id="mutationupdatedependencyproxypackagessettingsmavenexternalregistryurl"></a>`mavenExternalRegistryUrl` | [`String`](#string) | URL for the external Maven packages registry. Introduced in 16.5: This feature is an Experiment. It can be changed or removed at any time. |
-| <a id="mutationupdatedependencyproxypackagessettingsmavenexternalregistryusername"></a>`mavenExternalRegistryUsername` | [`String`](#string) | Username for the external Maven packages registry. Introduced in 16.5: This feature is an Experiment. It can be changed or removed at any time. |
+| <a id="mutationupdatedependencyproxypackagessettingsmavenexternalregistryurl"></a>`mavenExternalRegistryUrl` | [`String`](#string) | URL for the external Maven packages registry. |
+| <a id="mutationupdatedependencyproxypackagessettingsmavenexternalregistryusername"></a>`mavenExternalRegistryUsername` | [`String`](#string) | Username for the external Maven packages registry. |
| <a id="mutationupdatedependencyproxypackagessettingsprojectpath"></a>`projectPath` | [`ID!`](#id) | Project path for the dependency proxy for packages settings. |
#### Fields
@@ -17601,9 +17596,9 @@ Project-level Dependency Proxy for packages settings.
| Name | Type | Description |
| ---- | ---- | ----------- |
-| <a id="dependencyproxypackagessettingenabled"></a>`enabled` **{warning-solid}** | [`Boolean!`](#boolean) | **Introduced** in 16.5. This feature is an Experiment. It can be changed or removed at any time. Indicates whether the dependency proxy for packages is enabled for the project. |
-| <a id="dependencyproxypackagessettingmavenexternalregistryurl"></a>`mavenExternalRegistryUrl` **{warning-solid}** | [`String`](#string) | **Introduced** in 16.5. This feature is an Experiment. It can be changed or removed at any time. URL for the external Maven packages registry. |
-| <a id="dependencyproxypackagessettingmavenexternalregistryusername"></a>`mavenExternalRegistryUsername` **{warning-solid}** | [`String`](#string) | **Introduced** in 16.5. This feature is an Experiment. It can be changed or removed at any time. Username for the external Maven packages registry. |
+| <a id="dependencyproxypackagessettingenabled"></a>`enabled` | [`Boolean!`](#boolean) | Indicates whether the dependency proxy for packages is enabled for the project. |
+| <a id="dependencyproxypackagessettingmavenexternalregistryurl"></a>`mavenExternalRegistryUrl` | [`String`](#string) | URL for the external Maven packages registry. |
+| <a id="dependencyproxypackagessettingmavenexternalregistryusername"></a>`mavenExternalRegistryUsername` | [`String`](#string) | Username for the external Maven packages registry. |
### `DependencyProxySetting`
@@ -24335,7 +24330,7 @@ Represents vulnerability finding of a security report on the pipeline.
| <a id="projectcreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of the project creation. |
| <a id="projectdastscannerprofiles"></a>`dastScannerProfiles` | [`DastScannerProfileConnection`](#dastscannerprofileconnection) | DAST scanner profiles associated with the project. (see [Connections](#connections)) |
| <a id="projectdastsiteprofiles"></a>`dastSiteProfiles` | [`DastSiteProfileConnection`](#dastsiteprofileconnection) | DAST Site Profiles associated with the project. (see [Connections](#connections)) |
-| <a id="projectdependencyproxypackagessetting"></a>`dependencyProxyPackagesSetting` **{warning-solid}** | [`DependencyProxyPackagesSetting`](#dependencyproxypackagessetting) | **Introduced** in 16.5. This feature is an Experiment. It can be changed or removed at any time. Packages Dependency Proxy settings for the project. Requires the packages and dependency proxy to be enabled in the config. Requires the packages feature to be enabled at the project level. Returns `null` if `packages_dependency_proxy_maven` feature flag is disabled. |
+| <a id="projectdependencyproxypackagessetting"></a>`dependencyProxyPackagesSetting` | [`DependencyProxyPackagesSetting`](#dependencyproxypackagessetting) | Packages Dependency Proxy settings for the project. Requires the packages and dependency proxy to be enabled in the config. Requires the packages feature to be enabled at the project level. |
| <a id="projectdescription"></a>`description` | [`String`](#string) | Short description of the project. |
| <a id="projectdescriptionhtml"></a>`descriptionHtml` | [`String`](#string) | GitLab Flavored Markdown rendering of `description`. |
| <a id="projectdetailedimportstatus"></a>`detailedImportStatus` | [`DetailedImportStatus`](#detailedimportstatus) | Detailed import status of the project. |
diff --git a/doc/api/group_level_variables.md b/doc/api/group_level_variables.md
index 339145e8da7..aeab76b7212 100644
--- a/doc/api/group_level_variables.md
+++ b/doc/api/group_level_variables.md
@@ -49,7 +49,10 @@ curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/a
## Show variable details
-Get the details of a group's specific variable.
+> The `filter` parameter was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340185) in GitLab 16.9.
+
+Get the details of a group's specific variable. If there are multiple variables with the same key,
+use `filter` to select the correct `environment_scope`.
```plaintext
GET /groups/:id/variables/:key
@@ -59,6 +62,7 @@ GET /groups/:id/variables/:key
|-----------|----------------|----------|-------------|
| `id` | integer/string | Yes | The ID of a group or [URL-encoded path of the group](rest/index.md#namespaced-path-encoding) |
| `key` | string | Yes | The `key` of a variable |
+| `filter` | hash | No | Available filters: `[environment_scope]`. See the [`filter` parameter details](#the-filter-parameter). |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/1/variables/TEST_VARIABLE_1"
@@ -117,7 +121,10 @@ curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" \
## Update variable
-Update a group's variable.
+> The `filter` parameter was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340185) in GitLab 16.9.
+
+Update a group's variable. If there are multiple variables with the same key,
+use `filter` to select the correct `environment_scope`.
```plaintext
PUT /groups/:id/variables/:key
@@ -130,6 +137,7 @@ PUT /groups/:id/variables/:key
| `value` | string | Yes | The `value` of a variable |
| `description` | string | No | The description of the variable. Default: `null`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/409641) in GitLab 16.2. |
| `environment_scope` **(PREMIUM ALL)** | string | No | The [environment scope](../ci/environments/index.md#limit-the-environment-scope-of-a-cicd-variable) of a variable |
+| `filter` | hash | No | Available filters: `[environment_scope]`. See the [`filter` parameter details](#the-filter-parameter). |
| `masked` | boolean | No | Whether the variable is masked |
| `protected` | boolean | No | Whether the variable is protected |
| `raw` | boolean | No | Whether the variable is treated as a raw string. Default: `false`. When `true`, variables in the value are not [expanded](../ci/variables/index.md#prevent-cicd-variable-expansion). |
@@ -155,7 +163,10 @@ curl --request PUT --header "PRIVATE-TOKEN: <your_access_token>" \
## Remove variable
-Remove a group's variable.
+> The `filter` parameter was [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340185) in GitLab 16.9.
+
+Remove a group's variable. If there are multiple variables with the same key,
+use `filter` to select the correct `environment_scope`.
```plaintext
DELETE /groups/:id/variables/:key
@@ -165,8 +176,45 @@ DELETE /groups/:id/variables/:key
|-----------|----------------|----------|-------------|
| `id` | integer/string | Yes | The ID of a group or [URL-encoded path of the group](rest/index.md#namespaced-path-encoding) |
| `key` | string | Yes | The `key` of a variable |
+| `filter` | hash | No | Available filters: `[environment_scope]`. See the [`filter` parameter details](#the-filter-parameter). |
```shell
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" \
"https://gitlab.example.com/api/v4/groups/1/variables/VARIABLE_1"
```
+
+## The `filter` parameter **(PREMIUM ALL)**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/340185) in GitLab 16.9.
+
+When multiple variables have the same `key`, [GET](#show-variable-details), [PUT](#update-variable),
+or [DELETE](#remove-variable) requests might return:
+
+```plaintext
+There are multiple variables with provided parameters. Please use 'filter[environment_scope]'.
+```
+
+Use `filter[environment_scope]` to select the variable with the matching `environment_scope` attribute.
+
+For example:
+
+- GET:
+
+ ```shell
+ curl --globoff --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/groups/1/variables/SCOPED_VARIABLE_1?filter[environment_scope]=production"
+ ```
+
+- PUT:
+
+ ```shell
+ curl --request PUT --globoff --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/groups/1/variables/SCOPED_VARIABLE_1?value=scoped-variable-updated-value&environment_scope=production&filter[environment_scope]=production"
+ ```
+
+- DELETE:
+
+ ```shell
+ curl --request DELETE --globoff --header "PRIVATE-TOKEN: <your_access_token>" \
+ "https://gitlab.example.com/api/v4/groups/1/variables/SCOPED_VARIABLE_1?filter[environment_scope]=production"
+ ```
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index 02407b5e650..1e26a23272d 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -1107,6 +1107,8 @@ Example response:
## List merge request diffs
+> `generated_file` was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141576) in GitLab 16.9 [with a flag](../administration/feature_flags.md) named `collapse_generated_diff_files`. Disabled by default.
+
List diffs of the files changed in a merge request.
```plaintext
@@ -1136,6 +1138,7 @@ following response attributes:
| `new_file` | boolean | Indicates if the file has just been added. |
| `renamed_file` | boolean | Indicates if the file has been renamed. |
| `deleted_file` | boolean | Indicates if the file has been removed. |
+| `generated_file` | boolean | Indicates if the file is marked as generated. |
Example request:
@@ -1156,7 +1159,8 @@ Example response:
"diff": "@@ -1 +1 @@\ -Title\ +README",
"new_file": false,
"renamed_file": false,
- "deleted_file": false
+ "deleted_file": false,
+ "generated_file": false
},
{
"old_path": "VERSION",
@@ -1166,7 +1170,8 @@ Example response:
"diff": "@@\ -1.9.7\ +1.9.8",
"new_file": false,
"renamed_file": false,
- "deleted_file": false
+ "deleted_file": false,
+ "generated_file": false
}
]
```
diff --git a/doc/architecture/blueprints/secret_detection/index.md b/doc/architecture/blueprints/secret_detection/index.md
index f98c954b60d..3e9421539e6 100644
--- a/doc/architecture/blueprints/secret_detection/index.md
+++ b/doc/architecture/blueprints/secret_detection/index.md
@@ -35,8 +35,8 @@ See [target types](#target-types) for scan target priorities.
### Non-Goals
-Initial proposal is limited to detection and alerting across platform, with rejection only
-during [preceive Git interactions and browser-based detection](#iterations).
+Phase1 is limited to detection and alerting across platform, with rejection only
+during [prereceive Git interactions and browser-based detection](#iterations).
Secret revocation and rotation is also beyond the scope of this new capability.
@@ -86,20 +86,47 @@ Targets out of scope for the initial phases include:
The existing Secret Detection configuration covers 100+ rules across a variety
of platforms. To reduce total cost of execution and likelihood of false positives
-the dedicated service targets only well-defined tokens. A well-defined token is
-defined as a token with a precise definition, most often a fixed substring prefix (or
-suffix) and fixed length.
+the dedicated service targets only well-defined, low-FP tokens.
Token types to identify in order of importance:
1. Well-defined GitLab tokens (including Personal Access Tokens and Pipeline Trigger Tokens)
1. Verified Partner tokens (including AWS)
-1. Well-defined third party tokens
+1. Well-defined low-FP third party tokens
1. Remainder tokens currently included in Secret Detection analyzer configuration
+A well-defined token is a token with a precise definition, most often a fixed
+substring prefix (or suffix) and fixed length.
+
+For GitLab and partner tokens, we have good domain understanding of our own tokens
+and by collaborating with partners verified the accuracy of their provided patterns.
+
+An observed low-FP token relies on user reports and dismissal reports. With delivery of
+[this data issue](https://gitlab.com/gitlab-data/product-analytics/-/issues/1225)
+we will have aggregates on FP-rates but primarily this is user-reported data, at present.
+
In order to minimize false positives, there are no plans to introduce or alert on high-entropy,
arbitrary strings; i.e. patterns such as `3lsjkw3a22`.
+#### Uniformity of rule configuration
+
+Rule pattern configuration should remain centralized in the `secrets` analyzer's packaged `gitleaks.toml`
+configuration, vendored to the monolith for Phase 1, and checksum-checked to ensure it matches the
+specific release version to avoid drift. Each token can be filtered by `tags` to form both high-confidence
+and blocking groupings. For example:
+
+```ruby
+prereceive_blocking_rules = toml.load_file('gitleaks.toml')['rules'].select do |r|
+ r.tags.include?('gitlab_blocking_p1') &&
+ r.tags.include?('gitlab_blocking')
+end
+```
+
+### Auditability
+
+A critical aspect of both secret detection and [suppression](#detection-suppression) is administrative visibility.
+With each phase we must include audit capabilities (events or logging) to enable event discovery.
+
## Proposal
The first iteration of the experimental capability will feature a blocking
@@ -142,17 +169,15 @@ In expansion phases we must explore chunking or alternative strategies like the
## Design and implementation details
+The detection capability relies on a multiphase rollout, from an experimental component implemented directly in the monolith to a standalone service capable of scanning text blobs generically.
+
The implementation of the secret scanning service is highly dependent on the outcomes of our benchmarking
and capacity planning against both GitLab.com and our
[Reference Architectures](../../../administration/reference_architectures/index.md).
As the scanning capability must be an on-by-default component of both our SaaS and self-managed
-instances [the PoC](#iterations), the deployment characteristics must be considered to determine whether
-this is a standalone component or executed as a subprocess of the existing Sidekiq worker fleet
-(similar to the implementation of our Elasticsearch indexing service).
-
-Similarly, the scan target volume will require a robust and scalable enqueueing system to limit resource consumption.
-
-The detection capability relies on a multiphase rollout, from an experimental component implemented directly in the monolith to a standalone service capable of scanning text blobs generically.
+instances, [each iteration's](#iterations) deployment characteristic defines whether
+the service will act as a standalone component, or executed as a subprocess of the Rails architecture
+(as mirrors the implementation of our Elasticsearch indexing service).
See [technical discovery](https://gitlab.com/gitlab-org/gitlab/-/issues/376716)
for further background exploration.
@@ -177,14 +202,18 @@ for pre-filtering and `re2` for regex detections. See [spike issue](https://gitl
Notable alternatives include high-performance regex engines such as [Hyperscan](https://github.com/intel/hyperscan) or it's portable fork [Vectorscan](https://github.com/VectorCamp/vectorscan).
These systems may be worth exploring in the future if our performance characteristics show a need to grow beyond the existing stack, however the team's velocity in building an independently scalable and generic scanning engine was prioritized, see [ADR 001](decisions/001_use_ruby_push_check_approach_within_monolith.md) for more on the implementation language considerations.
+### Organization-level Controls
+
+Configuration and workflows should be oriented around [Organizations](../organization/index.md). Detection controls and governance patterns should support configuration across multiple projects and groups in a uniform way that emphasizes shared allowlists, organization-wide policies (i.e. disablement of push option bypass), and auditability.
+
+Each phase documents the paradigm used as we iterate from Instance-level to Organization-level controls.
+
### Phase 1 - Ruby pushcheck pre-receive integration
The critical paths as outlined under [goals above](#goals) cover two major object
types: Git text blobs (corresponding to push events) and arbitrary text blobs. In Phase 1,
we focus entirely on Git text blobs.
-This phase will be considered "Experimental" with limited availability for customer opt-in, through instance level application settings.
-
The detection flow for push events relies on subscribing to the PreReceive hook
to scan commit data using the [PushCheck interface](https://gitlab.com/gitlab-org/gitlab/blob/3f1653f5706cd0e7bbd60ed7155010c0a32c681d/lib/gitlab/checks/push_check.rb). This `SecretScanningService`
service fetches the specified blob contents from Gitaly, scans
@@ -193,6 +222,10 @@ See [Push event detection flow](#push-event-detection-flow) for sequence.
In the case of a push detection, the commit is rejected inline and error returned to the end user.
+#### Configuration
+
+This phase will be considered "Experimental" with limited availability for customer opt-in, through instance level application settings.
+
#### High-Level Architecture
The Phase 1 architecture involves no additional components and is entirely encapsulated in the Rails application server. This provides a rapid deployment with tight integration within auth boundaries and no distribution coordination.
@@ -260,7 +293,7 @@ sequenceDiagram
The critical paths as outlined under [goals above](#goals) cover two major object
types: Git text blobs (corresponding to push events) and arbitrary text blobs. In Phase 2,
-we focus entirely on Git text blobs.
+we continue to focus on Git text blobs.
This phase emphasizes scaling the service outside of the monolith for general availability and to allow
an on-by-default behavior. The architecture is adapted to provide an isolated and independently
@@ -268,13 +301,17 @@ scalable service outside of the Rails monolith.
In the case of a push detection, the commit is rejected inline and error returned to the end user.
+#### Configuration
+
+This phase will be considered "Generally Available" and on-by-default, with disablement configuration through organization-level settings.
+
#### High-Level Architecture
The Phase 2 architecture involves extracting the secret detection logic into a standalone service
which communicates directly with both the Rails application and Gitaly. This provides a means to scale
the secret detection nodes independently, and reduce resource usage overhead on the rails application.
-Scans still runs synchronously as a (potentially) blocking pre-receive transaction.
+Scans still runs synchronously as a (potentially) blocking pre-receive transaction. The blob size remains limited to 1MB.
Note that the node count is purely illustrative, but serves to emphasize the independent scaling requirements for the scanning service.
@@ -387,6 +424,10 @@ In any other case of detection, the Rails application manually creates a vulnera
using the `Vulnerabilities::ManuallyCreateService` to surface the finding in the
existing Vulnerability Management UI.
+#### Configuration
+
+This phase will be considered "Generally Available" and on-by-default, with disablement configuration through organization-level settings.
+
#### High-Level Architecture
There is no change to the architecture defined in Phase 2, however the individual load requirements may require scaling up the node counts for the detection service.
@@ -426,6 +467,43 @@ sequenceDiagram
Rails->>User: rejected: secret found
```
+### Future Phases
+
+These are key items for delivering a feature-complete always-on experience but have not have yet been prioritized into phases.
+
+### Large blob sizes (1mb+)
+
+Current phases do not include expansions of blob sizes beyond 1mb. While the main limitation was chosen [to conform to RPC transfer limits for future iterations](#transfer-optimizations-for-large-git-data-blobs) we should expand to supporting additional blob sizes. This can be achieved in two ways:
+
+1. *Post-receive processing*
+
+ Accept blobs in a non-blocking fashion, process scanning as background job and alert passively on detection of a given secret.
+
+1. *Improvements to scanning logic batching*
+
+ Maintaining the constraint of 1MB is primarily futureproofing to match an expected transport protocol. This can be mitigated by using separate transport (http, reads from disk, ...) or by slicing blob sizes.
+
+### Detection Suppression
+
+Suppression of detection and action on leaked secrets will be supported at several levels.
+
+1. *Global suppression* - If a secret is highly-likely to be a false token (i.e. `EXAMPLE`) it should be suppressed in workflow contexts where user would be seriously inconvenienced.
+
+ We should still provide some means of triaging these results, whether via [audit events](#auditability) or as [automatic vulnerability resolution](../../../user/application_security/sast/index.md#automatic-vulnerability-resolution).
+
+1. *Organization suppression* - If a secret matches an organization's allowlist (or was previously flagged and remediated as irrelevant) it should not reoccur. See [Organization-level controls](#organization-level-controls).
+
+1. *Inline suppression* - Inline annotations should be supported in later phases with the Organization-level configuration to ignore annotations.
+
+### External Token Verification
+
+As a post-processing step for detection we should explore verification of detected secrets. This requires processors per supported token type in which we can distinguish tokens that are valid leaks from false positives. Similar to our [automatic response to leaked secrets](../../../user/application_security/secret_detection/automatic_response.md), we must externally verify a given token to give a high degree of confidence in our alerting.
+
+There are two token types: internal and external:
+
+- Internal tokens are verifiable and revocable as part of `ScanSecurityReportSecretsWorker` worker
+- External tokens require external verification, in which [the architecture](../../../user/application_security/secret_detection/automatic_response.md#high-level-architecture) will closely match the [Secret Revocation Service](https://gitlab.com/gitlab-com/gl-security/engineering-and-research/automation-team/secret-revocation-service/)
+
## Iterations
- ✓ Define [requirements for detection coverage and actions](https://gitlab.com/gitlab-org/gitlab/-/issues/376716)
@@ -435,14 +513,14 @@ sequenceDiagram
- [Pre-Production Performance Profiling for pre-receive PoCs](https://gitlab.com/gitlab-org/gitlab/-/issues/428499)
- Profiling service capabilities
- ✓ [Benchmarking regex performance between Ruby and Go approaches](https://gitlab.com/gitlab-org/gitlab/-/issues/423832)
- - x gRPC commit retrieval from Gitaly
- transfer latency, CPU, and memory footprint
- ✓ Implementation of secret scanning gem integration MVC (targeting individual commits)
+- Phase1 - Deployment and monitoring
- Capacity planning for addition of service component to Reference Architectures headroom
- Security and readiness review
-- Deployment and monitoring
-- Implementation of secret scanning service MVC (targeting arbitrary text blobs)
-- Deployment and monitoring
+- Phase2 - Deployment and monitoring
+- Implementation of secret scanning service (targeting arbitrary text blobs)
+- Phase3 - Deployment and monitoring
- High priority domain object rollout (priority `TBD`)
- Issuable comments
- Issuable bodies
diff --git a/doc/architecture/blueprints/tailwindcss/index.md b/doc/architecture/blueprints/tailwindcss/index.md
new file mode 100644
index 00000000000..0409f802038
--- /dev/null
+++ b/doc/architecture/blueprints/tailwindcss/index.md
@@ -0,0 +1,172 @@
+---
+status: proposed
+creation-date: "2023-12-21"
+authors: [ "@peterhegman", "@svedova", "@pgascouvaillancourt" ]
+approvers: [ "@samdbeckham" ]
+owning-stage: "~devops::manage"
+participating-stages: []
+---
+
+<!-- Blueprints often contain forward-looking statements -->
+<!-- vale gitlab.FutureTense = NO -->
+
+# Delegating CSS utility classes generation to Tailwind CSS
+
+## Summary
+
+Styling elements in GitLab primarily relies on CSS utility classes. Those are classes that
+generally define a single CSS property and that can be applied additively to change an element's look.
+We have developed our own tooling in the [GitLab UI](https://gitlab.com/gitlab-org/gitlab-ui) project
+to generate the utils we need, but our approach has demonstrated a number of flaws that can be
+circumvented by delegating that task to the [Tailwind CSS](https://tailwindcss.com/) framework.
+
+This initiative requires that we deprecate existing utilities so that Tailwind CSS can replace them.
+
+## Motivation
+
+In June 2019, we have consolidated our usage of CSS utility classes through [RFC#4](https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/4)
+which introduced the concept of silent classes, where utilities would be generated from a collection
+of manually defined SCSS mixins.
+
+This has served us well, but came with some caveats:
+
+- **Increased development overhead:** whenever a new utility is needed, it has to be manually added
+ to the [GitLab UI](https://gitlab.com/gitlab-org/gitlab-ui) project. One then needs to wait on a
+ new version of `@gitlab/ui` to be released and installed in the consumer project.
+- **Inconsistencies:** Without any tooling in place to check how utilities are named, we have seen
+ many inconsistencies make their way in the library, making it quite unpredictable. The most striking
+ example of this was the introduction of desktop-first utilities among a majority of mobile-first
+ utils, without any way of distinguishing the former from the latter, other than looking at the source.
+- **Disconnection between the utilities library and its consumers:** When a utility is added to the
+ library, it is made available to _any_ project that uses `@gitlab/ui`. As a result, some utils are
+ included in projects that don't need them. Conversely, if all consumers stop using a given util,
+ it could potentially be removed to decrease the CSS bundle size, but we have no visibility over this.
+- **Limited autocompletion:** Although it's possible to configure autocomplete for the existing
+ library, it is restricted to the utilities bundle. In contrast, Tailwind CSS autocomplete aligns
+ with an on-demand approach, ensuring that all utilities are readily available. Additionally, IDE
+ extensions can enhance understanding by revealing the values applied by a specific utility.
+
+As part of this architectural change, we are alleviating these issues by dropping our custom built
+solution for generating CSS utils, and delegating this task to [Tailwind CSS](https://tailwindcss.com/).
+
+It is worth noting that this was previously debated in [RFC#107](https://gitlab.com/gitlab-org/frontend/rfcs/-/issues/107).
+The RFC was well received. The few concerns that were raised were about the CSS utility approach as
+a whole, not the way we implemented it. This initiative's purpose _is not_ to question our reliance
+on utility classes, but to consolidate its implementation to improve engineers' efficiency when working
+with CSS utils.
+
+### Why Tailwind CSS?
+
+Here are a few reasons that led us to choosing Tailwind CSS over similar tools:
+
+- It is a long-standing project that has been battle-tested in many production apps and has a
+ healthy community around it.
+- Tailwind CSS is well maintained and keeps evolving without getting bloated.
+- It integrates well in all of our tech stacks
+ - Ruby on Rails projects can leverage the [`tailwindcss-rails` Gem](https://tailwindcss.com/docs/guides/ruby-on-rails).
+ - Nuxt apps can setup the [`tailwindcss` module](https://nuxt.com/modules/tailwindcss).
+ - More generic frontend stacks can use the [`tailwindcss` Node module](https://tailwindcss.com/docs/installation).
+
+### Goals
+
+This blueprint's goal is to improve the developer experience (DX) when working with CSS utility classes.
+As a result of this initiative, frontend engineers' efficiency should be increased thanks to a much
+lower development overhead.
+
+### Non-Goals
+
+As stated in the motivations above, this focuses on improving an existing architectural decision,
+not on replacing it with a new design. So this therefore:
+
+- _Is not_ aimed at revisiting the way we write CSS or how we apply styles within our projects.
+- _Does not_ focus on user-facing improvements. This change is mostly a developer experience enhancement.
+ The resulting increase in efficiency could certainly indirectly improve user experience, but that
+ is not our primary intent.
+
+## Proposal
+
+We will be setting up Tailwind CSS in GitLab UI _and_ GitLab. The intent is to have the main
+Tailwind CSS configuration in GitLab UI. This step is where we'll be maintaining the Pajamas-compliant
+configuration properties (color, spacing scale, etc.). The Tailwind CSS setup in GitLab will inherit from
+GitLab UI's setup. The subtlety here is that, in GitLab, we will be scanning both the GitLab codebase
+and the `@gitlab/ui` Node module. This will ensure that GitLab UI does not need to expose any CSS
+utilities anymore, but the ones it relies on are still generated in GitLab. A similar setup will
+need to be introduced in other projects that use CSS utilities and need to upgrade to the Tailwind
+CSS-based version.
+
+### Pros
+
+- We are removing the cumbersome workflow for adding new utilities. One should be able to use any
+ utility right away without contributing to another project and waiting through the release cycle.
+- We are introducing a predictable library, where the naming is decided upon in the overarching
+ Tailwind CSS project. As engineers know, naming things is difficult, and it's best that we defer
+ this to a well-established project.
+- Engineers should be able to refer to Tailwind CSS documentation to know what utils are available
+ and how to use them. No need to read through GitLab UI's source code anymore.
+- Because Tailwind CSS generates the required utils by scanning the consumer's codebase, we'll be
+ sure to only generate the utilities we actually need, keeping CSS bundle sizes under control. This
+ must be taken with a grain of salt though: Tailwind CSS is extremely flexible and makes it possible
+ to generate all sorts of utils, sometimes with developer-defined values, which could result in
+ large utils bundles depending on how we'll adopt Tailwind CSS' features.
+- We'll benefit from a robust IDE integration providing auto-completion and previews for the utils
+ we support.
+
+### Cons
+
+- More setup: each project that requires CSS utils would need to have Tailwind CSS set up,
+ which might be more or less tedious depending on the environment.
+- One more dev dependency in each project.
+- Inability to use string interpolation to build class names dynamically (Tailwind CSS
+ needs to see the full names to generate the required classes).
+- We'll need a migration: we'll need to ensure usages of the existing CSS utilities library
+ don't break, which implies a deprecation/migration process.
+
+## Design and implementation details
+
+In order to prevent breakages, we are taking an iterative approach to moving away from the current
+library. The proposed path here is purposefully rough around the edges. We acknowledge that it's
+not a one size fits all solution and that we might need to adjust to some cases along the way.
+
+Here's the basic process:
+
+1. Deprecate a collection of utility mixins in GitLab UI. This entails replacing the `gl-` prefix
+ with `gl-deprecated-` in the mixin's name, and updating all usages in both GitLab UI _and_ GitLab
+ accordingly. We will typically focus on a single mixins file at a time, though we might want to
+ deprecate several files at once if they are small enough. Conversely, some files might be too big
+ to be deprecated in one go and would require several iterations.
+1. Enable the corresponding [Tailwind CSS core plugins](https://tailwindcss.com/docs/configuration#core-plugins) so that we can immediately start using the
+ newer utilities.
+1. Migrate deprecated utilities to their Tailwind CSS equivalents.
+
+```mermaid
+flowchart TD
+ RequiresDeprecation(Is the mixins collection widely used in GitLab?)
+ DeprecateMixins[Mark the mixins as deprecated with the `gl-deprecated-` prefix]
+
+ HasTailwindEq(Does Tailwind CSS have equivalents?)
+ EnableCorePlugin["Enable the corresponding Tailwind CSS core plugin(s)"]
+ WriteCustomUtil[Write a custom Tailwind CSS utility]
+
+ MigrateUtils[Migrate legacy utils to Tailwind CSS]
+
+ RequiresDeprecation -- Yes --> DeprecateMixins
+ DeprecateMixins --> HasTailwindEq
+ RequiresDeprecation -- No --> HasTailwindEq
+ HasTailwindEq -- Yes --> EnableCorePlugin
+ HasTailwindEq -- No --> WriteCustomUtil
+ EnableCorePlugin --> MigrateUtils
+ WriteCustomUtil --> MigrateUtils
+```
+
+The deprecation step gives us some margin to evaluate each migration without risking breakages in
+production. It does have some drawbacks:
+
+- We might cause merge conflicts for others as we will be touching several areas of the product in
+ our deprecation MRs. We will make sure to communicate these changes efficiently to not make things
+ too confusing. We will also use our best judgement to split MRs when we feel like their scope gets
+ too large.
+- Deprecation MRs might require approval from several departments, which is another reason to
+ be transparent and iterative throughout the process.
+- We are purposefully introducing technical debt which we are committed to pay in a reasonable time frame.
+ We acknowledge that the actual duration of this initiative may be affected by a number of factors (uncovering
+ edge-cases, DRIs' capacity, department-wide involvement, etc.), but we expect to have it completed in 6-12 months.
diff --git a/doc/development/internal_analytics/index.md b/doc/development/internal_analytics/index.md
index 0875ea7afad..29d1a46c3cf 100644
--- a/doc/development/internal_analytics/index.md
+++ b/doc/development/internal_analytics/index.md
@@ -17,8 +17,8 @@ when developing new features or instrumenting existing ones.
<div class="video-fallback">
See the video about <a href="https://www.youtube.com/watch?v=GtFNXbjygWo">the concepts of events and metrics.</a>
</div>
-<figure class="video_container">
- <iframe src="https://www.youtube-nocookie.com/embed/GtFNXbjygWo" frameborder="0" allowfullscreen="true"> </iframe>
+<figure class="video-container">
+ <iframe src="https://www.youtube-nocookie.com/embed/GtFNXbjygWo" frameborder="0" allowfullscreen> </iframe>
</figure>
Events and metrics are the foundation of the internal analytics system.
diff --git a/doc/development/internal_analytics/internal_event_instrumentation/local_setup_and_debugging.md b/doc/development/internal_analytics/internal_event_instrumentation/local_setup_and_debugging.md
index 56e83184060..244482a4c2e 100644
--- a/doc/development/internal_analytics/internal_event_instrumentation/local_setup_and_debugging.md
+++ b/doc/development/internal_analytics/internal_event_instrumentation/local_setup_and_debugging.md
@@ -48,6 +48,15 @@ By default, self-managed instances do not collect event data via Snowplow. We ca
1. You can now see all events being sent by your local instance in the [Snowplow Micro UI](http://localhost:9091/micro/ui) and can filter for specific events.
+### Introduction to Snowplow Micro UI and API
+
+<div class="video-fallback">
+ Watch the video about <a href="https://www.youtube.com/watch?v=netZ0TogNcA">Snowplow Micro</a>
+</div>
+<figure class="video-container">
+ <iframe src="https://www.youtube-nocookie.com/embed/netZ0TogNcA" frameborder="0" allowfullscreen> </iframe>
+</figure>
+
## Configure a remote event collector
On GitLab.com events are sent to a collector configured by GitLab. By default, self-managed instances do not have a collector configured and do not collect data with Snowplow.
@@ -72,8 +81,8 @@ You can configure your self-managed GitLab instance to use a custom Snowplow col
<div class="video-fallback">
Watch the demo video about the <a href="https://www.youtube.com/watch?v=R7vT-VEzZOI">Internal Events Tracking Monitor</a>
</div>
-<figure class="video_container">
- <iframe src="https://www.youtube-nocookie.com/embed/R7vT-VEzZOI" frameborder="0" allowfullscreen="true"> </iframe>
+<figure class="video-container">
+ <iframe src="https://www.youtube-nocookie.com/embed/R7vT-VEzZOI" frameborder="0" allowfullscreen> </iframe>
</figure>
To understand how events are triggered and metrics are updated while you use the Rails app locally or `rails console`,
diff --git a/doc/development/internal_analytics/internal_event_instrumentation/quick_start.md b/doc/development/internal_analytics/internal_event_instrumentation/quick_start.md
index ae33eeb49f4..c70f7debe41 100644
--- a/doc/development/internal_analytics/internal_event_instrumentation/quick_start.md
+++ b/doc/development/internal_analytics/internal_event_instrumentation/quick_start.md
@@ -31,6 +31,13 @@ Triggering an event and thereby updating a metric is slightly different on backe
### Backend tracking
+<div class="video-fallback">
+ Watch the video about <a href="https://www.youtube.com/watch?v=Teid7o_2Mmg">Backend instrumentation using Internal Events</a>
+</div>
+<figure class="video-container">
+ <iframe src="https://www.youtube-nocookie.com/embed/Teid7o_2Mmg" frameborder="0" allowfullscreen> </iframe>
+</figure>
+
To trigger an event, call the `Gitlab::InternalEvents.track_event` method with the desired arguments:
```ruby
diff --git a/doc/user/markdown.md b/doc/user/markdown.md
index 3ec8ba74c75..372442bb53f 100644
--- a/doc/user/markdown.md
+++ b/doc/user/markdown.md
@@ -32,9 +32,6 @@ As this Markdown specification is **valid for GitLab only**, you should
We do our best to render the Markdown faithfully here, however the [GitLab documentation website](https://docs.gitlab.com)
and the [GitLab handbook](https://handbook.gitlab.com) use a different Markdown processor.
-GitLab Flavored Markdown extends the [CommonMark specification](https://spec.commonmark.org/current/).
-It was inspired by [GitHub Flavored Markdown](https://docs.github.com/en/get-started/writing-on-github/getting-started-with-writing-and-formatting-on-github/basic-writing-and-formatting-syntax).
-
## Where you can use GitLab Flavored Markdown
You can use GitLab Flavored Markdown in the following areas:
@@ -53,32 +50,46 @@ to do so. For more information, see the [`gitlab-markup` gem project](https://gi
### Differences between GitLab Flavored Markdown and standard Markdown
-GitLab uses standard CommonMark formatting. However, GitLab Flavored Markdown
-extends standard Markdown with features made specifically for GitLab.
+<!--
+Use this topic to list features that are not present in standard Markdown.
+Don't repeat this information in each individual topic, unless there's a specific
+reason, like in "Newlines".
+-->
+
+GitLab Flavored Markdown consists of the following:
+
+- Core Markdown features, based on the [CommonMark specification](https://spec.commonmark.org/current/).
+- Extensions from [GitHub Flavored Markdown](https://github.github.com/gfm/).
+- Extensions made specifically for GitLab.
+
+All standard Markdown formatting should work as expected in GitLab. Some standard
+functionality is extended with additional features, without affecting the standard usage.
The following features are not found in standard Markdown:
- [Color chips written in `HEX`, `RGB` or `HSL`](#colors)
- [Diagrams and flowcharts](#diagrams-and-flowcharts)
- [Emoji](#emoji)
+- [Footnotes](#footnotes)
- [Front matter](#front-matter)
+- [GitLab-specific references](#gitlab-specific-references)
- [Inline diffs](#inline-diff)
- [Math equations and symbols written in LaTeX](#math)
-- [Task Lists](#task-lists)
+- [Strikethrough](#emphasis)
- [Table of Contents](#table-of-contents)
-- [Wiki specific Markdown](#wiki-specific-markdown)
+- [Tables](#tables)
+- [Task lists](#task-lists)
+- [Wiki-specific Markdown](#wiki-specific-markdown)
-The following features be are extended from standard Markdown:
+The following features are extended from standard Markdown:
| Standard Markdown | Extended Markdown in GitLab |
|---------------------------------------|---------------------------------------------------------------------------------------|
-| [blockquotes](#blockquotes) | [multi-line blockquotes](#multiline-blockquote) |
-| [code blocks](#code-spans-and-blocks) | [colored code and syntax highlighting](#colored-code-and-syntax-highlighting) |
-| [emphasis](#emphasis) | [multiple underscores in words](#multiple-underscores-in-words-and-mid-word-emphasis) |
-| [headings](#headings) | [linkable heading IDs](#heading-ids-and-links) |
-| [images](#images) | [embedded videos](#videos) and [audio](#audio) |
-| [line breaks](#line-breaks) | [more line break control](#newlines) |
-| [links](#links) | [automatically linking URLs](#url-auto-linking) |
+| [Blockquotes](#blockquotes) | [Multiline blockquotes](#multiline-blockquote) |
+| [Code blocks](#code-spans-and-blocks) | [Colored code and syntax highlighting](#colored-code-and-syntax-highlighting) |
+| [Headings](#headings) | [Linkable heading IDs](#heading-ids-and-links) |
+| [Images](#images) | [Embedded videos](#videos) and [audio](#audio) |
+| [Links](#links) | [Automatically linking URLs](#url-auto-linking) |
## Markdown and accessibility
@@ -103,11 +114,7 @@ If there is no otherwise meaningful value for a cell, consider entering **N/A**
Describe the image or video in the `[alt text]`. Make the description accurate, succinct, and unique.
Don't use `image of` or `video of` in the description. For more information, see [WebAim Alternative Text](https://webaim.org/techniques/alttext/).
-## Features not found in standard Markdown
-
-The following features are not found in standard Markdown.
-
-### Colors
+## Colors
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#colors).
@@ -146,7 +153,7 @@ display a color chip next to the color code. For example:
- `HSL(540,70%,50%)`
- `HSLA(540,70%,50%,0.3)`
-### Diagrams and flowcharts
+## Diagrams and flowcharts
You can generate diagrams from text by using:
@@ -156,7 +163,7 @@ You can generate diagrams from text by using:
In wikis, you can also add and edit diagrams created with the [diagrams.net editor](#diagramsnet-editor).
-#### Mermaid
+### Mermaid
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#mermaid).
@@ -223,17 +230,17 @@ graph TB
end
```
-#### PlantUML
+### PlantUML
PlantUML integration is enabled on GitLab.com. To make PlantUML available in self-managed
installation of GitLab, a GitLab administrator [must enable it](../administration/integration/plantuml.md).
-#### Kroki
+### Kroki
To make Kroki available in GitLab, a GitLab administrator must enable it.
For more information, see the [Kroki integration](../administration/integration/kroki.md) page.
-### Emoji
+## Emoji
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#emoji).
@@ -266,7 +273,7 @@ Consult the [Emoji Cheat Sheet](https://www.webfx.com/tools/emoji-cheat-sheet/)
for a list of all supported emoji codes. :thumbsup:
```
-#### Emoji and your operating system
+### Emoji and your operating system
The previous emoji example uses hard-coded images. Rendered emoji
in GitLab might look different depending on the OS and browser used.
@@ -284,7 +291,7 @@ this font installed by default.
To learn more about adding custom emoji, see [Custom emoji](emoji_reactions.md#custom-emoji).
-### Front matter
+## Front matter
Front matter is metadata included at the beginning of a Markdown document, preceding
the content. This data can be used by static site generators like [Jekyll](https://jekyllrb.com/docs/front-matter/),
@@ -346,7 +353,7 @@ $example = array(
---
```
-### Inline diff
+## Inline diff
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#inline-diff).
@@ -385,7 +392,7 @@ each backtick with a backslash <code>&#92;</code>:
![Inline diff with mixed formatting, as rendered by the GitLab interface](img/inline_diff_02_v13_3.png)
-### Math
+## Math
> - LaTeX-compatible fencing [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/21757) in GitLab 15.4 [with a flag](../administration/feature_flags.md) named `markdown_dollar_math`. Disabled by default. Enabled on GitLab.com.
> - LaTeX-compatible fencing [generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/371180) in GitLab 15.8. Feature flag `markdown_dollar_math` removed.
@@ -442,7 +449,7 @@ $$
a^2+b^2=c^2
$$
-### Task lists
+## Task lists
> Inapplicable checkboxes [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/85982) in GitLab 15.3.
@@ -479,7 +486,7 @@ To create a task list, follow the format of an ordered or unordered list:
To include task lists in tables, [use HTML list tags or HTML tables](#task-lists-in-tables).
-### Table of contents
+## Table of contents
A table of contents is an unordered list that links to subheadings in the document.
You can add a table of contents to issues, merge requests, and epics, but you can't add one
@@ -528,13 +535,13 @@ Second section content.
![Preview of an auto-generated table of contents in a Wiki](img/markdown_toc_preview_v12_9.png)
-### Wiki-specific Markdown
+## Wiki-specific Markdown
The following topics show how links inside wikis behave.
When linking to wiki pages, you should use the **page slug** rather than the page name.
-#### Wiki - direct page link
+### Wiki - direct page link
A direct page link includes the slug for a page that points to that page,
at the base level of the wiki.
@@ -545,7 +552,7 @@ This example links to a `documentation` page at the root of your wiki:
[Link to Documentation](documentation)
```
-#### Wiki - direct file link
+### Wiki - direct file link
A direct file link points to a file extension for a file, relative to the current page.
@@ -556,7 +563,7 @@ it links to `<your_wiki>/documentation/file.md`:
[Link to File](file.md)
```
-#### Wiki - hierarchical link
+### Wiki - hierarchical link
A hierarchical link can be constructed relative to the current wiki page by using `./<page>`,
`../<page>`, and so on.
@@ -589,7 +596,7 @@ it links to `<your_wiki>/documentation/main.md`:
[Link to Related Page](../main.md)
```
-#### Wiki - root link
+### Wiki - root link
A root link starts with a `/` and is relative to the wiki root.
@@ -605,7 +612,7 @@ This example links to `<wiki_root>/miscellaneous.md`:
[Link to Related Page](/miscellaneous.md)
```
-#### diagrams.net editor
+### diagrams.net editor
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/322174) in GitLab 15.10.
@@ -615,7 +622,7 @@ the plain text editor and the rich text editor.
For more information, see [Diagrams.net](../administration/integration/diagrams_net.md).
-##### Plain text editor
+#### Plain text editor
To create a diagram in the plain text editor:
@@ -641,7 +648,7 @@ To edit a diagram in the plain text editor:
A Markdown image reference to the diagram is inserted in the wiki content,
replacing the previous diagram.
-##### Rich text editor
+#### Rich text editor
To create a diagram in the rich text editor:
@@ -723,9 +730,11 @@ For example:
> - Support for issues, merge requests, and epics [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/15694) in GitLab 14.6.
> - Support for work items [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/390854) in GitLab 16.0.
-To include the title in the rendered link of an issue, work item, merge request, or epic, add a plus (`+`)
-at the end of the reference. For example, a reference like `#123+` is rendered as
-`The issue title (#123)`.
+To include the title in the rendered link of an issue, work item, merge request, or epic:
+
+- Add a plus (`+`) at the end of the reference.
+
+For example, a reference like `#123+` is rendered as `The issue title (#123)`.
URL references like `https://gitlab.com/gitlab-org/gitlab/-/issues/1234+` are also expanded.
@@ -761,13 +770,7 @@ To embed an Observability dashboard URL:
1. In GitLab Observability UI, copy the URL in the address bar.
1. Paste your link in a comment or description. GitLab Flavored Markdown recognizes the URL and displays the source.
-## Features extended from standard Markdown
-
-All standard Markdown formatting should work as expected in GitLab. Some standard
-functionality is extended with additional features, without affecting the standard usage.
-If a functionality is extended, the new option is listed as a sub-section.
-
-### Blockquotes
+## Blockquotes
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#blockquotes).
@@ -790,12 +793,11 @@ Quote break.
> This very long line is still quoted properly when it wraps. Keep writing to make sure this line is long enough to actually wrap for everyone. You can also *use* **Markdown** in a blockquote.
-#### Multiline blockquote
+### Multiline blockquote
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#multiline-blockquote).
-GitLab Flavored Markdown extends the standard Markdown by also supporting multi-line blockquotes
-fenced by `>>>`, with a blank line before and after the block:
+Create multi-line blockquotes fenced by `>>>`, with a blank line before and after the block:
```markdown
@@ -821,13 +823,13 @@ trigger this problem.
>
> you can quote that without having to manually prepend `>` to every line!
-### Code spans and blocks
+## Code spans and blocks
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#code-spans-and-blocks).
-You can highlight anything that should be viewed as code and not standard text.
+Highlight anything that should be viewed as code and not standard text.
-Inline code is highlighted with single backticks `` ` ``:
+Inline code is formatted with single backticks `` ` ``:
```markdown
Inline `code` has `back-ticks around` it.
@@ -884,7 +886,7 @@ is like using
Tildes are OK too.
```
-#### Colored code and syntax highlighting
+### Colored code and syntax highlighting
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#colored-code-and-syntax-highlighting).
@@ -948,13 +950,12 @@ s = "No highlighting is shown for this line."
But let's throw in a <b>tag</b>.
```
-### Emphasis
+## Emphasis
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#emphasis).
-In Markdown, you can emphasize text in multiple ways. You can italicize, bold, strikethrough,
-and combine these emphasis styles together.
-Strikethrough is not part of the core Markdown standard, but is part of GitLab Flavored Markdown.
+You can emphasize text in multiple ways. Use italics, bold, strikethrough,
+or combine these emphasis styles together.
Examples:
@@ -980,13 +981,14 @@ Strikethrough with double tildes. ~~Scratch this.~~
<!-- markdownlint-enable MD050 -->
-#### Multiple underscores in words and mid-word emphasis
+### Multiple underscores in words and mid-word emphasis
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#multiple-underscores-in-words).
Avoid italicizing a portion of a word, especially when you're
dealing with code and names that often appear with multiple underscores.
-GitLab Flavored Markdown extends the standard Markdown standard by ignoring multiple underlines in words,
+
+GitLab Flavored Markdown ignores multiple underlines in words,
to allow better rendering of Markdown documents discussing code:
```markdown
@@ -1021,7 +1023,7 @@ perform*complicated*task
do*this*and*do*that*and*another thing
-### Footnotes
+## Footnotes
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#footnotes).
@@ -1060,7 +1062,9 @@ These are used to force the Vale ReferenceLinks check to skip these examples.
[^footnote-42]: This text is another footnote.
-### Headings
+## Headings
+
+Create headings from 1 to 6 by using `#`.
```markdown
# H1
@@ -1071,7 +1075,7 @@ These are used to force the Vale ReferenceLinks check to skip these examples.
###### H6
```
-Alternatively, for H1 and H2, an underline style:
+Alternatively, for H1 and H2, use an underline style:
```markdown
Alt-H1
@@ -1081,12 +1085,12 @@ Alt-H2
------
```
-#### Heading IDs and links
+### Heading IDs and links
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#heading-ids-and-links).
-GitLab Flavored Markdown extends the standard Markdown standard so that all Markdown-rendered headings automatically
-get IDs, which can be linked to, except in comments.
+All Markdown-rendered headings automatically
+get IDs that can be linked to, except in comments.
On hover, a link to those IDs becomes visible to make it easier to copy the link to
the heading to use it somewhere else.
@@ -1123,7 +1127,7 @@ Would generate the following link IDs:
Emoji processing happens before the heading IDs are generated. The
emoji is converted to an image, which is then removed from the ID.
-### Horizontal Rule
+## Horizontal rule
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#horizontal-rule).
@@ -1143,7 +1147,7 @@ ___
---
-### Images
+## Images
Embed images using inline or reference links.
To see title text, hover over the image.
@@ -1189,7 +1193,7 @@ Reference-style:
<!-- markdownlint-enable proper-names -->
-#### Change the image or video dimensions
+### Change the image or video dimensions
> - Support for images [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/28118) in GitLab 15.7.
> - Support for videos [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/17139) in GitLab 15.9.
@@ -1213,7 +1217,7 @@ For example
You can also use the `img` HTML tag instead of Markdown and set its `height` and
`width` parameters.
-#### Videos
+### Videos
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#videos).
@@ -1228,7 +1232,7 @@ Here's an example video:
![Sample Video](img/markdown_video.mp4)
-#### Audio
+### Audio
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#audio).
@@ -1243,7 +1247,7 @@ Here's an example audio clip:
![Sample Audio](img/markdown_audio.mp3)
-### Inline HTML
+## Inline HTML
> Allowing `rel="license"` [introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/20857) in GitLab 14.6.
@@ -1310,7 +1314,7 @@ Markdown is fine in GitLab.
</dd>
</dl>
-#### Collapsible section
+### Collapsible section
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#details-and-summary).
@@ -1375,7 +1379,7 @@ These details <em>remain</em> <b>hidden</b> until expanded.
</details>
-### Line breaks
+## Line breaks
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#line-breaks).
@@ -1405,7 +1409,7 @@ These lines are only separated by single newlines,
so they *do not break* and just follow the previous lines
in the *same paragraph*.
-#### Newlines
+### Newlines
GitLab Flavored Markdown adheres to the Markdown specification for handling
[paragraphs and line breaks](https://spec.commonmark.org/current/).
@@ -1428,7 +1432,7 @@ Another line, this time ending with a backslash.\
A new line due to the previous backslash.
```
-### Links
+## Links
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#links).
@@ -1491,11 +1495,11 @@ page, or a wiki page in a project file. The reason: a wiki is always
in a separate Git repository in GitLab. For example, `[I'm a reference-style link](style)`
points the link to `wikis/style` only when the link is inside of a wiki Markdown file.
-#### URL auto-linking
+### URL auto-linking
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#url-auto-linking).
-GitLab Flavored Markdown auto-links almost any URL you put into your text:
+Almost any URL you put into your text is auto-linked:
```markdown
- https://www.google.com
@@ -1517,7 +1521,7 @@ GitLab Flavored Markdown auto-links almost any URL you put into your text:
<!-- vale gitlab.Spelling = YES -->
-### Lists
+## Lists
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#lists).
@@ -1674,12 +1678,11 @@ For example:
CommonMark ignores the blank line and renders this as one list with paragraph spacing.
-### Superscripts / Subscripts
+## Superscripts / Subscripts
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#superscripts-subscripts).
-CommonMark and GitLab Flavored Markdown don't support the Redcarpet superscript syntax ( `x^2` ).
-Use the standard HTML syntax for superscripts and subscripts:
+For superscripts and subscripts, use the standard HTML syntax:
```html
The formula for water is H<sub>2</sub>O
@@ -1693,7 +1696,9 @@ while the equation for the theory of relativity is E = mc<sup>2</sup>.
<!-- vale gitlab.Spelling = YES -->
-### Keyboard HTML tag
+GitLab Flavored Markdown doesn't support the Redcarpet superscript syntax ( `x^2` ).
+
+## Keyboard HTML tag
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#keyboard-html-tag).
@@ -1705,11 +1710,11 @@ Press <kbd>Enter</kbd> to go to the next page.
Press <kbd>Enter</kbd> to go to the next page.
-### Tables
+## Tables
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#tables-1).
-Tables are not part of the core Markdown specification, but are part of GitLab Flavored Markdown.
+When creating tables:
- The first line contains the headers, separated by "pipes" (`|`).
- The second line separates the headers from the cells.
@@ -1743,7 +1748,7 @@ Example:
| cell 4 | cell 5 is longer | cell 6 is much longer than the others, but that's ok. It eventually wraps the text when the cell is too large for the display size. |
| cell 7 | | cell 9 |
-#### Alignment
+### Alignment
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#alignment).
@@ -1765,7 +1770,7 @@ to the sides of the "dash" lines in the second row. This affects every cell in t
[In GitLab itself](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#tables),
the headers are always left-aligned in Chrome and Firefox, and centered in Safari.
-#### Cells with multiple lines
+### Cells with multiple lines
[View this topic in GitLab](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/user/markdown.md#cells-with-multiple-lines).
@@ -1784,7 +1789,7 @@ use `<br>` tags to force a cell to have multiple lines:
| Item1 | This text is on one line |
| Item2 | This item has:<br>- Multiple items<br>- That we want listed separately |
-#### Task lists in tables
+### Task lists in tables
To add [task lists](#task-lists) with checkboxes, use HTML formatting. Using either:
@@ -1826,7 +1831,7 @@ To add [task lists](#task-lists) with checkboxes, use HTML formatting. Using eit
You can also [create a table in the rich text editor](rich_text_editor.md#tables) and insert a task list then.
-#### Copy and paste from a spreadsheet
+### Copy and paste from a spreadsheet
If you're working in spreadsheet software (for example, Microsoft Excel, Google
Sheets, or Apple Numbers), GitLab creates a Markdown table when you copy and paste
@@ -1840,7 +1845,7 @@ entry and paste the spreadsheet:
![Paste to Markdown table](img/markdown_paste_table_v12_7.png)
-#### JSON
+### JSON
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/86353) in GitLab 15.3.
diff --git a/doc/user/packages/package_registry/dependency_proxy/index.md b/doc/user/packages/package_registry/dependency_proxy/index.md
index 7b5e7a4c624..88e424ed3ac 100644
--- a/doc/user/packages/package_registry/dependency_proxy/index.md
+++ b/doc/user/packages/package_registry/dependency_proxy/index.md
@@ -7,12 +7,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
# Dependency proxy for packages **(PREMIUM ALL BETA)**
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/3610) in GitLab 16.6 [with a flag](../../../../administration/feature_flags.md) named `packages_dependency_proxy_maven`. Disabled by default.
-> - This feature is in [Beta](../../../../policy/experiment-beta-support.md).
-
-FLAG:
-On self-managed GitLab, by default this feature is not available. To make it available, an administrator can [enable the feature flag](../../../../administration/feature_flags.md) named `packages_dependency_proxy_maven`.
-On GitLab.com, this feature is not available.
-The feature is not ready for production use.
+> - [Generally available](https://gitlab.com/gitlab-org/gitlab/-/issues/415218) in GitLab 16.8. Feature flag `packages_dependency_proxy_maven` removed.
The GitLab dependency proxy for packages is a local proxy for frequently pulled packages.
It is implemented as a pull-through cache that works at the project level.
diff --git a/lib/api/entities/diff.rb b/lib/api/entities/diff.rb
index cc53736a5b1..e1e6ce26263 100644
--- a/lib/api/entities/diff.rb
+++ b/lib/api/entities/diff.rb
@@ -16,6 +16,7 @@ module API
expose :new_file?, as: :new_file, documentation: { type: 'boolean' }
expose :renamed_file?, as: :renamed_file, documentation: { type: 'boolean' }
expose :deleted_file?, as: :deleted_file, documentation: { type: 'boolean' }
+ expose :generated?, as: :generated_file, documentation: { type: 'boolean' }
end
end
end
diff --git a/lib/api/group_variables.rb b/lib/api/group_variables.rb
index f320fa06394..94702c36c85 100644
--- a/lib/api/group_variables.rb
+++ b/lib/api/group_variables.rb
@@ -106,11 +106,31 @@ module API
declared_params(include_missing: false)
)
- variable = ::Ci::ChangeVariableService.new(
- container: user_group,
- current_user: current_user,
- params: { action: :update, variable_params: filtered_params }
- ).execute
+ # If the 'filter' parameter is provided, the user is updating a scoped variable
+ # and we need to use `find_variable` to make sure we update the correct one.
+ # However, this would result in an error response in case the user attempts to
+ # update a scoped variable without providing a filter. This error response is
+ # technically correct, because updating a scoped variable without specifying
+ # the targeted scope causes non-deterministic behavior. But this endpoint was
+ # originally introduced without the ability to specify a filter, and returning
+ # an error in these cases now would be considered a breaking change.
+ # Thus we only use the new/correct code if the user provided a filter.
+ # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136475
+ if params.key?('filter')
+ variable = find_variable(user_group, params)
+
+ variable = ::Ci::ChangeVariableService.new(
+ container: user_group,
+ current_user: current_user,
+ params: { action: :update, variable: variable, variable_params: filtered_params }
+ ).execute
+ else
+ variable = ::Ci::ChangeVariableService.new(
+ container: user_group,
+ current_user: current_user,
+ params: { action: :update, variable_params: filtered_params }
+ ).execute
+ end
if variable.valid?
present variable, with: Entities::Ci::Variable
diff --git a/lib/gitlab/ci/config/external/file/remote.rb b/lib/gitlab/ci/config/external/file/remote.rb
index 9219747eef0..266901811f6 100644
--- a/lib/gitlab/ci/config/external/file/remote.rb
+++ b/lib/gitlab/ci/config/external/file/remote.rb
@@ -54,7 +54,7 @@ module Gitlab
private
def fetch_async_content
- return if ::Feature.disabled?(:ci_parallel_remote_includes, context.project)
+ return unless YamlProcessor::FeatureFlags.enabled?(:ci_parallel_remote_includes)
# It starts fetching the remote content in a separate thread and returns a lazy_response immediately.
Gitlab::HTTP.get(location, async: true).tap do |lazy_response|
diff --git a/lib/gitlab/diff/file_collection/paginated_merge_request_diff.rb b/lib/gitlab/diff/file_collection/paginated_merge_request_diff.rb
index 37abad81305..77461db7d7d 100644
--- a/lib/gitlab/diff/file_collection/paginated_merge_request_diff.rb
+++ b/lib/gitlab/diff/file_collection/paginated_merge_request_diff.rb
@@ -15,8 +15,8 @@ module Gitlab
delegate :limit_value, :current_page, :next_page, :prev_page, :total_count,
:total_pages, to: :paginated_collection
- def initialize(merge_request_diff, page, per_page)
- super(merge_request_diff, diff_options: nil)
+ def initialize(merge_request_diff, page, per_page, diff_options)
+ super(merge_request_diff, diff_options: diff_options)
@paginated_collection = load_paginated_collection(page, per_page)
end
diff --git a/lib/gitlab/event_store/event.rb b/lib/gitlab/event_store/event.rb
index b969670aeaf..aecb4fd17c3 100644
--- a/lib/gitlab/event_store/event.rb
+++ b/lib/gitlab/event_store/event.rb
@@ -47,7 +47,7 @@ module Gitlab
def validate_schema!
if self.class.json_schema_valid.nil?
- self.class.json_schema_valid = JSONSchemer.schema(self.class.json_schema).valid?(schema)
+ self.class.json_schema_valid = JSONSchemer.schema(Event.json_schema).valid?(schema)
end
return if self.class.json_schema_valid == true
diff --git a/lib/gitlab/tracking/event_definition.rb b/lib/gitlab/tracking/event_definition.rb
index 9d197de454e..ce8263e824b 100644
--- a/lib/gitlab/tracking/event_definition.rb
+++ b/lib/gitlab/tracking/event_definition.rb
@@ -27,7 +27,7 @@ module Gitlab
definition = YAML.safe_load(definition)
definition.deep_symbolize_keys!
- self.new(path, definition).tap(&:validate!)
+ self.new(path, definition)
rescue StandardError => e
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(Gitlab::Tracking::InvalidEventError.new(e.message))
end
@@ -51,17 +51,15 @@ module Gitlab
path.delete_prefix(Rails.root.to_s)
end
- def validate!
- SCHEMA.validate(attributes.stringify_keys).each do |error|
- error_message = <<~ERROR_MSG
+ def validation_errors
+ SCHEMA.validate(attributes.stringify_keys).map do |error|
+ <<~ERROR_MSG
+ --------------- VALIDATION ERROR ---------------
+ Definition file: #{path}
Error type: #{error['type']}
Data: #{error['data']}
Path: #{error['data_pointer']}
- Details: #{error['details']}
- Definition file: #{path}
ERROR_MSG
-
- Gitlab::ErrorTracking.track_and_raise_for_dev_exception(Gitlab::Tracking::InvalidEventError.new(error_message))
end
end
diff --git a/lib/gitlab/usage/metric_definition.rb b/lib/gitlab/usage/metric_definition.rb
index 5eddf8da7dd..71d3680e67e 100644
--- a/lib/gitlab/usage/metric_definition.rb
+++ b/lib/gitlab/usage/metric_definition.rb
@@ -59,17 +59,15 @@ module Gitlab
attributes[:value_type] == 'object' && attributes[:value_json_schema].present?
end
- def validate!
- errors.each do |error|
- error_message = <<~ERROR_MSG
+ def validation_errors
+ errors.map do |error|
+ <<~ERROR_MSG
+ --------------- VALIDATION ERROR ---------------
+ Metric file: #{path}
Error type: #{error['type']}
Data: #{error['data']}
Path: #{error['data_pointer']}
- Details: #{error['details']}
- Metric file: #{path}
ERROR_MSG
-
- Gitlab::ErrorTracking.track_and_raise_for_dev_exception(InvalidError.new(error_message))
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index b41845620a1..8b4d0514e18 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -760,9 +760,6 @@ msgstr ""
msgid "%{group_name} is approaching the limit of available seats"
msgstr ""
-msgid "%{group_name} uses group managed accounts. You need to create a new GitLab account which will be managed by %{group_name}."
-msgstr ""
-
msgid "%{group_name}&%{epic_iid} &middot; created %{epic_created} by %{author}"
msgstr ""
@@ -5047,9 +5044,6 @@ msgstr ""
msgid "Alternate support URL for Help page and Help dropdown."
msgstr ""
-msgid "Alternatively, you can convert your account to a managed account by the %{group_name} group."
-msgstr ""
-
msgid "Amazon EKS"
msgstr ""
@@ -20159,9 +20153,6 @@ msgstr ""
msgid "Existing projects will be able to use cleanup policies. Avoid enabling this if an external Container Registry is being used, as there is a performance risk if many images exist on one project."
msgstr ""
-msgid "Existing sign in methods may be removed"
-msgstr ""
-
msgid "Expand"
msgstr ""
@@ -21164,9 +21155,6 @@ msgstr ""
msgid "Finish review"
msgstr ""
-msgid "Finish setting up your dedicated account for %{group_name}."
-msgstr ""
-
msgid "Finished"
msgstr ""
@@ -21556,9 +21544,6 @@ msgstr ""
msgid "Full log"
msgstr ""
-msgid "Full name"
-msgstr ""
-
msgid "GCP region configured"
msgstr ""
@@ -23435,9 +23420,6 @@ msgstr ""
msgid "GroupSAML|Enforce SSO-only authentication for web activity for this group"
msgstr ""
-msgid "GroupSAML|Enforce users to have dedicated group-managed accounts for this group"
-msgstr ""
-
msgid "GroupSAML|Generate a SCIM token"
msgstr ""
@@ -23474,9 +23456,6 @@ msgstr ""
msgid "GroupSAML|No active SAML group links"
msgstr ""
-msgid "GroupSAML|Prohibit outer forks for this group"
-msgstr ""
-
msgid "GroupSAML|Reset SCIM token"
msgstr ""
@@ -23531,21 +23510,12 @@ msgstr ""
msgid "GroupSAML|This will be set as the access level of users added to the group."
msgstr ""
-msgid "GroupSAML|To be able to enable group-managed accounts, you first need to enable enforced SSO."
-msgstr ""
-
-msgid "GroupSAML|To be able to prohibit outer forks, you first need to enforce dedicate group managed accounts."
-msgstr ""
-
msgid "GroupSAML|Use SAML group links to manage group membership using SAML."
msgstr ""
msgid "GroupSAML|Valid SAML Response"
msgstr ""
-msgid "GroupSAML|With prohibit outer forks flag enabled group members will be able to fork project only inside your group."
-msgstr ""
-
msgid "GroupSAML|as %{access_level}"
msgstr ""
@@ -24537,9 +24507,6 @@ msgstr ""
msgid "How to track time"
msgstr ""
-msgid "I accept the %{terms_link}"
-msgstr ""
-
msgid "I am sorry, I am unable to find what you are looking for."
msgstr ""
@@ -33946,9 +33913,6 @@ msgstr ""
msgid "Only policy:"
msgstr ""
-msgid "Only proceed if you trust %{idp_url} to control your GitLab account sign in."
-msgstr ""
-
msgid "Only project members can comment."
msgstr ""
@@ -42723,9 +42687,6 @@ msgstr ""
msgid "SAML SSO"
msgstr ""
-msgid "SAML SSO for %{group_name}"
-msgstr ""
-
msgid "SAML discovery tokens"
msgstr ""
@@ -46210,18 +46171,12 @@ msgstr ""
msgid "Sign out"
msgstr ""
-msgid "Sign out & Register"
-msgstr ""
-
msgid "Sign up"
msgstr ""
msgid "Sign up for your free trial with:"
msgstr ""
-msgid "Sign up was successful! Please confirm your email to sign in."
-msgstr ""
-
msgid "Sign-in and Help page"
msgstr ""
@@ -51799,9 +51754,6 @@ msgstr ""
msgid "Transfer group to another parent group."
msgstr ""
-msgid "Transfer ownership"
-msgstr ""
-
msgid "Transfer project"
msgstr ""
@@ -56153,9 +56105,6 @@ msgstr ""
msgid "You are about to incur additional charges"
msgstr ""
-msgid "You are about to transfer the control of your account to %{group_name} group. This action is NOT reversible, you won't be able to access any of your groups and projects outside of %{group_name} once this transfer is complete."
-msgstr ""
-
msgid "You are already a member of this %{member_source}."
msgstr ""
@@ -56785,9 +56734,6 @@ msgstr ""
msgid "You tried to fork %{link_to_the_project} but it failed for the following reason:"
msgstr ""
-msgid "You will be removed from existing projects/groups"
-msgstr ""
-
msgid "You will be the author of all events in the activity feed that are the result of an update, like new branches being created or new commits being pushed to existing branches."
msgstr ""
@@ -56821,9 +56767,6 @@ msgstr ""
msgid "You'll be charged for %{true_up_start}users over license%{true_up_end} on a quarterly or annual basis, depending on the terms of your agreement."
msgstr ""
-msgid "You'll be signed out from your current account automatically."
-msgstr ""
-
msgid "You'll need to use different branch names to get a valid comparison."
msgstr ""
@@ -56973,6 +56916,9 @@ msgstr ""
msgid "Your GPG keys"
msgstr ""
+msgid "Your GitHub access token does not have the correct scope to import collaborators."
+msgstr ""
+
msgid "Your GitLab account has been locked due to an excessive number of unsuccessful sign in attempts. You can wait for your account to automatically unlock in %{duration} or you can click the link below to unlock now."
msgstr ""
diff --git a/spec/lib/api/entities/diff_spec.rb b/spec/lib/api/entities/diff_spec.rb
index 27d9ed44c98..535567d4d8d 100644
--- a/spec/lib/api/entities/diff_spec.rb
+++ b/spec/lib/api/entities/diff_spec.rb
@@ -23,7 +23,8 @@ RSpec.describe ::API::Entities::Diff, feature_category: :source_code_management
b_mode: diff.b_mode,
new_file: diff.new_file?,
renamed_file: diff.renamed_file?,
- deleted_file: diff.deleted_file?
+ deleted_file: diff.deleted_file?,
+ generated_file: diff.generated?
}
)
end
diff --git a/spec/lib/gitlab/ci/yaml_processor/test_cases/include_spec.rb b/spec/lib/gitlab/ci/yaml_processor/test_cases/include_spec.rb
new file mode 100644
index 00000000000..d8f8a58edf3
--- /dev/null
+++ b/spec/lib/gitlab/ci/yaml_processor/test_cases/include_spec.rb
@@ -0,0 +1,80 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+module Gitlab
+ module Ci
+ RSpec.describe YamlProcessor, feature_category: :pipeline_composition do
+ include StubRequests
+
+ subject(:processor) do
+ described_class.new(config, project: project, user: project.first_owner, logger: logger)
+ end
+
+ let_it_be(:project) { create(:project, :repository) }
+
+ let(:logger) { Gitlab::Ci::Pipeline::Logger.new(project: project) }
+ let(:result) { processor.execute }
+ let(:builds) { result.builds }
+
+ context 'with include:remote' do
+ let(:config) do
+ <<~YAML
+ include:
+ - remote: http://my.domain.com/config1.yml
+ - remote: http://my.domain.com/config2.yml
+ YAML
+ end
+
+ before do
+ stub_full_request('http://my.domain.com/config1.yml')
+ .to_return(body: 'build1: { script: echo Hello World }')
+
+ stub_full_request('http://my.domain.com/config2.yml')
+ .to_return(body: 'build2: { script: echo Hello World }')
+ end
+
+ it 'returns builds from included files' do
+ expect(builds.pluck(:name)).to eq %w[build1 build2]
+ end
+
+ it 'stores instrumentation logs' do
+ result
+
+ expect(logger.observations_hash['config_mapper_process_duration_s']['count']).to eq(1)
+ end
+
+ # Remove with the FF ci_parallel_remote_includes
+ it 'does not store log with config_file_fetch_remote_content' do
+ result
+
+ expect(logger.observations_hash).not_to have_key('config_file_fetch_remote_content_duration_s')
+ end
+
+ context 'when the FF ci_parallel_remote_includes is disabled' do
+ before do
+ stub_feature_flags(ci_parallel_remote_includes: false)
+ end
+
+ it 'stores log with config_file_fetch_remote_content' do
+ result
+
+ expect(logger.observations_hash['config_file_fetch_remote_content_duration_s']['count']).to eq(2)
+ end
+
+ context 'when the FF is specifically enabled for the project' do
+ before do
+ stub_feature_flags(ci_parallel_remote_includes: [project])
+ end
+
+ it 'does not store log with config_file_fetch_remote_content' do
+ result
+
+ expect(logger.observations_hash).not_to have_key('config_file_fetch_remote_content_duration_s')
+ end
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/yaml_processor/test_cases/interruptible_spec.rb b/spec/lib/gitlab/ci/yaml_processor/test_cases/interruptible_spec.rb
index 03ff7077969..297872f4cf3 100644
--- a/spec/lib/gitlab/ci/yaml_processor/test_cases/interruptible_spec.rb
+++ b/spec/lib/gitlab/ci/yaml_processor/test_cases/interruptible_spec.rb
@@ -5,9 +5,10 @@ require 'spec_helper'
module Gitlab
module Ci
RSpec.describe YamlProcessor, feature_category: :pipeline_composition do
- subject(:processor) { described_class.new(config, user: nil).execute }
+ subject(:processor) { described_class.new(config, user: nil) }
- let(:builds) { processor.builds }
+ let(:result) { processor.execute }
+ let(:builds) { result.builds }
context 'with interruptible' do
let(:default_config) { nil }
diff --git a/spec/lib/gitlab/diff/file_collection/paginated_merge_request_diff_spec.rb b/spec/lib/gitlab/diff/file_collection/paginated_merge_request_diff_spec.rb
index 891336658ce..6c9a5341695 100644
--- a/spec/lib/gitlab/diff/file_collection/paginated_merge_request_diff_spec.rb
+++ b/spec/lib/gitlab/diff/file_collection/paginated_merge_request_diff_spec.rb
@@ -9,9 +9,10 @@ RSpec.describe Gitlab::Diff::FileCollection::PaginatedMergeRequestDiff, feature_
let(:diffable) { merge_request.merge_request_diff }
let(:diff_files_relation) { diffable.merge_request_diff_files }
let(:diff_files) { subject.diff_files }
+ let(:diff_options) { {} }
subject do
- described_class.new(diffable, page, per_page)
+ described_class.new(diffable, page, per_page, diff_options)
end
describe '#diff_files' do
@@ -77,18 +78,32 @@ RSpec.describe Gitlab::Diff::FileCollection::PaginatedMergeRequestDiff, feature_
context 'when last page' do
it 'returns correct diff files' do
last_page = diff_files_relation.count - per_page
- collection = described_class.new(diffable, last_page, per_page)
+ collection = described_class.new(diffable, last_page, per_page, diff_options)
expected_batch_files = diff_files_relation.page(last_page).per(per_page).map(&:new_path)
expect(collection.diff_files.map(&:new_path)).to eq(expected_batch_files)
end
end
+
+ context 'when collapse_generated is given' do
+ let(:diff_options) { { collapse_generated: true } }
+
+ it 'returns generated value' do
+ expect(diff_files.first.generated?).not_to be_nil
+ end
+ end
+
+ context 'when collapse_generated is not given' do
+ it 'returns nil' do
+ expect(diff_files.first.generated?).to be_nil
+ end
+ end
end
it_behaves_like 'unfoldable diff' do
subject do
- described_class.new(merge_request.merge_request_diff, page, per_page)
+ described_class.new(merge_request.merge_request_diff, page, per_page, diff_options)
end
end
@@ -100,7 +115,7 @@ RSpec.describe Gitlab::Diff::FileCollection::PaginatedMergeRequestDiff, feature_
let(:diffable) { merge_request.merge_request_diff }
subject do
- described_class.new(merge_request.merge_request_diff, page, per_page)
+ described_class.new(merge_request.merge_request_diff, page, per_page, diff_options)
end
end
end
diff --git a/spec/lib/gitlab/event_store/event_spec.rb b/spec/lib/gitlab/event_store/event_spec.rb
index edcb0e5dd1a..367b3334020 100644
--- a/spec/lib/gitlab/event_store/event_spec.rb
+++ b/spec/lib/gitlab/event_store/event_spec.rb
@@ -93,6 +93,13 @@ RSpec.describe Gitlab::EventStore::Event, feature_category: :shared do
expect(event_class.json_schema_valid).to eq(false)
end
+
+ it 'does not store JSON schema on subclass' do
+ expect { event }.to raise_error(Gitlab::EventStore::InvalidEvent)
+
+ expect(event_class.instance_variables).not_to include(:@json_schema)
+ expect(described_class.instance_variables).to include(:@json_schema)
+ end
end
end
end
diff --git a/spec/lib/gitlab/tracking/event_definition_spec.rb b/spec/lib/gitlab/tracking/event_definition_spec.rb
index 5e41c691da8..7c5047dc0c6 100644
--- a/spec/lib/gitlab/tracking/event_definition_spec.rb
+++ b/spec/lib/gitlab/tracking/event_definition_spec.rb
@@ -31,10 +31,6 @@ RSpec.describe Gitlab::Tracking::EventDefinition do
File.write(path, content)
end
- it 'has all definitions valid' do
- expect { described_class.definitions }.not_to raise_error
- end
-
it 'has no duplicated actions in InternalEventTracking events', :aggregate_failures do
definitions_by_action = described_class.definitions
.select { |d| d.category == 'InternalEventTracking' }
@@ -85,10 +81,8 @@ RSpec.describe Gitlab::Tracking::EventDefinition do
attributes[attribute] = value
end
- it 'raise exception' do
- expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).at_least(:once).with(instance_of(Gitlab::Tracking::InvalidEventError))
-
- described_class.new(path, attributes).validate!
+ it 'has validation errors' do
+ expect(described_class.new(path, attributes).validation_errors).not_to be_empty
end
end
end
diff --git a/spec/lib/gitlab/tracking/event_definition_validate_all_spec.rb b/spec/lib/gitlab/tracking/event_definition_validate_all_spec.rb
new file mode 100644
index 00000000000..cc2ccc511bb
--- /dev/null
+++ b/spec/lib/gitlab/tracking/event_definition_validate_all_spec.rb
@@ -0,0 +1,12 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Tracking::EventDefinition, feature_category: :product_analytics_data_management do
+ it 'only has valid event definitions', :aggregate_failures do
+ described_class.definitions.each do |definition|
+ validation_errors = definition.validation_errors
+ expect(validation_errors).to be_empty, validation_errors.join
+ end
+ end
+end
diff --git a/spec/lib/gitlab/usage/metric_definition_spec.rb b/spec/lib/gitlab/usage/metric_definition_spec.rb
index fb46d48c1bb..caa114cb00f 100644
--- a/spec/lib/gitlab/usage/metric_definition_spec.rb
+++ b/spec/lib/gitlab/usage/metric_definition_spec.rb
@@ -33,6 +33,14 @@ RSpec.describe Gitlab::Usage::MetricDefinition, feature_category: :service_ping
described_class.instance_variable_set(:@definitions, nil)
end
+ def expect_validation_errors
+ expect(described_class.new(path, attributes).validation_errors).not_to be_empty
+ end
+
+ def expect_no_validation_errors
+ expect(described_class.new(path, attributes).validation_errors).to be_empty
+ end
+
def write_metric(metric, path, content)
path = File.join(metric, path)
dir = File.dirname(path)
@@ -40,12 +48,6 @@ RSpec.describe Gitlab::Usage::MetricDefinition, feature_category: :service_ping
File.write(path, content)
end
- it 'has only valid definitions' do
- described_class.all.each do |definition|
- expect { definition.validate! }.not_to raise_error
- end
- end
-
describe '.instrumentation_class' do
context 'for non internal events' do
let(:attributes) { { key_path: 'metric1', instrumentation_class: 'RedisHLLMetric', data_source: 'redis_hll' } }
@@ -197,10 +199,8 @@ RSpec.describe Gitlab::Usage::MetricDefinition, feature_category: :service_ping
attributes[attribute] = value
end
- it 'raise exception' do
- expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).at_least(:once).with(instance_of(Gitlab::Usage::MetricDefinition::InvalidError))
-
- described_class.new(path, attributes).validate!
+ it 'has validation errors' do
+ expect_validation_errors
end
end
@@ -210,9 +210,7 @@ RSpec.describe Gitlab::Usage::MetricDefinition, feature_category: :service_ping
attributes[:status] = 'broken'
attributes.delete(:repair_issue_url)
- expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).at_least(:once).with(instance_of(Gitlab::Usage::MetricDefinition::InvalidError))
-
- described_class.new(path, attributes).validate!
+ expect_validation_errors
end
end
@@ -221,20 +219,16 @@ RSpec.describe Gitlab::Usage::MetricDefinition, feature_category: :service_ping
attributes[:status] = 'removed'
end
- it 'raise dev exception when removed_by_url is not provided' do
+ it 'has validation errors when removed_by_url is not provided' do
attributes.delete(:removed_by_url)
- expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).at_least(:once).with(instance_of(Gitlab::Usage::MetricDefinition::InvalidError))
-
- described_class.new(path, attributes).validate!
+ expect_validation_errors
end
- it 'raises dev exception when milestone_removed is not provided' do
+ it 'has validation errors when milestone_removed is not provided' do
attributes.delete(:milestone_removed)
- expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).at_least(:once).with(instance_of(Gitlab::Usage::MetricDefinition::InvalidError))
-
- described_class.new(path, attributes).validate!
+ expect_validation_errors
end
end
@@ -251,18 +245,16 @@ RSpec.describe Gitlab::Usage::MetricDefinition, feature_category: :service_ping
end
with_them do
- it 'raises dev exception when invalid' do
+ it 'has validation errors when invalid' do
attributes[:instrumentation_class] = instrumentation_class if instrumentation_class
attributes[:options] = options if options
attributes[:events] = events if events
if is_valid
- expect(Gitlab::ErrorTracking).not_to receive(:track_and_raise_for_dev_exception)
+ expect_no_validation_errors
else
- expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).at_least(:once).with(instance_of(Gitlab::Usage::MetricDefinition::InvalidError))
+ expect_validation_errors
end
-
- described_class.new(path, attributes).validate!
end
end
end
@@ -294,12 +286,10 @@ RSpec.describe Gitlab::Usage::MetricDefinition, feature_category: :service_ping
attributes[:options] = options
if is_valid
- expect(Gitlab::ErrorTracking).not_to receive(:track_and_raise_for_dev_exception)
+ expect_no_validation_errors
else
- expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).at_least(:once).with(instance_of(Gitlab::Usage::MetricDefinition::InvalidError))
+ expect_validation_errors
end
-
- described_class.new(path, attributes).validate!
end
end
end
@@ -340,12 +330,10 @@ RSpec.describe Gitlab::Usage::MetricDefinition, feature_category: :service_ping
attributes[:options] = options
if is_valid
- expect(Gitlab::ErrorTracking).not_to receive(:track_and_raise_for_dev_exception)
+ expect_no_validation_errors
else
- expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).at_least(:once).with(instance_of(Gitlab::Usage::MetricDefinition::InvalidError))
+ expect_validation_errors
end
-
- described_class.new(path, attributes).validate!
end
end
end
diff --git a/spec/lib/gitlab/usage/metric_definition_validate_all_spec.rb b/spec/lib/gitlab/usage/metric_definition_validate_all_spec.rb
new file mode 100644
index 00000000000..d6255b54068
--- /dev/null
+++ b/spec/lib/gitlab/usage/metric_definition_validate_all_spec.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Gitlab::Usage::MetricDefinition, feature_category: :product_analytics_data_management do
+ # rubocop:disable Rails/FindEach -- The all method invoked here is unrelated to the ActiveRecord scope all
+ it 'only has valid metric definitions', :aggregate_failures do
+ described_class.all.each do |definition|
+ validation_errors = definition.validation_errors
+ expect(validation_errors).to be_empty, validation_errors.join
+ end
+ end
+ # rubocop:enable Rails/FindEach
+end
diff --git a/spec/models/merge_request_diff_spec.rb b/spec/models/merge_request_diff_spec.rb
index 910b32cc1f1..e31a4399646 100644
--- a/spec/models/merge_request_diff_spec.rb
+++ b/spec/models/merge_request_diff_spec.rb
@@ -608,11 +608,35 @@ RSpec.describe MergeRequestDiff, feature_category: :code_review_workflow do
end
describe '#paginated_diffs' do
+ shared_examples 'diffs with generated files check' do
+ context 'when collapse_generated_diff_files FF is enabled' do
+ it 'checks generated files' do
+ diffs = diff_with_commits.paginated_diffs(1, 10)
+
+ expect(diffs.diff_files.first.generated?).not_to be_nil
+ end
+ end
+
+ context 'when collapse_generated_diff_files FF is disabled' do
+ before do
+ stub_feature_flags(collapse_generated_diff_files: false)
+ end
+
+ it 'does not check generated files' do
+ diffs = diff_with_commits.paginated_diffs(1, 10)
+
+ expect(diffs.diff_files.first.generated?).to be_nil
+ end
+ end
+ end
+
context 'when no persisted files available' do
before do
diff_with_commits.clean!
end
+ it_behaves_like 'diffs with generated files check'
+
it 'returns a Gitlab::Diff::FileCollection::Compare' do
diffs = diff_with_commits.paginated_diffs(1, 10)
@@ -622,6 +646,8 @@ RSpec.describe MergeRequestDiff, feature_category: :code_review_workflow do
end
context 'when persisted files available' do
+ it_behaves_like 'diffs with generated files check'
+
it 'returns paginated diffs' do
diffs = diff_with_commits.paginated_diffs(1, 10)
diff --git a/spec/requests/api/import_github_spec.rb b/spec/requests/api/import_github_spec.rb
index f555f39ff74..532492c9c2c 100644
--- a/spec/requests/api/import_github_spec.rb
+++ b/spec/requests/api/import_github_spec.rb
@@ -20,11 +20,18 @@ RSpec.describe API::ImportGithub, feature_category: :importers do
}
end
+ let(:headers) do
+ {
+ 'x-oauth-scopes' => 'read:org'
+ }
+ end
+
let(:client) { double('client', user: provider_user, repository: provider_repo) }
before do
Grape::Endpoint.before_each do |endpoint|
allow(endpoint).to receive(:client).and_return(client)
+ allow(client).to receive_message_chain(:octokit, :last_response, :headers).and_return(headers)
end
end
diff --git a/spec/services/import/github_service_spec.rb b/spec/services/import/github_service_spec.rb
index 06ce00260ed..6fe17a31f3e 100644
--- a/spec/services/import/github_service_spec.rb
+++ b/spec/services/import/github_service_spec.rb
@@ -21,12 +21,19 @@ RSpec.describe Import::GithubService, feature_category: :importers do
}
end
+ let(:headers) do
+ {
+ 'x-oauth-scopes' => 'read:org'
+ }
+ end
+
let(:client) { Gitlab::GithubImport::Client.new(token) }
let(:project_double) { instance_double(Project, persisted?: true) }
subject(:github_importer) { described_class.new(client, user, params) }
before do
+ allow(client).to receive_message_chain(:octokit, :last_response, :headers).and_return(headers)
allow(Gitlab::GithubImport::Settings).to receive(:new).with(project_double).and_return(settings)
allow(settings)
.to receive(:write)
@@ -195,6 +202,24 @@ RSpec.describe Import::GithubService, feature_category: :importers do
end
end
+ context 'validates scopes when collaborator import is true' do
+ let(:optional_stages) do
+ {
+ collaborators_import: true
+ }
+ end
+
+ let(:headers) do
+ {
+ 'x-oauth-scopes' => 'read:user'
+ }
+ end
+
+ it 'returns error when scope is not adequate' do
+ expect(subject.execute(access_params, :github)).to include(scope_error)
+ end
+ end
+
context 'when timeout strategy param is present' do
let(:timeout_strategy) { 'pessimistic' }
@@ -330,6 +355,14 @@ RSpec.describe Import::GithubService, feature_category: :importers do
}
end
+ def scope_error
+ {
+ status: :error,
+ http_status: :unprocessable_entity,
+ message: 'Your GitHub access token does not have the correct scope to import collaborators.'
+ }
+ end
+
def blocked_url_error(url)
{
status: :error,
diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml
index 6aac031be6f..2dc9546ab14 100644
--- a/spec/support/rspec_order_todo.yml
+++ b/spec/support/rspec_order_todo.yml
@@ -94,7 +94,6 @@
- './ee/spec/controllers/groups/security/merge_commit_reports_controller_spec.rb'
- './ee/spec/controllers/groups/security/policies_controller_spec.rb'
- './ee/spec/controllers/groups/security/vulnerabilities_controller_spec.rb'
-- './ee/spec/controllers/groups/sso_controller_spec.rb'
- './ee/spec/controllers/groups/todos_controller_spec.rb'
- './ee/spec/controllers/groups/wikis_controller_spec.rb'
- './ee/spec/controllers/ldap/omniauth_callbacks_controller_spec.rb'
@@ -284,7 +283,6 @@
- './ee/spec/features/groups/settings/user_configures_insights_spec.rb'
- './ee/spec/features/groups/settings/user_searches_in_settings_spec.rb'
- './ee/spec/features/groups_spec.rb'
-- './ee/spec/features/groups/sso_spec.rb'
- './ee/spec/features/groups/wikis_spec.rb'
- './ee/spec/features/groups/wiki/user_views_wiki_empty_spec.rb'
- './ee/spec/features/ide/user_opens_ide_spec.rb'
@@ -918,7 +916,6 @@
- './ee/spec/helpers/gitlab_subscriptions/upcoming_reconciliation_helper_spec.rb'
- './ee/spec/helpers/groups/ldap_sync_helper_spec.rb'
- './ee/spec/helpers/groups/security_features_helper_spec.rb'
-- './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/license_monitoring_helper_spec.rb'
@@ -2619,14 +2616,11 @@
- './ee/spec/services/gitlab_subscriptions/preview_billable_user_change_service_spec.rb'
- './ee/spec/services/gitlab_subscriptions/reconciliations/calculate_seat_count_data_service_spec.rb'
- './ee/spec/services/gitlab_subscriptions/reconciliations/check_seat_usage_alerts_eligibility_service_spec.rb'
-- './ee/spec/services/group_saml/group_managed_accounts/clean_up_members_service_spec.rb'
-- './ee/spec/services/group_saml/group_managed_accounts/transfer_membership_service_spec.rb'
- './ee/spec/services/group_saml/identity/destroy_service_spec.rb'
- './ee/spec/services/group_saml/saml_group_links/create_service_spec.rb'
- './ee/spec/services/group_saml/saml_group_links/destroy_service_spec.rb'
- './ee/spec/services/group_saml/saml_provider/create_service_spec.rb'
- './ee/spec/services/group_saml/saml_provider/update_service_spec.rb'
-- './ee/spec/services/group_saml/sign_up_service_spec.rb'
- './ee/spec/services/groups/create_service_spec.rb'
- './ee/spec/services/groups/destroy_service_spec.rb'
- './ee/spec/services/groups/epics_count_service_spec.rb'