From 61cb988554d7d554f0e9727fc73acc9acba5ea8f Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Thu, 23 Nov 2023 15:13:51 +0000 Subject: Add latest changes from gitlab-org/gitlab@master --- .../components/details/ci_resource_header.vue | 12 +- .../list/catalog_list_skeleton_loader.vue | 14 +- .../components/list/ci_resources_list_item.vue | 19 ++- .../fragments/catalog_resource.fragment.graphql | 5 - .../components/states/mr_widget_conflicts.vue | 4 +- .../work_items/components/work_item_detail.vue | 83 +++--------- .../components/work_item_sticky_header.vue | 142 +++++++++++++++++++++ .../stylesheets/page_bundles/merge_requests.scss | 2 +- app/finders/events_finder.rb | 1 - app/finders/members_finder.rb | 9 +- app/models/ci/build_need.rb | 12 +- app/models/ci/build_report_result.rb | 6 +- app/models/ci/build_runner_session.rb | 6 +- app/models/ci/build_trace_metadata.rb | 6 +- app/models/ci/job_annotation.rb | 6 +- app/models/ci/pending_build.rb | 6 +- app/models/ci/running_build.rb | 5 +- app/models/ci/sources/pipeline.rb | 2 +- app/models/ci/unit_test_failure.rb | 6 +- app/models/event.rb | 4 +- app/models/ml/model.rb | 4 + app/models/vulnerability.rb | 2 +- app/services/jira_import/users_mapper_service.rb | 1 + app/services/ml/destroy_model_service.rb | 19 +++ 24 files changed, 264 insertions(+), 112 deletions(-) create mode 100644 app/assets/javascripts/work_items/components/work_item_sticky_header.vue create mode 100644 app/services/ml/destroy_model_service.rb (limited to 'app') diff --git a/app/assets/javascripts/ci/catalog/components/details/ci_resource_header.vue b/app/assets/javascripts/ci/catalog/components/details/ci_resource_header.vue index ff2dcd4393a..0b14a8e81a5 100644 --- a/app/assets/javascripts/ci/catalog/components/details/ci_resource_header.vue +++ b/app/assets/javascripts/ci/catalog/components/details/ci_resource_header.vue @@ -1,6 +1,7 @@ @@ -86,7 +84,7 @@ export default { class="gl-display-flex gl-flex-direction-column gl-align-items-flex-start gl-justify-content-center" >
- {{ fullPath }} + {{ webPath }}
{{ resource.name }}
diff --git a/app/assets/javascripts/ci/catalog/components/list/catalog_list_skeleton_loader.vue b/app/assets/javascripts/ci/catalog/components/list/catalog_list_skeleton_loader.vue index 3722b8e6c59..5de71fa1fc5 100644 --- a/app/assets/javascripts/ci/catalog/components/list/catalog_list_skeleton_loader.vue +++ b/app/assets/javascripts/ci/catalog/components/list/catalog_list_skeleton_loader.vue @@ -37,21 +37,19 @@ export default { > - - + + + + - + - - - - - + diff --git a/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue b/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue index 5bbf11e541f..504d3d38275 100644 --- a/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue +++ b/app/assets/javascripts/ci/catalog/components/list/ci_resources_list_item.vue @@ -3,6 +3,7 @@ import { GlAvatar, GlBadge, GlIcon, GlLink, GlSprintf, GlTooltipDirective } from import { s__ } from '~/locale'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { formatDate, getTimeago } from '~/lib/utils/datetime_utility'; +import { cleanLeadingSeparator } from '~/lib/utils/url_utility'; import { CI_RESOURCE_DETAILS_PAGE_NAME } from '../../router/constants'; export default { @@ -45,6 +46,9 @@ export default { starCount() { return this.resource?.starCount || 0; }, + starIcon() { + return this.starCount > 0 ? 'star' : 'star-o'; + }, hasReleasedVersion() { return Boolean(this.latestVersion?.releasedAt); }, @@ -57,12 +61,12 @@ export default { releasedAt() { return getTimeago().format(this.latestVersion?.releasedAt); }, - resourcePath() { - return `${this.resource.rootNamespace?.name} / ${this.resource.rootNamespace?.fullPath} / `; - }, tagName() { return this.latestVersion?.tagName || this.$options.i18n.unreleased; }, + webPath() { + return cleanLeadingSeparator(this.resource?.webPath); + }, }, methods: { navigateToDetailsPage(e) { @@ -98,20 +102,21 @@ export default { @click="navigateToDetailsPage" />
-
+ {{ webPath }} +
- {{ resourcePath }} {{ resource.name }} + {{ resource.name }}
- {{ tagName }} + {{ tagName }} - + {{ starCount }} diff --git a/app/assets/javascripts/ci/catalog/graphql/fragments/catalog_resource.fragment.graphql b/app/assets/javascripts/ci/catalog/graphql/fragments/catalog_resource.fragment.graphql index a86db4c1b03..0dc16e3492d 100644 --- a/app/assets/javascripts/ci/catalog/graphql/fragments/catalog_resource.fragment.graphql +++ b/app/assets/javascripts/ci/catalog/graphql/fragments/catalog_resource.fragment.graphql @@ -15,10 +15,5 @@ fragment CatalogResourceFields on CiCatalogResource { webUrl } } - rootNamespace { - id - fullPath - name - } webPath } diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue index 55ae390216d..d2c1c914028 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_conflicts.vue @@ -22,14 +22,14 @@ export default { variables() { return this.mergeRequestQueryVariables; }, - update: (data) => data.project.mergeRequest.userPermissions, + update: (data) => data.project?.mergeRequest.userPermissions || {}, }, state: { query: conflictsStateQuery, variables() { return this.mergeRequestQueryVariables; }, - update: (data) => data.project.mergeRequest, + update: (data) => data.project?.mergeRequest || {}, }, }, props: { diff --git a/app/assets/javascripts/work_items/components/work_item_detail.vue b/app/assets/javascripts/work_items/components/work_item_detail.vue index 45d3aa564a5..2440fc7d433 100644 --- a/app/assets/javascripts/work_items/components/work_item_detail.vue +++ b/app/assets/javascripts/work_items/components/work_item_detail.vue @@ -3,12 +3,10 @@ import { isEmpty } from 'lodash'; import { GlAlert, GlSkeletonLoader, - GlLoadingIcon, GlIcon, GlButton, GlTooltipDirective, GlEmptyState, - GlIntersectionObserver, } from '@gitlab/ui'; import noAccessSvg from '@gitlab/svgs/dist/illustrations/analytics/no-access.svg?raw'; import { s__ } from '~/locale'; @@ -17,7 +15,6 @@ import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { isLoggedIn } from '~/lib/utils/common_utils'; import AbuseCategorySelector from '~/abuse_reports/components/abuse_category_selector.vue'; -import ConfidentialityBadge from '~/vue_shared/components/confidentiality_badge.vue'; import { WORKSPACE_PROJECT } from '~/issues/constants'; import { i18n, @@ -52,6 +49,7 @@ import WorkItemDetailModal from './work_item_detail_modal.vue'; import WorkItemAwardEmoji from './work_item_award_emoji.vue'; import WorkItemRelationships from './work_item_relationships/work_item_relationships.vue'; import WorkItemTypeIcon from './work_item_type_icon.vue'; +import WorkItemStickyHeader from './work_item_sticky_header.vue'; export default { i18n, @@ -62,7 +60,6 @@ export default { components: { GlAlert, GlButton, - GlLoadingIcon, GlSkeletonLoader, GlIcon, GlEmptyState, @@ -78,9 +75,8 @@ export default { WorkItemNotes, WorkItemDetailModal, AbuseCategorySelector, - GlIntersectionObserver, - ConfidentialityBadge, WorkItemRelationships, + WorkItemStickyHeader, }, mixins: [glFeatureFlagMixin()], inject: ['fullPath', 'isGroup', 'reportAbusePath'], @@ -235,7 +231,7 @@ export default { return this.isWidgetPresent(WIDGET_TYPE_CURRENT_USER_TODOS); }, showWorkItemCurrentUserTodos() { - return this.$options.isLoggedIn && this.workItemCurrentUserTodos; + return Boolean(this.$options.isLoggedIn && this.workItemCurrentUserTodos); }, currentUserTodos() { return this.workItemCurrentUserTodos?.currentUserTodos?.nodes; @@ -537,62 +533,25 @@ export default { :update-in-progress="updateInProgress" />
- - -
-
- - {{ workItem.title }} - - - - - -
-
-
-
+ :current-user-todos="currentUserTodos" + :show-work-item-current-user-todos="showWorkItemCurrentUserTodos" + :parent-work-item-confidentiality="parentWorkItemConfidentiality" + :update-in-progress="updateInProgress" + :full-path="fullPath" + :is-modal="isModal" + :work-item="workItem" + :is-sticky-header-showing="isStickyHeaderShowing" + :work-item-parent-id="workItemParentId" + :work-item-notifications-subscribed="workItemNotificationsSubscribed" + @hideStickyHeader="hideStickyHeader" + @showStickyHeader="showStickyHeader" + @deleteWorkItem="$emit('deleteWorkItem', { workItemType, workItemId: workItem.id })" + @toggleWorkItemConfidentiality="toggleConfidentiality" + @error="updateError = $event" + @promotedToObjective="$emit('promotedToObjective', workItemIid)" + />
+import { GlLoadingIcon, GlIntersectionObserver } from '@gitlab/ui'; +import { WORKSPACE_PROJECT } from '~/issues/constants'; +import ConfidentialityBadge from '~/vue_shared/components/confidentiality_badge.vue'; +import WorkItemActions from './work_item_actions.vue'; +import WorkItemTodos from './work_item_todos.vue'; + +export default { + components: { + GlIntersectionObserver, + GlLoadingIcon, + WorkItemActions, + WorkItemTodos, + ConfidentialityBadge, + }, + props: { + workItem: { + type: Object, + required: true, + }, + fullPath: { + type: String, + required: true, + }, + isStickyHeaderShowing: { + type: Boolean, + required: true, + }, + workItemNotificationsSubscribed: { + type: Boolean, + required: true, + }, + workItemParentId: { + type: String, + required: false, + default: null, + }, + updateInProgress: { + type: Boolean, + required: false, + default: false, + }, + parentWorkItemConfidentiality: { + type: Boolean, + required: false, + default: false, + }, + showWorkItemCurrentUserTodos: { + type: Boolean, + required: false, + default: false, + }, + isModal: { + type: Boolean, + required: false, + default: false, + }, + currentUserTodos: { + type: Array, + required: false, + default: () => [], + }, + }, + computed: { + canUpdate() { + return this.workItem.userPermissions?.updateWorkItem; + }, + canDelete() { + return this.workItem.userPermissions?.deleteWorkItem; + }, + workItemType() { + return this.workItem.workItemType?.name; + }, + workItemTypeId() { + return this.workItem.workItemType?.id; + }, + projectFullPath() { + return this.workItem.namespace?.fullPath; + }, + }, + WORKSPACE_PROJECT, +}; + + + diff --git a/app/assets/stylesheets/page_bundles/merge_requests.scss b/app/assets/stylesheets/page_bundles/merge_requests.scss index 5422fc0ec0a..e65f716d71a 100644 --- a/app/assets/stylesheets/page_bundles/merge_requests.scss +++ b/app/assets/stylesheets/page_bundles/merge_requests.scss @@ -552,7 +552,7 @@ $tabs-holder-z-index: 250; .mr-widget-section:not(:first-child) > div, .mr-widget-section:not(:first-child) > section, - .mr-widget-section .mr-widget-section > div { + .mr-widget-section .mr-widget-section > div:not(:first-child) { border-top: solid 1px var(--border-color, $border-color); } diff --git a/app/finders/events_finder.rb b/app/finders/events_finder.rb index 7bccfe453ab..4ed447a90ce 100644 --- a/app/finders/events_finder.rb +++ b/app/finders/events_finder.rb @@ -61,7 +61,6 @@ class EventsFinder def by_current_user_access(events) events.merge(Project.public_or_visible_to_user(current_user)) .joins(:project) - .allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417462") end # rubocop: enable CodeReuse/ActiveRecord diff --git a/app/finders/members_finder.rb b/app/finders/members_finder.rb index 6348bceb157..5b4b83652df 100644 --- a/app/finders/members_finder.rb +++ b/app/finders/members_finder.rb @@ -90,10 +90,8 @@ class MembersFinder # enumerate the columns here since we are enumerating them in the union and want to be immune to # column caching issues when adding/removing columns - members = Member.select(*Member.column_names) - .includes(:user).from([Arel.sql("(#{sql}) AS #{Member.table_name}")]) # rubocop: disable CodeReuse/ActiveRecord - # The left join with the table users in the method distinct_on needs to be resolved - members.allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417456") + Member.select(*Member.column_names) + .preload(:user).from([Arel.sql("(#{sql}) AS #{Member.table_name}")]) # rubocop: disable CodeReuse/ActiveRecord -- TODO: Usage of `from` forces us to use this. end def distinct_on(union) @@ -102,8 +100,7 @@ class MembersFinder <<~SQL SELECT DISTINCT ON (user_id, invite_email) #{member_columns} FROM (#{union.to_sql}) AS #{member_union_table} - LEFT JOIN users on users.id = member_union.user_id - LEFT JOIN project_authorizations on project_authorizations.user_id = users.id + LEFT JOIN project_authorizations on project_authorizations.user_id = member_union.user_id AND project_authorizations.project_id = #{project.id} ORDER BY user_id, diff --git a/app/models/ci/build_need.rb b/app/models/ci/build_need.rb index 1831b7868f9..fb0a02ca56e 100644 --- a/app/models/ci/build_need.rb +++ b/app/models/ci/build_need.rb @@ -11,7 +11,12 @@ module Ci columns_changing_default :partition_id - belongs_to :build, class_name: "Ci::Processable", foreign_key: :build_id, inverse_of: :needs + belongs_to :build, + ->(need) { in_partition(need) }, + class_name: 'Ci::Processable', + foreign_key: :build_id, + partition_foreign_key: :partition_id, + inverse_of: :needs partitionable scope: :build @@ -19,7 +24,10 @@ module Ci validates :name, presence: true, length: { maximum: MAX_JOB_NAME_LENGTH } validates :optional, inclusion: { in: [true, false] } - scope :scoped_build, -> { where("#{Ci::Build.quoted_table_name}.id = #{quoted_table_name}.build_id") } + scope :scoped_build, -> { + where(arel_table[:build_id].eq(Ci::Build.arel_table[:id])) + .where(arel_table[:partition_id].eq(Ci::Build.arel_table[:partition_id])) + } scope :artifacts, -> { where(artifacts: true) } end end diff --git a/app/models/ci/build_report_result.rb b/app/models/ci/build_report_result.rb index 90b621b8da1..1dabf05e03c 100644 --- a/app/models/ci/build_report_result.rb +++ b/app/models/ci/build_report_result.rb @@ -9,7 +9,11 @@ module Ci self.primary_key = :build_id - belongs_to :build, class_name: "Ci::Build", inverse_of: :report_results + belongs_to :build, + ->(report_result) { in_partition(report_result) }, + class_name: 'Ci::Build', + partition_foreign_key: :partition_id, + inverse_of: :report_results belongs_to :project, class_name: "Project", inverse_of: :build_report_results partitionable scope: :build diff --git a/app/models/ci/build_runner_session.rb b/app/models/ci/build_runner_session.rb index e197217bb70..223cb9c5d68 100644 --- a/app/models/ci/build_runner_session.rb +++ b/app/models/ci/build_runner_session.rb @@ -15,7 +15,11 @@ module Ci self.table_name = 'ci_builds_runner_session' - belongs_to :build, class_name: 'Ci::Build', inverse_of: :runner_session + belongs_to :build, + ->(runner_session) { in_partition(runner_session) }, + class_name: 'Ci::Build', + partition_foreign_key: :partition_id, + inverse_of: :runner_session partitionable scope: :build diff --git a/app/models/ci/build_trace_metadata.rb b/app/models/ci/build_trace_metadata.rb index 525cb08f2ca..859dad29a06 100644 --- a/app/models/ci/build_trace_metadata.rb +++ b/app/models/ci/build_trace_metadata.rb @@ -11,7 +11,11 @@ module Ci self.table_name = 'ci_build_trace_metadata' self.primary_key = :build_id - belongs_to :build, class_name: 'Ci::Build' + belongs_to :build, + ->(trace_metadata) { in_partition(trace_metadata) }, + class_name: 'Ci::Build', + partition_foreign_key: :partition_id, + inverse_of: :trace_metadata belongs_to :trace_artifact, class_name: 'Ci::JobArtifact' partitionable scope: :build diff --git a/app/models/ci/job_annotation.rb b/app/models/ci/job_annotation.rb index a6ce4196cc1..d56830433b1 100644 --- a/app/models/ci/job_annotation.rb +++ b/app/models/ci/job_annotation.rb @@ -8,7 +8,11 @@ module Ci self.table_name = :p_ci_job_annotations self.primary_key = :id - belongs_to :job, class_name: 'Ci::Build', inverse_of: :job_annotations + belongs_to :job, + ->(job_annotation) { in_partition(job_annotation) }, + class_name: 'Ci::Build', + partition_foreign_key: :partition_id, + inverse_of: :job_annotations partitionable scope: :job, partitioned: true diff --git a/app/models/ci/pending_build.rb b/app/models/ci/pending_build.rb index dc9a8b7a1bf..80cc74a9946 100644 --- a/app/models/ci/pending_build.rb +++ b/app/models/ci/pending_build.rb @@ -9,7 +9,11 @@ module Ci columns_changing_default :partition_id belongs_to :project - belongs_to :build, class_name: 'Ci::Build' + + belongs_to :build, # rubocop: disable Rails/InverseOf -- this relation is not present on build + ->(pending_build) { in_partition(pending_build) }, + class_name: 'Ci::Build', + partition_foreign_key: :partition_id belongs_to :namespace, inverse_of: :pending_builds, class_name: 'Namespace' partitionable scope: :build diff --git a/app/models/ci/running_build.rb b/app/models/ci/running_build.rb index cfdc47de531..22753930b3c 100644 --- a/app/models/ci/running_build.rb +++ b/app/models/ci/running_build.rb @@ -17,7 +17,10 @@ module Ci partitionable scope: :build belongs_to :project - belongs_to :build, class_name: 'Ci::Build' + belongs_to :build, # rubocop: disable Rails/InverseOf -- this relation is not present on build + ->(running_build) { in_partition(running_build) }, + class_name: 'Ci::Build', + partition_foreign_key: :partition_id belongs_to :runner, class_name: 'Ci::Runner' enum runner_type: ::Ci::Runner.runner_types diff --git a/app/models/ci/sources/pipeline.rb b/app/models/ci/sources/pipeline.rb index 3c6a5563846..6c9d3b9c19f 100644 --- a/app/models/ci/sources/pipeline.rb +++ b/app/models/ci/sources/pipeline.rb @@ -13,7 +13,7 @@ module Ci belongs_to :project, class_name: "::Project" belongs_to :pipeline, class_name: "Ci::Pipeline", inverse_of: :source_pipeline - belongs_to :build, class_name: "Ci::Build", foreign_key: :source_job_id, inverse_of: :sourced_pipelines + belongs_to :build, class_name: 'Ci::Build', foreign_key: :source_job_id, inverse_of: :sourced_pipelines belongs_to :source_project, class_name: "::Project", foreign_key: :source_project_id belongs_to :source_job, class_name: "CommitStatus", foreign_key: :source_job_id diff --git a/app/models/ci/unit_test_failure.rb b/app/models/ci/unit_test_failure.rb index 37893f6cdae..bec74d8be20 100644 --- a/app/models/ci/unit_test_failure.rb +++ b/app/models/ci/unit_test_failure.rb @@ -12,7 +12,11 @@ module Ci validates :unit_test, :build, :failed_at, presence: true belongs_to :unit_test, class_name: "Ci::UnitTest", foreign_key: :unit_test_id - belongs_to :build, class_name: "Ci::Build", foreign_key: :build_id + belongs_to :build, + ->(unit_test_failure) { in_partition(unit_test_failure) }, + class_name: 'Ci::Build', + foreign_key: :build_id, + partition_foreign_key: :partition_id partitionable scope: :build diff --git a/app/models/event.rb b/app/models/event.rb index 3ff5a46f2d9..7b91727f7d4 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -113,8 +113,8 @@ class Event < ApplicationRecord scope :with_associations, -> do # We're using preload for "push_event_payload" as otherwise the association # is not always available (depending on the query being built). - includes(:author, :project, project: [:project_feature, :import_data, :namespace]) - .preload(:target, :push_event_payload) + includes(:project, project: [:project_feature, :import_data, :namespace]) + .preload(:author, :target, :push_event_payload) end scope :for_milestone_id, ->(milestone_id) { where(target_type: "Milestone", target_id: milestone_id) } diff --git a/app/models/ml/model.rb b/app/models/ml/model.rb index b6f7e9a0639..bec03c05151 100644 --- a/app/models/ml/model.rb +++ b/app/models/ml/model.rb @@ -31,6 +31,10 @@ module Ml scope :by_name, ->(name) { where("ml_models.name LIKE ?", "%#{sanitize_sql_like(name)}%") } # rubocop:disable GitlabSecurity/SqlInjection scope :by_project, ->(project) { where(project_id: project.id) } + def all_packages + Packages::MlModel::Package.where(project: project, id: versions.select(:package_id)) + end + def valid_default_experiment? return unless default_experiment diff --git a/app/models/vulnerability.rb b/app/models/vulnerability.rb index da607dcb771..6bf63bab82c 100644 --- a/app/models/vulnerability.rb +++ b/app/models/vulnerability.rb @@ -5,7 +5,7 @@ class Vulnerability < ApplicationRecord include EachBatch include IgnorableColumns - ignore_column %i[epic_id milestone_id last_edited_at last_edited_by_id + ignore_column %i[due_date epic_id milestone_id last_edited_at last_edited_by_id start_date start_date_sourcing_milestone_id updated_by_id], remove_with: '16.9', remove_after: '2024-01-19' diff --git a/app/services/jira_import/users_mapper_service.rb b/app/services/jira_import/users_mapper_service.rb index 13e0dd5120e..45a607dd2b0 100644 --- a/app/services/jira_import/users_mapper_service.rb +++ b/app/services/jira_import/users_mapper_service.rb @@ -63,6 +63,7 @@ module JiraImport relations << User.by_emails(jira_emails).select("users.id, users.name, users.username, emails.email as user_email") User.from_union(relations).id_in(project_member_ids).select("users.id as user_id, users.name as name, users.username as username, user_email") + .allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/432608") end end diff --git a/app/services/ml/destroy_model_service.rb b/app/services/ml/destroy_model_service.rb new file mode 100644 index 00000000000..308d289fbe1 --- /dev/null +++ b/app/services/ml/destroy_model_service.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Ml + class DestroyModelService + def initialize(model, user) + @model = model + @user = user + end + + def execute + return unless @model.destroy + + ::Packages::MarkPackagesForDestructionService.new( + packages: @model.all_packages, + current_user: @user + ).execute + end + end +end -- cgit v1.2.3