Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-05-22 21:19:41 +00:00
parent a2948c6707
commit 36ab26efd2
174 changed files with 1627 additions and 637 deletions

View File

@ -18,6 +18,7 @@ Gitlab/BoundedContexts:
- 'app/finders/achievements/achievements_finder.rb'
- 'app/finders/admin/abuse_report_labels_finder.rb'
- 'app/finders/admin/plans_finder.rb'
- 'app/finders/admin/projects_finder.rb'
- 'app/finders/alert_management/alerts_finder.rb'
- 'app/finders/alert_management/http_integrations_finder.rb'
- 'app/finders/applications_finder.rb'
@ -92,6 +93,7 @@ Gitlab/BoundedContexts:
- 'app/finders/lfs_pointers_finder.rb'
- 'app/finders/license_template_finder.rb'
- 'app/finders/members_finder.rb'
- 'app/finders/merge_request/metrics_finder.rb'
- 'app/finders/merge_request_target_project_finder.rb'
- 'app/finders/merge_requests_finder.rb'
- 'app/finders/merge_requests_finder/params.rb'
@ -309,6 +311,7 @@ Gitlab/BoundedContexts:
- 'app/graphql/resolvers/error_tracking/sentry_error_collection_resolver.rb'
- 'app/graphql/resolvers/error_tracking/sentry_error_stack_trace_resolver.rb'
- 'app/graphql/resolvers/error_tracking/sentry_errors_resolver.rb'
- 'app/graphql/resolvers/feature_flag_resolver.rb'
- 'app/graphql/resolvers/full_path_resolver.rb'
- 'app/graphql/resolvers/group_environment_scopes_resolver.rb'
- 'app/graphql/resolvers/group_issues_resolver.rb'
@ -578,6 +581,8 @@ Gitlab/BoundedContexts:
- 'app/graphql/types/milestone_wildcard_id_enum.rb'
- 'app/graphql/types/mutation_operation_mode_enum.rb'
- 'app/graphql/types/mutation_type.rb'
- 'app/graphql/types/namespace/package_settings_type.rb'
- 'app/graphql/types/namespace/shared_runners_setting_enum.rb'
- 'app/graphql/types/namespace_type.rb'
- 'app/graphql/types/negated_milestone_wildcard_id_enum.rb'
- 'app/graphql/types/nested_environment_type.rb'
@ -1204,7 +1209,10 @@ Gitlab/BoundedContexts:
- 'app/models/context_commits_diff.rb'
- 'app/models/current.rb'
- 'app/models/custom_emoji.rb'
- 'app/models/customer_relations/contact.rb'
- 'app/models/customer_relations/contact_state_counts.rb'
- 'app/models/customer_relations/issue_contact.rb'
- 'app/models/customer_relations/organization.rb'
- 'app/models/cycle_analytics/project_level_stage_adapter.rb'
- 'app/models/deploy_key.rb'
- 'app/models/deploy_keys_project.rb'
@ -1247,6 +1255,9 @@ Gitlab/BoundedContexts:
- 'app/models/environment_status.rb'
- 'app/models/epic.rb'
- 'app/models/error_tracking.rb'
- 'app/models/error_tracking/client_key.rb'
- 'app/models/error_tracking/error.rb'
- 'app/models/error_tracking/error_event.rb'
- 'app/models/error_tracking/project_error_tracking_setting.rb'
- 'app/models/event.rb'
- 'app/models/event_collection.rb'
@ -1259,6 +1270,7 @@ Gitlab/BoundedContexts:
- 'app/models/gpg_key_subkey.rb'
- 'app/models/grafana_integration.rb'
- 'app/models/group.rb'
- 'app/models/group/crm_settings.rb'
- 'app/models/group_custom_attribute.rb'
- 'app/models/group_deploy_key.rb'
- 'app/models/group_deploy_keys_group.rb'
@ -1285,14 +1297,18 @@ Gitlab/BoundedContexts:
- 'app/models/individual_note_discussion.rb'
- 'app/models/instance_configuration.rb'
- 'app/models/instance_metadata.rb'
- 'app/models/instance_metadata/kas.rb'
- 'app/models/integration.rb'
- 'app/models/internal_id.rb'
- 'app/models/issuable_severity.rb'
- 'app/models/issue.rb'
- 'app/models/issue/email.rb'
- 'app/models/issue/metrics.rb'
- 'app/models/issue_assignee.rb'
- 'app/models/issue_email_participant.rb'
- 'app/models/issue_link.rb'
- 'app/models/issue_user_mention.rb'
- 'app/models/issues/csv_import.rb'
- 'app/models/issues/search_data.rb'
- 'app/models/jira_connect/public_key.rb'
- 'app/models/jira_connect_installation.rb'
@ -1313,6 +1329,7 @@ Gitlab/BoundedContexts:
- 'app/models/list.rb'
- 'app/models/list_user_preference.rb'
- 'app/models/loose_foreign_keys.rb'
- 'app/models/loose_foreign_keys/deleted_record.rb'
- 'app/models/loose_foreign_keys/modification_tracker.rb'
- 'app/models/loose_foreign_keys/turbo_modification_tracker.rb'
- 'app/models/main_clusterwide/application_record.rb'
@ -1323,6 +1340,10 @@ Gitlab/BoundedContexts:
- 'app/models/members/project_namespace_member.rb'
- 'app/models/members_preloader.rb'
- 'app/models/merge_request.rb'
- 'app/models/merge_request/approval_removal_settings.rb'
- 'app/models/merge_request/cleanup_schedule.rb'
- 'app/models/merge_request/diff_commit_user.rb'
- 'app/models/merge_request/metrics.rb'
- 'app/models/merge_request_assignee.rb'
- 'app/models/merge_request_context_commit.rb'
- 'app/models/merge_request_context_commit_diff_file.rb'
@ -1336,6 +1357,11 @@ Gitlab/BoundedContexts:
- 'app/models/milestone_note.rb'
- 'app/models/milestone_release.rb'
- 'app/models/namespace.rb'
- 'app/models/namespace/admin_note.rb'
- 'app/models/namespace/aggregation_schedule.rb'
- 'app/models/namespace/detail.rb'
- 'app/models/namespace/package_setting.rb'
- 'app/models/namespace/root_storage_statistics.rb'
- 'app/models/namespace/traversal_hierarchy.rb'
- 'app/models/namespace_ci_cd_setting.rb'
- 'app/models/namespace_setting.rb'
@ -1410,8 +1436,12 @@ Gitlab/BoundedContexts:
- 'app/models/prometheus_metric.rb'
- 'app/models/protectable_dropdown.rb'
- 'app/models/protected_branch.rb'
- 'app/models/protected_branch/cache_key.rb'
- 'app/models/protected_branch/merge_access_level.rb'
- 'app/models/protected_branch/push_access_level.rb'
- 'app/models/protected_ref/access_level.rb'
- 'app/models/protected_tag.rb'
- 'app/models/protected_tag/create_access_level.rb'
- 'app/models/push_event.rb'
- 'app/models/push_event_payload.rb'
- 'app/models/raw_usage_data.rb'
@ -1551,6 +1581,8 @@ Gitlab/BoundedContexts:
- 'app/policies/merge_requests_closing_issues_policy.rb'
- 'app/policies/metrics/dashboard/annotation_policy.rb'
- 'app/policies/milestone_policy.rb'
- 'app/policies/namespace/package_setting_policy.rb'
- 'app/policies/namespace/root_storage_statistics_policy.rb'
- 'app/policies/namespace_ci_cd_setting_policy.rb'
- 'app/policies/namespace_policy.rb'
- 'app/policies/note_policy.rb'
@ -1583,6 +1615,7 @@ Gitlab/BoundedContexts:
- 'app/policies/todo_policy.rb'
- 'app/policies/upload_policy.rb'
- 'app/policies/user_policy.rb'
- 'app/policies/wiki_page/meta_policy.rb'
- 'app/policies/wiki_page_policy.rb'
- 'app/policies/wiki_policy.rb'
- 'app/policies/work_item_policy.rb'
@ -2160,7 +2193,6 @@ Gitlab/BoundedContexts:
- 'app/workers/batched_git_ref_updates/cleanup_scheduler_worker.rb'
- 'app/workers/batched_git_ref_updates/project_cleanup_worker.rb'
- 'app/workers/build_queue_worker.rb'
- 'app/workers/build_success_worker.rb'
- 'app/workers/bulk_import_worker.rb'
- 'app/workers/bulk_imports/entity_worker.rb'
- 'app/workers/bulk_imports/export_request_worker.rb'
@ -3047,7 +3079,7 @@ Gitlab/BoundedContexts:
- 'ee/app/helpers/groups/merge_request_approval_settings_helper.rb'
- 'ee/app/helpers/groups/security_features_helper.rb'
- 'ee/app/helpers/groups/sso_helper.rb'
- 'ee/app/helpers/groups/trial_discover_page_helper.rb'
- 'ee/app/helpers/groups/discovers_helper.rb'
- 'ee/app/helpers/incident_management/escalation_policy_helper.rb'
- 'ee/app/helpers/incident_management/oncall_schedule_helper.rb'
- 'ee/app/helpers/license_helper.rb'
@ -3065,7 +3097,9 @@ Gitlab/BoundedContexts:
- 'ee/app/helpers/security_helper.rb'
- 'ee/app/helpers/selects_helper.rb'
- 'ee/app/helpers/service_access_token_expiration_helper.rb'
- 'ee/app/helpers/subscriptions/hand_raise_leads_helper.rb'
- 'ee/app/helpers/subscriptions_helper.rb'
- 'ee/app/helpers/subscriptions/hand_raise_leads_helper.rb'
- 'ee/app/helpers/trial_registrations_helper.rb'
- 'ee/app/helpers/trial_status_widget_helper.rb'
- 'ee/app/helpers/trials_helper.rb'
@ -3201,6 +3235,7 @@ Gitlab/BoundedContexts:
- 'ee/app/models/dast/pre_scan_verification.rb'
- 'ee/app/models/dast/pre_scan_verification_step.rb'
- 'ee/app/models/dast/profile.rb'
- 'ee/app/models/dast/profile_schedule.rb'
- 'ee/app/models/dast/profile_tag.rb'
- 'ee/app/models/dast/profiles_pipeline.rb'
- 'ee/app/models/dast/scanner_profiles_build.rb'
@ -3323,10 +3358,15 @@ Gitlab/BoundedContexts:
- 'ee/app/models/elastic/group_index_status.rb'
- 'ee/app/models/elastic/index_setting.rb'
- 'ee/app/models/elastic/migration_record.rb'
- 'ee/app/models/elastic/reindexing_slice.rb'
- 'ee/app/models/elastic/reindexing_subtask.rb'
- 'ee/app/models/elastic/reindexing_task.rb'
- 'ee/app/models/elasticsearch_indexed_namespace.rb'
- 'ee/app/models/elasticsearch_indexed_project.rb'
- 'ee/app/models/embedding/application_record.rb'
- 'ee/app/models/embedding/vertex/gitlab_documentation.rb'
- 'ee/app/models/epic/metrics.rb'
- 'ee/app/models/epic/related_epic_link.rb'
- 'ee/app/models/epic_issue.rb'
- 'ee/app/models/epic_user_mention.rb'
- 'ee/app/models/feature_flag_issue.rb'
@ -3367,6 +3407,8 @@ Gitlab/BoundedContexts:
- 'ee/app/models/ldap_key.rb'
- 'ee/app/models/license.rb'
- 'ee/app/models/members/member_role.rb'
- 'ee/app/models/merge_request/predictions.rb'
- 'ee/app/models/merge_request/review_llm_summary.rb'
- 'ee/app/models/merge_request_block.rb'
- 'ee/app/models/merge_request_diff_detail.rb'
- 'ee/app/models/namespace_limit.rb'
@ -3390,6 +3432,8 @@ Gitlab/BoundedContexts:
- 'ee/app/models/productivity_analytics.rb'
- 'ee/app/models/project_alias.rb'
- 'ee/app/models/project_security_setting.rb'
- 'ee/app/models/protected_branch/required_code_owners_section.rb'
- 'ee/app/models/protected_branch/unprotect_access_level.rb'
- 'ee/app/models/protected_environment.rb'
- 'ee/app/models/protected_environments/approval_rule.rb'
- 'ee/app/models/protected_environments/approval_rules/summarizable.rb'
@ -3496,6 +3540,7 @@ Gitlab/BoundedContexts:
- 'ee/app/policies/issuable_metric_image_policy.rb'
- 'ee/app/policies/iteration_policy.rb'
- 'ee/app/policies/iterations/cadence_policy.rb'
- 'ee/app/policies/merge_request/review_llm_summary_policy.rb'
- 'ee/app/policies/merge_request_diff_policy.rb'
- 'ee/app/policies/path_lock_policy.rb'
- 'ee/app/policies/product_analytics/dashboard_policy.rb'
@ -3968,6 +4013,7 @@ Gitlab/BoundedContexts:
- 'ee/app/services/target_branch_rules/create_service.rb'
- 'ee/app/services/target_branch_rules/destroy_service.rb'
- 'ee/app/services/target_branch_rules/find_service.rb'
- 'ee/app/services/test_hooks/group_service.rb'
- 'ee/app/services/timebox/event_aggregation_service.rb'
- 'ee/app/services/timebox/report_service.rb'
- 'ee/app/services/timebox_report_service.rb'
@ -4160,6 +4206,7 @@ Gitlab/BoundedContexts:
- 'ee/app/workers/personal_access_tokens/groups/policy_worker.rb'
- 'ee/app/workers/personal_access_tokens/instance/policy_worker.rb'
- 'ee/app/workers/product_analytics/initialize_snowplow_product_analytics_worker.rb'
- 'ee/app/workers/product_analytics/move_funnels_worker.rb'
- 'ee/app/workers/product_analytics/post_push_worker.rb'
- 'ee/app/workers/product_analytics/sync_funnels_worker.rb'
- 'ee/app/workers/project_import_schedule_worker.rb'
@ -4624,6 +4671,7 @@ Gitlab/BoundedContexts:
- 'lib/generators/model/model_generator.rb'
- 'lib/generators/post_deployment_migration/post_deployment_migration_generator.rb'
- 'lib/gitaly/server.rb'
- 'lib/gitlab/background_migration/migrate_remediations_for_vulnerability_findings.rb'
- 'lib/gitlab_edition.rb'
- 'lib/gitlab_settings.rb'
- 'lib/gitlab_settings/options.rb'

