Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
2f912c4a01
commit
89523b62fd
2
Gemfile
2
Gemfile
|
|
@ -471,7 +471,7 @@ group :opentelemetry do
|
|||
gem 'opentelemetry-instrumentation-sidekiq', feature_category: :observability
|
||||
end
|
||||
|
||||
gem 'warning', '~> 1.3.0', feature_category: :shared
|
||||
gem 'warning', '~> 1.5.0', feature_category: :shared
|
||||
|
||||
group :development do
|
||||
gem 'lefthook', '~> 1.11.0', require: false, feature_category: :tooling
|
||||
|
|
|
|||
|
|
@ -783,7 +783,7 @@
|
|||
{"name":"vite_ruby","version":"3.9.1","platform":"ruby","checksum":"e4584a4ba1578602f13a3ac73402007aed044bd660daaac220523a97c49a4cc4"},
|
||||
{"name":"vmstat","version":"2.3.1","platform":"ruby","checksum":"5587cb430a54dbfc4a5c29dd01bd6a4031b2ff4c1d387504d74ff246f3b39104"},
|
||||
{"name":"warden","version":"1.2.9","platform":"ruby","checksum":"46684f885d35a69dbb883deabf85a222c8e427a957804719e143005df7a1efd0"},
|
||||
{"name":"warning","version":"1.3.0","platform":"ruby","checksum":"23695a5d8e50bd5c46068931b529bee0b28e4982cbcefbe77d867800dde8069e"},
|
||||
{"name":"warning","version":"1.5.0","platform":"ruby","checksum":"0f12c49fea0c06757778eefdcc7771e4fd99308901e3d55c504d87afdd718c53"},
|
||||
{"name":"webauthn","version":"3.0.0","platform":"ruby","checksum":"3f77d422c2a8a4b31e56cf42f83414bd066e0506e9896936e1730262dc4a20e6"},
|
||||
{"name":"webfinger","version":"2.1.3","platform":"ruby","checksum":"567a52bde77fb38ca6b67e55db755f988766ec4651c1d24916a65aa70540695c"},
|
||||
{"name":"webmock","version":"3.25.0","platform":"ruby","checksum":"573c23fc4887008c830f22da588db339ca38b6d59856fd57f5a068959474198e"},
|
||||
|
|
|
|||
|
|
@ -1956,7 +1956,7 @@ GEM
|
|||
vmstat (2.3.1)
|
||||
warden (1.2.9)
|
||||
rack (>= 2.0.9)
|
||||
warning (1.3.0)
|
||||
warning (1.5.0)
|
||||
webauthn (3.0.0)
|
||||
android_key_attestation (~> 0.3.0)
|
||||
awrence (~> 1.1)
|
||||
|
|
@ -2358,7 +2358,7 @@ DEPENDENCIES
|
|||
vite_rails (~> 3.0.17)
|
||||
vite_ruby (~> 3.9.0)
|
||||
vmstat (~> 2.3.0)
|
||||
warning (~> 1.3.0)
|
||||
warning (~> 1.5.0)
|
||||
webauthn (~> 3.0)
|
||||
webmock (~> 3.25.0)
|
||||
webrick (~> 1.8.1)
|
||||
|
|
|
|||
|
|
@ -796,7 +796,7 @@
|
|||
{"name":"vite_ruby","version":"3.9.1","platform":"ruby","checksum":"e4584a4ba1578602f13a3ac73402007aed044bd660daaac220523a97c49a4cc4"},
|
||||
{"name":"vmstat","version":"2.3.1","platform":"ruby","checksum":"5587cb430a54dbfc4a5c29dd01bd6a4031b2ff4c1d387504d74ff246f3b39104"},
|
||||
{"name":"warden","version":"1.2.9","platform":"ruby","checksum":"46684f885d35a69dbb883deabf85a222c8e427a957804719e143005df7a1efd0"},
|
||||
{"name":"warning","version":"1.3.0","platform":"ruby","checksum":"23695a5d8e50bd5c46068931b529bee0b28e4982cbcefbe77d867800dde8069e"},
|
||||
{"name":"warning","version":"1.5.0","platform":"ruby","checksum":"0f12c49fea0c06757778eefdcc7771e4fd99308901e3d55c504d87afdd718c53"},
|
||||
{"name":"webauthn","version":"3.0.0","platform":"ruby","checksum":"3f77d422c2a8a4b31e56cf42f83414bd066e0506e9896936e1730262dc4a20e6"},
|
||||
{"name":"webfinger","version":"2.1.3","platform":"ruby","checksum":"567a52bde77fb38ca6b67e55db755f988766ec4651c1d24916a65aa70540695c"},
|
||||
{"name":"webmock","version":"3.25.0","platform":"ruby","checksum":"573c23fc4887008c830f22da588db339ca38b6d59856fd57f5a068959474198e"},
|
||||
|
|
|
|||
|
|
@ -1990,7 +1990,7 @@ GEM
|
|||
vmstat (2.3.1)
|
||||
warden (1.2.9)
|
||||
rack (>= 2.0.9)
|
||||
warning (1.3.0)
|
||||
warning (1.5.0)
|
||||
webauthn (3.0.0)
|
||||
android_key_attestation (~> 0.3.0)
|
||||
awrence (~> 1.1)
|
||||
|
|
@ -2392,7 +2392,7 @@ DEPENDENCIES
|
|||
vite_rails (~> 3.0.17)
|
||||
vite_ruby (~> 3.9.0)
|
||||
vmstat (~> 2.3.0)
|
||||
warning (~> 1.3.0)
|
||||
warning (~> 1.5.0)
|
||||
webauthn (~> 3.0)
|
||||
webmock (~> 3.25.0)
|
||||
webrick (~> 1.8.1)
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export const formattedTime = (seconds = 0) => {
|
|||
});
|
||||
}
|
||||
|
||||
const hoursAndMinutes = stringifyTime(parseSeconds(seconds));
|
||||
const hoursAndMinutes = stringifyTime(parseSeconds(seconds, { hoursPerDay: 24, daysPerWeek: 7 }));
|
||||
const remainingSeconds =
|
||||
seconds % 60 >= 1
|
||||
? sprintf(__('%{seconds}s'), {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ export default {
|
|||
createdByPipelineText: s__(
|
||||
'PackageRegistry|Built by pipeline %{link} triggered %{datetime} by %{author}',
|
||||
),
|
||||
publishText: s__('PackageRegistry|Published to the %{project} Package Registry %{datetime}'),
|
||||
publishText: s__('PackageRegistry|Published to the %{project} package registry %{datetime}'),
|
||||
combinedUpdateText: s__(
|
||||
'PackageRegistry|Package updated by commit %{link} on branch %{branch}, built by pipeline %{pipeline}, and published to the registry %{datetime}',
|
||||
),
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ export const ERRORED_PACKAGE_TEXT = s__(
|
|||
export const ERROR_PUBLISHING = s__('PackageRegistry|Error publishing');
|
||||
export const WARNING_TEXT = __('Warning');
|
||||
|
||||
export const PACKAGE_REGISTRY_TITLE = __('Package Registry');
|
||||
export const PACKAGE_REGISTRY_TITLE = __('Package registry');
|
||||
|
||||
export const PACKAGE_ERROR_STATUS = 'ERROR';
|
||||
export const PACKAGE_DEFAULT_STATUS = 'DEFAULT';
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ export default {
|
|||
),
|
||||
packageRegistryLabel: s__('ProjectSettings|Package registry'),
|
||||
packageRegistryForEveryoneLabel: s__(
|
||||
'ProjectSettings|Allow anyone to pull from Package Registry',
|
||||
'ProjectSettings|Allow anyone to pull from package registry',
|
||||
),
|
||||
modelExperimentsLabel: s__('ProjectSettings|Model experiments'),
|
||||
modelExperimentsHelpText: s__(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import { GlAlert } from '@gitlab/ui';
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { produce } from 'immer';
|
||||
import { __ } from '~/locale';
|
||||
import wikiPageQuery from '~/wikis/graphql/wiki_page.query.graphql';
|
||||
import SkeletonNote from '~/vue_shared/components/notes/skeleton_note.vue';
|
||||
|
|
@ -87,17 +88,29 @@ export default {
|
|||
this.placeholderNote = {};
|
||||
},
|
||||
async updateDiscussions(discussion) {
|
||||
this.discussions = [
|
||||
...this.discussions,
|
||||
{
|
||||
// apollo does not update cache when a discussion is added so we have to do it manually
|
||||
if (!this.$apollo.provider) return;
|
||||
const { defaultClient: cache } = this.$apollo.provider.clients;
|
||||
const queryData = cache.readQuery({
|
||||
query: wikiPageQuery,
|
||||
variables: this.queryVariables,
|
||||
});
|
||||
const data = produce(queryData, (draft) => {
|
||||
draft.wikiPage.discussions.nodes.push({
|
||||
...discussion,
|
||||
replyId: discussion.id,
|
||||
replyId: null,
|
||||
resolvable: false,
|
||||
resolved: false,
|
||||
resolvedAt: null,
|
||||
resolvedBy: null,
|
||||
},
|
||||
];
|
||||
});
|
||||
});
|
||||
|
||||
cache.writeQuery({
|
||||
query: wikiPageQuery,
|
||||
variables: this.queryVariables,
|
||||
data,
|
||||
});
|
||||
},
|
||||
getDiscussionKey(key, stringModifier) {
|
||||
return [key, stringModifier].join('-');
|
||||
|
|
|
|||
|
|
@ -1,7 +1,3 @@
|
|||
<!--
|
||||
this component should be here only temporary until this MR gets sorted:
|
||||
https://gitlab.com/gitlab-org/gitlab-ui/-/merge_requests/3969
|
||||
-->
|
||||
<script>
|
||||
import { GlFormInput, GlIcon, GlLoadingIcon, GlButton, GlTooltipDirective } from '@gitlab/ui';
|
||||
import { __ } from '~/locale';
|
||||
|
|
@ -115,12 +111,6 @@ export default {
|
|||
showClearButton() {
|
||||
return this.hasValue && !this.disabled;
|
||||
},
|
||||
regexButtonHighlightClass() {
|
||||
return {
|
||||
'!gl-bg-blue-50': this.regexButtonState,
|
||||
'!gl-shadow-none': !this.regexButtonState,
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
isInputOrClearButton(element) {
|
||||
|
|
@ -194,8 +184,8 @@ export default {
|
|||
:title="$options.i18n.label"
|
||||
:aria-label="$options.i18n.label"
|
||||
class="gl-ml-2 gl-hidden sm:gl-block"
|
||||
:class="regexButtonHighlightClass"
|
||||
category="secondary"
|
||||
:selected="regexButtonState"
|
||||
category="tertiary"
|
||||
variant="default"
|
||||
size="small"
|
||||
icon="regular-expression"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Resolvers
|
||||
module Users
|
||||
class RecentlyViewedMergeRequestsResolver < BaseResolver
|
||||
include Gitlab::Graphql::Authorize::AuthorizeResource
|
||||
|
||||
type [Types::MergeRequestType], null: true
|
||||
|
||||
authorize :read_user
|
||||
authorizes_object!
|
||||
|
||||
def resolve
|
||||
recent_merge_requests = ::Gitlab::Search::RecentMergeRequests.new(user: current_user)
|
||||
recent_merge_requests.search(nil) # nil skips filtering results by title or description
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -17,6 +17,11 @@ module Types
|
|||
description: 'Most-recently viewed issues for the current user.',
|
||||
experiment: { milestone: '17.9' }
|
||||
|
||||
field :recently_viewed_merge_requests, # rubocop:disable GraphQL/ExtractType -- To be refactored
|
||||
resolver: Resolvers::Users::RecentlyViewedMergeRequestsResolver,
|
||||
description: 'Most-recently viewed merge requests for the current user.',
|
||||
experiment: { milestone: '17.10' }
|
||||
|
||||
field :work_items,
|
||||
null: true,
|
||||
resolver: Resolvers::WorkItems::UserWorkItemsResolver,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ module Types
|
|||
module Packages
|
||||
class PackageBaseType < ::Types::BaseObject
|
||||
graphql_name 'PackageBase'
|
||||
description 'Represents a package in the Package Registry'
|
||||
description 'Represents a package in the package registry'
|
||||
|
||||
PROTECTION_RULE_EXISTS_BATCH_SIZE = 20
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ module Types
|
|||
module Packages
|
||||
class PackageType < Types::Packages::PackageBaseType
|
||||
graphql_name 'Package'
|
||||
description 'Represents a package with pipelines in the Package Registry'
|
||||
description 'Represents a package with pipelines in the package registry'
|
||||
|
||||
authorize :read_package
|
||||
|
||||
|
|
|
|||
|
|
@ -36,18 +36,12 @@ module Ci
|
|||
|
||||
def policies_allowed?(accessed_project, policies)
|
||||
return true if self_referential?(accessed_project)
|
||||
|
||||
unless accessed_project.ci_inbound_job_token_scope_enabled?
|
||||
# We capture policies even if the inbound scopes are disabled
|
||||
capture_job_token_policies(policies)
|
||||
return true
|
||||
end
|
||||
|
||||
return false unless inbound_accessible?(accessed_project)
|
||||
|
||||
# We capture policies even if the feature flag is disabled
|
||||
capture_job_token_policies(policies)
|
||||
# We capture policies even if the inbound scopes are disabled or the feature flag is disabled
|
||||
Ci::JobToken::Authorization.capture_job_token_policies(policies) if policies.present?
|
||||
|
||||
return true unless accessed_project.ci_inbound_job_token_scope_enabled?
|
||||
return true unless Feature.enabled?(:add_policies_to_ci_job_token, accessed_project)
|
||||
|
||||
policies_allowed_for_accessed_project?(accessed_project, policies)
|
||||
|
|
@ -146,12 +140,6 @@ module Ci
|
|||
def outbound_allowlist
|
||||
Ci::JobToken::Allowlist.new(current_project, direction: :outbound)
|
||||
end
|
||||
|
||||
def capture_job_token_policies(policies)
|
||||
return if policies.blank?
|
||||
|
||||
Ci::JobToken::Authorization.capture_job_token_policies(policies)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,8 +5,13 @@ module Notes
|
|||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
# Aliases to make application_helper#edited_time_ago_with_tooltip helper work properly with notes.
|
||||
# See https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/10392/diffs#note_28719102
|
||||
alias_attribute :last_edited_by, :updated_by
|
||||
|
||||
belongs_to :author, class_name: "User"
|
||||
belongs_to :updated_by, class_name: "User"
|
||||
belongs_to :last_edited_by, class_name: 'User'
|
||||
|
||||
has_many :todos
|
||||
|
||||
|
|
@ -17,21 +22,13 @@ module Notes
|
|||
validates :author, presence: true
|
||||
validates :discussion_id, presence: true, format: { with: /\A\h{40}\z/ }
|
||||
validate :validate_created_after
|
||||
end
|
||||
|
||||
# Alias to make application_helper#edited_time_ago_with_tooltip helper work properly with notes.
|
||||
# See https://gitlab.com/gitlab-org/gitlab-foss/merge_requests/10392/diffs#note_28719102
|
||||
def last_edited_by
|
||||
updated_by
|
||||
end
|
||||
def validate_created_after
|
||||
return unless created_at
|
||||
return if created_at >= '1970-01-01'
|
||||
|
||||
private
|
||||
|
||||
def validate_created_after
|
||||
return unless created_at
|
||||
return if created_at >= '1970-01-01'
|
||||
|
||||
errors.add(:created_at, s_('Note|The created date provided is too far in the past.'))
|
||||
errors.add(:created_at, s_('Note|The created date provided is too far in the past.'))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ module Packages
|
|||
module TerraformModule
|
||||
class Metadatum < ApplicationRecord
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
include SemanticVersionable
|
||||
|
||||
self.primary_key = :package_id
|
||||
|
||||
|
|
@ -12,9 +13,11 @@ module Packages
|
|||
belongs_to :package, class_name: 'Packages::TerraformModule::Package', inverse_of: :terraform_module_metadatum
|
||||
belongs_to :project
|
||||
|
||||
validates :package, presence: true
|
||||
validates :project, :fields, presence: true
|
||||
validates :fields, json_schema: { filename: 'terraform_module_metadata', detail_errors: true }
|
||||
attribute :fields, default: -> { {} }
|
||||
|
||||
validates :package, :project, presence: true
|
||||
validates :fields, json_schema: { filename: 'terraform_module_metadata', detail_errors: true },
|
||||
if: -> { fields.present? }
|
||||
validate :ensure_fields_size
|
||||
|
||||
private
|
||||
|
|
|
|||
|
|
@ -7,7 +7,9 @@ module Packages
|
|||
|
||||
has_one :terraform_module_metadatum, inverse_of: :package, class_name: 'Packages::TerraformModule::Metadatum'
|
||||
|
||||
validates :name, format: { with: Gitlab::Regex.terraform_module_package_name_regex }, if: :terraform_module?
|
||||
accepts_nested_attributes_for :terraform_module_metadatum
|
||||
|
||||
validates :name, format: { with: Gitlab::Regex.terraform_module_package_name_regex }
|
||||
validates :version, format: { with: Gitlab::Regex.semver_regex, message: Gitlab::Regex.semver_regex_message }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -5,24 +5,20 @@ module Packages
|
|||
class CreatePackageService < ::Packages::CreatePackageService
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
EMPTY_VERSION_ERROR = ServiceResponse.error(message: 'Version is empty.', reason: :bad_request).freeze
|
||||
NAMESPACE_DUPLICATION_ERROR = ServiceResponse.error(
|
||||
message: 'A module with the same name already exists in the namespace.',
|
||||
reason: :forbidden
|
||||
).freeze
|
||||
PROJECT_DUPLICATION_ERROR = ServiceResponse.error(
|
||||
message: 'A module with the same name & version already exists in the project.',
|
||||
reason: :forbidden
|
||||
).freeze
|
||||
|
||||
def execute
|
||||
if params[:module_version].blank?
|
||||
return ServiceResponse.error(message: 'Version is empty.', reason: :bad_request)
|
||||
end
|
||||
|
||||
if duplicates_not_allowed? && current_package_exists_elsewhere?
|
||||
return ServiceResponse.error(
|
||||
message: 'A module with the same name already exists in the namespace.',
|
||||
reason: :forbidden
|
||||
)
|
||||
end
|
||||
|
||||
if current_package_version_exists?
|
||||
return ServiceResponse.error(
|
||||
message: 'A module with the same name & version already exists in the project.',
|
||||
reason: :forbidden
|
||||
)
|
||||
end
|
||||
return EMPTY_VERSION_ERROR if params[:module_version].blank?
|
||||
return NAMESPACE_DUPLICATION_ERROR if duplicates_not_allowed? && current_package_exists_elsewhere?
|
||||
return PROJECT_DUPLICATION_ERROR if current_package_version_exists?
|
||||
|
||||
package, package_file = ApplicationRecord.transaction { create_terraform_module_package! }
|
||||
|
||||
|
|
@ -36,7 +32,15 @@ module Packages
|
|||
private
|
||||
|
||||
def create_terraform_module_package!
|
||||
package = create_package!(:terraform_module, name: name, version: params[:module_version])
|
||||
package = create_package!(
|
||||
:terraform_module,
|
||||
name: name,
|
||||
version: params[:module_version],
|
||||
terraform_module_metadatum_attributes: {
|
||||
project: project,
|
||||
semver: params[:module_version]
|
||||
}
|
||||
)
|
||||
package_file = ::Packages::CreatePackageFileService.new(package, file_params).execute
|
||||
[package, package_file]
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,42 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Packages
|
||||
module TerraformModule
|
||||
module Metadata
|
||||
class CreateService
|
||||
def initialize(package, metadata_hash)
|
||||
@package = package
|
||||
@metadata_hash = metadata_hash
|
||||
end
|
||||
|
||||
def execute
|
||||
metadata = ::Packages::TerraformModule::Metadatum.new(
|
||||
package: package,
|
||||
project: package.project,
|
||||
fields: metadata_hash,
|
||||
updated_at: Time.current,
|
||||
created_at: Time.current
|
||||
)
|
||||
|
||||
if metadata.valid?
|
||||
::Packages::TerraformModule::Metadatum.upsert(metadata.attributes, returning: false)
|
||||
|
||||
ServiceResponse.success(payload: { metadata: metadata })
|
||||
else
|
||||
Gitlab::ErrorTracking.track_exception(
|
||||
ActiveRecord::RecordInvalid.new(metadata),
|
||||
class: self.class.name,
|
||||
package_id: package.id
|
||||
)
|
||||
|
||||
ServiceResponse.error(message: metadata.errors.full_messages, reason: :bad_request)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :package, :metadata_hash
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Packages
|
||||
module TerraformModule
|
||||
module Metadata
|
||||
class UpdateService
|
||||
delegate :terraform_module_metadatum, to: :package, private: true
|
||||
|
||||
def initialize(package, metadata_hash)
|
||||
@package = package
|
||||
@metadata_hash = metadata_hash
|
||||
end
|
||||
|
||||
def execute
|
||||
terraform_module_metadatum.assign_attributes(fields: metadata_hash)
|
||||
|
||||
if terraform_module_metadatum.valid?
|
||||
::Packages::TerraformModule::Metadatum.upsert(terraform_module_metadatum.attributes, returning: false)
|
||||
|
||||
ServiceResponse.success(payload: { metadata: terraform_module_metadatum })
|
||||
else
|
||||
Gitlab::ErrorTracking.track_exception(
|
||||
ActiveRecord::RecordInvalid.new(terraform_module_metadatum),
|
||||
class: self.class.name,
|
||||
package_id: package.id
|
||||
)
|
||||
|
||||
ServiceResponse.error(
|
||||
message: terraform_module_metadatum.errors.full_messages.to_sentence,
|
||||
reason: :bad_request
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :package, :metadata_hash
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -21,7 +21,7 @@ module Packages
|
|||
end
|
||||
|
||||
if result&.success?
|
||||
::Packages::TerraformModule::Metadata::CreateService.new(package_file.package, result.payload).execute
|
||||
::Packages::TerraformModule::Metadata::UpdateService.new(package_file.package, result.payload).execute
|
||||
end
|
||||
|
||||
ServiceResponse.success
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
- if Gitlab.config.packages.enabled
|
||||
= render ::Layouts::SettingsBlockComponent.new(_('Package Registry'),
|
||||
= render ::Layouts::SettingsBlockComponent.new(_('Package registry'),
|
||||
id: 'js-package-settings',
|
||||
expanded: expanded_by_default?) do |c|
|
||||
- c.with_description do
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
- page_title _("Package Registry")
|
||||
- page_title _("Package registry")
|
||||
|
||||
.row
|
||||
.col-12
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
- package_file_size_limits = @instance_configuration.settings[:package_file_size_limits]
|
||||
- content_for :table_content do
|
||||
- if package_file_size_limits.present?
|
||||
%li= link_to _('Package Registry'), '#package-registry'
|
||||
%li= link_to _('Package registry'), '#package-registry'
|
||||
|
||||
- content_for :settings_content do
|
||||
- if package_file_size_limits.present?
|
||||
%h2#package-registry
|
||||
= _('Package Registry')
|
||||
= _('Package registry')
|
||||
|
||||
%p
|
||||
= _('There are several file size limits in place for the Package Registry.')
|
||||
= _('There are several file size limits in place for the package registry.')
|
||||
.table-responsive
|
||||
%table
|
||||
%thead
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@
|
|||
= render 'help/instance_configuration/rate_limit_row', title: _('Authenticated API requests'), rate_limit: rate_limits[:authenticated_api]
|
||||
= render 'help/instance_configuration/rate_limit_row', title: _('Authenticated web requests'), rate_limit: rate_limits[:authenticated_web]
|
||||
= render 'help/instance_configuration/rate_limit_row', title: _('Protected Paths: requests'), rate_limit: rate_limits[:protected_paths]
|
||||
= render 'help/instance_configuration/rate_limit_row', title: _('Package Registry: unauthenticated API requests'), rate_limit: rate_limits[:unauthenticated_packages_api], public_visible: true
|
||||
= render 'help/instance_configuration/rate_limit_row', title: _('Package Registry: authenticated API requests'), rate_limit: rate_limits[:authenticated_packages_api]
|
||||
= render 'help/instance_configuration/rate_limit_row', title: _('Package registry: unauthenticated API requests'), rate_limit: rate_limits[:unauthenticated_packages_api], public_visible: true
|
||||
= render 'help/instance_configuration/rate_limit_row', title: _('Package registry: authenticated API requests'), rate_limit: rate_limits[:authenticated_packages_api]
|
||||
= render 'help/instance_configuration/rate_limit_row', title: _('Authenticated Git LFS requests'), rate_limit: rate_limits[:authenticated_git_lfs_api]
|
||||
= render 'help/instance_configuration/rate_limit_row', title: _('Issue creation requests'), rate_limit: rate_limits[:issue_creation]
|
||||
= render 'help/instance_configuration/rate_limit_row', title: _('Note creation requests'), rate_limit: rate_limits[:note_creation]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
- page_title _("Package Registry")
|
||||
- page_title _("Package registry")
|
||||
|
||||
.row
|
||||
.col-12
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
migration_job_name: BackfillPackagesDebianProjectComponentFilesProjectId
|
||||
description: Backfills sharding key `packages_debian_project_component_files.project_id` from `packages_debian_project_components`.
|
||||
feature_category: package_registry
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/183806
|
||||
milestone: '17.10'
|
||||
queued_migration_version: 20250307100241
|
||||
finalized_by: # version of the migration that finalized this BBM
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
---
|
||||
migration_job_name: BackfillVulnerabilityOccurrenceIdentifiersProjectId
|
||||
description: Backfills sharding key `vulnerability_occurrence_identifiers.project_id` from `vulnerability_occurrences`.
|
||||
description: Backfills sharding key `vulnerability_occurrence_identifiers.project_id`
|
||||
from `vulnerability_occurrences`.
|
||||
feature_category: vulnerability_management
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/161217
|
||||
milestone: '17.3'
|
||||
queued_migration_version: 20240730171961
|
||||
finalized_by: # version of the migration that finalized this BBM
|
||||
finalized_by: '20250227231728'
|
||||
|
|
|
|||
|
|
@ -8,14 +8,6 @@ description: https://docs.gitlab.com/ee/user/project/releases/#release-evidence
|
|||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/17217
|
||||
milestone: '12.4'
|
||||
gitlab_schema: gitlab_main_cell
|
||||
desired_sharding_key:
|
||||
project_id:
|
||||
references: projects
|
||||
backfill_via:
|
||||
parent:
|
||||
foreign_key: release_id
|
||||
table: releases
|
||||
sharding_key: project_id
|
||||
belongs_to: release
|
||||
desired_sharding_key_migration_job_name: BackfillEvidencesProjectId
|
||||
table_size: small
|
||||
sharding_key:
|
||||
project_id: projects
|
||||
|
|
|
|||
|
|
@ -18,3 +18,4 @@ desired_sharding_key:
|
|||
sharding_key: project_id
|
||||
belongs_to: component
|
||||
table_size: small
|
||||
desired_sharding_key_migration_job_name: BackfillPackagesDebianProjectComponentFilesProjectId
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddVersionPartsToPackagesTerraformModuleMetadata < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
milestone '17.10'
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
add_column :packages_terraform_module_metadata, :semver_major, :integer
|
||||
add_column :packages_terraform_module_metadata, :semver_minor, :integer
|
||||
add_column :packages_terraform_module_metadata, :semver_patch, :integer
|
||||
add_column :packages_terraform_module_metadata, :semver_prerelease, :text
|
||||
end
|
||||
|
||||
add_text_limit :packages_terraform_module_metadata, :semver_prerelease, 255
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_column :packages_terraform_module_metadata, :semver_major, :integer
|
||||
remove_column :packages_terraform_module_metadata, :semver_minor, :integer
|
||||
remove_column :packages_terraform_module_metadata, :semver_patch, :integer
|
||||
remove_column :packages_terraform_module_metadata, :semver_prerelease, :text
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddProjectIdToPackagesDebianProjectComponentFiles < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
|
||||
def change
|
||||
add_column :packages_debian_project_component_files, :project_id, :bigint
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddEvidencesProjectIdNotNull < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_not_null_constraint :evidences, :project_id
|
||||
end
|
||||
|
||||
def down
|
||||
remove_not_null_constraint :evidences, :project_id
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class FinalizeHkBackfillVulnerabilityOccurrenceIdentifiersProjectId < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
|
||||
|
||||
def up
|
||||
ensure_batched_background_migration_is_finished(
|
||||
job_class_name: 'BackfillVulnerabilityOccurrenceIdentifiersProjectId',
|
||||
table_name: :vulnerability_occurrence_identifiers,
|
||||
column_name: :id,
|
||||
job_arguments: [:project_id, :vulnerability_occurrences, :project_id, :occurrence_id],
|
||||
finalize: true
|
||||
)
|
||||
end
|
||||
|
||||
def down; end
|
||||
end
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class IndexPackagesDebianProjectComponentFilesOnProjectId < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
disable_ddl_transaction!
|
||||
|
||||
INDEX_NAME = 'index_packages_debian_project_component_files_on_project_id'
|
||||
|
||||
def up
|
||||
add_concurrent_index :packages_debian_project_component_files, :project_id, name: INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name :packages_debian_project_component_files, INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddPackagesDebianProjectComponentFilesProjectIdFk < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key :packages_debian_project_component_files, :projects, column: :project_id,
|
||||
on_delete: :cascade
|
||||
end
|
||||
|
||||
def down
|
||||
with_lock_retries do
|
||||
remove_foreign_key :packages_debian_project_component_files, column: :project_id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddPackagesDebianProjectComponentFilesProjectIdTrigger < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
|
||||
def up
|
||||
install_sharding_key_assignment_trigger(
|
||||
table: :packages_debian_project_component_files,
|
||||
sharding_key: :project_id,
|
||||
parent_table: :packages_debian_project_components,
|
||||
parent_sharding_key: :project_id,
|
||||
foreign_key: :component_id
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_sharding_key_assignment_trigger(
|
||||
table: :packages_debian_project_component_files,
|
||||
sharding_key: :project_id,
|
||||
parent_table: :packages_debian_project_components,
|
||||
parent_sharding_key: :project_id,
|
||||
foreign_key: :component_id
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class QueueBackfillPackagesDebianProjectComponentFilesProjectId < Gitlab::Database::Migration[2.2]
|
||||
milestone '17.10'
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
|
||||
|
||||
MIGRATION = "BackfillPackagesDebianProjectComponentFilesProjectId"
|
||||
DELAY_INTERVAL = 2.minutes
|
||||
BATCH_SIZE = 1000
|
||||
SUB_BATCH_SIZE = 100
|
||||
|
||||
def up
|
||||
queue_batched_background_migration(
|
||||
MIGRATION,
|
||||
:packages_debian_project_component_files,
|
||||
:id,
|
||||
:project_id,
|
||||
:packages_debian_project_components,
|
||||
:project_id,
|
||||
:component_id,
|
||||
job_interval: DELAY_INTERVAL,
|
||||
batch_size: BATCH_SIZE,
|
||||
sub_batch_size: SUB_BATCH_SIZE
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
delete_batched_background_migration(
|
||||
MIGRATION,
|
||||
:packages_debian_project_component_files,
|
||||
:id,
|
||||
[
|
||||
:project_id,
|
||||
:packages_debian_project_components,
|
||||
:project_id,
|
||||
:component_id
|
||||
]
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
9127a2f74f59d34354d74e3ad6113c49924fcab7176bf0bb349cbacfdcf0a574
|
||||
|
|
@ -0,0 +1 @@
|
|||
1f4d5a525a3f860e762292a4e0209d1ad88bc57341775e27f7e36558a455ea35
|
||||
|
|
@ -0,0 +1 @@
|
|||
98dace6c2236bde6eb75caa7a3b48e7a18fd94a6851c1d8b12c93efa847a8585
|
||||
|
|
@ -0,0 +1 @@
|
|||
a385918942265b050889d48071da188e7db1ed194e40ee45007a22ad3b5a1ef0
|
||||
|
|
@ -0,0 +1 @@
|
|||
b078309cfe8a8b49335fbb99d5b857d8ac18909d19451f97609ccc3b974cf74a
|
||||
|
|
@ -0,0 +1 @@
|
|||
0740154b8ccf87515cc2b4fb4bbd5e61fd163abb5677645dc8b85d79c5961cea
|
||||
|
|
@ -0,0 +1 @@
|
|||
71824066a1c3bc1409d19fa3fa391de8021574c3f51c71510c02ce35139e3f20
|
||||
|
|
@ -0,0 +1 @@
|
|||
846626fbc08e99bf7fde3f2c3a6b72775d7e85cc85a615276898383dd3e88e93
|
||||
|
|
@ -1140,6 +1140,22 @@ RETURN NEW;
|
|||
END
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_0af180e1ec89() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
IF NEW."project_id" IS NULL THEN
|
||||
SELECT "project_id"
|
||||
INTO NEW."project_id"
|
||||
FROM "packages_debian_project_components"
|
||||
WHERE "packages_debian_project_components"."id" = NEW."component_id";
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
|
||||
END
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_0c326daf67cf() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
|
|
@ -13711,7 +13727,8 @@ CREATE TABLE evidences (
|
|||
updated_at timestamp with time zone NOT NULL,
|
||||
summary_sha bytea,
|
||||
summary jsonb DEFAULT '{}'::jsonb NOT NULL,
|
||||
project_id bigint
|
||||
project_id bigint,
|
||||
CONSTRAINT check_32e833c325 CHECK ((project_id IS NOT NULL))
|
||||
);
|
||||
|
||||
CREATE SEQUENCE evidences_id_seq
|
||||
|
|
@ -18099,6 +18116,7 @@ CREATE TABLE packages_debian_project_component_files (
|
|||
file_store smallint DEFAULT 1 NOT NULL,
|
||||
file text NOT NULL,
|
||||
file_sha256 bytea NOT NULL,
|
||||
project_id bigint,
|
||||
CONSTRAINT check_e5af03fa2d CHECK ((char_length(file) <= 255))
|
||||
);
|
||||
|
||||
|
|
@ -18602,6 +18620,11 @@ CREATE TABLE packages_terraform_module_metadata (
|
|||
package_id bigint NOT NULL,
|
||||
project_id bigint NOT NULL,
|
||||
fields jsonb NOT NULL,
|
||||
semver_major integer,
|
||||
semver_minor integer,
|
||||
semver_patch integer,
|
||||
semver_prerelease text,
|
||||
CONSTRAINT check_46aa6c883a CHECK ((char_length(semver_prerelease) <= 255)),
|
||||
CONSTRAINT chk_rails_49f7b485ae CHECK ((char_length((fields)::text) <= 10485760))
|
||||
);
|
||||
|
||||
|
|
@ -34409,6 +34432,8 @@ CREATE INDEX index_packages_debian_project_architectures_on_project_id ON packag
|
|||
|
||||
CREATE INDEX index_packages_debian_project_component_files_on_component_id ON packages_debian_project_component_files USING btree (component_id);
|
||||
|
||||
CREATE INDEX index_packages_debian_project_component_files_on_project_id ON packages_debian_project_component_files USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_packages_debian_project_components_on_project_id ON packages_debian_project_components USING btree (project_id);
|
||||
|
||||
CREATE INDEX index_packages_debian_project_distribution_keys_on_project_id ON packages_debian_project_distribution_keys USING btree (project_id);
|
||||
|
|
@ -38503,6 +38528,8 @@ CREATE TRIGGER trigger_0a29d4d42b62 BEFORE INSERT OR UPDATE ON approval_project_
|
|||
|
||||
CREATE TRIGGER trigger_0aea02e5a699 BEFORE INSERT OR UPDATE ON protected_branch_merge_access_levels FOR EACH ROW EXECUTE FUNCTION trigger_0aea02e5a699();
|
||||
|
||||
CREATE TRIGGER trigger_0af180e1ec89 BEFORE INSERT OR UPDATE ON packages_debian_project_component_files FOR EACH ROW EXECUTE FUNCTION trigger_0af180e1ec89();
|
||||
|
||||
CREATE TRIGGER trigger_0c326daf67cf BEFORE INSERT OR UPDATE ON analytics_cycle_analytics_value_stream_settings FOR EACH ROW EXECUTE FUNCTION trigger_0c326daf67cf();
|
||||
|
||||
CREATE TRIGGER trigger_0d96daa4d734 BEFORE INSERT OR UPDATE ON bulk_import_export_uploads FOR EACH ROW EXECUTE FUNCTION trigger_0d96daa4d734();
|
||||
|
|
@ -40701,6 +40728,9 @@ ALTER TABLE ONLY ml_candidate_metrics
|
|||
ALTER TABLE ONLY approval_merge_request_rules
|
||||
ADD CONSTRAINT fk_e33a9aaf67 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY packages_debian_project_component_files
|
||||
ADD CONSTRAINT fk_e4ff7d8a8b FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY abuse_events
|
||||
ADD CONSTRAINT fk_e5ce49c215 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,10 @@ By deploying GitLab Duo Self-Hosted, you can manage the entire lifecycle of requ
|
|||
For a click-through demo, see [GitLab Duo Self-Hosted product tour](https://gitlab.navattic.com/gitlab-duo-self-hosted).
|
||||
<!-- Demo published on 2025-02-13 -->
|
||||
|
||||
<i class="fa-youtube-play" aria-hidden="true"></i>
|
||||
For an overview, see [GitLab Duo Self-Hosted: AI in your private environment](https://youtu.be/TQoO3sFnb28?si=uD-ps6aRnE28xNv3).
|
||||
<!-- Video published on 2025-02-20 -->
|
||||
|
||||
## Why use GitLab Duo Self-Hosted
|
||||
|
||||
With GitLab Duo Self-Hosted, you can:
|
||||
|
|
|
|||
|
|
@ -444,8 +444,8 @@ To disable forwarding Maven requests:
|
|||
|
||||
1. On the left sidebar, at the bottom, select **Admin**.
|
||||
1. Select **Settings > CI/CD**.
|
||||
1. Expand the **Package Registry** section.
|
||||
1. Clear the checkbox **Forward Maven package requests to the Maven Registry if the packages are not found in the GitLab Package Registry**.
|
||||
1. Expand the **Package registry** section.
|
||||
1. Clear the checkbox **Forward Maven package requests to the Maven registry if the packages are not found in the GitLab Package registry**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
### npm Forwarding
|
||||
|
|
@ -463,8 +463,8 @@ To disable it:
|
|||
|
||||
1. On the left sidebar, at the bottom, select **Admin**.
|
||||
1. Select **Settings > CI/CD**.
|
||||
1. Expand the **Package Registry** section.
|
||||
1. Clear the checkbox **Forward npm package requests to the npm Registry if the packages are not found in the GitLab Package Registry**.
|
||||
1. Expand the **Package registry** section.
|
||||
1. Clear the checkbox **Forward npm package requests to the npm registry if the packages are not found in the GitLab package registry**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
### PyPI Forwarding
|
||||
|
|
@ -482,8 +482,8 @@ To disable it:
|
|||
|
||||
1. On the left sidebar, at the bottom, select **Admin**.
|
||||
1. Select **Settings > CI/CD**.
|
||||
1. Expand the **Package Registry** section.
|
||||
1. Clear the checkbox **Forward PyPI package requests to the PyPI Registry if the packages are not found in the GitLab Package Registry**.
|
||||
1. Expand the **Package registry** section.
|
||||
1. Clear the checkbox **Forward PyPI package requests to the PyPI registry if the packages are not found in the GitLab package registry**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
### Package file size limits
|
||||
|
|
@ -494,7 +494,7 @@ To set the maximum file size:
|
|||
|
||||
1. On the left sidebar, at the bottom, select **Admin**.
|
||||
1. Select **Settings > CI/CD**.
|
||||
1. Expand the **Package Registry** section.
|
||||
1. Expand the **Package registry** section.
|
||||
1. Find the package type you would like to adjust.
|
||||
1. Enter the maximum file size, in bytes.
|
||||
1. Select **Save size limits**.
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ If an authenticated user declines the terms, they are signed out.
|
|||
|
||||
When enabled, it adds a mandatory checkbox to the sign up page for new users:
|
||||
|
||||

|
||||

|
||||
|
||||
<!-- ## Troubleshooting
|
||||
|
||||
|
|
|
|||
|
|
@ -23382,6 +23382,7 @@ The currently authenticated GitLab user.
|
|||
| <a id="currentuserpronouns"></a>`pronouns` | [`String`](#string) | Pronouns of the user. |
|
||||
| <a id="currentuserpublicemail"></a>`publicEmail` | [`String`](#string) | User's public email. |
|
||||
| <a id="currentuserrecentlyviewedissues"></a>`recentlyViewedIssues` {{< icon name="warning-solid" >}} | [`[Issue!]`](#issue) | **Introduced** in GitLab 17.9. **Status**: Experiment. Most-recently viewed issues for the current user. |
|
||||
| <a id="currentuserrecentlyviewedmergerequests"></a>`recentlyViewedMergeRequests` {{< icon name="warning-solid" >}} | [`[MergeRequest!]`](#mergerequest) | **Introduced** in GitLab 17.10. **Status**: Experiment. Most-recently viewed merge requests for the current user. |
|
||||
| <a id="currentusersavedreplies"></a>`savedReplies` | [`SavedReplyConnection`](#savedreplyconnection) | Saved replies authored by the user. (see [Connections](#connections)) |
|
||||
| <a id="currentuserstate"></a>`state` | [`UserState!`](#userstate) | State of the user. |
|
||||
| <a id="currentuserstatus"></a>`status` | [`UserStatus`](#userstatus) | User status. |
|
||||
|
|
@ -32481,7 +32482,7 @@ An organization user badge.
|
|||
|
||||
### `Package`
|
||||
|
||||
Represents a package with pipelines in the Package Registry.
|
||||
Represents a package with pipelines in the package registry.
|
||||
|
||||
#### Fields
|
||||
|
||||
|
|
@ -32505,7 +32506,7 @@ Represents a package with pipelines in the Package Registry.
|
|||
|
||||
### `PackageBase`
|
||||
|
||||
Represents a package in the Package Registry.
|
||||
Represents a package in the package registry.
|
||||
|
||||
#### Fields
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ package registry, see the [Composer package registry documentation](../../user/p
|
|||
{{< alert type="note" >}}
|
||||
|
||||
These endpoints do not adhere to the standard API authentication methods.
|
||||
See the [Composer Package Registry documentation](../../user/packages/composer_repository/_index.md)
|
||||
See the [Composer package registry documentation](../../user/packages/composer_repository/_index.md)
|
||||
for details on which headers and token types are supported. Undocumented authentication methods might be removed in the future.
|
||||
|
||||
{{< /alert >}}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ and is generally not meant for manual consumption.
|
|||
{{< /alert >}}
|
||||
|
||||
For instructions on how to upload and install Helm packages from the GitLab
|
||||
Package Registry, see the [Helm registry documentation](../../user/packages/helm_repository/_index.md).
|
||||
package registry, see the [Helm registry documentation](../../user/packages/helm_repository/_index.md).
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ and is not meant for manual consumption.
|
|||
{{< /alert >}}
|
||||
|
||||
For instructions on how to upload and install npm packages from the GitLab
|
||||
Package Registry, see the [npm package registry documentation](../../user/packages/npm_registry/_index.md).
|
||||
package registry, see the [npm package registry documentation](../../user/packages/npm_registry/_index.md).
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ The metadata file content is generated by npm, but looks something like this:
|
|||
"_nodeVersion": "12.18.4",
|
||||
"_npmVersion": "6.14.6",
|
||||
"author": {
|
||||
"name": "GitLab Package Registry Utility"
|
||||
"name": "GitLab package registry Utility"
|
||||
},
|
||||
"description": "Package created by me",
|
||||
"dist": {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ and is generally not meant for manual consumption.
|
|||
{{< /alert >}}
|
||||
|
||||
For instructions on how to upload and install NuGet packages from the GitLab
|
||||
Package Registry, see the [NuGet package registry documentation](../../user/packages/nuget_repository/_index.md).
|
||||
package registry, see the [NuGet package registry documentation](../../user/packages/nuget_repository/_index.md).
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ and is generally not meant for manual consumption.
|
|||
{{< /alert >}}
|
||||
|
||||
For instructions on how to upload and install PyPI packages from the GitLab
|
||||
Package Registry, see the [PyPI package registry documentation](../../user/packages/pypi_repository/_index.md).
|
||||
package registry, see the [PyPI package registry documentation](../../user/packages/pypi_repository/_index.md).
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
|
|
|
|||
|
|
@ -612,11 +612,11 @@ to configure other related settings. These requirements are
|
|||
| `mirror_capacity_threshold` | integer | no | Minimum capacity to be available before scheduling more mirrors preemptively. Premium and Ultimate only. |
|
||||
| `mirror_max_capacity` | integer | no | Maximum number of mirrors that can be synchronizing at the same time. Premium and Ultimate only. |
|
||||
| `mirror_max_delay` | integer | no | Maximum time (in minutes) between updates that a mirror can have when scheduled to synchronize. Premium and Ultimate only. |
|
||||
| `maven_package_requests_forwarding` | boolean | no | Use repo.maven.apache.org as a default remote repository when the package is not found in the GitLab Package Registry for Maven. Premium and Ultimate only. |
|
||||
| `npm_package_requests_forwarding` | boolean | no | Use npmjs.org as a default remote repository when the package is not found in the GitLab Package Registry for npm. Premium and Ultimate only. |
|
||||
| `pypi_package_requests_forwarding` | boolean | no | Use pypi.org as a default remote repository when the package is not found in the GitLab Package Registry for PyPI. Premium and Ultimate only. |
|
||||
| `maven_package_requests_forwarding` | boolean | no | Use repo.maven.apache.org as a default remote repository when the package is not found in the GitLab package registry for Maven. Premium and Ultimate only. |
|
||||
| `npm_package_requests_forwarding` | boolean | no | Use npmjs.org as a default remote repository when the package is not found in the GitLab package registry for npm. Premium and Ultimate only. |
|
||||
| `pypi_package_requests_forwarding` | boolean | no | Use pypi.org as a default remote repository when the package is not found in the GitLab package registry for PyPI. Premium and Ultimate only. |
|
||||
| `outbound_local_requests_whitelist` | array of strings | no | Define a list of trusted domains or IP addresses to which local requests are allowed when local requests for webhooks and integrations are disabled. |
|
||||
| `package_registry_allow_anyone_to_pull_option` | boolean | no | Enable to [allow anyone to pull from Package Registry](../user/packages/package_registry/_index.md#allow-anyone-to-pull-from-package-registry) visible and changeable. |
|
||||
| `package_registry_allow_anyone_to_pull_option` | boolean | no | Enable to [allow anyone to pull from package registry](../user/packages/package_registry/_index.md#allow-anyone-to-pull-from-package-registry) visible and changeable. |
|
||||
| `package_metadata_purl_types` | array of integers | no | List of [package registry metadata to sync](../administration/settings/security_and_compliance.md#choose-package-registry-metadata-to-sync). See [the list](https://gitlab.com/gitlab-org/gitlab/-/blob/ace16c20d5da7c4928dd03fb139692638b557fe3/app/models/concerns/enums/package_metadata.rb#L5) of the available values. GitLab Self-Managed, Ultimate only. |
|
||||
| `pages_domain_verification_enabled` | boolean | no | Require users to prove ownership of custom domains. Domain verification is an essential security measure for public GitLab sites. Users are required to demonstrate they control a domain before it is enabled. |
|
||||
| `password_authentication_enabled_for_git` | boolean | no | Enable authentication for Git over HTTP(S) via a GitLab account password. Default is `true`. |
|
||||
|
|
@ -719,9 +719,9 @@ to configure other related settings. These requirements are
|
|||
| `throttle_authenticated_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_authenticated_api_period_in_seconds` and `throttle_authenticated_api_requests_per_period`) Enable authenticated API request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
|
||||
| `throttle_authenticated_api_period_in_seconds` | integer | required by:<br>`throttle_authenticated_api_enabled` | Rate limit period (in seconds). |
|
||||
| `throttle_authenticated_api_requests_per_period` | integer | required by:<br>`throttle_authenticated_api_enabled` | Maximum requests per period per user. |
|
||||
| `throttle_authenticated_packages_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_authenticated_packages_api_period_in_seconds` and `throttle_authenticated_packages_api_requests_per_period`) Enable authenticated API request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). View [Package Registry rate limits](../administration/settings/package_registry_rate_limits.md) for more details. |
|
||||
| `throttle_authenticated_packages_api_period_in_seconds` | integer | required by:<br>`throttle_authenticated_packages_api_enabled` | Rate limit period (in seconds). View [Package Registry rate limits](../administration/settings/package_registry_rate_limits.md) for more details. |
|
||||
| `throttle_authenticated_packages_api_requests_per_period` | integer | required by:<br>`throttle_authenticated_packages_api_enabled` | Maximum requests per period per user. View [Package Registry rate limits](../administration/settings/package_registry_rate_limits.md) for more details. |
|
||||
| `throttle_authenticated_packages_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_authenticated_packages_api_period_in_seconds` and `throttle_authenticated_packages_api_requests_per_period`) Enable authenticated API request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). View [package registry rate limits](../administration/settings/package_registry_rate_limits.md) for more details. |
|
||||
| `throttle_authenticated_packages_api_period_in_seconds` | integer | required by:<br>`throttle_authenticated_packages_api_enabled` | Rate limit period (in seconds). View [package registry rate limits](../administration/settings/package_registry_rate_limits.md) for more details. |
|
||||
| `throttle_authenticated_packages_api_requests_per_period` | integer | required by:<br>`throttle_authenticated_packages_api_enabled` | Maximum requests per period per user. View [package registry rate limits](../administration/settings/package_registry_rate_limits.md) for more details. |
|
||||
| `throttle_authenticated_web_enabled` | boolean | no | (**If enabled, requires:** `throttle_authenticated_web_period_in_seconds` and `throttle_authenticated_web_requests_per_period`) Enable authenticated web request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
|
||||
| `throttle_authenticated_web_period_in_seconds` | integer | required by:<br>`throttle_authenticated_web_enabled` | Rate limit period (in seconds). |
|
||||
| `throttle_authenticated_web_requests_per_period` | integer | required by:<br>`throttle_authenticated_web_enabled` | Maximum requests per period per user. |
|
||||
|
|
@ -731,9 +731,9 @@ to configure other related settings. These requirements are
|
|||
| `throttle_unauthenticated_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_unauthenticated_api_period_in_seconds` and `throttle_unauthenticated_api_requests_per_period`) Enable unauthenticated API request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
|
||||
| `throttle_unauthenticated_api_period_in_seconds` | integer | required by:<br>`throttle_unauthenticated_api_enabled` | Rate limit period in seconds. |
|
||||
| `throttle_unauthenticated_api_requests_per_period` | integer | required by:<br>`throttle_unauthenticated_api_enabled` | Max requests per period per IP. |
|
||||
| `throttle_unauthenticated_packages_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_unauthenticated_packages_api_period_in_seconds` and `throttle_unauthenticated_packages_api_requests_per_period`) Enable authenticated API request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). View [Package Registry rate limits](../administration/settings/package_registry_rate_limits.md) for more details. |
|
||||
| `throttle_unauthenticated_packages_api_period_in_seconds` | integer | required by:<br>`throttle_unauthenticated_packages_api_enabled` | Rate limit period (in seconds). View [Package Registry rate limits](../administration/settings/package_registry_rate_limits.md) for more details. |
|
||||
| `throttle_unauthenticated_packages_api_requests_per_period` | integer | required by:<br>`throttle_unauthenticated_packages_api_enabled` | Maximum requests per period per user. View [Package Registry rate limits](../administration/settings/package_registry_rate_limits.md) for more details. |
|
||||
| `throttle_unauthenticated_packages_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_unauthenticated_packages_api_period_in_seconds` and `throttle_unauthenticated_packages_api_requests_per_period`) Enable authenticated API request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). View [package registry rate limits](../administration/settings/package_registry_rate_limits.md) for more details. |
|
||||
| `throttle_unauthenticated_packages_api_period_in_seconds` | integer | required by:<br>`throttle_unauthenticated_packages_api_enabled` | Rate limit period (in seconds). View [package registry rate limits](../administration/settings/package_registry_rate_limits.md) for more details. |
|
||||
| `throttle_unauthenticated_packages_api_requests_per_period` | integer | required by:<br>`throttle_unauthenticated_packages_api_enabled` | Maximum requests per period per user. View [package registry rate limits](../administration/settings/package_registry_rate_limits.md) for more details. |
|
||||
| `throttle_unauthenticated_web_enabled` | boolean | no | (**If enabled, requires:** `throttle_unauthenticated_web_period_in_seconds` and `throttle_unauthenticated_web_requests_per_period`) Enable unauthenticated web request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
|
||||
| `throttle_unauthenticated_web_period_in_seconds` | integer | required by:<br>`throttle_unauthenticated_web_enabled` | Rate limit period in seconds. |
|
||||
| `throttle_unauthenticated_web_requests_per_period` | integer | required by:<br>`throttle_unauthenticated_web_enabled` | Max requests per period per IP. |
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ Test the pipeline by creating a commit with a message like:
|
|||
fix: testing patch releases
|
||||
```
|
||||
|
||||
Push the commit to the default branch. The pipeline should create a new release (`v1.0.0`) on the project's **Releases** page and publish a new version of the package to the project's **Package Registry** page.
|
||||
Push the commit to the default branch. The pipeline should create a new release (`v1.0.0`) on the project's **Releases** page and publish a new version of the package to the project's **Package registry** page.
|
||||
|
||||
To create a minor release, use a commit message like:
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ This page includes an exhaustive list of settings related to and maintained by t
|
|||
| `npm_package_requests_forwarding` | `application_settings` | Enables or disables npm package forwarding for the instance. |
|
||||
| `pypi_package_requests_forwarding` | `application_settings` | Enables or disables PyPI package forwarding for the instance. |
|
||||
| `packages_cleanup_package_file_worker_capacity` | `application_settings` | Number of concurrent workers allowed for package file cleanup. |
|
||||
| `package_registry_allow_anyone_to_pull_option` | `application_settings` | Enables or disables the `Allow anyone to pull from Package Registry` toggle. |
|
||||
| `package_registry_allow_anyone_to_pull_option` | `application_settings` | Enables or disables the `Allow anyone to pull from package registry` toggle. |
|
||||
| `throttle_unauthenticated_packages_api_requests_per_period` | `application_settings` | Request limit for unauthenticated package API requests in the period defined by `throttle_unauthenticated_packages_api_period_in_seconds`. |
|
||||
| `throttle_unauthenticated_packages_api_period_in_seconds` | `application_settings` | Period in seconds to measure unauthenticated package API requests. |
|
||||
| `throttle_authenticated_packages_api_requests_per_period` | `application_settings` | Request limit for authenticated package API requests in the period defined by `throttle_authenticated_packages_api_period_in_seconds`. |
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ Unless otherwise noted, all of this content applies to both GitLab.com and self-
|
|||
|
||||
## Rust CD
|
||||
|
||||
- GitLab Package Registry Support for Cargo - [Open for Contributions](https://gitlab.com/gitlab-org/gitlab/-/issues/33060)
|
||||
- GitLab package registry Support for Cargo - [Open for Contributions](https://gitlab.com/gitlab-org/gitlab/-/issues/33060)
|
||||
- [GitLab CICD Rust Component (Currently in Prerelease)](https://gitlab.com/explore/catalog/components/rust) `[GitLab Built]`
|
||||
- [How To Use the Rust Component](../../../ci/components/examples.md#example-test-a-rust-language-cicd-component) `[GitLab Built]`
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,10 @@ To improve your workflow across the entire software development lifecycle, try t
|
|||
- [GitLab Duo Chat](../gitlab_duo_chat/_index.md): Write and understand code, get up to speed on the status of projects,
|
||||
and learn about GitLab by asking your questions in a chat window.
|
||||
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://www.youtube.com/watch?v=ZQBAuf-CTAY)
|
||||
<!-- Video published on 2024-04-18 -->
|
||||
- [GitLab Duo Self-Hosted](../../administration/gitlab_duo_self_hosted/_index.md): Host the language models that power AI features in GitLab.
|
||||
<i class="fa fa-youtube-play youtube" aria-hidden="true"></i> [Watch overview](https://youtu.be/TQoO3sFnb28?si=w_gFAYLYIzPEbhEl)
|
||||
<!-- Video published on 2025-02-20 -->
|
||||
Code Suggestions and Chat are supported. Use GitLab model vendors or self-host a supported language model.
|
||||
- [GitLab Duo Workflow](../duo_workflow/_index.md): Automate tasks and help increase productivity in your development workflow.
|
||||
- [AI Impact Dashboard](../analytics/ai_impact_analytics.md): Measure the AI effectiveness and impact on SDLC metrics.
|
||||
|
|
@ -115,7 +118,7 @@ To improve your security, try these features:
|
|||
| [Fix Code](../gitlab_duo_chat/examples.md#fix-code-in-the-ide) | Premium, Ultimate | GitLab Duo Pro or Enterprise | GitLab.com, Self-managed, GitLab Dedicated | General availability |
|
||||
| [GitLab Duo for the CLI](../../editor_extensions/gitlab_cli/_index.md#gitlab-duo-for-the-cli) | Ultimate | GitLab Duo Enterprise | GitLab.com, Self-managed, GitLab Dedicated | General availability |
|
||||
| [Merge Request Summary](../project/merge_requests/duo_in_merge_requests.md#generate-a-description-by-summarizing-code-changes) | Ultimate | GitLab Duo Enterprise | GitLab.com | Beta |
|
||||
| [Code Review](../project/merge_requests/duo_in_merge_requests.md#have-gitlab-duo-review-your-code) | Ultimate | GitLab Duo Enterprise | GitLab.com | Experiment |
|
||||
| [Code Review](../project/merge_requests/duo_in_merge_requests.md#have-gitlab-duo-review-your-code) | Ultimate | GitLab Duo Enterprise | GitLab.com | Beta |
|
||||
| [Code Review Summary](../project/merge_requests/duo_in_merge_requests.md#summarize-a-code-review) | Ultimate | GitLab Duo Enterprise | GitLab.com, Self-managed | Experiment |
|
||||
| [Merge Commit Message Generation](../project/merge_requests/duo_in_merge_requests.md#generate-a-merge-commit-message) | Ultimate | GitLab Duo Enterprise | GitLab.com, Self-managed, GitLab Dedicated | General availability |
|
||||
| [Root Cause Analysis](../gitlab_duo_chat/examples.md#troubleshoot-failed-cicd-jobs-with-root-cause-analysis) | Ultimate | GitLab Duo Enterprise | GitLab.com, Self-managed, GitLab Dedicated | General availability |
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ To publish the package with a deploy token:
|
|||
- `<tag>` is the Git tag name of the version you want to publish.
|
||||
To publish a branch, use `branch=<branch>` instead of `tag=<tag>`.
|
||||
|
||||
You can view the published package by going to **Deploy > Package Registry** and
|
||||
You can view the published package by going to **Deploy > Package registry** and
|
||||
selecting the **Composer** tab.
|
||||
|
||||
## Publish a Composer package by using CI/CD
|
||||
|
|
@ -104,7 +104,7 @@ You can publish a Composer package to the package registry as part of your CI/CD
|
|||
|
||||
1. Run the pipeline.
|
||||
|
||||
To view the published package, go to **Deploy > Package Registry** and select the **Composer** tab.
|
||||
To view the published package, go to **Deploy > Package registry** and select the **Composer** tab.
|
||||
|
||||
### Use a CI/CD template
|
||||
|
||||
|
|
|
|||
|
|
@ -314,7 +314,7 @@ There are two ways to remove a Conan package from the GitLab package registry.
|
|||
|
||||
- From the GitLab user interface:
|
||||
|
||||
Go to your project's **Deploy > Package Registry**. Remove the
|
||||
Go to your project's **Deploy > Package registry**. Remove the
|
||||
package by selecting **Remove repository** ({{< icon name="remove" >}}).
|
||||
|
||||
## Search for Conan packages in the package registry
|
||||
|
|
|
|||
|
|
@ -681,7 +681,7 @@ And the `.npmrc` file should look like:
|
|||
|
||||
If you get this error, ensure that:
|
||||
|
||||
- The package registry is enabled in your project settings. Although the package registry is enabled by default, it's possible to [disable it](../package_registry/_index.md#disable-the-package-registry).
|
||||
- The package registry is enabled in your project settings. Although the package registry is enabled by default, it's possible to [disable it](../package_registry/_index.md#turn-off-the-package-registry).
|
||||
- Your token is not expired and has appropriate permissions.
|
||||
- A package with the same name or version doesn't already exist within the given scope.
|
||||
- The scoped packages URL includes a trailing slash:
|
||||
|
|
|
|||
|
|
@ -33,10 +33,10 @@ Learn how to use the GitLab package registry to build your own custom package wo
|
|||
|
||||
## View packages
|
||||
|
||||
You can view packages for your project or group.
|
||||
You can view packages for your project or group:
|
||||
|
||||
1. Go to the project or group.
|
||||
1. Go to **Deploy > Package Registry**.
|
||||
1. Go to **Deploy > Package registry**.
|
||||
|
||||
You can search, sort, and filter packages on this page. You can share your search results by copying
|
||||
and pasting the URL from your browser.
|
||||
|
|
@ -49,7 +49,7 @@ When you view packages in a group:
|
|||
- Only the projects you can access are displayed.
|
||||
- If a project is private, or you are not a member of the project, the packages from that project are not displayed.
|
||||
|
||||
For information on how to create and upload a package, view the GitLab documentation for your package type.
|
||||
To learn how to create and upload a package, follow the instructions for your [package type](supported_package_managers.md).
|
||||
|
||||
## Authenticate with the registry
|
||||
|
||||
|
|
@ -68,13 +68,15 @@ For most package types, the following credential types are valid:
|
|||
- [Job token](../../../ci/jobs/ci_job_token.md):
|
||||
allows access to packages in the project running the job for the users running the pipeline.
|
||||
Access to other external projects can be configured.
|
||||
- If your organization uses two factor authentication (2FA), you must use a personal access token with the scope set to `api`.
|
||||
- If you are publishing a package by using CI/CD pipelines, you must use a CI job token.
|
||||
- If your organization uses two-factor authentication (2FA), you must use a personal access token with the scope set to `api`.
|
||||
- If you are publishing a package by using CI/CD pipelines, you must use a CI/CD job token.
|
||||
|
||||
{{< alert type="note" >}}
|
||||
|
||||
If the "Package registry" feature is turned off for your project at **Settings > General > Visibility, project features, permissions**, you will receive a 403 Forbidden response.
|
||||
Accessing the package registry with a deploy token is not available when external authorization is enabled.
|
||||
When configuring authentication to the package registry:
|
||||
|
||||
- If the **Package registry** project setting is [turned off](#turn-off-the-package-registry), you receive a `403 Forbidden` error when you interact with the package registry, even if you have the Owner role.
|
||||
- If [external authorization](../../../administration/settings/external_authorization.md) is turned on, you can't access the package registry with a deploy token.
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
|
|
@ -87,7 +89,7 @@ a package registry.
|
|||
|
||||
You can authenticate with GitLab by using the `CI_JOB_TOKEN`.
|
||||
|
||||
CI/CD templates, which you can use to get started, are in [this repository](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates).
|
||||
To get started, you can use the available [CI/CD templates](https://gitlab.com/gitlab-org/gitlab/-/tree/master/lib/gitlab/ci/templates).
|
||||
|
||||
For more information about using the GitLab package registry with CI/CD, see:
|
||||
|
||||
|
|
@ -117,13 +119,14 @@ For a list of supported packages, see [Importing packages from other repositorie
|
|||
For information on reducing your storage use for the package registry, see
|
||||
[Reduce package registry storage use](reduce_package_registry_storage.md).
|
||||
|
||||
## Disable the package registry
|
||||
## Turn off the package registry
|
||||
|
||||
The package registry is automatically enabled.
|
||||
The package registry is automatically turned on.
|
||||
|
||||
If you are using a self-managed instance of GitLab, your administrator can remove
|
||||
the menu item, **Packages and registries**, from the GitLab sidebar. For more information,
|
||||
see the [administration documentation](../../../administration/packages/_index.md).
|
||||
On a GitLab Self-Managed instance, your administrator can remove
|
||||
the **Packages and registries** menu item from the GitLab sidebar.
|
||||
For more information,
|
||||
see [GitLab package registry administration](../../../administration/packages/_index.md).
|
||||
|
||||
You can also remove the package registry for your project specifically:
|
||||
|
||||
|
|
@ -132,23 +135,23 @@ You can also remove the package registry for your project specifically:
|
|||
**Packages** feature.
|
||||
1. Select **Save changes**.
|
||||
|
||||
The **Deploy > Package Registry** entry is removed from the sidebar.
|
||||
The **Deploy > Package registry** entry is removed from the sidebar.
|
||||
|
||||
## Package registry visibility permissions
|
||||
|
||||
[Project-level permissions](../../permissions.md)
|
||||
determine actions such as downloading, pushing, or deleting packages.
|
||||
[Project permissions](../../permissions.md)
|
||||
determine which members and users can download, push, or delete packages.
|
||||
|
||||
The visibility of the package registry is independent of the repository and can be controlled from
|
||||
your project's settings. For example, if you have a public project and set the repository visibility
|
||||
to **Only Project Members**, the package registry is then public. Disabling the Package
|
||||
Registry disables all package registry operations.
|
||||
to **Only Project Members**, the package registry is then public. Turning off the **Package
|
||||
registry** toggle turns off all package registry operations.
|
||||
|
||||
| Project visibility | Action | Minimum [role](../../permissions.md#roles) required |
|
||||
|--------------------|-----------------------|---------------------------------------------------------|
|
||||
| Public | View package registry | `n/a`, everyone on the internet can perform this action |
|
||||
| Public | View package registry | N/A. Anyone on the internet can perform this action. |
|
||||
| Public | Publish a package | Developer |
|
||||
| Public | Pull a package | `n/a`, everyone on the internet can perform this action |
|
||||
| Public | Pull a package | N/A. Anyone on the internet can perform this action. |
|
||||
| Internal | View package registry | Guest |
|
||||
| Internal | Publish a package | Developer |
|
||||
| Internal | Pull a package | Guest (1) |
|
||||
|
|
@ -172,7 +175,7 @@ To allow anyone to pull from the package registry, regardless of project visibil
|
|||
1. On the left sidebar, select **Search or go to** and find your private or internal project.
|
||||
1. Select **Settings > General**.
|
||||
1. Expand **Visibility, project features, permissions**.
|
||||
1. Turn on the **Allow anyone to pull from Package Registry** toggle.
|
||||
1. Turn on the **Allow anyone to pull from package registry** toggle.
|
||||
1. Select **Save changes**.
|
||||
|
||||
Anyone on the internet can access the package registry for the project.
|
||||
|
|
@ -183,17 +186,17 @@ Prerequisites:
|
|||
|
||||
- You must be an administrator.
|
||||
|
||||
To hide the **Allow anyone to pull from Package Registry** toggle globally:
|
||||
To hide the **Allow anyone to pull from package registry** toggle globally:
|
||||
|
||||
- [Update the application setting](../../../api/settings.md#update-application-settings) `package_registry_allow_anyone_to_pull_option` to `false`.
|
||||
|
||||
Anonymous downloads are disabled, even for projects that turned on the **Allow anyone to pull from Package Registry** toggle.
|
||||
Anonymous downloads are turned off, even for projects that turned on the **Allow anyone to pull from Package Registry** toggle.
|
||||
|
||||
Several known issues exist when you allow anyone to pull from the package registry:
|
||||
|
||||
- Endpoints for projects are supported.
|
||||
- NuGet registry endpoints for groups are supported. However, because of how NuGet clients send the authentication credentials, anonymous downloads are not allowed. Only GitLab users can pull from the package registry, even if this feature is enabled.
|
||||
- Maven registry endpoint for groups are supported.
|
||||
- NuGet registry endpoints for groups are supported. However, because of how NuGet clients send the authentication credentials, anonymous downloads are not allowed. Only GitLab users can pull from the package registry, even if this setting is turned on.
|
||||
- Maven registry endpoints for groups are supported.
|
||||
- Terraform module registry endpoints for namespaces are supported.
|
||||
- Other group and instance endpoints are not fully supported. Support for group endpoints is proposed in [epic 14234](https://gitlab.com/groups/gitlab-org/-/epics/14234).
|
||||
- It does not work with the [Composer](../composer_repository/_index.md#install-a-composer-package), because Composer only has a group endpoint.
|
||||
|
|
@ -214,7 +217,7 @@ Several known issues exist when you allow anyone to pull from the package regist
|
|||
|
||||
{{< /history >}}
|
||||
|
||||
Create audit events when a package is published or deleted. Namespace Owners can turn on the `audit_events_enabled` setting through the [GraphQl API](../../../api/graphql/reference/_index.md#packagesettings).
|
||||
Create audit events when a package is published or deleted. Namespace Owners can turn on the `audit_events_enabled` setting through the [GraphQL API](../../../api/graphql/reference/_index.md#packagesettings).
|
||||
|
||||
You can view audit events:
|
||||
|
||||
|
|
@ -223,9 +226,9 @@ You can view audit events:
|
|||
|
||||
## Accepting contributions
|
||||
|
||||
This table lists unsupported package manager formats that we are accepting contributions for.
|
||||
Consider contributing to GitLab. This [development documentation](../../../development/packages/_index.md)
|
||||
guides you through the process.
|
||||
The following table lists unsupported package manager formats that we are accepting contributions for.
|
||||
See the [development guidelines](../../../development/packages/_index.md)
|
||||
to learn how to contribute to GitLab.
|
||||
|
||||
<!-- vale gitlab_base.Spelling = NO -->
|
||||
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ and that users who pull from the cache have the necessary authentication:
|
|||
1. In the global configuration, if the following features are disabled, enable them:
|
||||
- The [`package` feature](../../../../administration/packages/_index.md#enable-or-disable-the-package-registry). Enabled by default.
|
||||
- The [`dependency_proxy` feature](../../../../administration/packages/dependency_proxy.md#turn-on-the-dependency-proxy). Enabled by default.
|
||||
1. In the project settings, if the [`package` feature](../_index.md#disable-the-package-registry)
|
||||
1. In the project settings, if the [`package` feature](../_index.md#turn-off-the-package-registry)
|
||||
is disabled, enable it. It is enabled by default.
|
||||
1. [Add an authentication method](#configure-a-client). The dependency proxy supports the same [authentication methods](../_index.md#authenticate-with-the-registry) as the package registry:
|
||||
- [Personal access token](../../../profile/personal_access_tokens.md)
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ You can delete packages by using [the API](../../../api/packages.md#delete-a-pro
|
|||
|
||||
To delete a package in the UI, from your group or project:
|
||||
|
||||
1. Go to **Deploy > Package Registry**.
|
||||
1. Go to **Deploy > Package registry**.
|
||||
1. Find the name of the package you want to delete.
|
||||
1. Select **Delete**.
|
||||
|
||||
|
|
@ -52,7 +52,7 @@ You can delete packages by using [the API](../../../api/packages.md#delete-a-pac
|
|||
|
||||
To delete package assets in the UI, from your group or project:
|
||||
|
||||
1. Go to **Deploy > Package Registry**.
|
||||
1. Go to **Deploy > Package registry**.
|
||||
1. Find the name of the package you want to delete.
|
||||
1. Select the package to view additional details.
|
||||
1. Find the name of the assets you would like to delete.
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ Provide feedback on this feature in [issue 443236](https://gitlab.com/gitlab-org
|
|||
|
||||
{{< details >}}
|
||||
|
||||
- Status: Experiment
|
||||
- Status: Beta
|
||||
- LLM: Anthropic [Claude 3.5 Sonnet](https://console.cloud.google.com/vertex-ai/publishers/anthropic/model-garden/claude-3-5-sonnet)
|
||||
|
||||
{{< /details >}}
|
||||
|
|
@ -61,7 +61,8 @@ Provide feedback on this feature in [issue 443236](https://gitlab.com/gitlab-org
|
|||
{{< history >}}
|
||||
|
||||
- [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/14825) in GitLab 17.5 as an [experiment](../../../policy/development_stages_support.md#experiment) behind two feature flags named [`ai_review_merge_request`](https://gitlab.com/gitlab-org/gitlab/-/issues/456106) and [`duo_code_review_chat`](https://gitlab.com/gitlab-org/gitlab/-/issues/508632), both disabled by default.
|
||||
- Feature flags [`ai_review_merge_request`](https://gitlab.com/gitlab-org/gitlab/-/issues/456106) and [`duo_code_review_chat`](https://gitlab.com/gitlab-org/gitlab/-/issues/508632) enabled for GitLab.com in 17.10.
|
||||
- Feature flags [`ai_review_merge_request`](https://gitlab.com/gitlab-org/gitlab/-/issues/456106) and [`duo_code_review_chat`](https://gitlab.com/gitlab-org/gitlab/-/issues/508632) enabled by default on GitLab.com, GitLab Self-Managed, and GitLab Dedicated in 17.10.
|
||||
- [Changed](https://gitlab.com/gitlab-org/gitlab/-/issues/516234) to beta in GitLab 17.10.
|
||||
|
||||
{{< /history >}}
|
||||
|
||||
|
|
@ -72,12 +73,6 @@ For more information, see the history.
|
|||
|
||||
{{< /alert >}}
|
||||
|
||||
{{< alert type="warning" >}}
|
||||
|
||||
This feature is considered [experimental](../../../policy/development_stages_support.md) and breaking changes may still be made to this feature.
|
||||
|
||||
{{< /alert >}}
|
||||
|
||||
When your merge request is ready to be reviewed, use GitLab Duo Code Review to perform an initial review:
|
||||
|
||||
1. On the left sidebar, select **Search or go to** and find your project.
|
||||
|
|
|
|||
|
|
@ -22,12 +22,15 @@ Each commit shows:
|
|||
|
||||
- The date of the commit. GitLab groups together all commits made on the same day.
|
||||
- The user's avatar.
|
||||
- The user's name. Hover over the name to see the user's job title, location, local time, and current status message.
|
||||
- The user's name. Hover over the name to see the user's job title, location, local time,
|
||||
and current status message.
|
||||
- The date of the commit, in time-ago format. To see the precise date and time of
|
||||
the commit, hover over the date.
|
||||
- If the [commit is signed](../signed_commits/_index.md), a **Verified** badge.
|
||||
- The commit SHA. GitLab shows the first 8 characters. Select **Copy commit SHA** ({{< icon name="copy-to-clipboard" >}}) to copy the entire SHA.
|
||||
- A link to **browse** ({{< icon name="folder-open" >}}) the file as it appeared at the time of this commit.
|
||||
- The commit SHA. GitLab shows the first 8 characters.
|
||||
Select **Copy commit SHA** ({{< icon name="copy-to-clipboard" >}}) to copy the entire SHA.
|
||||
- A link to **browse** ({{< icon name="folder-open" >}}) the file as it appeared at the time of
|
||||
this commit.
|
||||
|
||||
GitLab retrieves the user name and email information from the
|
||||
[Git configuration](https://git-scm.com/book/en/v2/Customizing-Git-Git-Configuration)
|
||||
|
|
@ -42,14 +45,6 @@ To see a file's Git history in the UI:
|
|||
1. Go to your desired file in the repository.
|
||||
1. In the upper-right corner, select **History**.
|
||||
|
||||
## Related topics
|
||||
|
||||
- [Git blame](git_blame.md) for line-by-line information about a file
|
||||
- [Common Git commands](../../../../topics/git/commands.md)
|
||||
- [File management with Git](../../../../topics/git/file_management.md)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
## Limit history range of results
|
||||
|
||||
{{< history >}}
|
||||
|
|
@ -76,8 +71,12 @@ Separate each key-value pair in the query string with an ampersand (`&`), like t
|
|||
|
||||
The full URL to the range of commits looks like this:
|
||||
|
||||
For example:
|
||||
|
||||
```plaintext
|
||||
https://gitlab.com/gitlab-org/gitlab/-/commits/master/CONTRIBUTING.md?ref_type=heads&committed_after=2023-05-15&committed_before=2023-11-22
|
||||
```
|
||||
|
||||
## Related topics
|
||||
|
||||
- [Git blame](git_blame.md)
|
||||
- [Common Git commands](../../../../topics/git/commands.md)
|
||||
- [File management with Git](../../../../topics/git/file_management.md)
|
||||
|
|
|
|||
|
|
@ -1036,6 +1036,7 @@ module API
|
|||
|
||||
def job_token_policies_authorized?(project)
|
||||
return true unless current_user&.from_ci_job_token?
|
||||
return true unless Feature.enabled?(:add_policies_to_ci_job_token, project)
|
||||
return true if skip_job_token_policies?
|
||||
return true if publicly_accessible_feature?(project)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Gitlab
|
||||
module BackgroundMigration
|
||||
class BackfillPackagesDebianProjectComponentFilesProjectId < BackfillDesiredShardingKeyJob
|
||||
operation_name :backfill_packages_debian_project_component_files_project_id
|
||||
feature_category :package_registry
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -35,7 +35,7 @@ module Sidebars
|
|||
return nil_menu_item(:packages_registry) unless context.group.packages_feature_enabled?
|
||||
|
||||
::Sidebars::MenuItem.new(
|
||||
title: _('Package Registry'),
|
||||
title: _('Package registry'),
|
||||
link: group_packages_path(context.group),
|
||||
super_sidebar_parent: ::Sidebars::Groups::SuperSidebarMenus::DeployMenu,
|
||||
active_routes: { controller: 'groups/packages' },
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ module Sidebars
|
|||
end
|
||||
|
||||
::Sidebars::MenuItem.new(
|
||||
title: _('Package Registry'),
|
||||
title: _('Package registry'),
|
||||
link: project_packages_path(context.project),
|
||||
super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::DeployMenu,
|
||||
active_routes: { controller: :packages },
|
||||
|
|
|
|||
|
|
@ -41122,15 +41122,6 @@ msgstr ""
|
|||
msgid "PQL|Thank you for reaching out! Our sales team will get back to you soon."
|
||||
msgstr ""
|
||||
|
||||
msgid "Package Registry"
|
||||
msgstr ""
|
||||
|
||||
msgid "Package Registry: authenticated API requests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Package Registry: unauthenticated API requests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Package already exists"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -41152,12 +41143,21 @@ msgstr ""
|
|||
msgid "Package recipe already exists"
|
||||
msgstr ""
|
||||
|
||||
msgid "Package registry"
|
||||
msgstr ""
|
||||
|
||||
msgid "Package registry rate limits"
|
||||
msgstr ""
|
||||
|
||||
msgid "Package registry types for which metadata is stored, required for License Compliance for CycloneDX files."
|
||||
msgstr ""
|
||||
|
||||
msgid "Package registry: authenticated API requests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Package registry: unauthenticated API requests"
|
||||
msgstr ""
|
||||
|
||||
msgid "Package type"
|
||||
msgstr ""
|
||||
|
||||
|
|
@ -41592,10 +41592,10 @@ msgstr ""
|
|||
msgid "PackageRegistry|Published to %{projectName}, %{date}"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|Published to the %{project} Package Registry %{datetime}"
|
||||
msgid "PackageRegistry|Published to the %{project} Terraform Module Registry %{datetime}"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|Published to the %{project} Terraform Module Registry %{datetime}"
|
||||
msgid "PackageRegistry|Published to the %{project} package registry %{datetime}"
|
||||
msgstr ""
|
||||
|
||||
msgid "PackageRegistry|PyPI"
|
||||
|
|
@ -45821,7 +45821,7 @@ msgstr ""
|
|||
msgid "ProjectSettings|Allow"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectSettings|Allow anyone to pull from Package Registry"
|
||||
msgid "ProjectSettings|Allow anyone to pull from package registry"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectSettings|Allow skipping the merge train"
|
||||
|
|
@ -59019,7 +59019,7 @@ msgstr ""
|
|||
msgid "There are running deployments on the environment. Please retry later."
|
||||
msgstr ""
|
||||
|
||||
msgid "There are several file size limits in place for the Package Registry."
|
||||
msgid "There are several file size limits in place for the package registry."
|
||||
msgstr ""
|
||||
|
||||
msgid "There are several rate limits in place to protect the system."
|
||||
|
|
|
|||
|
|
@ -43,13 +43,22 @@ module QA
|
|||
end
|
||||
|
||||
def wait_for_latest_pipeline_to_have_status(project:, status: nil, wait: 240)
|
||||
raise "'#{status}' is an invalid pipeline status." if AVAILABLE_STATUSES.exclude?(status)
|
||||
wait_for_pipeline_status(
|
||||
project: project,
|
||||
status: status,
|
||||
wait: wait,
|
||||
pipeline_finder: -> { project.latest_pipeline }
|
||||
)
|
||||
end
|
||||
|
||||
Runtime::Logger.info("Waiting for #{project.name}'s latest pipeline to have status #{status}...")
|
||||
Support::Waiter.wait_until(message: "Wait for latest pipeline #{status}", max_duration: wait) do
|
||||
pipeline = project.latest_pipeline
|
||||
pipeline[:status] == status
|
||||
end
|
||||
def wait_for_pipeline_to_have_status_by_id(project:, pipeline_id:, status: nil, wait: 240)
|
||||
wait_for_pipeline_status(
|
||||
project: project,
|
||||
status: status,
|
||||
wait: wait,
|
||||
pipeline_finder: -> { project.pipelines.find { |p| p[:id] == pipeline_id } },
|
||||
pipeline_identifier: pipeline_id
|
||||
)
|
||||
end
|
||||
|
||||
def wait_for_latest_pipeline_to_start(project:, wait: 240)
|
||||
|
|
@ -66,6 +75,23 @@ module QA
|
|||
pipeline[:started_at].present? && pipeline[:finished_at].present?
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def wait_for_pipeline_status(project:, status:, wait:, pipeline_finder:, pipeline_identifier: 'latest')
|
||||
raise "'#{status}' is an invalid pipeline status." if AVAILABLE_STATUSES.exclude?(status)
|
||||
|
||||
pipeline_desc = pipeline_identifier == 'latest' ? 'latest pipeline' : "pipeline #{pipeline_identifier}"
|
||||
Runtime::Logger.info("Waiting for #{project.name}'s #{pipeline_desc} to have status #{status}...")
|
||||
|
||||
Support::Waiter.wait_until(
|
||||
message: "Wait for #{pipeline_desc} to have status #{status}",
|
||||
max_duration: wait
|
||||
) do
|
||||
pipeline = pipeline_finder.call
|
||||
pipeline[:status] == status
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ module QA
|
|||
extend QA::Page::PageConcern
|
||||
|
||||
def go_to_package_registry
|
||||
open_deploy_submenu("Package Registry")
|
||||
open_deploy_submenu("Package registry")
|
||||
end
|
||||
|
||||
def go_to_container_registry
|
||||
|
|
|
|||
|
|
@ -470,6 +470,10 @@ module QA
|
|||
jobs.find { |job| job[:name] == job_name }
|
||||
end
|
||||
|
||||
def has_job?(job_name)
|
||||
!!job_by_name(job_name)
|
||||
end
|
||||
|
||||
def visit_job(job_name)
|
||||
url = job_by_name(job_name)[:web_url]
|
||||
Runtime::Logger.info("Visiting #{Rainbow(self.class.name).black.bg(:white)}'s job #{job_name} at #{url}")
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ ee/spec/frontend/ai/settings/components/duo_experiment_beta_features_form_spec.j
|
|||
ee/spec/frontend/analytics/analytics_dashboards/components/analytics_dashboards_breadcrumbs_spec.js
|
||||
ee/spec/frontend/analytics/analytics_dashboards/components/analytics_data_explorer_spec.js
|
||||
ee/spec/frontend/analytics/analytics_dashboards/components/list/feature_list_item_spec.js
|
||||
ee/spec/frontend/analytics/cycle_analytics/components/value_stream_aggregation_status_spec.js
|
||||
ee/spec/frontend/analytics/cycle_analytics/vsa_settings/components/value_stream_form_content_spec.js
|
||||
ee/spec/frontend/analytics/dashboards/ai_impact/components/metric_table_spec.js
|
||||
ee/spec/frontend/analytics/devops_reports/devops_adoption/components/devops_adoption_app_spec.js
|
||||
|
|
|
|||
|
|
@ -5,5 +5,6 @@ FactoryBot.define do
|
|||
package { association(:terraform_module_package) }
|
||||
project { package.project }
|
||||
fields { { root: { readme: 'README' }, submodules: { 'submodule1' => { readme: 'submodule1 README' } } } }
|
||||
semver { package.version }
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -28,5 +28,11 @@ FactoryBot.define do
|
|||
end
|
||||
# rubocop:enable RSpec/FactoryBot/StrategyInCallback
|
||||
end
|
||||
|
||||
trait :with_metadatum do
|
||||
terraform_module_metadatum do
|
||||
association(:terraform_module_metadatum, package: instance)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -24,6 +24,6 @@ RSpec.describe 'Admin searches application settings', :js, feature_category: :gl
|
|||
visit(ci_cd_admin_application_settings_path)
|
||||
end
|
||||
|
||||
it_behaves_like 'can search settings', 'Variables', 'Package Registry'
|
||||
it_behaves_like 'can search settings', 'Variables', 'Package registry'
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ RSpec.describe 'Group Packages', feature_category: :package_registry do
|
|||
|
||||
it 'sidebar menu is open' do
|
||||
sidebar = find_by_testid('super-sidebar')
|
||||
expect(sidebar).to have_link _('Package Registry')
|
||||
expect(sidebar).to have_link _('Package registry')
|
||||
end
|
||||
|
||||
context 'when there are packages' do
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ RSpec.describe 'Groups > sidebar', :js, feature_category: :groups_and_projects d
|
|||
it 'shows main menu' do
|
||||
within_testid 'super-sidebar' do
|
||||
click_button 'Deploy'
|
||||
expect(page).to have_link(_('Package Registry'))
|
||||
expect(page).to have_link(_('Package registry'))
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -64,5 +64,19 @@ describe('Test reports utils', () => {
|
|||
expect(result).toBe('1h 1m 2s');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when time is greater than 8 hours', () => {
|
||||
it('should return time in hours', () => {
|
||||
const result = formattedTime(28801);
|
||||
expect(result).toBe('8h 1s');
|
||||
});
|
||||
});
|
||||
|
||||
describe('when time is greater than 24 hours', () => {
|
||||
it('should return time in days', () => {
|
||||
const result = formattedTime(86600);
|
||||
expect(result).toBe('1d 3m 20s');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ describe('Package History', () => {
|
|||
${'created-on'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'clock'} | ${'@gitlab-org/package-15 version 1.0.0 was first created'} | ${packageData().createdAt} | ${null}
|
||||
${'first-pipeline-commit'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'commit'} | ${'Created by commit b83d6e39 on branch master'} | ${null} | ${onePipeline.commitPath}
|
||||
${'first-pipeline-pipeline'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pipeline'} | ${'Built by pipeline #1 triggered by Administrator'} | ${onePipeline.createdAt} | ${onePipeline.path}
|
||||
${'published'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'package'} | ${'Published to the baz project Package Registry'} | ${packageData().createdAt} | ${null}
|
||||
${'published'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'package'} | ${'Published to the baz project package registry'} | ${packageData().createdAt} | ${null}
|
||||
${'archived'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'history'} | ${'Package has 1 archived update'} | ${null} | ${null}
|
||||
${'archived'} | ${HISTORY_PIPELINES_LIMIT + 3} | ${'history'} | ${'Package has 2 archived updates'} | ${null} | ${null}
|
||||
${'pipeline-entry'} | ${HISTORY_PIPELINES_LIMIT + 2} | ${'pencil'} | ${'Package updated by commit b83d6e39 on branch master, built by pipeline #3, and published to the registry'} | ${packageData().createdAt} | ${onePipeline.commitPath}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import eventHub, {
|
|||
EVENT_EDIT_WIKI_START,
|
||||
} from '~/pages/shared/wikis/event_hub';
|
||||
import createMockApollo from 'helpers/mock_apollo_helper';
|
||||
import { note, noteableId, queryVariables } from '../mock_data';
|
||||
import { noteableId, queryVariables } from '../mock_data';
|
||||
|
||||
Vue.use(VueApollo);
|
||||
|
||||
|
|
@ -53,6 +53,11 @@ const mockDiscussion = (...children) => {
|
|||
};
|
||||
};
|
||||
|
||||
const apolloCache = {
|
||||
writeQuery: jest.fn(),
|
||||
readQuery: jest.fn(),
|
||||
};
|
||||
|
||||
describe('WikiNotesApp', () => {
|
||||
let wrapper;
|
||||
let fakeApollo;
|
||||
|
|
@ -79,6 +84,14 @@ describe('WikiNotesApp', () => {
|
|||
],
|
||||
]);
|
||||
|
||||
fakeApollo.clients.defaultClient.cache = apolloCache;
|
||||
fakeApollo.queries = {
|
||||
wikiPage: {
|
||||
loading: false,
|
||||
refetch: jest.fn().mockResolvedValue({}),
|
||||
},
|
||||
};
|
||||
|
||||
wrapper = shallowMountExtended(WikiNotesApp, {
|
||||
apolloProvider: fakeApollo,
|
||||
provide: {
|
||||
|
|
@ -91,8 +104,24 @@ describe('WikiNotesApp', () => {
|
|||
await nextTick();
|
||||
};
|
||||
|
||||
let wikiPage = {};
|
||||
beforeEach(async () => {
|
||||
await createWrapper();
|
||||
|
||||
wikiPage = {
|
||||
id: noteableId,
|
||||
discussions: {
|
||||
nodes: [],
|
||||
},
|
||||
};
|
||||
|
||||
// stub apollo's cache read, and add some default data with the wikiPage result method
|
||||
apolloCache.readQuery.mockReturnValue({
|
||||
noteableId,
|
||||
wikiPage,
|
||||
});
|
||||
|
||||
wrapper.vm.$options.apollo.wikiPage.result.call(wrapper.vm, { data: {} });
|
||||
});
|
||||
|
||||
describe('when editing a wiki page', () => {
|
||||
|
|
@ -304,26 +333,31 @@ describe('WikiNotesApp', () => {
|
|||
expect(wrapper.vm.placeholderNote).toMatchObject({});
|
||||
});
|
||||
|
||||
it('shouldupdateDiscussions when "creating-note:success" is called', async () => {
|
||||
it('should call writeQuery with the correct data when "creating-note:success" is called', async () => {
|
||||
const newDiscussion = {
|
||||
id: '2',
|
||||
notes: {
|
||||
nodes: [
|
||||
{
|
||||
...note,
|
||||
id: 2,
|
||||
body: 'New Comment',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const commentForm = wrapper.findComponent(WikiCommentForm);
|
||||
commentForm.vm.$emit('creating-note:success', newDiscussion);
|
||||
await nextTick();
|
||||
|
||||
const discussions = wrapper.findAllComponents(WikiDiscussion);
|
||||
expect(discussions.length).toBe(2);
|
||||
expect(discussions.at(1).props('discussion')).toMatchObject(newDiscussion.notes.nodes);
|
||||
wikiPage.discussions.nodes.push({
|
||||
...newDiscussion,
|
||||
replyId: null,
|
||||
resolvable: false,
|
||||
resolved: false,
|
||||
resolvedAt: null,
|
||||
resolvedBy: null,
|
||||
});
|
||||
|
||||
expect(apolloCache.writeQuery).toHaveBeenCalledWith({
|
||||
query: wikiPageQuery,
|
||||
variables: queryVariables,
|
||||
data: {
|
||||
noteableId: '7',
|
||||
wikiPage,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -169,7 +169,7 @@ describe('search box by type component', () => {
|
|||
expect(wrapper.findComponent(GlLoadingIcon).exists()).toBe(true);
|
||||
});
|
||||
|
||||
describe('regular expression button', () => {
|
||||
describe('regular expression button active', () => {
|
||||
const regexButtonHandlerSpy = jest.fn();
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
|
|
@ -183,10 +183,6 @@ describe('search box by type component', () => {
|
|||
expect(findRegulareExpressionToggle().exists()).toBe(true);
|
||||
});
|
||||
|
||||
it('renders regular expression button state correctly', () => {
|
||||
expect(findRegulareExpressionToggle().classes('!gl-bg-blue-50')).toBe(true);
|
||||
});
|
||||
|
||||
it('triggers correct action when clicked', () => {
|
||||
findRegulareExpressionToggle().vm.$emit('click');
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,59 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Resolvers::Users::RecentlyViewedMergeRequestsResolver, feature_category: :user_profile do
|
||||
include GraphqlHelpers
|
||||
|
||||
specify { expect(described_class).to have_nullable_graphql_type(Types::MergeRequestType) }
|
||||
|
||||
specify { expect(described_class).to require_graphql_authorizations(:read_user) }
|
||||
|
||||
describe '#resolve' do
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:other_user) { create(:user) }
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:membership) { create(:project_member, project: project, user: user) }
|
||||
let_it_be(:recently_viewed_merge_request1) do
|
||||
create(:merge_request, source_project: project, source_branch: 'branch-1', author: user)
|
||||
end
|
||||
|
||||
let_it_be(:recently_viewed_merge_request2) do
|
||||
create(:merge_request, source_project: project, source_branch: 'branch-2', author: user)
|
||||
end
|
||||
|
||||
let_it_be(:unviewed_merge_request) do
|
||||
create(:merge_request, source_project: project, source_branch: 'branch-3', author: user)
|
||||
end
|
||||
|
||||
let_it_be(:finder) { ::Gitlab::Search::RecentMergeRequests.new(user: user) }
|
||||
|
||||
before do
|
||||
finder.log_view(recently_viewed_merge_request1)
|
||||
finder.log_view(recently_viewed_merge_request2)
|
||||
end
|
||||
|
||||
it 'returns recently viewed items for the current user' do
|
||||
resolved_merge_requests = resolve_recent_merge_requests(current_user: user)
|
||||
expect(resolved_merge_requests).to contain_exactly(recently_viewed_merge_request1, recently_viewed_merge_request2)
|
||||
expect(resolved_merge_requests).not_to include(unviewed_merge_request)
|
||||
end
|
||||
|
||||
it 'does not return recently viewed items for another user' do
|
||||
resolved_merge_requests = resolve_recent_merge_requests(current_user: other_user)
|
||||
expect(resolved_merge_requests).not_to include(recently_viewed_merge_request1, recently_viewed_merge_request2)
|
||||
end
|
||||
|
||||
it 'does not leak items you no longer have access to' do
|
||||
# revoke access
|
||||
membership.destroy!
|
||||
|
||||
resolved_merge_requests = resolve_recent_merge_requests(current_user: user)
|
||||
expect(resolved_merge_requests).not_to include(recently_viewed_merge_request1, recently_viewed_merge_request2)
|
||||
end
|
||||
end
|
||||
|
||||
def resolve_recent_merge_requests(current_user:)
|
||||
resolve(described_class, obj: current_user, ctx: { current_user: current_user })
|
||||
end
|
||||
end
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe GitlabSchema.types['PackageBase'], feature_category: :package_registry do
|
||||
specify { expect(described_class.description).to eq('Represents a package in the Package Registry') }
|
||||
specify { expect(described_class.description).to eq('Represents a package in the package registry') }
|
||||
specify { expect(described_class).to require_graphql_authorizations(:read_package) }
|
||||
specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Package) }
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe GitlabSchema.types['Package'], feature_category: :package_registry do
|
||||
specify { expect(described_class.description).to eq('Represents a package with pipelines in the Package Registry') }
|
||||
specify { expect(described_class.description).to eq('Represents a package with pipelines in the package registry') }
|
||||
specify { expect(described_class).to require_graphql_authorizations(:read_package) }
|
||||
specify { expect(described_class).to expose_permissions_using(Types::PermissionTypes::Package) }
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::BackgroundMigration::BackfillPackagesDebianProjectComponentFilesProjectId,
|
||||
feature_category: :package_registry,
|
||||
schema: 20250307100237 do
|
||||
include_examples 'desired sharding key backfill job' do
|
||||
let(:batch_table) { :packages_debian_project_component_files }
|
||||
let(:backfill_column) { :project_id }
|
||||
let(:backfill_via_table) { :packages_debian_project_components }
|
||||
let(:backfill_via_column) { :project_id }
|
||||
let(:backfill_via_foreign_key) { :component_id }
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
require_migration!
|
||||
|
||||
RSpec.describe QueueBackfillPackagesDebianProjectComponentFilesProjectId, feature_category: :package_registry do
|
||||
let!(:batched_migration) { described_class::MIGRATION }
|
||||
|
||||
it 'schedules a new batched migration' do
|
||||
reversible_migration do |migration|
|
||||
migration.before -> {
|
||||
expect(batched_migration).not_to have_scheduled_batched_migration
|
||||
}
|
||||
|
||||
migration.after -> {
|
||||
expect(batched_migration).to have_scheduled_batched_migration(
|
||||
table_name: :packages_debian_project_component_files,
|
||||
column_name: :id,
|
||||
interval: described_class::DELAY_INTERVAL,
|
||||
batch_size: described_class::BATCH_SIZE,
|
||||
sub_batch_size: described_class::SUB_BATCH_SIZE,
|
||||
gitlab_schema: :gitlab_main_cell,
|
||||
job_arguments: [
|
||||
:project_id,
|
||||
:packages_debian_project_components,
|
||||
:project_id,
|
||||
:component_id
|
||||
]
|
||||
)
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -726,36 +726,6 @@ RSpec.describe Note, feature_category: :team_planning do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#last_edited_by' do
|
||||
let(:user) { build(:user) }
|
||||
|
||||
context 'when last_edited_at is nil' do
|
||||
let(:note) { build(:note, last_edited_at: nil, updated_by: user) }
|
||||
|
||||
it 'returns nil' do
|
||||
expect(note.last_edited_by).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context 'when last_edited_at is set' do
|
||||
context 'when updated_by is set' do
|
||||
let(:note) { build(:note, last_edited_at: Time.current, updated_by: user) }
|
||||
|
||||
it 'returns the updated_by user' do
|
||||
expect(note.last_edited_by).to eq(user)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when updated_by is not set' do
|
||||
let(:note) { build(:note, last_edited_at: Time.current, updated_by: nil) }
|
||||
|
||||
it 'returns the ghost user' do
|
||||
expect(note.last_edited_by).to eq(Users::Internal.ghost)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#confidential?' do
|
||||
context 'when note is not confidential' do
|
||||
context 'when include_noteable is set to true' do
|
||||
|
|
|
|||
|
|
@ -3,15 +3,20 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Packages::TerraformModule::Metadatum, type: :model, feature_category: :package_registry do
|
||||
it { is_expected.to be_a(SemanticVersionable) }
|
||||
|
||||
describe 'relationships' do
|
||||
it { is_expected.to belong_to(:package) }
|
||||
it { is_expected.to belong_to(:project) }
|
||||
end
|
||||
|
||||
describe 'default values' do
|
||||
it { is_expected.to have_attributes(fields: {}) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
it { is_expected.to validate_presence_of(:package) }
|
||||
it { is_expected.to validate_presence_of(:project) }
|
||||
it { is_expected.to validate_presence_of(:fields) }
|
||||
|
||||
describe '#metadata' do
|
||||
let_it_be(:metadata_fields) do
|
||||
|
|
@ -25,7 +30,7 @@ RSpec.describe Packages::TerraformModule::Metadatum, type: :model, feature_categ
|
|||
}
|
||||
end
|
||||
|
||||
it 'validates #content against the terraform_module_metadata schema', :aggregate_failures do
|
||||
it 'validates #fields against the terraform_module_metadata schema', :aggregate_failures do
|
||||
is_expected.to allow_value(root: { readme: 'README' }).for(:fields)
|
||||
is_expected.to allow_value(
|
||||
root: metadata_fields,
|
||||
|
|
@ -36,7 +41,7 @@ RSpec.describe Packages::TerraformModule::Metadatum, type: :model, feature_categ
|
|||
submodules: { submodule: metadata_fields },
|
||||
examples: { example: metadata_fields.except(:dependencies, :resources) }
|
||||
).for(:fields)
|
||||
is_expected.not_to allow_value({}).for(:fields)
|
||||
is_expected.to allow_value({}).for(:fields)
|
||||
is_expected.not_to allow_value(root: { readme: 1 }).for(:fields)
|
||||
is_expected.not_to allow_value(root: { readme: 'README' }, submodules: [{ readme: 'README' }]).for(:fields)
|
||||
is_expected.not_to allow_value(root: { readme: 'README' * described_class::MAX_FIELDS_SIZE }).for(:fields)
|
||||
|
|
@ -63,10 +68,39 @@ RSpec.describe Packages::TerraformModule::Metadatum, type: :model, feature_categ
|
|||
end
|
||||
end
|
||||
|
||||
describe 'semver validation' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
where(:version, :valid, :semver_major, :semver_minor, :semver_patch, :semver_prerelease) do
|
||||
'1' | false | nil | nil | nil | nil
|
||||
'1.2' | false | nil | nil | nil | nil
|
||||
'1.2.3' | true | 1 | 2 | 3 | nil
|
||||
'1.2.3-beta' | true | 1 | 2 | 3 | 'beta'
|
||||
'1.2.3.beta' | false | nil | nil | nil | nil
|
||||
end
|
||||
|
||||
with_them do
|
||||
let(:metadatum) { build(:terraform_module_metadatum, semver: version) }
|
||||
|
||||
it 'validates the semver' do
|
||||
if valid
|
||||
expect(metadatum).to be_valid.and have_attributes(
|
||||
semver_major: semver_major,
|
||||
semver_minor: semver_minor,
|
||||
semver_patch: semver_patch,
|
||||
semver_prerelease: semver_prerelease
|
||||
)
|
||||
else
|
||||
expect(metadatum).not_to be_valid
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the parent project is destroyed' do
|
||||
let_it_be(:metadatum) { create(:terraform_module_metadatum) }
|
||||
|
||||
it 'desroys the metadatum' do
|
||||
it 'destroys the metadatum' do
|
||||
expect { metadatum.project.destroy! }.to change { described_class.count }.by(-1)
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ RSpec.describe Packages::TerraformModule::Package, type: :model, feature_categor
|
|||
end
|
||||
end
|
||||
|
||||
describe 'nested attributes' do
|
||||
it { is_expected.to accept_nested_attributes_for(:terraform_module_metadatum) }
|
||||
end
|
||||
|
||||
describe 'validations' do
|
||||
describe '#name' do
|
||||
subject { build_stubbed(:terraform_module_package) }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,150 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'Creating a pipeline that includes CI components', feature_category: :pipeline_composition do
|
||||
let_it_be_with_refind(:project) { create(:project, :repository) }
|
||||
let_it_be_with_reload(:user) { project.first_owner }
|
||||
|
||||
let(:components_project) do
|
||||
create(:project, :repository, creator: user, namespace: user.namespace)
|
||||
end
|
||||
|
||||
let(:component_path) do
|
||||
"#{Gitlab.config.gitlab.host}/#{components_project.full_path}/my-component@v0.1"
|
||||
end
|
||||
|
||||
let(:template) do
|
||||
<<~YAML
|
||||
spec:
|
||||
inputs:
|
||||
stage:
|
||||
suffix:
|
||||
default: my-job
|
||||
---
|
||||
test-$[[ inputs.suffix ]]:
|
||||
stage: $[[ inputs.stage ]]
|
||||
script: run tests
|
||||
YAML
|
||||
end
|
||||
|
||||
let(:sha) do
|
||||
components_project.repository.create_file(
|
||||
user,
|
||||
'templates/my-component/template.yml',
|
||||
template,
|
||||
message: 'Add my first CI component',
|
||||
branch_name: 'master'
|
||||
)
|
||||
end
|
||||
|
||||
let(:config) do
|
||||
<<~YAML
|
||||
include:
|
||||
- component: #{component_path}
|
||||
inputs:
|
||||
stage: my-stage
|
||||
|
||||
stages:
|
||||
- my-stage
|
||||
|
||||
test-1:
|
||||
stage: my-stage
|
||||
script: run test-1
|
||||
YAML
|
||||
end
|
||||
|
||||
before do
|
||||
stub_ci_pipeline_yaml_file(config)
|
||||
end
|
||||
|
||||
context 'when there is no version with specified tag' do
|
||||
before do
|
||||
components_project.repository.add_tag(user, 'v0.01', sha)
|
||||
end
|
||||
|
||||
it 'does not create a pipeline' do
|
||||
response = execute_service
|
||||
|
||||
pipeline = response.payload
|
||||
|
||||
expect(pipeline).to be_persisted
|
||||
expect(pipeline.error_messages[0].content)
|
||||
.to include "my-component@v0.1' - content not found"
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is a proper revision available' do
|
||||
before do
|
||||
components_project.repository.add_tag(user, 'v0.1', sha)
|
||||
end
|
||||
|
||||
context 'when component is valid' do
|
||||
it 'creates a pipeline using a pipeline component' do
|
||||
response = execute_service
|
||||
|
||||
pipeline = response.payload
|
||||
|
||||
expect(pipeline).to be_persisted
|
||||
expect(pipeline.error_messages).to be_empty
|
||||
expect(pipeline.statuses.count).to eq 2
|
||||
expect(pipeline.statuses.map(&:name)).to match_array %w[test-1 test-my-job]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when interpolation is invalid' do
|
||||
let(:template) do
|
||||
<<~YAML
|
||||
spec:
|
||||
inputs:
|
||||
stage:
|
||||
---
|
||||
test:
|
||||
stage: $[[ inputs.stage ]]
|
||||
script: rspec --suite $[[ inputs.suite ]]
|
||||
YAML
|
||||
end
|
||||
|
||||
it 'does not create a pipeline' do
|
||||
response = execute_service
|
||||
|
||||
pipeline = response.payload
|
||||
|
||||
expect(pipeline).to be_persisted
|
||||
expect(pipeline.error_messages[0].content)
|
||||
.to include 'unknown interpolation key: `suite`'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is a syntax error in the template' do
|
||||
let(:template) do
|
||||
<<~YAML
|
||||
spec:
|
||||
inputs:
|
||||
stage:
|
||||
---
|
||||
:test
|
||||
stage: $[[ inputs.stage ]]
|
||||
YAML
|
||||
end
|
||||
|
||||
it 'does not create a pipeline' do
|
||||
response = execute_service
|
||||
|
||||
pipeline = response.payload
|
||||
|
||||
expect(pipeline).to be_persisted
|
||||
expect(pipeline.error_messages[0].content)
|
||||
.to include 'mapping values are not allowed'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def execute_service
|
||||
::Ci::CreatePipelineService
|
||||
.new(project, user, { ref: project.default_branch })
|
||||
.execute(:push, save_on_errors: true) do |pipeline|
|
||||
yield(pipeline) if block_given?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1736,142 +1736,6 @@ RSpec.describe Ci::CreatePipelineService, :clean_gitlab_redis_cache, feature_cat
|
|||
end
|
||||
end
|
||||
|
||||
describe 'pipeline components' do
|
||||
let(:components_project) do
|
||||
create(:project, :repository, creator: user, namespace: user.namespace)
|
||||
end
|
||||
|
||||
let(:component_path) do
|
||||
"#{Gitlab.config.gitlab.host}/#{components_project.full_path}/my-component@v0.1"
|
||||
end
|
||||
|
||||
let(:template) do
|
||||
<<~YAML
|
||||
spec:
|
||||
inputs:
|
||||
stage:
|
||||
suffix:
|
||||
default: my-job
|
||||
---
|
||||
test-$[[ inputs.suffix ]]:
|
||||
stage: $[[ inputs.stage ]]
|
||||
script: run tests
|
||||
YAML
|
||||
end
|
||||
|
||||
let(:sha) do
|
||||
components_project.repository.create_file(
|
||||
user,
|
||||
'templates/my-component/template.yml',
|
||||
template,
|
||||
message: 'Add my first CI component',
|
||||
branch_name: 'master'
|
||||
)
|
||||
end
|
||||
|
||||
let(:config) do
|
||||
<<~YAML
|
||||
include:
|
||||
- component: #{component_path}
|
||||
inputs:
|
||||
stage: my-stage
|
||||
|
||||
stages:
|
||||
- my-stage
|
||||
|
||||
test-1:
|
||||
stage: my-stage
|
||||
script: run test-1
|
||||
YAML
|
||||
end
|
||||
|
||||
before do
|
||||
stub_ci_pipeline_yaml_file(config)
|
||||
end
|
||||
|
||||
context 'when there is no version with specified tag' do
|
||||
before do
|
||||
components_project.repository.add_tag(user, 'v0.01', sha)
|
||||
end
|
||||
|
||||
it 'does not create a pipeline' do
|
||||
response = execute_service(save_on_errors: true)
|
||||
|
||||
pipeline = response.payload
|
||||
|
||||
expect(pipeline).to be_persisted
|
||||
expect(pipeline.error_messages[0].content)
|
||||
.to include "my-component@v0.1' - content not found"
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is a proper revision available' do
|
||||
before do
|
||||
components_project.repository.add_tag(user, 'v0.1', sha)
|
||||
end
|
||||
|
||||
context 'when component is valid' do
|
||||
it 'creates a pipeline using a pipeline component' do
|
||||
response = execute_service(save_on_errors: true)
|
||||
|
||||
pipeline = response.payload
|
||||
|
||||
expect(pipeline).to be_persisted
|
||||
expect(pipeline.error_messages).to be_empty
|
||||
expect(pipeline.statuses.count).to eq 2
|
||||
expect(pipeline.statuses.map(&:name)).to match_array %w[test-1 test-my-job]
|
||||
end
|
||||
end
|
||||
|
||||
context 'when interpolation is invalid' do
|
||||
let(:template) do
|
||||
<<~YAML
|
||||
spec:
|
||||
inputs:
|
||||
stage:
|
||||
---
|
||||
test:
|
||||
stage: $[[ inputs.stage ]]
|
||||
script: rspec --suite $[[ inputs.suite ]]
|
||||
YAML
|
||||
end
|
||||
|
||||
it 'does not create a pipeline' do
|
||||
response = execute_service(save_on_errors: true)
|
||||
|
||||
pipeline = response.payload
|
||||
|
||||
expect(pipeline).to be_persisted
|
||||
expect(pipeline.error_messages[0].content)
|
||||
.to include 'unknown interpolation key: `suite`'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when there is a syntax error in the template' do
|
||||
let(:template) do
|
||||
<<~YAML
|
||||
spec:
|
||||
inputs:
|
||||
stage:
|
||||
---
|
||||
:test
|
||||
stage: $[[ inputs.stage ]]
|
||||
YAML
|
||||
end
|
||||
|
||||
it 'does not create a pipeline' do
|
||||
response = execute_service(save_on_errors: true)
|
||||
|
||||
pipeline = response.payload
|
||||
|
||||
expect(pipeline).to be_persisted
|
||||
expect(pipeline.error_messages[0].content)
|
||||
.to include 'mapping values are not allowed'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# TODO: Remove this test section when include:with is removed as part of https://gitlab.com/gitlab-org/gitlab/-/issues/408369
|
||||
describe 'pipeline components using include:with instead of include:inputs' do
|
||||
let(:components_project) do
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ RSpec.describe Packages::TerraformModule::CreatePackageService, feature_category
|
|||
let_it_be_with_reload(:namespace) { create(:group) }
|
||||
let_it_be_with_reload(:project) { create(:project, namespace: namespace) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
let_it_be(:sha256) { '440e5e148a25331bbd7991575f7d54933c0ebf6cc735a18ee5066ac1381bb590' }
|
||||
let_it_be_with_reload(:package_settings) { create(:namespace_package_setting, namespace: namespace) }
|
||||
|
||||
let(:sha256) { '440e5e148a25331bbd7991575f7d54933c0ebf6cc735a18ee5066ac1381bb590' }
|
||||
let(:overrides) { {} }
|
||||
|
||||
let(:params) do
|
||||
|
|
@ -24,11 +24,12 @@ RSpec.describe Packages::TerraformModule::CreatePackageService, feature_category
|
|||
subject { described_class.new(project, user, params).execute }
|
||||
|
||||
describe '#execute' do
|
||||
shared_examples 'creating a package' do
|
||||
it 'creates a package' do
|
||||
shared_examples 'creating a package and its metadatum' do
|
||||
it 'creates a package and its metadatum' do
|
||||
expect(::Packages::TerraformModule::ProcessPackageFileWorker).to receive(:perform_async).once
|
||||
|
||||
expect { subject }.to change { ::Packages::TerraformModule::Package.count }.by(1)
|
||||
.and change { ::Packages::TerraformModule::Metadatum.count }.by(1)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -49,7 +50,7 @@ RSpec.describe Packages::TerraformModule::CreatePackageService, feature_category
|
|||
context 'when regex matches' do
|
||||
let(:regex) { ".*#{existing_package.name.last(3)}.*" }
|
||||
|
||||
it_behaves_like 'creating a package'
|
||||
it_behaves_like 'creating a package and its metadatum'
|
||||
end
|
||||
|
||||
context 'when regex does not match' do
|
||||
|
|
@ -73,18 +74,19 @@ RSpec.describe Packages::TerraformModule::CreatePackageService, feature_category
|
|||
context 'when regex does not match' do
|
||||
let(:regex) { '.*not-a-match.*' }
|
||||
|
||||
it_behaves_like 'creating a package'
|
||||
it_behaves_like 'creating a package and its metadatum'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when valid package' do
|
||||
it_behaves_like 'creating a package'
|
||||
it_behaves_like 'creating a package and its metadatum'
|
||||
end
|
||||
|
||||
context 'when package already exists elsewhere' do
|
||||
let(:project2) { create(:project, namespace: namespace) }
|
||||
let_it_be(:project2) { create(:project, namespace: namespace) }
|
||||
let!(:existing_package) do
|
||||
create(:terraform_module_package, project: project2, name: 'foo/bar', version: '1.0.0')
|
||||
create(:terraform_module_package, project: project2, name: 'foo/bar', version: '1.0.0',
|
||||
without_package_files: true)
|
||||
end
|
||||
|
||||
context 'when duplicates not allowed' do
|
||||
|
|
@ -101,7 +103,7 @@ RSpec.describe Packages::TerraformModule::CreatePackageService, feature_category
|
|||
package_settings.update_column(:terraform_module_duplicates_allowed, true)
|
||||
end
|
||||
|
||||
it_behaves_like 'creating a package'
|
||||
it_behaves_like 'creating a package and its metadatum'
|
||||
it_behaves_like 'with duplicate regex exception, prevent creation of matching package'
|
||||
end
|
||||
|
||||
|
|
@ -118,7 +120,7 @@ RSpec.describe Packages::TerraformModule::CreatePackageService, feature_category
|
|||
package_settings.update_column(:terraform_module_duplicates_allowed, true)
|
||||
end
|
||||
|
||||
it_behaves_like 'creating a package'
|
||||
it_behaves_like 'creating a package and its metadatum'
|
||||
end
|
||||
|
||||
context 'when duplicates allowed in an ancestor with exception' do
|
||||
|
|
@ -138,12 +140,15 @@ RSpec.describe Packages::TerraformModule::CreatePackageService, feature_category
|
|||
existing_package.pending_destruction!
|
||||
end
|
||||
|
||||
it_behaves_like 'creating a package'
|
||||
it_behaves_like 'creating a package and its metadatum'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when version already exists' do
|
||||
let!(:existing_version) { create(:terraform_module_package, project: project, name: 'foo/bar', version: '1.0.1') }
|
||||
let_it_be_with_reload(:existing_version) do
|
||||
create(:terraform_module_package, project: project, name: 'foo/bar', version: '1.0.1',
|
||||
without_package_files: true)
|
||||
end
|
||||
|
||||
it 'returns error' do
|
||||
is_expected.to be_error.and have_attributes(
|
||||
|
|
@ -157,7 +162,7 @@ RSpec.describe Packages::TerraformModule::CreatePackageService, feature_category
|
|||
existing_version.pending_destruction!
|
||||
end
|
||||
|
||||
it_behaves_like 'creating a package'
|
||||
it_behaves_like 'creating a package and its metadatum'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue