Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
5005c6e61f
commit
8968ab7b21
|
@ -1 +1 @@
|
||||||
65bddca7ed089abdc7869c0f500825f29bd5a89f
|
56aa9a2196f0003bc011e4152bb093b8d32be83d
|
||||||
|
|
|
@ -41,7 +41,7 @@ export default {
|
||||||
<template>
|
<template>
|
||||||
<a :href="mergeRequestHref" class="btn-link d-flex align-items-center">
|
<a :href="mergeRequestHref" class="btn-link d-flex align-items-center">
|
||||||
<span class="d-flex gl-mr-3 ide-search-list-current-icon">
|
<span class="d-flex gl-mr-3 ide-search-list-current-icon">
|
||||||
<gl-icon v-if="isActive" :size="18" name="mobile-issue-close" use-deprecated-sizes />
|
<gl-icon v-if="isActive" :size="16" name="mobile-issue-close" />
|
||||||
</span>
|
</span>
|
||||||
<span>
|
<span>
|
||||||
<strong> {{ item.title }} </strong>
|
<strong> {{ item.title }} </strong>
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
query getAlert($iid: String!, $fullPath: ID!) {
|
query getAlert($iid: String!, $fullPath: ID!) {
|
||||||
project(fullPath: $fullPath) {
|
project(fullPath: $fullPath) {
|
||||||
issue(iid: $iid) {
|
issue(iid: $iid) {
|
||||||
|
id
|
||||||
alertManagementAlert {
|
alertManagementAlert {
|
||||||
iid
|
iid
|
||||||
title
|
title
|
||||||
|
|
|
@ -186,6 +186,8 @@ export default {
|
||||||
:is="linkComponent"
|
:is="linkComponent"
|
||||||
ref="link"
|
ref="link"
|
||||||
v-gl-hover-load="handlePreload"
|
v-gl-hover-load="handlePreload"
|
||||||
|
v-gl-tooltip:tooltip-container
|
||||||
|
:title="fullPath"
|
||||||
:to="routerLinkTo"
|
:to="routerLinkTo"
|
||||||
:href="url"
|
:href="url"
|
||||||
:class="{
|
:class="{
|
||||||
|
|
|
@ -943,6 +943,41 @@ derived from the class name or namespace.
|
||||||
|
|
||||||
Be aware of the limitations [when using models in migrations](#using-models-in-migrations-discouraged).
|
Be aware of the limitations [when using models in migrations](#using-models-in-migrations-discouraged).
|
||||||
|
|
||||||
|
### Modifying existing data
|
||||||
|
|
||||||
|
In most circumstances, prefer migrating data in **batches** when modifying data in the database.
|
||||||
|
|
||||||
|
We introduced a new helper [each_batch_range](https://gitlab.com/gitlab-org/gitlab/-/blob/cd3e0a5cddcb464cb9b8c6e3275839cf57dfa6e2/lib/gitlab/database/dynamic_model_helpers.rb#L28-32) which facilitates the process of iterating over a collection in a performant way. The default size of the batch is defined in the `BATCH_SIZE` constant.
|
||||||
|
|
||||||
|
See the following example to get an idea.
|
||||||
|
|
||||||
|
**Purging data in batch:**
|
||||||
|
|
||||||
|
```ruby
|
||||||
|
include ::Gitlab::Database::DynamicModelHelpers
|
||||||
|
|
||||||
|
disable_ddl_transaction!
|
||||||
|
|
||||||
|
def up
|
||||||
|
each_batch_range('ci_pending_builds', scope: ->(table) { table.ref_protected }, of: BATCH_SIZE) do |min, max|
|
||||||
|
execute <<~SQL
|
||||||
|
DELETE FROM ci_pending_builds
|
||||||
|
USING ci_builds
|
||||||
|
WHERE ci_builds.id = ci_pending_builds.build_id
|
||||||
|
AND ci_builds.status != 'pending'
|
||||||
|
AND ci_builds.type = 'Ci::Build'
|
||||||
|
AND ci_pending_builds.id BETWEEN #{min} AND #{max}
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
- The first argument is the table being modified: `'ci_pending_builds'`.
|
||||||
|
- The second argument calls a lambda which fetches the relevant dataset selected (the default is set to `.all`): `scope: ->(table) { table.ref_protected }`.
|
||||||
|
- The third argument is the batch size (the default is set in the `BATCH_SIZE` constant): `of: BATCH_SIZE`.
|
||||||
|
|
||||||
|
Here is an [example MR](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62195) illustrating how to use our new helper.
|
||||||
|
|
||||||
### Renaming reserved paths
|
### Renaming reserved paths
|
||||||
|
|
||||||
When a new route for projects is introduced, it could conflict with any
|
When a new route for projects is introduced, it could conflict with any
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
module Gitlab
|
module Gitlab
|
||||||
module Database
|
module Database
|
||||||
module DynamicModelHelpers
|
module DynamicModelHelpers
|
||||||
|
BATCH_SIZE = 1_000
|
||||||
|
|
||||||
def define_batchable_model(table_name)
|
def define_batchable_model(table_name)
|
||||||
Class.new(ActiveRecord::Base) do
|
Class.new(ActiveRecord::Base) do
|
||||||
include EachBatch
|
include EachBatch
|
||||||
|
@ -12,7 +14,7 @@ module Gitlab
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def each_batch(table_name, scope: ->(table) { table.all }, of: 1000)
|
def each_batch(table_name, scope: ->(table) { table.all }, of: BATCH_SIZE)
|
||||||
if transaction_open?
|
if transaction_open?
|
||||||
raise <<~MSG.squish
|
raise <<~MSG.squish
|
||||||
each_batch should not run inside a transaction, you can disable
|
each_batch should not run inside a transaction, you can disable
|
||||||
|
@ -25,7 +27,7 @@ module Gitlab
|
||||||
.each_batch(of: of) { |batch| yield batch }
|
.each_batch(of: of) { |batch| yield batch }
|
||||||
end
|
end
|
||||||
|
|
||||||
def each_batch_range(table_name, scope: ->(table) { table.all }, of: 1000)
|
def each_batch_range(table_name, scope: ->(table) { table.all }, of: BATCH_SIZE)
|
||||||
each_batch(table_name, scope: scope, of: of) do |batch|
|
each_batch(table_name, scope: scope, of: of) do |batch|
|
||||||
yield batch.pluck('MIN(id), MAX(id)').first
|
yield batch.pluck('MIN(id), MAX(id)').first
|
||||||
end
|
end
|
||||||
|
|
|
@ -42,6 +42,7 @@ Migration/UpdateLargeTable:
|
||||||
- :user_details
|
- :user_details
|
||||||
- :vulnerability_occurrences
|
- :vulnerability_occurrences
|
||||||
- :web_hook_logs
|
- :web_hook_logs
|
||||||
|
- :vulnerabilities
|
||||||
DeniedMethods:
|
DeniedMethods:
|
||||||
- :change_column_type_concurrently
|
- :change_column_type_concurrently
|
||||||
- :rename_column_concurrently
|
- :rename_column_concurrently
|
||||||
|
|
|
@ -3,20 +3,57 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe 'Incident Detail', :js do
|
RSpec.describe 'Incident Detail', :js do
|
||||||
|
let_it_be(:project) { create(:project, :public) }
|
||||||
|
let_it_be(:payload) do
|
||||||
|
{
|
||||||
|
'title' => 'Alert title',
|
||||||
|
'start_time' => '2020-04-27T10:10:22.265949279Z',
|
||||||
|
'custom' => {
|
||||||
|
'alert' => {
|
||||||
|
'fields' => %w[one two]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'yet' => {
|
||||||
|
'another' => 73
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
let_it_be(:user) { create(:user) }
|
||||||
|
let_it_be(:started_at) { Time.now.rfc3339 }
|
||||||
|
let_it_be(:alert) { create(:alert_management_alert, project: project, payload: payload, started_at: started_at) }
|
||||||
|
let_it_be(:incident) { create(:incident, project: project, description: 'hello', alert_management_alert: alert) }
|
||||||
|
|
||||||
context 'when user displays the incident' do
|
context 'when user displays the incident' do
|
||||||
it 'shows the incident tabs' do
|
before do
|
||||||
project = create(:project, :public)
|
project.add_developer(user)
|
||||||
incident = create(:incident, project: project, description: 'hello')
|
sign_in(user)
|
||||||
|
|
||||||
visit project_issue_path(project, incident)
|
visit project_issue_path(project, incident)
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'shows incident and alert data' do
|
||||||
page.within('.issuable-details') do
|
page.within('.issuable-details') do
|
||||||
incident_tabs = find('[data-testid="incident-tabs"]')
|
incident_tabs = find('[data-testid="incident-tabs"]')
|
||||||
|
|
||||||
expect(find('h2')).to have_content(incident.title)
|
aggregate_failures 'shows title and Summary tab' do
|
||||||
expect(incident_tabs).to have_content('Summary')
|
expect(find('h2')).to have_content(incident.title)
|
||||||
expect(incident_tabs).to have_content(incident.description)
|
expect(incident_tabs).to have_content('Summary')
|
||||||
|
expect(incident_tabs).to have_content(incident.description)
|
||||||
|
end
|
||||||
|
|
||||||
|
aggregate_failures 'shows the incident highlight bar' do
|
||||||
|
expect(incident_tabs).to have_content('Alert events: 1')
|
||||||
|
expect(incident_tabs).to have_content('Original alert: #1')
|
||||||
|
end
|
||||||
|
|
||||||
|
aggregate_failures 'shows the Alert details tab' do
|
||||||
|
click_link 'Alert details'
|
||||||
|
|
||||||
|
expect(incident_tabs).to have_content('"title": "Alert title"')
|
||||||
|
expect(incident_tabs).to have_content('"yet.another": 73')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,6 +11,7 @@ exports[`Repository table row component renders a symlink table row 1`] = `
|
||||||
class="tree-item-link str-truncated"
|
class="tree-item-link str-truncated"
|
||||||
data-qa-selector="file_name_link"
|
data-qa-selector="file_name_link"
|
||||||
href="https://test.com"
|
href="https://test.com"
|
||||||
|
title="test"
|
||||||
>
|
>
|
||||||
<file-icon-stub
|
<file-icon-stub
|
||||||
class="mr-1 position-relative text-secondary"
|
class="mr-1 position-relative text-secondary"
|
||||||
|
@ -64,6 +65,7 @@ exports[`Repository table row component renders table row 1`] = `
|
||||||
class="tree-item-link str-truncated"
|
class="tree-item-link str-truncated"
|
||||||
data-qa-selector="file_name_link"
|
data-qa-selector="file_name_link"
|
||||||
href="https://test.com"
|
href="https://test.com"
|
||||||
|
title="test"
|
||||||
>
|
>
|
||||||
<file-icon-stub
|
<file-icon-stub
|
||||||
class="mr-1 position-relative text-secondary"
|
class="mr-1 position-relative text-secondary"
|
||||||
|
@ -117,6 +119,7 @@ exports[`Repository table row component renders table row for path with special
|
||||||
class="tree-item-link str-truncated"
|
class="tree-item-link str-truncated"
|
||||||
data-qa-selector="file_name_link"
|
data-qa-selector="file_name_link"
|
||||||
href="https://test.com"
|
href="https://test.com"
|
||||||
|
title="test"
|
||||||
>
|
>
|
||||||
<file-icon-stub
|
<file-icon-stub
|
||||||
class="mr-1 position-relative text-secondary"
|
class="mr-1 position-relative text-secondary"
|
||||||
|
|
Loading…
Reference in New Issue