View File

@ -2,19 +2,6 @@
# Cop supports --autocorrect.
Layout/FirstHashElementIndentation:
Exclude:
- 'app/helpers/projects/project_members_helper.rb'
- 'app/helpers/search_helper.rb'
- 'app/helpers/ssh_keys_helper.rb'
- 'app/helpers/tags_helper.rb'
- 'app/models/application_setting.rb'
- 'app/models/ci/build_metadata.rb'
- 'app/models/concerns/has_wiki_page_slug_attributes.rb'
- 'app/models/concerns/subscribable.rb'
- 'app/models/concerns/taskable.rb'
- 'app/models/diff_note.rb'
- 'app/models/merge_request.rb'
- 'app/models/milestone.rb'
- 'app/models/operations/feature_flags/strategy.rb'
- 'app/models/project.rb'
- 'app/presenters/ci/build_metadata_presenter.rb'
- 'app/serializers/detailed_status_entity.rb'
@ -32,7 +19,6 @@ Layout/FirstHashElementIndentation:
- 'ee/app/models/ee/list.rb'
- 'ee/app/services/app_sec/dast/profiles/update_service.rb'
- 'ee/app/services/elastic/cluster_reindexing_service.rb'
- 'ee/app/services/gitlab_subscriptions/plan_upgrade_service.rb'
- 'ee/app/services/iterations/create_service.rb'
- 'ee/app/services/resource_events/change_iteration_service.rb'
- 'ee/app/services/security/token_revocation_service.rb'

View File

@ -214,7 +214,7 @@ Layout/LineEndStringConcatenationIndentation:
- 'ee/app/graphql/types/vulnerability_state_enum.rb'
- 'ee/app/graphql/types/vulnerability_type.rb'
- 'ee/app/helpers/ee/members_helper.rb'
- 'ee/app/helpers/groups/trial_discover_page_helper.rb'
- 'ee/app/helpers/groups/discovers_helper.rb'
- 'ee/app/helpers/namespaces/free_user_cap_helper.rb'
- 'ee/app/helpers/push_rules_helper.rb'
- 'ee/app/helpers/users/identity_verification_helper.rb'

View File

@ -978,7 +978,6 @@ Layout/LineLength:
- 'ee/app/services/geo/framework_repository_sync_service.rb'
- 'ee/app/services/geo/request_service.rb'
- 'ee/app/services/geo/verification_state_backfill_service.rb'
- 'ee/app/services/gitlab_subscriptions/plan_upgrade_service.rb'
- 'ee/app/services/group_saml/saml_provider/base_service.rb'
- 'ee/app/services/groups/memberships/export_service.rb'
- 'ee/app/services/groups/sync_service.rb'

View File

