Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
b19efd7274
commit
017841e3c0
49 changed files with 1028 additions and 171 deletions
|
@ -517,8 +517,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
|
|||
- ee/spec/policies/merge_request_policy_spec.rb
|
||||
- ee/spec/policies/project_policy_spec.rb
|
||||
- ee/spec/policies/vulnerabilities/issue_link_policy_spec.rb
|
||||
- ee/spec/presenters/approval_rule_presenter_spec.rb
|
||||
- ee/spec/presenters/ci/pipeline_presenter_spec.rb
|
||||
- ee/spec/requests/api/analytics/code_review_analytics_spec.rb
|
||||
- ee/spec/requests/api/audit_events_spec.rb
|
||||
- ee/spec/requests/api/commits_spec.rb
|
||||
|
|
|
@ -91,7 +91,7 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
availablePanels() {
|
||||
decoratedPanels() {
|
||||
const PANEL_TITLES = experiment(NEW_REPO_EXPERIMENT, {
|
||||
use: () => ({
|
||||
blank: s__('ProjectsNew|Create blank project'),
|
||||
|
@ -103,20 +103,22 @@ export default {
|
|||
}),
|
||||
});
|
||||
|
||||
const updatedPanels = PANELS.map(({ key, title, ...el }) => ({
|
||||
return PANELS.map(({ key, title, ...el }) => ({
|
||||
...el,
|
||||
title: PANEL_TITLES[key] !== undefined ? PANEL_TITLES[key] : title,
|
||||
}));
|
||||
},
|
||||
|
||||
availablePanels() {
|
||||
if (this.isCiCdAvailable) {
|
||||
return updatedPanels;
|
||||
return this.decoratedPanels;
|
||||
}
|
||||
|
||||
return updatedPanels.filter((p) => p.name !== CI_CD_PANEL);
|
||||
return this.decoratedPanels.filter((p) => p.name !== CI_CD_PANEL);
|
||||
},
|
||||
|
||||
activePanel() {
|
||||
return PANELS.find((p) => p.name === this.activeTab);
|
||||
return this.decoratedPanels.find((p) => p.name === this.activeTab);
|
||||
},
|
||||
|
||||
breadcrumbs() {
|
||||
|
|
|
@ -2,12 +2,20 @@
|
|||
|
||||
module Resolvers
|
||||
class PackageDetailsResolver < BaseResolver
|
||||
type ::Types::Packages::PackageType, null: true
|
||||
type ::Types::Packages::PackageDetailsType, null: true
|
||||
|
||||
argument :id, ::Types::GlobalIDType[::Packages::Package],
|
||||
required: true,
|
||||
description: 'The global ID of the package.'
|
||||
|
||||
def ready?(**args)
|
||||
context[self.class] ||= { executions: 0 }
|
||||
context[self.class][:executions] += 1
|
||||
raise GraphQL::ExecutionError, "Package details can be requested only for one package at a time" if context[self.class][:executions] > 1
|
||||
|
||||
super
|
||||
end
|
||||
|
||||
def resolve(id:)
|
||||
# TODO: remove this line when the compatibility layer is removed
|
||||
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/257883
|
||||
|
|
|
@ -36,6 +36,34 @@ module Types
|
|||
jobs_for_pipeline(pl, indexed.keys, include_needs).each do |stage_id, statuses|
|
||||
key = indexed[stage_id]
|
||||
groups = ::Ci::Group.fabricate(project, key.stage, statuses)
|
||||
|
||||
if Feature.enabled?(:ci_no_empty_groups, project)
|
||||
groups.each do |group|
|
||||
rejected = group.jobs.reject { |job| Ability.allowed?(current_user, :read_commit_status, job) }
|
||||
group.jobs.select! { |job| Ability.allowed?(current_user, :read_commit_status, job) }
|
||||
next unless group.jobs.empty?
|
||||
|
||||
exc = StandardError.new('Empty Ci::Group')
|
||||
traces = rejected.map do |job|
|
||||
trace = []
|
||||
policy = Ability.policy_for(current_user, job)
|
||||
policy.debug(:read_commit_status, trace)
|
||||
trace
|
||||
end
|
||||
extra = {
|
||||
current_user_id: current_user&.id,
|
||||
project_id: project.id,
|
||||
pipeline_id: pl.id,
|
||||
stage_id: stage_id,
|
||||
group_name: group.name,
|
||||
rejected_job_ids: rejected.map(&:id),
|
||||
rejected_traces: traces
|
||||
}
|
||||
Gitlab::ErrorTracking.track_exception(exc, extra)
|
||||
end
|
||||
groups.reject! { |group| group.jobs.empty? }
|
||||
end
|
||||
|
||||
loader.call(key, groups)
|
||||
end
|
||||
end
|
||||
|
|
22
app/graphql/types/packages/conan/file_metadatum_type.rb
Normal file
22
app/graphql/types/packages/conan/file_metadatum_type.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Types
|
||||
module Packages
|
||||
module Conan
|
||||
class FileMetadatumType < BaseObject
|
||||
graphql_name 'ConanFileMetadata'
|
||||
description 'Conan file metadata'
|
||||
|
||||
implements Types::Packages::FileMetadataType
|
||||
|
||||
authorize :read_package
|
||||
|
||||
field :id, ::Types::GlobalIDType[::Packages::Conan::FileMetadatum], null: false, description: 'ID of the metadatum.'
|
||||
field :recipe_revision, GraphQL::STRING_TYPE, null: false, description: 'Revision of the Conan recipe.'
|
||||
field :package_revision, GraphQL::STRING_TYPE, null: true, description: 'Revision of the package.'
|
||||
field :conan_package_reference, GraphQL::STRING_TYPE, null: true, description: 'Reference of the Conan package.'
|
||||
field :conan_file_type, ::Types::Packages::Conan::MetadatumFileTypeEnum, null: false, description: 'Type of the Conan file.'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
16
app/graphql/types/packages/conan/metadatum_file_type_enum.rb
Normal file
16
app/graphql/types/packages/conan/metadatum_file_type_enum.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Types
|
||||
module Packages
|
||||
module Conan
|
||||
class MetadatumFileTypeEnum < BaseEnum
|
||||
graphql_name 'ConanMetadatumFileTypeEnum'
|
||||
description 'Conan file types'
|
||||
|
||||
::Packages::Conan::FileMetadatum.conan_file_types.keys.each do |file|
|
||||
value file.upcase, value: file, description: "A #{file.humanize(capitalize: false)} type."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
22
app/graphql/types/packages/conan/metadatum_type.rb
Normal file
22
app/graphql/types/packages/conan/metadatum_type.rb
Normal file
|
@ -0,0 +1,22 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Types
|
||||
module Packages
|
||||
module Conan
|
||||
class MetadatumType < BaseObject
|
||||
graphql_name 'ConanMetadata'
|
||||
description 'Conan metadata'
|
||||
|
||||
authorize :read_package
|
||||
|
||||
field :id, ::Types::GlobalIDType[::Packages::Conan::Metadatum], null: false, description: 'ID of the metadatum.'
|
||||
field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
|
||||
field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
|
||||
field :package_username, GraphQL::STRING_TYPE, null: false, description: 'Username of the Conan package.'
|
||||
field :package_channel, GraphQL::STRING_TYPE, null: false, description: 'Channel of the Conan package.'
|
||||
field :recipe, GraphQL::STRING_TYPE, null: false, description: 'Recipe of the Conan package.'
|
||||
field :recipe_path, GraphQL::STRING_TYPE, null: false, description: 'Recipe path of the Conan package.'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
27
app/graphql/types/packages/file_metadata_type.rb
Normal file
27
app/graphql/types/packages/file_metadata_type.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Types
|
||||
module Packages
|
||||
module FileMetadataType
|
||||
include ::Types::BaseInterface
|
||||
graphql_name 'PackageFileMetadata'
|
||||
description 'Represents metadata associated with a Package file'
|
||||
|
||||
field :created_at, ::Types::TimeType, null: false, description: 'Date of creation.'
|
||||
field :updated_at, ::Types::TimeType, null: false, description: 'Date of most recent update.'
|
||||
|
||||
def self.resolve_type(object, context)
|
||||
case object
|
||||
when ::Packages::Conan::FileMetadatum
|
||||
::Types::Packages::Conan::FileMetadatumType
|
||||
else
|
||||
# NOTE: This method must be kept in sync with `PackageFileType#file_metadata`,
|
||||
# which must never produce data that this discriminator cannot handle.
|
||||
raise 'Unsupported file metadata type'
|
||||
end
|
||||
end
|
||||
|
||||
orphan_types Types::Packages::Conan::FileMetadatumType
|
||||
end
|
||||
end
|
||||
end
|
|
@ -6,12 +6,14 @@ module Types
|
|||
graphql_name 'PackageMetadata'
|
||||
description 'Represents metadata associated with a Package'
|
||||
|
||||
possible_types ::Types::Packages::Composer::MetadatumType
|
||||
possible_types ::Types::Packages::Composer::MetadatumType, ::Types::Packages::Conan::MetadatumType
|
||||
|
||||
def self.resolve_type(object, context)
|
||||
case object
|
||||
when ::Packages::Composer::Metadatum
|
||||
::Types::Packages::Composer::MetadatumType
|
||||
when ::Packages::Conan::Metadatum
|
||||
::Types::Packages::Conan::MetadatumType
|
||||
else
|
||||
# NOTE: This method must be kept in sync with `PackageWithoutVersionsType#metadata`,
|
||||
# which must never produce data that this discriminator cannot handle.
|
||||
|
|
20
app/graphql/types/packages/package_details_type.rb
Normal file
20
app/graphql/types/packages/package_details_type.rb
Normal file
|
@ -0,0 +1,20 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Types
|
||||
module Packages
|
||||
class PackageDetailsType < PackageType
|
||||
graphql_name 'PackageDetailsType'
|
||||
description 'Represents a package details in the Package Registry. Note that this type is in beta and susceptible to changes'
|
||||
authorize :read_package
|
||||
|
||||
field :versions, ::Types::Packages::PackageType.connection_type, null: true,
|
||||
description: 'The other versions of the package.'
|
||||
|
||||
field :package_files, Types::Packages::PackageFileType.connection_type, null: true, description: 'Package files.'
|
||||
|
||||
def versions
|
||||
object.versions
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
36
app/graphql/types/packages/package_file_type.rb
Normal file
36
app/graphql/types/packages/package_file_type.rb
Normal file
|
@ -0,0 +1,36 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Types
|
||||
module Packages
|
||||
class PackageFileType < BaseObject
|
||||
graphql_name 'PackageFile'
|
||||
description 'Represents a package file'
|
||||
authorize :read_package
|
||||
|
||||
field :id, ::Types::GlobalIDType[::Packages::PackageFile], null: false, description: 'ID of the file.'
|
||||
field :created_at, Types::TimeType, null: false, description: 'The created date.'
|
||||
field :updated_at, Types::TimeType, null: false, description: 'The updated date.'
|
||||
field :size, GraphQL::STRING_TYPE, null: false, description: 'Size of the package file.'
|
||||
field :file_name, GraphQL::STRING_TYPE, null: false, description: 'Name of the package file.'
|
||||
field :download_path, GraphQL::STRING_TYPE, null: false, description: 'Download path of the package file.'
|
||||
field :file_md5, GraphQL::STRING_TYPE, null: true, description: 'Md5 of the package file.'
|
||||
field :file_sha1, GraphQL::STRING_TYPE, null: true, description: 'Sha1 of the package file.'
|
||||
field :file_sha256, GraphQL::STRING_TYPE, null: true, description: 'Sha256 of the package file.'
|
||||
field :file_metadata, Types::Packages::FileMetadataType, null: true,
|
||||
description: 'File metadata.'
|
||||
|
||||
# NOTE: This method must be kept in sync with the union
|
||||
# type: `Types::Packages::FileMetadataType`.
|
||||
#
|
||||
# `Types::Packages::FileMetadataType.resolve_type(metadata, ctx)` must never raise.
|
||||
def file_metadata
|
||||
case object.package.package_type
|
||||
when 'conan'
|
||||
object.conan_file_metadatum
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -2,13 +2,52 @@
|
|||
|
||||
module Types
|
||||
module Packages
|
||||
class PackageType < PackageWithoutVersionsType
|
||||
class PackageType < ::Types::BaseObject
|
||||
graphql_name 'Package'
|
||||
description 'Represents a package in the Package Registry'
|
||||
description 'Represents a package in the Package Registry. Note that this type is in beta and susceptible to changes'
|
||||
|
||||
authorize :read_package
|
||||
|
||||
field :versions, ::Types::Packages::PackageWithoutVersionsType.connection_type, null: true,
|
||||
description: 'The other versions of the package.'
|
||||
field :id, ::Types::GlobalIDType[::Packages::Package], null: false,
|
||||
description: 'ID of the package.'
|
||||
|
||||
field :name, GraphQL::STRING_TYPE, null: false, description: 'Name of the package.'
|
||||
field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
|
||||
field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
|
||||
field :version, GraphQL::STRING_TYPE, null: true, description: 'Version string.'
|
||||
field :package_type, Types::Packages::PackageTypeEnum, null: false, description: 'Package type.'
|
||||
field :tags, Types::Packages::PackageTagType.connection_type, null: true, description: 'Package tags.'
|
||||
field :project, Types::ProjectType, null: false, description: 'Project where the package is stored.'
|
||||
field :pipelines, Types::Ci::PipelineType.connection_type, null: true,
|
||||
description: 'Pipelines that built the package.'
|
||||
field :metadata, Types::Packages::MetadataType, null: true,
|
||||
description: 'Package metadata.'
|
||||
field :versions, ::Types::Packages::PackageType.connection_type, null: true,
|
||||
description: 'The other versions of the package.',
|
||||
deprecated: { reason: 'This field is now only returned in the PackageDetailsType', milestone: '13.11' }
|
||||
|
||||
def project
|
||||
Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
|
||||
end
|
||||
|
||||
def versions
|
||||
[]
|
||||
end
|
||||
|
||||
# NOTE: This method must be kept in sync with the union
|
||||
# type: `Types::Packages::MetadataType`.
|
||||
#
|
||||
# `Types::Packages::MetadataType.resolve_type(metadata, ctx)` must never raise.
|
||||
def metadata
|
||||
case object.package_type
|
||||
when 'composer'
|
||||
object.composer_metadatum
|
||||
when 'conan'
|
||||
object.conan_metadatum
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Types
|
||||
module Packages
|
||||
class PackageWithoutVersionsType < ::Types::BaseObject
|
||||
graphql_name 'PackageWithoutVersions'
|
||||
description 'Represents a version of a package in the Package Registry'
|
||||
|
||||
authorize :read_package
|
||||
|
||||
field :id, ::Types::GlobalIDType[::Packages::Package], null: false,
|
||||
description: 'ID of the package.'
|
||||
|
||||
field :name, GraphQL::STRING_TYPE, null: false, description: 'Name of the package.'
|
||||
field :created_at, Types::TimeType, null: false, description: 'Date of creation.'
|
||||
field :updated_at, Types::TimeType, null: false, description: 'Date of most recent update.'
|
||||
field :version, GraphQL::STRING_TYPE, null: true, description: 'Version string.'
|
||||
field :package_type, Types::Packages::PackageTypeEnum, null: false, description: 'Package type.'
|
||||
field :tags, Types::Packages::PackageTagType.connection_type, null: true, description: 'Package tags.'
|
||||
field :project, Types::ProjectType, null: false, description: 'Project where the package is stored.'
|
||||
field :pipelines, Types::Ci::PipelineType.connection_type, null: true,
|
||||
description: 'Pipelines that built the package.'
|
||||
field :metadata, Types::Packages::MetadataType, null: true,
|
||||
description: 'Package metadata.'
|
||||
|
||||
def project
|
||||
Gitlab::Graphql::Loaders::BatchModelLoader.new(Project, object.project_id).find
|
||||
end
|
||||
|
||||
# NOTE: This method must be kept in sync with the union
|
||||
# type: `Types::Packages::MetadataType`.
|
||||
#
|
||||
# `Types::Packages::MetadataType.resolve_type(metadata, ctx)` must never raise.
|
||||
def metadata
|
||||
case object.package_type
|
||||
when 'composer'
|
||||
object.composer_metadatum
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
8
app/policies/packages/conan/file_metadatum_policy.rb
Normal file
8
app/policies/packages/conan/file_metadatum_policy.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
module Packages
|
||||
module Conan
|
||||
class FileMetadatumPolicy < BasePolicy
|
||||
delegate { @subject.package_file.package }
|
||||
end
|
||||
end
|
||||
end
|
8
app/policies/packages/conan/metadatum_policy.rb
Normal file
8
app/policies/packages/conan/metadatum_policy.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
module Packages
|
||||
module Conan
|
||||
class MetadatumPolicy < BasePolicy
|
||||
delegate { @subject.package }
|
||||
end
|
||||
end
|
||||
end
|
6
app/policies/packages/package_file_policy.rb
Normal file
6
app/policies/packages/package_file_policy.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
module Packages
|
||||
class PackageFilePolicy < BasePolicy
|
||||
delegate { @subject.package }
|
||||
end
|
||||
end
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Return email confirmation time from email entity
|
||||
merge_request: 58957
|
||||
author:
|
||||
type: changed
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Add Conan GraphQL type to package
|
||||
merge_request: 57719
|
||||
author:
|
||||
type: added
|
8
config/feature_flags/development/ci_no_empty_groups.yml
Normal file
8
config/feature_flags/development/ci_no_empty_groups.yml
Normal file
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: ci_no_empty_groups
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58789
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/327139
|
||||
milestone: '13.11'
|
||||
type: development
|
||||
group: group::verify
|
||||
default_enabled: false
|
|
@ -215,7 +215,7 @@ Returns [`Namespace`](#namespace).
|
|||
|
||||
Find a package.
|
||||
|
||||
Returns [`Package`](#package).
|
||||
Returns [`PackageDetailsType`](#packagedetailstype).
|
||||
|
||||
#### Arguments
|
||||
|
||||
|
@ -1548,6 +1548,34 @@ Composer metadata.
|
|||
| `composerJson` | [`PackageComposerJsonType!`](#packagecomposerjsontype) | Data of the Composer JSON file. |
|
||||
| `targetSha` | [`String!`](#string) | Target SHA of the package. |
|
||||
|
||||
### `ConanFileMetadata`
|
||||
|
||||
Conan file metadata.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `conanFileType` | [`ConanMetadatumFileTypeEnum!`](#conanmetadatumfiletypeenum) | Type of the Conan file. |
|
||||
| `conanPackageReference` | [`String`](#string) | Reference of the Conan package. |
|
||||
| `createdAt` | [`Time!`](#time) | Date of creation. |
|
||||
| `id` | [`PackagesConanFileMetadatumID!`](#packagesconanfilemetadatumid) | ID of the metadatum. |
|
||||
| `packageRevision` | [`String`](#string) | Revision of the package. |
|
||||
| `recipeRevision` | [`String!`](#string) | Revision of the Conan recipe. |
|
||||
| `updatedAt` | [`Time!`](#time) | Date of most recent update. |
|
||||
|
||||
### `ConanMetadata`
|
||||
|
||||
Conan metadata.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `createdAt` | [`Time!`](#time) | Date of creation. |
|
||||
| `id` | [`PackagesConanMetadatumID!`](#packagesconanmetadatumid) | ID of the metadatum. |
|
||||
| `packageChannel` | [`String!`](#string) | Channel of the Conan package. |
|
||||
| `packageUsername` | [`String!`](#string) | Username of the Conan package. |
|
||||
| `recipe` | [`String!`](#string) | Recipe of the Conan package. |
|
||||
| `recipePath` | [`String!`](#string) | Recipe path of the Conan package. |
|
||||
| `updatedAt` | [`Time!`](#time) | Date of most recent update. |
|
||||
|
||||
### `ConfigureSastPayload`
|
||||
|
||||
Autogenerated return type of ConfigureSast.
|
||||
|
@ -4501,7 +4529,7 @@ Autogenerated return type of OncallScheduleUpdate.
|
|||
|
||||
### `Package`
|
||||
|
||||
Represents a package in the Package Registry.
|
||||
Represents a package in the Package Registry. Note that this type is in beta and susceptible to changes.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
|
@ -4515,7 +4543,7 @@ Represents a package in the Package Registry.
|
|||
| `tags` | [`PackageTagConnection`](#packagetagconnection) | Package tags. |
|
||||
| `updatedAt` | [`Time!`](#time) | Date of most recent update. |
|
||||
| `version` | [`String`](#string) | Version string. |
|
||||
| `versions` | [`PackageWithoutVersionsConnection`](#packagewithoutversionsconnection) | The other versions of the package. |
|
||||
| `versions` **{warning-solid}** | [`PackageConnection`](#packageconnection) | **Deprecated** in 13.11. This field is now only returned in the PackageDetailsType. |
|
||||
|
||||
### `PackageComposerJsonType`
|
||||
|
||||
|
@ -4538,6 +4566,25 @@ The connection type for Package.
|
|||
| `nodes` | [`[Package]`](#package) | A list of nodes. |
|
||||
| `pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
|
||||
|
||||
### `PackageDetailsType`
|
||||
|
||||
Represents a package details in the Package Registry. Note that this type is in beta and susceptible to changes.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `createdAt` | [`Time!`](#time) | Date of creation. |
|
||||
| `id` | [`PackagesPackageID!`](#packagespackageid) | ID of the package. |
|
||||
| `metadata` | [`PackageMetadata`](#packagemetadata) | Package metadata. |
|
||||
| `name` | [`String!`](#string) | Name of the package. |
|
||||
| `packageFiles` | [`PackageFileConnection`](#packagefileconnection) | Package files. |
|
||||
| `packageType` | [`PackageTypeEnum!`](#packagetypeenum) | Package type. |
|
||||
| `pipelines` | [`PipelineConnection`](#pipelineconnection) | Pipelines that built the package. |
|
||||
| `project` | [`Project!`](#project) | Project where the package is stored. |
|
||||
| `tags` | [`PackageTagConnection`](#packagetagconnection) | Package tags. |
|
||||
| `updatedAt` | [`Time!`](#time) | Date of most recent update. |
|
||||
| `version` | [`String`](#string) | Version string. |
|
||||
| `versions` | [`PackageConnection`](#packageconnection) | The other versions of the package. |
|
||||
|
||||
### `PackageEdge`
|
||||
|
||||
An edge in a connection.
|
||||
|
@ -4547,6 +4594,42 @@ An edge in a connection.
|
|||
| `cursor` | [`String!`](#string) | A cursor for use in pagination. |
|
||||
| `node` | [`Package`](#package) | The item at the end of the edge. |
|
||||
|
||||
### `PackageFile`
|
||||
|
||||
Represents a package file.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `createdAt` | [`Time!`](#time) | The created date. |
|
||||
| `downloadPath` | [`String!`](#string) | Download path of the package file. |
|
||||
| `fileMd5` | [`String`](#string) | Md5 of the package file. |
|
||||
| `fileMetadata` | [`PackageFileMetadata`](#packagefilemetadata) | File metadata. |
|
||||
| `fileName` | [`String!`](#string) | Name of the package file. |
|
||||
| `fileSha1` | [`String`](#string) | Sha1 of the package file. |
|
||||
| `fileSha256` | [`String`](#string) | Sha256 of the package file. |
|
||||
| `id` | [`PackagesPackageFileID!`](#packagespackagefileid) | ID of the file. |
|
||||
| `size` | [`String!`](#string) | Size of the package file. |
|
||||
| `updatedAt` | [`Time!`](#time) | The updated date. |
|
||||
|
||||
### `PackageFileConnection`
|
||||
|
||||
The connection type for PackageFile.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `edges` | [`[PackageFileEdge]`](#packagefileedge) | A list of edges. |
|
||||
| `nodes` | [`[PackageFile]`](#packagefile) | A list of nodes. |
|
||||
| `pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
|
||||
|
||||
### `PackageFileEdge`
|
||||
|
||||
An edge in a connection.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `cursor` | [`String!`](#string) | A cursor for use in pagination. |
|
||||
| `node` | [`PackageFile`](#packagefile) | The item at the end of the edge. |
|
||||
|
||||
### `PackageFileRegistry`
|
||||
|
||||
Represents the Geo sync and verification state of a package file.
|
||||
|
@ -4620,42 +4703,6 @@ An edge in a connection.
|
|||
| `cursor` | [`String!`](#string) | A cursor for use in pagination. |
|
||||
| `node` | [`PackageTag`](#packagetag) | The item at the end of the edge. |
|
||||
|
||||
### `PackageWithoutVersions`
|
||||
|
||||
Represents a version of a package in the Package Registry.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `createdAt` | [`Time!`](#time) | Date of creation. |
|
||||
| `id` | [`PackagesPackageID!`](#packagespackageid) | ID of the package. |
|
||||
| `metadata` | [`PackageMetadata`](#packagemetadata) | Package metadata. |
|
||||
| `name` | [`String!`](#string) | Name of the package. |
|
||||
| `packageType` | [`PackageTypeEnum!`](#packagetypeenum) | Package type. |
|
||||
| `pipelines` | [`PipelineConnection`](#pipelineconnection) | Pipelines that built the package. |
|
||||
| `project` | [`Project!`](#project) | Project where the package is stored. |
|
||||
| `tags` | [`PackageTagConnection`](#packagetagconnection) | Package tags. |
|
||||
| `updatedAt` | [`Time!`](#time) | Date of most recent update. |
|
||||
| `version` | [`String`](#string) | Version string. |
|
||||
|
||||
### `PackageWithoutVersionsConnection`
|
||||
|
||||
The connection type for PackageWithoutVersions.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `edges` | [`[PackageWithoutVersionsEdge]`](#packagewithoutversionsedge) | A list of edges. |
|
||||
| `nodes` | [`[PackageWithoutVersions]`](#packagewithoutversions) | A list of nodes. |
|
||||
| `pageInfo` | [`PageInfo!`](#pageinfo) | Information to aid in pagination. |
|
||||
|
||||
### `PackageWithoutVersionsEdge`
|
||||
|
||||
An edge in a connection.
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `cursor` | [`String!`](#string) | A cursor for use in pagination. |
|
||||
| `node` | [`PackageWithoutVersions`](#packagewithoutversions) | The item at the end of the edge. |
|
||||
|
||||
### `PageInfo`
|
||||
|
||||
Information about pagination in a connection.
|
||||
|
@ -7536,6 +7583,15 @@ Mode of a commit action.
|
|||
| `BASE64` | Base64 encoding. |
|
||||
| `TEXT` | Text encoding. |
|
||||
|
||||
### `ConanMetadatumFileTypeEnum`
|
||||
|
||||
Conan file types.
|
||||
|
||||
| Value | Description |
|
||||
| ----- | ----------- |
|
||||
| `PACKAGE_FILE` | A package file type. |
|
||||
| `RECIPE_FILE` | A recipe file type. |
|
||||
|
||||
### `ContainerExpirationPolicyCadenceEnum`
|
||||
|
||||
| Value | Description |
|
||||
|
@ -8794,6 +8850,24 @@ A `NoteableID` is a global ID. It is encoded as a string.
|
|||
|
||||
An example `NoteableID` is: `"gid://gitlab/Noteable/1"`.
|
||||
|
||||
### `PackagesConanFileMetadatumID`
|
||||
|
||||
A `PackagesConanFileMetadatumID` is a global ID. It is encoded as a string.
|
||||
|
||||
An example `PackagesConanFileMetadatumID` is: `"gid://gitlab/Packages::Conan::FileMetadatum/1"`.
|
||||
|
||||
### `PackagesConanMetadatumID`
|
||||
|
||||
A `PackagesConanMetadatumID` is a global ID. It is encoded as a string.
|
||||
|
||||
An example `PackagesConanMetadatumID` is: `"gid://gitlab/Packages::Conan::Metadatum/1"`.
|
||||
|
||||
### `PackagesPackageFileID`
|
||||
|
||||
A `PackagesPackageFileID` is a global ID. It is encoded as a string.
|
||||
|
||||
An example `PackagesPackageFileID` is: `"gid://gitlab/Packages::PackageFile/1"`.
|
||||
|
||||
### `PackagesPackageID`
|
||||
|
||||
A `PackagesPackageID` is a global ID. It is encoded as a string.
|
||||
|
@ -8902,6 +8976,7 @@ Represents metadata associated with a Package.
|
|||
One of:
|
||||
|
||||
- [`ComposerMetadata`](#composermetadata)
|
||||
- [`ConanMetadata`](#conanmetadata)
|
||||
|
||||
#### `VulnerabilityDetail`
|
||||
|
||||
|
@ -9054,6 +9129,19 @@ Implementations:
|
|||
| `discussions` | [`DiscussionConnection!`](#discussionconnection) | All discussions on this noteable. |
|
||||
| `notes` | [`NoteConnection!`](#noteconnection) | All notes on this noteable. |
|
||||
|
||||
#### `PackageFileMetadata`
|
||||
|
||||
Represents metadata associated with a Package file.
|
||||
|
||||
Implementations:
|
||||
|
||||
- [`ConanFileMetadata`](#conanfilemetadata)
|
||||
|
||||
| Field | Type | Description |
|
||||
| ----- | ---- | ----------- |
|
||||
| `createdAt` | [`Time!`](#time) | Date of creation. |
|
||||
| `updatedAt` | [`Time!`](#time) | Date of most recent update. |
|
||||
|
||||
#### `ResolvableInterface`
|
||||
|
||||
Implementations:
|
||||
|
|
149
doc/api/packages/rubygems.md
Normal file
149
doc/api/packages/rubygems.md
Normal file
|
@ -0,0 +1,149 @@
|
|||
---
|
||||
stage: Package
|
||||
group: Package
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Ruby gems API
|
||||
|
||||
This is the API documentation for [Ruby gems](../../user/packages/rubygems_registry/index.md).
|
||||
|
||||
WARNING:
|
||||
This API is used by the [Ruby gems and Bundler package manager clients](https://maven.apache.org/)
|
||||
and is generally not meant for manual consumption. This API is under development and is not ready
|
||||
for production use due to limited functionality.
|
||||
|
||||
For instructions on how to upload and install gems from the GitLab
|
||||
package registry, see the [Ruby gems registry documentation](../../user/packages/rubygems_registry/index.md).
|
||||
|
||||
NOTE:
|
||||
These endpoints do not adhere to the standard API authentication methods.
|
||||
See the [Ruby gems registry documentation](../../user/packages/rubygems_registry/index.md)
|
||||
for details on which headers and token types are supported.
|
||||
|
||||
## Enable the Ruby gems API
|
||||
|
||||
The Ruby gems API for GitLab is behind a feature flag that is disabled by default. GitLab
|
||||
administrators with access to the GitLab Rails console can enable this API for your instance.
|
||||
|
||||
To enable it:
|
||||
|
||||
```ruby
|
||||
Feature.enable(:rubygem_packages)
|
||||
```
|
||||
|
||||
To disable it:
|
||||
|
||||
```ruby
|
||||
Feature.disable(:rubygem_packages)
|
||||
```
|
||||
|
||||
To enable or disable it for specific projects:
|
||||
|
||||
```ruby
|
||||
Feature.enable(:rubygem_packages, Project.find(1))
|
||||
Feature.disable(:rubygem_packages, Project.find(2))
|
||||
```
|
||||
|
||||
## Download a gem file
|
||||
|
||||
> Introduced in GitLab 13.10.
|
||||
|
||||
Download a gem:
|
||||
|
||||
```plaintext
|
||||
GET projects/:id/packages/rubygems/gems/:file_name
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| ------------ | ------ | -------- | ----------- |
|
||||
| `id` | string | yes | The ID or full path of the project. |
|
||||
| `file_name` | string | yes | The name of the `.gem` file. |
|
||||
|
||||
```shell
|
||||
curl --header "Authorization:<personal_access_token>" "https://gitlab.example.com/api/v4/projects/1/packages/rubygems/gems/my_gem-1.0.0.gem"
|
||||
```
|
||||
|
||||
Write the output to file:
|
||||
|
||||
```shell
|
||||
curl --header "Authorization:<personal_access_token>" "https://gitlab.example.com/api/v4/projects/1/packages/rubygems/gems/my_gem-1.0.0.gem" >> my_gem-1.0.0.gem
|
||||
```
|
||||
|
||||
This writes the downloaded file to `my_gem-1.0.0.gem` in the current directory.
|
||||
|
||||
## Fetch a list of dependencies
|
||||
|
||||
> Introduced in GitLab 13.10.
|
||||
|
||||
Fetch a list of dependencies for a list of gems:
|
||||
|
||||
```plaintext
|
||||
GET projects/:id/packages/rubygems/api/v1/dependencies
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ------ | -------- | ----------- |
|
||||
| `id` | string | yes | The ID or full path of the project. |
|
||||
| `gems` | string | no | Comma-separated list of gems to fetch dependencies for. |
|
||||
|
||||
```shell
|
||||
curl --header "Authorization:<personal_access_token>" "https://gitlab.example.com/api/v4/projects/1/packages/rubygems/api/v1/dependencies?gems=my_gem,foo"
|
||||
```
|
||||
|
||||
This endpoint returns a marshalled array of hashes for all versions of the requested gems. Since the
|
||||
response is marshalled, you can store it in a file. If Ruby is installed, you can use the following
|
||||
Ruby command to read the response. For this to work, you must
|
||||
[set your credentials in `~/.gem/credentials`](../../user/packages/rubygems_registry/index.md#authenticate-with-a-personal-access-token-or-deploy-token):
|
||||
|
||||
```shell
|
||||
$ ruby -ropen-uri -rpp -e \
|
||||
'pp Marshal.load(open("https://gitlab.example.com/api/v4/projects/1/packages/rubygems/api/v1/dependencies?gems=my_gem,rails,foo"))'
|
||||
|
||||
[{:name=>"my_gem", :number=>"0.0.1", :platform=>"ruby", :dependencies=>[]},
|
||||
{:name=>"my_gem",
|
||||
:number=>"0.0.3",
|
||||
:platform=>"ruby",
|
||||
:dependencies=>
|
||||
[["dependency_1", "~> 1.2.3"],
|
||||
["dependency_2", "= 3.0.0"],
|
||||
["dependency_3", ">= 1.0.0"],
|
||||
["dependency_4", ">= 0"]]},
|
||||
{:name=>"my_gem",
|
||||
:number=>"0.0.2",
|
||||
:platform=>"ruby",
|
||||
:dependencies=>
|
||||
[["dependency_1", "~> 1.2.3"],
|
||||
["dependency_2", "= 3.0.0"],
|
||||
["dependency_3", ">= 1.0.0"],
|
||||
["dependency_4", ">= 0"]]},
|
||||
{:name=>"foo",
|
||||
:number=>"0.0.2",
|
||||
:platform=>"ruby",
|
||||
:dependencies=>
|
||||
["dependency_2", "= 3.0.0"],
|
||||
["dependency_4", ">= 0"]]}]
|
||||
```
|
||||
|
||||
This writes the downloaded file to `mypkg-1.0-SNAPSHOT.jar` in the current directory.
|
||||
|
||||
## Upload a gem
|
||||
|
||||
> Introduced in GitLab 13.11.
|
||||
|
||||
Upload a gem:
|
||||
|
||||
```plaintext
|
||||
POST projects/:id/packages/rubygems/api/v1/gems
|
||||
```
|
||||
|
||||
| Attribute | Type | Required | Description |
|
||||
| --------- | ------ | -------- | ----------- |
|
||||
| `id` | string | yes | The ID or full path of the project. |
|
||||
|
||||
```shell
|
||||
curl --request POST \
|
||||
--upload-file path/to/my_gem_file.gem \
|
||||
--header "Authorization:<personal_access_token>" \
|
||||
"https://gitlab.example.com/api/v4/projects/1/packages/rubygems/api/v1/gems"
|
||||
```
|
|
@ -397,6 +397,18 @@ these as the changelog entries. You can enrich entries with additional data,
|
|||
such as a link to the merge request or details about the commit author. You can
|
||||
[customize the format of a changelog](#customize-the-changelog-output) section with a template.
|
||||
|
||||
Trailers can be manually added while editing a commit message. To include a commit
|
||||
using the default trailer of `Changelog` and categorize it as a feature, the
|
||||
trailer could be added to a commit message like so:
|
||||
|
||||
```plaintext
|
||||
<Commit message subject>
|
||||
|
||||
<Commit message description>
|
||||
|
||||
Changelog: feature
|
||||
```
|
||||
|
||||
### Reverted commits
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55537) in GitLab 13.10.
|
||||
|
|
|
@ -1213,11 +1213,13 @@ GET /user/emails
|
|||
[
|
||||
{
|
||||
"id": 1,
|
||||
"email": "email@example.com"
|
||||
"email": "email@example.com",
|
||||
"confirmed_at" : "2021-03-26T19:07:56.248Z"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"email": "email2@example.com"
|
||||
"email": "email2@example.com",
|
||||
"confirmed_at" : null
|
||||
}
|
||||
]
|
||||
```
|
||||
|
@ -1257,7 +1259,8 @@ Parameters:
|
|||
```json
|
||||
{
|
||||
"id": 1,
|
||||
"email": "email@example.com"
|
||||
"email": "email@example.com",
|
||||
"confirmed_at" : "2021-03-26T19:07:56.248Z"
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -1276,7 +1279,8 @@ Parameters:
|
|||
```json
|
||||
{
|
||||
"id": 4,
|
||||
"email": "email@example.com"
|
||||
"email": "email@example.com",
|
||||
"confirmed_at" : "2021-03-26T19:07:56.248Z"
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ graph TD
|
|||
Running? -->|No| Excluded[Control / No Tracking]
|
||||
Cached? -->|No| Excluded?
|
||||
Cached? -->|Yes| Cached[Cached Value]
|
||||
Excluded? -->|Yes / Cached| Excluded
|
||||
Excluded? -->|Yes| Excluded
|
||||
Excluded? -->|No| Segmented?
|
||||
Segmented? -->|Yes / Cached| VariantA
|
||||
Segmented? -->|No| Included?[Experiment Group?]
|
||||
|
@ -92,7 +92,7 @@ end
|
|||
```
|
||||
|
||||
When this code executes, the experiment is run, a variant is assigned, and (if within a
|
||||
controller or view) a `window.gon.experiment.pillColor` object will be available in the
|
||||
controller or view) a `window.gon.experiment.pill_color` object will be available in the
|
||||
client layer, with details like:
|
||||
|
||||
- The assigned variant.
|
||||
|
|
|
@ -13,6 +13,7 @@ generated by their application. By surfacing alerts and incidents where the code
|
|||
being developed, efficiency and awareness can be increased. Check out the following sections for more information:
|
||||
|
||||
- [Integrate your monitoring tools](integrations.md).
|
||||
- Receive [notifications](paging.md) for triggered alerts.
|
||||
- Manage [on-call schedules](oncall_schedules.md) and receive [notifications](paging.md) for
|
||||
triggered alerts.
|
||||
- Triage [Alerts](alerts.md) and [Incidents](incidents.md).
|
||||
- Inform stakeholders with [Status Page](status_page.md).
|
||||
|
|
|
@ -37,7 +37,7 @@ create [rotations](#rotations) for your schedule.
|
|||
|
||||
![Schedule Empty Grid](img/oncall_schedule_empty_grid_v13_10.png)
|
||||
|
||||
### Update a schedule
|
||||
### Edit a schedule
|
||||
|
||||
Follow these steps to update a schedule:
|
||||
|
||||
|
@ -46,6 +46,9 @@ Follow these steps to update a schedule:
|
|||
1. In the **Edit schedule** form, edit the information you wish to update.
|
||||
1. Click the **Edit schedule** button to save your changes.
|
||||
|
||||
If you change the schedule's time zone, GitLab automatically updates the rotation's restricted time
|
||||
interval (if one is set) to the corresponding times in the new time zone.
|
||||
|
||||
### Delete a schedule
|
||||
|
||||
Follow these steps to delete a schedule:
|
||||
|
@ -70,8 +73,8 @@ Follow these steps to create a rotation:
|
|||
- **Starts on:** The date and time the rotation begins.
|
||||
- **Enable end date:** With the toggle set to on, you can select the date and time your rotation
|
||||
ends.
|
||||
- **Restrict to time intervals:** With the toggle set to on, you can restrict your rotation to
|
||||
the time period you select.
|
||||
- **Restrict to time intervals:** With the toggle set to on, you can restrict your rotation to the
|
||||
time period you select.
|
||||
|
||||
### Edit a rotation
|
||||
|
||||
|
|
|
@ -295,3 +295,10 @@ Never commit the `auth.json` file to your repository. To install packages from a
|
|||
consider using the [`composer config`](https://getcomposer.org/doc/articles/handling-private-packages.md#satis) tool with your personal access token
|
||||
stored in a [GitLab CI/CD variable](../../../ci/variables/README.md) or in
|
||||
[HashiCorp Vault](../../../ci/secrets/index.md).
|
||||
|
||||
## Supported CLI commands
|
||||
|
||||
The GitLab Composer repository supports the following Composer CLI commands:
|
||||
|
||||
- `composer install`: Install Composer dependencies.
|
||||
- `composer update`: Install the latest version of Composer dependencies.
|
||||
|
|
|
@ -24,6 +24,7 @@ The Package Registry supports the following formats:
|
|||
<tr><td><a href="https://docs.gitlab.com/ee/user/packages/nuget_repository/index.html">NuGet</a></td><td>12.8+</td></tr>
|
||||
<tr><td><a href="https://docs.gitlab.com/ee/user/packages/pypi_repository/index.html">PyPI</a></td><td>12.10+</td></tr>
|
||||
<tr><td><a href="https://docs.gitlab.com/ee/user/packages/generic_packages/index.html">Generic packages</a></td><td>13.5+</td></tr>
|
||||
<tr><td><a href="https://docs.gitlab.com/ee/user/packages/rubygems_registry/index.html">RubyGems</a></td><td>13.10+</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -49,7 +50,6 @@ guides you through the process.
|
|||
| P2 | [#36895](https://gitlab.com/gitlab-org/gitlab/-/issues/36895) |
|
||||
| Puppet | [#36897](https://gitlab.com/gitlab-org/gitlab/-/issues/36897) |
|
||||
| RPM | [#5932](https://gitlab.com/gitlab-org/gitlab/-/issues/5932) |
|
||||
| RubyGems | [#803](https://gitlab.com/gitlab-org/gitlab/-/issues/803) |
|
||||
| SBT | [#36898](https://gitlab.com/gitlab-org/gitlab/-/issues/36898) |
|
||||
| Terraform | [Draft: Merge Request](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/18834) |
|
||||
| Vagrant | [#36899](https://gitlab.com/gitlab-org/gitlab/-/issues/36899) |
|
||||
|
|
|
@ -871,3 +871,11 @@ package:
|
|||
- 'mvn help:system'
|
||||
- 'mvn package'
|
||||
```
|
||||
|
||||
## Supported CLI commands
|
||||
|
||||
The GitLab Maven repository supports the following Maven CLI commands:
|
||||
|
||||
- `mvn deploy`: Publish your package to the Package Registry.
|
||||
- `mvn install`: Install packages specified in your Maven project.
|
||||
- `mvn dependency:get`: Install a specific package.
|
||||
|
|
|
@ -515,4 +515,19 @@ This is usually a permissions issue with either:
|
|||
- The remote bucket if [object storage](../../../administration/packages/#using-object-storage)
|
||||
is used.
|
||||
|
||||
In the latter case, ensure the bucket exists and the GitLab has write access to it.
|
||||
In the latter case, ensure the bucket exists and GitLab has write access to it.
|
||||
|
||||
## Supported CLI commands
|
||||
|
||||
The GitLab npm repository supports the following commands for the npm CLI (`npm`) and yarn CLI
|
||||
(`yarn`):
|
||||
|
||||
- `npm install`: Install npm packages.
|
||||
- `npm publish`: Publish an npm package to the registry.
|
||||
- `npm dist-tag add`: Add a dist-tag to an npm package.
|
||||
- `npm dist-tag ls`: List dist-tags for a package.
|
||||
- `npm dist-tag rm`: Delete a dist-tag.
|
||||
- `npm ci`: Install npm packages directly from your `package-lock.json` file.
|
||||
- `npm view`: Show package metadata.
|
||||
- `yarn add`: Install an npm package.
|
||||
- `yarn update`: Update your dependencies.
|
||||
|
|
|
@ -393,3 +393,13 @@ dotnet add package <package_id> \
|
|||
|
||||
- `<package_id>` is the package ID.
|
||||
- `<package_version>` is the package version. Optional.
|
||||
|
||||
## Supported CLI commands
|
||||
|
||||
The GitLab NuGet repository supports the following commands for the NuGet CLI (`nuget`) and the .NET
|
||||
CLI (`dotnet`):
|
||||
|
||||
- `nuget push`: Upload a package to the registry.
|
||||
- `dotnet nuget push`: Upload a package to the registry.
|
||||
- `nuget install`: Install a package from the registry.
|
||||
- `dotnet add`: Install a package from the registry.
|
||||
|
|
|
@ -359,3 +359,10 @@ characters are removed.
|
|||
|
||||
A `pip install` request for `my.package` looks for packages that match any of
|
||||
the three characters, such as `my-package`, `my_package`, and `my....package`.
|
||||
|
||||
## Supported CLI commands
|
||||
|
||||
The GitLab PyPI repository supports the following CLI commands:
|
||||
|
||||
- `twine upload`: Upload a package to the registry.
|
||||
- `pip install`: Install a PyPI package from the registry.
|
||||
|
|
137
doc/user/packages/rubygems_registry/index.md
Normal file
137
doc/user/packages/rubygems_registry/index.md
Normal file
|
@ -0,0 +1,137 @@
|
|||
---
|
||||
stage: Package
|
||||
group: Package
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments
|
||||
---
|
||||
|
||||
# Ruby gems in the Package Registry
|
||||
|
||||
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/803) in [GitLab Free](https://about.gitlab.com/pricing/) 13.10.
|
||||
|
||||
WARNING:
|
||||
The Ruby gems registry for GitLab is under development and isn't ready for production use due to
|
||||
limited functionality.
|
||||
|
||||
You can publish Ruby gems in your project's Package Registry, then install the packages when you
|
||||
need to use them as a dependency. Although you can push gems to the registry, you cannot install
|
||||
them from the registry. However, you can download `gem` files directly from the Package Registry's
|
||||
UI, or by using the [API](../../../api/packages/rubygems.md#download-a-gem-file).
|
||||
|
||||
For documentation of the specific API endpoints that the Ruby gems and Bundler package manager
|
||||
clients use, see the [Ruby gems API documentation](../../../api/packages/rubygems.md).
|
||||
|
||||
## Enable the Ruby gems registry
|
||||
|
||||
The Ruby gems registry for GitLab is behind a feature flag that is disabled by default. GitLab
|
||||
administrators with access to the GitLab Rails console can enable this registry for your instance.
|
||||
|
||||
To enable it:
|
||||
|
||||
```ruby
|
||||
Feature.enable(:rubygem_packages)
|
||||
```
|
||||
|
||||
To disable it:
|
||||
|
||||
```ruby
|
||||
Feature.disable(:rubygem_packages)
|
||||
```
|
||||
|
||||
To enable or disable it for specific projects:
|
||||
|
||||
```ruby
|
||||
Feature.enable(:rubygem_packages, Project.find(1))
|
||||
Feature.disable(:rubygem_packages, Project.find(2))
|
||||
```
|
||||
|
||||
## Create a Ruby Gem
|
||||
|
||||
If you need help creating a Ruby gem, see the [RubyGems documentation](https://guides.rubygems.org/make-your-own-gem/).
|
||||
|
||||
## Authenticate to the Package Registry
|
||||
|
||||
Before you can push to the Package Registry, you must authenticate.
|
||||
|
||||
To do this, you can use:
|
||||
|
||||
- A [personal access token](../../../user/profile/personal_access_tokens.md)
|
||||
with the scope set to `api`.
|
||||
- A [deploy token](../../project/deploy_tokens/index.md) with the scope set to
|
||||
`read_package_registry`, `write_package_registry`, or both.
|
||||
- A [CI job token](#authenticate-with-a-ci-job-token).
|
||||
|
||||
### Authenticate with a personal access token or deploy token
|
||||
|
||||
To authenticate with a personal access token, create or edit the `~/.gem/credentials` file and add:
|
||||
|
||||
```ini
|
||||
---
|
||||
https://gitlab.example.com/api/v4/projects/<project_id>/packages/rubygems: '<your token>'
|
||||
```
|
||||
|
||||
- `<your token>` must be the token value of either your personal access token or deploy token.
|
||||
- Your project ID is on your project's home page.
|
||||
|
||||
### Authenticate with a CI job token
|
||||
|
||||
To work with RubyGems commands within [GitLab CI/CD](../../../ci/README.md),
|
||||
you can use `CI_JOB_TOKEN` instead of a personal access token or deploy token.
|
||||
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
image: ruby:latest
|
||||
|
||||
run:
|
||||
script:
|
||||
```
|
||||
|
||||
You can also use `CI_JOB_TOKEN` in a `~/.gem/credentials` file that you check in to
|
||||
GitLab:
|
||||
|
||||
```ini
|
||||
---
|
||||
https://gitlab.example.com/api/v4/projects/${env.CI_PROJECT_ID}/packages/rubygems: '${env.CI_JOB_TOKEN}'
|
||||
```
|
||||
|
||||
## Push a Ruby gem
|
||||
|
||||
Prerequisites:
|
||||
|
||||
- You must [authenticate to the Package Registry](#authenticate-to-the-package-registry).
|
||||
- The maximum allowed gem size is 3 GB.
|
||||
|
||||
To push your gem, run a command like this one:
|
||||
|
||||
```shell
|
||||
gem push my_gem-0.0.1.gem --host <host>
|
||||
```
|
||||
|
||||
Note that `<host>` is the URL you used when setting up authentication. For example:
|
||||
|
||||
```shell
|
||||
gem push my_gem-0.0.1.gem --host https://gitlab.example.com/api/v4/projects/1/packages/rubygems
|
||||
```
|
||||
|
||||
This message indicates that the gem uploaded successfully:
|
||||
|
||||
```plaintext
|
||||
Pushing gem to https://gitlab.example.com/api/v4/projects/1/packages/rubygems...
|
||||
{"message":"201 Created"}
|
||||
```
|
||||
|
||||
To view the published gem, go to your project's **Packages & Registries** page. Gems pushed to
|
||||
GitLab aren't displayed in your project's Packages UI immediately. It can take up to 10 minutes to
|
||||
process a gem.
|
||||
|
||||
### Pushing gems with the same name or version
|
||||
|
||||
You can push a gem if a package of the same name and version already exists.
|
||||
Both are visible and accessible in the UI. However, only the most recently
|
||||
pushed gem is used for installs.
|
||||
|
||||
## Install a Ruby gem
|
||||
|
||||
The Ruby gems registry for GitLab is under development, and isn't ready for production use. You
|
||||
cannot install Gems from the registry. However, you can download `.gem` files directly from the UI
|
||||
or by using the [API](../../../api/packages/rubygems.md#download-a-gem-file).
|
|
@ -3,7 +3,7 @@
|
|||
module API
|
||||
module Entities
|
||||
class Email < Grape::Entity
|
||||
expose :id, :email
|
||||
expose :id, :email, :confirmed_at
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
"@gitlab/favicon-overlay": "2.0.0",
|
||||
"@gitlab/svgs": "1.188.0",
|
||||
"@gitlab/tributejs": "1.0.0",
|
||||
"@gitlab/ui": "29.2.1",
|
||||
"@gitlab/ui": "29.3.0",
|
||||
"@gitlab/visual-review-tools": "1.6.1",
|
||||
"@rails/actioncable": "^6.0.3-4",
|
||||
"@rails/ujs": "^6.0.3-4",
|
||||
|
|
37
spec/fixtures/api/schemas/graphql/packages/package_conan_metadata.json
vendored
Normal file
37
spec/fixtures/api/schemas/graphql/packages/package_conan_metadata.json
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"id",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"packageUsername",
|
||||
"packageChannel",
|
||||
"recipe",
|
||||
"recipePath",
|
||||
"packageName"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string"
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"updated_at": {
|
||||
"type": "string"
|
||||
},
|
||||
"package_username": {
|
||||
"type": "string"
|
||||
},
|
||||
"package_channel": {
|
||||
"type": "string"
|
||||
},
|
||||
"recipe": {
|
||||
"type": "string"
|
||||
},
|
||||
"recipe_path": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,8 +2,17 @@
|
|||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": [
|
||||
"id", "name", "createdAt", "updatedAt", "version", "packageType",
|
||||
"project", "tags", "pipelines", "versions", "metadata"
|
||||
"id",
|
||||
"name",
|
||||
"createdAt",
|
||||
"updatedAt",
|
||||
"version",
|
||||
"packageType",
|
||||
"project",
|
||||
"tags",
|
||||
"pipelines",
|
||||
"versions",
|
||||
"metadata"
|
||||
],
|
||||
"properties": {
|
||||
"id": {
|
||||
|
@ -23,7 +32,18 @@
|
|||
},
|
||||
"packageType": {
|
||||
"type": ["string"],
|
||||
"enum": ["MAVEN", "NPM", "CONAN", "NUGET", "PYPI", "COMPOSER", "GENERIC", "GOLANG", "RUBYGEMS", "DEBIAN"]
|
||||
"enum": [
|
||||
"MAVEN",
|
||||
"NPM",
|
||||
"CONAN",
|
||||
"NUGET",
|
||||
"PYPI",
|
||||
"COMPOSER",
|
||||
"GENERIC",
|
||||
"GOLANG",
|
||||
"RUBYGEMS",
|
||||
"DEBIAN"
|
||||
]
|
||||
},
|
||||
"tags": {
|
||||
"type": "object",
|
||||
|
@ -59,8 +79,18 @@
|
|||
"metadata": {
|
||||
"anyOf": [
|
||||
{ "$ref": "./package_composer_metadata.json" },
|
||||
{ "$ref": "./package_conan_metadata.json" },
|
||||
{ "type": "null" }
|
||||
]
|
||||
},
|
||||
"packageFiles": {
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"pageInfo": { "type": "object" },
|
||||
"edges": { "type": "array" },
|
||||
"nodes": { "type": "array" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ describe('Experimental new project creation app', () => {
|
|||
findWelcomePage()
|
||||
.props()
|
||||
.panels.find((p) => p.name === panelName);
|
||||
const findPanelHeader = () => wrapper.find('h4');
|
||||
|
||||
describe('new_repo experiment', () => {
|
||||
describe('when in the candidate variant', () => {
|
||||
|
@ -33,6 +34,17 @@ describe('Experimental new project creation app', () => {
|
|||
|
||||
expect(findPanel('blank_project').title).toBe('Create blank project/repository');
|
||||
});
|
||||
|
||||
describe('when hash is not empty on load', () => {
|
||||
beforeEach(() => {
|
||||
window.location.hash = '#blank_project';
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('renders "project/repository"', () => {
|
||||
expect(findPanelHeader().text()).toBe('Create blank project/repository');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when in the control variant', () => {
|
||||
|
@ -43,6 +55,17 @@ describe('Experimental new project creation app', () => {
|
|||
|
||||
expect(findPanel('blank_project').title).toBe('Create blank project');
|
||||
});
|
||||
|
||||
describe('when hash is not empty on load', () => {
|
||||
beforeEach(() => {
|
||||
window.location.hash = '#blank_project';
|
||||
createComponent();
|
||||
});
|
||||
|
||||
it('renders "project"', () => {
|
||||
expect(findPanelHeader().text()).toBe('Create blank project');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe GitlabSchema.types['ConanFileMetadata'] do
|
||||
it 'includes conan file metadatum fields' do
|
||||
expected_fields = %w[
|
||||
id created_at updated_at recipe_revision package_revision conan_package_reference conan_file_type
|
||||
]
|
||||
|
||||
expect(described_class).to include_graphql_fields(*expected_fields)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe GitlabSchema.types['ConanMetadatumFileTypeEnum'] do
|
||||
it 'uses all possible options from model' do
|
||||
expected_keys = ::Packages::Conan::FileMetadatum.conan_file_types
|
||||
.keys
|
||||
.map(&:upcase)
|
||||
|
||||
expect(described_class.values.keys).to contain_exactly(*expected_keys)
|
||||
end
|
||||
end
|
13
spec/graphql/types/packages/conan/metadatum_type_spec.rb
Normal file
13
spec/graphql/types/packages/conan/metadatum_type_spec.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe GitlabSchema.types['ConanMetadata'] do
|
||||
it 'includes conan metadatum fields' do
|
||||
expected_fields = %w[
|
||||
id created_at updated_at package_username package_channel recipe recipe_path
|
||||
]
|
||||
|
||||
expect(described_class).to include_graphql_fields(*expected_fields)
|
||||
end
|
||||
end
|
|
@ -2,10 +2,10 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe GitlabSchema.types['PackageWithoutVersions'] do
|
||||
RSpec.describe GitlabSchema.types['PackageDetailsType'] do
|
||||
it 'includes all the package fields' do
|
||||
expected_fields = %w[
|
||||
id name version created_at updated_at package_type tags project pipelines
|
||||
id name version created_at updated_at package_type tags project pipelines versions package_files
|
||||
]
|
||||
|
||||
expect(described_class).to include_graphql_fields(*expected_fields)
|
13
spec/graphql/types/packages/package_file_type_spec.rb
Normal file
13
spec/graphql/types/packages/package_file_type_spec.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe GitlabSchema.types['PackageFile'] do
|
||||
it 'includes package file fields' do
|
||||
expected_fields = %w[
|
||||
id file_name created_at updated_at size file_name download_path file_md5 file_sha1 file_sha256 file_metadata
|
||||
]
|
||||
|
||||
expect(described_class).to include_graphql_fields(*expected_fields)
|
||||
end
|
||||
end
|
|
@ -8,7 +8,7 @@ RSpec.describe GitlabSchema.types['Package'] do
|
|||
id name version package_type
|
||||
created_at updated_at
|
||||
project
|
||||
tags pipelines versions
|
||||
tags pipelines metadata versions
|
||||
]
|
||||
|
||||
expect(described_class).to include_graphql_fields(*expected_fields)
|
||||
|
|
|
@ -98,6 +98,6 @@ RSpec.describe GitlabSchema.types['Query'] do
|
|||
describe 'package field' do
|
||||
subject { described_class.fields['package'] }
|
||||
|
||||
it { is_expected.to have_graphql_type(Types::Packages::PackageType) }
|
||||
it { is_expected.to have_graphql_type(Types::Packages::PackageDetailsType) }
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe ::Ci::PipelineEditorHelper do
|
||||
let_it_be(:project) { create(:project, :public, :repository) }
|
||||
|
||||
describe '#js_pipeline_editor_data' do
|
||||
before do
|
||||
allow(helper).to receive(:namespace_project_new_merge_request_path).and_return('/mock/project/-/merge_requests/new')
|
||||
end
|
||||
|
||||
subject { helper.js_pipeline_editor_data(project) }
|
||||
|
||||
it {
|
||||
is_expected.to match({
|
||||
"ci-config-path": project.ci_config_path_or_default,
|
||||
"commit-sha" => project.commit.sha,
|
||||
"default-branch" => project.default_branch,
|
||||
"empty-state-illustration-path" => match_asset_path("/assets/illustrations/empty-state/empty-dag-md.svg"),
|
||||
"initial-branch-name": nil,
|
||||
"lint-help-page-path" => help_page_path('ci/lint', anchor: 'validate-basic-logic-and-syntax'),
|
||||
"new-merge-request-path" => '/mock/project/-/merge_requests/new',
|
||||
"project-path" => project.path,
|
||||
"project-full-path" => project.full_path,
|
||||
"project-namespace" => project.namespace.full_path,
|
||||
"yml-help-page-path" => help_page_path('ci/yaml/README')
|
||||
})
|
||||
}
|
||||
end
|
||||
end
|
|
@ -2,33 +2,47 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'package details' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
include GraphqlHelpers
|
||||
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:package) { create(:composer_package, project: project) }
|
||||
let_it_be(:composer_package) { create(:composer_package, project: project) }
|
||||
let_it_be(:composer_json) { { name: 'name', type: 'type', license: 'license', version: 1 } }
|
||||
let_it_be(:composer_metadatum) do
|
||||
# we are forced to manually create the metadatum, without using the factory to force the sha to be a string
|
||||
# and avoid an error where gitaly can't find the repository
|
||||
create(:composer_metadatum, package: package, target_sha: 'foo_sha', composer_json: composer_json)
|
||||
create(:composer_metadatum, package: composer_package, target_sha: 'foo_sha', composer_json: composer_json)
|
||||
end
|
||||
|
||||
let(:depth) { 3 }
|
||||
let(:excluded) { %w[metadata apiFuzzingCiConfiguration pipeline] }
|
||||
let(:excluded) { %w[metadata apiFuzzingCiConfiguration pipeline packageFiles] }
|
||||
let(:metadata) { query_graphql_fragment('ComposerMetadata') }
|
||||
let(:package_files) {all_graphql_fields_for('PackageFile')}
|
||||
let(:package_files_metadata) {query_graphql_fragment('ConanFileMetadata')}
|
||||
|
||||
let(:query) do
|
||||
graphql_query_for(:package, { id: package_global_id }, <<~FIELDS)
|
||||
#{all_graphql_fields_for('Package', max_depth: depth, excluded: excluded)}
|
||||
#{all_graphql_fields_for('PackageDetailsType', max_depth: depth, excluded: excluded)}
|
||||
metadata {
|
||||
#{query_graphql_fragment('ComposerMetadata')}
|
||||
#{metadata}
|
||||
}
|
||||
packageFiles {
|
||||
nodes {
|
||||
#{package_files}
|
||||
fileMetadata {
|
||||
#{package_files_metadata}
|
||||
}
|
||||
}
|
||||
}
|
||||
FIELDS
|
||||
end
|
||||
|
||||
let(:user) { project.owner }
|
||||
let(:package_global_id) { global_id_of(package) }
|
||||
let(:package_global_id) { global_id_of(composer_package) }
|
||||
let(:package_details) { graphql_data_at(:package) }
|
||||
let(:metadata_response) { graphql_data_at(:package, :metadata) }
|
||||
let(:package_files_response) { graphql_data_at(:package, :package_files, :nodes) }
|
||||
let(:first_file_response) { graphql_data_at(:package, :package_files, :nodes, 0)}
|
||||
let(:first_file_response_metadata) { graphql_data_at(:package, :package_files, :nodes, 0, :file_metadata)}
|
||||
|
||||
subject { post_graphql(query, current_user: user) }
|
||||
|
||||
|
@ -40,15 +54,68 @@ RSpec.describe 'package details' do
|
|||
it 'matches the JSON schema' do
|
||||
expect(package_details).to match_schema('graphql/packages/package_details')
|
||||
end
|
||||
end
|
||||
|
||||
it 'includes the fields of the correct package' do
|
||||
expect(package_details).to include(
|
||||
'id' => package_global_id,
|
||||
'metadata' => {
|
||||
describe 'Packages Metadata' do
|
||||
before do
|
||||
subject
|
||||
end
|
||||
|
||||
describe 'Composer' do
|
||||
it 'has the correct metadata' do
|
||||
expect(metadata_response).to include(
|
||||
'targetSha' => 'foo_sha',
|
||||
'composerJson' => composer_json.transform_keys(&:to_s).transform_values(&:to_s)
|
||||
}
|
||||
)
|
||||
)
|
||||
end
|
||||
|
||||
it 'does not have files' do
|
||||
expect(package_files_response).to be_empty
|
||||
end
|
||||
end
|
||||
|
||||
describe 'Conan' do
|
||||
let_it_be(:conan_package) { create(:conan_package, project: project) }
|
||||
|
||||
let(:package_global_id) { global_id_of(conan_package) }
|
||||
let(:metadata) { query_graphql_fragment('ConanMetadata') }
|
||||
let(:first_file) { conan_package.package_files.find { |f| global_id_of(f) == first_file_response['id'] } }
|
||||
|
||||
it 'has the correct metadata' do
|
||||
expect(metadata_response).to include(
|
||||
'id' => global_id_of(conan_package.conan_metadatum),
|
||||
'recipe' => conan_package.conan_metadatum.recipe,
|
||||
'packageChannel' => conan_package.conan_metadatum.package_channel,
|
||||
'packageUsername' => conan_package.conan_metadatum.package_username,
|
||||
'recipePath' => conan_package.conan_metadatum.recipe_path
|
||||
)
|
||||
end
|
||||
|
||||
it 'has the right amount of files' do
|
||||
expect(package_files_response.length).to be(conan_package.package_files.length)
|
||||
end
|
||||
|
||||
it 'has the basic package files data' do
|
||||
expect(first_file_response).to include(
|
||||
'id' => global_id_of(first_file),
|
||||
'fileName' => first_file.file_name,
|
||||
'size' => first_file.size.to_s,
|
||||
'downloadPath' => first_file.download_path,
|
||||
'fileSha1' => first_file.file_sha1,
|
||||
'fileMd5' => first_file.file_md5,
|
||||
'fileSha256' => first_file.file_sha256
|
||||
)
|
||||
end
|
||||
|
||||
it 'has the correct file metadata' do
|
||||
expect(first_file_response_metadata).to include(
|
||||
'id' => global_id_of(first_file.conan_file_metadatum),
|
||||
'packageRevision' => first_file.conan_file_metadatum.package_revision,
|
||||
'conanPackageReference' => first_file.conan_file_metadatum.conan_package_reference,
|
||||
'recipeRevision' => first_file.conan_file_metadatum.recipe_revision,
|
||||
'conanFileType' => first_file.conan_file_metadatum.conan_file_type.upcase
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -56,7 +123,7 @@ RSpec.describe 'package details' do
|
|||
let(:depth) { 3 }
|
||||
let(:excluded) { %w[metadata project tags pipelines] } # to limit the query complexity
|
||||
|
||||
let_it_be(:siblings) { create_list(:composer_package, 2, project: project, name: package.name) }
|
||||
let_it_be(:siblings) { create_list(:composer_package, 2, project: project, name: composer_package.name) }
|
||||
|
||||
it 'includes the sibling versions' do
|
||||
subject
|
||||
|
@ -73,8 +140,32 @@ RSpec.describe 'package details' do
|
|||
subject
|
||||
|
||||
expect(graphql_data_at(:package, :versions, :nodes, :version)).to be_present
|
||||
expect(graphql_data_at(:package, :versions, :nodes, :versions)).not_to be_present
|
||||
expect(graphql_data_at(:package, :versions, :nodes, :versions, :nodes)).to be_empty
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with a batched query' do
|
||||
let_it_be(:conan_package) { create(:conan_package, project: project) }
|
||||
|
||||
let(:batch_query) do
|
||||
<<~QUERY
|
||||
{
|
||||
a: package(id: "#{global_id_of(composer_package)}") { name }
|
||||
b: package(id: "#{global_id_of(conan_package)}") { name }
|
||||
}
|
||||
QUERY
|
||||
end
|
||||
|
||||
let(:a_packages_names) { graphql_data_at(:a, :packages, :nodes, :name) }
|
||||
|
||||
it 'returns an error for the second package and data for the first' do
|
||||
post_graphql(batch_query, current_user: user)
|
||||
|
||||
expect(graphql_data_at(:a, :name)).to eq(composer_package.name)
|
||||
|
||||
expect_graphql_errors_to_include [/Package details can be requested only for one package at a time/]
|
||||
expect(graphql_data_at(:b)).to be(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1795,8 +1795,7 @@ RSpec.describe API::Users do
|
|||
post api("/users/#{user.id}/emails", admin), params: email_attrs
|
||||
end.to change { user.emails.count }.by(1)
|
||||
|
||||
email = Email.find_by(user_id: user.id, email: email_attrs[:email])
|
||||
expect(email).not_to be_confirmed
|
||||
expect(json_response['confirmed_at']).to be_nil
|
||||
end
|
||||
|
||||
it "returns a 400 for invalid ID" do
|
||||
|
@ -1813,8 +1812,7 @@ RSpec.describe API::Users do
|
|||
|
||||
expect(response).to have_gitlab_http_status(:created)
|
||||
|
||||
email = Email.find_by(user_id: user.id, email: email_attrs[:email])
|
||||
expect(email).to be_confirmed
|
||||
expect(json_response['confirmed_at']).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -907,10 +907,10 @@
|
|||
resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8"
|
||||
integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw==
|
||||
|
||||
"@gitlab/ui@29.2.1":
|
||||
version "29.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.2.1.tgz#e6377131f3a22eebe07903198ec874ca5d26884c"
|
||||
integrity sha512-vLzCMQsppGLpzWRaNxXpx86y6JjSOEnQXQxtLudnSJktWl0uHfglED2xe7vJQJo+qmzQf6T5m3gbVupj/pG4+A==
|
||||
"@gitlab/ui@29.3.0":
|
||||
version "29.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.3.0.tgz#e549b73341246bb9cd1005b2f4c10a599c680cb1"
|
||||
integrity sha512-TWc3O3w7L+aCLC7Vp2JbYTFgCwseLExxjhwDfJuc2Iwkr+1k8k1ygctbid9XRX2Jcy3JPbL+o+m0K/ZXMJTWdg==
|
||||
dependencies:
|
||||
"@babel/standalone" "^7.0.0"
|
||||
"@gitlab/vue-toasted" "^1.3.0"
|
||||
|
|
Loading…
Reference in a new issue