Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-07-20 15:07:25 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-07-20 15:07:25 +0300
commit07b1e2691206717206d40f9c7f0abfd1a30ecbdd (patch)
treea5b6b9655d73f158c22ecc70bcb65535226fd4ac /app
parent65a0673d76bb86d6acca6dc3ab42dc91a04f56c2 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/editor/schema/ci.json28
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/failed_jobs_list.vue11
-rw-r--r--app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/pipeline_failed_jobs_widget.vue1
-rw-r--r--app/assets/javascripts/vue_shared/components/markdown/field.vue3
-rw-r--r--app/assets/javascripts/work_items/components/item_state.vue10
-rw-r--r--app/assets/javascripts/work_items/components/item_title.vue2
-rw-r--r--app/assets/javascripts/work_items/components/work_item_assignees.vue4
-rw-r--r--app/assets/javascripts/work_items/components/work_item_detail.vue6
-rw-r--r--app/assets/javascripts/work_items/components/work_item_labels.vue4
-rw-r--r--app/assets/stylesheets/components/content_editor.scss12
-rw-r--r--app/assets/stylesheets/page_bundles/work_items.scss35
-rw-r--r--app/finders/group_descendants_finder.rb2
-rw-r--r--app/finders/group_members_finder.rb5
-rw-r--r--app/finders/group_projects_finder.rb16
-rw-r--r--app/models/ci/catalog/resource.rb1
-rw-r--r--app/models/ci/catalog/resources/version.rb21
-rw-r--r--app/models/concerns/approvable.rb2
-rw-r--r--app/models/group.rb23
-rw-r--r--app/models/packages/dependency.rb4
-rw-r--r--app/models/packages/package.rb3
-rw-r--r--app/models/project.rb2
-rw-r--r--app/models/release.rb2
-rw-r--r--app/policies/concerns/find_group_projects.rb4
-rw-r--r--app/policies/group_policy.rb2
-rw-r--r--app/services/clusters/management/validate_management_project_permissions_service.rb2
-rw-r--r--app/services/packages/npm/generate_metadata_service.rb35
-rw-r--r--app/validators/json_schemas/build_metadata_secrets.json21
-rw-r--r--app/views/shared/access_tokens/_form.html.haml8
-rw-r--r--app/workers/merge_requests/mergeability_check_batch_worker.rb3
29 files changed, 198 insertions, 74 deletions
diff --git a/app/assets/javascripts/editor/schema/ci.json b/app/assets/javascripts/editor/schema/ci.json
index 3a1188d7aab..ed1d3d8af08 100644
--- a/app/assets/javascripts/editor/schema/ci.json
+++ b/app/assets/javascripts/editor/schema/ci.json
@@ -703,6 +703,21 @@
}
]
},
+ "azure_key_vault": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string"
+ },
+ "version": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "name"
+ ],
+ "additionalProperties": false
+ },
"file": {
"type": "boolean",
"default": true,
@@ -713,8 +728,17 @@
"description": "Specifies the JWT variable that should be used to authenticate with Hashicorp Vault."
}
},
- "required": [
- "vault"
+ "anyOf": [
+ {
+ "required": [
+ "vault"
+ ]
+ },
+ {
+ "required": [
+ "azure_key_vault"
+ ]
+ }
],
"additionalProperties": false
}
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/failed_jobs_list.vue b/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/failed_jobs_list.vue
index 1c1d0bc7273..6f5467cb018 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/failed_jobs_list.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/failed_jobs_list.vue
@@ -20,6 +20,10 @@ export default {
},
inject: ['graphqlPath'],
props: {
+ failedJobsCount: {
+ required: true,
+ type: Number,
+ },
isPipelineActive: {
required: true,
type: Boolean,
@@ -95,6 +99,13 @@ export default {
isActive(flag) {
this.handlePolling(flag);
},
+ failedJobsCount(count) {
+ // If the REST data is updated first, we force a refetch
+ // to keep them in sync
+ if (this.failedJobs.length !== count) {
+ this.$apollo.queries.failedJobs.refetch();
+ }
+ },
},
mounted() {
if (!this.isActive && !this.isPipelineActive) {
diff --git a/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/pipeline_failed_jobs_widget.vue b/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/pipeline_failed_jobs_widget.vue
index a30914869f7..8b28807b964 100644
--- a/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/pipeline_failed_jobs_widget.vue
+++ b/app/assets/javascripts/pipelines/components/pipelines_list/failure_widget/pipeline_failed_jobs_widget.vue
@@ -107,6 +107,7 @@ export default {
<gl-collapse v-model="isExpanded">
<failed-jobs-list
v-if="isExpanded"
+ :failed-jobs-count="failedJobsCount"
:is-pipeline-active="isPipelineActive"
:pipeline-iid="pipelineIid"
:project-path="projectPath"
diff --git a/app/assets/javascripts/vue_shared/components/markdown/field.vue b/app/assets/javascripts/vue_shared/components/markdown/field.vue
index 7c569763a75..aeb03625a37 100644
--- a/app/assets/javascripts/vue_shared/components/markdown/field.vue
+++ b/app/assets/javascripts/vue_shared/components/markdown/field.vue
@@ -398,7 +398,6 @@ export default {
v-show="previewMarkdown"
ref="markdown-preview"
class="js-vue-md-preview md-preview-holder gl-px-5"
- :class="{ md: !hasSuggestion }"
>
<suggestions
v-if="hasSuggestion"
@@ -409,7 +408,7 @@ export default {
:help-page-path="helpPagePath"
/>
<template v-else>
- <div v-safe-html:[$options.safeHtmlConfig]="markdownPreview"></div>
+ <div v-safe-html:[$options.safeHtmlConfig]="markdownPreview" class="md"></div>
</template>
</div>
<div
diff --git a/app/assets/javascripts/work_items/components/item_state.vue b/app/assets/javascripts/work_items/components/item_state.vue
index 9053d8972de..2100cc67c8c 100644
--- a/app/assets/javascripts/work_items/components/item_state.vue
+++ b/app/assets/javascripts/work_items/components/item_state.vue
@@ -63,17 +63,9 @@ export default {
:options="$options.states"
:disabled="disabled"
data-testid="work-item-state-select"
- class="gl-w-auto hide-select-decoration gl-pl-4 gl-my-1 work-item-field-value"
+ class="hide-unfocused-input-decoration work-item-field-value gl-w-auto gl-pl-4 gl-my-1"
:class="{ 'gl-bg-transparent! gl-cursor-text!': disabled }"
@change="setState"
/>
</gl-form-group>
</template>
-
-<style>
-.hide-select-decoration:not(:focus, :hover),
-.hide-select-decoration:disabled {
- background-image: none;
- box-shadow: none;
-}
-</style>
diff --git a/app/assets/javascripts/work_items/components/item_title.vue b/app/assets/javascripts/work_items/components/item_title.vue
index 1dc6d341811..74bcc2717bd 100644
--- a/app/assets/javascripts/work_items/components/item_title.vue
+++ b/app/assets/javascripts/work_items/components/item_title.vue
@@ -52,7 +52,7 @@ export default {
:aria-label="__('Title')"
:data-placeholder="placeholder"
:contenteditable="!disabled"
- class="gl-px-4 gl-py-3 gl-ml-n4 gl-border gl-border-white gl-rounded-base gl-display-block"
+ class="hide-unfocused-input-decoration gl-px-4 gl-py-3 gl-ml-n4 gl-border gl-rounded-base gl-display-block"
:class="{ 'gl-hover-border-gray-200 gl-pseudo-placeholder': !disabled }"
@paste="handlePaste"
@blur="handleBlur"
diff --git a/app/assets/javascripts/work_items/components/work_item_assignees.vue b/app/assets/javascripts/work_items/components/work_item_assignees.vue
index f7ac63e16c3..4b4aa7f96ca 100644
--- a/app/assets/javascripts/work_items/components/work_item_assignees.vue
+++ b/app/assets/javascripts/work_items/components/work_item_assignees.vue
@@ -148,7 +148,7 @@ export default {
};
},
containerClass() {
- return !this.isEditing ? 'gl-shadow-none!' : '';
+ return !this.isEditing ? 'gl-shadow-none! hide-unfocused-input-decoration' : '';
},
isLoadingUsers() {
return this.$apollo.queries.users.loading;
@@ -318,7 +318,7 @@ export default {
:loading="isLoadingUsers && !isLoadingMore"
:view-only="!canUpdate"
:allow-clear-all="isEditing"
- class="assignees-selector gl-flex-grow-1 gl-border gl-border-white gl-rounded-base col-9 gl-align-self-start gl-px-0! gl-mx-2 work-item-field-value"
+ class="assignees-selector hide-unfocused-input-decoration work-item-field-value gl-flex-grow-1 gl-border gl-rounded-base col-9 gl-align-self-start gl-px-0! gl-mx-2"
data-testid="work-item-assignees-input"
@input="handleAssigneesInput"
@text-input="debouncedSearchKeyUpdate"
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 1402b313cee..bbf1f39e308 100644
--- a/app/assets/javascripts/work_items/components/work_item_detail.vue
+++ b/app/assets/javascripts/work_items/components/work_item_detail.vue
@@ -397,13 +397,13 @@ export default {
<div class="gl-display-flex gl-align-items-center" data-testid="work-item-body">
<ul
v-if="parentWorkItem"
- class="list-unstyled gl-display-flex gl-mr-auto gl-max-w-26 gl-md-max-w-50p gl-min-w-0 gl-mb-0 gl-z-index-0"
+ class="list-unstyled gl-display-flex gl-min-w-0 gl-mr-auto gl-mb-0 gl-z-index-0"
data-testid="work-item-parent"
>
- <li class="gl-ml-n4 gl-display-flex gl-align-items-center gl-overflow-hidden">
+ <li class="gl-ml-n4 gl-display-flex gl-align-items-center gl-min-w-0">
<gl-button
v-gl-tooltip.hover
- class="gl-text-truncate gl-max-w-full"
+ class="gl-text-truncate"
:icon="parentWorkItemIconName"
category="tertiary"
:href="parentUrl"
diff --git a/app/assets/javascripts/work_items/components/work_item_labels.vue b/app/assets/javascripts/work_items/components/work_item_labels.vue
index 8676456a6a4..5bfb65fe91c 100644
--- a/app/assets/javascripts/work_items/components/work_item_labels.vue
+++ b/app/assets/javascripts/work_items/components/work_item_labels.vue
@@ -121,7 +121,7 @@ export default {
return this.labelsWidget?.allowsScopedLabels;
},
containerClass() {
- return !this.isEditing ? 'gl-shadow-none!' : '';
+ return !this.isEditing ? 'gl-shadow-none! hide-unfocused-input-decoration' : '';
},
isLoading() {
return this.$apollo.queries.searchLabels.loading;
@@ -272,7 +272,7 @@ export default {
:loading="isLoading"
:view-only="!canUpdate"
:allow-clear-all="isEditing"
- class="gl-flex-grow-1 gl-border gl-border-white gl-rounded-base col-9 gl-align-self-start gl-px-0! gl-mx-2! work-item-field-value"
+ class="hide-unfocused-input-decoration work-item-field-value gl-flex-grow-1 gl-border gl-rounded-base col-9 gl-align-self-start gl-px-0! gl-mx-2!"
menu-class="token-selector-menu-class"
data-testid="work-item-labels-input"
:class="{ 'gl-hover-border-gray-200': canUpdate }"
diff --git a/app/assets/stylesheets/components/content_editor.scss b/app/assets/stylesheets/components/content_editor.scss
index 08a956bf90f..2030f2c7095 100644
--- a/app/assets/stylesheets/components/content_editor.scss
+++ b/app/assets/stylesheets/components/content_editor.scss
@@ -114,6 +114,18 @@
max-width: 100%;
}
+ > ul {
+ list-style-type: disc;
+
+ ul {
+ list-style-type: circle;
+
+ ul {
+ list-style-type: square;
+ }
+ }
+ }
+
ul[data-type='taskList'] {
list-style: none;
padding: 0;
diff --git a/app/assets/stylesheets/page_bundles/work_items.scss b/app/assets/stylesheets/page_bundles/work_items.scss
index 013aa064c4e..e8fa93e1504 100644
--- a/app/assets/stylesheets/page_bundles/work_items.scss
+++ b/app/assets/stylesheets/page_bundles/work_items.scss
@@ -1,5 +1,6 @@
@import 'mixins_and_variables_and_functions';
+$work-item-field-inset-shadow: inset 0 0 0 $gl-border-size-1 var(--gray-200, $gray-200) !important;
$work-item-overview-right-sidebar-width: 340px;
$work-item-sticky-header-height: 52px;
@@ -8,15 +9,14 @@ $work-item-sticky-header-height: 52px;
align-items: center;
}
-#weight-widget-input:not(:hover, :focus),
-#weight-widget-input[readonly] {
+.hide-unfocused-input-decoration:not(:focus, :hover),
+.hide-unfocused-input-decoration:disabled {
+ background-color: transparent;
+ border-color: transparent;
+ background-image: none;
box-shadow: none;
}
-#weight-widget-input[readonly] {
- background-color: var(--white, $white);
-}
-
.work-item-assignees {
.assign-myself {
display: none;
@@ -68,19 +68,27 @@ $work-item-sticky-header-height: 52px;
}
.work-item-dropdown {
- .gl-dropdown-toggle {
- background: none !important;
+ // duplicate classname because we are fighting with gl-button styles
+ .gl-dropdown-toggle.gl-dropdown-toggle {
+ background: none;
&:hover,
&:focus {
- box-shadow: inset 0 0 0 $gl-border-size-1 var(--gray-darkest, $gray-darkest) !important;
+ box-shadow: $work-item-field-inset-shadow;
+ background-color: $input-bg;
+
+ .gl-dark & {
+ // $input-bg is overridden in dark mode but that does not
+ // work in page bundles currently, manually override here
+ background-color: var(--gray-50, $input-bg);
+ }
}
&.is-not-focused:not(:hover, :focus) {
box-shadow: none;
.gl-button-icon {
- display: none;
+ visibility: hidden;
}
}
}
@@ -150,6 +158,13 @@ $work-item-sticky-header-height: 52px;
.work-item-overview & {
max-width: 65%;
}
+
+ &.gl-form-select {
+ &:hover,
+ &:focus {
+ box-shadow: $work-item-field-inset-shadow;
+ }
+ }
}
.token-selector-menu-class {
diff --git a/app/finders/group_descendants_finder.rb b/app/finders/group_descendants_finder.rb
index 72ab30cf567..3e31c7a2bb2 100644
--- a/app/finders/group_descendants_finder.rb
+++ b/app/finders/group_descendants_finder.rb
@@ -141,7 +141,7 @@ class GroupDescendantsFinder
# rubocop: disable CodeReuse/Finder
def direct_child_projects
- GroupProjectsFinder.new(group: parent_group, current_user: current_user, params: params, options: { only_owned: true })
+ GroupProjectsFinder.new(group: parent_group, current_user: current_user, params: params, options: { exclude_shared: true })
.execute
end
# rubocop: enable CodeReuse/Finder
diff --git a/app/finders/group_members_finder.rb b/app/finders/group_members_finder.rb
index 1025e0ebc9b..639db58b00d 100644
--- a/app/finders/group_members_finder.rb
+++ b/app/finders/group_members_finder.rb
@@ -86,11 +86,6 @@ class GroupMembersFinder < UnionFinder
end
def members_of_groups(groups, shared_from_groups)
- if Feature.disabled?(:members_with_shared_group_access, @group.root_ancestor)
- groups << shared_from_groups unless shared_from_groups.nil?
- return GroupMember.non_request.of_groups(find_union(groups, Group))
- end
-
members = GroupMember.non_request.of_groups(find_union(groups, Group))
return members if shared_from_groups.nil?
diff --git a/app/finders/group_projects_finder.rb b/app/finders/group_projects_finder.rb
index db8a0f14fbc..21341797910 100644
--- a/app/finders/group_projects_finder.rb
+++ b/app/finders/group_projects_finder.rb
@@ -9,8 +9,10 @@
# project_ids_relation: int[] - project ids to use
# group
# options:
-# only_owned: boolean
+# exclude_shared: boolean
+# When true, only projects within the group are included in the result.
# only_shared: boolean
+# When true, only projects arising from group-project shares are included in the result.
# limit: integer
# include_subgroups: boolean
# include_ancestor_groups: boolean
@@ -63,10 +65,10 @@ class GroupProjectsFinder < ProjectsFinder
projects =
if only_shared?
[shared_projects]
- elsif only_owned?
- [owned_projects]
+ elsif exclude_shared?
+ [projects_within_group]
else
- [owned_projects, shared_projects]
+ [projects_within_group, shared_projects]
end
projects.map! do |project_relation|
@@ -104,8 +106,8 @@ class GroupProjectsFinder < ProjectsFinder
end
end
- def only_owned?
- options.fetch(:only_owned, false)
+ def exclude_shared?
+ options.fetch(:exclude_shared, false)
end
def owned_projects?
@@ -126,7 +128,7 @@ class GroupProjectsFinder < ProjectsFinder
options.fetch(:include_ancestor_groups, false)
end
- def owned_projects
+ def projects_within_group
return group.projects unless include_subgroups? || include_ancestor_groups?
union_relations = []
diff --git a/app/models/ci/catalog/resource.rb b/app/models/ci/catalog/resource.rb
index 38603ddfe59..442851f5777 100644
--- a/app/models/ci/catalog/resource.rb
+++ b/app/models/ci/catalog/resource.rb
@@ -11,6 +11,7 @@ module Ci
self.table_name = 'catalog_resources'
belongs_to :project
+ has_many :versions, class_name: 'Ci::Catalog::Resources::Version', inverse_of: :catalog_resource
scope :for_projects, ->(project_ids) { where(project_id: project_ids) }
scope :order_by_created_at_desc, -> { reorder(created_at: :desc) }
diff --git a/app/models/ci/catalog/resources/version.rb b/app/models/ci/catalog/resources/version.rb
new file mode 100644
index 00000000000..bef1b6e64cb
--- /dev/null
+++ b/app/models/ci/catalog/resources/version.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+module Ci
+ module Catalog
+ module Resources
+ # This class represents a CI/CD Catalog resource version.
+ # Only versions which contain valid CI components are included in this table.
+ class Version < ::ApplicationRecord
+ self.table_name = 'catalog_resource_versions'
+
+ belongs_to :release, inverse_of: :catalog_resource_version
+ belongs_to :catalog_resource, class_name: 'Ci::Catalog::Resource', inverse_of: :versions
+ belongs_to :project, inverse_of: :catalog_resource_versions
+
+ validates :release, :catalog_resource, :project, presence: true
+ end
+ end
+ end
+end
+
+Ci::Catalog::Resources::Version.prepend_mod_with('Ci::Catalog::Resources::Version')
diff --git a/app/models/concerns/approvable.rb b/app/models/concerns/approvable.rb
index 55e138d84fb..dc4a34d775f 100644
--- a/app/models/concerns/approvable.rb
+++ b/app/models/concerns/approvable.rb
@@ -51,7 +51,7 @@ module Approvable
end
def eligible_for_approval_by?(user)
- user && !approved_by?(user) && user.can?(:approve_merge_request, self)
+ user.present? && !approved_by?(user) && user.can?(:approve_merge_request, self)
end
def eligible_for_unapproval_by?(user)
diff --git a/app/models/group.rb b/app/models/group.rb
index 2b5a392e02c..7a9eb12db4e 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -641,13 +641,20 @@ class Group < Namespace
.where(source_id: self_and_hierarchy.reorder(nil).select(:id))
end
- def direct_and_indirect_members_with_inactive
+ def hierarchy_members_with_inactive
GroupMember
.non_request
.non_invite
.where(source_id: self_and_hierarchy.reorder(nil).select(:id))
end
+ def descendant_project_members_with_inactive
+ ProjectMember
+ .with_source_id(all_projects)
+ .non_request
+ .non_invite
+ end
+
def users_with_parents
User
.where(id: members_with_parents.select(:user_id))
@@ -685,20 +692,6 @@ class Group < Namespace
])
end
- # Returns all users (also inactive) that are members of the group because:
- # 1. They belong to the group
- # 2. They belong to a project that belongs to the group
- # 3. They belong to a sub-group or project in such sub-group
- # 4. They belong to an ancestor group
- def direct_and_indirect_users_with_inactive
- User.from_union([
- User
- .where(id: direct_and_indirect_members_with_inactive.select(:user_id))
- .reorder(nil),
- project_users_with_descendants
- ]).allow_cross_joins_across_databases(url: "https://gitlab.com/gitlab-org/gitlab/-/issues/417455") # failed in spec/tasks/gitlab/user_management_rake_spec.rb
- end
-
def users_count
members.count
end
diff --git a/app/models/packages/dependency.rb b/app/models/packages/dependency.rb
index c39b46dcc20..c46489340f7 100644
--- a/app/models/packages/dependency.rb
+++ b/app/models/packages/dependency.rb
@@ -8,6 +8,10 @@ class Packages::Dependency < ApplicationRecord
validates :name, uniqueness: { scope: :version_pattern }
+ scope :with_packages, ->(packages) do
+ joins(:dependency_links).where(dependency_links: { package: packages })
+ end
+
NAME_VERSION_PATTERN_TUPLE_MATCHING = '(name, version_pattern) = (?, ?)'
MAX_STRING_LENGTH = 255
MAX_CHUNKED_QUERIES_COUNT = 10
diff --git a/app/models/packages/package.rb b/app/models/packages/package.rb
index b618c7c20c4..8218f8b9eba 100644
--- a/app/models/packages/package.rb
+++ b/app/models/packages/package.rb
@@ -132,7 +132,8 @@ class Packages::Package < ApplicationRecord
scope :including_project_route, -> { includes(project: :route) }
scope :including_project_namespace_route, -> { includes(project: { namespace: :route }) }
scope :including_tags, -> { includes(:tags) }
- scope :including_dependency_links, -> { includes(dependency_links: :dependency) }
+ scope :including_dependency_links, -> { includes(:dependency_links) }
+ scope :including_dependency_links_with_dependencies, -> { includes(dependency_links: :dependency) }
scope :including_dependency_links_with_nuget_metadatum, -> { includes(dependency_links: [:dependency, :nuget_metadatum]) }
scope :with_conan_channel, ->(package_channel) do
diff --git a/app/models/project.rb b/app/models/project.rb
index 931f4db3a54..9aeacf23ad9 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -170,6 +170,8 @@ class Project < ApplicationRecord
alias_attribute :parent_id, :namespace_id
has_one :catalog_resource, class_name: 'Ci::Catalog::Resource', inverse_of: :project
+ has_many :catalog_resource_versions, class_name: 'Ci::Catalog::Resources::Version', inverse_of: :project
+
has_one :last_event, -> { order 'events.created_at DESC' }, class_name: 'Event'
has_many :boards
diff --git a/app/models/release.rb b/app/models/release.rb
index f0ba56390ab..6830f6e8480 100644
--- a/app/models/release.rb
+++ b/app/models/release.rb
@@ -20,6 +20,8 @@ class Release < ApplicationRecord
has_many :milestones, through: :milestone_releases
has_many :evidences, inverse_of: :release, class_name: 'Releases::Evidence'
+ has_one :catalog_resource_version, class_name: 'Ci::Catalog::Resources::Version', inverse_of: :release
+
accepts_nested_attributes_for :links, allow_destroy: true
before_create :set_released_at
diff --git a/app/policies/concerns/find_group_projects.rb b/app/policies/concerns/find_group_projects.rb
index aad9081bd7d..914e336b4ab 100644
--- a/app/policies/concerns/find_group_projects.rb
+++ b/app/policies/concerns/find_group_projects.rb
@@ -3,11 +3,11 @@
module FindGroupProjects
extend ActiveSupport::Concern
- def group_projects_for(user:, group:, only_owned: true)
+ def group_projects_for(user:, group:, exclude_shared: true)
GroupProjectsFinder.new(
group: group,
current_user: user,
- options: { include_subgroups: true, only_owned: only_owned }
+ options: { include_subgroups: true, exclude_shared: exclude_shared }
).execute
end
end
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index 29b966b43e2..e35312fbd09 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -61,7 +61,7 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
end
condition(:design_management_enabled) do
- group_projects_for(user: @user, group: @subject, only_owned: false).any? { |p| p.design_management_enabled? }
+ group_projects_for(user: @user, group: @subject, exclude_shared: false).any? { |p| p.design_management_enabled? }
end
condition(:dependency_proxy_available, scope: :subject) do
diff --git a/app/services/clusters/management/validate_management_project_permissions_service.rb b/app/services/clusters/management/validate_management_project_permissions_service.rb
index e89a0afe6d2..e407c159bc7 100644
--- a/app/services/clusters/management/validate_management_project_permissions_service.rb
+++ b/app/services/clusters/management/validate_management_project_permissions_service.rb
@@ -46,7 +46,7 @@ module Clusters
::GroupProjectsFinder.new(
group: group,
current_user: current_user,
- options: { only_owned: true, include_subgroups: include_subgroups }
+ options: { exclude_shared: true, include_subgroups: include_subgroups }
).execute
end
end
diff --git a/app/services/packages/npm/generate_metadata_service.rb b/app/services/packages/npm/generate_metadata_service.rb
index e1795079513..c84c170b234 100644
--- a/app/services/packages/npm/generate_metadata_service.rb
+++ b/app/services/packages/npm/generate_metadata_service.rb
@@ -13,6 +13,7 @@ module Packages
def initialize(name, packages)
@name = name
@packages = packages
+ @dependencies_cache = {}
end
def execute(only_dist_tags: false)
@@ -21,7 +22,7 @@ module Packages
private
- attr_reader :name, :packages
+ attr_reader :name, :packages, :dependencies_cache
def metadata(only_dist_tags)
result = { dist_tags: dist_tags }
@@ -38,9 +39,17 @@ module Packages
package_versions = {}
packages.each_batch do |relation|
- batched_packages = relation.including_dependency_links
- .preload_files
- .preload_npm_metadatum
+ batched_packages = if Feature.enabled?(:npm_optimize_metadata_generation)
+ fill_dependencies_cache(relation)
+
+ relation.including_dependency_links
+ .preload_files
+ .preload_npm_metadatum
+ else
+ relation.including_dependency_links_with_dependencies
+ .preload_files
+ .preload_npm_metadatum
+ end
batched_packages.each do |package|
package_file = package.installable_package_files.last
@@ -85,7 +94,12 @@ module Packages
dependencies = Hash.new { |h, key| h[key] = {} }
package.dependency_links.each do |dependency_link|
- dependency = dependency_link.dependency
+ dependency = if Feature.enabled?(:npm_optimize_metadata_generation)
+ dependencies_cache[dependency_link.dependency_id]
+ else
+ dependency_link.dependency
+ end
+
dependencies[dependency_link.dependency_type][dependency.name] = dependency.version_pattern
end
@@ -106,6 +120,17 @@ module Packages
json = package.npm_metadatum&.package_json || {}
json.slice(*PACKAGE_JSON_ALLOWED_FIELDS)
end
+
+ def fill_dependencies_cache(packages)
+ Packages::Dependency
+ .with_packages(packages)
+ .id_not_in(dependencies_cache.keys)
+ .each_batch do |dependencies|
+ dependencies.each do |dependency|
+ dependencies_cache[dependency.id] = dependency
+ end
+ end
+ end
end
end
end
diff --git a/app/validators/json_schemas/build_metadata_secrets.json b/app/validators/json_schemas/build_metadata_secrets.json
index 5dcd33a2cf0..ac34af3f107 100644
--- a/app/validators/json_schemas/build_metadata_secrets.json
+++ b/app/validators/json_schemas/build_metadata_secrets.json
@@ -24,9 +24,30 @@
},
"additionalProperties": false
},
+ "^azure_key_vault$": {
+ "type": "object",
+ "required": ["name"],
+ "properties": {
+ "name": { "type": "string" },
+ "version": { "type": ["string", "null"] }
+ },
+ "additionalProperties": false
+ },
"^file$": { "type": "boolean" },
"^token$": { "type": "string" }
},
+ "anyOf": [
+ {
+ "required": [
+ "vault"
+ ]
+ },
+ {
+ "required": [
+ "azure_key_vault"
+ ]
+ }
+ ],
"additionalProperties": false
}
}
diff --git a/app/views/shared/access_tokens/_form.html.haml b/app/views/shared/access_tokens/_form.html.haml
index 54af364aca3..a8f781d2272 100644
--- a/app/views/shared/access_tokens/_form.html.haml
+++ b/app/views/shared/access_tokens/_form.html.haml
@@ -15,9 +15,13 @@
.form-group
= f.label :name, s_('AccessTokens|Token name'), class: 'label-bold'
- - resource_type = resource.is_a?(Group) ? "group" : "project"
= f.text_field :name, class: 'form-control gl-form-input gl-max-w-80', required: true, data: { qa_selector: 'access_token_name_field' }, :'aria-describedby' => 'access_token_help_text'
- %span.form-text.text-muted#access_token_help_text= s_("AccessTokens|For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members.") % { resource_type: resource_type }
+ %span.form-text.text-muted#access_token_help_text
+ - if resource
+ - resource_type = resource.is_a?(Group) ? "group" : "project"
+ = s_("AccessTokens|For example, the application using the token or the purpose of the token. Do not give sensitive information for the name of the token, as it will be visible to all %{resource_type} members.") % { resource_type: resource_type }
+ - else
+ = s_("AccessTokens|For example, the application using the token or the purpose of the token.")
.js-access-tokens-expires-at{ data: expires_at_field_data }
= f.text_field :expires_at, class: 'gl-datepicker-input form-control gl-form-input', placeholder: 'YYYY-MM-DD', autocomplete: 'off', data: { js_name: 'expiresAt' }
diff --git a/app/workers/merge_requests/mergeability_check_batch_worker.rb b/app/workers/merge_requests/mergeability_check_batch_worker.rb
index f48e9c234ab..e95c3952c8c 100644
--- a/app/workers/merge_requests/mergeability_check_batch_worker.rb
+++ b/app/workers/merge_requests/mergeability_check_batch_worker.rb
@@ -40,8 +40,7 @@ module MergeRequests
private
def merge_status_recheck_not_allowed?(merge_request, user)
- ::Feature.enabled?(:restrict_merge_status_recheck, merge_request.project) &&
- !Ability.allowed?(user, :update_merge_request, merge_request.project)
+ !Ability.allowed?(user, :update_merge_request, merge_request.project)
end
end
end