@ -65,7 +65,6 @@ RSpec/ExpectInHook:
- 'ee/spec/services/geo/blob_download_service_spec.rb'
- 'ee/spec/services/geo/registry_consistency_service_spec.rb'
- 'ee/spec/services/gitlab_subscriptions/fetch_subscription_plans_service_spec.rb'
- 'ee/spec/services/gitlab_subscriptions/plan_upgrade_service_spec.rb'
- 'ee/spec/services/gitlab_subscriptions/reconciliations/calculate_seat_count_data_service_spec.rb'
- 'ee/spec/services/groups/update_repository_storage_service_spec.rb'
- 'ee/spec/services/members/await_service_spec.rb'

View File

@ -1 +1 @@
v17.1.0-rc2
v17.1.0-rc3

View File

@ -54,7 +54,7 @@ gem 'view_component', '~> 3.12.1' # rubocop:todo Gemfile/MissingFeatureCategory
# Supported DBs
gem 'pg', '~> 1.5.6' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'neighbor', '~> 0.2.3' # rubocop:todo Gemfile/MissingFeatureCategory
gem 'neighbor', '~> 0.3.2', feature_category: :duo_chat
gem 'rugged', '~> 1.6' # rubocop:todo Gemfile/MissingFeatureCategory

View File

@ -393,7 +393,7 @@
{"name":"mustermann","version":"3.0.0","platform":"ruby","checksum":"6d3569aa3c3b2f048c60626f48d9b2d561cc8d2ef269296943b03da181c08b67"},
{"name":"mustermann-grape","version":"1.0.2","platform":"ruby","checksum":"6f5309d6a338f801f211c644e8c2d3cc2577a8693f9cd51dadfdb29c1260f5fe"},
{"name":"nap","version":"1.1.0","platform":"ruby","checksum":"949691660f9d041d75be611bb2a8d2fd559c467537deac241f4097d9b5eea576"},
{"name":"neighbor","version":"0.2.3","platform":"ruby","checksum":"70887ac2110d0c7ab243ee988f64359b8bb94a63a0c78542bbeef4f33b1933e5"},
{"name":"neighbor","version":"0.3.2","platform":"ruby","checksum":"b795bbcc24b1b9ae82d9f7e97a3461b0b3607d24a85a7acbed776bd498e7eba8"},
{"name":"nenv","version":"0.3.0","platform":"ruby","checksum":"d9de6d8fb7072228463bf61843159419c969edb34b3cef51832b516ae7972765"},
{"name":"net-http","version":"0.1.1","platform":"ruby","checksum":"75a4e109b6f9af32fad0e98a6180c47aceb415927ca3bd70c8fc3e7dbbabbe86"},
{"name":"net-http-persistent","version":"4.0.1","platform":"ruby","checksum":"2752f4cce05fd1c45e0537c6f3a98fa5a4899efd5f88e63c104ed5f05cbddef9"},

View File

@ -1112,8 +1112,8 @@ GEM
mustermann-grape (1.0.2)
mustermann (>= 1.0.0)
nap (1.1.0)
neighbor (0.2.3)
activerecord (>= 5.2)
neighbor (0.3.2)
activerecord (>= 6.1)
nenv (0.3.0)
net-http (0.1.1)
net-protocol
@ -2094,7 +2094,7 @@ DEPENDENCIES
mini_magick (~> 4.12)
minitest (~> 5.11.0)
multi_json (~> 1.14.1)
neighbor (~> 0.2.3)
neighbor (~> 0.3.2)
net-http (= 0.1.1)
net-ldap (~> 0.17.1)
net-ntp

View File

