Commit 2a53c24c authored by 🤖 GitLab Bot 🤖's avatar 🤖 GitLab Bot 🤖

Add latest changes from gitlab-org/[email protected]

parent 8e812185
......@@ -6,6 +6,7 @@ require_relative 'lib/gitlab/danger/request_helper'
danger.import_plugin('danger/plugins/helper.rb')
danger.import_plugin('danger/plugins/roulette.rb')
danger.import_plugin('danger/plugins/changelog.rb')
danger.import_plugin('danger/plugins/sidekiq_queues.rb')
return if helper.release_automation?
......
......@@ -64,6 +64,11 @@ export default {
type: Boolean,
required: true,
},
isDisabled: {
type: Boolean,
required: false,
default: false,
},
},
data() {
return {
......@@ -118,6 +123,9 @@ export default {
.then(() => {
this.activated = value;
this.loadingActivated = false;
if (value) {
window.location.reload();
}
})
.catch(() => {
createFlash(__('Update failed. Please try again.'));
......@@ -142,7 +150,7 @@ export default {
<gl-form-group :label="__('Active')" label-for="activated" label-class="label-bold">
<toggle-button
id="activated"
:disabled-input="loadingActivated"
:disabled-input="loadingActivated || isDisabled"
:is-loading="loadingActivated"
:value="activated"
@change="toggleActivated"
......@@ -152,7 +160,11 @@ export default {
<div class="input-group">
<gl-form-input id="url" :readonly="true" :value="url" />
<span class="input-group-append">
<clipboard-button :text="url" :title="$options.COPY_TO_CLIPBOARD" />
<clipboard-button
:text="url"
:title="$options.COPY_TO_CLIPBOARD"
:disabled="isDisabled"
/>
</span>
</div>
</gl-form-group>
......@@ -164,10 +176,16 @@ export default {
<div class="input-group">
<gl-form-input id="authorization-key" :readonly="true" :value="authorizationKey" />
<span class="input-group-append">
<clipboard-button :text="authorizationKey" :title="$options.COPY_TO_CLIPBOARD" />
<clipboard-button
:text="authorizationKey"
:title="$options.COPY_TO_CLIPBOARD"
:disabled="isDisabled"
/>
</span>
</div>
<gl-button v-gl-modal.authKeyModal class="mt-2">{{ $options.RESET_KEY }}</gl-button>
<gl-button v-gl-modal.authKeyModal class="mt-2" :disabled="isDisabled">{{
$options.RESET_KEY
}}</gl-button>
<gl-modal
modal-id="authKeyModal"
:title="$options.RESET_KEY"
......
......@@ -14,8 +14,11 @@ export default el => {
formPath,
authorizationKey,
url,
disabled,
} = el.dataset;
const activated = parseBoolean(activatedStr);
const isDisabled = parseBoolean(disabled);
return new Vue({
el,
......@@ -28,6 +31,7 @@ export default el => {
formPath,
initialAuthorizationKey: authorizationKey,
url,
isDisabled,
},
});
},
......
import mountErrorTrackingForm from '~/error_tracking_settings';
import initAlertsSettings from '~/alerts_service_settings';
import mountOperationSettings from '~/operation_settings';
import mountGrafanaIntegration from '~/grafana_integration';
import initSettingsPanels from '~/settings_panels';
......@@ -10,4 +11,5 @@ document.addEventListener('DOMContentLoaded', () => {
if (!IS_EE) {
initSettingsPanels();
}
initAlertsSettings(document.querySelector('.js-alerts-service-settings'));
});
......@@ -5,6 +5,7 @@ const PERSISTENT_USER_CALLOUTS = [
'.js-users-over-license-callout',
'.js-admin-licensed-user-count-threshold',
'.js-buy-pipeline-minutes-notification-callout',
'.js-alerts-moved-alert',
];
const initCallouts = () => {
......
......@@ -46,3 +46,8 @@
// Gitlab UI util classes
@import "@gitlab/ui/src/scss/utilities";
/* print styles */
@media print {
@import "print";
}
......@@ -11,7 +11,7 @@ module Projects
helper_method :error_tracking_setting
def show
render locals: { prometheus_service: prometheus_service }
render locals: { prometheus_service: prometheus_service, alerts_service: alerts_service }
end
def update
......@@ -52,6 +52,10 @@ module Projects
project.find_or_initialize_service(::PrometheusService.to_param)
end
def alerts_service
project.find_or_initialize_service(::AlertsService.to_param)
end
def render_update_response(result)
respond_to do |format|
format.html do
......
......@@ -7,6 +7,7 @@ module UserCalloutsHelper
SUGGEST_POPOVER_DISMISSED = 'suggest_popover_dismissed'
TABS_POSITION_HIGHLIGHT = 'tabs_position_highlight'
WEBHOOKS_MOVED = 'webhooks_moved'
ALERTS_MOVED = 'alerts_moved'
def show_admin_integrations_moved?
!user_dismissed?(ADMIN_INTEGRATIONS_MOVED)
......@@ -43,6 +44,10 @@ module UserCalloutsHelper
!user_dismissed?(WEBHOOKS_MOVED)
end
def show_alerts_moved_alert?
!user_dismissed?(ALERTS_MOVED)
end
private
def user_dismissed?(feature_name, ignore_dismissal_earlier_than = nil)
......
......@@ -79,6 +79,7 @@ class Namespace < ApplicationRecord
'COALESCE(SUM(ps.storage_size), 0) AS storage_size',
'COALESCE(SUM(ps.repository_size), 0) AS repository_size',
'COALESCE(SUM(ps.wiki_size), 0) AS wiki_size',
'COALESCE(SUM(ps.snippets_size), 0) AS snippets_size',
'COALESCE(SUM(ps.lfs_objects_size), 0) AS lfs_objects_size',
'COALESCE(SUM(ps.build_artifacts_size), 0) AS build_artifacts_size',
'COALESCE(SUM(ps.packages_size), 0) AS packages_size'
......
......@@ -7,15 +7,11 @@ class ProjectStatistics < ApplicationRecord
belongs_to :namespace
default_value_for :wiki_size, 0
# older migrations fail due to non-existent attribute without this
def wiki_size
has_attribute?(:wiki_size) ? super : 0
end
default_value_for :snippets_size, 0
before_save :update_storage_size
COLUMNS_TO_REFRESH = [:repository_size, :wiki_size, :lfs_objects_size, :commit_count].freeze
COLUMNS_TO_REFRESH = [:repository_size, :wiki_size, :lfs_objects_size, :commit_count, :snippets_size].freeze
INCREMENTABLE_COLUMNS = { build_artifacts_size: %i[storage_size], packages_size: %i[storage_size] }.freeze
NAMESPACE_RELATABLE_COLUMNS = [:repository_size, :wiki_size, :lfs_objects_size].freeze
......@@ -54,17 +50,32 @@ class ProjectStatistics < ApplicationRecord
self.wiki_size = project.wiki.repository.size * 1.megabyte
end
def update_snippets_size
self.snippets_size = project.snippets.with_statistics.sum(:repository_size)
end
def update_lfs_objects_size
self.lfs_objects_size = project.lfs_objects.sum(:size)
end
# older migrations fail due to non-existent attribute without this
def packages_size
has_attribute?(:packages_size) ? super : 0
# `wiki_size` and `snippets_size` have no default value in the database
# and the column can be nil.
# This means that, when the columns were added, all rows had nil
# values on them.
# Therefore, any call to any of those methods will return nil instead
# of 0, because `default_value_for` works with new records, not existing ones.
#
# These two methods provide consistency and avoid returning nil.
def wiki_size
super.to_i
end
def snippets_size
super.to_i
end
def update_storage_size
self.storage_size = repository_size + wiki_size.to_i + lfs_objects_size + build_artifacts_size + packages_size
self.storage_size = repository_size + wiki_size + lfs_objects_size + build_artifacts_size + packages_size + snippets_size
end
# Since this incremental update method does not call update_storage_size above,
......
......@@ -79,6 +79,7 @@ class Snippet < ApplicationRecord
scope :fresh, -> { order("created_at DESC") }
scope :inc_author, -> { includes(:author) }
scope :inc_relations_for_view, -> { includes(author: :status) }
scope :with_statistics, -> { joins(:statistics) }
attr_mentionable :description
......
......@@ -17,7 +17,8 @@ module UserCalloutEnums
suggest_popover_dismissed: 9,
tabs_position_highlight: 10,
webhooks_moved: 13,
admin_integrations_moved: 15
admin_integrations_moved: 15,
alerts_moved: 20
}
end
end
......
......@@ -53,7 +53,6 @@
= stylesheet_link_tag "application_dark", media: "all"
- else
= stylesheet_link_tag "application", media: "all"
= stylesheet_link_tag "print", media: "print"
= stylesheet_link_tag "disable_animations", media: "all" if Rails.env.test? || Gitlab.config.gitlab['disable_animations']
= stylesheet_link_tag 'performance_bar' if performance_bar_enabled?
......
- if lookup_context.template_exists?('top', "projects/services/#{@service.to_param}", true)
= render "projects/services/#{@service.to_param}/top"
.row.gl-mt-3.gl-mb-3
.col-lg-4
%h4.gl-mt-0
......@@ -12,7 +15,7 @@
.col-lg-8
= form_for(@service, as: :service, url: scoped_integration_path(@service), method: :put, html: { class: 'gl-show-field-errors integration-settings-form js-integration-settings-form', data: { 'can-test' => @service.can_test?, 'test-url' => test_project_service_path(@project, @service) } }) do |form|
= render 'shared/service_settings', form: form, integration: @service
.footer-block.row-content-block
.footer-block.row-content-block{ :class => "#{'gl-display-none' if @service.is_a?(AlertsService)}" }
%input{ id: 'services_redirect_to', type: 'hidden', name: 'redirect_to', value: request.referrer }
= service_save_button
&nbsp;
......
......@@ -2,5 +2,6 @@
form_path: scoped_integration_path(@service),
authorization_key: @service.token,
url: @service.url || _('<namespace / project>'),
disabled: 'true',
alerts_setup_url: help_page_path('user/project/integrations/generic_alerts.html', anchor: 'setting-up-generic-alerts'),
alerts_usage_url: help_page_path('user/project/operations/alert_management.html') } }
- return unless show_alerts_moved_alert?
.row
.col-lg-12
.gl-alert.gl-alert-info.js-alerts-moved-alert{ role: 'alert', data: { feature_id: UserCalloutsHelper::ALERTS_MOVED, dismiss_endpoint: user_callouts_path } }
= sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
%button.js-close.gl-alert-dismiss{ type: 'button', 'aria-label' => _('Dismiss') }
= sprite_icon('close', size: 16, css_class: 'gl-icon')
.gl-alert-body
= _('You can now manage alert endpoint configuration in the Alerts section on the Operations settings page. Fields on this page have been deprecated.')
.gl-alert-actions
= link_to _('Visit settings page'), project_settings_operations_path(@project), class: 'btn gl-alert-action btn-info new-gl-button'
- return unless can?(current_user, :admin_operations, @project)
%section.settings.no-animate.js-alert-management-settings
.settings-header
%h3{ :class => "h4" }
= _('Alerts')
%button.btn.js-settings-toggle{ type: 'button' }
= _('Expand')
%p
= _('Display alerts from all your monitoring tools directly within GitLab.')
= link_to _('More information'), help_page_path('user/project/operations/alert_management'), target: '_blank', rel: 'noopener noreferrer'
.settings-content
.js-alerts-service-settings{ data: { activated: service.activated?.to_s,
form_path: scoped_integration_path(service),
authorization_key: service.token,
url: service.url || _('<namespace / project>'),
alerts_setup_url: help_page_path('user/project/integrations/generic_alerts.html', anchor: 'setting-up-generic-alerts'),
alerts_usage_url: project_alert_management_index_path(@project) } }
......@@ -2,6 +2,7 @@
- page_title _('Operations Settings')
- breadcrumb_title _('Operations Settings')
= render 'projects/settings/operations/alert_management', service: alerts_service
= render 'projects/settings/operations/incidents'
= render 'projects/settings/operations/error_tracking'
= render 'projects/settings/operations/prometheus', service: prometheus_service if Feature.enabled?(:settings_operations_prometheus_service)
......
---
title: Create schema for static partitions
merge_request: 35268
author:
type: other
---
title: Move configuration for Alerts endpoint from "Settings > Integration" to "Settings > Operations > Alerts"
merge_request: 35187
author:
type: other
---
title: Include snippets size in project statistics
merge_request: 35120
author:
type: changed
---
title: Add migration for experimental product analytics table
merge_request: 35168
author:
type: added
# frozen_string_literal: true
require_relative '../../lib/gitlab/danger/sidekiq_queues'
module Danger
class SidekiqQueues < Plugin
# Put the helper code somewhere it can be tested
include Gitlab::Danger::SidekiqQueues
end
end
# frozen_string_literal: true
SCALABILITY_REVIEW_MESSAGE = <<~MSG
## Sidekiq queue changes
This merge request contains changes to Sidekiq queues. Please follow the [documentation on changing a queue's urgency](https://docs.gitlab.com/ee/development/sidekiq_style_guide.html#changing-a-queues-urgency).
MSG
ADDED_QUEUES_MESSAGE = <<~MSG
These queues were added:
MSG
CHANGED_QUEUES_MESSAGE = <<~MSG
These queues had their attributes changed:
MSG
if sidekiq_queues.added_queue_names.any? || sidekiq_queues.changed_queue_names.any?
markdown(SCALABILITY_REVIEW_MESSAGE)
if sidekiq_queues.added_queue_names.any?
markdown(ADDED_QUEUES_MESSAGE + helper.markdown_list(sidekiq_queues.added_queue_names))
end
if sidekiq_queues.changed_queue_names.any?
markdown(CHANGED_QUEUES_MESSAGE + helper.markdown_list(sidekiq_queues.changed_queue_names))
end
end
# frozen_string_literal: true
class CreateStaticPartitionsSchema < ActiveRecord::Migration[6.0]
include Gitlab::Database::SchemaHelpers
DOWNTIME = false
def up
execute 'CREATE SCHEMA gitlab_partitions_static'
create_comment(:schema, :gitlab_partitions_static, <<~EOS.strip)
Schema to hold static partitions, e.g. for hash partitioning
EOS
end
def down
execute 'DROP SCHEMA gitlab_partitions_static'
end
end
# frozen_string_literal: true
class AddProductAnalyticsTable < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
include Gitlab::Database::PartitioningMigrationHelpers::TableManagementHelpers
# Set this constant to true if this migration requires downtime.
DOWNTIME = false
# Table is based on https://github.com/snowplow/snowplow/blob/master/4-storage/postgres-storage/sql/atomic-def.sql 6e07b1c, with the following differences:
# * app_id varchar -> project_id integer (+ FK)
# * Add `id bigserial`
# * Hash partitioning based on `project_id`
# * Timestamp columns: Change type to timestamp with time zone
#
# This table is part of the "product analytics experiment" and as such marked "experimental". The goal here is to
# explore the product analytics as a MVP feature more. We are explicitly not spending time on relational modeling
# here.
#
# We expect significant changes to the database part of this once the feature has been validated.
# Therefore, we expect to drop the table when feature validation is complete. All data will be lost.
def up
with_lock_retries do
execute <<~SQL
CREATE TABLE "product_analytics_events_experimental" (
id bigserial NOT NULL,
-- App
"project_id" integer NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
"platform" varchar(255),
-- Date/time
"etl_tstamp" timestamp with time zone,
"collector_tstamp" timestamp with time zone NOT NULL,
"dvce_created_tstamp" timestamp with time zone,
-- Date/time
"event" varchar(128),
"event_id" char(36) NOT NULL,
"txn_id" integer,
-- Versioning
"name_tracker" varchar(128),
"v_tracker" varchar(100),
"v_collector" varchar(100) NOT NULL,
"v_etl" varchar(100) NOT NULL,
-- User and visit
"user_id" varchar(255),
"user_ipaddress" varchar(45),
"user_fingerprint" varchar(50),
"domain_userid" varchar(36),
"domain_sessionidx" smallint,
"network_userid" varchar(38),
-- Location
"geo_country" char(2),
"geo_region" char(3),
"geo_city" varchar(75),
"geo_zipcode" varchar(15),
"geo_latitude" double precision,
"geo_longitude" double precision,
"geo_region_name" varchar(100),
-- IP lookups
"ip_isp" varchar(100),
"ip_organization" varchar(100),
"ip_domain" varchar(100),
"ip_netspeed" varchar(100),
-- Page
"page_url" text,
"page_title" varchar(2000),
"page_referrer" text,
-- Page URL components
"page_urlscheme" varchar(16),
"page_urlhost" varchar(255),
"page_urlport" integer,
"page_urlpath" varchar(3000),
"page_urlquery" varchar(6000),
"page_urlfragment" varchar(3000),
-- Referrer URL components
"refr_urlscheme" varchar(16),
"refr_urlhost" varchar(255),
"refr_urlport" integer,
"refr_urlpath" varchar(6000),
"refr_urlquery" varchar(6000),
"refr_urlfragment" varchar(3000),
-- Referrer details
"refr_medium" varchar(25),
"refr_source" varchar(50),
"refr_term" varchar(255),
-- Marketing
"mkt_medium" varchar(255),
"mkt_source" varchar(255),
"mkt_term" varchar(255),
"mkt_content" varchar(500),
"mkt_campaign" varchar(255),
-- Custom structured event
"se_category" varchar(1000),
"se_action" varchar(1000),
"se_label" varchar(1000),
"se_property" varchar(1000),
"se_value" double precision,
-- Ecommerce
"tr_orderid" varchar(255),
"tr_affiliation" varchar(255),
"tr_total" decimal(18,2),
"tr_tax" decimal(18,2),
"tr_shipping" decimal(18,2),
"tr_city" varchar(255),
"tr_state" varchar(255),
"tr_country" varchar(255),
"ti_orderid" varchar(255),
"ti_sku" varchar(255),
"ti_name" varchar(255),
"ti_category" varchar(255),
"ti_price" decimal(18,2),
"ti_quantity" integer,
-- Page ping
"pp_xoffset_min" integer,
"pp_xoffset_max" integer,
"pp_yoffset_min" integer,
"pp_yoffset_max" integer,
-- User Agent
"useragent" varchar(1000),
-- Browser
"br_name" varchar(50),
"br_family" varchar(50),
"br_version" varchar(50),
"br_type" varchar(50),
"br_renderengine" varchar(50),
"br_lang" varchar(255),
"br_features_pdf" boolean,
"br_features_flash" boolean,
"br_features_java" boolean,
"br_features_director" boolean,
"br_features_quicktime" boolean,
"br_features_realplayer" boolean,
"br_features_windowsmedia" boolean,
"br_features_gears" boolean,
"br_features_silverlight" boolean,
"br_cookies" boolean,
"br_colordepth" varchar(12),
"br_viewwidth" integer,
"br_viewheight" integer,
-- Operating System
"os_name" varchar(50),
"os_family" varchar(50),
"os_manufacturer" varchar(50),
"os_timezone" varchar(50),
-- Device/Hardware
"dvce_type" varchar(50),
"dvce_ismobile" boolean,
"dvce_screenwidth" integer,
"dvce_screenheight" integer,
-- Document
"doc_charset" varchar(128),
"doc_width" integer,
"doc_height" integer,
-- Currency
"tr_currency" char(3),
"tr_total_base" decimal(18, 2),
"tr_tax_base" decimal(18, 2),
"tr_shipping_base" decimal(18, 2),
"ti_currency" char(3),
"ti_price_base" decimal(18, 2),
"base_currency" char(3),
-- Geolocation
"geo_timezone" varchar(64),
-- Click ID
"mkt_clickid" varchar(128),
"mkt_network" varchar(64),
-- ETL tags
"etl_tags" varchar(500),
-- Time event was sent
"dvce_sent_tstamp" timestamp with time zone,
-- Referer
"refr_domain_userid" varchar(36),
"refr_dvce_tstamp" timestamp with time zone,
-- Session ID
"domain_sessionid" char(36),
-- Derived timestamp
"derived_tstamp" timestamp with time zone,
-- Event schema
"event_vendor" varchar(1000),
"event_name" varchar(1000),
"event_format" varchar(128),
"event_version" varchar(128),
-- Event fingerprint
"event_fingerprint" varchar(128),
-- True timestamp
"true_tstamp" timestamp with time zone,
PRIMARY KEY (id, project_id)
) PARTITION BY HASH (project_id)
WITHOUT OIDS;
CREATE INDEX index_product_analytics_events_experimental_project_and_time ON product_analytics_events_experimental (project_id, collector_tstamp);
SQL
create_hash_partitions :product_analytics_events_experimental, 64
end
end
def down
with_lock_retries do
execute 'DROP TABLE product_analytics_events_experimental'
end
end
end
This diff is collapsed.
......@@ -56,9 +56,7 @@ From there, you can see the following actions:
- User sign-in via [Group SAML](../user/group/saml_sso/index.md)
- Permissions changes of a user assigned to a group
- Removed user from group
- Project imported in to group
- Project added to group and with which visibility level
- Project removed from group
- Project repository imported into group
- [Project shared with group](../user/project/members/share_project_with_groups.md)
and with which [permissions](../user/permissions.md)
- Removal of a previously shared group with a project
......@@ -80,7 +78,7 @@ To view a project's audit events, navigate to **Project > Settings > Audit Event
From there, you can see the following actions:
- Added or removed deploy keys
- Project created, deleted, renamed, moved(transferred), changed path
- Project created, deleted, renamed, moved (transferred), changed path
- Project changed visibility level
- User was added to project and with which [permissions](../user/permissions.md)
- Permission changes of a user assigned to a project
......
......@@ -491,6 +491,28 @@ GET /api/v4/projects/1/branches/my%2Fbranch/commits
GET /api/v4/projects/1/repository/tags/my%2Ftag
```
## Request Payload
API Requests can use parameters sent as [query strings](https://en.wikipedia.org/wiki/Query_string)
or as a [payload body](https://tools.ietf.org/html/draft-ietf-httpbis-p3-payload-14#section-3.2).
GET requests usually send a query string, while PUT/POST requests usually send the payload body:
- Query string:
```shell