Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
22321cc5dd
commit
1374102ff6
|
|
@ -70,12 +70,18 @@ export default {
|
|||
onChange(event) {
|
||||
this.items.forEach((item) => {
|
||||
const id = item[this.idProperty];
|
||||
this.$set(this.selectedReferences, id, event);
|
||||
this.selectedReferences = {
|
||||
...this.selectedReferences,
|
||||
[id]: event,
|
||||
};
|
||||
});
|
||||
},
|
||||
selectItem(item) {
|
||||
const id = item[this.idProperty];
|
||||
this.$set(this.selectedReferences, id, !this.selectedReferences[id]);
|
||||
this.selectedReferences = {
|
||||
...this.selectedReferences,
|
||||
[id]: !this.selectedReferences[id],
|
||||
};
|
||||
},
|
||||
isSelected(item) {
|
||||
const id = item[this.idProperty];
|
||||
|
|
|
|||
|
|
@ -9,8 +9,7 @@ const Template = (args, { argTypes }) => ({
|
|||
components: { SettingsBlock },
|
||||
props: Object.keys(argTypes),
|
||||
template: `
|
||||
<settings-block v-bind="$props">
|
||||
<template #title>Settings section title</template>
|
||||
<settings-block v-bind="$props" title="Settings section title">
|
||||
<template #description>Settings section description</template>
|
||||
<template #default>
|
||||
<p>Content</p>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,11 @@ import { __ } from '~/locale';
|
|||
export default {
|
||||
components: { GlButton, GlCollapse },
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: null,
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
required: false,
|
||||
|
|
@ -50,23 +55,24 @@ export default {
|
|||
|
||||
<template>
|
||||
<section class="vue-settings-block">
|
||||
<div class="gl-display-flex gl-justify-content-space-between gl-align-items-flex-start">
|
||||
<div class="gl-flex-grow-1">
|
||||
<h4
|
||||
<div class="gl-flex gl-justify-between gl-items-start">
|
||||
<div class="gl-grow">
|
||||
<h2
|
||||
role="button"
|
||||
tabindex="-1"
|
||||
class="gl-cursor-pointer gl-mt-0 gl-mb-3"
|
||||
class="gl-heading-2 gl-cursor-pointer !gl-mb-2"
|
||||
:aria-expanded="ariaExpanded"
|
||||
:aria-controls="collapseId"
|
||||
@click="toggleExpanded"
|
||||
>
|
||||
<slot name="title"></slot>
|
||||
</h4>
|
||||
<slot v-if="$scopedSlots.title" name="title"></slot>
|
||||
<template v-else>{{ title }}</template>
|
||||
</h2>
|
||||
<p class="gl-text-secondary gl-m-0"><slot name="description"></slot></p>
|
||||
</div>
|
||||
<div class="gl-flex-shrink-0 gl-px-3">
|
||||
<div class="gl-flex-shrink-0 gl-px-2">
|
||||
<gl-button
|
||||
class="gl-min-w-12"
|
||||
class="gl-min-w-12 gl-shrink-0"
|
||||
:aria-expanded="ariaExpanded"
|
||||
:aria-controls="collapseId"
|
||||
@click="toggleExpanded"
|
||||
|
|
@ -76,7 +82,8 @@ export default {
|
|||
</span>
|
||||
<span class="gl-sr-only">
|
||||
{{ toggleButtonText }}
|
||||
<slot name="title"></slot>
|
||||
<slot v-if="$scopedSlots.title" name="title"></slot>
|
||||
<template v-else>{{ title }}</template>
|
||||
</span>
|
||||
</gl-button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -267,7 +267,7 @@ export default {
|
|||
};
|
||||
},
|
||||
showIntersectionObserver() {
|
||||
return !this.isModal && !this.editMode;
|
||||
return !this.isModal && !this.editMode && !this.isDrawer;
|
||||
},
|
||||
workItemLinkedItems() {
|
||||
return this.isWidgetPresent(WIDGET_TYPE_LINKED_ITEMS);
|
||||
|
|
@ -623,6 +623,7 @@ export default {
|
|||
:class="{ 'is-modal': isModal }"
|
||||
>
|
||||
<work-item-attributes-wrapper
|
||||
:class="{ 'gl-top-3': isDrawer }"
|
||||
:full-path="workItemFullPath"
|
||||
:work-item="workItem"
|
||||
:group-path="groupPath"
|
||||
|
|
|
|||
|
|
@ -133,13 +133,13 @@ $work-item-overview-gap-width: 2rem;
|
|||
|
||||
@include container-and-media("min-width: #{calc($breakpoint-md)}") {
|
||||
.work-item-attributes-wrapper {
|
||||
top: calc(#{$calc-application-header-height} + #{$work-item-sticky-header-height});
|
||||
height: calc(#{$calc-application-viewport-height} - #{$work-item-sticky-header-height});
|
||||
margin-bottom: calc(#{$content-wrapper-padding} * -1);
|
||||
padding-inline: 0.5rem;
|
||||
position: sticky;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
top: calc(#{$calc-application-header-height} + #{$work-item-sticky-header-height});
|
||||
height: calc(#{$calc-application-viewport-height} - #{$work-item-sticky-header-height});
|
||||
margin-bottom: calc(#{$content-wrapper-padding} * -1);
|
||||
padding-inline: 0.5rem;
|
||||
position: sticky;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.work-item-date-picker {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
%section{ class: section_classes, id: js_id, data: (@id ? { testid: @id } : {}) }
|
||||
.gl-flex.gl-justify-between.gl-items-start.gl-pt-5
|
||||
.gl-grow
|
||||
%h2{ class: title_classes }
|
||||
= heading || @heading
|
||||
%p.gl-text-secondary.gl-m-0
|
||||
= description || @description
|
||||
.gl-shrink-0.gl-px-2
|
||||
= render Pajamas::ButtonComponent.new(button_options: { class: 'gl-min-w-12 js-settings-toggle' }) do
|
||||
= button_text
|
||||
.settings-content
|
||||
.gl-pt-5
|
||||
= body
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Layouts
|
||||
class SettingsBlockComponent < ViewComponent::Base
|
||||
# @param [String] heading
|
||||
# @param [String] description
|
||||
# @param [String] id
|
||||
# @param [Boolean] expanded
|
||||
def initialize(heading, description: nil, id: nil, expanded: nil)
|
||||
@heading = heading
|
||||
@description = description
|
||||
@id = id
|
||||
@expanded = expanded
|
||||
end
|
||||
|
||||
renders_one :heading
|
||||
renders_one :description
|
||||
renders_one :body
|
||||
|
||||
private
|
||||
|
||||
def section_classes
|
||||
classes = %w[settings no-animate]
|
||||
classes.push('expanded') if @expanded
|
||||
classes.join(' ')
|
||||
end
|
||||
|
||||
def title_classes
|
||||
%w[gl-heading-2 gl-cursor-pointer !gl-mb-2 js-settings-toggle js-settings-toggle-trigger-only]
|
||||
end
|
||||
|
||||
def button_text
|
||||
@expanded ? _('Collapse') : _('Expand')
|
||||
end
|
||||
|
||||
def js_id
|
||||
@id ? "js-#{@id}" : nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -52,7 +52,7 @@ class HelpController < ApplicationController
|
|||
end
|
||||
|
||||
def redirect_to_docs
|
||||
redirect_to documentation_base_url
|
||||
redirect_to documentation_base_url || Gitlab::Saas.doc_url
|
||||
end
|
||||
|
||||
def shortcuts
|
||||
|
|
|
|||
|
|
@ -826,7 +826,7 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord
|
|||
reset_memoized_terms
|
||||
end
|
||||
after_commit :expire_performance_bar_allowed_user_ids_cache, if: -> { previous_changes.key?('performance_bar_allowed_group_id') }
|
||||
after_commit :reset_deletion_warning_redis_key, if: :saved_change_to_inactive_projects_delete_after_months?
|
||||
after_commit :reset_deletion_warning_redis_key, if: :should_reset_inactive_project_deletion_warning?
|
||||
|
||||
def validate_grafana_url
|
||||
validate_url(parsed_grafana_url, :grafana_url, GRAFANA_URL_ERROR_MESSAGE)
|
||||
|
|
@ -991,6 +991,10 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord
|
|||
default_group_visibility_changed? ||
|
||||
restricted_visibility_levels_changed?
|
||||
end
|
||||
|
||||
def should_reset_inactive_project_deletion_warning?
|
||||
saved_change_to_inactive_projects_delete_after_months? || saved_change_to_delete_inactive_projects?(from: true, to: false)
|
||||
end
|
||||
end
|
||||
|
||||
ApplicationSetting.prepend_mod_with('ApplicationSetting')
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description:
|
|||
value_description:
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::conversion
|
||||
product_group: acquisition
|
||||
milestone: "15.0"
|
||||
introduced_by_url:
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description:
|
|||
value_description:
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::conversion
|
||||
product_group: acquisition
|
||||
milestone: "15.0"
|
||||
introduced_by_url:
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description:
|
|||
value_description:
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::adoption
|
||||
product_group: activation
|
||||
milestone: "13.12"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59713
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description:
|
|||
value_description:
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::adoption
|
||||
product_group: activation
|
||||
milestone: "13.12"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59713
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description: "`[admin | maintainer | developer | owner]`"
|
|||
value_description: ""
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::expansion
|
||||
product_group: activation
|
||||
milestone: "12.9"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/26605
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description: ""
|
|||
value_description: ""
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::expansion
|
||||
product_group: activation
|
||||
milestone: "13.4"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41774
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description: ""
|
|||
value_description: ""
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::expansion
|
||||
product_group: activation
|
||||
milestone: "13.4"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41774
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description: ""
|
|||
value_description: ""
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::expansion
|
||||
product_group: activation
|
||||
milestone: "13.4"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39752
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description: ""
|
|||
value_description: ""
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::expansion
|
||||
product_group: activation
|
||||
milestone: "13.4"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/39752
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description: "`[admin | maintainer | developer | owner]`"
|
|||
value_description: ""
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::expansion
|
||||
product_group: activation
|
||||
milestone: "13.12"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/35069
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description: "ID of namespace"
|
|||
value_description: ""
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::adoption
|
||||
product_group: activation
|
||||
milestone: "13.5"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42653
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description: "`[Growth::Conversion::Experiment::LearnGitLab | Growth::A
|
|||
value_description: ""
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::conversion
|
||||
product_group: acquisition
|
||||
milestone: "13.12"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58689
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description: ""
|
|||
value_description: ""
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::expansion
|
||||
product_group: activation
|
||||
milestone: "14.0"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62505
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description: ""
|
|||
value_description: ""
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::expansion
|
||||
product_group: activation
|
||||
milestone: "14.0"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62505
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description: "`[feature_url]`"
|
|||
value_description: ""
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::adoption
|
||||
product_group: activation
|
||||
milestone: "13.12"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/60804
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ property_description: "`[admin | maintainer | developer | owner]`"
|
|||
value_description: "`10`"
|
||||
extra_properties:
|
||||
identifiers:
|
||||
product_group: group::expansion
|
||||
product_group: activation
|
||||
milestone: "12.9"
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23823
|
||||
distributions:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
migration_job_name: BackfillVulnerabilityFindingSignaturesProjectId
|
||||
description: Backfills sharding key `vulnerability_finding_signatures.project_id` from `vulnerability_occurrences`.
|
||||
feature_category: vulnerability_management
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156794
|
||||
milestone: '17.2'
|
||||
queued_migration_version: 20240619142934
|
||||
finalize_after: '2024-07-22'
|
||||
finalized_by: # version of the migration that finalized this BBM
|
||||
|
|
@ -19,3 +19,4 @@ desired_sharding_key:
|
|||
table: vulnerability_occurrences
|
||||
sharding_key: project_id
|
||||
belongs_to: finding
|
||||
desired_sharding_key_migration_job_name: BackfillVulnerabilityFindingSignaturesProjectId
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddProjectIdToVulnerabilityFindingSignatures < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
def change
|
||||
add_column :vulnerability_finding_signatures, :project_id, :bigint
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveImportedColumnOnDesignManagementDesigns < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
def up
|
||||
remove_column :design_management_designs, :imported
|
||||
end
|
||||
|
||||
def down
|
||||
add_column :design_management_designs, :imported, :integer, default: 0, null: false, limit: 2
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveImportedColumnOnEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
def up
|
||||
remove_column :events, :imported
|
||||
end
|
||||
|
||||
def down
|
||||
add_column :events, :imported, :integer, default: 0, null: false, limit: 2
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveImportedColumnOnIssues < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
def up
|
||||
remove_column :issues, :imported
|
||||
end
|
||||
|
||||
def down
|
||||
add_column :issues, :imported, :integer, default: 0, null: false, limit: 2
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveImportedColumnOnMergeRequests < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
def up
|
||||
remove_column :merge_requests, :imported
|
||||
end
|
||||
|
||||
def down
|
||||
add_column :merge_requests, :imported, :integer, default: 0, null: false, limit: 2
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveImportedColumnOnNotes < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
def up
|
||||
remove_column :notes, :imported
|
||||
end
|
||||
|
||||
def down
|
||||
add_column :notes, :imported, :integer, default: 0, null: false, limit: 2
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveImportedColumnOnResourceLabelEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
def up
|
||||
remove_column :resource_label_events, :imported
|
||||
end
|
||||
|
||||
def down
|
||||
add_column :resource_label_events, :imported, :integer, default: 0, null: false, limit: 2
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveImportedColumnOnResourceMilestoneEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
def up
|
||||
remove_column :resource_milestone_events, :imported
|
||||
end
|
||||
|
||||
def down
|
||||
add_column :resource_milestone_events, :imported, :integer, default: 0, null: false, limit: 2
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveImportedColumnOnResourceStateEvents < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
def up
|
||||
remove_column :resource_state_events, :imported
|
||||
end
|
||||
|
||||
def down
|
||||
add_column :resource_state_events, :imported, :integer, default: 0, null: false, limit: 2
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveImportedColumnOnSnippets < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
def up
|
||||
remove_column :snippets, :imported
|
||||
end
|
||||
|
||||
def down
|
||||
add_column :snippets, :imported, :integer, default: 0, null: false, limit: 2
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class IndexVulnerabilityFindingSignaturesOnProjectId < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'index_vulnerability_finding_signatures_on_project_id'
|
||||
|
||||
def up
|
||||
add_concurrent_index :vulnerability_finding_signatures, :project_id, name: INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name :vulnerability_finding_signatures, INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddVulnerabilityFindingSignaturesProjectIdFk < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key :vulnerability_finding_signatures, :projects, column: :project_id, on_delete: :cascade
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_foreign_key :vulnerability_finding_signatures, column: :project_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddVulnerabilityFindingSignaturesProjectIdTrigger < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
|
||||
def up
|
||||
install_sharding_key_assignment_trigger(
|
||||
table: :vulnerability_finding_signatures,
|
||||
sharding_key: :project_id,
|
||||
parent_table: :vulnerability_occurrences,
|
||||
parent_sharding_key: :project_id,
|
||||
foreign_key: :finding_id
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_sharding_key_assignment_trigger(
|
||||
table: :vulnerability_finding_signatures,
|
||||
sharding_key: :project_id,
|
||||
parent_table: :vulnerability_occurrences,
|
||||
parent_sharding_key: :project_id,
|
||||
foreign_key: :finding_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class QueueBackfillVulnerabilityFindingSignaturesProjectId < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.2'
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
|
||||
|
||||
MIGRATION = "BackfillVulnerabilityFindingSignaturesProjectId"
|
||||
DELAY_INTERVAL = 2.minutes
|
||||
BATCH_SIZE = 1000
|
||||
SUB_BATCH_SIZE = 100
|
||||
|
||||
def up
|
||||
queue_batched_background_migration(
|
||||
MIGRATION,
|
||||
:vulnerability_finding_signatures,
|
||||
:id,
|
||||
:project_id,
|
||||
:vulnerability_occurrences,
|
||||
:project_id,
|
||||
:finding_id,
|
||||
job_interval: DELAY_INTERVAL,
|
||||
batch_size: BATCH_SIZE,
|
||||
sub_batch_size: SUB_BATCH_SIZE
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
delete_batched_background_migration(
|
||||
MIGRATION,
|
||||
:vulnerability_finding_signatures,
|
||||
:id,
|
||||
[
|
||||
:project_id,
|
||||
:vulnerability_occurrences,
|
||||
:project_id,
|
||||
:finding_id
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
8db45462581d0bdce23eb2da53af92f6e9f707eed2569746ddc0d0b01be0047c
|
||||
|
|
@ -0,0 +1 @@
|
|||
3c3413b504d4db871b1162a3456263944f03e7efc5207cb2ddbe8602597db7ee
|
||||
|
|
@ -0,0 +1 @@
|
|||
e5a6467d186ec85b38feb7fb94231ca63714bcf4867a76da74c71ed5e7e01b05
|
||||
|
|
@ -0,0 +1 @@
|
|||
6688efd3cafd26994ec14b7460914cddf74af6f636de9148494c774305b20373
|
||||
|
|
@ -0,0 +1 @@
|
|||
6b188bd456daf99f88e52b846c99edf3ccfdf099354d34bcc0429cbcac2b3768
|
||||
|
|
@ -0,0 +1 @@
|
|||
0d2c85e9d3a0f5a3e63908575ee45486cec9b1aa70b292ad184cd5a9e372788f
|
||||
|
|
@ -0,0 +1 @@
|
|||
2c4b550ac5fad69332a56ddaca7492586ae11dcab4e686853fe9df1813c265ae
|
||||
|
|
@ -0,0 +1 @@
|
|||
0e15662b9ec2d99b242661070a52ac2fd19d00113778d5b660a232cbc595b18d
|
||||
|
|
@ -0,0 +1 @@
|
|||
6cfe6d8fc12d0d259a53518decfbe6e053a98947f69e5d3a1ab9eefd1ddc902c
|
||||
|
|
@ -0,0 +1 @@
|
|||
7f01812c9e2e64223b73917afc473f36e698175ae76db275fc44039c273c98db
|
||||
|
|
@ -0,0 +1 @@
|
|||
5531164d9950e01cf7a583ad7b648d6a74d30add7f6dba1fb90e0b0489ceeb26
|
||||
|
|
@ -0,0 +1 @@
|
|||
c3bf77d1753cda8080f9fe0bc46c385d6c835a4795f3be8e1db7966d89d587f6
|
||||
|
|
@ -0,0 +1 @@
|
|||
0690243770e91a2432ea16a8947eee342048a43c2807218421a3639f33f6f0f8
|
||||
|
|
@ -0,0 +1 @@
|
|||
58630d6ef2a223266af2bedc0e7a7a95d4e38f70aceb8f28726d0f2d8dc0d85e
|
||||
|
|
@ -1660,6 +1660,22 @@ BEGIN
|
|||
END;
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_fff8735b6b9a() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
IF NEW."project_id" IS NULL THEN
|
||||
SELECT "project_id"
|
||||
INTO NEW."project_id"
|
||||
FROM "vulnerability_occurrences"
|
||||
WHERE "vulnerability_occurrences"."id" = NEW."finding_id";
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION unset_has_issues_on_vulnerability_reads() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
|
|
@ -9442,7 +9458,6 @@ CREATE TABLE design_management_designs (
|
|||
cached_markdown_version integer,
|
||||
description text,
|
||||
description_html text,
|
||||
imported smallint DEFAULT 0 NOT NULL,
|
||||
imported_from smallint DEFAULT 0 NOT NULL,
|
||||
namespace_id bigint,
|
||||
CONSTRAINT check_07155e2715 CHECK ((char_length((filename)::text) <= 255)),
|
||||
|
|
@ -10061,7 +10076,6 @@ CREATE TABLE events (
|
|||
fingerprint bytea,
|
||||
id bigint NOT NULL,
|
||||
target_id bigint,
|
||||
imported smallint DEFAULT 0 NOT NULL,
|
||||
imported_from smallint DEFAULT 0 NOT NULL,
|
||||
CONSTRAINT check_97e06e05ad CHECK ((octet_length(fingerprint) <= 128))
|
||||
);
|
||||
|
|
@ -11539,7 +11553,6 @@ CREATE TABLE issues (
|
|||
namespace_id bigint,
|
||||
start_date date,
|
||||
tmp_epic_id bigint,
|
||||
imported smallint DEFAULT 0 NOT NULL,
|
||||
imported_from smallint DEFAULT 0 NOT NULL,
|
||||
CONSTRAINT check_2addf801cd CHECK ((work_item_type_id IS NOT NULL)),
|
||||
CONSTRAINT check_c33362cd43 CHECK ((namespace_id IS NOT NULL)),
|
||||
|
|
@ -12450,7 +12463,6 @@ CREATE TABLE merge_requests (
|
|||
merged_commit_sha bytea,
|
||||
override_requested_changes boolean DEFAULT false NOT NULL,
|
||||
head_pipeline_id_convert_to_bigint bigint,
|
||||
imported smallint DEFAULT 0 NOT NULL,
|
||||
imported_from smallint DEFAULT 0 NOT NULL,
|
||||
CONSTRAINT check_970d272570 CHECK ((lock_version IS NOT NULL))
|
||||
);
|
||||
|
|
@ -13148,7 +13160,6 @@ CREATE TABLE notes (
|
|||
internal boolean DEFAULT false NOT NULL,
|
||||
id bigint NOT NULL,
|
||||
namespace_id bigint,
|
||||
imported smallint DEFAULT 0 NOT NULL,
|
||||
imported_from smallint DEFAULT 0 NOT NULL,
|
||||
CONSTRAINT check_1244cbd7d0 CHECK ((noteable_type IS NOT NULL))
|
||||
);
|
||||
|
|
@ -16416,7 +16427,6 @@ CREATE TABLE resource_label_events (
|
|||
cached_markdown_version integer,
|
||||
reference text,
|
||||
reference_html text,
|
||||
imported smallint DEFAULT 0 NOT NULL,
|
||||
imported_from smallint DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
|
|
@ -16457,7 +16467,6 @@ CREATE TABLE resource_milestone_events (
|
|||
action smallint NOT NULL,
|
||||
state smallint NOT NULL,
|
||||
created_at timestamp with time zone NOT NULL,
|
||||
imported smallint DEFAULT 0 NOT NULL,
|
||||
imported_from smallint DEFAULT 0 NOT NULL
|
||||
);
|
||||
|
||||
|
|
@ -16482,7 +16491,6 @@ CREATE TABLE resource_state_events (
|
|||
close_after_error_tracking_resolve boolean DEFAULT false NOT NULL,
|
||||
close_auto_resolve_prometheus_alert boolean DEFAULT false NOT NULL,
|
||||
source_merge_request_id bigint,
|
||||
imported smallint DEFAULT 0 NOT NULL,
|
||||
imported_from smallint DEFAULT 0 NOT NULL,
|
||||
CONSTRAINT check_f0bcfaa3a2 CHECK ((char_length(source_commit) <= 40)),
|
||||
CONSTRAINT state_events_must_belong_to_issue_or_merge_request_or_epic CHECK ((((issue_id <> NULL::bigint) AND (merge_request_id IS NULL) AND (epic_id IS NULL)) OR ((issue_id IS NULL) AND (merge_request_id <> NULL::bigint) AND (epic_id IS NULL)) OR ((issue_id IS NULL) AND (merge_request_id IS NULL) AND (epic_id <> NULL::integer))))
|
||||
|
|
@ -17347,7 +17355,6 @@ CREATE TABLE snippets (
|
|||
encrypted_secret_token_iv character varying(255),
|
||||
secret boolean DEFAULT false NOT NULL,
|
||||
repository_read_only boolean DEFAULT false NOT NULL,
|
||||
imported smallint DEFAULT 0 NOT NULL,
|
||||
imported_from smallint DEFAULT 0 NOT NULL,
|
||||
organization_id bigint DEFAULT 1
|
||||
);
|
||||
|
|
@ -18701,7 +18708,8 @@ CREATE TABLE vulnerability_finding_signatures (
|
|||
created_at timestamp with time zone NOT NULL,
|
||||
updated_at timestamp with time zone NOT NULL,
|
||||
algorithm_type smallint NOT NULL,
|
||||
signature_sha bytea NOT NULL
|
||||
signature_sha bytea NOT NULL,
|
||||
project_id bigint
|
||||
);
|
||||
|
||||
CREATE SEQUENCE vulnerability_finding_signatures_id_seq
|
||||
|
|
@ -29124,6 +29132,8 @@ CREATE INDEX index_vulnerability_feedback_on_pipeline_id ON vulnerability_feedba
|
|||
|
||||
CREATE INDEX index_vulnerability_finding_signatures_on_finding_id ON vulnerability_finding_signatures USING btree (finding_id);
|
||||
|
||||
CREATE INDEX index_vulnerability_finding_signatures_on_project_id ON vulnerability_finding_signatures USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_vulnerability_finding_signatures_on_signature_sha ON vulnerability_finding_signatures USING btree (signature_sha);
|
||||
|
||||
CREATE INDEX index_vulnerability_findings_remediations_on_project_id ON vulnerability_findings_remediations USING btree (project_id);
|
||||
|
|
@ -31310,6 +31320,8 @@ CREATE TRIGGER trigger_fd041fe2d1a7 BEFORE INSERT OR UPDATE ON merge_request_met
|
|||
|
||||
CREATE TRIGGER trigger_ff16c1fd43ea BEFORE INSERT OR UPDATE ON geo_event_log FOR EACH ROW EXECUTE FUNCTION trigger_ff16c1fd43ea();
|
||||
|
||||
CREATE TRIGGER trigger_fff8735b6b9a BEFORE INSERT OR UPDATE ON vulnerability_finding_signatures FOR EACH ROW EXECUTE FUNCTION trigger_fff8735b6b9a();
|
||||
|
||||
CREATE TRIGGER trigger_has_external_issue_tracker_on_delete AFTER DELETE ON integrations FOR EACH ROW WHEN ((((old.category)::text = 'issue_tracker'::text) AND (old.active = true) AND (old.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker();
|
||||
|
||||
CREATE TRIGGER trigger_has_external_issue_tracker_on_insert AFTER INSERT ON integrations FOR EACH ROW WHEN ((((new.category)::text = 'issue_tracker'::text) AND (new.active = true) AND (new.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker();
|
||||
|
|
@ -32433,6 +32445,9 @@ ALTER TABLE ONLY agent_activity_events
|
|||
ALTER TABLE ONLY issue_links
|
||||
ADD CONSTRAINT fk_c900194ff2 FOREIGN KEY (source_id) REFERENCES issues(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY vulnerability_finding_signatures
|
||||
ADD CONSTRAINT fk_c909c7e07b FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY personal_access_tokens
|
||||
ADD CONSTRAINT fk_c951fbf57e FOREIGN KEY (previous_personal_access_token_id) REFERENCES personal_access_tokens(id) ON DELETE SET NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -1051,7 +1051,7 @@ This file is located at:
|
|||
- `/var/log/gitlab/gitlab-rails/epic_work_item_sync.log` on Linux package installations.
|
||||
- `/home/git/gitlab/log/epic_work_item_sync.log` on self-compiled installations.
|
||||
|
||||
## `secret_detection.log`
|
||||
## `secret_push_protection.log`
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate
|
||||
|
|
@ -1059,12 +1059,12 @@ DETAILS:
|
|||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/137812) in GitLab 16.7.
|
||||
|
||||
The `secret_detection.log` file logs information related to [Secret Push Protection](../../user/application_security/secret_detection/secret_push_protection/index.md) feature.
|
||||
The `secret_push_protection.log` file logs information related to [Secret Push Protection](../../user/application_security/secret_detection/secret_push_protection/index.md) feature.
|
||||
|
||||
This file is located at:
|
||||
|
||||
- `/var/log/gitlab/gitlab-rails/secret_detection.log` on Linux package installations.
|
||||
- `/home/git/gitlab/log/secret_detection.log` on self-compiled installations.
|
||||
- `/var/log/gitlab/gitlab-rails/secret_push_protection.log` on Linux package installations.
|
||||
- `/home/git/gitlab/log/secret_push_protection.log` on self-compiled installations.
|
||||
|
||||
## Registry logs
|
||||
|
||||
|
|
|
|||
|
|
@ -309,7 +309,7 @@ sequenceDiagram
|
|||
HTTP Router->> TS / Classify Service: Classify(SessionPrefix) "cell1"
|
||||
TS / Classify Service->>HTTP Router: gitlab-org/gitlab => Cell 1
|
||||
HTTP Router->> Cell 1: GET "/gitlab-org/gitlab/-/issues"<br>Cookie: _gitlab_session=cell1:df1f861a9e609
|
||||
Cell 2->> HTTP Router: Issues Page Response
|
||||
Cell 1->> HTTP Router: Issues Page Response
|
||||
HTTP Router->>User1: Issues Page Response
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,22 @@ The Pipeline Execution Policy MVC will allow the transition from compliance pipe
|
|||
- Jobs coming from the policies should be marked as such in the database so that they can be distinguished, for example by using build metadata. This allows for different handling of jobs and the corresponding variables by the runner.
|
||||
- Users should be able to define the stage in which their job will run, and Pipeline Execution Policies will have a method to handle precedence. For example, a security/compliance team may want to enforce jobs that run commonly after a build stage. The stages and jobs must not interfere with those defined by development teams once enforced by a Pipeline Execution Policy.
|
||||
- Pipeline Execution Policies should allow for jobs to be enforced in projects that do not contain an existing CI configuration.
|
||||
- To reduce complexity, the `content` of a Pipeline Execution Policy can only be an inclusion of a single [CI file from a project](../../../ci/yaml/index.md#includeproject).
|
||||
|
||||
MVC syntax example:
|
||||
|
||||
```yaml
|
||||
type: pipeline_execution_policy
|
||||
name: PEP example
|
||||
description: 'PEP example'
|
||||
enabled: true
|
||||
pipeline_config_strategy: inject_ci
|
||||
content:
|
||||
include:
|
||||
- project: namespace-path/project-path
|
||||
file: policy_ci.yml
|
||||
ref: main
|
||||
```
|
||||
|
||||
### Stages management strategy
|
||||
|
||||
|
|
|
|||
|
|
@ -153,9 +153,7 @@ To enable the Dangerfile on another existing GitLab project, complete the follow
|
|||
|
||||
```yaml
|
||||
include:
|
||||
- project: 'gitlab-org/quality/pipeline-common'
|
||||
file:
|
||||
- '/ci/danger-review.yml'
|
||||
- component: ${CI_SERVER_FQDN}/gitlab-org/components/danger-review/danger-review@1.2.0
|
||||
rules:
|
||||
- if: $CI_SERVER_HOST == "gitlab.com"
|
||||
```
|
||||
|
|
|
|||
|
|
@ -9,75 +9,17 @@ info: Any user with at least the Maintainer role can merge updates to this conte
|
|||
NOTE:
|
||||
To track user interactions in the browser, Do-Not-Track (“DNT”) needs to be disabled. DNT is disabled by default for most browsers.
|
||||
|
||||
Internal events are using a tool called Snowplow under the hood. To develop and test internal events, there are several tools related to Snowplow to test frontend and backend events:
|
||||
Internal events are using a tool called Snowplow under the hood. To develop and test internal events, there are several tools to test frontend and backend events:
|
||||
|
||||
| Testing Tool | Frontend Tracking | Backend Tracking | Local Development Environment | Production Environment | Production Environment |
|
||||
| Testing Tool | Frontend Tracking | Backend Tracking | Local Development Environment | Production Environment | Shows individual events |
|
||||
|----------------------------------------------|--------------------|---------------------|-------------------------------|------------------------|------------------------|
|
||||
| Snowplow Analytics Debugger Chrome Extension | Yes | No | Yes | Yes | Yes |
|
||||
| Snowplow Micro | Yes | Yes | Yes | No | No |
|
||||
| [Internal Events Monitor](#internal-events-monitor) | Yes | Yes | Yes | Yes | Yes, if running [Snowplow Micro](#snowplow-micro) |
|
||||
| [Snowplow Micro](#snowplow-micro) | Yes | Yes | Yes | No | Yes |
|
||||
| [Manual check in GDK](#manual-check-in-gdk) | Yes | Yes | Yes | Yes | No |
|
||||
| [Snowplow Analytics Debugger Chrome Extension](#snowplow-analytics-debugger-chrome-extension) | Yes | No | Yes | Yes | Yes |
|
||||
| [Remote event collector](#remote-event-collector) | Yes | No | Yes | No | Yes |
|
||||
|
||||
For local development you will have to either [setup a local event collector](#setup-local-event-collector) or [configure a remote event collector](#configure-a-remote-event-collector).
|
||||
We recommend using the local setup together with the [internal events monitor](#internal-events-monitor) when actively developing new events.
|
||||
|
||||
## Setup local event collector
|
||||
|
||||
By default, self-managed instances do not collect event data via Snowplow. We can use [Snowplow Micro](https://docs.snowplow.io/docs/testing-debugging/snowplow-micro/what-is-micro/), a Docker based Snowplow collector, to test events locally:
|
||||
|
||||
1. Ensure [Docker is installed and working](https://www.docker.com/get-started/).
|
||||
|
||||
1. Enable Snowplow Micro:
|
||||
|
||||
```shell
|
||||
gdk config set snowplow_micro.enabled true
|
||||
```
|
||||
|
||||
1. Optional. Snowplow Micro runs on port `9091` by default, you can change to `9092` by running:
|
||||
|
||||
```shell
|
||||
gdk config set snowplow_micro.port 9092
|
||||
```
|
||||
|
||||
1. Regenerate your Procfile and YAML config by reconfiguring GDK:
|
||||
|
||||
```shell
|
||||
gdk reconfigure
|
||||
```
|
||||
|
||||
1. Restart the GDK:
|
||||
|
||||
```shell
|
||||
gdk restart
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
You can configure your self-managed GitLab instance to use a custom Snowplow collector.
|
||||
|
||||
1. On the left sidebar, at the bottom, select **Admin Area**.
|
||||
1. Select **Settings > General**.
|
||||
1. Expand **Snowplow**.
|
||||
1. Select **Enable Snowplow tracking** and enter your Snowplow configuration information. For example:
|
||||
|
||||
| Name | Value |
|
||||
|--------------------|-------------------------------|
|
||||
| Collector hostname | `your-snowplow-collector.net` |
|
||||
| App ID | `gitlab` |
|
||||
| Cookie domain | `.your-gitlab-instance.com` |
|
||||
|
||||
1. Select **Save changes**.
|
||||
For local development we recommend using the [internal events monitor](#internal-events-monitor) when actively developing new events.
|
||||
|
||||
## Internal Events Monitor
|
||||
|
||||
|
|
@ -88,7 +30,7 @@ You can configure your self-managed GitLab instance to use a custom Snowplow col
|
|||
<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`,
|
||||
To understand how events are triggered and metrics are updated while you use the GitLab application locally or `rails console`,
|
||||
you can use the monitor.
|
||||
|
||||
Start the monitor and list one or more events that you would like to monitor. In this example we would like to monitor `i_code_review_user_create_mr`.
|
||||
|
|
@ -97,11 +39,14 @@ Start the monitor and list one or more events that you would like to monitor. In
|
|||
rails runner scripts/internal_events/monitor.rb i_code_review_user_create_mr
|
||||
```
|
||||
|
||||
The monitor shows two tables. The top table lists all the metrics that are defined on the `i_code_review_user_create_mr` event.
|
||||
The second right-most column shows the value of each metric when the monitor was started and the right most column shows the current value of each metric.
|
||||
The bottom table has a list selected properties of all Snowplow events that matches the event name.
|
||||
The monitor can show two tables:
|
||||
|
||||
If a new `i_code_review_user_create_mr` event is fired, the metrics values will get updated and a new event will appear in the `SNOWPLOW EVENTS` table.
|
||||
- The `RELEVANT METRICS` table lists all the metrics that are defined on the `i_code_review_user_create_mr` event.
|
||||
The second right-most column shows the value of each metric when the monitor was started and the right most column shows the current value of each metric.
|
||||
|
||||
- The `SNOWPLOW EVENTS` table lists a selection of properties from all Snowplow events that match the event name. This table is only visible if you also set up [Snowplow Micro](#snowplow-micro).
|
||||
|
||||
If a new `i_code_review_user_create_mr` event is fired, the metrics values get updated and a new event appears in the `SNOWPLOW EVENTS` table.
|
||||
|
||||
The monitor looks like below.
|
||||
|
||||
|
|
@ -130,7 +75,48 @@ Monitored events: i_code_review_user_create_mr
|
|||
+------------------------------+--------------------------+---------+--------------+------------+---------+
|
||||
```
|
||||
|
||||
## Manually check the relevant metric values in GDK
|
||||
## Snowplow Micro
|
||||
|
||||
By default, self-managed instances do not collect event data through Snowplow. We can use [Snowplow Micro](https://docs.snowplow.io/docs/testing-debugging/snowplow-micro/what-is-micro/), a Docker based Snowplow collector, to test events locally:
|
||||
|
||||
1. Ensure [Docker is installed and working](https://www.docker.com/get-started/).
|
||||
|
||||
1. Enable Snowplow Micro:
|
||||
|
||||
```shell
|
||||
gdk config set snowplow_micro.enabled true
|
||||
```
|
||||
|
||||
1. Optional. Snowplow Micro runs on port `9091` by default, you can change to `9092` by running:
|
||||
|
||||
```shell
|
||||
gdk config set snowplow_micro.port 9092
|
||||
```
|
||||
|
||||
1. Regenerate your Procfile and YAML configuration by reconfiguring GDK:
|
||||
|
||||
```shell
|
||||
gdk reconfigure
|
||||
```
|
||||
|
||||
1. Restart the GDK:
|
||||
|
||||
```shell
|
||||
gdk restart
|
||||
```
|
||||
|
||||
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>
|
||||
|
||||
## Manual check in GDK
|
||||
|
||||
As a quick test of whether an event is getting triggered & metric is updated, you can check the latest values in the rails console.
|
||||
Make sure to load the helpers below so that the most recent events & records are included in the output.
|
||||
|
|
@ -157,3 +143,22 @@ It works in production, staging, and local development environments. It is espec
|
|||
1. Install the [Snowplow Analytics Debugger](https://chromewebstore.google.com/detail/snowplow-analytics-debugg/jbnlcgeengmijcghameodeaenefieedm) Chrome browser extension.
|
||||
1. Open Chrome DevTools to the Snowplow Debugger tab.
|
||||
1. Any event triggered on a GitLab page should appear in the Snowplow Debugger tab.
|
||||
|
||||
## 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.
|
||||
|
||||
You can configure your self-managed GitLab instance to use a custom Snowplow collector.
|
||||
|
||||
1. On the left sidebar, at the bottom, select **Admin Area**.
|
||||
1. Select **Settings > General**.
|
||||
1. Expand **Snowplow**.
|
||||
1. Select **Enable Snowplow tracking** and enter your Snowplow configuration information. For example if your custom snowplow collector is available at `your-snowplow-collector.net`:
|
||||
|
||||
| Name | Value |
|
||||
|--------------------|-------------------------------|
|
||||
| Collector hostname | `your-snowplow-collector.net` |
|
||||
| App ID | `gitlab` |
|
||||
| Cookie domain | `.your-gitlab-instance.com` |
|
||||
|
||||
1. Select **Save changes**.
|
||||
|
|
|
|||
|
|
@ -736,6 +736,67 @@ The attributes are case-sensitive.
|
|||
| First Name | `first_name`, `firstname`, `firstName`, `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname`, `http://schemas.microsoft.com/ws/2008/06/identity/claims/givenname` |
|
||||
| Last Name | `last_name`, `lastname`, `lastName`, `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname`, `http://schemas.microsoft.com/ws/2008/06/identity/claims/surname` |
|
||||
|
||||
When GitLab receives a SAML response from a SAML SSO provider, GitLab looks for the following values in the attribute `name` field:
|
||||
|
||||
- `"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"`
|
||||
- `"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"`
|
||||
- `"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"`
|
||||
- `firstname`
|
||||
- `lastname`
|
||||
- `email`
|
||||
|
||||
You must include these values correctly in the attribute `Name` field so that GitLab can parse the SAML response. For example, GitLab can parse the following SAML response snippets:
|
||||
|
||||
```xml
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname">
|
||||
<AttributeValue>Alvin</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname">
|
||||
<AttributeValue>Test</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
|
||||
<AttributeValue>alvintest@example.com</AttributeValue>
|
||||
</Attribute>
|
||||
```
|
||||
|
||||
```xml
|
||||
<Attribute Name="firstname">
|
||||
<AttributeValue>Alvin</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="lastname">
|
||||
<AttributeValue>Test</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="email">
|
||||
<AttributeValue>alvintest@example.com</AttributeValue>
|
||||
</Attribute>
|
||||
```
|
||||
|
||||
However, GitLab cannot parse the following SAML response snippets:
|
||||
|
||||
```xml
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/firstname">
|
||||
<AttributeValue>Alvin</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/lastname">
|
||||
<AttributeValue>Test</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mail">
|
||||
<AttributeValue>alvintest@example.com</AttributeValue>
|
||||
</Attribute>
|
||||
```
|
||||
|
||||
```xml
|
||||
<Attribute FriendlyName="firstname" Name="urn:oid:2.5.4.42">
|
||||
<AttributeValue>Alvin</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute FriendlyName="lastname" Name="urn:oid:2.5.4.4">
|
||||
<AttributeValue>Test</AttributeValue>
|
||||
</Attribute>
|
||||
<Attribute FriendlyName="email" Name="urn:oid:0.9.2342.19200300.100.1.3">
|
||||
<AttributeValue>alvintest@example.com</AttributeValue>
|
||||
</Attribute>
|
||||
```
|
||||
|
||||
See [`attribute_statements`](#map-saml-response-attribute-names) for:
|
||||
|
||||
- Custom assertion configuration examples.
|
||||
|
|
|
|||
|
|
@ -202,13 +202,6 @@ RSpec.describe Gitlab::SecretDetection::Scan, feature_category: :secret_detectio
|
|||
expect(scan.secrets_scan(blobs, subprocess: true)).to eq(expected_response)
|
||||
end
|
||||
|
||||
it "takes at least same time to run as running in main process" do
|
||||
expect { scan.secrets_scan(large_blobs, subprocess: true) }.to perform_faster_than {
|
||||
scan.secrets_scan(large_blobs,
|
||||
subprocess: false)
|
||||
}.once
|
||||
end
|
||||
|
||||
it "allocates less memory than when running in main process" do
|
||||
forked_stats = Benchmark::Malloc.new.run { scan.secrets_scan(large_blobs, subprocess: true) }
|
||||
non_forked_stats = Benchmark::Malloc.new.run { scan.secrets_scan(large_blobs, subprocess: false) }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module BackgroundMigration
|
||||
class BackfillVulnerabilityFindingSignaturesProjectId < BackfillDesiredShardingKeyJob
|
||||
operation_name :backfill_vulnerability_finding_signatures_project_id
|
||||
feature_category :vulnerability_management
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -13436,6 +13436,9 @@ msgstr ""
|
|||
msgid "ComplianceFrameworks|Compliance framework created"
|
||||
msgstr ""
|
||||
|
||||
msgid "ComplianceFrameworks|Compliance frameworks applied to %{projectName}"
|
||||
msgstr ""
|
||||
|
||||
msgid "ComplianceFrameworks|Compliance frameworks that are linked to an active policy can't be deleted"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -13478,6 +13481,9 @@ msgstr ""
|
|||
msgid "ComplianceFrameworks|Linked"
|
||||
msgstr ""
|
||||
|
||||
msgid "ComplianceFrameworks|Multiple frameworks"
|
||||
msgstr ""
|
||||
|
||||
msgid "ComplianceFrameworks|Name"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -13601,6 +13607,9 @@ msgstr ""
|
|||
msgid "ComplianceReport|Create a new framework"
|
||||
msgstr ""
|
||||
|
||||
msgid "ComplianceReport|Dismiss"
|
||||
msgstr ""
|
||||
|
||||
msgid "ComplianceReport|Do you want to refresh the filtered results to include your change?"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -13622,6 +13631,9 @@ msgstr ""
|
|||
msgid "ComplianceReport|Less than 2 approvers"
|
||||
msgstr ""
|
||||
|
||||
msgid "ComplianceReport|Migrate pipeline to a policy"
|
||||
msgstr ""
|
||||
|
||||
msgid "ComplianceReport|No frameworks found"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -62091,9 +62103,6 @@ msgstr ""
|
|||
msgid "ciReport|Automatically apply the patch in a new branch"
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|Automatically opens a merge request with a solution generated by AI"
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|Browser Performance"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -62177,6 +62186,9 @@ msgstr ""
|
|||
msgid "ciReport|Dynamic Application Security Testing (DAST)"
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|Explain vulnerability"
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|Failed to load %{reportName} report"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -62299,6 +62311,12 @@ msgstr ""
|
|||
msgid "ciReport|This report contains all Code Quality issues in the source branch."
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|Use GitLab Duo AI to generate a merge request with a suggested solution"
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|Use GitLab Duo AI to provide insights about the vulnerability and suggested solutions"
|
||||
msgstr ""
|
||||
|
||||
msgid "ciReport|Used by %{packagesString}"
|
||||
msgid_plural "ciReport|Used by %{packagesString}, and %{lastPackage}"
|
||||
msgstr[0] ""
|
||||
|
|
|
|||
|
|
@ -349,14 +349,16 @@ module InternalEventsCli
|
|||
|
||||
cli.say <<~TEXT
|
||||
#{divider}
|
||||
#{format_help('# TERMINAL -- monitor events sent to snowplow & changes to service ping metrics as they occur')}
|
||||
#{format_help('# TERMINAL -- monitor events & changes to service ping metrics as they occur')}
|
||||
|
||||
1. Configure gdk with snowplow micro https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/snowplow_micro.md
|
||||
2. From `gitlab/` directory, run the monitor script:
|
||||
1. From `gitlab/` directory, run the monitor script:
|
||||
|
||||
#{format_warning("bin/rails runner scripts/internal_events/monitor.rb #{event.action}")}
|
||||
|
||||
3. View all snowplow events in the browser at http://localhost:9091/micro/all (or whichever hostname & port you configured)
|
||||
2. View metric updates within the terminal
|
||||
|
||||
3. [Optional] Configure gdk with snowplow micro to see individual events: https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/snowplow_micro.md
|
||||
|
||||
#{divider}
|
||||
#{format_help('# RAILS CONSOLE -- generate service ping payload, including most recent usage data')}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,17 @@ def generate_snowplow_table
|
|||
)
|
||||
end
|
||||
|
||||
def generate_snowplow_placeholder
|
||||
Terminal::Table.new(
|
||||
title: 'SNOWPLOW EVENTS',
|
||||
rows: [
|
||||
["Could not connect to Snowplow Micro."],
|
||||
["Please follow these instruction to set up Snowplow Micro:"],
|
||||
["https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/snowplow_micro.md"]
|
||||
]
|
||||
)
|
||||
end
|
||||
|
||||
def relevant_events_from_args(metric_definition)
|
||||
metric_definition.events.keys.intersection(ARGV).sort
|
||||
end
|
||||
|
|
@ -143,9 +154,9 @@ def generate_metrics_table
|
|||
)
|
||||
end
|
||||
|
||||
def render_screen(paused)
|
||||
def render_screen(paused, snowplow_available)
|
||||
metrics_table = generate_metrics_table
|
||||
events_table = generate_snowplow_table
|
||||
events_table = snowplow_available ? generate_snowplow_table : generate_snowplow_placeholder
|
||||
|
||||
print TTY::Cursor.clear_screen
|
||||
print TTY::Cursor.move_to(0, 0)
|
||||
|
|
@ -155,7 +166,6 @@ def render_screen(paused)
|
|||
puts
|
||||
|
||||
puts metrics_table
|
||||
|
||||
puts events_table
|
||||
|
||||
puts
|
||||
|
|
@ -163,13 +173,12 @@ def render_screen(paused)
|
|||
puts "Press \"q\" to quit"
|
||||
end
|
||||
|
||||
snowplow_available = true
|
||||
|
||||
begin
|
||||
snowplow_data
|
||||
rescue Errno::ECONNREFUSED
|
||||
puts "Could not connect to Snowplow Micro."
|
||||
puts "Please follow these instruction to set up Snowplow Micro:"
|
||||
puts "https://gitlab.com/gitlab-org/gitlab-development-kit/-/blob/main/doc/howto/snowplow_micro.md"
|
||||
exit 1
|
||||
snowplow_available = false
|
||||
end
|
||||
|
||||
reader = TTY::Reader.new
|
||||
|
|
@ -180,12 +189,12 @@ begin
|
|||
case reader.read_keypress(nonblock: true)
|
||||
when 'p'
|
||||
paused = !paused
|
||||
render_screen(paused)
|
||||
render_screen(paused, snowplow_available)
|
||||
when 'q'
|
||||
break
|
||||
end
|
||||
|
||||
render_screen(paused) unless paused
|
||||
render_screen(paused, snowplow_available) unless paused
|
||||
|
||||
sleep 1
|
||||
end
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe Layouts::SettingsBlockComponent, type: :component, feature_category: :shared do
|
||||
let(:heading) { 'Settings block heading' }
|
||||
let(:description) { 'Settings block description' }
|
||||
let(:body) { 'Settings block content' }
|
||||
let(:id) { 'settings-block-id' }
|
||||
|
||||
describe 'slots' do
|
||||
it 'renders heading' do
|
||||
render_inline described_class.new(heading)
|
||||
|
||||
expect(page).to have_css('h2.gl-heading-2', text: heading)
|
||||
end
|
||||
|
||||
it 'renders description' do
|
||||
render_inline described_class.new(heading, description: description)
|
||||
|
||||
expect(page).to have_css('.gl-text-secondary', text: description)
|
||||
end
|
||||
|
||||
it 'renders description slot' do
|
||||
render_inline described_class.new(heading) do |c|
|
||||
c.with_description { description }
|
||||
end
|
||||
|
||||
expect(page).to have_css('.gl-text-secondary', text: description)
|
||||
end
|
||||
|
||||
it 'renders body slot' do
|
||||
render_inline described_class.new(heading) do |c|
|
||||
c.with_body { body }
|
||||
end
|
||||
|
||||
expect(page).to have_css('.settings-content', text: body)
|
||||
end
|
||||
|
||||
it 'renders ids' do
|
||||
render_inline described_class.new(heading, id: id)
|
||||
|
||||
expect(page).to have_css('#js-settings-block-id')
|
||||
expect(page).to have_css('[data-testid="settings-block-id"]')
|
||||
end
|
||||
|
||||
it 'renders collapsed if not expanded' do
|
||||
render_inline described_class.new(heading, expanded: nil)
|
||||
|
||||
expect(page).to have_css('.js-settings-toggle', text: 'Expand')
|
||||
end
|
||||
|
||||
it 'renders expanded if expanded' do
|
||||
render_inline described_class.new(heading, expanded: true)
|
||||
|
||||
expect(page).to have_css('.settings.expanded')
|
||||
expect(page).to have_css('.js-settings-toggle', text: 'Collapse')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Layouts
|
||||
class SettingsBlockComponentPreview < ViewComponent::Preview
|
||||
# @param heading text
|
||||
# @param description text
|
||||
# @param body text
|
||||
# @param id text
|
||||
def default(
|
||||
heading: 'Settings block heading',
|
||||
description: 'Settings block description',
|
||||
body: 'Settings block content',
|
||||
id: 'settings-block-id'
|
||||
)
|
||||
render(::Layouts::SettingsBlockComponent.new(heading, description: description, id: id, expanded: nil)) do |c|
|
||||
c.with_description { description }
|
||||
c.with_body { body }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -407,7 +407,13 @@ RSpec.describe HelpController do
|
|||
describe 'GET #docs' do
|
||||
subject { get :redirect_to_docs }
|
||||
|
||||
before do
|
||||
stub_application_setting(help_page_documentation_base_url: custom_docs_url)
|
||||
end
|
||||
|
||||
context 'with no custom docs URL configured' do
|
||||
let(:custom_docs_url) { nil }
|
||||
|
||||
it 'redirects to docs.gitlab.com' do
|
||||
subject
|
||||
|
||||
|
|
@ -418,10 +424,6 @@ RSpec.describe HelpController do
|
|||
context 'with a custom docs URL configured' do
|
||||
let(:custom_docs_url) { 'https://foo.example.com' }
|
||||
|
||||
before do
|
||||
stub_application_setting(help_page_documentation_base_url: custom_docs_url)
|
||||
end
|
||||
|
||||
it 'redirects to the configured docs URL' do
|
||||
subject
|
||||
|
||||
|
|
|
|||
|
|
@ -773,6 +773,17 @@ describe('WorkItemDetail component', () => {
|
|||
|
||||
expect(findWorkItemDescription().props('editMode')).toBe(true);
|
||||
});
|
||||
|
||||
it('sticky header is visible by default', () => {
|
||||
expect(findStickyHeader().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('sticky header is not visible if is drawer view', async () => {
|
||||
createComponent({ isDrawer: true });
|
||||
await waitForPromises();
|
||||
|
||||
expect(findStickyHeader().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('edit button for work item title and description', () => {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::BackgroundMigration::BackfillVulnerabilityFindingSignaturesProjectId,
|
||||
feature_category: :vulnerability_management,
|
||||
schema: 20240619142930 do
|
||||
include_examples 'desired sharding key backfill job' do
|
||||
let(:batch_table) { :vulnerability_finding_signatures }
|
||||
let(:backfill_column) { :project_id }
|
||||
let(:backfill_via_table) { :vulnerability_occurrences }
|
||||
let(:backfill_via_column) { :project_id }
|
||||
let(:backfill_via_foreign_key) { :finding_id }
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe QueueBackfillVulnerabilityFindingSignaturesProjectId, feature_category: :vulnerability_management do
|
||||
let!(:batched_migration) { described_class::MIGRATION }
|
||||
|
||||
it 'schedules a new batched migration' do
|
||||
reversible_migration do |migration|
|
||||
migration.before -> {
|
||||
expect(batched_migration).not_to have_scheduled_batched_migration
|
||||
}
|
||||
|
||||
migration.after -> {
|
||||
expect(batched_migration).to have_scheduled_batched_migration(
|
||||
table_name: :vulnerability_finding_signatures,
|
||||
column_name: :id,
|
||||
interval: described_class::DELAY_INTERVAL,
|
||||
batch_size: described_class::BATCH_SIZE,
|
||||
sub_batch_size: described_class::SUB_BATCH_SIZE,
|
||||
gitlab_schema: :gitlab_main_cell,
|
||||
job_arguments: [
|
||||
:project_id,
|
||||
:vulnerability_occurrences,
|
||||
:project_id,
|
||||
:finding_id
|
||||
]
|
||||
)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1688,4 +1688,39 @@ RSpec.describe ApplicationSetting, feature_category: :shared, type: :model do
|
|||
it { is_expected.to validate_numericality_of(:asciidoc_max_includes).only_integer.is_greater_than_or_equal_to(0) }
|
||||
it { is_expected.to validate_numericality_of(:asciidoc_max_includes).only_integer.is_less_than_or_equal_to(64) }
|
||||
end
|
||||
|
||||
describe 'after_commit callback' do
|
||||
before do
|
||||
allow(setting).to receive(:reset_deletion_warning_redis_key)
|
||||
end
|
||||
|
||||
context 'when inactive_projects_delete_after_months changes' do
|
||||
it 'calls reset_deletion_warning_redis_key' do
|
||||
setting.update!(inactive_projects_delete_after_months: 6)
|
||||
expect(setting).to have_received(:reset_deletion_warning_redis_key)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when delete_inactive_projects changes from true to false' do
|
||||
it 'calls reset_deletion_warning_redis_key' do
|
||||
setting.update!(delete_inactive_projects: true)
|
||||
setting.update!(delete_inactive_projects: false)
|
||||
expect(setting).to have_received(:reset_deletion_warning_redis_key)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when delete_inactive_projects changes from false to true' do
|
||||
it 'does not call reset_deletion_warning_redis_key' do
|
||||
setting.update!(delete_inactive_projects: true)
|
||||
expect(setting).not_to have_received(:reset_deletion_warning_redis_key)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there are no relevant changes' do
|
||||
it 'does not call reset_deletion_warning_redis_key' do
|
||||
setting.update!(default_artifacts_expire_in: 30)
|
||||
expect(setting).not_to have_received(:reset_deletion_warning_redis_key)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
Loading…
Reference in New Issue