Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
0c87da9375
commit
c44eade0d7
|
|
@ -39,7 +39,7 @@ dont-interrupt-me:
|
|||
<% if test_suite_prefix.nil? %>
|
||||
.base-rspec-predictive:
|
||||
extends:
|
||||
- .rspec-base-pg12
|
||||
- .rspec-base-pg13
|
||||
- .base-predictive
|
||||
variables:
|
||||
# We're using the FOSS one here because we want to exclude EE-only ones
|
||||
|
|
@ -98,7 +98,7 @@ rspec system predictive:
|
|||
<% if test_suite_prefix == 'ee/' %>
|
||||
.base-rspec-ee-predictive:
|
||||
extends:
|
||||
- .rspec-ee-base-pg12
|
||||
- .rspec-ee-base-pg13
|
||||
- .base-predictive
|
||||
variables:
|
||||
RSPEC_TESTS_FILTER_FILE: "${RSPEC_MATCHING_TESTS_EE_PATH}"
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ export default {
|
|||
<span class="note-headline-light note-headline-meta">
|
||||
<span class="system-note-message"> <slot></slot> </span>
|
||||
<gl-link
|
||||
class="note-timestamp system-note-separator gl-display-block gl-mb-2"
|
||||
class="note-timestamp system-note-separator gl-display-block gl-mb-2 gl-font-sm"
|
||||
:href="`#note_${noteAnchorId}`"
|
||||
>
|
||||
<time-ago-tooltip :time="note.createdAt" tooltip-placement="bottom" />
|
||||
|
|
|
|||
|
|
@ -39,31 +39,31 @@ export default {
|
|||
|
||||
<template>
|
||||
<li
|
||||
class="toggle-comments gl-bg-gray-50 gl-display-flex gl-align-items-center gl-py-3"
|
||||
class="toggle-comments gl-bg-gray-50 gl-display-flex gl-align-items-center gl-py-3 gl-min-h-8"
|
||||
:class="{ expanded: !collapsed }"
|
||||
data-testid="toggle-comments-wrapper"
|
||||
>
|
||||
<gl-icon :name="iconName" class="gl-ml-3" @click.stop="$emit('toggle')" />
|
||||
<gl-button
|
||||
variant="link"
|
||||
class="toggle-comments-button gl-ml-2 gl-mr-2"
|
||||
class="toggle-comments-button gl-ml-2 gl-mr-2 gl-font-sm!"
|
||||
@click.stop="$emit('toggle')"
|
||||
>
|
||||
{{ toggleText }}
|
||||
</gl-button>
|
||||
<template v-if="collapsed">
|
||||
<span class="gl-text-gray-500">{{ __('Last reply by') }}</span>
|
||||
<span class="gl-text-gray-500 gl-font-sm">{{ __('Last reply by') }}</span>
|
||||
<gl-link
|
||||
:href="lastReply.author.webUrl"
|
||||
target="_blank"
|
||||
class="link-inherit-color gl-text-body gl-text-decoration-none gl-font-weight-bold gl-ml-2 gl-mr-2"
|
||||
class="link-inherit-color gl-text-body gl-text-decoration-none gl-font-weight-bold gl-font-sm gl-ml-2 gl-mr-2"
|
||||
>
|
||||
{{ lastReply.author.name }}
|
||||
</gl-link>
|
||||
<time-ago-tooltip
|
||||
:time="lastReply.createdAt"
|
||||
tooltip-placement="bottom"
|
||||
class="gl-text-gray-500"
|
||||
class="gl-text-gray-500 gl-font-sm"
|
||||
/>
|
||||
</template>
|
||||
</li>
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ export const containsSensitiveToken = (message) => {
|
|||
{
|
||||
// eslint-disable-next-line @gitlab/require-i18n-strings
|
||||
name: 'Feed Token',
|
||||
regex: 'feed_token=[0-9a-zA-Z_-]{20}',
|
||||
regex: 'feed_token=((glft-)?[0-9a-zA-Z_-]{20}|glft-[a-h0-9]+-[0-9]+_)',
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ const PERSISTENT_USER_CALLOUTS = [
|
|||
'.js-eoa-bronze-plan-banner',
|
||||
'.js-security-newsletter-callout',
|
||||
'.js-approaching-seat-count-threshold',
|
||||
'.js-storage-enforcement-banner',
|
||||
'.js-storage-pre-enforcement-alert',
|
||||
'.js-user-over-limit-free-plan-alert',
|
||||
'.js-minute-limit-banner',
|
||||
'.js-submit-license-usage-data-banner',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
import iconUrl from 'leaflet/dist/images/marker-icon.png';
|
||||
import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png';
|
||||
import shadowUrl from 'leaflet/dist/images/marker-shadow.png';
|
||||
import { __ } from '~/locale';
|
||||
|
||||
export const RENDER_ERROR_MSG = __(
|
||||
'The map can not be displayed because there was an error loading the GeoJSON file.',
|
||||
);
|
||||
|
||||
export const OPEN_STREET_TILE_URL = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
|
||||
export const ICON_CONFIG = { iconUrl, iconRetinaUrl, shadowUrl };
|
||||
export const MAP_ATTRIBUTION = __('Map data from');
|
||||
export const OPEN_STREET_COPYRIGHT_LINK =
|
||||
'<a href="https://www.openstreetmap.org/copyright" target="_blank" rel="noopener noreferrer">OpenStreetMap</a>';
|
||||
|
||||
export const POPUP_CONTENT_TEMPLATE = `
|
||||
<div class="gl-pt-4">
|
||||
<% eachFunction(popupProperties, function(value, label) { %>
|
||||
<div>
|
||||
<strong><%- label %>:</strong> <span><%- value %></span>
|
||||
</div>
|
||||
<% }); %>
|
||||
</div>
|
||||
`;
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<script>
|
||||
import { createAlert } from '~/alert';
|
||||
import { RENDER_ERROR_MSG } from './constants';
|
||||
import { initLeafletMap } from './utils';
|
||||
|
||||
export default {
|
||||
props: {
|
||||
blob: {
|
||||
type: Object,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
hasError: false,
|
||||
loading: true,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
try {
|
||||
initLeafletMap(this.$refs.map, JSON.parse(this.blob.rawTextBlob));
|
||||
} catch (error) {
|
||||
createAlert({ message: RENDER_ERROR_MSG });
|
||||
this.hasError = true;
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="!hasError" ref="map" class="gl-h-100vh gl-z-index-0" data-testid="map"></div>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
import { map, tileLayer, geoJson, featureGroup, Icon } from 'leaflet';
|
||||
import { template, each } from 'lodash';
|
||||
import {
|
||||
OPEN_STREET_TILE_URL,
|
||||
MAP_ATTRIBUTION,
|
||||
OPEN_STREET_COPYRIGHT_LINK,
|
||||
ICON_CONFIG,
|
||||
POPUP_CONTENT_TEMPLATE,
|
||||
} from './constants';
|
||||
|
||||
const generateOpenStreetMapTiles = () => {
|
||||
const attribution = `${MAP_ATTRIBUTION} ${OPEN_STREET_COPYRIGHT_LINK}`;
|
||||
return tileLayer(OPEN_STREET_TILE_URL, { attribution });
|
||||
};
|
||||
|
||||
export const popupContent = (popupProperties) => {
|
||||
return template(POPUP_CONTENT_TEMPLATE)({
|
||||
eachFunction: each,
|
||||
popupProperties,
|
||||
});
|
||||
};
|
||||
|
||||
const loadGeoJsonGroupAndBounds = (geoJsonData) => {
|
||||
const layers = [];
|
||||
const geoJsonGroup = geoJson(geoJsonData, {
|
||||
onEachFeature: (feature, layer) => {
|
||||
layers.push(layer);
|
||||
if (feature.properties) {
|
||||
layer.bindPopup(popupContent(feature.properties));
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
return { geoJsonGroup, bounds: featureGroup(layers).getBounds() };
|
||||
};
|
||||
|
||||
export const initLeafletMap = (el, geoJsonData) => {
|
||||
if (!el || !geoJsonData) return;
|
||||
|
||||
import('leaflet/dist/leaflet.css');
|
||||
Icon.Default.mergeOptions(ICON_CONFIG);
|
||||
const leafletMap = map(el, { layers: [generateOpenStreetMapTiles()] });
|
||||
const { bounds, geoJsonGroup } = loadGeoJsonGroupAndBounds(geoJsonData);
|
||||
|
||||
geoJsonGroup.addTo(leafletMap);
|
||||
leafletMap.fitBounds(bounds);
|
||||
};
|
||||
|
|
@ -12,6 +12,7 @@ const viewers = {
|
|||
sketch: () => import('./sketch_viewer.vue'),
|
||||
notebook: () => import('./notebook_viewer.vue'),
|
||||
openapi: () => import('./openapi_viewer.vue'),
|
||||
geo_json: () => import('./geo_json/geo_json_viewer.vue'),
|
||||
};
|
||||
|
||||
export const loadViewer = (type, isUsingLfs) => {
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ $t-gray-a-16-design-pin: rgba($black, 0.16);
|
|||
}
|
||||
|
||||
.design-note-pin {
|
||||
margin-left: $gl-padding;
|
||||
margin-left: 9px;
|
||||
}
|
||||
|
||||
.design-discussion {
|
||||
|
|
@ -148,13 +148,13 @@ $t-gray-a-16-design-pin: rgba($black, 0.16);
|
|||
content: '';
|
||||
border-left: 1px solid var(--gray-100, $gray-100);
|
||||
position: absolute;
|
||||
left: 28px;
|
||||
left: 22px;
|
||||
top: -17px;
|
||||
height: 17px;
|
||||
}
|
||||
|
||||
.design-note {
|
||||
padding: $gl-padding;
|
||||
padding: $gl-padding-8;
|
||||
list-style: none;
|
||||
transition: background $gl-transition-duration-medium $general-hover-transition-curve;
|
||||
border-top-left-radius: $border-radius-default; // same border radius used by .bordered-box
|
||||
|
|
@ -170,7 +170,9 @@ $t-gray-a-16-design-pin: rgba($black, 0.16);
|
|||
}
|
||||
|
||||
.reply-wrapper {
|
||||
padding: $gl-padding;
|
||||
padding: $gl-padding-8 $gl-padding-8 $gl-padding-4;
|
||||
background: $gray-10;
|
||||
border-radius: 0 0 $border-radius-default $border-radius-default;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ class Blob < SimpleDelegator
|
|||
BlobViewer::Notebook,
|
||||
BlobViewer::SVG,
|
||||
BlobViewer::OpenApi,
|
||||
BlobViewer::GeoJson,
|
||||
|
||||
BlobViewer::Image,
|
||||
BlobViewer::Sketch,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module BlobViewer
|
||||
class GeoJson < Base
|
||||
include Rich
|
||||
include ClientSide
|
||||
|
||||
self.binary = false
|
||||
self.extensions = %w[geojson]
|
||||
self.partial_name = 'geo_json'
|
||||
end
|
||||
end
|
||||
|
|
@ -38,7 +38,7 @@ class Group < Namespace
|
|||
has_many :users, through: :group_members
|
||||
has_many :owners,
|
||||
-> { where(members: { access_level: Gitlab::Access::OWNER }) },
|
||||
through: :group_members,
|
||||
through: :all_group_members,
|
||||
source: :user
|
||||
|
||||
has_many :requesters, -> { where.not(requested_at: nil) }, dependent: :destroy, as: :source, class_name: 'GroupMember' # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
|
|
|||
|
|
@ -57,10 +57,14 @@ class User < ApplicationRecord
|
|||
|
||||
FORBIDDEN_SEARCH_STATES = %w(blocked banned ldap_blocked).freeze
|
||||
|
||||
INCOMING_MAIL_TOKEN_PREFIX = 'glimt-'
|
||||
FEED_TOKEN_PREFIX = 'glft-'
|
||||
|
||||
columns_changing_default :notified_of_own_activity
|
||||
|
||||
add_authentication_token_field :incoming_email_token, token_generator: -> { SecureRandom.hex.to_i(16).to_s(36) }
|
||||
add_authentication_token_field :feed_token
|
||||
# lib/tasks/tokens.rake needs to be updated when changing mail and feed tokens
|
||||
add_authentication_token_field :incoming_email_token, token_generator: -> { self.generate_incoming_mail_token }
|
||||
add_authentication_token_field :feed_token, format_with_prefix: :prefix_for_feed_token
|
||||
add_authentication_token_field :static_object_token, encrypted: :optional
|
||||
|
||||
attribute :admin, default: false
|
||||
|
|
@ -968,6 +972,10 @@ class User < ApplicationRecord
|
|||
def get_ids_by_ids_or_usernames(ids, usernames)
|
||||
by_ids_or_usernames(ids, usernames).pluck(:id)
|
||||
end
|
||||
|
||||
def generate_incoming_mail_token
|
||||
"#{INCOMING_MAIL_TOKEN_PREFIX}#{SecureRandom.hex.to_i(16).to_s(36)}"
|
||||
end
|
||||
end
|
||||
|
||||
#
|
||||
|
|
@ -2596,6 +2604,10 @@ class User < ApplicationRecord
|
|||
|
||||
Ci::NamespaceMirror.contains_traversal_ids(traversal_ids)
|
||||
end
|
||||
|
||||
def prefix_for_feed_token
|
||||
FEED_TOKEN_PREFIX
|
||||
end
|
||||
end
|
||||
|
||||
User.prepend_mod_with('User')
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
- project = @project.present(current_user: current_user)
|
||||
- ref = local_assigns[:ref] || @ref
|
||||
- expanded = params[:expanded].present?
|
||||
- if blob.rich_viewer
|
||||
-# If the blob has a RichViewer we preload the content except for GeoJSON since it is handled by Vue
|
||||
- if blob.rich_viewer && blob.extension != 'geojson'
|
||||
- add_page_startup_api_call local_assigns.fetch(:viewer_url) { url_for(safe_params.merge(viewer: blob.rich_viewer.type, format: :json)) }
|
||||
|
||||
.info-well.d-none.d-sm-block
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: merge_commit_diff_modes
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123501
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/415579
|
||||
milestone: '16.1'
|
||||
type: development
|
||||
group: group::source code
|
||||
default_enabled: false
|
||||
|
|
@ -40,7 +40,9 @@ else
|
|||
# https://gitlab.com/gitlab-org/gitlab/-/issues/369970
|
||||
/Passing an Active Record object to `\w+` directly is deprecated/,
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/410086
|
||||
/Using `return`, `break` or `throw` to exit a transaction block/
|
||||
/Using `return`, `break` or `throw` to exit a transaction block/,
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/414556
|
||||
/Merging .* no longer maintain both conditions, and will be replaced by the latter in Rails 7\.0/
|
||||
]
|
||||
|
||||
view_component_3_warnings = [
|
||||
|
|
|
|||
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ReplaceOldFkCiBuildPendingStatesToBuilds < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::MigrationHelpers::WraparoundAutovacuum
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
return unless should_run?
|
||||
return if new_foreign_key_exists?
|
||||
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists :ci_build_pending_states, :ci_builds,
|
||||
name: :fk_861cd17da3_p, reverse_lock_order: true
|
||||
|
||||
rename_constraint :ci_build_pending_states, :temp_fk_861cd17da3_p, :fk_861cd17da3_p
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
return unless should_run?
|
||||
return unless new_foreign_key_exists?
|
||||
|
||||
add_concurrent_foreign_key :ci_build_pending_states, :ci_builds,
|
||||
name: :temp_fk_861cd17da3_p,
|
||||
column: [:partition_id, :build_id],
|
||||
target_column: [:partition_id, :id],
|
||||
on_update: :cascade,
|
||||
on_delete: :cascade,
|
||||
validate: true,
|
||||
reverse_lock_order: true
|
||||
|
||||
switch_constraint_names :ci_build_pending_states, :fk_861cd17da3_p, :temp_fk_861cd17da3_p
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def should_run?
|
||||
can_execute_on?(:ci_build_pending_states, :ci_builds)
|
||||
end
|
||||
|
||||
def new_foreign_key_exists?
|
||||
foreign_key_exists?(:ci_build_pending_states, :p_ci_builds, name: :fk_861cd17da3_p)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ReplaceOldFkCiBuildTraceChunksToBuilds < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::MigrationHelpers::WraparoundAutovacuum
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
return unless should_run?
|
||||
return if new_foreign_key_exists?
|
||||
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists :ci_build_trace_chunks, :ci_builds,
|
||||
name: :fk_89e29fa5ee_p, reverse_lock_order: true
|
||||
|
||||
rename_constraint :ci_build_trace_chunks, :temp_fk_89e29fa5ee_p, :fk_89e29fa5ee_p
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
return unless should_run?
|
||||
return unless new_foreign_key_exists?
|
||||
|
||||
add_concurrent_foreign_key :ci_build_trace_chunks, :ci_builds,
|
||||
name: :temp_fk_89e29fa5ee_p,
|
||||
column: [:partition_id, :build_id],
|
||||
target_column: [:partition_id, :id],
|
||||
on_update: :cascade,
|
||||
on_delete: :cascade,
|
||||
validate: true,
|
||||
reverse_lock_order: true
|
||||
|
||||
switch_constraint_names :ci_build_trace_chunks, :fk_89e29fa5ee_p, :temp_fk_89e29fa5ee_p
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def should_run?
|
||||
can_execute_on?(:ci_build_trace_chunks, :ci_builds)
|
||||
end
|
||||
|
||||
def new_foreign_key_exists?
|
||||
foreign_key_exists?(:ci_build_trace_chunks, :p_ci_builds, name: :fk_89e29fa5ee_p)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ReplaceOldFkCiUnitTestFailuresToBuilds < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::MigrationHelpers::WraparoundAutovacuum
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
return unless should_run?
|
||||
return if new_foreign_key_exists?
|
||||
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists :ci_unit_test_failures, :ci_builds,
|
||||
name: :fk_9e0fc58930_p, reverse_lock_order: true
|
||||
|
||||
rename_constraint :ci_unit_test_failures, :temp_fk_9e0fc58930_p, :fk_9e0fc58930_p
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
return unless should_run?
|
||||
return unless new_foreign_key_exists?
|
||||
|
||||
add_concurrent_foreign_key :ci_unit_test_failures, :ci_builds,
|
||||
name: :temp_fk_9e0fc58930_p,
|
||||
column: [:partition_id, :build_id],
|
||||
target_column: [:partition_id, :id],
|
||||
on_update: :cascade,
|
||||
on_delete: :cascade,
|
||||
validate: true,
|
||||
reverse_lock_order: true
|
||||
|
||||
switch_constraint_names :ci_unit_test_failures, :fk_9e0fc58930_p, :temp_fk_9e0fc58930_p
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def should_run?
|
||||
can_execute_on?(:ci_unit_test_failures, :ci_builds)
|
||||
end
|
||||
|
||||
def new_foreign_key_exists?
|
||||
foreign_key_exists?(:ci_unit_test_failures, :p_ci_builds, name: :fk_9e0fc58930_p)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ReplaceOldFkCiSourcesPipelinesToBuilds < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::MigrationHelpers::WraparoundAutovacuum
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
return unless should_run?
|
||||
return if new_foreign_key_exists?
|
||||
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists :ci_sources_pipelines, :ci_builds,
|
||||
name: :fk_be5624bf37_p, reverse_lock_order: true
|
||||
|
||||
rename_constraint :ci_sources_pipelines, :temp_fk_be5624bf37_p, :fk_be5624bf37_p
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
return unless should_run?
|
||||
return unless new_foreign_key_exists?
|
||||
|
||||
add_concurrent_foreign_key :ci_sources_pipelines, :ci_builds,
|
||||
name: :temp_fk_be5624bf37_p,
|
||||
column: [:source_partition_id, :source_job_id],
|
||||
target_column: [:partition_id, :id],
|
||||
on_update: :cascade,
|
||||
on_delete: :cascade,
|
||||
validate: true,
|
||||
reverse_lock_order: true
|
||||
|
||||
switch_constraint_names :ci_sources_pipelines, :fk_be5624bf37_p, :temp_fk_be5624bf37_p
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def should_run?
|
||||
can_execute_on?(:ci_sources_pipelines, :ci_builds)
|
||||
end
|
||||
|
||||
def new_foreign_key_exists?
|
||||
foreign_key_exists?(:ci_sources_pipelines, :p_ci_builds, name: :fk_be5624bf37_p)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ReplaceOldFkCiResourcesToBuilds < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::MigrationHelpers::WraparoundAutovacuum
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
return unless should_run?
|
||||
return if new_foreign_key_exists?
|
||||
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists :ci_resources, :ci_builds,
|
||||
name: :fk_e169a8e3d5_p, reverse_lock_order: true
|
||||
|
||||
rename_constraint :ci_resources, :temp_fk_e169a8e3d5_p, :fk_e169a8e3d5_p
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
return unless should_run?
|
||||
return unless new_foreign_key_exists?
|
||||
|
||||
add_concurrent_foreign_key :ci_resources, :ci_builds,
|
||||
name: :temp_fk_e169a8e3d5_p,
|
||||
column: [:partition_id, :build_id],
|
||||
target_column: [:partition_id, :id],
|
||||
on_update: :cascade,
|
||||
on_delete: :nullify,
|
||||
validate: true,
|
||||
reverse_lock_order: true
|
||||
|
||||
switch_constraint_names :ci_resources, :fk_e169a8e3d5_p, :temp_fk_e169a8e3d5_p
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def should_run?
|
||||
can_execute_on?(:ci_resources, :ci_builds)
|
||||
end
|
||||
|
||||
def new_foreign_key_exists?
|
||||
foreign_key_exists?(:ci_resources, :p_ci_builds, name: :fk_e169a8e3d5_p)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ReplaceOldFkCiBuildReportResultsToBuilds < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::MigrationHelpers::WraparoundAutovacuum
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
return unless should_run?
|
||||
return if new_foreign_key_exists?
|
||||
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists :ci_build_report_results, :ci_builds,
|
||||
name: :fk_rails_16cb1ff064_p, reverse_lock_order: true
|
||||
|
||||
rename_constraint :ci_build_report_results, :temp_fk_rails_16cb1ff064_p, :fk_rails_16cb1ff064_p
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
return unless should_run?
|
||||
return unless new_foreign_key_exists?
|
||||
|
||||
add_concurrent_foreign_key :ci_build_report_results, :ci_builds,
|
||||
name: :temp_fk_rails_16cb1ff064_p,
|
||||
column: [:partition_id, :build_id],
|
||||
target_column: [:partition_id, :id],
|
||||
on_update: :cascade,
|
||||
on_delete: :cascade,
|
||||
validate: true,
|
||||
reverse_lock_order: true
|
||||
|
||||
switch_constraint_names :ci_build_report_results, :fk_rails_16cb1ff064_p, :temp_fk_rails_16cb1ff064_p
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def should_run?
|
||||
can_execute_on?(:ci_build_report_results, :ci_builds)
|
||||
end
|
||||
|
||||
def new_foreign_key_exists?
|
||||
foreign_key_exists?(:ci_build_report_results, :p_ci_builds, name: :fk_rails_16cb1ff064_p)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ReplaceOldFkCiBuildNeedsToBuilds < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::MigrationHelpers::WraparoundAutovacuum
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
return unless should_run?
|
||||
return if new_foreign_key_exists?
|
||||
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists :ci_build_needs, :ci_builds,
|
||||
name: :fk_rails_3cf221d4ed_p, reverse_lock_order: true
|
||||
|
||||
rename_constraint :ci_build_needs, :temp_fk_rails_3cf221d4ed_p, :fk_rails_3cf221d4ed_p
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
return unless should_run?
|
||||
return unless new_foreign_key_exists?
|
||||
|
||||
add_concurrent_foreign_key :ci_build_needs, :ci_builds,
|
||||
name: :temp_fk_rails_3cf221d4ed_p,
|
||||
column: [:partition_id, :build_id],
|
||||
target_column: [:partition_id, :id],
|
||||
on_update: :cascade,
|
||||
on_delete: :cascade,
|
||||
validate: true,
|
||||
reverse_lock_order: true
|
||||
|
||||
switch_constraint_names :ci_build_needs, :fk_rails_3cf221d4ed_p, :temp_fk_rails_3cf221d4ed_p
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def should_run?
|
||||
can_execute_on?(:ci_build_needs, :ci_builds)
|
||||
end
|
||||
|
||||
def new_foreign_key_exists?
|
||||
foreign_key_exists?(:ci_build_needs, :p_ci_builds, name: :fk_rails_3cf221d4ed_p)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ReplaceOldFkCiBuildsRunnerSessionToBuilds < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::MigrationHelpers::WraparoundAutovacuum
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
return unless should_run?
|
||||
return if new_foreign_key_exists?
|
||||
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists :ci_builds_runner_session, :ci_builds,
|
||||
name: :fk_rails_70707857d3_p, reverse_lock_order: true
|
||||
|
||||
rename_constraint :ci_builds_runner_session, :temp_fk_rails_70707857d3_p, :fk_rails_70707857d3_p
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
return unless should_run?
|
||||
return unless new_foreign_key_exists?
|
||||
|
||||
add_concurrent_foreign_key :ci_builds_runner_session, :ci_builds,
|
||||
name: :temp_fk_rails_70707857d3_p,
|
||||
column: [:partition_id, :build_id],
|
||||
target_column: [:partition_id, :id],
|
||||
on_update: :cascade,
|
||||
on_delete: :cascade,
|
||||
validate: true,
|
||||
reverse_lock_order: true
|
||||
|
||||
switch_constraint_names :ci_builds_runner_session, :fk_rails_70707857d3_p, :temp_fk_rails_70707857d3_p
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def should_run?
|
||||
can_execute_on?(:ci_builds_runner_session, :ci_builds)
|
||||
end
|
||||
|
||||
def new_foreign_key_exists?
|
||||
foreign_key_exists?(:ci_builds_runner_session, :p_ci_builds, name: :fk_rails_70707857d3_p)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ReplaceOldFkCiPendingBuildsToBuilds < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::MigrationHelpers::WraparoundAutovacuum
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
return unless should_run?
|
||||
return if new_foreign_key_exists?
|
||||
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists :ci_pending_builds, :ci_builds,
|
||||
name: :fk_rails_725a2644a3_p, reverse_lock_order: true
|
||||
|
||||
rename_constraint :ci_pending_builds, :temp_fk_rails_725a2644a3_p, :fk_rails_725a2644a3_p
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
return unless should_run?
|
||||
return unless new_foreign_key_exists?
|
||||
|
||||
add_concurrent_foreign_key :ci_pending_builds, :ci_builds,
|
||||
name: :temp_fk_rails_725a2644a3_p,
|
||||
column: [:partition_id, :build_id],
|
||||
target_column: [:partition_id, :id],
|
||||
on_update: :cascade,
|
||||
on_delete: :cascade,
|
||||
validate: true,
|
||||
reverse_lock_order: true
|
||||
|
||||
switch_constraint_names :ci_pending_builds, :fk_rails_725a2644a3_p, :temp_fk_rails_725a2644a3_p
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def should_run?
|
||||
can_execute_on?(:ci_pending_builds, :ci_builds)
|
||||
end
|
||||
|
||||
def new_foreign_key_exists?
|
||||
foreign_key_exists?(:ci_pending_builds, :p_ci_builds, name: :fk_rails_725a2644a3_p)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ReplaceOldFkCiBuildTraceMetadataToBuilds < Gitlab::Database::Migration[2.1]
|
||||
include Gitlab::Database::MigrationHelpers::WraparoundAutovacuum
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
return unless should_run?
|
||||
return if new_foreign_key_exists?
|
||||
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists :ci_build_trace_metadata, :ci_builds,
|
||||
name: :fk_rails_aebc78111f_p, reverse_lock_order: true
|
||||
|
||||
rename_constraint :ci_build_trace_metadata, :temp_fk_rails_aebc78111f_p, :fk_rails_aebc78111f_p
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
return unless should_run?
|
||||
return unless new_foreign_key_exists?
|
||||
|
||||
add_concurrent_foreign_key :ci_build_trace_metadata, :ci_builds,
|
||||
name: :temp_fk_rails_aebc78111f_p,
|
||||
column: [:partition_id, :build_id],
|
||||
target_column: [:partition_id, :id],
|
||||
on_update: :cascade,
|
||||
on_delete: :cascade,
|
||||
validate: true,
|
||||
reverse_lock_order: true
|
||||
|
||||
switch_constraint_names :ci_build_trace_metadata, :fk_rails_aebc78111f_p, :temp_fk_rails_aebc78111f_p
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def should_run?
|
||||
can_execute_on?(:ci_build_trace_metadata, :ci_builds)
|
||||
end
|
||||
|
||||
def new_foreign_key_exists?
|
||||
foreign_key_exists?(:ci_build_trace_metadata, :p_ci_builds, name: :fk_rails_aebc78111f_p)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class PrepareIndexIssuesOnProjectHealthStatusAscWorkItemType < Gitlab::Database::Migration[2.1]
|
||||
INDEX_NAME = 'index_issues_on_project_health_status_asc_work_item_type'
|
||||
|
||||
def up
|
||||
prepare_async_index :issues,
|
||||
[:project_id, :health_status, :id, :state_id, :work_item_type_id],
|
||||
order: { health_status: 'ASC NULLS LAST', id: :desc },
|
||||
name: INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
unprepare_async_index :issues, INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class PrepareIndexIssuesOnProjectHealthStatusDescWorkItemType < Gitlab::Database::Migration[2.1]
|
||||
INDEX_NAME = 'index_issues_on_project_health_status_desc_work_item_type'
|
||||
|
||||
def up
|
||||
prepare_async_index :issues,
|
||||
[:project_id, :health_status, :id, :state_id, :work_item_type_id],
|
||||
order: { health_status: 'DESC NULLS LAST', id: :desc },
|
||||
name: INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
unprepare_async_index :issues, INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
a65e4718899a9339ef47da715f1fe48e20142b634bb95b0db70d2e4b6c5cc103
|
||||
|
|
@ -0,0 +1 @@
|
|||
e5ba43d180f8761c1892541ab4ca38c178bd3768f5ca0b9cfa977309306d600f
|
||||
|
|
@ -0,0 +1 @@
|
|||
96ad4cbf0debff7b289fa59b4af6164cd06226972ba55fbe696ad0e4c73eea0e
|
||||
|
|
@ -0,0 +1 @@
|
|||
c9e40d4c7d14b0914d520a8b425a8805e25e43beaea9b9a21a76e94c77431f79
|
||||
|
|
@ -0,0 +1 @@
|
|||
694a5369b0d8536402e0fe1091413bd20f978035fa0f2ba0487d5287ffc6fe19
|
||||
|
|
@ -0,0 +1 @@
|
|||
c871540f13d8d0ee7945ff1dd625ace59ec2b1f0907701ba7ff62d411bd51dac
|
||||
|
|
@ -0,0 +1 @@
|
|||
5eb86fcc023323c515964827c44052b5b6d8b6b216b3ccbde8b2e2033fd72180
|
||||
|
|
@ -0,0 +1 @@
|
|||
86407b35a175581e639e9e7d537e5655a80cf998f7c46e17b011b4f0241ffd5c
|
||||
|
|
@ -0,0 +1 @@
|
|||
0bfa09f5e8290de7dc2931b1ef6f5259653619cb4a722a04dc58c3c98eb523e4
|
||||
|
|
@ -0,0 +1 @@
|
|||
c18fe1c9744ebb939972f561f1de88afafedd0bba61b190d5fce4df25bd2d9f7
|
||||
|
|
@ -0,0 +1 @@
|
|||
99ecaa37e4b47b15fafb593e9af6bcf37f393dd10ecfdbd11a196c4700ab9571
|
||||
|
|
@ -0,0 +1 @@
|
|||
eb2627c95cf579d4c8a0eaa239093b0b3badbf666c257425bcb5d5a47cbf7d87
|
||||
|
|
@ -35642,7 +35642,7 @@ ALTER TABLE ONLY requirements
|
|||
ADD CONSTRAINT fk_85044baef0 FOREIGN KEY (issue_id) REFERENCES issues(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_build_pending_states
|
||||
ADD CONSTRAINT fk_861cd17da3_p FOREIGN KEY (partition_id, build_id) REFERENCES ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
ADD CONSTRAINT fk_861cd17da3_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY geo_event_log
|
||||
ADD CONSTRAINT fk_86c84214ec FOREIGN KEY (repository_renamed_event_id) REFERENCES geo_repository_renamed_events(id) ON DELETE CASCADE;
|
||||
|
|
@ -35666,7 +35666,7 @@ ALTER TABLE ONLY issues
|
|||
ADD CONSTRAINT fk_899c8f3231 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_build_trace_chunks
|
||||
ADD CONSTRAINT fk_89e29fa5ee_p FOREIGN KEY (partition_id, build_id) REFERENCES ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
ADD CONSTRAINT fk_89e29fa5ee_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY sbom_vulnerable_component_versions
|
||||
ADD CONSTRAINT fk_8a2a1197f9 FOREIGN KEY (sbom_component_version_id) REFERENCES sbom_component_versions(id) ON DELETE CASCADE;
|
||||
|
|
@ -35735,7 +35735,7 @@ ALTER TABLE ONLY user_group_callouts
|
|||
ADD CONSTRAINT fk_9dc8b9d4b2 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_unit_test_failures
|
||||
ADD CONSTRAINT fk_9e0fc58930_p FOREIGN KEY (partition_id, build_id) REFERENCES ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
ADD CONSTRAINT fk_9e0fc58930_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY protected_environments
|
||||
ADD CONSTRAINT fk_9e112565b7 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
|
@ -35894,7 +35894,7 @@ ALTER TABLE ONLY snippets
|
|||
ADD CONSTRAINT fk_be41fd4bb7 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_sources_pipelines
|
||||
ADD CONSTRAINT fk_be5624bf37_p FOREIGN KEY (source_partition_id, source_job_id) REFERENCES ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
ADD CONSTRAINT fk_be5624bf37_p FOREIGN KEY (source_partition_id, source_job_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY packages_maven_metadata
|
||||
ADD CONSTRAINT fk_be88aed360 FOREIGN KEY (package_id) REFERENCES packages_packages(id) ON DELETE CASCADE;
|
||||
|
|
@ -36053,7 +36053,7 @@ ALTER TABLE ONLY approval_project_rules
|
|||
ADD CONSTRAINT fk_e1372c912e FOREIGN KEY (scan_result_policy_id) REFERENCES scan_result_policies(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_resources
|
||||
ADD CONSTRAINT fk_e169a8e3d5_p FOREIGN KEY (partition_id, build_id) REFERENCES ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE SET NULL;
|
||||
ADD CONSTRAINT fk_e169a8e3d5_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE ONLY ci_sources_pipelines
|
||||
ADD CONSTRAINT fk_e1bad85861 FOREIGN KEY (pipeline_id) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
|
||||
|
|
@ -36347,7 +36347,7 @@ ALTER TABLE ONLY users_security_dashboard_projects
|
|||
ADD CONSTRAINT fk_rails_150cd5682c FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_build_report_results
|
||||
ADD CONSTRAINT fk_rails_16cb1ff064_p FOREIGN KEY (partition_id, build_id) REFERENCES ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
ADD CONSTRAINT fk_rails_16cb1ff064_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY catalog_resources
|
||||
ADD CONSTRAINT fk_rails_16f09e5c44 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
|
@ -36605,7 +36605,7 @@ ALTER TABLE ONLY chat_teams
|
|||
ADD CONSTRAINT fk_rails_3b543909cb FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_build_needs
|
||||
ADD CONSTRAINT fk_rails_3cf221d4ed_p FOREIGN KEY (partition_id, build_id) REFERENCES ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
ADD CONSTRAINT fk_rails_3cf221d4ed_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY cluster_groups
|
||||
ADD CONSTRAINT fk_rails_3d28377556 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
|
@ -36959,7 +36959,7 @@ ALTER TABLE ONLY analytics_dashboards_pointers
|
|||
ADD CONSTRAINT fk_rails_7027b7eaa9 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_builds_runner_session
|
||||
ADD CONSTRAINT fk_rails_70707857d3_p FOREIGN KEY (partition_id, build_id) REFERENCES ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
ADD CONSTRAINT fk_rails_70707857d3_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY list_user_preferences
|
||||
ADD CONSTRAINT fk_rails_70b2ef5ce2 FOREIGN KEY (list_id) REFERENCES lists(id) ON DELETE CASCADE;
|
||||
|
|
@ -36968,7 +36968,7 @@ ALTER TABLE ONLY project_custom_attributes
|
|||
ADD CONSTRAINT fk_rails_719c3dccc5 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_pending_builds
|
||||
ADD CONSTRAINT fk_rails_725a2644a3_p FOREIGN KEY (partition_id, build_id) REFERENCES ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
ADD CONSTRAINT fk_rails_725a2644a3_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE security_findings
|
||||
ADD CONSTRAINT fk_rails_729b763a54 FOREIGN KEY (scanner_id) REFERENCES vulnerability_scanners(id) ON DELETE CASCADE;
|
||||
|
|
@ -37370,7 +37370,7 @@ ALTER TABLE ONLY metrics_dashboard_annotations
|
|||
ADD CONSTRAINT fk_rails_aeb11a7643 FOREIGN KEY (environment_id) REFERENCES environments(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_build_trace_metadata
|
||||
ADD CONSTRAINT fk_rails_aebc78111f_p FOREIGN KEY (partition_id, build_id) REFERENCES ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
ADD CONSTRAINT fk_rails_aebc78111f_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY bulk_import_trackers
|
||||
ADD CONSTRAINT fk_rails_aed566d3f3 FOREIGN KEY (bulk_import_entity_id) REFERENCES bulk_import_entities(id) ON DELETE CASCADE;
|
||||
|
|
@ -37942,39 +37942,9 @@ ALTER TABLE issue_search_data
|
|||
ALTER TABLE product_analytics_events_experimental
|
||||
ADD CONSTRAINT product_analytics_events_experimental_project_id_fkey FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_build_pending_states
|
||||
ADD CONSTRAINT temp_fk_861cd17da3_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_build_trace_chunks
|
||||
ADD CONSTRAINT temp_fk_89e29fa5ee_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_unit_test_failures
|
||||
ADD CONSTRAINT temp_fk_9e0fc58930_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_sources_pipelines
|
||||
ADD CONSTRAINT temp_fk_be5624bf37_p FOREIGN KEY (source_partition_id, source_job_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_resources
|
||||
ADD CONSTRAINT temp_fk_e169a8e3d5_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE ONLY ci_builds_metadata
|
||||
ADD CONSTRAINT temp_fk_e20479742e_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID;
|
||||
|
||||
ALTER TABLE ONLY ci_build_report_results
|
||||
ADD CONSTRAINT temp_fk_rails_16cb1ff064_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_build_needs
|
||||
ADD CONSTRAINT temp_fk_rails_3cf221d4ed_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_builds_runner_session
|
||||
ADD CONSTRAINT temp_fk_rails_70707857d3_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_pending_builds
|
||||
ADD CONSTRAINT temp_fk_rails_725a2644a3_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_build_trace_metadata
|
||||
ADD CONSTRAINT temp_fk_rails_aebc78111f_p FOREIGN KEY (partition_id, build_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_job_artifacts
|
||||
ADD CONSTRAINT temp_fk_rails_c5137cb2c1_p FOREIGN KEY (partition_id, job_id) REFERENCES p_ci_builds(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE NOT VALID;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ Review apps:
|
|||
|
||||
- Provide an automatic live preview of changes made in a feature branch by spinning up a dynamic environment for your merge requests.
|
||||
- Allow designers and product managers to see your changes without needing to check out your branch and run your changes in a sandbox environment.
|
||||
- Are fully integrated with the [GitLab DevOps LifeCycle](../../index.md#the-entire-devops-lifecycle).
|
||||
- Are fully integrated with the [GitLab DevOps LifeCycle](https://about.gitlab.com/stages-devops-lifecycle/).
|
||||
- Allow you to deploy your changes wherever you want.
|
||||
|
||||

|
||||
|
|
|
|||
|
|
@ -56,44 +56,66 @@ in the directory `lib/gitlab/background_migration/`.
|
|||
|
||||
### Execution mechanism
|
||||
|
||||
After being enqueued, batched background migrations are picked in sequential order by a Sidekiq worker.
|
||||
At this point, batched jobs are created - or retried and iterate over a range of records that are fetched based
|
||||
on the configuration defined inside the migration class. Each job instance receives a set of
|
||||
arguments based on this migration configuration. After each job execution, the optimization mechanism takes
|
||||
place to decide if the migration can be optimized.
|
||||
Batched background migrations are picked from the queue in the order they are enqueued. Multiple migrations are fetched
|
||||
and executed in parallel, as long they are in active state and do not target the same database table.
|
||||
The default number of migrations processed in parallel is 2, for GitLab.com this limit is configured to 4.
|
||||
Once migration is picked for execution, a job is created for the specific batch. After each job execution, migration's
|
||||
batch size may be increased or decreased, based on the performance of the last 20 jobs.
|
||||
|
||||
```plantuml
|
||||
@startuml
|
||||
hide empty description
|
||||
skinparam ConditionEndStyle hline
|
||||
start
|
||||
rectangle Queue {
|
||||
:Migration Three;
|
||||
note right: Waiting for Migration Two
|
||||
:Migration Two;
|
||||
note right: Waiting for Migration One
|
||||
left to right direction
|
||||
rectangle "Batched Background Migration Queue" as migrations {
|
||||
rectangle "Migration N (active)" as migrationn
|
||||
rectangle "Migration 1 (completed)" as migration1
|
||||
rectangle "Migration 2 (active)" as migration2
|
||||
rectangle "Migration 3 (on hold)" as migration3
|
||||
rectangle "Migration 4 (active)" as migration4
|
||||
migration1 -[hidden]> migration2
|
||||
migration2 -[hidden]> migration3
|
||||
migration3 -[hidden]> migration4
|
||||
migration4 -[hidden]> migrationn
|
||||
}
|
||||
rectangle "Execution Workers" as workers {
|
||||
rectangle "Execution Worker 1 (busy)" as worker1
|
||||
rectangle "Execution Worker 2 (available)" as worker2
|
||||
worker1 -[hidden]> worker2
|
||||
}
|
||||
migration2 --> [Scheduling Worker]
|
||||
migration4 --> [Scheduling Worker]
|
||||
[Scheduling Worker] --> worker2
|
||||
@enduml
|
||||
```
|
||||
|
||||
Soon as a worker is available, the BBM is processed by the runner.
|
||||
|
||||
```plantuml
|
||||
@startuml
|
||||
hide empty description
|
||||
start
|
||||
rectangle Runner {
|
||||
:Migration One;
|
||||
note right: Active migration
|
||||
if (Still have records to migrate?) then (Yes)
|
||||
if (Have a pending batched job?) then (Yes)
|
||||
:Retry batched job;
|
||||
:Migration;
|
||||
if (Have reached batching bounds?) then (Yes)
|
||||
if (Have jobs to retry?) then (Yes)
|
||||
:Fetch the batched job;
|
||||
else (No)
|
||||
:Create a batched job;
|
||||
endif
|
||||
:Evaluate DB health;
|
||||
note right: Table autovacuum, Patroni Apdex, Write-ahead logging
|
||||
if (Evaluation signs to stop?) then (Yes)
|
||||
:Put migration on hold;
|
||||
else (No)
|
||||
:Optimize migration;
|
||||
:Finish active migration;
|
||||
stop
|
||||
endif
|
||||
else (No)
|
||||
:Finish active migration;
|
||||
:Create a batched job;
|
||||
endif
|
||||
:Execute batched job;
|
||||
:Evaluate DB health;
|
||||
note right: Checks for table autovacuum, Patroni Apdex, Write-ahead logging
|
||||
if (Evaluation signs to stop?) then (Yes)
|
||||
:Put migration on hold;
|
||||
else (No)
|
||||
:Optimize migration;
|
||||
endif
|
||||
}
|
||||
stop
|
||||
@enduml
|
||||
```
|
||||
|
||||
|
|
@ -161,13 +183,16 @@ the migration as `failed`) if any of the following is true:
|
|||
|
||||
Because batched migrations are update heavy and there were few incidents in the past because of the heavy load from migrations while the database was underperforming, a throttling mechanism exists to mitigate them.
|
||||
|
||||
These database indicators are checked to throttle a migration. On getting a stop signal, the migration is paused for a set time (10 minutes):
|
||||
These database indicators are checked to throttle a migration. On getting a
|
||||
stop signal, the migration is paused for a set time (10 minutes):
|
||||
|
||||
- WAL queue pending archival crossing a threshold.
|
||||
- Active autovacuum on the tables on which the migration works on.
|
||||
- Patroni apdex SLI dropping below the SLO.
|
||||
|
||||
It's an ongoing effort to add more indicators to further enhance the database health check framework, more details can be found in this [epic](https://gitlab.com/groups/gitlab-org/-/epics/7594).
|
||||
It's an ongoing effort to add more indicators to further enhance the
|
||||
database health check framework. For more details, see
|
||||
[epic 7594](https://gitlab.com/groups/gitlab-org/-/epics/7594).
|
||||
|
||||
### Isolation
|
||||
|
||||
|
|
@ -348,21 +373,6 @@ class CopyColumnUsingBackgroundMigrationJob < BatchedMigrationJob
|
|||
end
|
||||
```
|
||||
|
||||
## Throttling batched migrations
|
||||
|
||||
Because batched migrations are update heavy and there were few incidents in the past because of the heavy load from migrations while the database was underperforming, a throttling mechanism exists to mitigate them.
|
||||
|
||||
These database indicators are checked to throttle a migration. On getting a
|
||||
stop signal, the migration is paused for a set time (10 minutes):
|
||||
|
||||
- WAL queue pending archival crossing a threshold.
|
||||
- Active autovacuum on the tables on which the migration works on.
|
||||
- Patroni apdex SLI dropping below the SLO.
|
||||
|
||||
It's an ongoing effort to add more indicators to further enhance the
|
||||
database health check framework. For more details, see
|
||||
[epic 7594](https://gitlab.com/groups/gitlab-org/-/epics/7594).
|
||||
|
||||
## Additional filters
|
||||
|
||||
By default, when creating background jobs to perform the migration, batched background migrations
|
||||
|
|
|
|||
29
doc/index.md
29
doc/index.md
|
|
@ -19,16 +19,15 @@ description: 'Learn how to use and administer GitLab, the most scalable Git-base
|
|||
|
||||
# GitLab Docs
|
||||
|
||||
Welcome to the GitLab documentation!
|
||||
Explore the different areas of the documentation:
|
||||
|
||||
| | |
|
||||
|:------------------------|:------------------------|
|
||||
| [**Use GitLab**](user/index.md)<br>Get started with GitLab features and functionality. | [**Administer GitLab**](administration/index.md)<br/>Administer a self-managed GitLab instance. |
|
||||
| [**New to Git and GitLab?**](tutorials/index.md)<br/>Start learning about Git and GitLab. | [**Contribute to GitLab development**](#contributing-to-gitlab)<br/>Create new GitLab functionality and documentation. |
|
||||
| [**New to Git and GitLab?**](tutorials/index.md)<br/>Start learning about Git and GitLab. | [**Contribute to GitLab development**](#contribute-to-gitlab)<br/>Create new GitLab functionality and documentation. |
|
||||
| [**Coming to GitLab from another platform?**](#coming-to-gitlab-from-another-platform)<br/>Learn how to move to GitLab. | [**Build an integration with GitLab**](#build-an-integration-with-gitlab)<br/>Integrate with Jira and other common applications. |
|
||||
| [**Choose a subscription**](subscriptions/index.md)<br/>Determine which subscription tier makes sense for you. | [**Install GitLab**](https://about.gitlab.com/install/)<br/>Install GitLab on different platforms. |
|
||||
| [**Choose a subscription**](subscriptions/index.md)<br/>Determine which subscription tier makes sense for you. | [**Install GitLab**](install/index.md)<br/>Install GitLab on different platforms. |
|
||||
| [**Reference architectures**](administration/reference_architectures/index.md)<br/>View recommended deployments at scale. | [**Upgrade GitLab**](update/index.md)<br/>Upgrade your GitLab self-managed instance to the latest version. |
|
||||
| [**GitLab releases**](https://about.gitlab.com/releases/)<br/>See what's new in GitLab. | |
|
||||
|
||||
## Popular topics
|
||||
|
||||
|
|
@ -48,15 +47,7 @@ Have a look at some of our most popular topics:
|
|||
| [SSL configuration for Linux package installations](https://docs.gitlab.com/omnibus/settings/ssl/index.html) | SSL settings for self-managed instances installed using Linux packages. |
|
||||
| [GitLab.com settings](user/gitlab_com/index.md) | Settings used for GitLab.com. |
|
||||
|
||||
## The entire DevOps lifecycle
|
||||
|
||||
GitLab is the first single application for software development, security,
|
||||
and operations that enables [Concurrent DevOps](https://about.gitlab.com/topics/concurrent-devops/).
|
||||
GitLab makes the software lifecycle faster and radically improves the speed of business.
|
||||
|
||||
GitLab provides solutions for [each of the stages of the DevOps lifecycle](https://about.gitlab.com/stages-devops-lifecycle/).
|
||||
|
||||
### User account
|
||||
## User account
|
||||
|
||||
For more information about GitLab account management, see:
|
||||
|
||||
|
|
@ -78,7 +69,7 @@ If you are coming to GitLab from another platform, the following information is
|
|||
|
||||
## Build an integration with GitLab
|
||||
|
||||
There are many ways to integrate with GitLab, including:
|
||||
You can build integrations with GitLab:
|
||||
|
||||
| Topic | Description |
|
||||
|:-------------------------------------------|:------------|
|
||||
|
|
@ -86,15 +77,11 @@ There are many ways to integrate with GitLab, including:
|
|||
| [GitLab GraphQL API](api/graphql/index.md) | Integrate with GitLab using our GraphQL API. |
|
||||
| [Integrations](integration/index.md) | Integrations with third-party products. |
|
||||
|
||||
## Contributing to GitLab
|
||||
|
||||
GitLab Community Edition is [open source](https://gitlab.com/gitlab-org/gitlab-foss/)
|
||||
and GitLab Enterprise Edition is [open-core](https://gitlab.com/gitlab-org/gitlab/).
|
||||
## Contribute to GitLab
|
||||
|
||||
Learn how to contribute to GitLab with the following resources:
|
||||
|
||||
| Topic | Description |
|
||||
|:------------------------------------------------------------|:------------|
|
||||
| [Development](development/index.md) | How to contribute to GitLab development. |
|
||||
| [Legal](legal/index.md) | Contributor license agreements. |
|
||||
| [Writing documentation](development/documentation/index.md) | How to contribute to GitLab Docs. |
|
||||
| [Contribute to GitLab development](development/index.md). | How to contribute to GitLab development. |
|
||||
| [Contribute to the documentation](development/documentation/index.md) | How to contribute to GitLab documentation. |
|
||||
|
|
|
|||
|
|
@ -262,6 +262,16 @@ module Gitlab
|
|||
SQL
|
||||
end
|
||||
|
||||
def switch_constraint_names(table_name, constraint_a, constraint_b)
|
||||
validate_not_in_transaction!(:switch_constraint_names)
|
||||
|
||||
with_lock_retries do
|
||||
rename_constraint(table_name, constraint_a, :temp_name_for_renaming)
|
||||
rename_constraint(table_name, constraint_b, constraint_a)
|
||||
rename_constraint(table_name, :temp_name_for_renaming, constraint_b)
|
||||
end
|
||||
end
|
||||
|
||||
def validate_check_constraint_name!(constraint_name)
|
||||
return unless constraint_name.to_s.length > MAX_IDENTIFIER_NAME_LENGTH
|
||||
|
||||
|
|
|
|||
|
|
@ -518,13 +518,15 @@ module Gitlab
|
|||
empty_diff_stats
|
||||
end
|
||||
|
||||
def find_changed_paths(commits)
|
||||
def find_changed_paths(commits, merge_commit_diff_mode: nil)
|
||||
processed_commits = commits.reject { |ref| ref.blank? || Gitlab::Git.blank_ref?(ref) }
|
||||
|
||||
return [] if processed_commits.empty?
|
||||
|
||||
wrapped_gitaly_errors do
|
||||
gitaly_commit_client.find_changed_paths(processed_commits)
|
||||
gitaly_commit_client.find_changed_paths(
|
||||
processed_commits, merge_commit_diff_mode: merge_commit_diff_mode
|
||||
)
|
||||
end
|
||||
rescue CommandError, TypeError, NoRepository
|
||||
[]
|
||||
|
|
|
|||
|
|
@ -12,6 +12,11 @@ module Gitlab
|
|||
'unspecified' => Gitaly::CommitDiffRequest::WhitespaceChanges::WHITESPACE_CHANGES_UNSPECIFIED
|
||||
}.freeze
|
||||
|
||||
MERGE_COMMIT_DIFF_MODES = {
|
||||
all_parents: Gitaly::FindChangedPathsRequest::MergeCommitDiffMode::MERGE_COMMIT_DIFF_MODE_ALL_PARENTS,
|
||||
include_merges: Gitaly::FindChangedPathsRequest::MergeCommitDiffMode::MERGE_COMMIT_DIFF_MODE_INCLUDE_MERGES
|
||||
}.freeze
|
||||
|
||||
TREE_ENTRIES_DEFAULT_LIMIT = 100_000
|
||||
|
||||
def initialize(repository)
|
||||
|
|
@ -242,8 +247,35 @@ module Gitlab
|
|||
response.flat_map { |rsp| rsp.stats.to_a }
|
||||
end
|
||||
|
||||
def find_changed_paths(commits)
|
||||
request = find_changed_paths_request(commits)
|
||||
# When finding changed paths and passing a sha for a merge commit we can
|
||||
# specify how to diff the commit.
|
||||
#
|
||||
# When diffing a merge commit and merge_commit_diff_mode is :all_parents
|
||||
# file paths are only returned if changed in both parents (or all parents
|
||||
# if diffing an octopus merge)
|
||||
#
|
||||
# This means if we create a merge request that includes a merge commit
|
||||
# of changes already existing in the target branch, we can omit those
|
||||
# changes when looking up the changed paths.
|
||||
#
|
||||
# e.g.
|
||||
# 1. User branches from master to new branch named feature/foo_bar
|
||||
# 2. User changes ./foo_bar.rb and commits change to feature/foo_bar
|
||||
# 3. Another user merges a change to ./bar_baz.rb to master
|
||||
# 4. User merges master into feature/foo_bar
|
||||
# 5. User pushes to GitLab
|
||||
# 6. GitLab checks which files have changed
|
||||
#
|
||||
# case merge_commit_diff_mode
|
||||
# when :all_parents
|
||||
# ['foo_bar.rb']
|
||||
# when :include_merges
|
||||
# ['foo_bar.rb', 'bar_baz.rb'],
|
||||
# else # defaults to :include_merges behavior
|
||||
# ['foo_bar.rb', 'bar_baz.rb'],
|
||||
#
|
||||
def find_changed_paths(commits, merge_commit_diff_mode: nil)
|
||||
request = find_changed_paths_request(commits, merge_commit_diff_mode)
|
||||
|
||||
response = gitaly_client_call(@repository.storage, :diff_service, :find_changed_paths, request, timeout: GitalyClient.medium_timeout)
|
||||
response.flat_map do |msg|
|
||||
|
|
@ -606,9 +638,11 @@ module Gitlab
|
|||
response.commit
|
||||
end
|
||||
|
||||
def find_changed_paths_request(commits)
|
||||
def find_changed_paths_request(commits, merge_commit_diff_mode)
|
||||
diff_mode = MERGE_COMMIT_DIFF_MODES[merge_commit_diff_mode] if Feature.enabled?(:merge_commit_diff_modes)
|
||||
|
||||
if Feature.disabled?(:find_changed_paths_new_format)
|
||||
return Gitaly::FindChangedPathsRequest.new(repository: @gitaly_repo, commits: commits)
|
||||
return Gitaly::FindChangedPathsRequest.new(repository: @gitaly_repo, commits: commits, merge_commit_diff_mode: diff_mode)
|
||||
end
|
||||
|
||||
commit_requests = commits.map do |commit|
|
||||
|
|
@ -617,7 +651,7 @@ module Gitlab
|
|||
)
|
||||
end
|
||||
|
||||
Gitaly::FindChangedPathsRequest.new(repository: @gitaly_repo, requests: commit_requests)
|
||||
Gitaly::FindChangedPathsRequest.new(repository: @gitaly_repo, requests: commit_requests, merge_commit_diff_mode: diff_mode)
|
||||
end
|
||||
|
||||
def path_error_message(path_error)
|
||||
|
|
|
|||
|
|
@ -31,6 +31,11 @@ class TmpUser < ActiveRecord::Base # rubocop:disable Rails/ApplicationRecord
|
|||
|
||||
self.table_name = 'users'
|
||||
|
||||
add_authentication_token_field :incoming_email_token, token_generator: -> { SecureRandom.hex.to_i(16).to_s(36) }
|
||||
add_authentication_token_field :feed_token
|
||||
add_authentication_token_field :incoming_email_token,
|
||||
token_generator: -> { User.generate_incoming_mail_token }
|
||||
add_authentication_token_field :feed_token, format_with_prefix: :prefix_for_feed_token
|
||||
|
||||
def prefix_for_feed_token
|
||||
User::FEED_TOKEN_PREFIX
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -27688,6 +27688,9 @@ msgstr ""
|
|||
msgid "Map a FogBugz account ID to a GitLab user"
|
||||
msgstr ""
|
||||
|
||||
msgid "Map data from"
|
||||
msgstr ""
|
||||
|
||||
msgid "Mar"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -46014,6 +46017,9 @@ msgstr ""
|
|||
msgid "The list creation wizard is already open"
|
||||
msgstr ""
|
||||
|
||||
msgid "The map can not be displayed because there was an error loading the GeoJSON file."
|
||||
msgstr ""
|
||||
|
||||
msgid "The maximum amount of time users have to set up two-factor authentication before it's enforced."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@
|
|||
"js-yaml": "^3.13.1",
|
||||
"jszip": "^3.1.3",
|
||||
"katex": "^0.13.2",
|
||||
"leaflet": "^1.9.4",
|
||||
"lodash": "^4.17.20",
|
||||
"lowlight": "^2.9.0",
|
||||
"marked": "^4.0.18",
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ module Gitlab
|
|||
div :project
|
||||
div :storage_type_legend
|
||||
span :container_registry_size
|
||||
div :purchased_usage_total
|
||||
div :storage_purchased, 'data-testid': 'storage-purchased'
|
||||
div :storage_purchase_successful_alert, text: /You have successfully purchased a storage/
|
||||
|
||||
# Pending members
|
||||
|
|
@ -70,7 +70,7 @@ module Gitlab
|
|||
def total_purchased_storage
|
||||
::QA::Support::WaitForRequests.wait_for_requests
|
||||
|
||||
purchased_usage_total[/(\d+){2}.\d+/].to_f
|
||||
storage_purchased[/(\d+){2}.\d+/].to_f
|
||||
end
|
||||
|
||||
# Waits for additional CI minutes to be available on the page
|
||||
|
|
|
|||
|
|
@ -533,51 +533,27 @@ module Gitlab
|
|||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +div :purchased_usage_total_free+
|
||||
# @return [String] The text content or value of +purchased_usage_total_free+
|
||||
def purchased_usage_total_free
|
||||
# @note Defined as +div :storage_purchased+
|
||||
# @return [String] The text content or value of +storage_purchased+
|
||||
def storage_purchased
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
|
||||
# expect(usage_quotas.purchased_usage_total_free_element).to exist
|
||||
# expect(usage_quotas.storage_purchased_element).to exist
|
||||
# end
|
||||
# @return [Watir::Div] The raw +Div+ element
|
||||
def purchased_usage_total_free_element
|
||||
def storage_purchased_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
|
||||
# expect(usage_quotas).to be_purchased_usage_total_free
|
||||
# expect(usage_quotas).to be_storage_purchased
|
||||
# end
|
||||
# @return [Boolean] true if the +purchased_usage_total_free+ element is present on the page
|
||||
def purchased_usage_total_free?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +span :purchased_usage_total+
|
||||
# @return [String] The text content or value of +purchased_usage_total+
|
||||
def purchased_usage_total
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
|
||||
# expect(usage_quotas.purchased_usage_total_element).to exist
|
||||
# end
|
||||
# @return [Watir::Span] The raw +Span+ element
|
||||
def purchased_usage_total_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
|
||||
# expect(usage_quotas).to be_purchased_usage_total
|
||||
# end
|
||||
# @return [Boolean] true if the +purchased_usage_total+ element is present on the page
|
||||
def purchased_usage_total?
|
||||
# @return [Boolean] true if the +storage_purchased+ element is present on the page
|
||||
def storage_purchased?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ exports[`Design note component should match the snapshot 1`] = `
|
|||
/>
|
||||
|
||||
<gllink-stub
|
||||
class="note-timestamp system-note-separator gl-display-block gl-mb-2"
|
||||
class="note-timestamp system-note-separator gl-display-block gl-mb-2 gl-font-sm"
|
||||
href="#note_123"
|
||||
>
|
||||
<timeagotooltip-stub
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ describe('containsSensitiveToken', () => {
|
|||
'token: glpat-cgyKc1k_AsnEpmP-5fRL',
|
||||
'token: GlPat-abcdefghijklmnopqrstuvwxyz',
|
||||
'token: feed_token=ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
'token: feed_token=glft-ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
'token: feed_token=glft-a8cc74ccb0de004d09a968705ba49099229b288b3de43f26c473a9d8d7fb7693-1234',
|
||||
'https://example.com/feed?feed_token=123456789_abcdefghij',
|
||||
'glpat-1234567890 and feed_token=ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
||||
];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
import { nextTick } from 'vue';
|
||||
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||
import GeoJsonViewer from '~/repository/components/blob_viewers/geo_json/geo_json_viewer.vue';
|
||||
import { initLeafletMap } from '~/repository/components/blob_viewers/geo_json/utils';
|
||||
import { RENDER_ERROR_MSG } from '~/repository/components/blob_viewers/geo_json/constants';
|
||||
import { createAlert } from '~/alert';
|
||||
|
||||
jest.mock('~/repository/components/blob_viewers/geo_json/utils');
|
||||
jest.mock('~/alert');
|
||||
|
||||
describe('GeoJson Viewer', () => {
|
||||
let wrapper;
|
||||
|
||||
const GEO_JSON_MOCK_DATA = '{ "type": "FeatureCollection" }';
|
||||
|
||||
const createComponent = (rawTextBlob = GEO_JSON_MOCK_DATA) => {
|
||||
wrapper = shallowMountExtended(GeoJsonViewer, {
|
||||
propsData: { blob: { rawTextBlob } },
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(() => createComponent());
|
||||
|
||||
const findMapWrapper = () => wrapper.findByTestId('map');
|
||||
|
||||
it('calls a the initLeafletMap util', () => {
|
||||
const mapWrapper = findMapWrapper();
|
||||
|
||||
expect(initLeafletMap).toHaveBeenCalledWith(mapWrapper.element, JSON.parse(GEO_JSON_MOCK_DATA));
|
||||
expect(mapWrapper.exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('displays an error if invalid json is provided', async () => {
|
||||
createComponent('invalid JSON');
|
||||
await nextTick();
|
||||
|
||||
expect(createAlert).toHaveBeenCalledWith({ message: RENDER_ERROR_MSG });
|
||||
expect(findMapWrapper().exists()).toBe(false);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
import { map, tileLayer, geoJson, featureGroup, Icon } from 'leaflet';
|
||||
import * as utils from '~/repository/components/blob_viewers/geo_json/utils';
|
||||
import {
|
||||
OPEN_STREET_TILE_URL,
|
||||
MAP_ATTRIBUTION,
|
||||
OPEN_STREET_COPYRIGHT_LINK,
|
||||
ICON_CONFIG,
|
||||
} from '~/repository/components/blob_viewers/geo_json/constants';
|
||||
|
||||
jest.mock('leaflet', () => ({
|
||||
featureGroup: () => ({ getBounds: jest.fn() }),
|
||||
Icon: { Default: { mergeOptions: jest.fn() } },
|
||||
tileLayer: jest.fn(),
|
||||
map: jest.fn().mockReturnValue({ fitBounds: jest.fn() }),
|
||||
geoJson: jest.fn().mockReturnValue({ addTo: jest.fn() }),
|
||||
}));
|
||||
|
||||
describe('GeoJson utilities', () => {
|
||||
const mockWrapper = document.createElement('div');
|
||||
const mockData = { test: 'data' };
|
||||
|
||||
describe('initLeafletMap', () => {
|
||||
describe('valid params', () => {
|
||||
beforeEach(() => utils.initLeafletMap(mockWrapper, mockData));
|
||||
|
||||
it('sets the correct icon', () => {
|
||||
expect(Icon.Default.mergeOptions).toHaveBeenCalledWith(ICON_CONFIG);
|
||||
});
|
||||
|
||||
it('inits the leaflet map', () => {
|
||||
const attribution = `${MAP_ATTRIBUTION} ${OPEN_STREET_COPYRIGHT_LINK}`;
|
||||
|
||||
expect(tileLayer).toHaveBeenCalledWith(OPEN_STREET_TILE_URL, { attribution });
|
||||
expect(map).toHaveBeenCalledWith(mockWrapper, { layers: [] });
|
||||
});
|
||||
|
||||
it('adds geojson data to the leaflet map', () => {
|
||||
expect(geoJson().addTo).toHaveBeenCalledWith(map());
|
||||
});
|
||||
|
||||
it('fits the map to the correct bounds', () => {
|
||||
expect(map().fitBounds).toHaveBeenCalledWith(featureGroup().getBounds());
|
||||
});
|
||||
|
||||
it('generates popup content containing the metaData', () => {
|
||||
const popupContent = utils.popupContent(mockData);
|
||||
|
||||
expect(popupContent).toContain(Object.keys(mockData)[0]);
|
||||
expect(popupContent).toContain(mockData.test);
|
||||
});
|
||||
});
|
||||
|
||||
describe('invalid params', () => {
|
||||
it.each([
|
||||
[null, null],
|
||||
[null, mockData],
|
||||
[mockWrapper, null],
|
||||
])('does nothing (returns early) if any of the params are not provided', (wrapper, data) => {
|
||||
utils.initLeafletMap(wrapper, data);
|
||||
expect(Icon.Default.mergeOptions).not.toHaveBeenCalled();
|
||||
expect(tileLayer).not.toHaveBeenCalled();
|
||||
expect(map).not.toHaveBeenCalled();
|
||||
expect(geoJson().addTo).not.toHaveBeenCalled();
|
||||
expect(map().fitBounds).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -679,4 +679,43 @@ RSpec.describe Gitlab::Database::Migrations::ConstraintsHelpers do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#switch_constraint_names' do
|
||||
before do
|
||||
ActiveRecord::Migration.connection.create_table(:_test_table) do |t|
|
||||
t.references :supplier, foreign_key: { to_table: :_test_table, name: :supplier_fk }
|
||||
t.references :customer, foreign_key: { to_table: :_test_table, name: :customer_fk }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when inside a transaction' do
|
||||
it 'raises an error' do
|
||||
expect(model).to receive(:transaction_open?).and_return(true)
|
||||
|
||||
expect do
|
||||
model.switch_constraint_names(:_test_table, :supplier_fk, :customer_fk)
|
||||
end.to raise_error(RuntimeError)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when outside a transaction' do
|
||||
before do
|
||||
allow(model).to receive(:transaction_open?).and_return(false)
|
||||
end
|
||||
|
||||
it 'executes the statement to swap the constraint names' do
|
||||
expect { model.switch_constraint_names(:_test_table, :supplier_fk, :customer_fk) }
|
||||
.to change { constrained_column_for(:customer_fk) }.from(:customer_id).to(:supplier_id)
|
||||
.and change { constrained_column_for(:supplier_fk) }.from(:supplier_id).to(:customer_id)
|
||||
end
|
||||
|
||||
def constrained_column_for(fk_name)
|
||||
Gitlab::Database::PostgresForeignKey
|
||||
.find_by!(referenced_table_name: :_test_table, name: fk_name)
|
||||
.constrained_columns
|
||||
.first
|
||||
.to_sym
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1454,7 +1454,7 @@ RSpec.describe Gitlab::Git::Repository, feature_category: :source_code_managemen
|
|||
it "returns the number of commits in the whole repository" do
|
||||
options = { all: true }
|
||||
|
||||
expect(repository.count_commits(options)).to eq(316)
|
||||
expect(repository.count_commits(options)).to eq(322)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -1675,6 +1675,41 @@ RSpec.describe Gitlab::Git::Repository, feature_category: :source_code_managemen
|
|||
expect(collection).to be_a(Enumerable)
|
||||
expect(collection.to_a).to be_empty
|
||||
end
|
||||
|
||||
describe 'merge_commit_diff_mode argument' do
|
||||
let(:gitaly_commit_client) { double('Gitlab::GitalyClient::CommitService') }
|
||||
|
||||
before do
|
||||
allow(repository).to receive(:gitaly_commit_client).and_return(gitaly_commit_client)
|
||||
allow(gitaly_commit_client).to receive(:find_changed_paths)
|
||||
end
|
||||
|
||||
context 'when omitted' do
|
||||
before do
|
||||
repository.find_changed_paths(['sha'])
|
||||
end
|
||||
|
||||
it 'defaults to nil' do
|
||||
expect(gitaly_commit_client)
|
||||
.to have_received(:find_changed_paths)
|
||||
.with(['sha'], merge_commit_diff_mode: nil)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when included' do
|
||||
let(:passed_value) { 'foobar' }
|
||||
|
||||
before do
|
||||
repository.find_changed_paths(['sha'], merge_commit_diff_mode: passed_value)
|
||||
end
|
||||
|
||||
it 'passes the value on to the commit client' do
|
||||
expect(gitaly_commit_client)
|
||||
.to have_received(:find_changed_paths)
|
||||
.with(['sha'], merge_commit_diff_mode: passed_value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "#ls_files" do
|
||||
|
|
|
|||
|
|
@ -168,34 +168,171 @@ RSpec.describe Gitlab::GitalyClient::CommitService, feature_category: :gitaly do
|
|||
end
|
||||
|
||||
describe '#find_changed_paths' do
|
||||
let(:commits) { %w[1a0b36b3cdad1d2ee32457c102a8c0b7056fa863 cfe32cf61b73a0d5e9f13e774abde7ff789b1660] }
|
||||
let(:requests) do
|
||||
[
|
||||
Gitaly::FindChangedPathsRequest::Request.new(
|
||||
commit_request: Gitaly::FindChangedPathsRequest::Request::CommitRequest.new(commit_revision: '1a0b36b3cdad1d2ee32457c102a8c0b7056fa863')
|
||||
),
|
||||
Gitaly::FindChangedPathsRequest::Request.new(
|
||||
commit_request: Gitaly::FindChangedPathsRequest::Request::CommitRequest.new(commit_revision: 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660')
|
||||
)
|
||||
let(:mapped_merge_commit_diff_mode) { described_class::MERGE_COMMIT_DIFF_MODES[merge_commit_diff_mode] }
|
||||
let(:commits) do
|
||||
%w[
|
||||
ade1c0b4b116209ed2a9958436b26f89085ec383
|
||||
594937c22df7a093888ff13af518f2b683f5f719
|
||||
760c58db5a6f3b64ad7e3ff6b3c4a009da7d9b33
|
||||
2b298117a741cdb06eb48df2c33f1390cf89f7e8
|
||||
c41e12c387b4e0e41bfc17208252d6a6430f2fcd
|
||||
1ada92f78a19f27cb442a0a205f1c451a3a15432
|
||||
]
|
||||
end
|
||||
|
||||
it 'sends an RPC request and returns the stats' do
|
||||
request = Gitaly::FindChangedPathsRequest.new(repository: repository_message, requests: requests)
|
||||
let(:requests) do
|
||||
commits.map do |commit|
|
||||
Gitaly::FindChangedPathsRequest::Request.new(
|
||||
commit_request: Gitaly::FindChangedPathsRequest::Request::CommitRequest.new(commit_revision: commit)
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
changed_paths_response = Gitaly::FindChangedPathsResponse.new(
|
||||
paths: [{
|
||||
path: "app/assets/javascripts/boards/components/project_select.vue",
|
||||
status: :MODIFIED
|
||||
}])
|
||||
let(:request) do
|
||||
Gitaly::FindChangedPathsRequest.new(repository: repository_message, requests: requests, merge_commit_diff_mode: merge_commit_diff_mode)
|
||||
end
|
||||
|
||||
expect_any_instance_of(Gitaly::DiffService::Stub).to receive(:find_changed_paths)
|
||||
.with(request, kind_of(Hash)).and_return([changed_paths_response])
|
||||
subject { described_class.new(repository).find_changed_paths(commits, merge_commit_diff_mode: merge_commit_diff_mode).as_json }
|
||||
|
||||
returned_value = described_class.new(repository).find_changed_paths(commits)
|
||||
mapped_expected_value = changed_paths_response.paths.map { |path| Gitlab::Git::ChangedPath.new(status: path.status, path: path.path) }
|
||||
before do
|
||||
allow(Gitaly::FindChangedPathsRequest).to receive(:new).and_call_original
|
||||
end
|
||||
|
||||
expect(returned_value.as_json).to eq(mapped_expected_value.as_json)
|
||||
shared_examples 'includes paths different in any parent' do
|
||||
let(:changed_paths) do
|
||||
[
|
||||
{ path: 'files/locked/foo.lfs', status: 'ADDED' },
|
||||
{ path: 'files/locked/foo.lfs', status: 'MODIFIED' },
|
||||
{ path: 'files/locked/bar.lfs', status: 'ADDED' },
|
||||
{ path: 'files/locked/foo.lfs', status: 'MODIFIED' },
|
||||
{ path: 'files/locked/bar.lfs', status: 'ADDED' },
|
||||
{ path: 'files/locked/bar.lfs', status: 'MODIFIED' },
|
||||
{ path: 'files/locked/bar.lfs', status: 'MODIFIED' },
|
||||
{ path: 'files/locked/baz.lfs', status: 'ADDED' },
|
||||
{ path: 'files/locked/baz.lfs', status: 'ADDED' }
|
||||
].as_json
|
||||
end
|
||||
|
||||
it 'returns all paths, including ones from merge commits' do
|
||||
is_expected.to eq(changed_paths)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'includes paths different in all parents' do
|
||||
let(:changed_paths) do
|
||||
[
|
||||
{ path: 'files/locked/foo.lfs', status: 'ADDED' },
|
||||
{ path: 'files/locked/foo.lfs', status: 'MODIFIED' },
|
||||
{ path: 'files/locked/bar.lfs', status: 'ADDED' },
|
||||
{ path: 'files/locked/bar.lfs', status: 'MODIFIED' },
|
||||
{ path: 'files/locked/baz.lfs', status: 'ADDED' },
|
||||
{ path: 'files/locked/baz.lfs', status: 'ADDED' }
|
||||
].as_json
|
||||
end
|
||||
|
||||
it 'returns only paths different in all parents' do
|
||||
is_expected.to eq(changed_paths)
|
||||
end
|
||||
end
|
||||
|
||||
shared_examples 'uses requests format' do
|
||||
it 'passes the revs via the requests kwarg as CommitRequest objects' do
|
||||
subject
|
||||
expect(Gitaly::FindChangedPathsRequest)
|
||||
.to have_received(:new).with(
|
||||
repository: repository_message,
|
||||
requests: requests,
|
||||
merge_commit_diff_mode: mapped_merge_commit_diff_mode
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is nil' do
|
||||
let(:merge_commit_diff_mode) { nil }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses requests format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is :unspecified' do
|
||||
let(:merge_commit_diff_mode) { :unspecified }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses requests format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is :include_merges' do
|
||||
let(:merge_commit_diff_mode) { :include_merges }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses requests format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is invalid' do
|
||||
let(:merge_commit_diff_mode) { 'invalid' }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses requests format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is :all_parents' do
|
||||
let(:merge_commit_diff_mode) { :all_parents }
|
||||
|
||||
include_examples 'includes paths different in all parents'
|
||||
|
||||
include_examples 'uses requests format'
|
||||
end
|
||||
|
||||
context 'when feature flag "merge_commit_diff_modes" is disabled' do
|
||||
let(:mapped_merge_commit_diff_mode) { nil }
|
||||
|
||||
before do
|
||||
stub_feature_flags(merge_commit_diff_modes: false)
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is nil' do
|
||||
let(:merge_commit_diff_mode) { nil }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses requests format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is :unspecified' do
|
||||
let(:merge_commit_diff_mode) { :unspecified }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses requests format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is :include_merges' do
|
||||
let(:merge_commit_diff_mode) { :include_merges }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses requests format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is invalid' do
|
||||
let(:merge_commit_diff_mode) { 'invalid' }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses requests format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is :all_parents' do
|
||||
let(:merge_commit_diff_mode) { :all_parents }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses requests format'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when feature flag "find_changed_paths_new_format" is disabled' do
|
||||
|
|
@ -203,22 +340,104 @@ RSpec.describe Gitlab::GitalyClient::CommitService, feature_category: :gitaly do
|
|||
stub_feature_flags(find_changed_paths_new_format: false)
|
||||
end
|
||||
|
||||
it 'sends an RPC request and returns the stats' do
|
||||
request = Gitaly::FindChangedPathsRequest.new(repository: repository_message, commits: commits)
|
||||
shared_examples 'uses commits format' do
|
||||
it do
|
||||
subject
|
||||
expect(Gitaly::FindChangedPathsRequest)
|
||||
.to have_received(:new).with(
|
||||
repository: repository_message,
|
||||
commits: commits,
|
||||
merge_commit_diff_mode: mapped_merge_commit_diff_mode
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
changed_paths_response = Gitaly::FindChangedPathsResponse.new(
|
||||
paths: [{
|
||||
path: "app/assets/javascripts/boards/components/project_select.vue",
|
||||
status: :MODIFIED
|
||||
}])
|
||||
context 'when merge_commit_diff_mode is nil' do
|
||||
let(:merge_commit_diff_mode) { nil }
|
||||
|
||||
expect_any_instance_of(Gitaly::DiffService::Stub).to receive(:find_changed_paths)
|
||||
.with(request, kind_of(Hash)).and_return([changed_paths_response])
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
returned_value = described_class.new(repository).find_changed_paths(commits)
|
||||
mapped_expected_value = changed_paths_response.paths.map { |path| Gitlab::Git::ChangedPath.new(status: path.status, path: path.path) }
|
||||
include_examples 'uses commits format'
|
||||
end
|
||||
|
||||
expect(returned_value.as_json).to eq(mapped_expected_value.as_json)
|
||||
context 'when merge_commit_diff_mode is :unspecified' do
|
||||
let(:merge_commit_diff_mode) { :unspecified }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses commits format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is :include_merges' do
|
||||
let(:merge_commit_diff_mode) { :include_merges }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses commits format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is invalid' do
|
||||
let(:merge_commit_diff_mode) { 'invalid' }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses commits format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is :all_parents' do
|
||||
let(:merge_commit_diff_mode) { :all_parents }
|
||||
|
||||
include_examples 'includes paths different in all parents'
|
||||
|
||||
include_examples 'uses commits format'
|
||||
end
|
||||
|
||||
context 'when feature flag "merge_commit_diff_modes" is disabled' do
|
||||
let(:mapped_merge_commit_diff_mode) { nil }
|
||||
|
||||
before do
|
||||
stub_feature_flags(merge_commit_diff_modes: false)
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is nil' do
|
||||
let(:merge_commit_diff_mode) { nil }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses commits format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is :unspecified' do
|
||||
let(:merge_commit_diff_mode) { :unspecified }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses commits format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is :include_merges' do
|
||||
let(:merge_commit_diff_mode) { :include_merges }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses commits format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is invalid' do
|
||||
let(:merge_commit_diff_mode) { 'invalid' }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses commits format'
|
||||
end
|
||||
|
||||
context 'when merge_commit_diff_mode is :all_parents' do
|
||||
let(:merge_commit_diff_mode) { :all_parents }
|
||||
|
||||
include_examples 'includes paths different in any parent'
|
||||
|
||||
include_examples 'uses commits format'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,10 +10,11 @@ RSpec.describe Group, feature_category: :groups_and_projects do
|
|||
|
||||
describe 'associations' do
|
||||
it { is_expected.to have_many :projects }
|
||||
it { is_expected.to have_many(:all_group_members).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:group_members).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:namespace_members) }
|
||||
it { is_expected.to have_many(:users).through(:group_members) }
|
||||
it { is_expected.to have_many(:owners).through(:group_members) }
|
||||
it { is_expected.to have_many(:owners).through(:all_group_members) }
|
||||
it { is_expected.to have_many(:requesters).dependent(:destroy) }
|
||||
it { is_expected.to have_many(:namespace_requesters) }
|
||||
it { is_expected.to have_many(:members_and_requesters) }
|
||||
|
|
@ -1448,10 +1449,9 @@ RSpec.describe Group, feature_category: :groups_and_projects do
|
|||
let(:developer) { create(:user) }
|
||||
|
||||
it 'returns the owners of a Group' do
|
||||
group.add_owner(owner)
|
||||
group.add_developer(developer)
|
||||
members = setup_group_members(group)
|
||||
|
||||
expect(group.owners).to eq([owner])
|
||||
expect(group.owners).to eq([members[:owner]])
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -2090,7 +2090,7 @@ RSpec.describe User, feature_category: :user_profile do
|
|||
|
||||
user = create(:user)
|
||||
|
||||
expect(user.incoming_email_token).to eql('gitlab')
|
||||
expect(user.incoming_email_token).to eql("glimt-gitlab")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -2137,6 +2137,12 @@ RSpec.describe User, feature_category: :user_profile do
|
|||
expect(user.reload.feed_token).to eq feed_token
|
||||
end
|
||||
|
||||
it 'returns feed tokens with a prefix' do
|
||||
user = create(:user)
|
||||
|
||||
expect(user.feed_token).to start_with('glft-')
|
||||
end
|
||||
|
||||
it 'ensures no feed token when disabled' do
|
||||
allow(Gitlab::CurrentSettings).to receive(:disable_feed_token).and_return(true)
|
||||
|
||||
|
|
@ -2184,7 +2190,7 @@ RSpec.describe User, feature_category: :user_profile do
|
|||
describe 'enabled_static_object_token' do
|
||||
let_it_be(:static_object_token) { 'ilqx6jm1u945macft4eff0nw' }
|
||||
|
||||
it 'returns incoming email token when supported' do
|
||||
it 'returns static object token when supported' do
|
||||
allow(Gitlab::CurrentSettings).to receive(:static_objects_external_storage_enabled?).and_return(true)
|
||||
|
||||
user = create(:user, static_object_token: static_object_token)
|
||||
|
|
@ -2212,6 +2218,14 @@ RSpec.describe User, feature_category: :user_profile do
|
|||
expect(user.enabled_incoming_email_token).to eq(incoming_email_token)
|
||||
end
|
||||
|
||||
it 'returns incoming mail tokens with a prefix' do
|
||||
allow(Gitlab::Email::IncomingEmail).to receive(:supports_issue_creation?).and_return(true)
|
||||
|
||||
user = create(:user)
|
||||
|
||||
expect(user.enabled_incoming_email_token).to start_with('glimt-')
|
||||
end
|
||||
|
||||
it 'returns `nil` when not supported' do
|
||||
allow(Gitlab::Email::IncomingEmail).to receive(:supports_issue_creation?).and_return(false)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,7 +9,24 @@ module TestEnv
|
|||
|
||||
ComponentFailedToInstallError = Class.new(StandardError)
|
||||
|
||||
# When developing the seed repository, comment out the branch you will modify.
|
||||
# https://gitlab.com/gitlab-org/gitlab-test is used to seed your local gdk
|
||||
# GitLab application and is also used in rspec tests. Because of this, when
|
||||
# building and testing features that require a specific type of file, you can
|
||||
# add them to the gitlab-test repo in order to access that blob during
|
||||
# development or testing.
|
||||
#
|
||||
# To add new branches
|
||||
#
|
||||
# 1. Push a new branch to gitlab-org/gitlab-test.
|
||||
# 2. Execute rm -rf tmp/tests in your gitlab repo.
|
||||
# 3. Add your branch and its HEAD commit sha to the BRANCH_SHA hash
|
||||
#
|
||||
# To add new commits to an existing branch
|
||||
#
|
||||
# 1. Push a new commit to a branch in gitlab-org/gitlab-test.
|
||||
# 2. Execute rm -rf tmp/tests in your gitlab repo.
|
||||
# 3. Update the HEAD sha value in the BRANCH_SHA hash
|
||||
#
|
||||
BRANCH_SHA = {
|
||||
'signed-commits' => 'c7794c1',
|
||||
'gpg-signed' => '8a852d5',
|
||||
|
|
@ -94,7 +111,8 @@ module TestEnv
|
|||
'smime-signed-commits' => 'ed775cc',
|
||||
'Ääh-test-utf-8' => '7975be0',
|
||||
'ssh-signed-commit' => '7b5160f',
|
||||
'changes-with-whitespace' => 'f2d141fadb33ceaafc95667c1a0a308ad5edc5f9'
|
||||
'changes-with-whitespace' => 'f2d141fadb33ceaafc95667c1a0a308ad5edc5f9',
|
||||
'lock-detection' => '1ada92f78a19f27cb442a0a205f1c451a3a15432'
|
||||
}.freeze
|
||||
|
||||
# gitlab-test-fork is a fork of gitlab-fork, but we don't necessarily
|
||||
|
|
|
|||
|
|
@ -8267,6 +8267,11 @@ layout-base@^2.0.0:
|
|||
resolved "https://registry.yarnpkg.com/layout-base/-/layout-base-2.0.1.tgz#d0337913586c90f9c2c075292069f5c2da5dd285"
|
||||
integrity sha512-dp3s92+uNI1hWIpPGH3jK2kxE2lMjdXdr+DH8ynZHpd6PUlH6x6cbuXnoMmiNumznqaNO31xu9e79F0uuZ0JFg==
|
||||
|
||||
leaflet@^1.9.4:
|
||||
version "1.9.4"
|
||||
resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-1.9.4.tgz#23fae724e282fa25745aff82ca4d394748db7d8d"
|
||||
integrity sha512-nxS1ynzJOmOlHp+iL3FyWqK89GtNL8U8rvlMOsQdTTssxZwCXh8N2NB3GDQOL+YR3XnWyZAxwQixURb+FA74PA==
|
||||
|
||||
leven@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
|
||||
|
|
|
|||
Loading…
Reference in New Issue