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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-07-26 15:10:08 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-07-26 15:10:08 +0300
commitc4af99d56fdef59d1da557d88a334f52e7531eb3 (patch)
tree10425fe4cbe9ceff8f567c5e1ebb0eea125afdd4
parentec3483bd1831dfca0c7baec0f8aad9079d28907d (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.rubocop_manual_todo.yml49
-rw-r--r--app/assets/javascripts/lib/dompurify.js17
-rw-r--r--app/assets/javascripts/security_configuration/components/upgrade_banner.vue22
-rw-r--r--app/controllers/projects/jobs_controller.rb26
-rw-r--r--app/graphql/types/access_level_type.rb2
-rw-r--r--app/graphql/types/admin/analytics/usage_trends/measurement_type.rb2
-rw-r--r--app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb6
-rw-r--r--app/graphql/types/alert_management/alert_status_counts_type.rb6
-rw-r--r--app/graphql/types/alert_management/alert_type.rb22
-rw-r--r--app/graphql/types/alert_management/integration_type.rb12
-rw-r--r--app/graphql/types/award_emojis/award_emoji_type.rb10
-rw-r--r--app/graphql/types/blob_viewer_type.rb12
-rw-r--r--app/graphql/types/board_list_type.rb12
-rw-r--r--app/graphql/types/board_type.rb12
-rw-r--r--app/graphql/types/boards/board_issuable_input_base_type.rb6
-rw-r--r--app/graphql/types/boards/board_issue_input_base_type.rb8
-rw-r--r--app/graphql/types/boards/board_issue_input_type.rb2
-rw-r--r--app/graphql/types/branch_type.rb2
-rw-r--r--app/graphql/types/ci/analytics_type.rb22
-rw-r--r--app/graphql/types/ci/application_setting_type.rb2
-rw-r--r--app/graphql/types/ci/build_need_type.rb4
-rw-r--r--app/graphql/types/ci/ci_cd_setting_type.rb8
-rw-r--r--app/graphql/types/ci/config/config_type.rb4
-rw-r--r--app/graphql/types/ci/config/group_type.rb4
-rw-r--r--app/graphql/types/ci/config/job_restriction_type.rb2
-rw-r--r--app/graphql/types/ci/config/job_type.rb20
-rw-r--r--app/graphql/types/ci/config/need_type.rb2
-rw-r--r--app/graphql/types/ci/config/stage_type.rb2
-rw-r--r--app/graphql/types/ci/detailed_status_type.rb18
-rw-r--r--app/graphql/types/ci/group_type.rb6
-rw-r--r--app/graphql/types/ci/job_artifact_type.rb2
-rw-r--r--app/graphql/types/ci/job_type.rb34
-rw-r--r--app/graphql/types/ci/pipeline_type.rb30
-rw-r--r--app/graphql/types/ci/recent_failures_type.rb4
-rw-r--r--app/graphql/types/ci/runner_architecture_type.rb4
-rw-r--r--app/graphql/types/ci/runner_platform_type.rb4
-rw-r--r--app/graphql/types/ci/runner_setup_type.rb4
-rw-r--r--app/graphql/types/ci/runner_type.rb24
-rw-r--r--app/graphql/types/ci/stage_type.rb6
-rw-r--r--app/graphql/types/ci/status_action_type.rb12
-rw-r--r--app/graphql/types/ci/template_type.rb4
-rw-r--r--app/graphql/types/ci/test_case_type.rb12
-rw-r--r--app/graphql/types/ci/test_report_total_type.rb12
-rw-r--r--app/graphql/types/ci/test_suite_summary_type.rb16
-rw-r--r--app/graphql/types/ci/test_suite_type.rb14
-rw-r--r--app/graphql/types/ci_configuration/sast/analyzers_entity_input_type.rb4
-rw-r--r--app/graphql/types/ci_configuration/sast/analyzers_entity_type.rb8
-rw-r--r--app/graphql/types/ci_configuration/sast/entity_input_type.rb6
-rw-r--r--app/graphql/types/ci_configuration/sast/entity_type.rb12
-rw-r--r--app/graphql/types/ci_configuration/sast/options_entity_type.rb4
-rw-r--r--app/graphql/types/commit_action_type.rb10
-rw-r--r--app/graphql/types/commit_type.rb22
-rw-r--r--app/graphql/types/container_expiration_policy_type.rb2
-rw-r--r--app/graphql/types/container_repository_tag_type.rb14
-rw-r--r--app/graphql/types/container_repository_type.rb12
-rw-r--r--app/graphql/types/countable_connection_type.rb2
-rw-r--r--app/graphql/types/custom_emoji_type.rb6
-rw-r--r--app/models/concerns/project_features_compatibility.rb11
-rw-r--r--app/models/namespace.rb32
-rw-r--r--app/models/project.rb27
-rw-r--r--app/models/project_feature.rb20
-rw-r--r--app/services/ci/build_cancel_service.rb35
-rw-r--r--app/services/ci/build_unschedule_service.rb35
-rw-r--r--app/workers/container_expiration_policies/cleanup_container_repository_worker.rb13
-rw-r--r--config/feature_flags/development/specialized_worker_for_group_lock_update_auth_recalculation.yml8
-rw-r--r--doc/administration/geo/replication/configuration.md158
-rw-r--r--doc/development/fe_guide/haml.md2
-rw-r--r--doc/development/github_importer.md3
-rw-r--r--doc/user/project/working_with_projects.md71
-rw-r--r--lib/gitlab/github_import/user_finder.rb14
-rw-r--r--locale/gitlab.pot16
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb158
-rw-r--r--spec/factories/projects.rb15
-rw-r--r--spec/frontend/security_configuration/components/upgrade_banner_spec.js4
-rw-r--r--spec/graphql/types/base_field_spec.rb32
-rw-r--r--spec/lib/gitlab/github_import/user_finder_spec.rb29
-rw-r--r--spec/lib/gitlab/subscription_portal_spec.rb2
-rw-r--r--spec/models/container_repository_spec.rb2
-rw-r--r--spec/models/namespace_spec.rb62
-rw-r--r--spec/models/project_feature_spec.rb34
-rw-r--r--spec/models/project_spec.rb32
-rw-r--r--spec/models/project_team_spec.rb2
-rw-r--r--spec/services/ci/build_cancel_service_spec.rb52
-rw-r--r--spec/services/ci/build_unschedule_service_spec.rb52
-rw-r--r--spec/workers/container_expiration_policies/cleanup_container_repository_worker_spec.rb17
85 files changed, 957 insertions, 587 deletions
diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml
index 4f8358977e3..170c5264372 100644
--- a/.rubocop_manual_todo.yml
+++ b/.rubocop_manual_todo.yml
@@ -28,55 +28,6 @@ Graphql/OldTypes:
Exclude:
- 'spec/**/*.rb'
- 'ee/spec/**/*.rb'
- - 'app/graphql/types/access_level_type.rb'
- - 'app/graphql/types/admin/analytics/usage_trends/measurement_type.rb'
- - 'app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb'
- - 'app/graphql/types/alert_management/alert_status_counts_type.rb'
- - 'app/graphql/types/alert_management/alert_type.rb'
- - 'app/graphql/types/alert_management/integration_type.rb'
- - 'app/graphql/types/award_emojis/award_emoji_type.rb'
- - 'app/graphql/types/blob_viewer_type.rb'
- - 'app/graphql/types/board_list_type.rb'
- - 'app/graphql/types/board_type.rb'
- - 'app/graphql/types/boards/board_issuable_input_base_type.rb'
- - 'app/graphql/types/boards/board_issue_input_base_type.rb'
- - 'app/graphql/types/boards/board_issue_input_type.rb'
- - 'app/graphql/types/branch_type.rb'
- - 'app/graphql/types/ci/application_setting_type.rb'
- - 'app/graphql/types/ci/build_need_type.rb'
- - 'app/graphql/types/ci/ci_cd_setting_type.rb'
- - 'app/graphql/types/ci/config/config_type.rb'
- - 'app/graphql/types/ci/config/group_type.rb'
- - 'app/graphql/types/ci/config/job_type.rb'
- - 'app/graphql/types/ci/config/need_type.rb'
- - 'app/graphql/types/ci/config/stage_type.rb'
- - 'app/graphql/types/ci/detailed_status_type.rb'
- - 'app/graphql/types/ci/group_type.rb'
- - 'app/graphql/types/ci/job_artifact_type.rb'
- - 'app/graphql/types/ci/job_type.rb'
- - 'app/graphql/types/ci/pipeline_type.rb'
- - 'app/graphql/types/ci/recent_failures_type.rb'
- - 'app/graphql/types/ci/runner_architecture_type.rb'
- - 'app/graphql/types/ci/runner_platform_type.rb'
- - 'app/graphql/types/ci/runner_setup_type.rb'
- - 'app/graphql/types/ci/runner_type.rb'
- - 'app/graphql/types/ci/stage_type.rb'
- - 'app/graphql/types/ci/status_action_type.rb'
- - 'app/graphql/types/ci/template_type.rb'
- - 'app/graphql/types/ci/test_case_type.rb'
- - 'app/graphql/types/ci/test_report_total_type.rb'
- - 'app/graphql/types/ci/test_suite_summary_type.rb'
- - 'app/graphql/types/ci/test_suite_type.rb'
- - 'app/graphql/types/ci_configuration/sast/analyzers_entity_input_type.rb'
- - 'app/graphql/types/ci_configuration/sast/analyzers_entity_type.rb'
- - 'app/graphql/types/ci_configuration/sast/entity_input_type.rb'
- - 'app/graphql/types/ci_configuration/sast/entity_type.rb'
- - 'app/graphql/types/ci_configuration/sast/options_entity_type.rb'
- - 'app/graphql/types/container_expiration_policy_type.rb'
- - 'app/graphql/types/container_repository_tag_type.rb'
- - 'app/graphql/types/container_repository_type.rb'
- - 'app/graphql/types/countable_connection_type.rb'
- - 'app/graphql/types/custom_emoji_type.rb'
- 'ee/app/graphql/ee/mutations/ci/ci_cd_settings_update.rb'
- 'ee/app/graphql/ee/resolvers/issues_resolver.rb'
- 'ee/app/graphql/ee/resolvers/namespace_projects_resolver.rb'
diff --git a/app/assets/javascripts/lib/dompurify.js b/app/assets/javascripts/lib/dompurify.js
index 4357918672d..a026f76e51b 100644
--- a/app/assets/javascripts/lib/dompurify.js
+++ b/app/assets/javascripts/lib/dompurify.js
@@ -1,14 +1,14 @@
import { sanitize as dompurifySanitize, addHook } from 'dompurify';
import { getBaseURL, relativePathToAbsolute } from '~/lib/utils/url_utility';
-// Safely allow SVG <use> tags
-
const defaultConfig = {
+ // Safely allow SVG <use> tags
ADD_TAGS: ['use'],
+ // Prevent possible XSS attacks with data-* attributes used by @rails/ujs
+ // See https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1421
+ FORBID_ATTR: ['data-remote', 'data-url', 'data-type', 'data-method'],
};
-const forbiddenDataAttrs = ['data-remote', 'data-url', 'data-type', 'data-method'];
-
// Only icons urls from `gon` are allowed
const getAllowedIconUrls = (gon = window.gon) =>
[gon.sprite_file_icons, gon.sprite_icons].filter(Boolean);
@@ -46,19 +46,10 @@ const sanitizeSvgIcon = (node) => {
removeUnsafeHref(node, 'xlink:href');
};
-const sanitizeHTMLAttributes = (node) => {
- forbiddenDataAttrs.forEach((attr) => {
- if (node.hasAttribute(attr)) {
- node.removeAttribute(attr);
- }
- });
-};
-
addHook('afterSanitizeAttributes', (node) => {
if (node.tagName.toLowerCase() === 'use') {
sanitizeSvgIcon(node);
}
- sanitizeHTMLAttributes(node);
});
export const sanitize = (val, config = defaultConfig) => dompurifySanitize(val, config);
diff --git a/app/assets/javascripts/security_configuration/components/upgrade_banner.vue b/app/assets/javascripts/security_configuration/components/upgrade_banner.vue
index ca0f9e5c85a..79e6b9d7a23 100644
--- a/app/assets/javascripts/security_configuration/components/upgrade_banner.vue
+++ b/app/assets/javascripts/security_configuration/components/upgrade_banner.vue
@@ -8,20 +8,18 @@ export default {
},
inject: ['upgradePath'],
i18n: {
- title: s__('SecurityConfiguration|Secure your project with Ultimate'),
+ title: s__('SecurityConfiguration|Secure your project'),
bodyStart: s__(
- `SecurityConfiguration|GitLab Ultimate checks your application for security vulnerabilities
- that may lead to unauthorized access, data leaks, and denial of service
- attacks. Its features include:`,
+ `SecurityConfiguration|Immediately begin risk analysis and remediation with application security features. Start with SAST and Secret Detection, available to all plans. Upgrade to Ultimate to get all features, including:`,
),
bodyListItems: [
- s__('SecurityConfiguration|Vulnerability details and statistics in the merge request.'),
- s__('SecurityConfiguration|High-level vulnerability statistics across projects and groups.'),
- s__('SecurityConfiguration|Runtime security metrics for application environments.'),
+ s__('SecurityConfiguration|Vulnerability details and statistics in the merge request'),
+ s__('SecurityConfiguration|High-level vulnerability statistics across projects and groups'),
+ s__('SecurityConfiguration|Runtime security metrics for application environments'),
+ s__(
+ 'SecurityConfiguration|More scan types, including Container Scanning, DAST, Dependency Scanning, Fuzzing, and Licence Compliance',
+ ),
],
- bodyEnd: s__(
- 'SecurityConfiguration|With the information provided, you can immediately begin risk analysis and remediation within GitLab.',
- ),
buttonText: s__('SecurityConfiguration|Upgrade or start a free trial'),
},
};
@@ -32,14 +30,14 @@ export default {
:title="$options.i18n.title"
:button-text="$options.i18n.buttonText"
:button-link="upgradePath"
+ variant="introduction"
v-on="$listeners"
>
<p>{{ $options.i18n.bodyStart }}</p>
- <ul>
+ <ul class="gl-pl-6">
<li v-for="bodyListItem in $options.i18n.bodyListItems" :key="bodyListItem">
{{ bodyListItem }}
</li>
</ul>
- <p>{{ $options.i18n.bodyEnd }}</p>
</gl-banner>
</template>
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index 49687a50ff6..778623a05c6 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -9,7 +9,7 @@ class Projects::JobsController < Projects::ApplicationController
before_action :authorize_read_build_trace!, only: [:trace, :raw]
before_action :authorize_read_build!
before_action :authorize_update_build!,
- except: [:index, :show, :status, :raw, :trace, :erase]
+ except: [:index, :show, :status, :raw, :trace, :erase, :cancel, :unschedule]
before_action :authorize_erase_build!, only: [:erase]
before_action :authorize_use_build_terminal!, only: [:terminal, :terminal_websocket_authorize]
before_action :verify_api_request!, only: :terminal_websocket_authorize
@@ -93,22 +93,28 @@ class Projects::JobsController < Projects::ApplicationController
end
def cancel
- return respond_422 unless @build.cancelable?
+ service_response = Ci::BuildCancelService.new(@build, current_user).execute
- @build.cancel
-
- if continue_params[:to]
- redirect_to continue_params[:to]
+ if service_response.success?
+ destination = continue_params[:to].presence || builds_project_pipeline_path(@project, @build.pipeline.id)
+ redirect_to destination
+ elsif service_response.http_status == :forbidden
+ access_denied!
else
- redirect_to builds_project_pipeline_path(@project, @build.pipeline.id)
+ head service_response.http_status
end
end
def unschedule
- return respond_422 unless @build.scheduled?
+ service_response = Ci::BuildUnscheduleService.new(@build, current_user).execute
- @build.unschedule!
- redirect_to build_path(@build)
+ if service_response.success?
+ redirect_to build_path(@build)
+ elsif service_response.http_status == :forbidden
+ access_denied!
+ else
+ head service_response.http_status
+ end
end
def status
diff --git a/app/graphql/types/access_level_type.rb b/app/graphql/types/access_level_type.rb
index 21c3669979c..2d97f6b30e8 100644
--- a/app/graphql/types/access_level_type.rb
+++ b/app/graphql/types/access_level_type.rb
@@ -6,7 +6,7 @@ module Types
graphql_name 'AccessLevel'
description 'Represents the access level of a relationship between a User and object that it is related to'
- field :integer_value, GraphQL::INT_TYPE, null: true,
+ field :integer_value, GraphQL::Types::Int, null: true,
description: 'Integer representation of access level.',
method: :to_i
diff --git a/app/graphql/types/admin/analytics/usage_trends/measurement_type.rb b/app/graphql/types/admin/analytics/usage_trends/measurement_type.rb
index c8ca702706f..c54c938402d 100644
--- a/app/graphql/types/admin/analytics/usage_trends/measurement_type.rb
+++ b/app/graphql/types/admin/analytics/usage_trends/measurement_type.rb
@@ -14,7 +14,7 @@ module Types
field :recorded_at, Types::TimeType, null: true,
description: 'The time the measurement was recorded.'
- field :count, GraphQL::INT_TYPE, null: false,
+ field :count, GraphQL::Types::Int, null: false,
description: 'Object count.'
field :identifier, Types::Admin::Analytics::UsageTrends::MeasurementIdentifierEnum, null: false,
diff --git a/app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb b/app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb
index 996300edad3..cc6e3db007b 100644
--- a/app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb
+++ b/app/graphql/types/admin/sidekiq_queues/delete_jobs_response_type.rb
@@ -10,17 +10,17 @@ module Types
description 'The response from the AdminSidekiqQueuesDeleteJobs mutation'
field :completed,
- GraphQL::BOOLEAN_TYPE,
+ GraphQL::Types::Boolean,
null: true,
description: 'Whether or not the entire queue was processed in time; if not, retrying the same request is safe.'
field :deleted_jobs,
- GraphQL::INT_TYPE,
+ GraphQL::Types::Int,
null: true,
description: 'The number of matching jobs deleted.'
field :queue_size,
- GraphQL::INT_TYPE,
+ GraphQL::Types::Int,
null: true,
description: 'The queue size after processing.'
end
diff --git a/app/graphql/types/alert_management/alert_status_counts_type.rb b/app/graphql/types/alert_management/alert_status_counts_type.rb
index 14a81735fa5..c4aedb09997 100644
--- a/app/graphql/types/alert_management/alert_status_counts_type.rb
+++ b/app/graphql/types/alert_management/alert_status_counts_type.rb
@@ -11,18 +11,18 @@ module Types
::AlertManagement::Alert.status_names.each do |status|
field status,
- GraphQL::INT_TYPE,
+ GraphQL::Types::Int,
null: true,
description: "Number of alerts with status #{status.to_s.upcase} for the project"
end
field :open,
- GraphQL::INT_TYPE,
+ GraphQL::Types::Int,
null: true,
description: 'Number of alerts with status TRIGGERED or ACKNOWLEDGED for the project.'
field :all,
- GraphQL::INT_TYPE,
+ GraphQL::Types::Int,
null: true,
description: 'Total number of alerts for the project.'
end
diff --git a/app/graphql/types/alert_management/alert_type.rb b/app/graphql/types/alert_management/alert_type.rb
index 0ff0775ca86..b8fefaee470 100644
--- a/app/graphql/types/alert_management/alert_type.rb
+++ b/app/graphql/types/alert_management/alert_type.rb
@@ -13,12 +13,12 @@ module Types
authorize :read_alert_management_alert
field :iid,
- GraphQL::ID_TYPE,
+ GraphQL::Types::ID,
null: false,
description: 'Internal ID of the alert.'
field :issue_iid,
- GraphQL::ID_TYPE,
+ GraphQL::Types::ID,
null: true,
deprecated: { reason: 'Use issue field', milestone: '13.10' },
description: 'Internal ID of the GitLab issue attached to the alert.'
@@ -29,12 +29,12 @@ module Types
description: 'Issue attached to the alert.'
field :title,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: true,
description: 'Title of the alert.'
field :description,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: true,
description: 'Description of the alert.'
@@ -50,17 +50,17 @@ module Types
method: :status_name
field :service,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: true,
description: 'Service the alert came from.'
field :monitoring_tool,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: true,
description: 'Monitoring tool the alert came from.'
field :hosts,
- [GraphQL::STRING_TYPE],
+ [GraphQL::Types::String],
null: true,
description: 'List of hosts the alert came from.'
@@ -80,7 +80,7 @@ module Types
description: 'Environment for the alert.'
field :event_count,
- GraphQL::INT_TYPE,
+ GraphQL::Types::Int,
null: true,
description: 'Number of events of this alert.',
method: :events
@@ -106,12 +106,12 @@ module Types
description: 'Assignees of the alert.'
field :metrics_dashboard_url,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: true,
description: 'URL for metrics embed for the alert.'
field :runbook,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: true,
description: 'Runbook for the alert as defined in alert details.'
@@ -122,7 +122,7 @@ module Types
resolver: Resolvers::TodoResolver
field :details_url,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: false,
description: 'The URL of the alert detail page.'
diff --git a/app/graphql/types/alert_management/integration_type.rb b/app/graphql/types/alert_management/integration_type.rb
index 6cbc17cdbfb..ca7ec99a480 100644
--- a/app/graphql/types/alert_management/integration_type.rb
+++ b/app/graphql/types/alert_management/integration_type.rb
@@ -7,7 +7,7 @@ module Types
graphql_name 'AlertManagementIntegration'
field :id,
- GraphQL::ID_TYPE,
+ GraphQL::Types::ID,
null: false,
description: 'ID of the integration.'
@@ -17,27 +17,27 @@ module Types
description: 'Type of integration.'
field :name,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: true,
description: 'Name of the integration.'
field :active,
- GraphQL::BOOLEAN_TYPE,
+ GraphQL::Types::Boolean,
null: true,
description: 'Whether the endpoint is currently accepting alerts.'
field :token,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: true,
description: 'Token used to authenticate alert notification requests.'
field :url,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: true,
description: 'Endpoint which accepts alert notifications.'
field :api_url,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: true,
description: 'URL at which Prometheus metrics can be queried to populate the metrics dashboard.'
diff --git a/app/graphql/types/award_emojis/award_emoji_type.rb b/app/graphql/types/award_emojis/award_emoji_type.rb
index 9409304e28f..1f6f0badcac 100644
--- a/app/graphql/types/award_emojis/award_emoji_type.rb
+++ b/app/graphql/types/award_emojis/award_emoji_type.rb
@@ -11,27 +11,27 @@ module Types
present_using AwardEmojiPresenter
field :name,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: false,
description: 'The emoji name.'
field :description,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: false,
description: 'The emoji description.'
field :unicode,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: false,
description: 'The emoji in Unicode.'
field :emoji,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: false,
description: 'The emoji as an icon.'
field :unicode_version,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: false,
description: 'The Unicode version for this emoji.'
diff --git a/app/graphql/types/blob_viewer_type.rb b/app/graphql/types/blob_viewer_type.rb
index 8d863c32bc7..8c565373cfd 100644
--- a/app/graphql/types/blob_viewer_type.rb
+++ b/app/graphql/types/blob_viewer_type.rb
@@ -9,30 +9,30 @@ module Types
description: 'Type of blob viewer.',
null: false
- field :load_async, GraphQL::BOOLEAN_TYPE,
+ field :load_async, GraphQL::Types::Boolean,
description: 'Shows whether the blob content is loaded asynchronously.',
null: false
- field :collapsed, GraphQL::BOOLEAN_TYPE,
+ field :collapsed, GraphQL::Types::Boolean,
description: 'Shows whether the blob should be displayed collapsed.',
method: :collapsed?,
null: false
- field :too_large, GraphQL::BOOLEAN_TYPE,
+ field :too_large, GraphQL::Types::Boolean,
description: 'Shows whether the blob is too large to be displayed.',
method: :too_large?,
null: false
- field :render_error, GraphQL::STRING_TYPE,
+ field :render_error, GraphQL::Types::String,
description: 'Error rendering the blob content.',
null: true
- field :file_type, GraphQL::STRING_TYPE,
+ field :file_type, GraphQL::Types::String,
description: 'Content file type.',
method: :partial_name,
null: false
- field :loading_partial_name, GraphQL::STRING_TYPE,
+ field :loading_partial_name, GraphQL::Types::String,
description: 'Loading partial name.',
null: false
diff --git a/app/graphql/types/board_list_type.rb b/app/graphql/types/board_list_type.rb
index dc10716dcb0..762e03973d9 100644
--- a/app/graphql/types/board_list_type.rb
+++ b/app/graphql/types/board_list_type.rb
@@ -10,19 +10,19 @@ module Types
alias_method :list, :object
- field :id, GraphQL::ID_TYPE, null: false,
+ field :id, GraphQL::Types::ID, null: false,
description: 'ID (global ID) of the list.'
- field :title, GraphQL::STRING_TYPE, null: false,
+ field :title, GraphQL::Types::String, null: false,
description: 'Title of the list.'
- field :list_type, GraphQL::STRING_TYPE, null: false,
+ field :list_type, GraphQL::Types::String, null: false,
description: 'Type of the list.'
- field :position, GraphQL::INT_TYPE, null: true,
+ field :position, GraphQL::Types::Int, null: true,
description: 'Position of list within the board.'
field :label, Types::LabelType, null: true,
description: 'Label of the list.'
- field :collapsed, GraphQL::BOOLEAN_TYPE, null: true,
+ field :collapsed, GraphQL::Types::Boolean, null: true,
description: 'Indicates if the list is collapsed for this user.'
- field :issues_count, GraphQL::INT_TYPE, null: true,
+ field :issues_count, GraphQL::Types::Int, null: true,
description: 'Count of issues in the list.'
field :issues, ::Types::IssueType.connection_type, null: true,
diff --git a/app/graphql/types/board_type.rb b/app/graphql/types/board_type.rb
index 292809b0d64..4ec9a8a9c63 100644
--- a/app/graphql/types/board_type.rb
+++ b/app/graphql/types/board_type.rb
@@ -9,15 +9,15 @@ module Types
present_using BoardPresenter
- field :id, type: GraphQL::ID_TYPE, null: false,
+ field :id, type: GraphQL::Types::ID, null: false,
description: 'ID (global ID) of the board.'
- field :name, type: GraphQL::STRING_TYPE, null: true,
+ field :name, type: GraphQL::Types::String, null: true,
description: 'Name of the board.'
- field :hide_backlog_list, type: GraphQL::BOOLEAN_TYPE, null: true,
+ field :hide_backlog_list, type: GraphQL::Types::Boolean, null: true,
description: 'Whether or not backlog list is hidden.'
- field :hide_closed_list, type: GraphQL::BOOLEAN_TYPE, null: true,
+ field :hide_closed_list, type: GraphQL::Types::Boolean, null: true,
description: 'Whether or not closed list is hidden.'
field :created_at, Types::TimeType, null: false,
@@ -33,10 +33,10 @@ module Types
resolver: Resolvers::BoardListsResolver,
extras: [:lookahead]
- field :web_path, GraphQL::STRING_TYPE, null: false,
+ field :web_path, GraphQL::Types::String, null: false,
description: 'Web path of the board.'
- field :web_url, GraphQL::STRING_TYPE, null: false,
+ field :web_url, GraphQL::Types::String, null: false,
description: 'Web URL of the board.'
end
end
diff --git a/app/graphql/types/boards/board_issuable_input_base_type.rb b/app/graphql/types/boards/board_issuable_input_base_type.rb
index 2cd057347d6..326f73846d0 100644
--- a/app/graphql/types/boards/board_issuable_input_base_type.rb
+++ b/app/graphql/types/boards/board_issuable_input_base_type.rb
@@ -4,15 +4,15 @@ module Types
module Boards
# Common arguments that we can be used to filter boards epics and issues
class BoardIssuableInputBaseType < BaseInputObject
- argument :label_name, [GraphQL::STRING_TYPE, null: true],
+ argument :label_name, [GraphQL::Types::String, null: true],
required: false,
description: 'Filter by label name.'
- argument :author_username, GraphQL::STRING_TYPE,
+ argument :author_username, GraphQL::Types::String,
required: false,
description: 'Filter by author username.'
- argument :my_reaction_emoji, GraphQL::STRING_TYPE,
+ argument :my_reaction_emoji, GraphQL::Types::String,
required: false,
description: 'Filter by reaction emoji applied by the current user.'
end
diff --git a/app/graphql/types/boards/board_issue_input_base_type.rb b/app/graphql/types/boards/board_issue_input_base_type.rb
index 30f4efcd403..983cd072ad3 100644
--- a/app/graphql/types/boards/board_issue_input_base_type.rb
+++ b/app/graphql/types/boards/board_issue_input_base_type.rb
@@ -4,19 +4,19 @@ module Types
module Boards
# rubocop: disable Graphql/AuthorizeTypes
class BoardIssueInputBaseType < BoardIssuableInputBaseType
- argument :iids, [GraphQL::STRING_TYPE],
+ argument :iids, [GraphQL::Types::String],
required: false,
description: 'List of IIDs of issues. For example `["1", "2"]`.'
- argument :milestone_title, GraphQL::STRING_TYPE,
+ argument :milestone_title, GraphQL::Types::String,
required: false,
description: 'Filter by milestone title.'
- argument :assignee_username, [GraphQL::STRING_TYPE, null: true],
+ argument :assignee_username, [GraphQL::Types::String, null: true],
required: false,
description: 'Filter by assignee username.'
- argument :release_tag, GraphQL::STRING_TYPE,
+ argument :release_tag, GraphQL::Types::String,
required: false,
description: 'Filter by release tag.'
end
diff --git a/app/graphql/types/boards/board_issue_input_type.rb b/app/graphql/types/boards/board_issue_input_type.rb
index 7580b0378fe..b4dbe87e32d 100644
--- a/app/graphql/types/boards/board_issue_input_type.rb
+++ b/app/graphql/types/boards/board_issue_input_type.rb
@@ -10,7 +10,7 @@ module Types
prepare: ->(negated_args, ctx) { negated_args.to_h },
description: 'List of negated arguments.'
- argument :search, GraphQL::STRING_TYPE,
+ argument :search, GraphQL::Types::String,
required: false,
description: 'Search query for issue title or description.'
diff --git a/app/graphql/types/branch_type.rb b/app/graphql/types/branch_type.rb
index b788ba79769..a861bcc4bb4 100644
--- a/app/graphql/types/branch_type.rb
+++ b/app/graphql/types/branch_type.rb
@@ -6,7 +6,7 @@ module Types
graphql_name 'Branch'
field :name,
- GraphQL::STRING_TYPE,
+ GraphQL::Types::String,
null: false,
description: 'Name of the branch.'
diff --git a/app/graphql/types/ci/analytics_type.rb b/app/graphql/types/ci/analytics_type.rb
index ba987b133bd..f52b9eae229 100644
--- a/app/graphql/types/ci/analytics_type.rb
+++ b/app/graphql/types/ci/analytics_type.rb
@@ -6,27 +6,27 @@ module Types
class AnalyticsType < BaseObject
graphql_name 'PipelineAnalytics'
- field :week_pipelines_totals, [GraphQL::INT_TYPE], null: true,
+ field :week_pipelines_totals, [GraphQL::Types::Int], null: true,
description: 'Total weekly pipeline count.'
- field :week_pipelines_successful, [GraphQL::INT_TYPE], null: true,
+ field :week_pipelines_successful, [GraphQL::Types::Int], null: true,
description: 'Total weekly successful pipeline count.'
- field :week_pipelines_labels, [GraphQL::STRING_TYPE], null: true,
+ field :week_pipelines_labels, [GraphQL::Types::String], null: true,
description: 'Labels for the weekly pipeline count.'
- field :month_pipelines_totals, [GraphQL::INT_TYPE], null: true,
+ field :month_pipelines_totals, [GraphQL::Types::Int], null: true,
description: 'Total monthly pipeline count.'
- field :month_pipelines_successful, [GraphQL::INT_TYPE], null: true,
+ field :month_pipelines_successful, [GraphQL::Types::Int], null: true,
description: 'Total monthly successful pipeline count.'
- field :month_pipelines_labels, [GraphQL::STRING_TYPE], null: true,
+ field :month_pipelines_labels, [GraphQL::Types::String], null: true,
description: 'Labels for the monthly pipeline count.'
- field :year_pipelines_totals, [GraphQL::INT_TYPE], null: true,
+ field :year_pipelines_totals, [GraphQL::Types::Int], null: true,
description: 'Total yearly pipeline count.'
- field :year_pipelines_successful, [GraphQL::INT_TYPE], null: true,
+ field :year_pipelines_successful, [GraphQL::Types::Int], null: true,
description: 'Total yearly successful pipeline count.'
- field :year_pipelines_labels, [GraphQL::STRING_TYPE], null: true,
+ field :year_pipelines_labels, [GraphQL::Types::String], null: true,
description: 'Labels for the yearly pipeline count.'
- field :pipeline_times_values, [GraphQL::INT_TYPE], null: true,
+ field :pipeline_times_values, [GraphQL::Types::Int], null: true,
description: 'Pipeline times.'
- field :pipeline_times_labels, [GraphQL::STRING_TYPE], null: true,
+ field :pipeline_times_labels, [GraphQL::Types::String], null: true,
description: 'Pipeline times labels.'
end
end
diff --git a/app/graphql/types/ci/application_setting_type.rb b/app/graphql/types/ci/application_setting_type.rb
index 8616280057c..2322778d159 100644
--- a/app/graphql/types/ci/application_setting_type.rb
+++ b/app/graphql/types/ci/application_setting_type.rb
@@ -7,7 +7,7 @@ module Types
authorize :read_application_setting
- field :keep_latest_artifact, GraphQL::BOOLEAN_TYPE, null: true,
+ field :keep_latest_artifact, GraphQL::Types::Boolean, null: true,
description: 'Whether to keep the latest jobs artifacts.'
end
end
diff --git a/app/graphql/types/ci/build_need_type.rb b/app/graphql/types/ci/build_need_type.rb
index 19ff758ad1d..7bd12c99a08 100644
--- a/app/graphql/types/ci/build_need_type.rb
+++ b/app/graphql/types/ci/build_need_type.rb
@@ -7,9 +7,9 @@ module Types
class BuildNeedType < BaseObject
graphql_name 'CiBuildNeed'
- field :id, GraphQL::ID_TYPE, null: false,
+ field :id, GraphQL::Types::ID, null: false,
description: 'ID of the job we need to complete.'
- field :name, GraphQL::STRING_TYPE, null: true,
+ field :name, GraphQL::Types::String, null: true,
description: 'Name of the job we need to complete.'
end
end
diff --git a/app/graphql/types/ci/ci_cd_setting_type.rb b/app/graphql/types/ci/ci_cd_setting_type.rb
index f90c75454ba..790deab8f68 100644
--- a/app/graphql/types/ci/ci_cd_setting_type.rb
+++ b/app/graphql/types/ci/ci_cd_setting_type.rb
@@ -7,16 +7,16 @@ module Types
authorize :admin_project
- field :merge_pipelines_enabled, GraphQL::BOOLEAN_TYPE, null: true,
+ field :merge_pipelines_enabled, GraphQL::Types::Boolean, null: true,
description: 'Whether merge pipelines are enabled.',
method: :merge_pipelines_enabled?
- field :merge_trains_enabled, GraphQL::BOOLEAN_TYPE, null: true,
+ field :merge_trains_enabled, GraphQL::Types::Boolean, null: true,
description: 'Whether merge trains are enabled.',
method: :merge_trains_enabled?
- field :keep_latest_artifact, GraphQL::BOOLEAN_TYPE, null: true,
+ field :keep_latest_artifact, GraphQL::Types::Boolean, null: true,
description: 'Whether to keep the latest builds artifacts.',
method: :keep_latest_artifacts_available?
- field :job_token_scope_enabled, GraphQL::BOOLEAN_TYPE, null: true,
+ field :job_token_scope_enabled, GraphQL::Types::Boolean, null: true,
description: 'Indicates CI job tokens generated in this project have restricted access to resources.',
method: :job_token_scope_enabled?
field :project, Types::ProjectType, null: true,
diff --git a/app/graphql/types/ci/config/config_type.rb b/app/graphql/types/ci/config/config_type.rb
index 88caf21c376..6ac21968bd4 100644
--- a/app/graphql/types/ci/config/config_type.rb
+++ b/app/graphql/types/ci/config/config_type.rb
@@ -7,9 +7,9 @@ module Types
class ConfigType < BaseObject
graphql_name 'CiConfig'
- field :errors, [GraphQL::STRING_TYPE], null: true,
+ field :errors, [GraphQL::Types::String], null: true,
description: 'Linting errors.'
- field :merged_yaml, GraphQL::STRING_TYPE, null: true,
+ field :merged_yaml, GraphQL::Types::String, null: true,
description: 'Merged CI configuration YAML.'
field :stages, Types::Ci::Config::StageType.connection_type, null: true,
description: 'Stages of the pipeline.'
diff --git a/app/graphql/types/ci/config/group_type.rb b/app/graphql/types/ci/config/group_type.rb
index 11be701e73f..e5cb0d4e72f 100644
--- a/app/graphql/types/ci/config/group_type.rb
+++ b/app/graphql/types/ci/config/group_type.rb
@@ -7,11 +7,11 @@ module Types
class GroupType < BaseObject
graphql_name 'CiConfigGroup'
- field :name, GraphQL::STRING_TYPE, null: true,
+ field :name, GraphQL::Types::String, null: true,
description: 'Name of the job group.'
field :jobs, Types::Ci::Config::JobType.connection_type, null: true,
description: 'Jobs in group.'
- field :size, GraphQL::INT_TYPE, null: true,
+ field :size, GraphQL::Types::Int, null: true,
description: 'Size of the job group.'
end
end
diff --git a/app/graphql/types/ci/config/job_restriction_type.rb b/app/graphql/types/ci/config/job_restriction_type.rb
index 294e3c94571..891ba18dacc 100644
--- a/app/graphql/types/ci/config/job_restriction_type.rb
+++ b/app/graphql/types/ci/config/job_restriction_type.rb
@@ -7,7 +7,7 @@ module Types
class JobRestrictionType < BaseObject
graphql_name 'CiConfigJobRestriction'
- field :refs, [GraphQL::STRING_TYPE], null: true,
+ field :refs, [GraphQL::Types::String], null: true,
description: 'The Git refs the job restriction applies to.'
end
end
diff --git a/app/graphql/types/ci/config/job_type.rb b/app/graphql/types/ci/config/job_type.rb
index 65fdc4c2615..4cf6780ef60 100644
--- a/app/graphql/types/ci/config/job_type.rb
+++ b/app/graphql/types/ci/config/job_type.rb
@@ -7,32 +7,32 @@ module Types
class JobType < BaseObject
graphql_name 'CiConfigJob'
- field :name, GraphQL::STRING_TYPE, null: true,
+ field :name, GraphQL::Types::String, null: true,
description: 'Name of the job.'
- field :group_name, GraphQL::STRING_TYPE, null: true,
+ field :group_name, GraphQL::Types::String, null: true,
description: 'Name of the job group.'
- field :stage, GraphQL::STRING_TYPE, null: true,
+ field :stage, GraphQL::Types::String, null: true,
description: 'Name of the job stage.'
field :needs, Types::Ci::Config::NeedType.connection_type, null: true,
description: 'Builds that must complete before the jobs run.'
- field :allow_failure, GraphQL::BOOLEAN_TYPE, null: true,
+ field :allow_failure, GraphQL::Types::Boolean, null: true,
description: 'Allow job to fail.'
- field :before_script, [GraphQL::STRING_TYPE], null: true,
+ field :before_script, [GraphQL::Types::String], null: true,
description: 'Override a set of commands that are executed before the job.'
- field :script, [GraphQL::STRING_TYPE], null: true,
+ field :script, [GraphQL::Types::String], null: true,
description: 'Shell script that is executed by a runner.'
- field :after_script, [GraphQL::STRING_TYPE], null: true,
+ field :after_script, [GraphQL::Types::String], null: true,
description: 'Override a set of commands that are executed after the job.'
- field :when, GraphQL::STRING_TYPE, null: true,
+ field :when, GraphQL::Types::String, null: true,
description: 'When to run the job.',
resolver_method: :restrict_when_to_run_jobs
- field :environment, GraphQL::STRING_TYPE, null: true,
+ field :environment, GraphQL::Types::String, null: true,
description: 'Name of an environment to which the job deploys.'
field :except, Types::Ci::Config::JobRestrictionType, null: true,
description: 'Limit when jobs are not created.'
field :only, Types::Ci::Config::JobRestrictionType, null: true,
description: 'Jobs are created when these conditions do not apply.'
- field :tags, [GraphQL::STRING_TYPE], null: true,
+ field :tags, [GraphQL::Types::String], null: true,
description: 'List of tags that are used to select a runner.'
def restrict_when_to_run_jobs
diff --git a/app/graphql/types/ci/config/need_type.rb b/app/graphql/types/ci/config/need_type.rb
index 01f73100409..6e9aea8eb64 100644
--- a/app/graphql/types/ci/config/need_type.rb
+++ b/app/graphql/types/ci/config/need_type.rb
@@ -7,7 +7,7 @@ module Types
class NeedType < BaseObject
graphql_name 'CiConfigNeed'
- field :name, GraphQL::STRING_TYPE, null: true,
+ field :name, GraphQL::Types::String, null: true,
description: 'Name of the need.'
end
end
diff --git a/app/graphql/types/ci/config/stage_type.rb b/app/graphql/types/ci/config/stage_type.rb
index 060efb7d45c..7e2aa9470f2 100644
--- a/app/graphql/types/ci/config/stage_type.rb
+++ b/app/graphql/types/ci/config/stage_type.rb
@@ -7,7 +7,7 @@ module Types
class StageType < BaseObject
graphql_name 'CiConfigStage'
- field :name, GraphQL::STRING_TYPE, null: true,
+ field :name, GraphQL::Types::String, null: true,
description: 'Name of the stage.'
field :groups, Types::Ci::Config::GroupType.connection_type, null: true,
description: 'Groups of jobs for the stage.'
diff --git a/app/graphql/types/ci/detailed_status_type.rb b/app/graphql/types/ci/detailed_status_type.rb
index 6310a62a103..4433e921971 100644
--- a/app/graphql/types/ci/detailed_status_type.rb
+++ b/app/graphql/types/ci/detailed_status_type.rb
@@ -6,26 +6,26 @@ module Types
class DetailedStatusType < BaseObject
graphql_name 'DetailedStatus'
- field :id, GraphQL::STRING_TYPE, null: false,
+ field :id, GraphQL::Types::String, null: false,
description: 'ID for a detailed status.',
extras: [:parent]
- field :group, GraphQL::STRING_TYPE, null: true,
+ field :group, GraphQL::Types::String, null: true,
description: 'Group of the status.'
- field :icon, GraphQL::STRING_TYPE, null: true,
+ field :icon, GraphQL::Types::String, null: true,
description: 'Icon of the status.'
- field :favicon, GraphQL::STRING_TYPE, null: true,
+ field :favicon, GraphQL::Types::String, null: true,
description: 'Favicon of the status.'
- field :details_path, GraphQL::STRING_TYPE, null: true,
+ field :details_path, GraphQL::Types::String, null: true,
description: 'Path of the details for the status.'
- field :has_details, GraphQL::BOOLEAN_TYPE, null: true,
+ field :has_details, GraphQL::Types::Boolean, null: true,
description: 'Indicates if the status has further details.',
method: :has_details?
- field :label, GraphQL::STRING_TYPE, null: true,
+ field :label, GraphQL::Types::String, null: true,
calls_gitaly: true,
description: 'Label of the status.'
- field :text, GraphQL::STRING_TYPE, null: true,
+ field :text, GraphQL::Types::String, null: true,
description: 'Text of the status.'
- field :tooltip, GraphQL::STRING_TYPE, null: true,
+ field :tooltip, GraphQL::Types::String, null: true,
description: 'Tooltip associated with the status.',
method: :status_tooltip
field :action, Types::Ci::StatusActionType, null: true,
diff --git a/app/graphql/types/ci/group_type.rb b/app/graphql/types/ci/group_type.rb
index 3da183cb842..3ae23ba9bd4 100644
--- a/app/graphql/types/ci/group_type.rb
+++ b/app/graphql/types/ci/group_type.rb
@@ -6,11 +6,11 @@ module Types
class GroupType < BaseObject
graphql_name 'CiGroup'
- field :id, GraphQL::STRING_TYPE, null: false,
+ field :id, GraphQL::Types::String, null: false,
description: 'ID for a group.'
- field :name, GraphQL::STRING_TYPE, null: true,
+ field :name, GraphQL::Types::String, null: true,
description: 'Name of the job group.'
- field :size, GraphQL::INT_TYPE, null: true,
+ field :size, GraphQL::Types::Int, null: true,
description: 'Size of the group.'
field :jobs, Ci::JobType.connection_type, null: true,
description: 'Jobs in group.'
diff --git a/app/graphql/types/ci/job_artifact_type.rb b/app/graphql/types/ci/job_artifact_type.rb
index 7dc93041b53..f80681bcf36 100644
--- a/app/graphql/types/ci/job_artifact_type.rb
+++ b/app/graphql/types/ci/job_artifact_type.rb
@@ -6,7 +6,7 @@ module Types
class JobArtifactType < BaseObject
graphql_name 'CiJobArtifact'
- field :download_path, GraphQL::STRING_TYPE, null: true,
+ field :download_path, GraphQL::Types::String, null: true,
description: "URL for downloading the artifact's file."
field :file_type, ::Types::Ci::JobArtifactFileTypeEnum, null: true,
diff --git a/app/graphql/types/ci/job_type.rb b/app/graphql/types/ci/job_type.rb
index 360ea3ba7a9..4a3518e1865 100644
--- a/app/graphql/types/ci/job_type.rb
+++ b/app/graphql/types/ci/job_type.rb
@@ -14,7 +14,7 @@ module Types
description: 'ID of the job.'
field :pipeline, Types::Ci::PipelineType, null: true,
description: 'Pipeline the job belongs to.'
- field :name, GraphQL::STRING_TYPE, null: true,
+ field :name, GraphQL::Types::String, null: true,
description: 'Name of the job.'
field :needs, BuildNeedType.connection_type, null: true,
description: 'References to builds that must complete before the jobs run.'
@@ -24,11 +24,11 @@ module Types
description: "Status of the job."
field :stage, Types::Ci::StageType, null: true,
description: 'Stage of the job.'
- field :allow_failure, ::GraphQL::BOOLEAN_TYPE, null: false,
+ field :allow_failure, ::GraphQL::Types::Boolean, null: false,
description: 'Whether the job is allowed to fail.'
- field :duration, GraphQL::INT_TYPE, null: true,
+ field :duration, GraphQL::Types::Int, null: true,
description: 'Duration of the job in seconds.'
- field :tags, [GraphQL::STRING_TYPE], null: true,
+ field :tags, [GraphQL::Types::String], null: true,
description: 'Tags for the current job.'
# Life-cycle timestamps:
@@ -53,33 +53,33 @@ module Types
description: 'Detailed status of the job.'
field :artifacts, Types::Ci::JobArtifactType.connection_type, null: true,
description: 'Artifacts generated by the job.'
- field :short_sha, type: GraphQL::STRING_TYPE, null: false,
+ field :short_sha, type: GraphQL::Types::String, null: false,
description: 'Short SHA1 ID of the commit.'
- field :scheduling_type, GraphQL::STRING_TYPE, null: true,
+ field :scheduling_type, GraphQL::Types::String, null: true,
description: 'Type of job scheduling. Value is `dag` if the job uses the `needs` keyword, and `stage` otherwise.'
- field :commit_path, GraphQL::STRING_TYPE, null: true,
+ field :commit_path, GraphQL::Types::String, null: true,
description: 'Path to the commit that triggered the job.'
- field :ref_name, GraphQL::STRING_TYPE, null: true,
+ field :ref_name, GraphQL::Types::String, null: true,
description: 'Ref name of the job.'
- field :ref_path, GraphQL::STRING_TYPE, null: true,
+ field :ref_path, GraphQL::Types::String, null: true,
description: 'Path to the ref.'
- field :playable, GraphQL::BOOLEAN_TYPE, null: false, method: :playable?,
+ field :playable, GraphQL::Types::Boolean, null: false, method: :playable?,
description: 'Indicates the job can be played.'
- field :retryable, GraphQL::BOOLEAN_TYPE, null: false, method: :retryable?,
+ field :retryable, GraphQL::Types::Boolean, null: false, method: :retryable?,
description: 'Indicates the job can be retried.'
- field :cancelable, GraphQL::BOOLEAN_TYPE, null: false, method: :cancelable?,
+ field :cancelable, GraphQL::Types::Boolean, null: false, method: :cancelable?,
description: 'Indicates the job can be canceled.'
- field :active, GraphQL::BOOLEAN_TYPE, null: false, method: :active?,
+ field :active, GraphQL::Types::Boolean, null: false, method: :active?,
description: 'Indicates the job is active.'
- field :stuck, GraphQL::BOOLEAN_TYPE, null: false, method: :stuck?,
+ field :stuck, GraphQL::Types::Boolean, null: false, method: :stuck?,
description: 'Indicates the job is stuck.'
field :coverage, GraphQL::FLOAT_TYPE, null: true,
description: 'Coverage level of the job.'
- field :created_by_tag, GraphQL::BOOLEAN_TYPE, null: false,
+ field :created_by_tag, GraphQL::Types::Boolean, null: false,
description: 'Whether the job was created by a tag.'
- field :manual_job, GraphQL::BOOLEAN_TYPE, null: true,
+ field :manual_job, GraphQL::Types::Boolean, null: true,
description: 'Whether the job has a manual action.'
- field :triggered, GraphQL::BOOLEAN_TYPE, null: true,
+ field :triggered, GraphQL::Types::Boolean, null: true,
description: 'Whether the job was triggered.'
def pipeline
diff --git a/app/graphql/types/ci/pipeline_type.rb b/app/graphql/types/ci/pipeline_type.rb
index f4a6c18f73e..0375257eb7b 100644
--- a/app/graphql/types/ci/pipeline_type.rb
+++ b/app/graphql/types/ci/pipeline_type.rb
@@ -12,25 +12,25 @@ module Types
expose_permissions Types::PermissionTypes::Ci::Pipeline
- field :id, GraphQL::ID_TYPE, null: false,
+ field :id, GraphQL::Types::ID, null: false,
description: 'ID of the pipeline.'
- field :iid, GraphQL::STRING_TYPE, null: false,
+ field :iid, GraphQL::Types::String, null: false,
description: 'Internal ID of the pipeline.'
- field :sha, GraphQL::STRING_TYPE, null: false,
+ field :sha, GraphQL::Types::String, null: false,
description: "SHA of the pipeline's commit."
- field :before_sha, GraphQL::STRING_TYPE, null: true,
+ field :before_sha, GraphQL::Types::String, null: true,
description: 'Base SHA of the source branch.'
- field :complete, GraphQL::BOOLEAN_TYPE, null: false, method: :complete?,
+ field :complete, GraphQL::Types::Boolean, null: false, method: :complete?,
description: 'Indicates if a pipeline is complete.'
field :status, PipelineStatusEnum, null: false,
description: "Status of the pipeline (#{::Ci::Pipeline.all_state_names.compact.join(', ').upcase})"
- field :warnings, GraphQL::BOOLEAN_TYPE, null: false, method: :has_warnings?,
+ field :warnings, GraphQL::Types::Boolean, null: false, method: :has_warnings?,
description: "Indicates if a pipeline has warnings."
field :detailed_status, Types::Ci::DetailedStatusType, null: false,
@@ -39,7 +39,7 @@ module Types
field :config_source, PipelineConfigSourceEnum, null: true,
description: "Configuration source of the pipeline (#{::Enums::Ci::Pipeline.config_sources.keys.join(', ').upcase})"
- field :duration, GraphQL::INT_TYPE, null: true,
+ field :duration, GraphQL::Types::Int, null: true,
description: 'Duration of the pipeline in seconds.'
field :queued_duration, Types::DurationType, null: true,
@@ -76,12 +76,12 @@ module Types
null: true,
description: 'Pipeline user.'
- field :retryable, GraphQL::BOOLEAN_TYPE,
+ field :retryable, GraphQL::Types::Boolean,
description: 'Specifies if a pipeline can be retried.',
method: :retryable?,
null: false
- field :cancelable, GraphQL::BOOLEAN_TYPE,
+ field :cancelable, GraphQL::Types::Boolean,
description: 'Specifies if a pipeline can be canceled.',
method: :cancelable?,
null: false
@@ -103,7 +103,7 @@ module Types
required: false,
description: 'ID of the job.'
argument :name,
- type: ::GraphQL::STRING_TYPE,
+ type: ::GraphQL::Types::String,
required: false,
description: 'Name of the job.'
end
@@ -122,19 +122,19 @@ module Types
description: 'Pipeline that triggered the pipeline.',
method: :triggered_by_pipeline
- field :path, GraphQL::STRING_TYPE, null: true,
+ field :path, GraphQL::Types::String, null: true,
description: "Relative path to the pipeline's page."
- field :commit_path, GraphQL::STRING_TYPE, null: true,
+ field :commit_path, GraphQL::Types::String, null: true,
description: 'Path to the commit that triggered the pipeline.'
field :project, Types::ProjectType, null: true,
description: 'Project the pipeline belongs to.'
- field :active, GraphQL::BOOLEAN_TYPE, null: false, method: :active?,
+ field :active, GraphQL::Types::Boolean, null: false, method: :active?,
description: 'Indicates if the pipeline is active.'
- field :uses_needs, GraphQL::BOOLEAN_TYPE, null: true,
+ field :uses_needs, GraphQL::Types::Boolean, null: true,
method: :uses_needs?,
description: 'Indicates if the pipeline has jobs with `needs` dependencies.'
@@ -150,7 +150,7 @@ module Types
description: 'A specific test suite in a pipeline test report.',
resolver: Resolvers::Ci::TestSuiteResolver
- field :ref, GraphQL::STRING_TYPE, null: true,
+ field :ref, GraphQL::Types::String, null: true,
description: 'Reference to the branch from which the pipeline was triggered.'
def detailed_status
diff --git a/app/graphql/types/ci/recent_failures_type.rb b/app/graphql/types/ci/recent_failures_type.rb
index eeff7222762..f56b0939086 100644
--- a/app/graphql/types/ci/recent_failures_type.rb
+++ b/app/graphql/types/ci/recent_failures_type.rb
@@ -9,10 +9,10 @@ module Types
connection_type_class(Types::CountableConnectionType)
- field :count, GraphQL::INT_TYPE, null: true,
+ field :count, GraphQL::Types::Int, null: true,
description: 'Number of times the test case has failed in the past 14 days.'
- field :base_branch, GraphQL::STRING_TYPE, null: true,
+ field :base_branch, GraphQL::Types::String, null: true,
description: 'Name of the base branch of the project.'
end
# rubocop: enable Graphql/AuthorizeTypes
diff --git a/app/graphql/types/ci/runner_architecture_type.rb b/app/graphql/types/ci/runner_architecture_type.rb
index 229974d4d13..08d3f98592b 100644
--- a/app/graphql/types/ci/runner_architecture_type.rb
+++ b/app/graphql/types/ci/runner_architecture_type.rb
@@ -6,9 +6,9 @@ module Types
class RunnerArchitectureType < BaseObject
graphql_name 'RunnerArchitecture'
- field :name, GraphQL::STRING_TYPE, null: false,
+ field :name, GraphQL::Types::String, null: false,
description: 'Name of the runner platform architecture.'
- field :download_location, GraphQL::STRING_TYPE, null: false,
+ field :download_location, GraphQL::Types::String, null: false,
description: 'Download location for the runner for the platform architecture.'
end
end
diff --git a/app/graphql/types/ci/runner_platform_type.rb b/app/graphql/types/ci/runner_platform_type.rb
index 5636f88835e..ffcf6364968 100644
--- a/app/graphql/types/ci/runner_platform_type.rb
+++ b/app/graphql/types/ci/runner_platform_type.rb
@@ -6,9 +6,9 @@ module Types
class RunnerPlatformType < BaseObject
graphql_name 'RunnerPlatform'
- field :name, GraphQL::STRING_TYPE, null: false,
+ field :name, GraphQL::Types::String, null: false,
description: 'Name slug of the runner platform.'
- field :human_readable_name, GraphQL::STRING_TYPE, null: false,
+ field :human_readable_name, GraphQL::Types::String, null: false,
description: 'Human readable name of the runner platform.'
field :architectures, Types::Ci::RunnerArchitectureType.connection_type, null: true,
description: 'Runner architectures supported for the platform.'
diff --git a/app/graphql/types/ci/runner_setup_type.rb b/app/graphql/types/ci/runner_setup_type.rb
index 61a2ea2a411..70f33cef8ad 100644
--- a/app/graphql/types/ci/runner_setup_type.rb
+++ b/app/graphql/types/ci/runner_setup_type.rb
@@ -6,9 +6,9 @@ module Types
class RunnerSetupType < BaseObject
graphql_name 'RunnerSetup'
- field :install_instructions, GraphQL::STRING_TYPE, null: false,
+ field :install_instructions, GraphQL::Types::String, null: false,
description: 'Instructions for installing the runner on the specified architecture.'
- field :register_instructions, GraphQL::STRING_TYPE, null: true,
+ field :register_instructions, GraphQL::Types::String, null: true,
description: 'Instructions for registering the runner.'
end
end
diff --git a/app/graphql/types/ci/runner_type.rb b/app/graphql/types/ci/runner_type.rb
index 9c5041b0860..7dc4d867713 100644
--- a/app/graphql/types/ci/runner_type.rb
+++ b/app/graphql/types/ci/runner_type.rb
@@ -12,38 +12,38 @@ module Types
field :id, ::Types::GlobalIDType[::Ci::Runner], null: false,
description: 'ID of the runner.'
- field :description, GraphQL::STRING_TYPE, null: true,
+ field :description, GraphQL::Types::String, null: true,
description: 'Description of the runner.'
field :contacted_at, Types::TimeType, null: true,
description: 'Last contact from the runner.',
method: :contacted_at
- field :maximum_timeout, GraphQL::INT_TYPE, null: true,
+ field :maximum_timeout, GraphQL::Types::Int, null: true,
description: 'Maximum timeout (in seconds) for jobs processed by the runner.'
field :access_level, ::Types::Ci::RunnerAccessLevelEnum, null: false,
description: 'Access level of the runner.'
- field :active, GraphQL::BOOLEAN_TYPE, null: false,
+ field :active, GraphQL::Types::Boolean, null: false,
description: 'Indicates the runner is allowed to receive jobs.'
field :status, ::Types::Ci::RunnerStatusEnum, null: false,
description: 'Status of the runner.'
- field :version, GraphQL::STRING_TYPE, null: true,
+ field :version, GraphQL::Types::String, null: true,
description: 'Version of the runner.'
- field :short_sha, GraphQL::STRING_TYPE, null: true,
+ field :short_sha, GraphQL::Types::String, null: true,
description: %q(First eight characters of the runner's token used to authenticate new job requests. Used as the runner's unique ID.)
- field :revision, GraphQL::STRING_TYPE, null: true,
+ field :revision, GraphQL::Types::String, null: true,
description: 'Revision of the runner.'
- field :locked, GraphQL::BOOLEAN_TYPE, null: true,
+ field :locked, GraphQL::Types::Boolean, null: true,
description: 'Indicates the runner is locked.'
- field :run_untagged, GraphQL::BOOLEAN_TYPE, null: false,
+ field :run_untagged, GraphQL::Types::Boolean, null: false,
description: 'Indicates the runner is able to run untagged jobs.'
- field :ip_address, GraphQL::STRING_TYPE, null: true,
+ field :ip_address, GraphQL::Types::String, null: true,
description: 'IP address of the runner.'
field :runner_type, ::Types::Ci::RunnerTypeEnum, null: false,
description: 'Type of the runner.'
- field :tag_list, [GraphQL::STRING_TYPE], null: true,
+ field :tag_list, [GraphQL::Types::String], null: true,
description: 'Tags associated with the runner.'
- field :project_count, GraphQL::INT_TYPE, null: true,
+ field :project_count, GraphQL::Types::Int, null: true,
description: 'Number of projects that the runner is associated with.'
- field :job_count, GraphQL::INT_TYPE, null: true,
+ field :job_count, GraphQL::Types::Int, null: true,
description: "Number of jobs processed by the runner (limited to #{JOB_COUNT_LIMIT}, plus one to indicate that more items exist)."
def job_count
diff --git a/app/graphql/types/ci/stage_type.rb b/app/graphql/types/ci/stage_type.rb
index ce3edb6c54f..ee8fd792bbf 100644
--- a/app/graphql/types/ci/stage_type.rb
+++ b/app/graphql/types/ci/stage_type.rb
@@ -6,9 +6,9 @@ module Types
graphql_name 'CiStage'
authorize :read_commit_status
- field :id, GraphQL::ID_TYPE, null: false,
+ field :id, GraphQL::Types::ID, null: false,
description: 'ID of the stage.'
- field :name, type: GraphQL::STRING_TYPE, null: true,
+ field :name, type: GraphQL::Types::String, null: true,
description: 'Name of the stage.'
field :groups, type: Ci::GroupType.connection_type, null: true,
extras: [:lookahead],
@@ -18,7 +18,7 @@ module Types
field :jobs, Ci::JobType.connection_type, null: true,
description: 'Jobs for the stage.',
method: 'latest_statuses'
- field :status, GraphQL::STRING_TYPE,
+ field :status, GraphQL::Types::String,
null: true,
description: 'Status of the pipeline stage.'
diff --git a/app/graphql/types/ci/status_action_type.rb b/app/graphql/types/ci/status_action_type.rb
index a06b09735b3..15e5344e130 100644
--- a/app/graphql/types/ci/status_action_type.rb
+++ b/app/graphql/types/ci/status_action_type.rb
@@ -5,19 +5,19 @@ module Types
class StatusActionType < BaseObject
graphql_name 'StatusAction'
- field :id, GraphQL::STRING_TYPE, null: false,
+ field :id, GraphQL::Types::String, null: false,
description: 'ID for a status action.',
extras: [:parent]
- field :button_title, GraphQL::STRING_TYPE, null: true,
+ field :button_title, GraphQL::Types::String, null: true,
description: 'Title for the button, for example: Retry this job.'
- field :icon, GraphQL::STRING_TYPE, null: true,
+ field :icon, GraphQL::Types::String, null: true,
description: 'Icon used in the action button.'
- field :method, GraphQL::STRING_TYPE, null: true,
+ field :method, GraphQL::Types::String, null: true,
description: 'Method for the action, for example: :post.',
resolver_method: :action_method
- field :path, GraphQL::STRING_TYPE, null: true,
+ field :path, GraphQL::Types::String, null: true,
description: 'Path for the action.'
- field :title, GraphQL::STRING_TYPE, null: true,
+ field :title, GraphQL::Types::String, null: true,
description: 'Title for the action, for example: Retry.'
def id(parent:)
diff --git a/app/graphql/types/ci/template_type.rb b/app/graphql/types/ci/template_type.rb
index 5f07fa16928..7e7ee44025f 100644
--- a/app/graphql/types/ci/template_type.rb
+++ b/app/graphql/types/ci/template_type.rb
@@ -7,9 +7,9 @@ module Types
graphql_name 'CiTemplate'
description 'GitLab CI/CD configuration template.'
- field :name, GraphQL::STRING_TYPE, null: false,
+ field :name, GraphQL::Types::String, null: false,
description: 'Name of the CI template.'
- field :content, GraphQL::STRING_TYPE, null: false,
+ field :content, GraphQL::Types::String, null: false,
description: 'Contents of the CI template.'
end
end
diff --git a/app/graphql/types/ci/test_case_type.rb b/app/graphql/types/ci/test_case_type.rb
index 9cc3f918125..9ec5daa44ea 100644
--- a/app/graphql/types/ci/test_case_type.rb
+++ b/app/graphql/types/ci/test_case_type.rb
@@ -12,25 +12,25 @@ module Types
field :status, Types::Ci::TestCaseStatusEnum, null: true,
description: "Status of the test case (#{::Gitlab::Ci::Reports::TestCase::STATUS_TYPES.join(', ')})."
- field :name, GraphQL::STRING_TYPE, null: true,
+ field :name, GraphQL::Types::String, null: true,
description: 'Name of the test case.'
- field :classname, GraphQL::STRING_TYPE, null: true,
+ field :classname, GraphQL::Types::String, null: true,
description: 'Classname of the test case.'
field :execution_time, GraphQL::FLOAT_TYPE, null: true,
description: 'Test case execution time in seconds.'
- field :file, GraphQL::STRING_TYPE, null: true,
+ field :file, GraphQL::Types::String, null: true,
description: 'Path to the file of the test case.'
- field :attachment_url, GraphQL::STRING_TYPE, null: true,
+ field :attachment_url, GraphQL::Types::String, null: true,
description: 'URL of the test case attachment file.'
- field :system_output, GraphQL::STRING_TYPE, null: true,
+ field :system_output, GraphQL::Types::String, null: true,
description: 'System output of the test case.'
- field :stack_trace, GraphQL::STRING_TYPE, null: true,
+ field :stack_trace, GraphQL::Types::String, null: true,
description: 'Stack trace of the test case.'
field :recent_failures, Types::Ci::RecentFailuresType, null: true,
diff --git a/app/graphql/types/ci/test_report_total_type.rb b/app/graphql/types/ci/test_report_total_type.rb
index 1123734adc3..aa07a391519 100644
--- a/app/graphql/types/ci/test_report_total_type.rb
+++ b/app/graphql/types/ci/test_report_total_type.rb
@@ -10,22 +10,22 @@ module Types
field :time, GraphQL::FLOAT_TYPE, null: true,
description: 'Total duration of the tests.'
- field :count, GraphQL::INT_TYPE, null: true,
+ field :count, GraphQL::Types::Int, null: true,
description: 'Total number of the test cases.'
- field :success, GraphQL::INT_TYPE, null: true,
+ field :success, GraphQL::Types::Int, null: true,
description: 'Total number of test cases that succeeded.'
- field :failed, GraphQL::INT_TYPE, null: true,
+ field :failed, GraphQL::Types::Int, null: true,
description: 'Total number of test cases that failed.'
- field :skipped, GraphQL::INT_TYPE, null: true,
+ field :skipped, GraphQL::Types::Int, null: true,
description: 'Total number of test cases that were skipped.'
- field :error, GraphQL::INT_TYPE, null: true,
+ field :error, GraphQL::Types::Int, null: true,
description: 'Total number of test cases that had an error.'
- field :suite_error, GraphQL::STRING_TYPE, null: true,
+ field :suite_error, GraphQL::Types::String, null: true,
description: 'Test suite error message.'
end
# rubocop: enable Graphql/AuthorizeTypes
diff --git a/app/graphql/types/ci/test_suite_summary_type.rb b/app/graphql/types/ci/test_suite_summary_type.rb
index a80a9179cb4..3db2d80d591 100644
--- a/app/graphql/types/ci/test_suite_summary_type.rb
+++ b/app/graphql/types/ci/test_suite_summary_type.rb
@@ -9,31 +9,31 @@ module Types
connection_type_class(Types::CountableConnectionType)
- field :name, GraphQL::STRING_TYPE, null: true,
+ field :name, GraphQL::Types::String, null: true,
description: 'Name of the test suite.'
field :total_time, GraphQL::FLOAT_TYPE, null: true,
description: 'Total duration of the tests in the test suite.'
- field :total_count, GraphQL::INT_TYPE, null: true,
+ field :total_count, GraphQL::Types::Int, null: true,
description: 'Total number of the test cases in the test suite.'
- field :success_count, GraphQL::INT_TYPE, null: true,
+ field :success_count, GraphQL::Types::Int, null: true,
description: 'Total number of test cases that succeeded in the test suite.'
- field :failed_count, GraphQL::INT_TYPE, null: true,
+ field :failed_count, GraphQL::Types::Int, null: true,
description: 'Total number of test cases that failed in the test suite.'
- field :skipped_count, GraphQL::INT_TYPE, null: true,
+ field :skipped_count, GraphQL::Types::Int, null: true,
description: 'Total number of test cases that were skipped in the test suite.'
- field :error_count, GraphQL::INT_TYPE, null: true,
+ field :error_count, GraphQL::Types::Int, null: true,
description: 'Total number of test cases that had an error.'
- field :suite_error, GraphQL::STRING_TYPE, null: true,
+ field :suite_error, GraphQL::Types::String, null: true,
description: 'Test suite error message.'
- field :build_ids, [GraphQL::ID_TYPE], null: true,
+ field :build_ids, [GraphQL::Types::ID], null: true,
description: 'IDs of the builds used to run the test suite.'
end
# rubocop: enable Graphql/AuthorizeTypes
diff --git a/app/graphql/types/ci/test_suite_type.rb b/app/graphql/types/ci/test_suite_type.rb
index 7d4c01da81b..f9f37d4045e 100644
--- a/app/graphql/types/ci/test_suite_type.rb
+++ b/app/graphql/types/ci/test_suite_type.rb
@@ -9,28 +9,28 @@ module Types
connection_type_class(Types::CountableConnectionType)
- field :name, GraphQL::STRING_TYPE, null: true,
+ field :name, GraphQL::Types::String, null: true,
description: 'Name of the test suite.'
field :total_time, GraphQL::FLOAT_TYPE, null: true,
description: 'Total duration of the tests in the test suite.'
- field :total_count, GraphQL::INT_TYPE, null: true,
+ field :total_count, GraphQL::Types::Int, null: true,
description: 'Total number of the test cases in the test suite.'
- field :success_count, GraphQL::INT_TYPE, null: true,
+ field :success_count, GraphQL::Types::Int, null: true,
description: 'Total number of test cases that succeeded in the test suite.'
- field :failed_count, GraphQL::INT_TYPE, null: true,
+ field :failed_count, GraphQL::Types::Int, null: true,
description: 'Total number of test cases that failed in the test suite.'
- field :skipped_count, GraphQL::INT_TYPE, null: true,
+ field :skipped_count, GraphQL::Types::Int, null: true,
description: 'Total number of test cases that were skipped in the test suite.'
- field :error_count, GraphQL::INT_TYPE, null: true,
+ field :error_count, GraphQL::Types::Int, null: true,
description: 'Total number of test cases that had an error.'
- field :suite_error, GraphQL::STRING_TYPE, null: true,
+ field :suite_error, GraphQL::Types::String, null: true,
description: 'Test suite error message.'
field :test_cases, Types::Ci::TestCaseType.connection_type, null: true,
diff --git a/app/graphql/types/ci_configuration/sast/analyzers_entity_input_type.rb b/app/graphql/types/ci_configuration/sast/analyzers_entity_input_type.rb
index ccb72283cf6..68b9a63d8dc 100644
--- a/app/graphql/types/ci_configuration/sast/analyzers_entity_input_type.rb
+++ b/app/graphql/types/ci_configuration/sast/analyzers_entity_input_type.rb
@@ -7,10 +7,10 @@ module Types
graphql_name 'SastCiConfigurationAnalyzersEntityInput'
description 'Represents the analyzers entity in SAST CI configuration'
- argument :name, GraphQL::STRING_TYPE, required: true,
+ argument :name, GraphQL::Types::String, required: true,
description: 'Name of analyzer.'
- argument :enabled, GraphQL::BOOLEAN_TYPE, required: true,
+ argument :enabled, GraphQL::Types::Boolean, required: true,
description: 'State of the analyzer.'
argument :variables, [::Types::CiConfiguration::Sast::EntityInputType],
diff --git a/app/graphql/types/ci_configuration/sast/analyzers_entity_type.rb b/app/graphql/types/ci_configuration/sast/analyzers_entity_type.rb
index 3c6202ca7e0..9fdc7c1b000 100644
--- a/app/graphql/types/ci_configuration/sast/analyzers_entity_type.rb
+++ b/app/graphql/types/ci_configuration/sast/analyzers_entity_type.rb
@@ -8,16 +8,16 @@ module Types
graphql_name 'SastCiConfigurationAnalyzersEntity'
description 'Represents an analyzer entity in SAST CI configuration'
- field :name, GraphQL::STRING_TYPE, null: true,
+ field :name, GraphQL::Types::String, null: true,
description: 'Name of the analyzer.'
- field :label, GraphQL::STRING_TYPE, null: true,
+ field :label, GraphQL::Types::String, null: true,
description: 'Analyzer label used in the config UI.'
- field :enabled, GraphQL::BOOLEAN_TYPE, null: true,
+ field :enabled, GraphQL::Types::Boolean, null: true,
description: 'Indicates whether an analyzer is enabled.'
- field :description, GraphQL::STRING_TYPE, null: true,
+ field :description, GraphQL::Types::String, null: true,
description: 'Analyzer description that is displayed on the form.'
field :variables, ::Types::CiConfiguration::Sast::EntityType.connection_type, null: true,
diff --git a/app/graphql/types/ci_configuration/sast/entity_input_type.rb b/app/graphql/types/ci_configuration/sast/entity_input_type.rb
index 9fce120889b..f0e3c07d71f 100644
--- a/app/graphql/types/ci_configuration/sast/entity_input_type.rb
+++ b/app/graphql/types/ci_configuration/sast/entity_input_type.rb
@@ -7,13 +7,13 @@ module Types
graphql_name 'SastCiConfigurationEntityInput'
description 'Represents an entity in SAST CI configuration'
- argument :field, GraphQL::STRING_TYPE, required: true,
+ argument :field, GraphQL::Types::String, required: true,
description: 'CI keyword of entity.'
- argument :default_value, GraphQL::STRING_TYPE, required: true,
+ argument :default_value, GraphQL::Types::String, required: true,
description: 'Default value that is used if value is empty.'
- argument :value, GraphQL::STRING_TYPE, required: true,
+ argument :value, GraphQL::Types::String, required: true,
description: 'Current value of the entity.'
end
end
diff --git a/app/graphql/types/ci_configuration/sast/entity_type.rb b/app/graphql/types/ci_configuration/sast/entity_type.rb
index eeb9025391f..41b8575d99a 100644
--- a/app/graphql/types/ci_configuration/sast/entity_type.rb
+++ b/app/graphql/types/ci_configuration/sast/entity_type.rb
@@ -8,25 +8,25 @@ module Types
graphql_name 'SastCiConfigurationEntity'
description 'Represents an entity in SAST CI configuration'
- field :field, GraphQL::STRING_TYPE, null: true,
+ field :field, GraphQL::Types::String, null: true,
description: 'CI keyword of entity.'
- field :label, GraphQL::STRING_TYPE, null: true,
+ field :label, GraphQL::Types::String, null: true,
description: 'Label for entity used in the form.'
- field :type, GraphQL::STRING_TYPE, null: true,
+ field :type, GraphQL::Types::String, null: true,
description: 'Type of the field value.'
field :options, ::Types::CiConfiguration::Sast::OptionsEntityType.connection_type, null: true,
description: 'Different possible values of the field.'
- field :default_value, GraphQL::STRING_TYPE, null: true,
+ field :default_value, GraphQL::Types::String, null: true,
description: 'Default value that is used if value is empty.'
- field :description, GraphQL::STRING_TYPE, null: true,
+ field :description, GraphQL::Types::String, null: true,
description: 'Entity description that is displayed on the form.'
- field :value, GraphQL::STRING_TYPE, null: true,
+ field :value, GraphQL::Types::String, null: true,
description: 'Current value of the entity.'
field :size, ::Types::CiConfiguration::Sast::UiComponentSizeEnum, null: true,
diff --git a/app/graphql/types/ci_configuration/sast/options_entity_type.rb b/app/graphql/types/ci_configuration/sast/options_entity_type.rb
index 86d104a7fda..5f365807cfe 100644
--- a/app/graphql/types/ci_configuration/sast/options_entity_type.rb
+++ b/app/graphql/types/ci_configuration/sast/options_entity_type.rb
@@ -8,10 +8,10 @@ module Types
graphql_name 'SastCiConfigurationOptionsEntity'
description 'Represents an entity for options in SAST CI configuration'
- field :label, GraphQL::STRING_TYPE, null: true,
+ field :label, GraphQL::Types::String, null: true,
description: 'Label of option entity.'
- field :value, GraphQL::STRING_TYPE, null: true,
+ field :value, GraphQL::Types::String, null: true,
description: 'Value of option entity.'
end
end
diff --git a/app/graphql/types/commit_action_type.rb b/app/graphql/types/commit_action_type.rb
index cc1f45478e4..b170134b388 100644
--- a/app/graphql/types/commit_action_type.rb
+++ b/app/graphql/types/commit_action_type.rb
@@ -4,15 +4,15 @@ module Types
class CommitActionType < BaseInputObject
argument :action, type: Types::CommitActionModeEnum, required: true,
description: 'The action to perform, create, delete, move, update, chmod.'
- argument :file_path, type: GraphQL::STRING_TYPE, required: true,
+ argument :file_path, type: GraphQL::Types::String, required: true,
description: 'Full path to the file.'
- argument :content, type: GraphQL::STRING_TYPE, required: false,
+ argument :content, type: GraphQL::Types::String, required: false,
description: 'Content of the file.'
- argument :previous_path, type: GraphQL::STRING_TYPE, required: false,
+ argument :previous_path, type: GraphQL::Types::String, required: false,
description: 'Original full path to the file being moved.'
- argument :last_commit_id, type: GraphQL::STRING_TYPE, required: false,
+ argument :last_commit_id, type: GraphQL::Types::String, required: false,
description: 'Last known file commit ID.'
- argument :execute_filemode, type: GraphQL::BOOLEAN_TYPE, required: false,
+ argument :execute_filemode, type: GraphQL::Types::Boolean, required: false,
description: 'Enables/disables the execute flag on the file.'
argument :encoding, type: Types::CommitEncodingEnum, required: false,
description: 'Encoding of the file. Default is text.'
diff --git a/app/graphql/types/commit_type.rb b/app/graphql/types/commit_type.rb
index d137901380b..dc1bf6a3101 100644
--- a/app/graphql/types/commit_type.rb
+++ b/app/graphql/types/commit_type.rb
@@ -8,31 +8,31 @@ module Types
present_using CommitPresenter
- field :id, type: GraphQL::ID_TYPE, null: false,
+ field :id, type: GraphQL::Types::ID, null: false,
description: 'ID (global ID) of the commit.'
- field :sha, type: GraphQL::STRING_TYPE, null: false,
+ field :sha, type: GraphQL::Types::String, null: false,
description: 'SHA1 ID of the commit.'
- field :short_id, type: GraphQL::STRING_TYPE, null: false,
+ field :short_id, type: GraphQL::Types::String, null: false,
description: 'Short SHA1 ID of the commit.'
- field :title, type: GraphQL::STRING_TYPE, null: true, calls_gitaly: true,
+ field :title, type: GraphQL::Types::String, null: true, calls_gitaly: true,
description: 'Title of the commit message.'
markdown_field :title_html, null: true
- field :description, type: GraphQL::STRING_TYPE, null: true,
+ field :description, type: GraphQL::Types::String, null: true,
description: 'Description of the commit message.'
markdown_field :description_html, null: true
- field :message, type: GraphQL::STRING_TYPE, null: true,
+ field :message, type: GraphQL::Types::String, null: true,
description: 'Raw commit message.'
field :authored_date, type: Types::TimeType, null: true,
description: 'Timestamp of when the commit was authored.'
- field :web_url, type: GraphQL::STRING_TYPE, null: false,
+ field :web_url, type: GraphQL::Types::String, null: false,
description: 'Web URL of the commit.'
- field :web_path, type: GraphQL::STRING_TYPE, null: false,
+ field :web_path, type: GraphQL::Types::String, null: false,
description: 'Web path of the commit.'
- field :signature_html, type: GraphQL::STRING_TYPE, null: true, calls_gitaly: true,
+ field :signature_html, type: GraphQL::Types::String, null: true, calls_gitaly: true,
description: 'Rendered HTML of the commit signature.'
- field :author_name, type: GraphQL::STRING_TYPE, null: true,
+ field :author_name, type: GraphQL::Types::String, null: true,
description: 'Commit authors name.'
- field :author_gravatar, type: GraphQL::STRING_TYPE, null: true,
+ field :author_gravatar, type: GraphQL::Types::String, null: true,
description: 'Commit authors gravatar.'
# models/commit lazy loads the author by email
diff --git a/app/graphql/types/container_expiration_policy_type.rb b/app/graphql/types/container_expiration_policy_type.rb
index 2b01474617a..6d6df21fe3f 100644
--- a/app/graphql/types/container_expiration_policy_type.rb
+++ b/app/graphql/types/container_expiration_policy_type.rb
@@ -10,7 +10,7 @@ module Types
field :created_at, Types::TimeType, null: false, description: 'Timestamp of when the container expiration policy was created.'
field :updated_at, Types::TimeType, null: false, description: 'Timestamp of when the container expiration policy was updated.'
- field :enabled, GraphQL::BOOLEAN_TYPE, null: false, description: 'Indicates whether this container expiration policy is enabled.'
+ field :enabled, GraphQL::Types::Boolean, null: false, description: 'Indicates whether this container expiration policy is enabled.'
field :older_than, Types::ContainerExpirationPolicyOlderThanEnum, null: true, description: 'Tags older that this will expire.'
field :cadence, Types::ContainerExpirationPolicyCadenceEnum, null: false, description: 'This container expiration policy schedule.'
field :keep_n, Types::ContainerExpirationPolicyKeepEnum, null: true, description: 'Number of tags to retain.'
diff --git a/app/graphql/types/container_repository_tag_type.rb b/app/graphql/types/container_repository_tag_type.rb
index 6de16416395..b6b65bce421 100644
--- a/app/graphql/types/container_repository_tag_type.rb
+++ b/app/graphql/types/container_repository_tag_type.rb
@@ -8,15 +8,15 @@ module Types
authorize :read_container_image
- field :name, GraphQL::STRING_TYPE, null: false, description: 'Name of the tag.'
- field :path, GraphQL::STRING_TYPE, null: false, description: 'Path of the tag.'
- field :location, GraphQL::STRING_TYPE, null: false, description: 'URL of the tag.'
- field :digest, GraphQL::STRING_TYPE, null: true, description: 'Digest of the tag.'
- field :revision, GraphQL::STRING_TYPE, null: true, description: 'Revision of the tag.'
- field :short_revision, GraphQL::STRING_TYPE, null: true, description: 'Short revision of the tag.'
+ field :name, GraphQL::Types::String, null: false, description: 'Name of the tag.'
+ field :path, GraphQL::Types::String, null: false, description: 'Path of the tag.'
+ field :location, GraphQL::Types::String, null: false, description: 'URL of the tag.'
+ field :digest, GraphQL::Types::String, null: true, description: 'Digest of the tag.'
+ field :revision, GraphQL::Types::String, null: true, description: 'Revision of the tag.'
+ field :short_revision, GraphQL::Types::String, null: true, description: 'Short revision of the tag.'
field :total_size, GraphQL::Types::BigInt, null: true, description: 'The size of the tag.'
field :created_at, Types::TimeType, null: true, description: 'Timestamp when the tag was created.'
- field :can_delete, GraphQL::BOOLEAN_TYPE, null: false, description: 'Can the current user delete this tag.'
+ field :can_delete, GraphQL::Types::Boolean, null: false, description: 'Can the current user delete this tag.'
def can_delete
Ability.allowed?(current_user, :destroy_container_image, object)
diff --git a/app/graphql/types/container_repository_type.rb b/app/graphql/types/container_repository_type.rb
index 48c2b9f460f..91a65053131 100644
--- a/app/graphql/types/container_repository_type.rb
+++ b/app/graphql/types/container_repository_type.rb
@@ -8,17 +8,17 @@ module Types
authorize :read_container_image
- field :id, GraphQL::ID_TYPE, null: false, description: 'ID of the container repository.'
- field :name, GraphQL::STRING_TYPE, null: false, description: 'Name of the container repository.'
- field :path, GraphQL::STRING_TYPE, null: false, description: 'Path of the container repository.'
- field :location, GraphQL::STRING_TYPE, null: false, description: 'URL of the container repository.'
+ field :id, GraphQL::Types::ID, null: false, description: 'ID of the container repository.'
+ field :name, GraphQL::Types::String, null: false, description: 'Name of the container repository.'
+ field :path, GraphQL::Types::String, null: false, description: 'Path of the container repository.'
+ field :location, GraphQL::Types::String, null: false, description: 'URL of the container repository.'
field :created_at, Types::TimeType, null: false, description: 'Timestamp when the container repository was created.'
field :updated_at, Types::TimeType, null: false, description: 'Timestamp when the container repository was updated.'
field :expiration_policy_started_at, Types::TimeType, null: true, description: 'Timestamp when the cleanup done by the expiration policy was started on the container repository.'
field :expiration_policy_cleanup_status, Types::ContainerRepositoryCleanupStatusEnum, null: true, description: 'The tags cleanup status for the container repository.'
field :status, Types::ContainerRepositoryStatusEnum, null: true, description: 'Status of the container repository.'
- field :tags_count, GraphQL::INT_TYPE, null: false, description: 'Number of tags associated with this image.'
- field :can_delete, GraphQL::BOOLEAN_TYPE, null: false, description: 'Can the current user delete the container repository.'
+ field :tags_count, GraphQL::Types::Int, null: false, description: 'Number of tags associated with this image.'
+ field :can_delete, GraphQL::Types::Boolean, null: false, description: 'Can the current user delete the container repository.'
field :project, Types::ProjectType, null: false, description: 'Project of the container registry.'
def can_delete
diff --git a/app/graphql/types/countable_connection_type.rb b/app/graphql/types/countable_connection_type.rb
index 0a9699a4570..0f24964daa6 100644
--- a/app/graphql/types/countable_connection_type.rb
+++ b/app/graphql/types/countable_connection_type.rb
@@ -3,7 +3,7 @@
module Types
# rubocop: disable Graphql/AuthorizeTypes
class CountableConnectionType < GraphQL::Types::Relay::BaseConnection
- field :count, GraphQL::INT_TYPE, null: false,
+ field :count, GraphQL::Types::Int, null: false,
description: 'Total count of collection.'
def count
diff --git a/app/graphql/types/custom_emoji_type.rb b/app/graphql/types/custom_emoji_type.rb
index 246b60ce184..64381b3ee1e 100644
--- a/app/graphql/types/custom_emoji_type.rb
+++ b/app/graphql/types/custom_emoji_type.rb
@@ -11,16 +11,16 @@ module Types
null: false,
description: 'The ID of the emoji.'
- field :name, GraphQL::STRING_TYPE,
+ field :name, GraphQL::Types::String,
null: false,
description: 'The name of the emoji.'
- field :url, GraphQL::STRING_TYPE,
+ field :url, GraphQL::Types::String,
null: false,
method: :file,
description: 'The link to file of the emoji.'
- field :external, GraphQL::BOOLEAN_TYPE,
+ field :external, GraphQL::Types::Boolean,
null: false,
description: 'Whether the emoji is an external link.'
end
diff --git a/app/models/concerns/project_features_compatibility.rb b/app/models/concerns/project_features_compatibility.rb
index 484c91e0833..121b696a659 100644
--- a/app/models/concerns/project_features_compatibility.rb
+++ b/app/models/concerns/project_features_compatibility.rb
@@ -90,6 +90,17 @@ module ProjectFeaturesCompatibility
write_feature_attribute_string(:container_registry_access_level, value)
end
+ # TODO: Remove this method after we drop support for project create/edit APIs to set the
+ # container_registry_enabled attribute. They can instead set the container_registry_access_level
+ # attribute.
+ def container_registry_enabled=(value)
+ write_feature_attribute_boolean(:container_registry_access_level, value)
+
+ # TODO: Remove this when we remove the projects.container_registry_enabled
+ # column. https://gitlab.com/gitlab-org/gitlab/-/issues/335425
+ super
+ end
+
private
def write_feature_attribute_boolean(field, value)
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index d296f6a44d2..9914b443eba 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -465,10 +465,34 @@ class Namespace < ApplicationRecord
end
def refresh_access_of_projects_invited_groups
- Group
- .joins(project_group_links: :project)
- .where(projects: { namespace_id: id })
- .find_each(&:refresh_members_authorized_projects)
+ if Feature.enabled?(:specialized_worker_for_group_lock_update_auth_recalculation)
+ Project
+ .where(namespace_id: id)
+ .joins(:project_group_links)
+ .distinct
+ .find_each do |project|
+ AuthorizedProjectUpdate::ProjectRecalculateWorker.perform_async(project.id)
+ end
+
+ # Until we compare the inconsistency rates of the new specialized worker and
+ # the old approach, we still run AuthorizedProjectsWorker
+ # but with some delay and lower urgency as a safety net.
+ Group
+ .joins(project_group_links: :project)
+ .where(projects: { namespace_id: id })
+ .distinct
+ .find_each do |group|
+ group.refresh_members_authorized_projects(
+ blocking: false,
+ priority: UserProjectAccessChangedService::LOW_PRIORITY
+ )
+ end
+ else
+ Group
+ .joins(project_group_links: :project)
+ .where(projects: { namespace_id: id })
+ .find_each(&:refresh_members_authorized_projects)
+ end
end
def nesting_level_allowed
diff --git a/app/models/project.rb b/app/models/project.rb
index 24ff0ed3b8c..6a90ae9038a 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -76,7 +76,6 @@ class Project < ApplicationRecord
default_value_for :packages_enabled, true
default_value_for :archived, false
default_value_for :resolve_outdated_diff_discussions, false
- default_value_for :container_registry_enabled, gitlab_config_features.container_registry
default_value_for(:repository_storage) do
Repository.pick_storage_shard
end
@@ -98,9 +97,6 @@ class Project < ApplicationRecord
before_save :ensure_runners_token
- # https://api.rubyonrails.org/v6.0.3.4/classes/ActiveRecord/AttributeMethods/Dirty.html#method-i-will_save_change_to_attribute-3F
- before_update :set_container_registry_access_level, if: :will_save_change_to_container_registry_enabled?
-
after_save :update_project_statistics, if: :saved_change_to_namespace_id?
after_save :create_import_state, if: ->(project) { project.import? && project.import_state.nil? }
@@ -1184,6 +1180,15 @@ class Project < ApplicationRecord
import_type == 'gitea'
end
+ def github_import?
+ import_type == 'github'
+ end
+
+ def github_enterprise_import?
+ github_import? &&
+ URI.parse(import_url).host != URI.parse(Octokit::Default::API_ENDPOINT).host
+ end
+
def has_remote_mirror?
remote_mirror_available? && remote_mirrors.enabled.exists?
end
@@ -2659,20 +2664,6 @@ class Project < ApplicationRecord
private
- def set_container_registry_access_level
- # changes_to_save = { 'container_registry_enabled' => [value_before_update, value_after_update] }
- value = changes_to_save['container_registry_enabled'][1]
-
- access_level =
- if value
- ProjectFeature::ENABLED
- else
- ProjectFeature::DISABLED
- end
-
- project_feature.update!(container_registry_access_level: access_level)
- end
-
def find_integration(integrations, name)
integrations.find { _1.to_param == name }
end
diff --git a/app/models/project_feature.rb b/app/models/project_feature.rb
index f6e889396c6..94db683267d 100644
--- a/app/models/project_feature.rb
+++ b/app/models/project_feature.rb
@@ -2,6 +2,7 @@
class ProjectFeature < ApplicationRecord
include Featurable
+ extend Gitlab::ConfigHelper
# When updating this array, make sure to update rubocop/cop/gitlab/feature_available_usage.rb as well.
FEATURES = %i[
@@ -48,8 +49,6 @@ class ProjectFeature < ApplicationRecord
end
end
- before_create :set_container_registry_access_level
-
# Default scopes force us to unscope here since a service may need to check
# permissions for a project in pending_delete
# http://stackoverflow.com/questions/1540645/how-to-disable-default-scope-for-a-belongs-to
@@ -80,6 +79,14 @@ class ProjectFeature < ApplicationRecord
end
end
+ default_value_for(:container_registry_access_level, allows_nil: false) do |feature|
+ if gitlab_config_features.container_registry
+ ENABLED
+ else
+ DISABLED
+ end
+ end
+
def public_pages?
return true unless Gitlab.config.pages.access_control
@@ -94,15 +101,6 @@ class ProjectFeature < ApplicationRecord
private
- def set_container_registry_access_level
- self.container_registry_access_level =
- if project&.read_attribute(:container_registry_enabled)
- ENABLED
- else
- DISABLED
- end
- end
-
# Validates builds and merge requests access level
# which cannot be higher than repository access level
def repository_children_level
diff --git a/app/services/ci/build_cancel_service.rb b/app/services/ci/build_cancel_service.rb
new file mode 100644
index 00000000000..a23418ed738
--- /dev/null
+++ b/app/services/ci/build_cancel_service.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module Ci
+ class BuildCancelService
+ def initialize(build, user)
+ @build = build
+ @user = user
+ end
+
+ def execute
+ return forbidden unless allowed?
+ return unprocessable_entity unless build.cancelable?
+
+ build.cancel
+
+ ServiceResponse.success(payload: build)
+ end
+
+ private
+
+ attr_reader :build, :user
+
+ def allowed?
+ user.can?(:update_build, build)
+ end
+
+ def forbidden
+ ServiceResponse.error(message: 'Forbidden', http_status: :forbidden)
+ end
+
+ def unprocessable_entity
+ ServiceResponse.error(message: 'Unprocessable entity', http_status: :unprocessable_entity)
+ end
+ end
+end
diff --git a/app/services/ci/build_unschedule_service.rb b/app/services/ci/build_unschedule_service.rb
new file mode 100644
index 00000000000..3b367ecc4c4
--- /dev/null
+++ b/app/services/ci/build_unschedule_service.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+module Ci
+ class BuildUnscheduleService
+ def initialize(build, user)
+ @build = build
+ @user = user
+ end
+
+ def execute
+ return forbidden unless allowed?
+ return unprocessable_entity unless build.scheduled?
+
+ build.unschedule!
+
+ ServiceResponse.success(payload: build)
+ end
+
+ private
+
+ attr_reader :build, :user
+
+ def allowed?
+ user.can?(:update_build, build)
+ end
+
+ def forbidden
+ ServiceResponse.error(message: 'Forbidden', http_status: :forbidden)
+ end
+
+ def unprocessable_entity
+ ServiceResponse.error(message: 'Unprocessable entity', http_status: :unprocessable_entity)
+ end
+ end
+end
diff --git a/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb b/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb
index 762f1f10bb6..de9bb4d5a93 100644
--- a/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb
+++ b/app/workers/container_expiration_policies/cleanup_container_repository_worker.rb
@@ -63,16 +63,23 @@ module ContainerExpirationPolicies
def container_repository
strong_memoize(:container_repository) do
ContainerRepository.transaction do
- # We need a lock to prevent two workers from picking up the same row
- container_repository = next_container_repository
+ repository = next_container_repository
- container_repository&.tap(&:cleanup_ongoing!)
+ repository&.tap do |repo|
+ log_info(
+ project_id: repo.project_id,
+ container_repository_id: repo.id
+ )
+
+ repo.cleanup_ongoing!
+ end
end
end
end
def next_container_repository
# rubocop: disable CodeReuse/ActiveRecord
+ # We need a lock to prevent two workers from picking up the same row
next_one_requiring = ContainerRepository.requiring_cleanup
.order(:expiration_policy_cleanup_status, :expiration_policy_started_at)
.limit(1)
diff --git a/config/feature_flags/development/specialized_worker_for_group_lock_update_auth_recalculation.yml b/config/feature_flags/development/specialized_worker_for_group_lock_update_auth_recalculation.yml
new file mode 100644
index 00000000000..820e6cafb41
--- /dev/null
+++ b/config/feature_flags/development/specialized_worker_for_group_lock_update_auth_recalculation.yml
@@ -0,0 +1,8 @@
+---
+name: specialized_worker_for_group_lock_update_auth_recalculation
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66525
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336592
+milestone: '14.2'
+type: development
+group: group::access
+default_enabled: false
diff --git a/doc/administration/geo/replication/configuration.md b/doc/administration/geo/replication/configuration.md
index 7331b032c52..3a116de32bd 100644
--- a/doc/administration/geo/replication/configuration.md
+++ b/doc/administration/geo/replication/configuration.md
@@ -7,35 +7,35 @@ type: howto
# Geo configuration **(PREMIUM SELF)**
-## Configuring a new **secondary** node
+## Configuring a new **secondary** site
NOTE:
-This is the final step in setting up a **secondary** Geo node. Stages of the
+This is the final step in setting up a **secondary** Geo site. Stages of the
setup process must be completed in the documented order.
Before attempting the steps in this stage, [complete all prior stages](../setup/index.md#using-omnibus-gitlab).
-The basic steps of configuring a **secondary** node are to:
+The basic steps of configuring a **secondary** site are to:
-- Replicate required configurations between the **primary** node and the **secondary** nodes.
-- Configure a tracking database on each **secondary** node.
-- Start GitLab on each **secondary** node.
+- Replicate required configurations between the **primary** site and the **secondary** sites.
+- Configure a tracking database on each **secondary** site.
+- Start GitLab on each **secondary** site.
You are encouraged to first read through all the steps before executing them
in your testing/production environment.
NOTE:
-**Do not** set up any custom authentication for the **secondary** nodes. This is handled by the **primary** node.
+**Do not** set up any custom authentication for the **secondary** sites. This is handled by the **primary** site.
Any change that requires access to the **Admin Area** needs to be done in the
-**primary** node because the **secondary** node is a read-only replica.
+**primary** site because the **secondary** site is a read-only replica.
### Step 1. Manually replicate secret GitLab values
GitLab stores a number of secret values in the `/etc/gitlab/gitlab-secrets.json`
-file which *must* be the same on all nodes. Until there is
-a means of automatically replicating these between nodes (see [issue #3789](https://gitlab.com/gitlab-org/gitlab/-/issues/3789)),
-they must be manually replicated to the **secondary** node.
+file which *must* be the same on all of a site's nodes. Until there is
+a means of automatically replicating these between sites (see [issue #3789](https://gitlab.com/gitlab-org/gitlab/-/issues/3789)),
+they must be manually replicated to **all nodes of the secondary site**.
-1. SSH into the **primary** node, and execute the command below:
+1. SSH into a **Rails node on your primary** site, and execute the command below:
```shell
sudo cat /etc/gitlab/gitlab-secrets.json
@@ -43,7 +43,7 @@ they must be manually replicated to the **secondary** node.
This displays the secrets that need to be replicated, in JSON format.
-1. SSH into the **secondary** node and login as the `root` user:
+1. SSH **into each node on your secondary Geo site** and login as the `root` user:
```shell
sudo -i
@@ -55,7 +55,7 @@ they must be manually replicated to the **secondary** node.
mv /etc/gitlab/gitlab-secrets.json /etc/gitlab/gitlab-secrets.json.`date +%F`
```
-1. Copy `/etc/gitlab/gitlab-secrets.json` from the **primary** node to the **secondary** node, or
+1. Copy `/etc/gitlab/gitlab-secrets.json` from the **Rails node on your primary** site to **each node on your secondary** site, or
copy-and-paste the file contents between nodes:
```shell
@@ -72,28 +72,28 @@ they must be manually replicated to the **secondary** node.
chmod 0600 /etc/gitlab/gitlab-secrets.json
```
-1. Reconfigure the **secondary** node for the change to take effect:
+1. Reconfigure **each Rails, Sidekiq and Gitaly nodes on your secondary** site for the change to take effect:
```shell
gitlab-ctl reconfigure
gitlab-ctl restart
```
-### Step 2. Manually replicate the **primary** node's SSH host keys
+### Step 2. Manually replicate the **primary** site's SSH host keys
GitLab integrates with the system-installed SSH daemon, designating a user
(typically named `git`) through which all access requests are handled.
In a [Disaster Recovery](../disaster_recovery/index.md) situation, GitLab system
-administrators promote a **secondary** node to the **primary** node. DNS records for the
-**primary** domain should also be updated to point to the new **primary** node
-(previously a **secondary** node). Doing so avoids the need to update Git remotes and API URLs.
+administrators promote a **secondary** site to the **primary** site. DNS records for the
+**primary** domain should also be updated to point to the new **primary** site
+(previously a **secondary** site). Doing so avoids the need to update Git remotes and API URLs.
-This causes all SSH requests to the newly promoted **primary** node to
+This causes all SSH requests to the newly promoted **primary** site to
fail due to SSH host key mismatch. To prevent this, the primary SSH host
-keys must be manually replicated to the **secondary** node.
+keys must be manually replicated to the **secondary** site.
-1. SSH into the **secondary** node and login as the `root` user:
+1. SSH into **each node on your secondary** site and login as the `root` user:
```shell
sudo -i
@@ -105,34 +105,34 @@ keys must be manually replicated to the **secondary** node.
find /etc/ssh -iname ssh_host_* -exec cp {} {}.backup.`date +%F` \;
```
-1. Copy OpenSSH host keys from the **primary** node:
+1. Copy OpenSSH host keys from the **primary** site:
- If you can access your **primary** node using the **root** user:
+ If you can access one of the **nodes on your primary** site serving SSH traffic (usually, the main GitLab Rails application nodes) using the **root** user:
```shell
- # Run this from the secondary node, change `<primary_node_fqdn>` for the IP or FQDN of the server
+ # Run this from the secondary site, change `<primary_site_fqdn>` for the IP or FQDN of the server
scp root@<primary_node_fqdn>:/etc/ssh/ssh_host_*_key* /etc/ssh
```
If you only have access through a user with `sudo` privileges:
```shell
- # Run this from your primary node:
+ # Run this from the node on your primary site:
sudo tar --transform 's/.*\///g' -zcvf ~/geo-host-key.tar.gz /etc/ssh/ssh_host_*_key*
- # Run this from your secondary node:
- scp <user_with_sudo>@<primary_node_fqdn>:geo-host-key.tar.gz .
+ # Run this on each node on your secondary site:
+ scp <user_with_sudo>@<primary_site_fqdn>:geo-host-key.tar.gz .
tar zxvf ~/geo-host-key.tar.gz -C /etc/ssh
```
-1. On your **secondary** node, ensure the file permissions are correct:
+1. On **each node on your secondary** site, ensure the file permissions are correct:
```shell
chown root:root /etc/ssh/ssh_host_*_key*
chmod 0600 /etc/ssh/ssh_host_*_key*
```
-1. To verify key fingerprint matches, execute the following command on both nodes:
+1. To verify key fingerprint matches, execute the following command on both primary and secondary nodes on each site:
```shell
for file in /etc/ssh/ssh_host_*_key; do ssh-keygen -lf $file; done
@@ -160,7 +160,7 @@ keys must be manually replicated to the **secondary** node.
NOTE:
The output for private keys and public keys command should generate the same fingerprint.
-1. Restart `sshd` on your **secondary** node:
+1. Restart `sshd` on **each node on your secondary** site:
```shell
# Debian or Ubuntu installations
@@ -175,31 +175,31 @@ keys must be manually replicated to the **secondary** node.
SSH into your GitLab **secondary** server in a new terminal. If you are unable to connect,
verify the permissions are correct according to the previous steps.
-### Step 3. Add the **secondary** node
+### Step 3. Add the **secondary** site
-1. SSH into your GitLab **secondary** server and login as root:
+1. SSH into **each Rails and Sidekiq node on your secondary** site and login as root:
```shell
sudo -i
```
-1. Edit `/etc/gitlab/gitlab.rb` and add a **unique** name for your node. You need this in the next steps:
+1. Edit `/etc/gitlab/gitlab.rb` and add a **unique** name for your site. You need this in the next steps:
```ruby
- # The unique identifier for the Geo node.
- gitlab_rails['geo_node_name'] = '<node_name_here>'
+ # The unique identifier for the Geo site.
+ gitlab_rails['geo_node_name'] = '<site_name_here>'
```
-1. Reconfigure the **secondary** node for the change to take effect:
+1. Reconfigure **each Rails and Sidekiq node on your secondary** site for the change to take effect:
```shell
gitlab-ctl reconfigure
```
-1. On the top bar of the primary node, select **Menu >** **{admin}** **Admin**.
-1. On the left sidebar, select **Geo > Nodes**.
-1. Select **Add site**.
- ![Add secondary node](img/adding_a_secondary_node_v13_3.png)
+1. On the top bar, select **Menu >** **{admin}** **Admin**.
+1. On the left sidebar, select **Geo > Sites**.
+1. Select **New site**.
+ ![Add secondary site](img/adding_a_secondary_node_v13_3.png)
1. Fill in **Name** with the `gitlab_rails['geo_node_name']` in
`/etc/gitlab/gitlab.rb`. These values must always match *exactly*, character
for character.
@@ -207,10 +207,10 @@ keys must be manually replicated to the **secondary** node.
values must always match, but it doesn't matter if one ends with a `/` and
the other doesn't.
1. Optionally, choose which groups or storage shards should be replicated by the
- **secondary** node. Leave blank to replicate all. Read more in
+ **secondary** site. Leave blank to replicate all. Read more in
[selective synchronization](#selective-synchronization).
-1. Select **Add node** to add the **secondary** node.
-1. SSH into your GitLab **secondary** server and restart the services:
+1. Select **Add site** to add the **secondary** site.
+1. SSH into **each Rails, and Sidekiq node on your secondary** site and restart the services:
```shell
gitlab-ctl restart
@@ -222,56 +222,56 @@ keys must be manually replicated to the **secondary** node.
gitlab-rake gitlab:geo:check
```
-1. SSH into your **primary** server and login as root to verify the
- **secondary** node is reachable or there are any common issue with your Geo setup:
+1. SSH into a **Rails or Sidekiq server on your primary** site and login as root to verify the
+ **secondary** site is reachable or there are any common issue with your Geo setup:
```shell
gitlab-rake gitlab:geo:check
```
-Once added to the Geo administration page and restarted, the **secondary** node automatically starts
-replicating missing data from the **primary** node in a process known as **backfill**.
-Meanwhile, the **primary** node starts to notify each **secondary** node of any changes, so
-that the **secondary** node can act on those notifications immediately.
+Once added to the Geo administration page and restarted, the **secondary** site automatically starts
+replicating missing data from the **primary** site in a process known as **backfill**.
+Meanwhile, the **primary** site starts to notify each **secondary** site of any changes, so
+that the **secondary** site can act on those notifications immediately.
-Be sure the _secondary_ node is running and accessible. You can sign in to the
-_secondary_ node with the same credentials as were used with the _primary_ node.
+Be sure the _secondary_ site is running and accessible. You can sign in to the
+_secondary_ site with the same credentials as were used with the _primary_ site.
-### Step 4. (Optional) Configuring the **secondary** node to trust the **primary** node
+### Step 4. (Optional) Configuring the **secondary** site to trust the **primary** site
-You can safely skip this step if your **primary** node uses a CA-issued HTTPS certificate.
+You can safely skip this step if your **primary** site uses a CA-issued HTTPS certificate.
-If your **primary** node is using a self-signed certificate for *HTTPS* support, you
-need to add that certificate to the **secondary** node's trust store. Retrieve the
-certificate from the **primary** node and follow
+If your **primary** site is using a self-signed certificate for *HTTPS* support, you
+need to add that certificate to the **secondary** site's trust store. Retrieve the
+certificate from the **primary** site and follow
[these instructions](https://docs.gitlab.com/omnibus/settings/ssl.html)
-on the **secondary** node.
+on the **secondary** site.
### Step 5. Enable Git access over HTTP/HTTPS
Geo synchronizes repositories over HTTP/HTTPS, and therefore requires this clone
-method to be enabled. This is enabled by default, but if converting an existing node to Geo it should be checked:
+method to be enabled. This is enabled by default, but if converting an existing site to Geo it should be checked:
-On the **primary** node:
+On the **primary** site:
1. On the top bar, select **Menu >** **{admin}** **Admin**.
1. On the left sidebar, select **Settings > General**.
1. Expand **Visibility and access controls**.
1. Ensure "Enabled Git access protocols" is set to either "Both SSH and HTTP(S)" or "Only HTTP(S)".
-### Step 6. Verify proper functioning of the **secondary** node
+### Step 6. Verify proper functioning of the **secondary** site
-You can sign in to the **secondary** node with the same credentials you used with
-the **primary** node. After you sign in:
+You can sign in to the **secondary** site with the same credentials you used with
+the **primary** site. After you sign in:
1. On the top bar, select **Menu >** **{admin}** **Admin**.
-1. On the left sidebar, select **Geo > Nodes**.
-1. Verify that it's correctly identified as a **secondary** Geo node, and that
+1. On the left sidebar, select **Geo > Sites**.
+1. Verify that it's correctly identified as a **secondary** Geo site, and that
Geo is enabled.
The initial replication, or 'backfill', is probably still in progress. You
-can monitor the synchronization process on each Geo node from the **primary**
-node's **Geo Nodes** dashboard in your browser.
+can monitor the synchronization process on each Geo site from the **primary**
+site's **Geo Sites** dashboard in your browser.
![Geo dashboard](img/geo_node_dashboard_v14_0.png)
@@ -286,10 +286,10 @@ The two most obvious issues that can become apparent in the dashboard are:
- You are using a custom certificate or custom CA (see the [troubleshooting document](troubleshooting.md)).
- The instance is firewalled (check your firewall rules).
-Disabling a **secondary** node stops the synchronization process.
+Please note that disabling a **secondary** site stops the synchronization process.
-If `git_data_dirs` is customized on the **primary** node for multiple
-repository shards you must duplicate the same configuration on each **secondary** node.
+Please note that if `git_data_dirs` is customized on the **primary** site for multiple
+repository shards you must duplicate the same configuration on each **secondary** site.
Point your users to the [Using a Geo Site guide](usage.md).
@@ -304,7 +304,7 @@ Currently, this is what is synced:
## Selective synchronization
Geo supports selective synchronization, which allows administrators to choose
-which projects should be synchronized by **secondary** nodes.
+which projects should be synchronized by **secondary** sites.
A subset of projects can be chosen, either by group or by storage shard. The
former is ideal for replicating data belonging to a subset of users, while the
latter is more suited to progressively rolling out Geo to a large GitLab
@@ -312,22 +312,22 @@ instance.
It is important to note that selective synchronization:
-1. Does not restrict permissions from **secondary** nodes.
-1. Does not hide project metadata from **secondary** nodes.
+1. Does not restrict permissions from **secondary** sites.
+1. Does not hide project metadata from **secondary** sites.
- Since Geo currently relies on PostgreSQL replication, all project metadata
- gets replicated to **secondary** nodes, but repositories that have not been
+ gets replicated to **secondary** sites, but repositories that have not been
selected are empty.
1. Does not reduce the number of events generated for the Geo event log.
- - The **primary** node generates events as long as any **secondary** nodes are present.
- Selective synchronization restrictions are implemented on the **secondary** nodes,
- not the **primary** node.
+ - The **primary** site generates events as long as any **secondary** sites are present.
+ Selective synchronization restrictions are implemented on the **secondary** sites,
+ not the **primary** site.
### Git operations on unreplicated repositories
> [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/2562) in GitLab 12.10 for HTTP(S) and in GitLab 13.0 for SSH.
Git clone, pull, and push operations over HTTP(S) and SSH are supported for repositories that
-exist on the **primary** node but not on **secondary** nodes. This situation can occur
+exist on the **primary** site but not on **secondary** sites. This situation can occur
when:
- Selective synchronization does not include the project attached to the repository.
@@ -335,7 +335,7 @@ when:
## Upgrading Geo
-See the [updating the Geo nodes document](updating_the_geo_nodes.md).
+See the [updating the Geo sites document](updating_the_geo_nodes.md).
## Troubleshooting
diff --git a/doc/development/fe_guide/haml.md b/doc/development/fe_guide/haml.md
index eaf475a35b6..8f501007755 100644
--- a/doc/development/fe_guide/haml.md
+++ b/doc/development/fe_guide/haml.md
@@ -31,7 +31,7 @@ For example:
- Before:
```haml
- = gitlab_ui_form_for @group do |f|
+ = form_for @group do |f|
.form-group.gl-mb-3
.gl-form-checkbox.custom-control.custom-checkbox
= f.check_box :prevent_sharing_groups_outside_hierarchy, disabled: !can_change_prevent_sharing_groups_outside_hierarchy?(@group), class: 'custom-control-input'
diff --git a/doc/development/github_importer.md b/doc/development/github_importer.md
index 91df33e6d95..14fd8f6bf72 100644
--- a/doc/development/github_importer.md
+++ b/doc/development/github_importer.md
@@ -183,6 +183,9 @@ perform:
tries to find the user based on the GitHub user ID, while the second query
is used to find the user using their GitHub Email address.
+To avoid mismatching users, the search by GitHub user ID is not done when importing from GitHub
+Enterprise.
+
Because this process is quite expensive we cache the result of these lookups in
Redis. For every user looked up we store three keys:
diff --git a/doc/user/project/working_with_projects.md b/doc/user/project/working_with_projects.md
index 08b63bfed5f..15a3087cabc 100644
--- a/doc/user/project/working_with_projects.md
+++ b/doc/user/project/working_with_projects.md
@@ -148,39 +148,44 @@ To use a custom project template on the **New project** page:
> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/26388) in GitLab 10.5.
-When you create a new repository locally, instead of manually creating a new project in GitLab
-and then [cloning the repository](../../gitlab-basics/start-using-git.md#clone-a-repository)
-locally, you can directly push it to GitLab to create the new project, all without leaving
-your terminal. If you have access rights to the associated namespace, GitLab
-automatically creates a new project under that GitLab namespace with its visibility
-set to Private by default (you can later change it in the [project's settings](../../public_access/public_access.md#change-project-visibility)).
-
-This can be done by using either SSH or HTTPS:
-
-```shell
-## Git push using SSH
-git push --set-upstream git@gitlab.example.com:namespace/nonexistent-project.git master
-
-## Git push using HTTPS
-git push --set-upstream https://gitlab.example.com/namespace/nonexistent-project.git master
-```
-
-You can pass the flag `--tags` to the `git push` command to export existing repository tags.
-
-Once the push finishes successfully, a remote message indicates
-the command to set the remote and the URL to the new project:
-
-```plaintext
-remote:
-remote: The private project namespace/nonexistent-project was created.
-remote:
-remote: To configure the remote, run:
-remote: git remote add origin https://gitlab.example.com/namespace/nonexistent-project.git
-remote:
-remote: To view the project, visit:
-remote: https://gitlab.example.com/namespace/nonexistent-project
-remote:
-```
+When you create a new repository locally, you don't have to sign in to the GitLab
+interface to create a project and
+[clone its repository](../../gitlab-basics/start-using-git.md#clone-a-repository).
+You can directly push your new repository to GitLab, which creates your new project
+without leaving your terminal.
+
+To push a new project:
+
+1. Identify the [namespace](../group/index.md#namespaces) you want to add the new
+ project to, as you need this information in a future step. To determine if you have
+ permission to create new projects in a namespace, view the group's page in a
+ web browser and confirm the page displays a **New project** button.
+
+ NOTE:
+ As project creation permissions can have many factors, contact your
+ GitLab administrator if you're unsure.
+
+1. If you want to push using SSH, ensure you have [created a SSH key](../../ssh/README.md) and
+ [added it to your GitLab account](../../ssh/index.md#add-an-ssh-key-to-your-gitlab-account).
+1. Push with one of the following methods. Replace `gitlab.example.com` with the
+ domain name of the machine that hosts your Git repository, `namespace` with the name of
+ your namespace, and `myproject` with the name of your new project:
+ - To push with SSH: `git push --set-upstream git@gitlab.example.com:namespace/myproject.git master`
+ - To push with HTTPS: `git push --set-upstream https://gitlab.example.com/namespace/myproject.git master`
+ Optional: to export existing repository tags, append the `--tags` flag to your `git push` command.
+1. When the push completes, GitLab displays a message:
+
+ ```plaintext
+ remote: The private project namespace/myproject was created.
+ ```
+
+1. (Optional) To configure the remote, alter the command
+ `git remote add origin https://gitlab.example.com/namespace/myproject.git`
+ to match your namespace and project names.
+
+You can view your new project at `https://gitlab.example.com/namespace/myproject`.
+Your project's visibility is set to **Private** by default, but you can change it
+in your [project's settings](../../public_access/public_access.md#change-project-visibility)).
## Fork a project
diff --git a/lib/gitlab/github_import/user_finder.rb b/lib/gitlab/github_import/user_finder.rb
index 058cd1ebd57..f583ef39d13 100644
--- a/lib/gitlab/github_import/user_finder.rb
+++ b/lib/gitlab/github_import/user_finder.rb
@@ -120,10 +120,18 @@ module Gitlab
read_id_from_cache(ID_FOR_EMAIL_CACHE_KEY % email)
end
- # Queries and caches the GitLab user ID for a GitHub user ID, if one was
- # found.
+ # If importing from github.com, queries and caches the GitLab user ID for
+ # a GitHub user ID, if one was found.
+ #
+ # When importing from Github Enterprise, do not query user by Github ID
+ # since we only have users' Github ID from github.com.
def id_for_github_id(id)
- gitlab_id = query_id_for_github_id(id) || nil
+ gitlab_id =
+ if project.github_enterprise_import?
+ nil
+ else
+ query_id_for_github_id(id)
+ end
Gitlab::Cache::Import::Caching.write(ID_CACHE_KEY % id, gitlab_id)
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 68c8a5efbdc..f44a91e9cca 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -28964,10 +28964,10 @@ msgstr ""
msgid "SecurityConfiguration|Feature documentation for %{featureName}"
msgstr ""
-msgid "SecurityConfiguration|GitLab Ultimate checks your application for security vulnerabilities that may lead to unauthorized access, data leaks, and denial of service attacks. Its features include:"
+msgid "SecurityConfiguration|High-level vulnerability statistics across projects and groups"
msgstr ""
-msgid "SecurityConfiguration|High-level vulnerability statistics across projects and groups."
+msgid "SecurityConfiguration|Immediately begin risk analysis and remediation with application security features. Start with SAST and Secret Detection, available to all plans. Upgrade to Ultimate to get all features, including:"
msgstr ""
msgid "SecurityConfiguration|Manage"
@@ -28982,6 +28982,9 @@ msgstr ""
msgid "SecurityConfiguration|More information"
msgstr ""
+msgid "SecurityConfiguration|More scan types, including Container Scanning, DAST, Dependency Scanning, Fuzzing, and Licence Compliance"
+msgstr ""
+
msgid "SecurityConfiguration|Not enabled"
msgstr ""
@@ -28991,7 +28994,7 @@ msgstr ""
msgid "SecurityConfiguration|Quickly enable all continuous testing and compliance tools by enabling %{linkStart}Auto DevOps%{linkEnd}"
msgstr ""
-msgid "SecurityConfiguration|Runtime security metrics for application environments."
+msgid "SecurityConfiguration|Runtime security metrics for application environments"
msgstr ""
msgid "SecurityConfiguration|SAST Analyzers"
@@ -29000,7 +29003,7 @@ msgstr ""
msgid "SecurityConfiguration|SAST Configuration"
msgstr ""
-msgid "SecurityConfiguration|Secure your project with Ultimate"
+msgid "SecurityConfiguration|Secure your project"
msgstr ""
msgid "SecurityConfiguration|Security Control"
@@ -29027,10 +29030,7 @@ msgstr ""
msgid "SecurityConfiguration|View history"
msgstr ""
-msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request."
-msgstr ""
-
-msgid "SecurityConfiguration|With the information provided, you can immediately begin risk analysis and remediation within GitLab."
+msgid "SecurityConfiguration|Vulnerability details and statistics in the merge request"
msgstr ""
msgid "SecurityConfiguration|You can quickly enable all security scanning tools by enabling %{linkStart}Auto DevOps%{linkEnd}."
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index a7a36d3a074..e9e7c3c3bb3 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -868,64 +868,85 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
end
describe 'POST cancel' do
- before do
- project.add_developer(user)
- sign_in(user)
- end
+ context 'when user is authorized to cancel the build' do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
- context 'when continue url is present' do
- let(:job) { create(:ci_build, :cancelable, pipeline: pipeline) }
+ context 'when continue url is present' do
+ let(:job) { create(:ci_build, :cancelable, pipeline: pipeline) }
- context 'when continue to is a safe url' do
- let(:url) { '/test' }
+ context 'when continue to is a safe url' do
+ let(:url) { '/test' }
- before do
- post_cancel(continue: { to: url })
- end
+ before do
+ post_cancel(continue: { to: url })
+ end
- it 'redirects to the continue url' do
- expect(response).to have_gitlab_http_status(:found)
- expect(response).to redirect_to(url)
+ it 'redirects to the continue url' do
+ expect(response).to have_gitlab_http_status(:found)
+ expect(response).to redirect_to(url)
+ end
+
+ it 'transits to canceled' do
+ expect(job.reload).to be_canceled
+ end
end
- it 'transits to canceled' do
- expect(job.reload).to be_canceled
+ context 'when continue to is not a safe url' do
+ let(:url) { 'http://example.com' }
+
+ it 'raises an error' do
+ expect { cancel_with_redirect(url) }.to raise_error
+ end
end
end
- context 'when continue to is not a safe url' do
- let(:url) { 'http://example.com' }
+ context 'when continue url is not present' do
+ before do
+ post_cancel
+ end
+
+ context 'when job is cancelable' do
+ let(:job) { create(:ci_build, :cancelable, pipeline: pipeline) }
+
+ it 'redirects to the builds page' do
+ expect(response).to have_gitlab_http_status(:found)
+ expect(response).to redirect_to(builds_namespace_project_pipeline_path(id: pipeline.id))
+ end
+
+ it 'transits to canceled' do
+ expect(job.reload).to be_canceled
+ end
+ end
+
+ context 'when job is not cancelable' do
+ let(:job) { create(:ci_build, :canceled, pipeline: pipeline) }
- it 'raises an error' do
- expect { cancel_with_redirect(url) }.to raise_error
+ it 'returns unprocessable_entity' do
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ end
end
end
end
- context 'when continue url is not present' do
+ context 'when user is not authorized to cancel the build' do
+ let!(:job) { create(:ci_build, :cancelable, pipeline: pipeline) }
+
before do
+ project.add_reporter(user)
+ sign_in(user)
+
post_cancel
end
- context 'when job is cancelable' do
- let(:job) { create(:ci_build, :cancelable, pipeline: pipeline) }
-
- it 'redirects to the builds page' do
- expect(response).to have_gitlab_http_status(:found)
- expect(response).to redirect_to(builds_namespace_project_pipeline_path(id: pipeline.id))
- end
-
- it 'transits to canceled' do
- expect(job.reload).to be_canceled
- end
+ it 'responds with not_found' do
+ expect(response).to have_gitlab_http_status(:not_found)
end
- context 'when job is not cancelable' do
- let(:job) { create(:ci_build, :canceled, pipeline: pipeline) }
-
- it 'returns unprocessable_entity' do
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
- end
+ it 'does not transit to canceled' do
+ expect(job.reload).not_to be_canceled
end
end
@@ -938,43 +959,60 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
describe 'POST unschedule' do
before do
- project.add_developer(user)
+ create(:protected_branch, :developers_can_merge, name: 'master', project: project)
+ end
- create(:protected_branch, :developers_can_merge,
- name: 'master', project: project)
+ context 'when user is authorized to unschedule the build' do
+ before do
+ project.add_developer(user)
+ sign_in(user)
- sign_in(user)
+ post_unschedule
+ end
- post_unschedule
- end
+ context 'when job is scheduled' do
+ let(:job) { create(:ci_build, :scheduled, pipeline: pipeline) }
- context 'when job is scheduled' do
- let(:job) { create(:ci_build, :scheduled, pipeline: pipeline) }
+ it 'redirects to the unscheduled job page' do
+ expect(response).to have_gitlab_http_status(:found)
+ expect(response).to redirect_to(namespace_project_job_path(id: job.id))
+ end
- it 'redirects to the unscheduled job page' do
- expect(response).to have_gitlab_http_status(:found)
- expect(response).to redirect_to(namespace_project_job_path(id: job.id))
+ it 'transits to manual' do
+ expect(job.reload).to be_manual
+ end
end
- it 'transits to manual' do
- expect(job.reload).to be_manual
+ context 'when job is not scheduled' do
+ let(:job) { create(:ci_build, pipeline: pipeline) }
+
+ it 'renders unprocessable_entity' do
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ end
end
end
- context 'when job is not scheduled' do
- let(:job) { create(:ci_build, pipeline: pipeline) }
+ context 'when user is not authorized to unschedule the build' do
+ let(:job) { create(:ci_build, :scheduled, pipeline: pipeline) }
- it 'renders unprocessable_entity' do
- expect(response).to have_gitlab_http_status(:unprocessable_entity)
+ before do
+ project.add_reporter(user)
+ sign_in(user)
+
+ post_unschedule
+ end
+
+ it 'responds with not_found' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+
+ it 'does not transit to scheduled' do
+ expect(job.reload).not_to be_manual
end
end
def post_unschedule
- post :unschedule, params: {
- namespace_id: project.namespace,
- project_id: project,
- id: job.id
- }
+ post :unschedule, params: { namespace_id: project.namespace, project_id: project, id: job.id }
end
end
diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb
index 84686c58a8e..d18369b8023 100644
--- a/spec/factories/projects.rb
+++ b/spec/factories/projects.rb
@@ -34,6 +34,7 @@ FactoryBot.define do
end
metrics_dashboard_access_level { ProjectFeature::PRIVATE }
operations_access_level { ProjectFeature::ENABLED }
+ container_registry_access_level { ProjectFeature::ENABLED }
# we can't assign the delegated `#ci_cd_settings` attributes directly, as the
# `#ci_cd_settings` relation needs to be created first
@@ -70,6 +71,17 @@ FactoryBot.define do
}
project.build_project_feature(hash)
+
+ # This is not included in the `hash` above because the default_value_for in
+ # the ProjectFeature model overrides the value set by `build_project_feature` when
+ # evaluator.container_registry_access_level == ProjectFeature::DISABLED.
+ #
+ # This is because the default_value_for gem uses the <column>_changed? method
+ # to determine if the default value should be applied. For new records,
+ # <column>_changed? returns false if the value of the column is the same as
+ # the database default.
+ # See https://github.com/FooBarWidget/default_value_for/blob/release-3.4.0/lib/default_value_for.rb#L158.
+ project.project_feature.container_registry_access_level = evaluator.container_registry_access_level
end
after(:create) do |project, evaluator|
@@ -344,6 +356,9 @@ FactoryBot.define do
trait(:analytics_enabled) { analytics_access_level { ProjectFeature::ENABLED } }
trait(:analytics_disabled) { analytics_access_level { ProjectFeature::DISABLED } }
trait(:analytics_private) { analytics_access_level { ProjectFeature::PRIVATE } }
+ trait(:container_registry_enabled) { container_registry_access_level { ProjectFeature::ENABLED } }
+ trait(:container_registry_disabled) { container_registry_access_level { ProjectFeature::DISABLED } }
+ trait(:container_registry_private) { container_registry_access_level { ProjectFeature::PRIVATE } }
trait :auto_devops do
association :auto_devops, factory: :project_auto_devops
diff --git a/spec/frontend/security_configuration/components/upgrade_banner_spec.js b/spec/frontend/security_configuration/components/upgrade_banner_spec.js
index cf7945343af..a35fded72fb 100644
--- a/spec/frontend/security_configuration/components/upgrade_banner_spec.js
+++ b/spec/frontend/security_configuration/components/upgrade_banner_spec.js
@@ -43,11 +43,11 @@ describe('UpgradeBanner component', () => {
it('renders the list of benefits', () => {
const wrapperText = wrapper.text();
- expect(wrapperText).toContain('GitLab Ultimate checks your application');
+ expect(wrapperText).toContain('Immediately begin risk analysis and remediation');
expect(wrapperText).toContain('statistics in the merge request');
expect(wrapperText).toContain('statistics across projects');
expect(wrapperText).toContain('Runtime security metrics');
- expect(wrapperText).toContain('risk analysis and remediation');
+ expect(wrapperText).toContain('More scan types, including Container Scanning,');
});
it(`re-emits GlBanner's close event`, () => {
diff --git a/spec/graphql/types/base_field_spec.rb b/spec/graphql/types/base_field_spec.rb
index c34fbf42dd8..82efd618e38 100644
--- a/spec/graphql/types/base_field_spec.rb
+++ b/spec/graphql/types/base_field_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe Types::BaseField do
end
it 'defaults to 1' do
- field = described_class.new(name: 'test', type: GraphQL::STRING_TYPE, null: true)
+ field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true)
expect(field.to_graphql.complexity).to eq 1
end
@@ -25,7 +25,7 @@ RSpec.describe Types::BaseField do
describe '#base_complexity' do
context 'with no gitaly calls' do
it 'defaults to 1' do
- field = described_class.new(name: 'test', type: GraphQL::STRING_TYPE, null: true)
+ field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true)
expect(field.base_complexity).to eq 1
end
@@ -33,7 +33,7 @@ RSpec.describe Types::BaseField do
context 'with a gitaly call' do
it 'adds 1 to the default value' do
- field = described_class.new(name: 'test', type: GraphQL::STRING_TYPE, null: true, calls_gitaly: true)
+ field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, calls_gitaly: true)
expect(field.base_complexity).to eq 2
end
@@ -41,14 +41,14 @@ RSpec.describe Types::BaseField do
end
it 'has specified value' do
- field = described_class.new(name: 'test', type: GraphQL::STRING_TYPE, null: true, complexity: 12)
+ field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, complexity: 12)
expect(field.to_graphql.complexity).to eq 12
end
context 'when field has a resolver' do
context 'when a valid complexity is already set' do
- let(:field) { described_class.new(name: 'test', type: GraphQL::STRING_TYPE.connection_type, resolver_class: resolver, complexity: 2, max_page_size: 100, null: true) }
+ let(:field) { described_class.new(name: 'test', type: GraphQL::Types::String.connection_type, resolver_class: resolver, complexity: 2, max_page_size: 100, null: true) }
it 'uses this complexity' do
expect(field.to_graphql.complexity).to eq 2
@@ -56,7 +56,7 @@ RSpec.describe Types::BaseField do
end
context 'and is a connection' do
- let(:field) { described_class.new(name: 'test', type: GraphQL::STRING_TYPE.connection_type, resolver_class: resolver, max_page_size: 100, null: true) }
+ let(:field) { described_class.new(name: 'test', type: GraphQL::Types::String.connection_type, resolver_class: resolver, max_page_size: 100, null: true) }
it 'sets complexity depending on arguments for resolvers' do
expect(field.to_graphql.complexity.call({}, {}, 2)).to eq 4
@@ -71,7 +71,7 @@ RSpec.describe Types::BaseField do
context 'and is not a connection' do
it 'sets complexity as normal' do
- field = described_class.new(name: 'test', type: GraphQL::STRING_TYPE, resolver_class: resolver, max_page_size: 100, null: true)
+ field = described_class.new(name: 'test', type: GraphQL::Types::String, resolver_class: resolver, max_page_size: 100, null: true)
expect(field.to_graphql.complexity.call({}, {}, 2)).to eq 2
expect(field.to_graphql.complexity.call({}, { first: 50 }, 2)).to eq 2
@@ -82,8 +82,8 @@ RSpec.describe Types::BaseField do
context 'calls_gitaly' do
context 'for fields with a resolver' do
it 'adds 1 if true' do
- with_gitaly_field = described_class.new(name: 'test', type: GraphQL::STRING_TYPE, resolver_class: resolver, null: true, calls_gitaly: true)
- without_gitaly_field = described_class.new(name: 'test', type: GraphQL::STRING_TYPE, resolver_class: resolver, null: true)
+ with_gitaly_field = described_class.new(name: 'test', type: GraphQL::Types::String, resolver_class: resolver, null: true, calls_gitaly: true)
+ without_gitaly_field = described_class.new(name: 'test', type: GraphQL::Types::String, resolver_class: resolver, null: true)
base_result = without_gitaly_field.to_graphql.complexity.call({}, {}, 2)
expect(with_gitaly_field.to_graphql.complexity.call({}, {}, 2)).to eq base_result + 1
@@ -92,28 +92,28 @@ RSpec.describe Types::BaseField do
context 'for fields without a resolver' do
it 'adds 1 if true' do
- field = described_class.new(name: 'test', type: GraphQL::STRING_TYPE, null: true, calls_gitaly: true)
+ field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, calls_gitaly: true)
expect(field.to_graphql.complexity).to eq 2
end
end
it 'defaults to false' do
- field = described_class.new(name: 'test', type: GraphQL::STRING_TYPE, null: true)
+ field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true)
expect(field.base_complexity).to eq Types::BaseField::DEFAULT_COMPLEXITY
end
context 'with declared constant complexity value' do
it 'has complexity set to that constant' do
- field = described_class.new(name: 'test', type: GraphQL::STRING_TYPE, null: true, complexity: 12)
+ field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, complexity: 12)
expect(field.to_graphql.complexity).to eq 12
end
it 'does not raise an error even with Gitaly calls' do
allow(Gitlab::GitalyClient).to receive(:get_request_count).and_return([0, 1])
- field = described_class.new(name: 'test', type: GraphQL::STRING_TYPE, null: true, complexity: 12)
+ field = described_class.new(name: 'test', type: GraphQL::Types::String, null: true, complexity: 12)
expect(field.to_graphql.complexity).to eq 12
end
@@ -123,7 +123,7 @@ RSpec.describe Types::BaseField do
describe '#visible?' do
context 'and has a feature_flag' do
let(:flag) { :test_feature }
- let(:field) { described_class.new(name: 'test', type: GraphQL::STRING_TYPE, feature_flag: flag, null: false) }
+ let(:field) { described_class.new(name: 'test', type: GraphQL::Types::String, feature_flag: flag, null: false) }
let(:context) { {} }
before do
@@ -156,7 +156,7 @@ RSpec.describe Types::BaseField do
describe '#description' do
context 'feature flag given' do
- let(:field) { described_class.new(name: 'test', type: GraphQL::STRING_TYPE, feature_flag: flag, null: false, description: 'Test description.') }
+ let(:field) { described_class.new(name: 'test', type: GraphQL::Types::String, feature_flag: flag, null: false, description: 'Test description.') }
let(:flag) { :test_flag }
it 'prepends the description' do
@@ -211,7 +211,7 @@ RSpec.describe Types::BaseField do
include_examples 'Gitlab-style deprecations' do
def subject(args = {})
- base_args = { name: 'test', type: GraphQL::STRING_TYPE, null: true }
+ base_args = { name: 'test', type: GraphQL::Types::String, null: true }
described_class.new(**base_args.merge(args))
end
diff --git a/spec/lib/gitlab/github_import/user_finder_spec.rb b/spec/lib/gitlab/github_import/user_finder_spec.rb
index 20e67a784e1..f81fa3b1e2e 100644
--- a/spec/lib/gitlab/github_import/user_finder_spec.rb
+++ b/spec/lib/gitlab/github_import/user_finder_spec.rb
@@ -3,7 +3,14 @@
require 'spec_helper'
RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
- let(:project) { create(:project) }
+ let(:project) do
+ create(
+ :project,
+ import_type: 'github',
+ import_url: 'https://api.github.com/user/repo'
+ )
+ end
+
let(:client) { double(:client) }
let(:finder) { described_class.new(project, client) }
@@ -263,6 +270,26 @@ RSpec.describe Gitlab::GithubImport::UserFinder, :clean_gitlab_redis_cache do
finder.id_for_github_id(id)
end
+
+ context 'when importing from github enterprise' do
+ let(:project) do
+ create(
+ :project,
+ import_type: 'github',
+ import_url: 'https://othergithub.net/user/repo'
+ )
+ end
+
+ it 'does not look up the user by external id' do
+ expect(finder).not_to receive(:query_id_for_github_id)
+
+ expect(Gitlab::Cache::Import::Caching)
+ .to receive(:write)
+ .with(described_class::ID_CACHE_KEY % id, nil)
+
+ finder.id_for_github_id(id)
+ end
+ end
end
describe '#id_for_github_email' do
diff --git a/spec/lib/gitlab/subscription_portal_spec.rb b/spec/lib/gitlab/subscription_portal_spec.rb
index ed551521b1d..628eb380396 100644
--- a/spec/lib/gitlab/subscription_portal_spec.rb
+++ b/spec/lib/gitlab/subscription_portal_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe ::Gitlab::SubscriptionPortal, skip: Gitlab.jh? do
+RSpec.describe ::Gitlab::SubscriptionPortal do
using RSpec::Parameterized::TableSyntax
where(:method_name, :test, :development, :result) do
diff --git a/spec/models/container_repository_spec.rb b/spec/models/container_repository_spec.rb
index a53db07cc59..846dfb30928 100644
--- a/spec/models/container_repository_spec.rb
+++ b/spec/models/container_repository_spec.rb
@@ -323,7 +323,7 @@ RSpec.describe ContainerRepository do
context 'with a subgroup' do
let_it_be(:test_group) { create(:group) }
let_it_be(:another_project) { create(:project, path: 'test', group: test_group) }
- let_it_be(:project3) { create(:project, path: 'test3', group: test_group, container_registry_enabled: false) }
+ let_it_be(:project3) { create(:project, :container_registry_disabled, path: 'test3', group: test_group) }
let_it_be(:another_repository) do
create(:container_repository, name: 'my_image', project: another_project)
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index ea1ce067e4d..57882b6f1b3 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -1152,6 +1152,68 @@ RSpec.describe Namespace do
end
end
+ context 'refreshing project access on updating share_with_group_lock' do
+ let(:group) { create(:group, share_with_group_lock: false) }
+ let(:project) { create(:project, :private, group: group) }
+
+ let_it_be(:shared_with_group_one) { create(:group) }
+ let_it_be(:shared_with_group_two) { create(:group) }
+ let_it_be(:group_one_user) { create(:user) }
+ let_it_be(:group_two_user) { create(:user) }
+
+ subject(:execute_update) { group.update!(share_with_group_lock: true) }
+
+ before do
+ shared_with_group_one.add_developer(group_one_user)
+ shared_with_group_two.add_developer(group_two_user)
+ create(:project_group_link, group: shared_with_group_one, project: project)
+ create(:project_group_link, group: shared_with_group_two, project: project)
+ end
+
+ it 'calls AuthorizedProjectUpdate::ProjectRecalculateWorker to update project authorizations' do
+ expect(AuthorizedProjectUpdate::ProjectRecalculateWorker)
+ .to receive(:perform_async).with(project.id).once
+
+ execute_update
+ end
+
+ it 'updates authorizations leading to users from shared groups losing access', :sidekiq_inline do
+ expect { execute_update }
+ .to change { group_one_user.authorized_projects.include?(project) }.from(true).to(false)
+ .and change { group_two_user.authorized_projects.include?(project) }.from(true).to(false)
+ end
+
+ it 'calls AuthorizedProjectUpdate::UserRefreshFromReplicaWorker with a delay to update project authorizations' do
+ expect(AuthorizedProjectUpdate::UserRefreshFromReplicaWorker).to(
+ receive(:bulk_perform_in)
+ .with(1.hour,
+ [[group_one_user.id]],
+ batch_delay: 30.seconds, batch_size: 100)
+ )
+
+ expect(AuthorizedProjectUpdate::UserRefreshFromReplicaWorker).to(
+ receive(:bulk_perform_in)
+ .with(1.hour,
+ [[group_two_user.id]],
+ batch_delay: 30.seconds, batch_size: 100)
+ )
+
+ execute_update
+ end
+
+ context 'when the feature flag `specialized_worker_for_group_lock_update_auth_recalculation` is disabled' do
+ before do
+ stub_feature_flags(specialized_worker_for_group_lock_update_auth_recalculation: false)
+ end
+
+ it 'refreshes the permissions of the members of the old and new namespace' do
+ expect { execute_update }
+ .to change { group_one_user.authorized_projects.include?(project) }.from(true).to(false)
+ .and change { group_two_user.authorized_projects.include?(project) }.from(true).to(false)
+ end
+ end
+ end
+
describe '#share_with_group_lock with subgroups' do
context 'when creating a subgroup' do
let(:subgroup) { create(:group, parent: root_group )}
diff --git a/spec/models/project_feature_spec.rb b/spec/models/project_feature_spec.rb
index 3fd7e57a5db..0ef5a2046ba 100644
--- a/spec/models/project_feature_spec.rb
+++ b/spec/models/project_feature_spec.rb
@@ -189,27 +189,33 @@ RSpec.describe ProjectFeature do
end
describe 'container_registry_access_level' do
- context 'when the project is created with container_registry_enabled false' do
- it 'creates project with DISABLED container_registry_access_level' do
- project = create(:project, container_registry_enabled: false)
+ context 'with default value' do
+ let(:project) { Project.new }
- expect(project.project_feature.container_registry_access_level).to eq(described_class::DISABLED)
+ context 'when the default is false' do
+ it 'creates project_feature with `disabled` container_registry_access_level' do
+ stub_config_setting(default_projects_features: { container_registry: false })
+
+ expect(project.project_feature.container_registry_access_level).to eq(described_class::DISABLED)
+ end
end
- end
- context 'when the project is created with container_registry_enabled true' do
- it 'creates project with ENABLED container_registry_access_level' do
- project = create(:project, container_registry_enabled: true)
+ context 'when the default is true' do
+ before do
+ stub_config_setting(default_projects_features: { container_registry: true })
+ end
- expect(project.project_feature.container_registry_access_level).to eq(described_class::ENABLED)
+ it 'creates project_feature with `enabled` container_registry_access_level' do
+ expect(project.project_feature.container_registry_access_level).to eq(described_class::ENABLED)
+ end
end
- end
- context 'when the project is created with container_registry_enabled nil' do
- it 'creates project with DISABLED container_registry_access_level' do
- project = create(:project, container_registry_enabled: nil)
+ context 'when the default is nil' do
+ it 'creates project_feature with `disabled` container_registry_access_level' do
+ stub_config_setting(default_projects_features: { container_registry: nil })
- expect(project.project_feature.container_registry_access_level).to eq(described_class::DISABLED)
+ expect(project.project_feature.container_registry_access_level).to eq(described_class::DISABLED)
+ end
end
end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index ec99e094a03..6aade778724 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -2407,7 +2407,7 @@ RSpec.describe Project, factory_default: :keep do
end
end
- describe '#set_container_registry_access_level' do
+ describe '#container_registry_enabled=' do
let_it_be_with_reload(:project) { create(:project) }
it 'updates project_feature', :aggregate_failures do
@@ -2872,6 +2872,36 @@ RSpec.describe Project, factory_default: :keep do
it { expect(project.import?).to be true }
end
+ describe '#github_import?' do
+ let_it_be(:project) { build(:project, import_type: 'github') }
+
+ it { expect(project.github_import?).to be true }
+ end
+
+ describe '#github_enterprise_import?' do
+ let_it_be(:github_com_project) do
+ build(
+ :project,
+ import_type: 'github',
+ import_url: 'https://api.github.com/user/repo'
+ )
+ end
+
+ let_it_be(:github_enterprise_project) do
+ build(
+ :project,
+ import_type: 'github',
+ import_url: 'https://othergithub.net/user/repo'
+ )
+ end
+
+ it { expect(github_com_project.github_import?).to be true }
+ it { expect(github_com_project.github_enterprise_import?).to be false }
+
+ it { expect(github_enterprise_project.github_import?).to be true }
+ it { expect(github_enterprise_project.github_enterprise_import?).to be true }
+ end
+
describe '#remove_import_data' do
let(:import_data) { ProjectImportData.new(data: { 'test' => 'some data' }) }
diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb
index ce75e68de32..8cc70a30794 100644
--- a/spec/models/project_team_spec.rb
+++ b/spec/models/project_team_spec.rb
@@ -307,7 +307,7 @@ RSpec.describe ProjectTeam do
it { expect(project.team.max_member_access(nonmember.id)).to eq(Gitlab::Access::NO_ACCESS) }
it { expect(project.team.max_member_access(requester.id)).to eq(Gitlab::Access::NO_ACCESS) }
- context 'but share_with_group_lock is true' do
+ context 'but share_with_group_lock is true', :sidekiq_inline do
before do
project.namespace.update!(share_with_group_lock: true)
end
diff --git a/spec/services/ci/build_cancel_service_spec.rb b/spec/services/ci/build_cancel_service_spec.rb
new file mode 100644
index 00000000000..fe036dc1368
--- /dev/null
+++ b/spec/services/ci/build_cancel_service_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::BuildCancelService do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
+
+ describe '#execute' do
+ subject(:execute) { described_class.new(build, user).execute }
+
+ context 'when user is authorized to cancel the build' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ context 'when build is cancelable' do
+ let!(:build) { create(:ci_build, :cancelable, pipeline: pipeline) }
+
+ it 'transits build to canceled', :aggregate_failures do
+ response = execute
+
+ expect(response).to be_success
+ expect(response.payload.reload).to be_canceled
+ end
+ end
+
+ context 'when build is not cancelable' do
+ let!(:build) { create(:ci_build, :canceled, pipeline: pipeline) }
+
+ it 'responds with unprocessable entity', :aggregate_failures do
+ response = execute
+
+ expect(response).to be_error
+ expect(response.http_status).to eq(:unprocessable_entity)
+ end
+ end
+ end
+
+ context 'when user is not authorized to cancel the build' do
+ let!(:build) { create(:ci_build, :cancelable, pipeline: pipeline) }
+
+ it 'responds with forbidden', :aggregate_failures do
+ response = execute
+
+ expect(response).to be_error
+ expect(response.http_status).to eq(:forbidden)
+ end
+ end
+ end
+end
diff --git a/spec/services/ci/build_unschedule_service_spec.rb b/spec/services/ci/build_unschedule_service_spec.rb
new file mode 100644
index 00000000000..d784d9a2754
--- /dev/null
+++ b/spec/services/ci/build_unschedule_service_spec.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Ci::BuildUnscheduleService do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:project) { create(:project) }
+ let_it_be(:pipeline) { create(:ci_pipeline, project: project) }
+
+ describe '#execute' do
+ subject(:execute) { described_class.new(build, user).execute }
+
+ context 'when user is authorized to unschedule the build' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ context 'when build is scheduled' do
+ let!(:build) { create(:ci_build, :scheduled, pipeline: pipeline) }
+
+ it 'transits build to manual' do
+ response = execute
+
+ expect(response).to be_success
+ expect(response.payload.reload).to be_manual
+ end
+ end
+
+ context 'when build is not scheduled' do
+ let!(:build) { create(:ci_build, pipeline: pipeline) }
+
+ it 'responds with unprocessable entity', :aggregate_failures do
+ response = execute
+
+ expect(response).to be_error
+ expect(response.http_status).to eq(:unprocessable_entity)
+ end
+ end
+ end
+
+ context 'when user is not authorized to unschedule the build' do
+ let!(:build) { create(:ci_build, :scheduled, pipeline: pipeline) }
+
+ it 'responds with forbidden', :aggregate_failures do
+ response = execute
+
+ expect(response).to be_error
+ expect(response.http_status).to eq(:forbidden)
+ end
+ end
+ end
+end
diff --git a/spec/workers/container_expiration_policies/cleanup_container_repository_worker_spec.rb b/spec/workers/container_expiration_policies/cleanup_container_repository_worker_spec.rb
index 506124216af..fdba67638c1 100644
--- a/spec/workers/container_expiration_policies/cleanup_container_repository_worker_spec.rb
+++ b/spec/workers/container_expiration_policies/cleanup_container_repository_worker_spec.rb
@@ -25,6 +25,7 @@ RSpec.describe ContainerExpirationPolicies::CleanupContainerRepositoryWorker do
expect(ContainerExpirationPolicies::CleanupService)
.to receive(:new).with(repository).and_return(double(execute: service_response))
expect_log_extra_metadata(service_response: service_response)
+ expect_log_info(project_id: project.id, container_repository_id: repository.id)
subject
end
@@ -35,6 +36,7 @@ RSpec.describe ContainerExpirationPolicies::CleanupContainerRepositoryWorker do
expect(ContainerExpirationPolicies::CleanupService)
.to receive(:new).with(repository).and_return(double(execute: service_response))
expect_log_extra_metadata(service_response: service_response, cleanup_status: :unfinished)
+ expect_log_info(project_id: project.id, container_repository_id: repository.id)
subject
end
@@ -45,6 +47,7 @@ RSpec.describe ContainerExpirationPolicies::CleanupContainerRepositoryWorker do
expect(ContainerExpirationPolicies::CleanupService)
.to receive(:new).with(repository).and_return(double(execute: service_response))
expect_log_extra_metadata(service_response: service_response, cleanup_status: :unfinished, truncated: true)
+ expect_log_info(project_id: project.id, container_repository_id: repository.id)
subject
end
@@ -65,6 +68,7 @@ RSpec.describe ContainerExpirationPolicies::CleanupContainerRepositoryWorker do
expect(ContainerExpirationPolicies::CleanupService)
.to receive(:new).with(repository).and_return(double(execute: service_response))
expect_log_extra_metadata(service_response: service_response, cleanup_status: :unfinished, truncated: truncated)
+ expect_log_info(project_id: project.id, container_repository_id: repository.id)
subject
end
@@ -78,6 +82,7 @@ RSpec.describe ContainerExpirationPolicies::CleanupContainerRepositoryWorker do
expect(ContainerExpirationPolicies::CleanupService)
.to receive(:new).with(repository).and_return(double(execute: service_response))
expect_log_extra_metadata(service_response: service_response, cleanup_status: :error)
+ expect_log_info(project_id: project.id, container_repository_id: repository.id)
subject
end
@@ -361,6 +366,7 @@ RSpec.describe ContainerExpirationPolicies::CleanupContainerRepositoryWorker do
expect(ContainerExpirationPolicies::CleanupService)
.to receive(:new).with(repository).and_return(double(execute: service_response))
expect_log_extra_metadata(service_response: service_response)
+ expect_log_info(project_id: project.id, container_repository_id: repository.id)
subject
end
@@ -396,6 +402,11 @@ RSpec.describe ContainerExpirationPolicies::CleanupContainerRepositoryWorker do
expect(worker).to receive(:log_extra_metadata_on_done).with(:cleanup_error_message, service_response.message)
end
end
+
+ def expect_log_info(structure)
+ expect(worker.logger)
+ .to receive(:info).with(worker.structured_payload(structure))
+ end
end
describe '#remaining_work_count' do
@@ -446,6 +457,12 @@ RSpec.describe ContainerExpirationPolicies::CleanupContainerRepositoryWorker do
end
it { is_expected.to eq(0) }
+
+ it 'does not log a selected container' do
+ expect(worker).not_to receive(:log_info)
+
+ subject
+ end
end
end