@ -4,6 +4,7 @@ import {
extractPaginationQueryParameters,
} from '~/analytics/shared/utils';
import Translate from '~/vue_shared/translate';
import { parseBoolean } from '~/lib/utils/common_utils';
import CycleAnalytics from './components/base.vue';
import createStore from './store';
import { buildCycleAnalyticsInitialData } from './utils';
@ -13,7 +14,7 @@ Vue.use(Translate);
export default () => {
const store = createStore();
const el = document.querySelector('#js-cycle-analytics');
const { noAccessSvgPath, noDataSvgPath } = el.dataset;
const { noAccessSvgPath, noDataSvgPath, hasScopedLabelsFeature } = el.dataset;
const initialData = buildCycleAnalyticsInitialData({ ...el.dataset, gon });
const pagination = extractPaginationQueryParameters(window.location.search);
@ -38,6 +39,9 @@ export default () => {
el,
name: 'CycleAnalytics',
apolloProvider: {},
provide: {
hasScopedLabelsFeature: parseBoolean(hasScopedLabelsFeature),
},
store,
render: (createElement) =>
createElement(CycleAnalytics, {

View File

@ -101,6 +101,7 @@ export default {
operators: OPERATORS_IS_NOT,
token: LabelToken,
unique: false,
recentSuggestionsStorageKey: `${this.fullPath}-board-recent-tokens-label`,
symbol: '~',
fetchLabels,
},

View File

@ -22,7 +22,7 @@ const apolloProvider = new VueApollo({
});
function mountBoardApp(el) {
const { boardId, groupId, fullPath, rootPath } = el.dataset;
const { boardId, groupId, fullPath, rootPath, hasScopedLabelsFeature } = el.dataset;
const rawFilterParams = queryToObject(window.location.search, { gatherArrays: true });
@ -82,6 +82,7 @@ function mountBoardApp(el) {
multipleIssueBoardsAvailable: parseBoolean(el.dataset.multipleBoardsAvailable),
scopedIssueBoardFeatureEnabled: parseBoolean(el.dataset.scopedIssueBoardFeatureEnabled),
allowSubEpics: false,
hasScopedLabelsFeature: parseBoolean(hasScopedLabelsFeature),
},
render: (createComponent) => createComponent(BoardApp),
});

View File

@ -42,10 +42,10 @@ export default {
variables,
});
if (isEmpty(data?.mlModelDestroy?.errors)) {
if (isEmpty(data?.mlModelDelete?.errors)) {
this.$emit('model-deleted');
} else {
this.handleError(new Error(data.mlModelDestroy.errors.join(', ')));
this.handleError(new Error(data.mlModelDelete.errors.join(', ')));
}
} catch (error) {
this.handleError(error);

View File

@ -1,5 +1,5 @@
mutation destroyModel($projectPath: ID!, $id: MlModelID!) {
mlModelDestroy(input: { projectPath: $projectPath, id: $id }) {
mutation deleteModel($projectPath: ID!, $id: MlModelID!) {
mlModelDelete(input: { projectPath: $projectPath, id: $id }) {
errors
}
}

View File

@ -6,6 +6,7 @@ fragment BaseGroup on Group {
id
}
webUrl
organizationEditPath
descriptionHtml
avatarUrl
descendantGroupsCount
@ -16,6 +17,7 @@ fragment BaseGroup on Group {
updatedAt
userPermissions {
removeGroup
viewEditPage
}
maxAccessLevel {
integerValue

View File

@ -28,10 +28,14 @@ const availableProjectActions = (userPermissions) => {
};
const availableGroupActions = (userPermissions) => {
const baseActions = [ACTION_EDIT];
const baseActions = [];
if (userPermissions.viewEditPage) {
baseActions.push(ACTION_EDIT);
}
if (userPermissions.removeGroup) {
return [...baseActions, ACTION_DELETE];
baseActions.push(ACTION_DELETE);
}
return baseActions;
@ -70,7 +74,16 @@ export const formatProjects = (projects) =>
export const formatGroups = (groups) =>
groups.map(
({ id, fullName, webUrl, parent, maxAccessLevel: accessLevel, userPermissions, ...group }) => ({
({
id,
fullName,
webUrl,
parent,
maxAccessLevel: accessLevel,
userPermissions,
organizationEditPath: editPath,
...group
}) => ({
...group,
id: getIdFromGraphQLId(id),
name: fullName,
@ -78,7 +91,7 @@ export const formatGroups = (groups) =>
webUrl,
parent: parent?.id || null,
accessLevel,
editPath: `${webUrl}/-/edit`,
editPath,
availableActions: availableGroupActions(userPermissions),
actionLoadingStates: {
[ACTION_DELETE]: false,

View File

@ -13,6 +13,7 @@ import { formatDate } from '~/lib/utils/datetime_utility';
import { numberToHumanSize } from '~/lib/utils/number_utils';
import {
CREATED_AT,
LAST_PUBLISHED_AT,
CLEANUP_UNSCHEDULED_TEXT,
CLEANUP_SCHEDULED_TEXT,
CLEANUP_ONGOING_TEXT,
@ -41,6 +42,7 @@ export default {
GlTooltip: GlTooltipDirective,
},
mixins: [timeagoMixin],
inject: ['config'],
props: {
image: {
type: Object,
@ -63,6 +65,7 @@ export default {
variables() {
return {
id: this.image.id,
metadataDatabaseEnabled: this.config.isMetadataDatabaseEnabled,
};
},
},
@ -75,11 +78,22 @@ export default {
return this.imageDetails?.project?.visibility === 'public' ? 'eye' : 'eye-slash';
},
formattedCreatedAtDate() {
return formatDate(this.imageDetails.createdAt, 'mmm d, yyyy HH:MM', true);
return this.formatDate(this.imageDetails.createdAt);
},
containsLastPublishedAtDate() {
return Boolean(this.imageDetails.lastPublishedAt);
},
formattedLastPublishedAtDate() {
return this.containsLastPublishedAtDate
? this.formatDate(this.imageDetails.lastPublishedAt)
: '';
},
createdText() {
return sprintf(CREATED_AT, { time: this.formattedCreatedAtDate });
},
lastPublishedAtText() {
return sprintf(LAST_PUBLISHED_AT, { time: this.formattedLastPublishedAtDate });
},
tagCountText() {
if (this.$apollo.queries.containerRepository.loading) {
return s__('ContainerRegistry|-- tags');
@ -115,6 +129,11 @@ export default {
return size ? numberToHumanSize(Number(size)) : null;
},
},
methods: {
formatDate(date) {
return formatDate(date, 'mmm d, yyyy HH:MM', true);
},
},
i18n: {
DELETE_IMAGE_TEXT,
MORE_ACTIONS_TEXT,
@ -168,6 +187,14 @@ export default {
data-testid="created-and-visibility"
/>
</template>
<template v-if="containsLastPublishedAtDate" #metadata-last-published-at>
<metadata-item
icon="calendar"
:text="lastPublishedAtText"
size="xl"
data-testid="last-published-at"
/>
</template>
<template v-if="!deleteButtonDisabled" #right-actions>
<gl-disclosure-dropdown
category="tertiary"

View File

@ -96,7 +96,12 @@ export default {
<slot name="commands"></slot>
</template>
<template v-if="imagesCount" #metadata-count>
<metadata-item data-testid="images-count" icon="container-image" :text="imagesCountText" />
<metadata-item
data-testid="images-count"
icon="container-image"
:text="imagesCountText"
size="xl"
/>
</template>
<template #metadata-exp-policies>
<metadata-item

View File

@ -66,6 +66,7 @@ export const MISSING_MANIFEST_WARNING_TOOLTIP = s__(
);
export const CREATED_AT = s__('ContainerRegistry|Created %{time}');
export const LAST_PUBLISHED_AT = s__('ContainerRegistry|Last published at %{time}');
export const NOT_AVAILABLE_TEXT = __('Not applicable.');
export const NOT_AVAILABLE_SIZE = __('0 B');

View File

@ -1,7 +1,11 @@
query getContainerRepositoryMetadata($id: ContainerRepositoryID!) {
query getContainerRepositoryMetadata(
$id: ContainerRepositoryID!
$metadataDatabaseEnabled: Boolean!
) {
containerRepository(id: $id) {
id
tagsCount
size
size @include(if: $metadataDatabaseEnabled)
lastPublishedAt @include(if: $metadataDatabaseEnabled)
}
}

View File

@ -19,11 +19,18 @@ export default class Wikis {
const listToggles = document.querySelectorAll('.js-wiki-list-toggle');
listToggles.forEach((listToggle) => {
listToggle.querySelector('.js-wiki-list-expand-button')?.addEventListener('click', () => {
listToggle.classList.remove('collapsed');
listToggle.querySelectorAll('a').forEach((link) => {
link.addEventListener('click', (e) => e.stopPropagation());
});
listToggle.querySelector('.js-wiki-list-collapse-button')?.addEventListener('click', () => {
listToggle.classList.add('collapsed');
listToggle.addEventListener('click', (e) => {
if (listToggle.classList.contains('collapsed')) {
listToggle.classList.remove('collapsed');
} else {
listToggle.classList.add('collapsed');
}
e.stopImmediatePropagation();
});
});

View File

@ -267,14 +267,24 @@ export function urlQueryToFilter(
* based on provided recentSuggestionsStorageKey
*
* @param {String} recentSuggestionsStorageKey
* @param {Array} appliedTokens
* @param {Function} valueIdentifier
* @returns
*/
export function getRecentlyUsedSuggestions(recentSuggestionsStorageKey) {
export function getRecentlyUsedSuggestions(
recentSuggestionsStorageKey,
appliedTokens,
valueIdentifier,
) {
let recentlyUsedSuggestions = [];
if (AccessorUtilities.canUseLocalStorage()) {
recentlyUsedSuggestions = JSON.parse(localStorage.getItem(recentSuggestionsStorageKey)) || [];
}
return recentlyUsedSuggestions;
return recentlyUsedSuggestions.filter((suggestion) => {
return !appliedTokens?.some(
(appliedToken) => appliedToken.value.data === valueIdentifier(suggestion),
);
});
}
/**

View File

@ -69,15 +69,20 @@ export default {
default: () => [],
},
valueIdentifier: {
type: String,
type: Function,
required: false,
default: 'id',
default: (token) => token.id,
},
searchBy: {
type: String,
required: false,
default: undefined,
},
appliedTokens: {
type: Array,
required: false,
default: () => [],
},
},
data() {
return {
@ -85,7 +90,11 @@ export default {
searchKey: '',
selectedTokens: [],
recentSuggestions: this.config.recentSuggestionsStorageKey
? getRecentlyUsedSuggestions(this.config.recentSuggestionsStorageKey) ?? []
? getRecentlyUsedSuggestions(
this.config.recentSuggestionsStorageKey,
this.appliedTokens,
this.valueIdentifier,
) ?? []
: [],
};
},
@ -97,10 +106,10 @@ export default {
return !this.config.suggestionsDisabled;
},
recentTokenIds() {
return this.recentSuggestions.map((tokenValue) => tokenValue[this.valueIdentifier]);
return this.recentSuggestions.map(this.valueIdentifier);
},
preloadedTokenIds() {
return this.preloadedSuggestions.map((tokenValue) => tokenValue[this.valueIdentifier]);
return this.preloadedSuggestions.map(this.valueIdentifier);
},
activeTokenValue() {
const data =
@ -127,8 +136,8 @@ export default {
? this.suggestions
: this.suggestions.filter(
(tokenValue) =>
!this.recentTokenIds.includes(tokenValue[this.valueIdentifier]) &&
!this.preloadedTokenIds.includes(tokenValue[this.valueIdentifier]),
!this.recentTokenIds.includes(this.valueIdentifier(tokenValue)) &&
!this.preloadedTokenIds.includes(this.valueIdentifier(tokenValue)),
);
return this.applyMaxSuggestions(suggestions);
@ -261,7 +270,7 @@ export default {
if (
this.isRecentSuggestionsEnabled &&
activeTokenValue &&
!this.preloadedTokenIds.includes(activeTokenValue[this.valueIdentifier])
!this.preloadedTokenIds.includes(this.valueIdentifier(activeTokenValue))
) {
setTokenValueToRecentlyUsed(this.config.recentSuggestionsStorageKey, activeTokenValue);
}

View File

@ -38,7 +38,12 @@ export default {
},
methods: {
getActiveEmoji(emojis, data) {
return emojis.find((emoji) => emoji.name.toLowerCase() === stripQuotes(data).toLowerCase());
return emojis.find(
(emoji) => this.getEmojiName(emoji).toLowerCase() === stripQuotes(data).toLowerCase(),
);
},
getEmojiName(emoji) {
return emoji.name;
},
fetchEmojis(searchTerm) {
this.loading = true;
@ -67,24 +72,24 @@ export default {
:suggestions="emojis"
:suggestions-loading="loading"
:get-active-token-value="getActiveEmoji"
value-identifier="name"
:value-identifier="getEmojiName"
v-bind="$attrs"
@fetch-suggestions="fetchEmojis"
v-on="$listeners"
>
<template #view="{ viewTokenProps: { inputValue, activeTokenValue } }">
<gl-emoji v-if="activeTokenValue" :data-name="activeTokenValue.name" />
<gl-emoji v-if="activeTokenValue" :data-name="getEmojiName(activeTokenValue)" />
<template v-else>{{ inputValue }}</template>
</template>
<template #suggestions-list="{ suggestions }">
<gl-filtered-search-suggestion
v-for="emoji in suggestions"
:key="emoji.name"
:value="emoji.name"
:key="getEmojiName(emoji)"
:value="getEmojiName(emoji)"
>
<div class="gl-display-flex">
<gl-emoji class="gl-mr-3" :data-name="emoji.name" />
{{ emoji.name }}
<gl-emoji class="gl-mr-3" :data-name="getEmojiName(emoji)" />
{{ getEmojiName(emoji) }}
</div>
</gl-filtered-search-suggestion>
</template>

View File

@ -138,6 +138,7 @@ export default {
:suggestions="labels"
:get-active-token-value="getActiveLabel"
:default-suggestions="defaultLabels"
:value-identifier="getLabelName"
v-bind="$attrs"
@fetch-suggestions="fetchLabels"
v-on="$listeners"

View File

@ -57,10 +57,14 @@ export default {
return (
milestones.find(
(milestone) => milestone.title.toLowerCase() === stripQuotes(data).toLowerCase(),
(milestone) =>
this.getMilestoneTitle(milestone).toLowerCase() === stripQuotes(data).toLowerCase(),
) || this.defaultMilestones.find(({ value }) => value === data)
);
},
getMilestoneTitle(milestone) {
return milestone.title;
},
fetchMilestonesBySearchTerm(search) {
return this.$apollo
.query({
@ -101,20 +105,21 @@ export default {
:suggestions="milestones"
:suggestions-loading="loading"
:get-active-token-value="getActiveMilestone"
:value-identifier="getMilestoneTitle"
v-bind="$attrs"
@fetch-suggestions="fetchMilestones"
v-on="$listeners"
>
<template #view="{ viewTokenProps: { inputValue, activeTokenValue } }">
%{{ activeTokenValue ? activeTokenValue.title : inputValue }}
%{{ activeTokenValue ? getMilestoneTitle(activeTokenValue) : inputValue }}
</template>
<template #suggestions-list="{ suggestions }">
<gl-filtered-search-suggestion
v-for="milestone in suggestions"
:key="milestone.id"
:value="milestone.title"
:value="getMilestoneTitle(milestone)"
>
{{ milestone.title }}
{{ getMilestoneTitle(milestone) }}
</gl-filtered-search-suggestion>
</template>
</base-token>

View File

@ -56,11 +56,14 @@ export default {
},
methods: {
getActiveUser(users, data) {
return users.find((user) => user.username.toLowerCase() === data.toLowerCase());
return users.find((user) => this.getUsername(user).toLowerCase() === data.toLowerCase());
},
getAvatarUrl(user) {
return user?.avatarUrl || user?.avatar_url;
},
getUsername(user) {
return user.username;
},
displayNameFor(username) {
return this.getActiveUser(this.allUsers, username)?.name || username;
},
@ -115,7 +118,7 @@ export default {
:get-active-token-value="getActiveUser"
:default-suggestions="defaultUsers"
:preloaded-suggestions="preloadedUsers"
value-identifier="username"
:value-identifier="getUsername"
v-bind="$attrs"
@fetch-suggestions="fetchUsers"
v-on="$listeners"
@ -144,22 +147,22 @@ export default {
<template #suggestions-list="{ suggestions, selections = [] }">
<gl-filtered-search-suggestion
v-for="user in suggestions"
:key="user.username"
:value="user.username"
:key="getUsername(user)"
:value="getUsername(user)"
>
<div
class="gl-display-flex gl-align-items-center"
:class="{ 'gl-pl-6': !selections.includes(user.username) }"
:class="{ 'gl-pl-6': !selections.includes(getUsername(user)) }"
>
<gl-icon
v-if="selections.includes(user.username)"
v-if="selections.includes(getUsername(user))"
name="check"
class="gl-mr-3 gl-text-secondary gl-flex-shrink-0"
/>
<gl-avatar :size="32" :src="getAvatarUrl(user)" />
<div>
<div>{{ user.name }}</div>
<div>@{{ user.username }}</div>
<div>@{{ getUsername(user) }}</div>
</div>
</div>
</gl-filtered-search-suggestion>

View File

@ -20,6 +20,14 @@
}
}
.board-swimlanes-headers {
background-color: $white;
.gl-dark & {
background-color: var(--gray-10);
}
}
.boards-list,
.board-swimlanes {
flex-grow: 1;

View File

@ -89,41 +89,18 @@
padding: 0 $gl-padding;
}
a {
&:hover,
&.active {
text-decoration: none;
span {
text-decoration: underline;
}
}
}
.active > .wiki-list {
background-color: var(--gray-50, $gray-50);
}
.wiki-list {
padding: $gl-spacing-scale-2 $gl-spacing-scale-3;
margin-bottom: $gl-spacing-scale-1;
border-radius: $gl-border-radius-base;
min-height: 30px;
&:hover {
background: var(--gray-50, $gray-50);
a {
color: $black;
}
.wiki-list-create-child-button {
display: block;
box-shadow: none;
&:focus {
box-shadow: 0 0 0 1px #fff, 0 0 0 3px $blue-400;
}
&:active {
background: $gray-100 !important;
box-shadow: 0 0 0 1px #fff, 0 0 0 3px $blue-400;
}
}
}
}
@ -131,10 +108,6 @@
.wiki-list-expand-button,
.wiki-list-collapse-button {
color: $gray-400;
&:hover {
color: $black;
}
}
ul.wiki-pages,
@ -147,10 +120,6 @@
ul.wiki-pages ul {
padding-left: 20px;
}
.wiki-sidebar-header {
padding: 0 $gl-padding $gl-padding;
}
}
ul.wiki-pages-list.content-list {
@ -178,11 +147,6 @@ ul.wiki-pages-list.content-list {
display: none;
}
.wiki-list-expand-button,
.wiki-list-collapse-button {
left: -$gl-spacing-scale-5;
}
.wiki-list-expand-button {
display: none;
}

View File

@ -13,6 +13,11 @@ module Types
null: false,
description: 'Web URL of the group.'
field :organization_edit_path, GraphQL::Types::String,
null: true,
description: 'Path for editing group at the organization level.',
alpha: { milestone: '17.1' }
field :avatar_url,
type: GraphQL::Types::String,
null: true,
@ -417,6 +422,15 @@ module Types
end
end
def organization_edit_path
return if group.organization.nil?
::Gitlab::Routing.url_helpers.edit_groups_organization_path(
group.organization,
id: group.to_param
)
end
private
def group

View File

@ -5,7 +5,7 @@ module Types
class Group < BasePermissionType
graphql_name 'GroupPermissions'
abilities :read_group, :create_projects, :create_custom_emoji, :remove_group
abilities :read_group, :create_projects, :create_custom_emoji, :remove_group, :view_edit_page
end
end
end

View File

@ -11,8 +11,8 @@ module Projects::ProjectMembersHelper
else
ERB::Util.html_escape(_("Members can be added by project " \
"%{i_open}Maintainers%{i_close} or %{i_open}Owners%{i_close}")) % {
i_open: '<i>'.html_safe, i_close: '</i>'.html_safe
}
i_open: '<i>'.html_safe, i_close: '</i>'.html_safe
}
end
end

View File

@ -345,11 +345,11 @@ module SearchHelper
[
{
category: 'In this project',
id: issue.id,
label: search_result_sanitize("#{issue.title} (#{issue.to_reference})"),
url: issue_path(issue),
avatar_url: issue.project.avatar_url || ''
category: 'In this project',
id: issue.id,
label: search_result_sanitize("#{issue.title} (#{issue.to_reference})"),
url: issue_path(issue),
avatar_url: issue.project.avatar_url || ''
}
]
end

View File

@ -5,21 +5,21 @@ module SshKeysHelper
title = _('Delete Key')
{
path: path,
method: 'delete',
testid: 'delete-ssh-key-button',
title: title,
aria_label: title,
modal_attributes: {
'data-testid': 'ssh-key-delete-modal',
title: _('Are you sure you want to delete this SSH key?'),
message: _('This action cannot be undone, and will permanently delete the %{key} SSH key') % { key: key.title },
okVariant: 'danger',
okTitle: _('Delete')
},
toggle: 'tooltip',
placement: 'top',
container: 'body'
path: path,
method: 'delete',
testid: 'delete-ssh-key-button',
title: title,
aria_label: title,
modal_attributes: {
'data-testid': 'ssh-key-delete-modal',
title: _('Are you sure you want to delete this SSH key?'),
message: _('This action cannot be undone, and will permanently delete the %{key} SSH key') % { key: key.title },
okVariant: 'danger',
okTitle: _('Delete')
},
toggle: 'tooltip',
placement: 'top',
container: 'body'
}
end
@ -27,19 +27,19 @@ module SshKeysHelper
title = _('Revoke Key')
{
path: path,
method: 'delete',
title: title,
aria_label: title,
modal_attributes: {
title: _('Are you sure you want to revoke this SSH key?'),
message: _('This action cannot be undone, and will permanently delete the %{key} SSH key. All commits signed using this SSH key will be marked as unverified.') % { key: key.title },
okVariant: 'danger',
okTitle: _('Revoke')
},
toggle: 'tooltip',
placement: 'top',
container: 'body'
path: path,
method: 'delete',
title: title,
aria_label: title,
modal_attributes: {
title: _('Are you sure you want to revoke this SSH key?'),
message: _('This action cannot be undone, and will permanently delete the %{key} SSH key. All commits signed using this SSH key will be marked as unverified.') % { key: key.title },
okVariant: 'danger',
okTitle: _('Revoke')
},
toggle: 'tooltip',
placement: 'top',
container: 'body'
}
end

View File

@ -16,9 +16,9 @@ module TagsHelper
def tag_description_help_text
text = s_('TagsPage|Optionally, add a message to the tag. Leaving this blank creates '\
'a %{link_start}lightweight tag.%{link_end}') % {
link_start: '<a href="https://git-scm.com/book/en/v2/Git-Basics-Tagging\" target="_blank" rel="noopener noreferrer">',
link_end: '</a>'
}
link_start: '<a href="https://git-scm.com/book/en/v2/Git-Basics-Tagging\" target="_blank" rel="noopener noreferrer">',
link_end: '</a>'
}
text.html_safe
end

View File

@ -45,10 +45,10 @@ module Ci
scope :with_exposed_artifacts, -> { where(has_exposed_artifacts: true) }
enum timeout_source: {
unknown_timeout_source: 1,
project_timeout_source: 2,
runner_timeout_source: 3,
job_timeout_source: 4
unknown_timeout_source: 1,
project_timeout_source: 2,
runner_timeout_source: 3,
job_timeout_source: 4
}
def update_timeout_state

View File

@ -1235,7 +1235,9 @@ module Ci
end
def modified_paths_since(compare_to_sha)
project.repository.diff_stats(project.repository.merge_base(compare_to_sha, sha), sha).paths
strong_memoize_with(:modified_paths_since, compare_to_sha) do
project.repository.diff_stats(project.repository.merge_base(compare_to_sha, sha), sha).paths
end
end
def all_worktree_paths

View File

@ -7,9 +7,9 @@ module HasWikiPageSlugAttributes
validates :slug, uniqueness: { scope: meta_foreign_key }
validates :slug, length: { maximum: 2048 }, allow_nil: false
validates :canonical, uniqueness: {
scope: meta_foreign_key,
if: :canonical?,
message: 'Only one slug can be canonical per wiki metadata record'
scope: meta_foreign_key,
if: :canonical?,
message: 'Only one slug can be canonical per wiki metadata record'
}
scope :canonical, -> { where(canonical: true) }

View File

@ -41,7 +41,7 @@ module Subscribable
id: subscription.subscribable_id,
subscribable_type: subscription.subscribable_type,
project_id: subscription.project_id
}, subscription)
}, subscription)
end
end
end

View File

@ -112,8 +112,8 @@ module Taskable
def task_completion_status
@task_completion_status ||= {
count: tasks.summary.item_count,
completed_count: tasks.summary.complete_count
count: tasks.summary.item_count,
completed_count: tasks.summary.complete_count
}
end
end

View File

@ -46,9 +46,9 @@ class DiffNote < Note
diff_line = diff_file.line_for_position(self.original_position)
unless diff_line
raise NoteDiffFileCreationError, DIFF_LINE_NOT_FOUND_MESSAGE % {
file_path: diff_file.file_path,
old_line: original_position.old_line,
new_line: original_position.new_line
file_path: diff_file.file_path,
old_line: original_position.old_line,
new_line: original_position.new_line
}
end

View File

@ -184,9 +184,9 @@ class Milestone < ApplicationRecord
.count
{
opened: counts['active'] || 0,
closed: counts['closed'] || 0,
all: counts.values.sum
opened: counts['active'] || 0,
closed: counts['closed'] || 0,
all: counts.values.sum
}
end

View File

@ -27,9 +27,9 @@ module Operations
validates :name,
inclusion: {
in: STRATEGIES.keys,
message: ->(_object, _data) { s_('Validation|strategy name is invalid') }
}
in: STRATEGIES.keys,
message: ->(_object, _data) { s_('Validation|strategy name is invalid') }
}
validate :parameters_validations, if: -> { errors[:name].blank? }
validates :user_list, presence: true, if: -> { name == STRATEGY_GITLABUSERLIST }

View File

@ -83,6 +83,10 @@ module Organizations
organization_users.owners.exists?(user: user)
end
def add_owner(user)
organization_users.owners.create(user: user)
end
def web_url(only_path: nil)
Gitlab::UrlBuilder.build(self, only_path: only_path)
end

View File

@ -1137,6 +1137,10 @@ class Project < ApplicationRecord
!!prometheus_integration&.active?
end
def jenkins_integration_active?
!!jenkins_integration&.active?
end
def personal_namespace_holder?(user)
return false unless personal?
return false unless user

View File

@ -279,6 +279,8 @@ class User < MainClusterwide::ApplicationRecord
has_many :organization_users, class_name: 'Organizations::OrganizationUser', inverse_of: :user
has_many :organizations, through: :organization_users, class_name: 'Organizations::Organization', inverse_of: :users,
disable_joins: true
has_many :owned_organizations, -> { where(organization_users: { access_level: Gitlab::Access::OWNER }) },
through: :organization_users, source: :organization, class_name: 'Organizations::Organization'
has_one :status, class_name: 'UserStatus'
has_one :user_preference
@ -1612,6 +1614,24 @@ class User < MainClusterwide::ApplicationRecord
.where_exists(counts)
end
# All organizations that are owned by this user, and only this user.
def solo_owned_organizations
ownerships_cte = Gitlab::SQL::CTE.new(:ownerships, organization_users.owners, materialized: false)
owned_orgs_from_cte = Organizations::Organization
.joins('INNER JOIN ownerships ON ownerships.organization_id = organizations.id')
counts = Organizations::OrganizationUser
.owners
.joins('INNER JOIN ownerships ON ownerships.organization_id = organization_users.organization_id')
.having('count(organization_users.user_id) = 1')
Organizations::Organization
.with(ownerships_cte.to_arel)
.from(owned_orgs_from_cte, :organizations)
.where_exists(counts)
end
def can_leave_project?(project)
project.namespace != namespace &&
project.member(self)

View File

@ -246,6 +246,10 @@ class MergeRequestPresenter < Gitlab::View::Presenter::Delegated
'%.2f' % merge_request.pipeline_coverage_delta
end
def jenkins_integration_active
project.jenkins_integration_active?
end
private
def cached_can_be_reverted?

View File

@ -242,6 +242,13 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
def terraform_states_anchor_data
if project.terraform_states.exists? && can_read_terraform_state?
terraform_warn_icon = content_tag(
:span,
title: s_('Terraform|Support for periods (`.`) in Terraform state names might break existing states.'),
class: 'gl-ml-2',
data: { toggle: 'tooltip' }
) { sprite_icon('error', css_class: 'gl-text-gray-600') }
AnchorData.new(
true,
statistic_icon('terraform') +
@ -249,7 +256,7 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
terraform_states_count: number_with_delimiter(project.terraform_states.count),
strong_start: '<strong class="project-stat-value">'.html_safe,
strong_end: '</strong>'.html_safe
},
} + terraform_warn_icon,
project_terraform_index_path(project)
)
end

View File

@ -124,6 +124,10 @@ class MergeRequestPollWidgetEntity < Grape::Entity
presenter(merge_request).approvals_widget_type
end
expose :jenkins_integration_active do |merge_request|
presenter(merge_request).jenkins_integration_active
end
private
delegate :current_user, to: :request

View File

@ -43,6 +43,11 @@ module Users
raise Gitlab::Access::AccessDeniedError, "#{current_user} tried to destroy user #{user}!"
end
if user.solo_owned_organizations.present?
user.errors.add(:base, 'You must transfer ownership of organizations before you can remove user')
return user
end
if !delete_solo_owned_groups && user.solo_owned_groups.present?
user.errors.add(:base, 'You must transfer ownership or delete groups before you can remove user')
return user

View File

@ -2,30 +2,32 @@
%aside.right-sidebar.right-sidebar-expanded.wiki-sidebar.js-wiki-sidebar.js-right-sidebar{ data: { "offset-top" => "50", "spy" => "affix" }, 'aria-label': _('Wiki') }
.sidebar-container
.block.wiki-sidebar-header.gl-mb-3.gl-w-full
.block.gl-mb-3.gl-mx-5.gl-block.sm:gl-hidden{ class: '!gl-pt-0' }
%a.gutter-toggle.gl-float-right.d-block.d-md-none.js-sidebar-wiki-toggle{ href: "#" }
= sprite_icon('chevron-double-lg-right', css_class: 'gl-icon')
.gl-display-flex.gl-flex-direction-column.gl-gap-3
- if can?(current_user, :create_wiki, @wiki)
- edit_sidebar_url = wiki_page_path(@wiki, Wiki::SIDEBAR, action: :edit)
- sidebar_link_class = (editing && @page&.slug == Wiki::SIDEBAR) ? 'active' : ''
= link_to edit_sidebar_url, class: sidebar_link_class do
= sprite_icon('pencil', css_class: 'gl-mr-2')
%span= _("Edit sidebar")
- if @sidebar_error.present?
= render 'shared/alert_info', body: s_('Wiki|The sidebar failed to load. You can reload the page to try again.')
.blocks-container
.block.block-first.gl-w-full
.blocks-container{ class: '!gl-px-3' }
.gl-flex.gl-place-content-between.gl-items-center.gl-pb-3.gl-pl-3.gl-pr-1
.gl-flex.gl-items-center
%h2.gl-text-lg.gl-my-0 Pages
%span.gl-px-2 &middot;
= render Pajamas::ButtonComponent.new(category: :tertiary, size: :small, variant: :link, href: wiki_path(@wiki, action: :pages), button_options: { data: { testid: 'view-all-pages-button' }, class: '' }) do
= s_("Wiki|View all")
- if can?(current_user, :create_wiki, @wiki)
- edit_sidebar_url = wiki_page_path(@wiki, Wiki::SIDEBAR, action: :edit)
- sidebar_link_class = (editing && @page&.slug == Wiki::SIDEBAR) ? 'active' : ''
= render Pajamas::ButtonComponent.new(href: edit_sidebar_url, category: :tertiary, size: :small, icon: 'pencil', button_options: { class: "gl-border-l gl-pl-3 has-tooltip #{sidebar_link_class}", title: s_('Wiki|Edit wiki sidebar'), aria: { label: s_('Wiki|Edit wiki sidebar') }})
.block{ class: '!gl-py-0 !gl-border-none !gl-w-full' }
- if @sidebar_page
= render_wiki_content(@sidebar_page)
.gl-px-3.gl-py-2
= render_wiki_content(@sidebar_page)
- elsif @sidebar_wiki_entries
%ul.wiki-pages
- @sidebar_wiki_entries.each do |entry|
= render partial: entry.to_partial_path, object: entry, locals: { context: 'sidebar' }
.block.gl-w-full
- if @sidebar_limited
= link_button_to wiki_path(@wiki, action: :pages), data: { testid: 'view-all-pages-button' }, block: true do
= s_("Wiki|View All Pages")

View File

@ -1,7 +1,8 @@
- wiki_path = wiki_page_path(@wiki, wiki_page)
%li{ class: active_when(params[:id] == wiki_page.slug) }
.gl-relative.gl-display-flex.gl-align-items-center.js-wiki-list-toggle.wiki-list{ data: { testid: 'wiki-list' } }
= render Pajamas::ButtonComponent.new(icon: 'plus', size: :small, href: "#{wiki_path}/{new_page_title}", button_options: { class: 'wiki-list-create-child-button gl-bg-transparent! gl-hover-bg-gray-50! gl-focus-bg-gray-50! gl-absolute gl-top-1/2 -gl-translate-y-1/2 gl-cursor-pointer gl-right-2' })
= link_to wiki_path, data: { testid: 'wiki-page-link', qa_page_name: wiki_page.human_title } do
.gl-relative.gl-flex.gl-items-center.js-wiki-list-toggle.wiki-list.gl-px-3.gl-rounded-base{ data: { testid: 'wiki-list' } }
= link_to wiki_path, class: 'gl-str-truncated', data: { testid: 'wiki-page-link', qa_page_name: wiki_page.human_title } do
= wiki_page.human_title
- plus_tooltip_title = safe_format(s_('Wiki|Create a new page under "%{page_title}"'), { page_title: wiki_page.human_title })
= render Pajamas::ButtonComponent.new(icon: 'plus', size: :small, category: :tertiary, href: "#{wiki_path}/{new_page_title}", button_options: { class: 'wiki-list-create-child-button gl-ml-2 has-tooltip', title: plus_tooltip_title, aria: { label: plus_tooltip_title } })

View File

@ -1,12 +1,13 @@
- wiki_path = wiki_page_path(@wiki, wiki_directory)
%li{ data: { testid: 'wiki-directory-content' } }
.gl-relative.gl-display-flex.gl-align-items-center.js-wiki-list-toggle.wiki-list{ data: { testid: 'wiki-list' } }<
= sprite_icon('chevron-right', css_class: 'js-wiki-list-expand-button wiki-list-expand-button gl-mr-2 gl-cursor-pointer')
= sprite_icon('chevron-down', css_class: 'js-wiki-list-collapse-button wiki-list-collapse-button gl-mr-2 gl-cursor-pointer')
= render Pajamas::ButtonComponent.new(icon: 'plus', size: :small, href: "#{wiki_path}/{new_page_title}", button_options: { class: 'wiki-list-create-child-button gl-bg-transparent! gl-hover-bg-gray-50! gl-focus-bg-gray-50! gl-absolute gl-top-1/2 -gl-translate-y-1/2 gl-cursor-pointer gl-right-2' })
= link_to wiki_path, data: { testid: 'wiki-dir-page-link', qa_page_name: wiki_directory.title } do
.gl-relative.gl-flex.gl-items-center.js-wiki-list-toggle.wiki-list.gl-px-3.gl-rounded-base.gl-cursor-pointer{ data: { testid: 'wiki-list' } }<
= link_to wiki_path, data: { testid: 'wiki-dir-page-link', qa_page_name: wiki_directory.title }, class: 'gl-str-truncated ' do
= wiki_directory.title
- plus_tooltip_title = safe_format(s_('Wiki|Create a new page under "%{page_title}"'), { page_title: wiki_directory.title })
= render Pajamas::ButtonComponent.new(icon: 'plus', size: :small, category: :tertiary, href: "#{wiki_path}/{new_page_title}", button_options: { class: 'wiki-list-create-child-button gl-ml-2 has-tooltip', title: plus_tooltip_title, aria: { label: plus_tooltip_title } })
= sprite_icon('chevron-right', css_class: 'js-wiki-list-expand-button wiki-list-expand-button gl-ml-2 gl-absolute gl-right-2')
= sprite_icon('chevron-down', css_class: 'js-wiki-list-collapse-button wiki-list-collapse-button gl-ml-2 gl-absolute gl-right-2')
%ul{ class: '!gl-pl-5' }
- wiki_directory.entries.each do |entry|
= render partial: entry.to_partial_path, object: entry, locals: { context: context }

View File

@ -112,4 +112,6 @@ Rails.application.configure do
end
config.middleware.insert_before(ActionDispatch::Cookies, Gitlab::Middleware::StripCookies, paths: [%r{^/assets/}])
config.log_level = Gitlab::Utils.to_rails_log_level(ENV["GITLAB_LOG_LEVEL"], :debug)
end

View File

@ -39,7 +39,7 @@ Rails.application.configure do
# Include generic and useful information about system operation, but avoid logging too much
# information to avoid inadvertent exposure of personally identifiable information (PII).
# Note: This configuration does not affect the log level of `Gitlab::Logger` and its subclasses.
config.log_level = :info
config.log_level = Gitlab::Utils.to_rails_log_level(ENV["GITLAB_LOG_LEVEL"], :info)
# Suppress 'Rendered template ...' messages in the log
# source: http://stackoverflow.com/a/16369363

View File

@ -0,0 +1,9 @@
---
name: memoized_rules_changes
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/461342
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152843
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/461658
milestone: '17.1'
group: group::pipeline execution
type: gitlab_com_derisk
default_enabled: false

View File

@ -6,7 +6,9 @@ product_section: sec
product_stage: secure
product_group: static_analysis
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75643
time_frame: 28d

View File

@ -6,7 +6,9 @@ product_section: sec
product_stage: secure
product_group: static_analysis
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75643
time_frame: 28d

View File

@ -6,7 +6,9 @@ product_section: sec
product_stage: secure
product_group: static_analysis
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: '14.7'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76917
time_frame: 28d

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: 28d

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: 28d

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: 28d

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: 28d

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: 28d

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: 28d

View File

@ -6,7 +6,9 @@ product_section: sec
product_stage: secure
product_group: static_analysis
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75643
time_frame: 7d

View File

@ -6,7 +6,9 @@ product_section: sec
product_stage: secure
product_group: static_analysis
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: '14.6'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75643
time_frame: 7d

View File

@ -6,7 +6,9 @@ product_section: sec
product_stage: secure
product_group: static_analysis
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: '14.7'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76917
time_frame: 7d

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: 7d

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: 7d

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: 7d

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: 7d

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: 7d

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: 7d

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: all

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: all

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: all

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: all

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: all

View File

@ -5,7 +5,9 @@ product_section: dev
product_stage: create
product_group: code_review
value_type: number
status: active
status: removed
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152166
milestone_removed: '17.1'
milestone: "15.4"
introduced_by_url: "https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96538"
time_frame: all

View File

@ -67,15 +67,24 @@ module Danger
return "" if files_with_legacy_utils.empty?
<<~MARKDOWN
### Legacy utils
### Legacy CSS utility classes
The following files contain legacy utils:
The following files contain legacy CSS utility classes:
#{format_files_with_legacy_utils_list(files_with_legacy_utils)}
Use the [Tailwind documentation](https://tailwindcss.com/docs/installation) to find the Tailwind
equivalent to these legacy utils. If the Tailwind equivalent is not available it is okay to use the
legacy util for now. The Tailwind equivalent will be made available when the corresponding migration issue
We are in the process of migrating our CSS utility classes to [Tailwind CSS](https://tailwindcss.com/).
The above CSS utility classes do not comply with Tailwind CSS naming conventions.
Please use the Tailwind CSS equivalent if it is available.
For more information on how to determine what CSS utility classes to use see
our [Tailwind CSS developer documentation](https://docs.gitlab.com/ee/development/fe_guide/style/scss.html#tailwind-css).
If the Tailwind CSS equivalent is not available, it is okay to use the legacy CSS utility class for now.
The Tailwind CSS equivalent will be made available when the corresponding migration issue
in [&13521](https://gitlab.com/groups/gitlab-org/-/epics/13521) is completed.
If a legacy CSS utility class is listed above but you did not change it in this MR it is okay to leave for now.
If it is a small or simple MR, feel free to leave the code better than you found it and migrate those
legacy CSS utility classes to Tailwind CSS.
MARKDOWN
end

View File

@ -23,3 +23,4 @@ desired_sharding_key:
table: audit_events_external_audit_event_destinations
sharding_key: namespace_id
belongs_to: external_audit_event_destination
desired_sharding_key_migration_job_name: BackfillAuditEventsStreamingHeadersGroupId

View File

@ -0,0 +1,9 @@
---
migration_job_name: BackfillAuditEventsStreamingHeadersGroupId
description: Backfills sharding key `audit_events_streaming_headers.group_id` from `audit_events_external_audit_event_destinations`.
feature_category: audit_events
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/152963
milestone: '17.1'
queued_migration_version: 20240514142206
finalize_after: '2024-06-22'
finalized_by: # version of the migration that finalized this BBM

View File

@ -0,0 +1,9 @@
---
migration_job_name: BackfillBoardsEpicBoardLabelsGroupId
description: Backfills sharding key `boards_epic_board_labels.group_id` from `boards_epic_boards`.
feature_category: portfolio_management
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/153674
milestone: '17.1'
queued_migration_version: 20240521090846
finalize_after: '2024-06-22'
finalized_by: # version of the migration that finalized this BBM

View File

@ -23,3 +23,4 @@ desired_sharding_key:
table: boards_epic_boards
sharding_key: group_id
belongs_to: epic_board
desired_sharding_key_migration_job_name: BackfillBoardsEpicBoardLabelsGroupId

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddGroupIdToAuditEventsStreamingHeaders < Gitlab::Database::Migration[2.2]
milestone '17.1'
def change
add_column :audit_events_streaming_headers, :group_id, :bigint
end
end

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddGroupIdToBoardsEpicBoardLabels < Gitlab::Database::Migration[2.2]
milestone '17.1'
def change
add_column :boards_epic_board_labels, :group_id, :bigint
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class IndexAuditEventsStreamingHeadersOnGroupId < Gitlab::Database::Migration[2.2]
milestone '17.1'
disable_ddl_transaction!
INDEX_NAME = 'index_audit_events_streaming_headers_on_group_id'
def up
add_concurrent_index :audit_events_streaming_headers, :group_id, name: INDEX_NAME
end
def down
remove_concurrent_index_by_name :audit_events_streaming_headers, INDEX_NAME
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class AddAuditEventsStreamingHeadersGroupIdFk < Gitlab::Database::Migration[2.2]
milestone '17.1'
disable_ddl_transaction!
def up
add_concurrent_foreign_key :audit_events_streaming_headers, :namespaces, column: :group_id, on_delete: :cascade
end
def down
with_lock_retries do
remove_foreign_key :audit_events_streaming_headers, column: :group_id
end
end
end

View File

@ -0,0 +1,25 @@
# frozen_string_literal: true
class AddAuditEventsStreamingHeadersGroupIdTrigger < Gitlab::Database::Migration[2.2]
milestone '17.1'
def up
install_sharding_key_assignment_trigger(
table: :audit_events_streaming_headers,
sharding_key: :group_id,
parent_table: :audit_events_external_audit_event_destinations,
parent_sharding_key: :namespace_id,
foreign_key: :external_audit_event_destination_id
)
end
def down
remove_sharding_key_assignment_trigger(
table: :audit_events_streaming_headers,
sharding_key: :group_id,
parent_table: :audit_events_external_audit_event_destinations,
parent_sharding_key: :namespace_id,
foreign_key: :external_audit_event_destination_id
)
end
end

View File

@ -0,0 +1,40 @@
# frozen_string_literal: true
class QueueBackfillAuditEventsStreamingHeadersGroupId < Gitlab::Database::Migration[2.2]
milestone '17.1'
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
MIGRATION = "BackfillAuditEventsStreamingHeadersGroupId"
DELAY_INTERVAL = 2.minutes
BATCH_SIZE = 1000
SUB_BATCH_SIZE = 100
def up
queue_batched_background_migration(
MIGRATION,
:audit_events_streaming_headers,
:id,
:group_id,
:audit_events_external_audit_event_destinations,
:namespace_id,
:external_audit_event_destination_id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
delete_batched_background_migration(
MIGRATION,
:audit_events_streaming_headers,
:id,
[
:group_id,
:audit_events_external_audit_event_destinations,
:namespace_id,
:external_audit_event_destination_id
]
)
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class IndexBoardsEpicBoardLabelsOnGroupId < Gitlab::Database::Migration[2.2]
milestone '17.1'
disable_ddl_transaction!
INDEX_NAME = 'index_boards_epic_board_labels_on_group_id'
def up
add_concurrent_index :boards_epic_board_labels, :group_id, name: INDEX_NAME
end
def down
remove_concurrent_index_by_name :boards_epic_board_labels, INDEX_NAME
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class AddBoardsEpicBoardLabelsGroupIdFk < Gitlab::Database::Migration[2.2]
milestone '17.1'
disable_ddl_transaction!
def up
add_concurrent_foreign_key :boards_epic_board_labels, :namespaces, column: :group_id, on_delete: :cascade
end
def down
with_lock_retries do
remove_foreign_key :boards_epic_board_labels, column: :group_id
end
end
end

View File

@ -0,0 +1,25 @@
# frozen_string_literal: true
class AddBoardsEpicBoardLabelsGroupIdTrigger < Gitlab::Database::Migration[2.2]
milestone '17.1'
def up
install_sharding_key_assignment_trigger(
table: :boards_epic_board_labels,
sharding_key: :group_id,
parent_table: :boards_epic_boards,
parent_sharding_key: :group_id,
foreign_key: :epic_board_id
)
end
def down
remove_sharding_key_assignment_trigger(
table: :boards_epic_board_labels,
sharding_key: :group_id,
parent_table: :boards_epic_boards,
parent_sharding_key: :group_id,
foreign_key: :epic_board_id
)
end
end

View File

@ -0,0 +1,40 @@
# frozen_string_literal: true
class QueueBackfillBoardsEpicBoardLabelsGroupId < Gitlab::Database::Migration[2.2]
milestone '17.1'
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
MIGRATION = "BackfillBoardsEpicBoardLabelsGroupId"
DELAY_INTERVAL = 2.minutes
BATCH_SIZE = 1000
SUB_BATCH_SIZE = 100
def up
queue_batched_background_migration(
MIGRATION,
:boards_epic_board_labels,
:id,
:group_id,
:boards_epic_boards,
:group_id,
:epic_board_id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
delete_batched_background_migration(
MIGRATION,
:boards_epic_board_labels,
:id,
[
:group_id,
:boards_epic_boards,
:group_id,
:epic_board_id
]
)
end
end

View File

@ -0,0 +1 @@
ad429972fc3b095aa05fd581079e06b79d267c4c5967494ce0c8352d88649ed6

View File

@ -0,0 +1 @@
438ff8300d67659bdd2b144ade85c5613b2e9375499308cdc5a1fdd2532a2fa8

View File

@ -0,0 +1 @@
14ddc0166ab7bc3fd4e69bd6db8613f0935ba40f5235f7a38f7486c1c4f4b51c

View File

@ -0,0 +1 @@
d1fc63768de318cff0ac9d57c56c5d965d5d1bd8c3cc2704fdbf3c4806d66ddc

View File

@ -0,0 +1 @@
8d210ca14b110464a63720a62c1661a97b1e5d2fdcaf764019b159c7a0609563

Some files were not shown because too many files have changed in this diff Show More