Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
32b8c029dc
commit
f84cdc5587
|
|
@ -1 +1 @@
|
|||
35cfdacad6baf3e031993625b9ce4e5d46dfd388
|
||||
7186455e61c1a6556cd6f0664a9c90c5da2e6bae
|
||||
|
|
|
|||
|
|
@ -21,11 +21,6 @@ export default {
|
|||
required: false,
|
||||
default: false,
|
||||
},
|
||||
duplicatesAllowed: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
required: false,
|
||||
},
|
||||
duplicateExceptionRegex: {
|
||||
type: String,
|
||||
default: '',
|
||||
|
|
@ -68,7 +63,7 @@ export default {
|
|||
>
|
||||
<gl-form-input
|
||||
:id="id"
|
||||
:disabled="duplicatesAllowed || loading"
|
||||
:disabled="loading"
|
||||
width="lg"
|
||||
:value="duplicateExceptionRegex"
|
||||
:state="isExceptionRegexValid"
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
<script>
|
||||
import { GlTableLite, GlToggle } from '@gitlab/ui';
|
||||
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
|
||||
import {
|
||||
GENERIC_PACKAGE_FORMAT,
|
||||
MAVEN_PACKAGE_FORMAT,
|
||||
|
|
@ -49,7 +48,6 @@ export default {
|
|||
GlToggle,
|
||||
ExceptionsInput,
|
||||
},
|
||||
mixins: [glFeatureFlagMixin()],
|
||||
inject: ['groupPath'],
|
||||
props: {
|
||||
packageSettings: {
|
||||
|
|
@ -160,13 +158,6 @@ export default {
|
|||
this.$emit('error');
|
||||
}
|
||||
},
|
||||
allowDuplicateExceptions(item) {
|
||||
if (item.format === NUGET_PACKAGE_FORMAT) return item.duplicatesAllowed;
|
||||
|
||||
// We're also enabling the duplicate exceptions input when duplicates are allowed
|
||||
// But the change is behind the packagesAllowDuplicateExceptions feature flag
|
||||
return !this.glFeatures.packagesAllowDuplicateExceptions && item.duplicatesAllowed;
|
||||
},
|
||||
update(type, value) {
|
||||
this.updateSettings({ [type]: value });
|
||||
},
|
||||
|
|
@ -204,7 +195,6 @@ export default {
|
|||
<template #cell(exceptions)="{ item }">
|
||||
<exceptions-input
|
||||
:id="item.id"
|
||||
:duplicates-allowed="allowDuplicateExceptions(item)"
|
||||
:duplicate-exception-regex="item.duplicateExceptionRegex"
|
||||
:duplicate-exception-regex-error="item.duplicateExceptionRegexError"
|
||||
:name="item.modelNames.exception"
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ module Groups
|
|||
|
||||
before_action do
|
||||
push_frontend_feature_flag(:maven_central_request_forwarding, group)
|
||||
push_frontend_feature_flag(:packages_allow_duplicate_exceptions, group)
|
||||
end
|
||||
|
||||
feature_category :package_registry
|
||||
|
|
|
|||
|
|
@ -366,9 +366,9 @@ module Ci
|
|||
|
||||
begin
|
||||
transaction do
|
||||
if self.runner_projects.empty?
|
||||
self.sharding_key_id = project.id
|
||||
if ::Project.id_in(sharding_key_id).empty?
|
||||
self.clear_memoization(:owner)
|
||||
self.sharding_key_id = fallback_owner_project&.id || project.id
|
||||
end
|
||||
|
||||
self.runner_projects << ::Ci::RunnerProject.new(project: project, runner: self)
|
||||
|
|
@ -407,14 +407,9 @@ module Ci
|
|||
when 'group_type'
|
||||
::Group.find_by_id(sharding_key_id)
|
||||
when 'project_type'
|
||||
# NOTE: when a project is deleted, the respective ci_runner_projects records are not immediately
|
||||
# deleted by the LFK, so we might find join records that point to a non-existing project
|
||||
project = ::Project.find_by_id(sharding_key_id)
|
||||
return project if project
|
||||
owner_project = ::Project.find_by_id(sharding_key_id)
|
||||
|
||||
project_ids = runner_projects.order(:id).pluck(:project_id)
|
||||
projects_added_to_runner_asc = Arel.sql("array_position(ARRAY[#{project_ids.join(',')}]::bigint[], id)")
|
||||
Project.order(projects_added_to_runner_asc).find_by_id(project_ids)
|
||||
owner_project || fallback_owner_project
|
||||
end
|
||||
end
|
||||
strong_memoize_attr :owner
|
||||
|
|
@ -570,6 +565,14 @@ module Ci
|
|||
joins(:runner_managers).merge(RunnerManager.with_upgrade_status(upgrade_status))
|
||||
end
|
||||
|
||||
def fallback_owner_project
|
||||
# NOTE: when a project is deleted, the respective ci_runner_projects records are not immediately
|
||||
# deleted by the LFK, so we might find join records that point to a still-existing project
|
||||
project_ids = runner_projects.order(:id).pluck(:project_id)
|
||||
projects_added_to_runner_asc = Arel.sql("array_position(ARRAY[#{project_ids.join(',')}]::bigint[], id)")
|
||||
Project.order(projects_added_to_runner_asc).find_by_id(project_ids)
|
||||
end
|
||||
|
||||
def compute_token_expiration_instance
|
||||
return unless expiration_interval = Gitlab::CurrentSettings.runner_token_expiration_interval
|
||||
|
||||
|
|
|
|||
|
|
@ -44,13 +44,9 @@ class Namespace::PackageSetting < ApplicationRecord
|
|||
"\\A#{package.package_settings["#{package.package_type}_duplicate_exception_regex"]}\\z"
|
||||
)
|
||||
|
||||
if Feature.enabled?(:packages_allow_duplicate_exceptions, package.project.group)
|
||||
regex_match = regex.match?(package.name) || regex.match?(package.version)
|
||||
regex_match = regex.match?(package.name) || regex.match?(package.version)
|
||||
|
||||
duplicates_allowed ? !regex_match : regex_match
|
||||
else
|
||||
duplicates_allowed || regex.match?(package.name) || regex.match?(package.version)
|
||||
end
|
||||
duplicates_allowed ? !regex_match : regex_match
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -667,6 +667,13 @@ class ProjectPolicy < BasePolicy
|
|||
enable :admin_protected_branch
|
||||
end
|
||||
|
||||
rule { can?(:manage_protected_tags) }.policy do
|
||||
enable :read_protected_tags
|
||||
enable :create_protected_tags
|
||||
enable :update_protected_tags
|
||||
enable :destroy_protected_tags
|
||||
end
|
||||
|
||||
rule { can?(:admin_build) }.enable :manage_trigger
|
||||
rule { can?(:admin_runner) }.enable :read_runner
|
||||
|
||||
|
|
|
|||
|
|
@ -42,18 +42,12 @@ module Packages
|
|||
end
|
||||
|
||||
def duplicates_not_allowed?
|
||||
ff_enabled = Feature.enabled?(:packages_allow_duplicate_exceptions, project.group)
|
||||
|
||||
package_settings_with_duplicates_allowed.none? do |setting|
|
||||
exception_regex_matches = ::Gitlab::UntrustedRegexp
|
||||
.new("\\A#{setting.terraform_module_duplicate_exception_regex}\\z")
|
||||
.match?(name)
|
||||
|
||||
if ff_enabled
|
||||
setting.terraform_module_duplicates_allowed ? !exception_regex_matches : exception_regex_matches
|
||||
else
|
||||
setting.terraform_module_duplicates_allowed || exception_regex_matches
|
||||
end
|
||||
setting.terraform_module_duplicates_allowed ? !exception_regex_matches : exception_regex_matches
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ module ProtectedTags
|
|||
attr_reader :protected_tag
|
||||
|
||||
def execute
|
||||
raise Gitlab::Access::AccessDeniedError unless can?(current_user, :admin_project, project)
|
||||
raise Gitlab::Access::AccessDeniedError unless can?(current_user, :create_protected_tags, project)
|
||||
|
||||
project.protected_tags.create(params)
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@
|
|||
module ProtectedTags
|
||||
class DestroyService < BaseService
|
||||
def execute(protected_tag)
|
||||
raise Gitlab::Access::AccessDeniedError unless can?(current_user, :destroy_protected_tags, project)
|
||||
|
||||
protected_tag.destroy
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
name: packages_allow_duplicate_exceptions
|
||||
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/482901
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/165467
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/498085
|
||||
milestone: '17.7'
|
||||
group: group::package registry
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
|
|
@ -12,9 +12,9 @@
|
|||
window: "1"
|
||||
body: | # (required) Do not modify this line, instead modify the lines below.
|
||||
The support for registration tokens and certain runner configuration arguments in the `POST` method operation on the `/api/v4/runners` endpoint is deprecated.
|
||||
This endpoint [registers](https://docs.gitlab.com/ee/api/runners.html#register-a-new-runner) a runner
|
||||
with a GitLab instance at the instance, group, or project level through the API. In GitLab 17.0, registration tokens, and support for certain configuration arguments,
|
||||
will start returning the HTTP `410 Gone` status code in GitLab 17.0. For more information, see [Migrating to the new runner registration workflow](https://docs.gitlab.com/ee/ci/runners/new_creation_workflow.html#prevent-your-runner-registration-workflow-from-breaking).
|
||||
This endpoint [registers](https://docs.gitlab.com/ee/api/runners.html#create-a-runner) a runner
|
||||
with a GitLab instance at the instance, group, or project level through the API. In GitLab 18.0, registration tokens, and support for certain configuration arguments,
|
||||
will start returning the HTTP `410 Gone` status code. For more information, see [Migrating to the new runner registration workflow](https://docs.gitlab.com/ee/ci/runners/new_creation_workflow.html#prevent-your-runner-registration-workflow-from-breaking).
|
||||
|
||||
The configuration arguments disabled for runner authentication tokens are:
|
||||
|
||||
|
|
@ -29,4 +29,4 @@
|
|||
This change is a breaking change. You should [create a runner in the UI](https://docs.gitlab.com/ee/ci/runners/runners_scope.html) to add configurations, and use the runner authentication token in the `gitlab-runner register` command instead.
|
||||
end_of_support_milestone: # (optional) Use "XX.YY" format. The milestone when support for this feature will end.
|
||||
tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
|
||||
documentation_url: https://docs.gitlab.com/ee/api/runners.html#register-a-new-runner # (optional) This is a link to the current documentation page
|
||||
documentation_url: https://docs.gitlab.com/ee/api/runners.html#create-a-runner # (optional) This is a link to the current documentation page
|
||||
|
|
|
|||
|
|
@ -24,8 +24,8 @@
|
|||
as part of the new [GitLab Runner token architecture](https://docs.gitlab.com/ee/ci/runners/new_creation_workflow.html).
|
||||
The work is planned in [this epic](https://gitlab.com/groups/gitlab-org/-/epics/7633).
|
||||
This new architecture introduces a new method for registering runners and will eliminate the legacy
|
||||
[runner registration token](https://docs.gitlab.com/ee/security/token_overview.html#runner-registration-tokens).
|
||||
[runner registration token](https://docs.gitlab.com/ee/security/tokens/index.html#runner-registration-tokens-deprecated).
|
||||
From GitLab 18.0 and later, the runner registration methods implemented by the new GitLab Runner token architecture will be the only supported methods.
|
||||
end_of_support_milestone: # (optional) Use "XX.YY" format. The milestone when support for this feature will end.
|
||||
tiers: # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate]
|
||||
documentation_url: https://docs.gitlab.com/ee/api/runners.html#register-a-new-runner # (optional) This is a link to the current documentation page
|
||||
documentation_url: https://docs.gitlab.com/ee/api/runners.html#create-a-runner # (optional) This is a link to the current documentation page
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
- title: '`ciUsedMinutes` GraphQL field renamed to `ciDuration`'
|
||||
- title: '`ciMinutesUsed` GraphQL field renamed to `ciDuration`'
|
||||
removal_milestone: '18.0'
|
||||
announcement_milestone: '17.5'
|
||||
breaking_change: true
|
||||
|
|
@ -11,8 +11,8 @@
|
|||
manual_task: true
|
||||
window: "2"
|
||||
body: |
|
||||
The `ciDuration` field of the `CiRunnerUsage` and `CiRunnerUsageByProject` types replaces the former `ciUsedMinutes` field.
|
||||
Update all references to `ciUsedMinutes` from these types to `ciDuration`.
|
||||
The `ciDuration` field of the `CiRunnerUsage` and `CiRunnerUsageByProject` types replaces the former `ciMinutesUsed` field.
|
||||
Update all references to `ciMinutesUsed` from these types to `ciDuration`.
|
||||
|
||||
tiers: Ultimate
|
||||
documentation_url: https://docs.gitlab.com/ee/api/graphql/reference/#cirunnerusage
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
as part of the new [GitLab Runner token architecture](https://docs.gitlab.com/ee/ci/runners/new_creation_workflow.html).
|
||||
For details, see [epic 7633](https://gitlab.com/groups/gitlab-org/-/epics/7633).
|
||||
This new architecture introduces a new method for registering runners and eliminates the legacy
|
||||
[runner registration token](https://docs.gitlab.com/ee/security/token_overview.html#runner-registration-tokens).
|
||||
[runner registration token](https://docs.gitlab.com/ee/security/tokens/index.html#runner-registration-tokens-deprecated).
|
||||
In GitLab 18.0, only the runner registration methods implemented in the new GitLab Runner token architecture will be supported.
|
||||
#
|
||||
# When support for this feature ends, in XX.YY milestone format.
|
||||
|
|
@ -29,7 +29,7 @@
|
|||
# like [Free, Silver, Gold, Core, Premium, Ultimate]
|
||||
tiers:
|
||||
# Links to documentation and thumbnail image
|
||||
documentation_url: https://docs.gitlab.com/ee/api/runners.html#register-a-new-runner # (optional) This is a link to the current documentation page
|
||||
documentation_url: https://docs.gitlab.com/ee/api/runners.html#create-a-runner # (optional) This is a link to the current documentation page
|
||||
image_url:
|
||||
# Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg
|
||||
video_url:
|
||||
|
|
|
|||
|
|
@ -218,4 +218,4 @@ Also plan ahead if you need the following GitLab Dedicated features:
|
|||
To view all available infrastructure configuration options, see [Configure your GitLab Dedicated instance](../../administration/dedicated/configure_instance.md).
|
||||
|
||||
NOTE:
|
||||
New GitLab Dedicated instances use default settings for a self-managed instance. A GitLab administrator can change these settings from the [Admin Area](../../administration/admin_area.md).
|
||||
New GitLab Dedicated instances use the same default settings as GitLab Self-Managed. A GitLab administrator can change these settings from the [Admin Area](../../administration/admin_area.md).
|
||||
|
|
|
|||
|
|
@ -350,7 +350,7 @@ tail -f log/elasticsearch.log
|
|||
|
||||
For `ActiveRecord` objects, the `ApplicationVersionedSearch` concern can be included on the model to index data based on callbacks. If that's not suitable, call `Elastic::ProcessBookkeepingService.track!()` with an instance of `Search::Elastic::Reference` whenever a document should be indexed.
|
||||
|
||||
Always check for `Gitlab::CurrentSettings.elasticsearch_indexing?` and `use_elasticsearch?` because some self-managed instances do not have Elasticsearch enabled and [namespace limiting](../integration/advanced_search/elasticsearch.md#limit-the-amount-of-namespace-and-project-data-to-index) can be enabled.
|
||||
Always check for `Gitlab::CurrentSettings.elasticsearch_indexing?` and `use_elasticsearch?` because some GitLab Self-Managed instances do not have Elasticsearch enabled and [namespace limiting](../integration/advanced_search/elasticsearch.md#limit-the-amount-of-namespace-and-project-data-to-index) can be enabled.
|
||||
|
||||
Also check that the index is able to handle the index request. For example, check that the index exists if it was added in the current major release by verifying that the migration to add the index was completed: `Elastic::DataMigrationService.migration_has_finished?`.
|
||||
|
||||
|
|
|
|||
|
|
@ -316,7 +316,7 @@ For more information, see [the guideline of the regression evaluator](https://gi
|
|||
|
||||
## GitLab Duo Chat Self-managed End-to-End Tests
|
||||
|
||||
In MRs, the end-to-end tests exercise the Duo Chat functionality of self-managed instances by using an instance of the GitLab Linux package
|
||||
In MRs, the end-to-end tests exercise the Duo Chat functionality of GitLab Self-Managed instances by using an instance of the GitLab Linux package
|
||||
integrated with the `latest` version of AI gateway. The instance of AI gateway is configured to return [mock responses](https://gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist#mocking-ai-model-responses).
|
||||
To view the results of these tests, open the `e2e:test-on-omnibus-ee` child pipeline and view the `ai-gateway` job.
|
||||
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ Include in the MR description:
|
|||
access and size. Include in the MR description answers to these questions:
|
||||
- What is the anticipated growth for the new table over the next 3 months, 6 months, 1 year? What assumptions are these based on?
|
||||
- How many reads and writes per hour would you expect this table to have in 3 months, 6 months, 1 year? Under what circumstances are rows updated? What assumptions are these based on?
|
||||
- Based on the anticipated data volume and access patterns, does the new table pose an availability risk to GitLab.com or self-managed instances? Does the proposed design scale to support the needs of GitLab.com and self-managed customers?
|
||||
- Based on the anticipated data volume and access patterns, does the new table pose an availability risk to GitLab.com or GitLab Self-Managed instances? Does the proposed design scale to support the needs of GitLab.com and GitLab Self-Managed customers?
|
||||
|
||||
#### Preparation when removing columns, tables, indexes, or other structures
|
||||
|
||||
|
|
|
|||
|
|
@ -423,6 +423,24 @@ about toggling feature flags.
|
|||
See [cleaning up feature flags](controls.md#cleaning-up) for more information about
|
||||
deleting feature flags.
|
||||
|
||||
## Migrate an `ops` feature flag to an application setting
|
||||
|
||||
To migrate an `ops` feature flag to an application setting:
|
||||
|
||||
1. In application settings, create or identify an existing `JSONB` column to store the setting.
|
||||
1. Write a migration to backfill the column.
|
||||
For an example, see [merge request 148014](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/148014).
|
||||
1. Optional. In application settings, update the documentation for the setting.
|
||||
1. In the **Admin** area, create a setting to enable or disable the feature.
|
||||
1. Replace the feature flag everywhere with the application setting.
|
||||
1. Update all the relevant documentation pages.
|
||||
1. Mark the backfill migration as a `NOOP` and remove the feature flag after the mandatory upgrade path is crossed.
|
||||
For an example, see [merge request 151080](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/151080).
|
||||
|
||||
The changes to backfill application settings and use the settings in the code must be merged in the same milestone.
|
||||
If frontend changes are merged in a later milestone, you should add documentation about how to update the settings
|
||||
by using the [application settings API](../../api/settings.md) or the Rails console.
|
||||
|
||||
## Develop with a feature flag
|
||||
|
||||
There are two main ways of using feature flags in the GitLab codebase:
|
||||
|
|
|
|||
|
|
@ -258,4 +258,4 @@ resolved.
|
|||
|
||||
- Blog post: [Getting started with Git LFS](https://about.gitlab.com/blog/2017/01/30/getting-started-with-git-lfs-tutorial/)
|
||||
- User documentation: [Git Large File Storage (LFS)](../topics/git/lfs/index.md)
|
||||
- [GitLab Git Large File Storage (LFS) Administration](../administration/lfs/index.md) for self-managed instances
|
||||
- [GitLab Git Large File Storage (LFS) Administration](../administration/lfs/index.md) for GitLab Self-Managed
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ Your migration **must be** reversible. This is very important, as it should
|
|||
be possible to downgrade in case of a vulnerability or bugs.
|
||||
|
||||
**Note**: On GitLab production environments, if a problem occurs, a roll-forward strategy is used instead of rolling back migrations using `db:rollback`.
|
||||
On self-managed instances we advise users to restore the backup which was created before the upgrade process started.
|
||||
On GitLab Self-Managed, we advise users to restore the backup which was created before the upgrade process started.
|
||||
The `down` method is used primarily in the development environment, for example, when a developer wants to ensure
|
||||
their local copy of `structure.sql` file and database are in a consistent state when switching between commits or branches.
|
||||
|
||||
|
|
@ -1544,7 +1544,7 @@ Any table which has some high read operation compared to current [high-traffic t
|
|||
|
||||
As a general rule, we discourage adding columns to high-traffic tables that are purely for
|
||||
analytics or reporting of GitLab.com. This can have negative performance impacts for all
|
||||
self-managed instances without providing direct feature value to them.
|
||||
GitLab Self-Managed instances without providing direct feature value to them.
|
||||
|
||||
## Milestone
|
||||
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ This window takes place on April 28 - 30, 2025 from 09:00 UTC to 22:00 UTC.
|
|||
| [Replace GraphQL field `take_ownership_pipeline_schedule` with `admin_pipeline_schedule` in PipelineSchedulePermissions](https://gitlab.com/gitlab-org/gitlab/-/issues/391941) | Low | Verify | Project |
|
||||
| [`GITLAB_SHARED_RUNNERS_REGISTRATION_TOKEN` is deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/453949) | Medium | Verify | Instance |
|
||||
| [The `heroku/builder:22` image is deprecated](https://gitlab.com/gitlab-org/cluster-integration/auto-build-image/-/issues/79) | Medium | Deploy | Project |
|
||||
| [`ciUsedMinutes` GraphQL field renamed to `ciDuration`](https://gitlab.com/gitlab-org/gitlab/-/issues/497364) | Medium | Verify | Instance |
|
||||
| [`ciMinutesUsed` GraphQL field renamed to `ciDuration`](https://gitlab.com/gitlab-org/gitlab/-/issues/497364) | Medium | Verify | Instance |
|
||||
| [`mergeTrainIndex` and `mergeTrainsCount` GraphQL fields deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/473759) | Low | Verify | Project |
|
||||
| [RunnersRegistrationTokenReset GraphQL mutation is deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/505703) | High | Verify | Instance, group, project |
|
||||
| [Behavior change for Upcoming and Started milestone filters](https://gitlab.com/gitlab-org/gitlab/-/issues/501294) | Low | Plan | Group, project |
|
||||
|
|
|
|||
|
|
@ -1213,9 +1213,9 @@ Instance administrators can set higher or lower limits as needed in the Admin ar
|
|||
</div>
|
||||
|
||||
The support for registration tokens and certain runner configuration arguments in the `POST` method operation on the `/api/v4/runners` endpoint is deprecated.
|
||||
This endpoint [registers](https://docs.gitlab.com/ee/api/runners.html#register-a-new-runner) a runner
|
||||
with a GitLab instance at the instance, group, or project level through the API. In GitLab 17.0, registration tokens, and support for certain configuration arguments,
|
||||
will start returning the HTTP `410 Gone` status code in GitLab 17.0. For more information, see [Migrating to the new runner registration workflow](https://docs.gitlab.com/ee/ci/runners/new_creation_workflow.html#prevent-your-runner-registration-workflow-from-breaking).
|
||||
This endpoint [registers](https://docs.gitlab.com/ee/api/runners.html#create-a-runner) a runner
|
||||
with a GitLab instance at the instance, group, or project level through the API. In GitLab 18.0, registration tokens, and support for certain configuration arguments,
|
||||
will start returning the HTTP `410 Gone` status code. For more information, see [Migrating to the new runner registration workflow](https://docs.gitlab.com/ee/ci/runners/new_creation_workflow.html#prevent-your-runner-registration-workflow-from-breaking).
|
||||
|
||||
The configuration arguments disabled for runner authentication tokens are:
|
||||
|
||||
|
|
@ -1451,7 +1451,7 @@ A new method to bind runners to a GitLab instance has been implemented
|
|||
as part of the new [GitLab Runner token architecture](https://docs.gitlab.com/ee/ci/runners/new_creation_workflow.html).
|
||||
For details, see [epic 7633](https://gitlab.com/groups/gitlab-org/-/epics/7633).
|
||||
This new architecture introduces a new method for registering runners and eliminates the legacy
|
||||
[runner registration token](https://docs.gitlab.com/ee/security/token_overview.html#runner-registration-tokens).
|
||||
[runner registration token](https://docs.gitlab.com/ee/security/tokens/index.html#runner-registration-tokens-deprecated).
|
||||
In GitLab 18.0, only the runner registration methods implemented in the new GitLab Runner token architecture will be supported.
|
||||
|
||||
</div>
|
||||
|
|
@ -1524,7 +1524,7 @@ We plan to implement a new method to bind runners to a GitLab instance
|
|||
as part of the new [GitLab Runner token architecture](https://docs.gitlab.com/ee/ci/runners/new_creation_workflow.html).
|
||||
The work is planned in [this epic](https://gitlab.com/groups/gitlab-org/-/epics/7633).
|
||||
This new architecture introduces a new method for registering runners and will eliminate the legacy
|
||||
[runner registration token](https://docs.gitlab.com/ee/security/token_overview.html#runner-registration-tokens).
|
||||
[runner registration token](https://docs.gitlab.com/ee/security/tokens/index.html#runner-registration-tokens-deprecated).
|
||||
From GitLab 18.0 and later, the runner registration methods implemented by the new GitLab Runner token architecture will be the only supported methods.
|
||||
|
||||
</div>
|
||||
|
|
@ -1737,7 +1737,7 @@ With the [upcoming default behavior change to the CI/CD job token](https://docs.
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### `ciUsedMinutes` GraphQL field renamed to `ciDuration`
|
||||
### `ciMinutesUsed` GraphQL field renamed to `ciDuration`
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
||||
|
|
@ -1747,8 +1747,8 @@ With the [upcoming default behavior change to the CI/CD job token](https://docs.
|
|||
|
||||
</div>
|
||||
|
||||
The `ciDuration` field of the `CiRunnerUsage` and `CiRunnerUsageByProject` types replaces the former `ciUsedMinutes` field.
|
||||
Update all references to `ciUsedMinutes` from these types to `ciDuration`.
|
||||
The `ciDuration` field of the `CiRunnerUsage` and `CiRunnerUsageByProject` types replaces the former `ciMinutesUsed` field.
|
||||
Update all references to `ciMinutesUsed` from these types to `ciDuration`.
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -476,6 +476,9 @@ To disable publishing duplicate file names:
|
|||
1. In the **Generic** row of the **Duplicate packages** table, turn off the **Allow duplicates** toggle.
|
||||
1. Optional. In the **Exceptions** text box, enter a regular expression that matches the names and versions of packages to allow.
|
||||
|
||||
NOTE:
|
||||
If **Allow duplicates** is turned on, you can specify package names and versions that should not have duplicates in the **Exceptions** text box.
|
||||
|
||||
## Add a package retention policy
|
||||
|
||||
Implement a package retention policy to manage storage and maintain relevant versions.
|
||||
|
|
|
|||
|
|
@ -874,6 +874,9 @@ In the UI:
|
|||
1. In the **Maven** row of the **Duplicate packages** table, turn off the **Allow duplicates** toggle.
|
||||
1. Optional. In the **Exceptions** text box, enter a regular expression that matches the names and versions of packages to allow.
|
||||
|
||||
NOTE:
|
||||
If **Allow duplicates** is turned on, you can specify package names and versions that should not have duplicates in the **Exceptions** text box.
|
||||
|
||||
Your changes are automatically saved.
|
||||
|
||||
### Request forwarding to Maven Central
|
||||
|
|
|
|||
|
|
@ -445,6 +445,9 @@ In the UI:
|
|||
1. In the **NuGet** row of the **Duplicate packages** table, turn off the **Allow duplicates** toggle.
|
||||
1. Optional. In the **Exceptions** text box, enter a regular expression that matches the names and versions of packages to allow.
|
||||
|
||||
NOTE:
|
||||
If **Allow duplicates** is turned on, you can specify package names and versions that should not have duplicates in the **Exceptions** text box.
|
||||
|
||||
Your changes are automatically saved.
|
||||
|
||||
WARNING:
|
||||
|
|
|
|||
|
|
@ -171,10 +171,13 @@ To allow publishing duplicate module names:
|
|||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
1. Select **Settings > Packages and registries**.
|
||||
1. In the **Terraform module** row of the **Duplicate packages** table, turn off the **Allow duplicates** toggle.
|
||||
1. Optional. In the **Exceptions** text box, enter a regular expression that matches the names of packages to allow.
|
||||
1. Optional. In the **Exceptions** text box, enter a regular expression that matches the names of modules to allow.
|
||||
|
||||
Your changes are automatically saved.
|
||||
|
||||
NOTE:
|
||||
If **Allow duplicates** is turned on, you can specify module names that should not have duplicates in the **Exceptions** text box.
|
||||
|
||||
You can also allow publishing duplicate names by enabling `terraform_module_duplicates_allowed` in the [GraphQL API](../../../api/graphql/reference/_index.md#packagesettings).
|
||||
|
||||
To allow duplicates with specific names:
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ module API
|
|||
|
||||
TAG_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(name: API::NO_SLASH_URL_PART_REGEX)
|
||||
|
||||
before { authorize_admin_project }
|
||||
|
||||
feature_category :source_code_management
|
||||
|
||||
helpers Helpers::ProtectedTagsHelpers
|
||||
|
|
@ -31,6 +29,7 @@ module API
|
|||
end
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
get ':id/protected_tags' do
|
||||
authorize!(:read_protected_tags, user_project)
|
||||
protected_tags = user_project.protected_tags.preload(:create_access_levels)
|
||||
|
||||
present paginate(protected_tags), with: Entities::ProtectedTag, project: user_project
|
||||
|
|
@ -51,6 +50,7 @@ module API
|
|||
end
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
get ':id/protected_tags/:name', requirements: TAG_ENDPOINT_REQUIREMENTS do
|
||||
authorize!(:read_protected_tags, user_project)
|
||||
protected_tag = user_project.protected_tags.find_by!(name: params[:name])
|
||||
|
||||
present protected_tag, with: Entities::ProtectedTag, project: user_project
|
||||
|
|
@ -77,6 +77,7 @@ module API
|
|||
use :optional_params_ee
|
||||
end
|
||||
post ':id/protected_tags' do
|
||||
authorize!(:create_protected_tags, user_project)
|
||||
protected_tags_params = {
|
||||
name: params[:name],
|
||||
create_access_levels_attributes: ::ProtectedRefs::AccessLevelParams.new(:create, params).access_levels
|
||||
|
|
@ -108,9 +109,14 @@ module API
|
|||
end
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
delete ':id/protected_tags/:name', requirements: TAG_ENDPOINT_REQUIREMENTS do
|
||||
authorize!(:destroy_protected_tags, user_project)
|
||||
|
||||
protected_tag = user_project.protected_tags.find_by!(name: params[:name])
|
||||
|
||||
destroy_conditionally!(protected_tag)
|
||||
destroy_conditionally!(protected_tag) do
|
||||
destroy_service = ::ProtectedTags::DestroyService.new(user_project, current_user)
|
||||
destroy_service.execute(protected_tag)
|
||||
end
|
||||
end
|
||||
# rubocop: enable CodeReuse/ActiveRecord
|
||||
end
|
||||
|
|
|
|||
|
|
@ -82,16 +82,10 @@ RSpec.describe 'Group Package and registry settings', feature_category: :package
|
|||
wait_for_requests
|
||||
|
||||
within_testid 'maven-settings' do
|
||||
expect(page).to have_field _('Exceptions')
|
||||
|
||||
click_button class: 'gl-toggle'
|
||||
|
||||
expect(page).to have_field _('Exceptions'), disabled: false
|
||||
|
||||
visit_settings_page
|
||||
|
||||
expect(page).to have_field _('Exceptions'), disabled: false
|
||||
end
|
||||
|
||||
expect(find('.gl-toast')).to have_content('Settings saved successfully.')
|
||||
end
|
||||
|
||||
it 'shows an error on wrong regex', :js do
|
||||
|
|
@ -101,7 +95,7 @@ RSpec.describe 'Group Package and registry settings', feature_category: :package
|
|||
within_testid 'maven-settings' do
|
||||
click_button class: 'gl-toggle'
|
||||
|
||||
fill_in _('Exceptions'), with: ')'
|
||||
fill_in class: 'gl-form-input', with: ')'
|
||||
|
||||
# simulate blur event
|
||||
send_keys(:tab)
|
||||
|
|
@ -110,64 +104,16 @@ RSpec.describe 'Group Package and registry settings', feature_category: :package
|
|||
expect(page).to have_content('is an invalid regexp')
|
||||
end
|
||||
|
||||
context 'when packages_allow_duplicate_exceptions disabled' do
|
||||
before do
|
||||
stub_feature_flags(packages_allow_duplicate_exceptions: false)
|
||||
end
|
||||
|
||||
it 'automatically saves changes to the server', :js do
|
||||
visit_settings_page
|
||||
wait_for_requests
|
||||
|
||||
within_testid 'maven-settings' do
|
||||
expect(page).to have_field _('Exceptions'), disabled: true
|
||||
|
||||
click_button class: 'gl-toggle'
|
||||
|
||||
expect(page).to have_field _('Exceptions'), disabled: false
|
||||
|
||||
visit_settings_page
|
||||
|
||||
expect(page).to have_field _('Exceptions'), disabled: false
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'in a sub group' do
|
||||
it 'works correctly', :js do
|
||||
it 'automatically saves changes to the server', :js do
|
||||
visit_sub_group_settings_page
|
||||
wait_for_requests
|
||||
|
||||
within_testid 'maven-settings' do
|
||||
expect(page).to have_content('Allow duplicates')
|
||||
|
||||
expect(page).to have_field _('Exceptions')
|
||||
|
||||
click_button class: 'gl-toggle'
|
||||
|
||||
expect(page).to have_field _('Exceptions'), disabled: false
|
||||
end
|
||||
end
|
||||
|
||||
context 'when packages_allow_duplicate_exceptions disabled' do
|
||||
before do
|
||||
stub_feature_flags(packages_allow_duplicate_exceptions: false)
|
||||
end
|
||||
|
||||
it 'works correctly', :js do
|
||||
visit_sub_group_settings_page
|
||||
wait_for_requests
|
||||
|
||||
within_testid 'maven-settings' do
|
||||
expect(page).to have_content('Allow duplicates')
|
||||
|
||||
expect(page).to have_field _('Exceptions'), disabled: true
|
||||
|
||||
click_button class: 'gl-toggle'
|
||||
|
||||
expect(page).to have_field _('Exceptions'), disabled: false
|
||||
end
|
||||
end
|
||||
expect(find('.gl-toast')).to have_content('Settings saved successfully.')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ describe('Exceptions Input', () => {
|
|||
let wrapper;
|
||||
|
||||
const defaultProps = {
|
||||
duplicatesAllowed: false,
|
||||
duplicateExceptionRegex: 'foo',
|
||||
id: 'maven-duplicated-settings-regex-input',
|
||||
name: 'exceptionModel',
|
||||
|
|
|
|||
|
|
@ -37,9 +37,6 @@ describe('Packages Settings', () => {
|
|||
const mountComponent = ({
|
||||
mountFn = shallowMountExtended,
|
||||
mutationResolver = jest.fn().mockResolvedValue(groupPackageSettingsMutationMock()),
|
||||
features = {
|
||||
packagesAllowDuplicateExceptions: false,
|
||||
},
|
||||
} = {}) => {
|
||||
Vue.use(VueApollo);
|
||||
|
||||
|
|
@ -49,10 +46,7 @@ describe('Packages Settings', () => {
|
|||
|
||||
wrapper = mountFn(component, {
|
||||
apolloProvider,
|
||||
provide: {
|
||||
...defaultProvide,
|
||||
glFeatures: features,
|
||||
},
|
||||
provide: defaultProvide,
|
||||
propsData: {
|
||||
packageSettings,
|
||||
},
|
||||
|
|
@ -141,12 +135,11 @@ describe('Packages Settings', () => {
|
|||
it('renders ExceptionsInput and assigns duplication allowness and exception props', () => {
|
||||
mountComponent({ mountFn: mountExtended });
|
||||
|
||||
const { mavenDuplicatesAllowed, mavenDuplicateExceptionRegex } = packageSettings;
|
||||
const { mavenDuplicateExceptionRegex } = packageSettings;
|
||||
|
||||
expect(findMavenDuplicatedSettingsExceptionsInput().exists()).toBe(true);
|
||||
|
||||
expect(findMavenDuplicatedSettingsExceptionsInput().props()).toMatchObject({
|
||||
duplicatesAllowed: mavenDuplicatesAllowed,
|
||||
duplicateExceptionRegex: mavenDuplicateExceptionRegex,
|
||||
duplicateExceptionRegexError: '',
|
||||
loading: false,
|
||||
|
|
@ -155,28 +148,6 @@ describe('Packages Settings', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('with packagesAllowDuplicateExceptions FF enabled', () => {
|
||||
it('renders ExceptionsInput and assigns duplication allowness and exception props', () => {
|
||||
mountComponent({
|
||||
mountFn: mountExtended,
|
||||
features: { packagesAllowDuplicateExceptions: true },
|
||||
});
|
||||
|
||||
const { mavenDuplicateExceptionRegex } = packageSettings;
|
||||
|
||||
expect(findMavenDuplicatedSettingsExceptionsInput().exists()).toBe(true);
|
||||
|
||||
expect(findMavenDuplicatedSettingsExceptionsInput().props()).toMatchObject({
|
||||
duplicatesAllowed: false,
|
||||
duplicateExceptionRegex: mavenDuplicateExceptionRegex,
|
||||
duplicateExceptionRegexError: '',
|
||||
loading: false,
|
||||
name: 'mavenDuplicateExceptionRegex',
|
||||
id: 'maven-duplicated-settings-regex-input',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('on update event calls the mutation', () => {
|
||||
const mutationResolver = jest.fn().mockResolvedValue(groupPackageSettingsMutationMock());
|
||||
mountComponent({ mountFn: mountExtended, mutationResolver });
|
||||
|
|
@ -215,10 +186,9 @@ describe('Packages Settings', () => {
|
|||
it('renders ExceptionsInput and assigns duplication allowness and exception props', () => {
|
||||
mountComponent({ mountFn: mountExtended });
|
||||
|
||||
const { genericDuplicatesAllowed, genericDuplicateExceptionRegex } = packageSettings;
|
||||
const { genericDuplicateExceptionRegex } = packageSettings;
|
||||
|
||||
expect(findGenericDuplicatedSettingsExceptionsInput().props()).toMatchObject({
|
||||
duplicatesAllowed: genericDuplicatesAllowed,
|
||||
duplicateExceptionRegex: genericDuplicateExceptionRegex,
|
||||
duplicateExceptionRegexError: '',
|
||||
loading: false,
|
||||
|
|
@ -227,26 +197,6 @@ describe('Packages Settings', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('with packagesAllowDuplicateExceptions FF enabled', () => {
|
||||
it('renders ExceptionsInput and assigns duplication allowness and exception props', () => {
|
||||
mountComponent({
|
||||
mountFn: mountExtended,
|
||||
features: { packagesAllowDuplicateExceptions: true },
|
||||
});
|
||||
|
||||
const { genericDuplicateExceptionRegex } = packageSettings;
|
||||
|
||||
expect(findGenericDuplicatedSettingsExceptionsInput().props()).toMatchObject({
|
||||
duplicatesAllowed: false,
|
||||
duplicateExceptionRegex: genericDuplicateExceptionRegex,
|
||||
duplicateExceptionRegexError: '',
|
||||
loading: false,
|
||||
name: 'genericDuplicateExceptionRegex',
|
||||
id: 'generic-duplicated-settings-regex-input',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('on update event calls the mutation', () => {
|
||||
const mutationResolver = jest.fn().mockResolvedValue(groupPackageSettingsMutationMock());
|
||||
mountComponent({ mountFn: mountExtended, mutationResolver });
|
||||
|
|
@ -287,10 +237,9 @@ describe('Packages Settings', () => {
|
|||
it('renders ExceptionsInput and assigns duplication allowness and exception props', () => {
|
||||
mountComponent({ mountFn: mountExtended });
|
||||
|
||||
const { nugetDuplicatesAllowed, nugetDuplicateExceptionRegex } = packageSettings;
|
||||
const { nugetDuplicateExceptionRegex } = packageSettings;
|
||||
|
||||
expect(findNugetDuplicatedSettingsExceptionsInput().props()).toMatchObject({
|
||||
duplicatesAllowed: nugetDuplicatesAllowed,
|
||||
duplicateExceptionRegex: nugetDuplicateExceptionRegex,
|
||||
duplicateExceptionRegexError: '',
|
||||
loading: false,
|
||||
|
|
@ -338,11 +287,9 @@ describe('Packages Settings', () => {
|
|||
it('renders ExceptionsInput and assigns duplication allowness and exception props', () => {
|
||||
mountComponent({ mountFn: mountExtended });
|
||||
|
||||
const { terraformModuleDuplicatesAllowed, terraformModuleDuplicateExceptionRegex } =
|
||||
packageSettings;
|
||||
const { terraformModuleDuplicateExceptionRegex } = packageSettings;
|
||||
|
||||
expect(findTerraformModuleDuplicatedSettingsExceptionsInput().props()).toMatchObject({
|
||||
duplicatesAllowed: terraformModuleDuplicatesAllowed,
|
||||
duplicateExceptionRegex: terraformModuleDuplicateExceptionRegex,
|
||||
duplicateExceptionRegexError: '',
|
||||
loading: false,
|
||||
|
|
@ -351,26 +298,6 @@ describe('Packages Settings', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('with packagesAllowDuplicateExceptions FF enabled', () => {
|
||||
it('renders ExceptionsInput and assigns duplication allowness and exception props', () => {
|
||||
mountComponent({
|
||||
mountFn: mountExtended,
|
||||
features: { packagesAllowDuplicateExceptions: true },
|
||||
});
|
||||
|
||||
const { terraformModuleDuplicateExceptionRegex } = packageSettings;
|
||||
|
||||
expect(findTerraformModuleDuplicatedSettingsExceptionsInput().props()).toMatchObject({
|
||||
duplicatesAllowed: false,
|
||||
duplicateExceptionRegex: terraformModuleDuplicateExceptionRegex,
|
||||
duplicateExceptionRegexError: '',
|
||||
loading: false,
|
||||
name: 'terraformModuleDuplicateExceptionRegex',
|
||||
id: 'terraform-module-duplicated-settings-regex-input',
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('on update event calls the mutation', () => {
|
||||
const mutationResolver = jest.fn().mockResolvedValue(groupPackageSettingsMutationMock());
|
||||
mountComponent({ mountFn: mountExtended, mutationResolver });
|
||||
|
|
|
|||
|
|
@ -535,19 +535,48 @@ RSpec.describe Ci::Runner, type: :model, factory_default: :keep, feature_categor
|
|||
end
|
||||
|
||||
context 'with project runner' do
|
||||
let(:runner) { create(:ci_runner, :project, projects: [other_project]) }
|
||||
let_it_be_with_refind(:owner_project) { create(:project, group: group) }
|
||||
let_it_be_with_reload(:fallback_owner_project) { create(:project, group: group) }
|
||||
|
||||
let(:associated_projects) { [owner_project, fallback_owner_project] }
|
||||
let(:runner) { create(:ci_runner, :project, projects: associated_projects) }
|
||||
|
||||
it 'assigns runner to project' do
|
||||
expect(assign_to).to be_truthy
|
||||
|
||||
expect(runner).to be_project_type
|
||||
expect(runner.runner_projects.pluck(:project_id)).to contain_exactly(project.id, other_project.id)
|
||||
expect(runner.runner_projects.pluck(:project_id))
|
||||
.to contain_exactly(project.id, owner_project.id, fallback_owner_project.id)
|
||||
end
|
||||
|
||||
it 'does not change sharding_key_id or owner' do
|
||||
expect { assign_to }
|
||||
.to not_change { runner.sharding_key_id }.from(other_project.id)
|
||||
.and not_change { runner.owner }.from(other_project)
|
||||
.to not_change { runner.sharding_key_id }.from(owner_project.id)
|
||||
.and not_change { runner.owner }.from(owner_project)
|
||||
end
|
||||
|
||||
context 'when sharding_key_id does not point to an existing project' do
|
||||
subject(:assign_to) do
|
||||
owner_project.destroy!
|
||||
|
||||
runner.assign_to(project)
|
||||
end
|
||||
|
||||
it 'changes sharding_key_id and owner to fallback owner project' do
|
||||
expect { assign_to }
|
||||
.to change { runner.sharding_key_id }.from(owner_project.id).to(fallback_owner_project.id)
|
||||
.and change { runner.owner }.from(owner_project).to(fallback_owner_project)
|
||||
end
|
||||
|
||||
context 'and fallback does not exist' do
|
||||
let(:associated_projects) { [owner_project] }
|
||||
|
||||
it 'changes sharding_key_id and owner to newly-assigned project' do
|
||||
expect { assign_to }
|
||||
.to change { runner.sharding_key_id }.from(owner_project.id).to(project.id)
|
||||
.and change { runner.owner }.from(owner_project).to(project)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -142,41 +142,6 @@ RSpec.describe Namespace::PackageSetting, feature_category: :package_registry do
|
|||
end
|
||||
end
|
||||
|
||||
context 'with packages_allow_duplicate_exceptions disabled' do
|
||||
before do
|
||||
stub_feature_flags(packages_allow_duplicate_exceptions: false)
|
||||
end
|
||||
|
||||
context 'package types with package_settings' do
|
||||
Namespace::PackageSetting::PACKAGES_WITH_SETTINGS.each do |package_type|
|
||||
context "with package_type: #{package_type}" do
|
||||
let_it_be(:package) { create("#{package_type}_package", package_name_and_version(package_type)) }
|
||||
let_it_be(:package_type) { package.package_type }
|
||||
let_it_be(:package_setting) { package.project.namespace.package_settings }
|
||||
|
||||
where(:duplicates_allowed, :duplicate_exception_regex, :result) do
|
||||
true | '' | true
|
||||
false | '' | false
|
||||
false | '.*' | true
|
||||
false | 'fo.*' | true
|
||||
false | '.*be.*' | true
|
||||
end
|
||||
|
||||
with_them do
|
||||
before do
|
||||
package_setting.update!(
|
||||
"#{package_type}_duplicates_allowed" => duplicates_allowed,
|
||||
"#{package_type}_duplicate_exception_regex" => duplicate_exception_regex
|
||||
)
|
||||
end
|
||||
|
||||
it { is_expected.to be(result) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'package types without package_settings'
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -562,44 +562,6 @@ RSpec.describe API::GenericPackages, feature_category: :package_registry do
|
|||
|
||||
it_behaves_like 'returns a bad request'
|
||||
end
|
||||
|
||||
context 'with packages_allow_duplicate_exceptions disabled' do
|
||||
before do
|
||||
stub_feature_flags(packages_allow_duplicate_exceptions: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'returns a bad request'
|
||||
|
||||
context 'when regex matches package name' do
|
||||
before do
|
||||
package_settings.update_column(
|
||||
:generic_duplicate_exception_regex,
|
||||
".*#{existing_package.name.last(3)}.*"
|
||||
)
|
||||
end
|
||||
|
||||
it_behaves_like 'creates a new package'
|
||||
end
|
||||
|
||||
context 'when regex matches package version' do
|
||||
before do
|
||||
package_settings.update_column(
|
||||
:generic_duplicate_exception_regex,
|
||||
".*#{existing_package.version.last(3)}.*"
|
||||
)
|
||||
end
|
||||
|
||||
it_behaves_like 'creates a new package'
|
||||
end
|
||||
|
||||
context 'when regex does not match package name or version' do
|
||||
before do
|
||||
package_settings.update_column(:generic_duplicate_exception_regex, ".*zzz.*")
|
||||
end
|
||||
|
||||
it_behaves_like 'returns a bad request'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when package duplicates are allowed' do
|
||||
|
|
@ -638,44 +600,6 @@ RSpec.describe API::GenericPackages, feature_category: :package_registry do
|
|||
|
||||
it_behaves_like 'creates a new package'
|
||||
end
|
||||
|
||||
context 'with packages_allow_duplicate_exceptions disabled' do
|
||||
before do
|
||||
stub_feature_flags(packages_allow_duplicate_exceptions: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'creates a new package'
|
||||
|
||||
context 'when regex matches package name' do
|
||||
before do
|
||||
package_settings.update_column(
|
||||
:generic_duplicate_exception_regex,
|
||||
".*#{existing_package.name.last(3)}.*"
|
||||
)
|
||||
end
|
||||
|
||||
it_behaves_like 'creates a new package'
|
||||
end
|
||||
|
||||
context 'when regex matches package version' do
|
||||
before do
|
||||
package_settings.update_column(
|
||||
:generic_duplicate_exception_regex,
|
||||
".*#{existing_package.version.last(3)}.*"
|
||||
)
|
||||
end
|
||||
|
||||
it_behaves_like 'creates a new package'
|
||||
end
|
||||
|
||||
context 'when regex does not match package name or version' do
|
||||
before do
|
||||
package_settings.update_column(:generic_duplicate_exception_regex, ".*zzz.*")
|
||||
end
|
||||
|
||||
it_behaves_like 'creates a new package'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'marked as pending_destruction' do
|
||||
|
|
|
|||
|
|
@ -119,14 +119,6 @@ RSpec.describe Packages::Generic::CreatePackageFileService, feature_category: :p
|
|||
end
|
||||
|
||||
it_behaves_like 'allows creating the file'
|
||||
|
||||
context 'when packages_allow_duplicate_exceptions is disabled' do
|
||||
before do
|
||||
stub_feature_flags(packages_allow_duplicate_exceptions: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'allows creating the file'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -143,14 +135,6 @@ RSpec.describe Packages::Generic::CreatePackageFileService, feature_category: :p
|
|||
end
|
||||
|
||||
it_behaves_like 'does not allow duplicates'
|
||||
|
||||
context 'when packages_allow_duplicate_exceptions is disabled' do
|
||||
before do
|
||||
stub_feature_flags(packages_allow_duplicate_exceptions: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'allows creating the file'
|
||||
end
|
||||
end
|
||||
|
||||
context 'with multiple files for the same package and the same pipeline' do
|
||||
|
|
|
|||
|
|
@ -55,14 +55,6 @@ RSpec.describe Packages::Maven::FindOrCreatePackageService, feature_category: :p
|
|||
end
|
||||
end
|
||||
|
||||
shared_examples 'reuse existing package when packages_allow_duplicate_exceptions is disabled' do
|
||||
before do
|
||||
stub_feature_flags(packages_allow_duplicate_exceptions: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'reuse existing package'
|
||||
end
|
||||
|
||||
context 'with path including version' do
|
||||
# Note that "path with version" and "file type maven metadata xml" only exists for snapshot versions
|
||||
# In other words, we will never have an metadata xml upload on a path with version for a non snapshot version
|
||||
|
|
@ -237,8 +229,6 @@ RSpec.describe Packages::Maven::FindOrCreatePackageService, feature_category: :p
|
|||
end
|
||||
|
||||
it_behaves_like 'returning an error', with_message: 'Duplicate package is not allowed'
|
||||
|
||||
it_behaves_like 'reuse existing package when packages_allow_duplicate_exceptions is disabled'
|
||||
end
|
||||
|
||||
context 'when the package version matches the exception regex' do
|
||||
|
|
@ -247,8 +237,6 @@ RSpec.describe Packages::Maven::FindOrCreatePackageService, feature_category: :p
|
|||
end
|
||||
|
||||
it_behaves_like 'returning an error', with_message: 'Duplicate package is not allowed'
|
||||
|
||||
it_behaves_like 'reuse existing package when packages_allow_duplicate_exceptions is disabled'
|
||||
end
|
||||
|
||||
context 'when the exception regex is blank' do
|
||||
|
|
|
|||
|
|
@ -94,15 +94,6 @@ RSpec.describe Packages::TerraformModule::CreatePackageService, feature_category
|
|||
|
||||
it_behaves_like 'duplicate package error'
|
||||
it_behaves_like 'with duplicate regex exception, allow creation of matching package'
|
||||
|
||||
context 'when packages_allow_duplicate_exceptions is disabled' do
|
||||
before do
|
||||
stub_feature_flags(packages_allow_duplicate_exceptions: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'duplicate package error'
|
||||
it_behaves_like 'with duplicate regex exception, allow creation of matching package'
|
||||
end
|
||||
end
|
||||
|
||||
context 'when duplicates allowed' do
|
||||
|
|
@ -112,14 +103,6 @@ RSpec.describe Packages::TerraformModule::CreatePackageService, feature_category
|
|||
|
||||
it_behaves_like 'creating a package'
|
||||
it_behaves_like 'with duplicate regex exception, prevent creation of matching package'
|
||||
|
||||
context 'when packages_allow_duplicate_exceptions is disabled' do
|
||||
before do
|
||||
stub_feature_flags(packages_allow_duplicate_exceptions: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'creating a package'
|
||||
end
|
||||
end
|
||||
|
||||
context 'for ancestor namespace' do
|
||||
|
|
@ -147,14 +130,6 @@ RSpec.describe Packages::TerraformModule::CreatePackageService, feature_category
|
|||
end
|
||||
|
||||
it_behaves_like 'duplicate package error'
|
||||
|
||||
context 'with packages_allow_duplicate_exceptions disabled' do
|
||||
before do
|
||||
stub_feature_flags(packages_allow_duplicate_exceptions: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'creating a package'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue