diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-04 18:09:19 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-07-04 18:09:19 +0300 |
commit | f7bd454bd5bfd5494e8a89fe1594f0612024bd6a (patch) | |
tree | 8dbcfb698959cae87e86bf5e92ecc3fa86126a2a | |
parent | cef4494e260d221524fc4e7e1d06d7554fdc7daa (diff) |
Add latest changes from gitlab-org/gitlab@master
69 files changed, 4014 insertions, 853 deletions
diff --git a/.gitlab/ci/review-apps/main.gitlab-ci.yml b/.gitlab/ci/review-apps/main.gitlab-ci.yml index 3522dac39e4..54dc4b4cb75 100644 --- a/.gitlab/ci/review-apps/main.gitlab-ci.yml +++ b/.gitlab/ci/review-apps/main.gitlab-ci.yml @@ -51,6 +51,7 @@ review-build-cng: on_stop: trigger-review-stop review-deploy: + timeout: 45min extends: - .review-workflow-base - .review:rules:review-deploy @@ -115,6 +116,7 @@ review-deploy-sample-projects: .review-stop-base: extends: .review-workflow-base + timeout: 15min environment: action: stop variables: diff --git a/.gitlab/ci/review.gitlab-ci.yml b/.gitlab/ci/review.gitlab-ci.yml index 68bfa682d0f..224312bd8ee 100644 --- a/.gitlab/ci/review.gitlab-ci.yml +++ b/.gitlab/ci/review.gitlab-ci.yml @@ -1,4 +1,5 @@ review-cleanup: + timeout: 15min extends: - .default-retry - .review:rules:review-cleanup diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml index d171baa11d0..241b457ddb0 100644 --- a/.gitlab/ci/rules.gitlab-ci.yml +++ b/.gitlab/ci/rules.gitlab-ci.yml @@ -2,7 +2,7 @@ # Conditions # ############## .if-not-canonical-namespace: &if-not-canonical-namespace - if: '$CI_PROJECT_NAMESPACE !~ /^gitlab(-org)?($|\/)/' + if: '$CI_PROJECT_NAMESPACE !~ /^gitlab(-org|-cn)?($|\/)/' .if-not-ee: &if-not-ee # Only consider FOSS not EE @@ -51,7 +51,7 @@ if: '$CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == "release-tools/update-gitaly" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /stable-(ee|jh)$/' .if-merge-request-targeting-stable-branch: &if-merge-request-targeting-stable-branch - if: '($CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "detached") && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^[\d-]+-stable(-ee)?$/' + if: '($CI_MERGE_REQUEST_EVENT_TYPE == "merged_result" || $CI_MERGE_REQUEST_EVENT_TYPE == "detached") && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME =~ /^[\d-]+-stable(-ee|-jh)?$/' .if-merge-request-labels-run-in-ruby2: &if-merge-request-labels-run-in-ruby2 if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-in-ruby2/' @@ -2104,6 +2104,17 @@ - <<: *if-merge-request changes: *static-analysis-patterns +.static-analysis:rules:trigger-depsaster: + rules: + - if: $ENABLE_DEPSASTER != 'true' + when: never + - <<: *if-fork-merge-request + when: never + - <<: *if-not-ee + when: never + - <<: *if-merge-request + changes: ["**/Gemfile.checksum"] + .semgrep-appsec-custom-rules:rules: rules: - <<: *if-not-ee diff --git a/.gitlab/ci/static-analysis.gitlab-ci.yml b/.gitlab/ci/static-analysis.gitlab-ci.yml index b351a63ecf0..7db853e51fd 100644 --- a/.gitlab/ci/static-analysis.gitlab-ci.yml +++ b/.gitlab/ci/static-analysis.gitlab-ci.yml @@ -217,3 +217,13 @@ ping-appsec-for-sast-findings: script: - apk add jq curl - scripts/process_custom_semgrep_results.sh + +trigger-depsaster: + extends: .static-analysis:rules:trigger-depsaster + stage: lint + variables: + MERGE_REQUEST_PROJECT_ID: $CI_MERGE_REQUEST_PROJECT_ID + MERGE_REQUEST_IID: $CI_MERGE_REQUEST_IID + trigger: + project: "gitlab-com/gl-security/appsec/tooling/depsaster" + allow_failure: true diff --git a/.rubocop.yml b/.rubocop.yml index 2a2f6102dfe..8219ce78f03 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -935,6 +935,10 @@ Migration/BackgroundMigrationBaseClass: BackgroundMigration/AvoidSilentRescueExceptions: Enabled: false +Migration/AvoidFinalizeBackgroundMigration: + Include: + - 'db/post_migrate/*.rb' + Style/ClassAndModuleChildren: Enabled: true diff --git a/.rubocop_todo/lint/missing_cop_enable_directive.yml b/.rubocop_todo/lint/missing_cop_enable_directive.yml index 8cfecb87f2b..1522d935008 100644 --- a/.rubocop_todo/lint/missing_cop_enable_directive.yml +++ b/.rubocop_todo/lint/missing_cop_enable_directive.yml @@ -139,7 +139,6 @@ Lint/MissingCopEnableDirective: - 'ee/lib/api/ldap_group_links.rb' - 'ee/lib/ee/gitlab/background_migration/backfill_project_statistics_container_repository_size.rb' - 'ee/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules.rb' - - 'ee/lib/ee/gitlab/usage_data.rb' - 'ee/lib/gitlab/spdx/license.rb' - 'ee/spec/helpers/groups/security_features_helper_spec.rb' - 'ee/spec/helpers/projects/security/discover_helper_spec.rb' diff --git a/.rubocop_todo/lint/redundant_cop_disable_directive.yml b/.rubocop_todo/lint/redundant_cop_disable_directive.yml index c2708644477..b35f876ed50 100644 --- a/.rubocop_todo/lint/redundant_cop_disable_directive.yml +++ b/.rubocop_todo/lint/redundant_cop_disable_directive.yml @@ -140,7 +140,6 @@ Lint/RedundantCopDisableDirective: - 'ee/lib/ee/gitlab/background_migration/migrate_shared_vulnerability_scanners.rb' - 'ee/lib/ee/gitlab/background_migration/migrate_vulnerabilities_feedback_to_vulnerabilities_state_transition.rb' - 'ee/lib/ee/gitlab/background_migration/purge_stale_security_scans.rb' - - 'ee/lib/ee/gitlab/usage_data.rb' - 'ee/lib/gitlab/analytics/type_of_work/tasks_by_type.rb' - 'ee/lib/gitlab/elastic/bool_expr.rb' - 'ee/lib/gitlab/spdx/license.rb' diff --git a/.rubocop_todo/lint/unused_method_argument.yml b/.rubocop_todo/lint/unused_method_argument.yml index de25c31558f..d1d626b68e0 100644 --- a/.rubocop_todo/lint/unused_method_argument.yml +++ b/.rubocop_todo/lint/unused_method_argument.yml @@ -479,7 +479,6 @@ Lint/UnusedMethodArgument: - 'lib/gitlab/graphql/calls_gitaly/field_extension.rb' - 'lib/gitlab/graphql/connection_redaction.rb' - 'lib/gitlab/graphql/extensions/externally_paginated_array_extension.rb' - - 'lib/gitlab/graphql/generic_tracing.rb' - 'lib/gitlab/graphql/lazy.rb' - 'lib/gitlab/graphql/project/dast_profile_connection_extension.rb' - 'lib/gitlab/graphql/query_analyzers/ast/logger_analyzer.rb' diff --git a/.rubocop_todo/migration/avoid_finalize_background_migration.yml b/.rubocop_todo/migration/avoid_finalize_background_migration.yml new file mode 100644 index 00000000000..bde85ce3e48 --- /dev/null +++ b/.rubocop_todo/migration/avoid_finalize_background_migration.yml @@ -0,0 +1,7 @@ +--- +Migration/AvoidFinalizeBackgroundMigration: + Details: grace period + Exclude: + - 'db/post_migrate/20220502015011_clean_up_fix_merge_request_diff_commit_users.rb' + - 'db/post_migrate/20220525131557_cleanup_backfill_integrations_enable_ssl_verification.rb' + - 'db/post_migrate/20220713133515_cleanup_backfill_draft_statuses_on_merge_requests.rb' diff --git a/.rubocop_todo/rspec/expect_in_hook.yml b/.rubocop_todo/rspec/expect_in_hook.yml index cfd7e0e8e06..3ae4d9ee7f4 100644 --- a/.rubocop_todo/rspec/expect_in_hook.yml +++ b/.rubocop_todo/rspec/expect_in_hook.yml @@ -230,7 +230,6 @@ RSpec/ExpectInHook: - 'spec/lib/gitlab/github_import/parallel_scheduling_spec.rb' - 'spec/lib/gitlab/github_import/user_finder_spec.rb' - 'spec/lib/gitlab/gpg_spec.rb' - - 'spec/lib/gitlab/graphql/generic_tracing_spec.rb' - 'spec/lib/gitlab/health_checks/gitaly_check_spec.rb' - 'spec/lib/gitlab/health_checks/probes/collection_spec.rb' - 'spec/lib/gitlab/health_checks/puma_check_spec.rb' diff --git a/.rubocop_todo/rspec/factory_bot/excessive_create_list.yml b/.rubocop_todo/rspec/factory_bot/excessive_create_list.yml index 5cff05f4163..39aed947a48 100644 --- a/.rubocop_todo/rspec/factory_bot/excessive_create_list.yml +++ b/.rubocop_todo/rspec/factory_bot/excessive_create_list.yml @@ -3,11 +3,7 @@ RSpec/FactoryBot/ExcessiveCreateList: Details: grace period Exclude: - 'ee/spec/controllers/groups/hooks_controller_spec.rb' - - 'ee/spec/controllers/projects/vulnerability_feedback_controller_spec.rb' - 'ee/spec/features/search/elastic/global_search_spec.rb' - - 'ee/spec/frontend/fixtures/on_demand_dast_scans.rb' - - 'ee/spec/graphql/types/dast_scanner_profile_type_spec.rb' - - 'ee/spec/graphql/types/dast_site_profile_type_spec.rb' - 'ee/spec/models/audit_events/external_audit_event_destination_spec.rb' - 'ee/spec/models/audit_events/instance_external_audit_event_destination_spec.rb' - 'ee/spec/models/license_spec.rb' diff --git a/.rubocop_todo/rspec/missing_feature_category.yml b/.rubocop_todo/rspec/missing_feature_category.yml index 5dab0b6c5e1..090c6701118 100644 --- a/.rubocop_todo/rspec/missing_feature_category.yml +++ b/.rubocop_todo/rspec/missing_feature_category.yml @@ -944,8 +944,6 @@ RSpec/MissingFeatureCategory: - 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_projects_with_assigned_security_policy_project_metric_spec.rb' - 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_projects_with_external_status_checks_metric_spec.rb' - 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_saml_group_links_metric_spec.rb' - - 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_gbp_metric_spec.rb' - - 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_metric_spec.rb' - 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_user_merge_requests_for_projects_with_applied_scan_result_policies_metric_spec.rb' - 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_user_merge_requests_with_applied_scan_result_policies_metric_spec.rb' - 'ee/spec/lib/gitlab/usage/metrics/instrumentations/count_users_associating_group_milestones_to_releases_metric_spec.rb' @@ -3052,7 +3050,6 @@ RSpec/MissingFeatureCategory: - 'spec/lib/gitlab/ci/ansi2json/parser_spec.rb' - 'spec/lib/gitlab/ci/ansi2json/result_spec.rb' - 'spec/lib/gitlab/ci/ansi2json/style_spec.rb' - - 'spec/lib/gitlab/ci/artifact_file_reader_spec.rb' - 'spec/lib/gitlab/ci/artifacts/logger_spec.rb' - 'spec/lib/gitlab/ci/artifacts/metrics_spec.rb' - 'spec/lib/gitlab/ci/badge/coverage/metadata_spec.rb' @@ -3749,7 +3746,6 @@ RSpec/MissingFeatureCategory: - 'spec/lib/gitlab/graphql/batch_key_spec.rb' - 'spec/lib/gitlab/graphql/calls_gitaly/field_extension_spec.rb' - 'spec/lib/gitlab/graphql/copy_field_description_spec.rb' - - 'spec/lib/gitlab/graphql/generic_tracing_spec.rb' - 'spec/lib/gitlab/graphql/known_operations_spec.rb' - 'spec/lib/gitlab/graphql/lazy_spec.rb' - 'spec/lib/gitlab/graphql/limit/field_call_count_spec.rb' diff --git a/.rubocop_todo/rspec/verified_doubles.yml b/.rubocop_todo/rspec/verified_doubles.yml index 3b4d4bc9e94..285dd769e25 100644 --- a/.rubocop_todo/rspec/verified_doubles.yml +++ b/.rubocop_todo/rspec/verified_doubles.yml @@ -578,7 +578,6 @@ RSpec/VerifiedDoubles: - 'spec/lib/gitlab/grape_logging/loggers/urgency_logger_spec.rb' - 'spec/lib/gitlab/graphql/authorize/object_authorization_spec.rb' - 'spec/lib/gitlab/graphql/batch_key_spec.rb' - - 'spec/lib/gitlab/graphql/generic_tracing_spec.rb' - 'spec/lib/gitlab/graphql/lazy_spec.rb' - 'spec/lib/gitlab/graphql/loaders/issuable_loader_spec.rb' - 'spec/lib/gitlab/graphql/present/field_extension_spec.rb' diff --git a/.rubocop_todo/style/empty_method.yml b/.rubocop_todo/style/empty_method.yml index 184e0d926d5..cb3896f0e5a 100644 --- a/.rubocop_todo/style/empty_method.yml +++ b/.rubocop_todo/style/empty_method.yml @@ -7,12 +7,10 @@ Style/EmptyMethod: - 'app/controllers/admin/deploy_keys_controller.rb' - 'app/controllers/admin/identities_controller.rb' - 'app/controllers/admin/labels_controller.rb' - - 'app/controllers/admin/runners_controller.rb' - 'app/controllers/admin/topics_controller.rb' - 'app/controllers/admin/usage_trends_controller.rb' - 'app/controllers/concerns/boards_actions.rb' - 'app/controllers/groups/milestones_controller.rb' - - 'app/controllers/groups/runners_controller.rb' - 'app/controllers/groups/settings/applications_controller.rb' - 'app/controllers/groups/settings/ci_cd_controller.rb' - 'app/controllers/groups/settings/packages_and_registries_controller.rb' @@ -40,7 +38,6 @@ Style/EmptyMethod: - 'app/controllers/projects/mattermosts_controller.rb' - 'app/controllers/projects/pages_domains_controller.rb' - 'app/controllers/projects/pipeline_schedules_controller.rb' - - 'app/controllers/projects/runners_controller.rb' - 'app/controllers/projects/settings/integrations_controller.rb' - 'app/controllers/projects/settings/packages_and_registries_controller.rb' - 'app/controllers/projects/terraform_controller.rb' diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb index 8c1a36e3b58..d312dcc3563 100644 --- a/app/controllers/admin/runners_controller.rb +++ b/app/controllers/admin/runners_controller.rb @@ -8,18 +8,15 @@ class Admin::RunnersController < Admin::ApplicationController feature_category :runner urgency :low - def index - end + def index; end - def show - end + def show; end def edit assign_projects end - def new - end + def new; end def register render_404 unless runner.registration_available? diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb index afc8ce5a5b8..2dd0e36b65f 100644 --- a/app/controllers/groups/runners_controller.rb +++ b/app/controllers/groups/runners_controller.rb @@ -16,11 +16,9 @@ class Groups::RunnersController < Groups::ApplicationController Gitlab::Tracking.event(self.class.name, 'index', user: current_user, namespace: @group) end - def show - end + def show; end - def edit - end + def edit; end def update if Ci::Runners::UpdateRunnerService.new(@runner).execute(runner_params).success? @@ -30,8 +28,7 @@ class Groups::RunnersController < Groups::ApplicationController end end - def new - end + def new; end def register render_404 unless runner.registration_available? diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb index 7df3887e9d4..db19ca23e9f 100644 --- a/app/controllers/projects/runners_controller.rb +++ b/app/controllers/projects/runners_controller.rb @@ -12,8 +12,7 @@ class Projects::RunnersController < Projects::ApplicationController redirect_to project_settings_ci_cd_path(@project, anchor: 'js-runners-settings') end - def edit - end + def edit; end def update if Ci::Runners::UpdateRunnerService.new(@runner).execute(runner_params).success? @@ -23,8 +22,7 @@ class Projects::RunnersController < Projects::ApplicationController end end - def new - end + def new; end def register render_404 unless runner.registration_available? @@ -54,8 +52,7 @@ class Projects::RunnersController < Projects::ApplicationController end end - def show - end + def show; end def toggle_shared_runners update_params = { shared_runners_enabled: !project.shared_runners_enabled } diff --git a/app/graphql/gitlab_schema.rb b/app/graphql/gitlab_schema.rb index eed7959a2f1..0c7195c5be3 100644 --- a/app/graphql/gitlab_schema.rb +++ b/app/graphql/gitlab_schema.rb @@ -15,9 +15,6 @@ class GitlabSchema < GraphQL::Schema use Gitlab::Graphql::Tracers::MetricsTracer use Gitlab::Graphql::Tracers::LoggerTracer - # TODO: Old tracer which will be removed eventually - # See https://gitlab.com/gitlab-org/gitlab/-/issues/345396 - use Gitlab::Graphql::GenericTracing use Gitlab::Graphql::Tracers::TimerTracer use Gitlab::Graphql::Subscriptions::ActionCableWithLoadBalancing diff --git a/app/models/concerns/database_event_tracking.rb b/app/models/concerns/database_event_tracking.rb index 26e184c202f..7e2f445189e 100644 --- a/app/models/concerns/database_event_tracking.rb +++ b/app/models/concerns/database_event_tracking.rb @@ -3,8 +3,6 @@ module DatabaseEventTracking extend ActiveSupport::Concern - FEATURE_FLAG_BATCH2_CLASSES = %w[Vulnerability MergeRequest::Metrics].freeze - included do after_create_commit :publish_database_create_event after_destroy_commit :publish_database_destroy_event @@ -24,9 +22,6 @@ module DatabaseEventTracking end def publish_database_event(name) - return unless database_events_for_class_enabled? - return unless database_events_feature_flag_enabled? - # Gitlab::Tracking#event is triggering Snowplow event # Snowplow events are sent with usage of # https://snowplow.github.io/snowplow-ruby-tracker/SnowplowTracker/AsyncEmitter.html @@ -54,14 +49,4 @@ module DatabaseEventTracking .with_indifferent_access .slice(*self.class::SNOWPLOW_ATTRIBUTES) end - - def database_events_for_class_enabled? - is_batch2 = FEATURE_FLAG_BATCH2_CLASSES.include?(self.class.to_s) - - !is_batch2 || Feature.enabled?(:product_intelligence_database_event_tracking_batch2) - end - - def database_events_feature_flag_enabled? - Feature.enabled?(:product_intelligence_database_event_tracking) - end end diff --git a/app/models/project.rb b/app/models/project.rb index a45b07d94ce..b578f9fdce7 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -692,6 +692,10 @@ class Project < ApplicationRecord scope :with_integration, -> (integration_class) { joins(:integrations).merge(integration_class.all) } scope :with_active_integration, -> (integration_class) { with_integration(integration_class).merge(integration_class.active) } scope :with_shared_runners_enabled, -> { where(shared_runners_enabled: true) } + # .with_slack_integration can generate poorly performing queries. It is intended only for UsagePing. + scope :with_slack_integration, -> { joins(:slack_integration) } + # .with_slack_slash_commands_integration can generate poorly performing queries. It is intended only for UsagePing. + scope :with_slack_slash_commands_integration, -> { joins(:slack_slash_commands_integration) } scope :inside_path, ->(path) do # We need routes alias rs for JOIN so it does not conflict with # includes(:route) which we use in ProjectsFinder. diff --git a/config/feature_flags/development/graphql_generic_tracing_metrics_deactivate.yml b/config/feature_flags/development/graphql_generic_tracing_metrics_deactivate.yml deleted file mode 100644 index c2954e791d6..00000000000 --- a/config/feature_flags/development/graphql_generic_tracing_metrics_deactivate.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: graphql_generic_tracing_metrics_deactivate -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123228 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/415004 -milestone: '16.1' -type: development -group: group::application performance -default_enabled: false diff --git a/config/feature_flags/development/product_intelligence_database_event_tracking.yml b/config/feature_flags/development/product_intelligence_database_event_tracking.yml deleted file mode 100644 index 63b53996eea..00000000000 --- a/config/feature_flags/development/product_intelligence_database_event_tracking.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: product_intelligence_database_event_tracking -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/92079 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/368976 -milestone: '15.3' -type: development -group: group::product intelligence -default_enabled: true diff --git a/config/feature_flags/development/product_intelligence_database_event_tracking_batch2.yml b/config/feature_flags/development/product_intelligence_database_event_tracking_batch2.yml deleted file mode 100644 index 825f684ed8c..00000000000 --- a/config/feature_flags/development/product_intelligence_database_event_tracking_batch2.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: product_intelligence_database_event_tracking_batch2 -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/116125 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/403041 -milestone: '16.0' -type: development -group: group::analytics instrumentation -default_enabled: true diff --git a/config/metrics/counts_28d/20210216175436_projects_slack_notifications_active.yml b/config/metrics/counts_28d/20210216175436_projects_slack_notifications_active.yml new file mode 100644 index 00000000000..46dbe74dde4 --- /dev/null +++ b/config/metrics/counts_28d/20210216175436_projects_slack_notifications_active.yml @@ -0,0 +1,21 @@ +--- +data_category: optional +key_path: usage_activity_by_stage_monthly.configure.projects_slack_notifications_active +description: Unique projects created in the past 28 days that have Slack notifications + enabled +product_section: dev +product_stage: manage +product_group: integrations +value_type: number +status: active +time_frame: 28d +data_source: database +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate +performance_indicator_type: [] +milestone: "<13.9" diff --git a/config/metrics/counts_28d/20210216175437_projects_slack_slash_active.yml b/config/metrics/counts_28d/20210216175437_projects_slack_slash_active.yml new file mode 100644 index 00000000000..cdb00803aad --- /dev/null +++ b/config/metrics/counts_28d/20210216175437_projects_slack_slash_active.yml @@ -0,0 +1,21 @@ +--- +data_category: optional +key_path: usage_activity_by_stage_monthly.configure.projects_slack_slash_active +description: Unique projects created in the past 28 days that have Slack ‘/’ commands + enabled +product_section: dev +product_stage: manage +product_group: integrations +value_type: number +status: active +time_frame: 28d +data_source: database +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate +performance_indicator_type: [] +milestone: "<13.9" diff --git a/config/metrics/counts_all/20210216175400_projects_slack_notifications_active.yml b/config/metrics/counts_all/20210216175400_projects_slack_notifications_active.yml new file mode 100644 index 00000000000..603fcb34053 --- /dev/null +++ b/config/metrics/counts_all/20210216175400_projects_slack_notifications_active.yml @@ -0,0 +1,20 @@ +--- +data_category: optional +key_path: usage_activity_by_stage.configure.projects_slack_notifications_active +description: Unique projects with Slack webhook enabled +product_section: dev +product_stage: manage +product_group: integrations +value_type: number +status: active +time_frame: all +data_source: database +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate +performance_indicator_type: [] +milestone: "<13.9" diff --git a/config/metrics/counts_all/20210216175402_projects_slack_slash_active.yml b/config/metrics/counts_all/20210216175402_projects_slack_slash_active.yml new file mode 100644 index 00000000000..4bbeabd7c87 --- /dev/null +++ b/config/metrics/counts_all/20210216175402_projects_slack_slash_active.yml @@ -0,0 +1,20 @@ +--- +data_category: optional +key_path: usage_activity_by_stage.configure.projects_slack_slash_active +description: Unique projects with Slack ‘/’ commands enabled +product_section: dev +product_stage: manage +product_group: integrations +value_type: number +status: active +time_frame: all +data_source: database +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate +performance_indicator_type: [] +milestone: "<13.9" diff --git a/config/metrics/counts_all/20220607141129_slack_app_installations_gbp.yml b/config/metrics/counts_all/20220607141129_slack_app_installations_gbp.yml new file mode 100644 index 00000000000..70ac24bbe36 --- /dev/null +++ b/config/metrics/counts_all/20220607141129_slack_app_installations_gbp.yml @@ -0,0 +1,21 @@ +--- +key_path: counts.slack_app_installations_gbp +description: Count of Slack app installations using the new GBP version +product_section: dev +product_stage: manage +product_group: integrations +value_type: number +status: active +milestone: "15.1" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89130 +time_frame: all +data_source: database +data_category: optional +instrumentation_class: CountSlackAppInstallationsGbpMetric +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate diff --git a/config/metrics/counts_all/20220607141417_slack_app_installations.yml b/config/metrics/counts_all/20220607141417_slack_app_installations.yml new file mode 100644 index 00000000000..232b3a9ae56 --- /dev/null +++ b/config/metrics/counts_all/20220607141417_slack_app_installations.yml @@ -0,0 +1,21 @@ +--- +key_path: counts.slack_app_installations +description: Count of Slack app installations +product_section: dev +product_stage: manage +product_group: integrations +value_type: number +status: active +milestone: "15.1" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89130 +time_frame: all +data_source: database +data_category: optional +instrumentation_class: CountSlackAppInstallationsMetric +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate diff --git a/db/post_migrate/20230621102941_replace_old_fk_ci_job_artifacts_to_builds_v2.rb b/db/post_migrate/20230621102941_replace_old_fk_ci_job_artifacts_to_builds_v2.rb new file mode 100644 index 00000000000..416b1c629c0 --- /dev/null +++ b/db/post_migrate/20230621102941_replace_old_fk_ci_job_artifacts_to_builds_v2.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class ReplaceOldFkCiJobArtifactsToBuildsV2 < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + def up + return if new_foreign_key_exists? + + with_lock_retries do + remove_foreign_key_if_exists :ci_job_artifacts, :ci_builds, + name: :fk_rails_c5137cb2c1_p, reverse_lock_order: true + + rename_constraint :ci_job_artifacts, :temp_fk_rails_c5137cb2c1_p, :fk_rails_c5137cb2c1_p + end + end + + def down + return unless new_foreign_key_exists? + + add_concurrent_foreign_key :ci_job_artifacts, :ci_builds, + name: :temp_fk_rails_c5137cb2c1_p, + column: [:partition_id, :job_id], + target_column: [:partition_id, :id], + on_update: :cascade, + on_delete: :cascade, + validate: true, + reverse_lock_order: true + + switch_constraint_names :ci_job_artifacts, :fk_rails_c5137cb2c1_p, :temp_fk_rails_c5137cb2c1_p + end + + private + + def new_foreign_key_exists? + foreign_key_exists?(:ci_job_artifacts, :p_ci_builds, name: :fk_rails_c5137cb2c1_p) + end +end diff --git a/db/post_migrate/20230621103000_replace_old_fk_ci_running_builds_to_builds_v2.rb b/db/post_migrate/20230621103000_replace_old_fk_ci_running_builds_to_builds_v2.rb new file mode 100644 index 00000000000..32702eceb17 --- /dev/null +++ b/db/post_migrate/20230621103000_replace_old_fk_ci_running_builds_to_builds_v2.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class ReplaceOldFkCiRunningBuildsToBuildsV2 < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + def up + return if new_foreign_key_exists? + + with_lock_retries do + remove_foreign_key_if_exists :ci_running_builds, :ci_builds, + name: :fk_rails_da45cfa165_p, reverse_lock_order: true + + rename_constraint :ci_running_builds, :temp_fk_rails_da45cfa165_p, :fk_rails_da45cfa165_p + end + end + + def down + return unless new_foreign_key_exists? + + add_concurrent_foreign_key :ci_running_builds, :ci_builds, + name: :temp_fk_rails_da45cfa165_p, + column: [:partition_id, :build_id], + target_column: [:partition_id, :id], + on_update: :cascade, + on_delete: :cascade, + validate: true, + reverse_lock_order: true + + switch_constraint_names :ci_running_builds, :fk_rails_da45cfa165_p, :temp_fk_rails_da45cfa165_p + end + + private + + def new_foreign_key_exists? + foreign_key_exists?(:ci_running_builds, :p_ci_builds, name: :fk_rails_da45cfa165_p) + end +end diff --git a/db/post_migrate/20230621103043_replace_old_fk_ci_job_variables_to_builds_v2.rb b/db/post_migrate/20230621103043_replace_old_fk_ci_job_variables_to_builds_v2.rb new file mode 100644 index 00000000000..68ae3dc56af --- /dev/null +++ b/db/post_migrate/20230621103043_replace_old_fk_ci_job_variables_to_builds_v2.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +class ReplaceOldFkCiJobVariablesToBuildsV2 < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + def up + return if new_foreign_key_exists? + + with_lock_retries do + remove_foreign_key_if_exists :ci_job_variables, :ci_builds, + name: :fk_rails_fbf3b34792_p, reverse_lock_order: true + + rename_constraint :ci_job_variables, :temp_fk_rails_fbf3b34792_p, :fk_rails_fbf3b34792_p + end + end + + def down + return unless new_foreign_key_exists? + + add_concurrent_foreign_key :ci_job_variables, :ci_builds, + name: :temp_fk_rails_fbf3b34792_p, + column: [:partition_id, :job_id], + target_column: [:partition_id, :id], + on_update: :cascade, + on_delete: :cascade, + validate: true, + reverse_lock_order: true + + switch_constraint_names :ci_job_variables, :fk_rails_fbf3b34792_p, :temp_fk_rails_fbf3b34792_p + end + + private + + def new_foreign_key_exists? + foreign_key_exists?(:ci_job_variables, :p_ci_builds, name: :fk_rails_fbf3b34792_p) + end +end diff --git a/db/post_migrate/20230626072436_drop_tmp_index_job_artifacts_id_and_expire_at.rb b/db/post_migrate/20230626072436_drop_tmp_index_job_artifacts_id_and_expire_at.rb new file mode 100644 index 00000000000..3b986a0dc5d --- /dev/null +++ b/db/post_migrate/20230626072436_drop_tmp_index_job_artifacts_id_and_expire_at.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +class DropTmpIndexJobArtifactsIdAndExpireAt < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + TABLE_NAME = :ci_job_artifacts + INDEX_NAME = :tmp_index_ci_job_artifacts_on_id_expire_at_file_type_trace + + EXPIRE_AT_ON_22_MIDNIGHT_IN_TIMEZONE_OR_TRACE = <<~SQL + (EXTRACT(day FROM timezone('UTC', expire_at)) IN (21, 22, 23) + AND EXTRACT(minute FROM timezone('UTC', expire_at)) IN (0, 30, 45) + AND EXTRACT(second FROM timezone('UTC', expire_at)) = 0) + OR file_type = 3 + SQL + + def up + remove_concurrent_index_by_name(TABLE_NAME, INDEX_NAME) + end + + def down + add_concurrent_index( + TABLE_NAME, + :id, + where: EXPIRE_AT_ON_22_MIDNIGHT_IN_TIMEZONE_OR_TRACE, + name: INDEX_NAME + ) + end +end diff --git a/db/schema_migrations/20230621102941 b/db/schema_migrations/20230621102941 new file mode 100644 index 00000000000..10d052d6055 --- /dev/null +++ b/db/schema_migrations/20230621102941 @@ -0,0 +1 @@ +d7e664cb16c66f72c409a5738a48f06a5b56d52409cd41095dedab7f5e9ea065
\ No newline at end of file diff --git a/db/schema_migrations/20230621103000 b/db/schema_migrations/20230621103000 new file mode 100644 index 00000000000..1d0aee1217e --- /dev/null +++ b/db/schema_migrations/20230621103000 @@ -0,0 +1 @@ +9d96b459795c8850ada522769855e2ab6c554ea774a78272baf1db873589f556
\ No newline at end of file diff --git a/db/schema_migrations/20230621103043 b/db/schema_migrations/20230621103043 new file mode 100644 index 00000000000..707105b67c4 --- /dev/null +++ b/db/schema_migrations/20230621103043 @@ -0,0 +1 @@ +b1c7f95cfa972fb23c536d5607b9b1d067e0e8af9e8036170cba6ca913a9c9e0
\ No newline at end of file diff --git a/db/schema_migrations/20230626072436 b/db/schema_migrations/20230626072436 new file mode 100644 index 00000000000..1800699ff54 --- /dev/null +++ b/db/schema_migrations/20230626072436 @@ -0,0 +1 @@ +7169f6ef838ca3992d32b92a8cda4063d147c7ffe64cc382d69ae92eca525d0b
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 876ec746da6..11cbcfc9344 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -33629,8 +33629,6 @@ CREATE INDEX tmp_idx_vulnerability_occurrences_on_id_where_report_type_7_99 ON v CREATE INDEX tmp_index_ci_job_artifacts_on_expire_at_where_locked_unknown ON ci_job_artifacts USING btree (expire_at, job_id) WHERE ((locked = 2) AND (expire_at IS NOT NULL)); -CREATE INDEX tmp_index_ci_job_artifacts_on_id_expire_at_file_type_trace ON ci_job_artifacts USING btree (id) WHERE (((date_part('day'::text, timezone('UTC'::text, expire_at)) = ANY (ARRAY[(21)::double precision, (22)::double precision, (23)::double precision])) AND (date_part('minute'::text, timezone('UTC'::text, expire_at)) = ANY (ARRAY[(0)::double precision, (30)::double precision, (45)::double precision])) AND (date_part('second'::text, timezone('UTC'::text, expire_at)) = (0)::double precision)) OR (file_type = 3)); - CREATE INDEX tmp_index_cis_vulnerability_reads_on_id ON vulnerability_reads USING btree (id) WHERE (report_type = 7); CREATE INDEX tmp_index_for_backfilling_resource_link_events ON system_note_metadata USING btree (id) WHERE (((action)::text = 'relate_to_parent'::text) OR ((action)::text = 'unrelate_from_parent'::text)); diff --git a/doc/api/openapi/openapi.yaml b/doc/api/openapi/openapi.yaml index e090eab1e5d..d89e33a916b 100644 --- a/doc/api/openapi/openapi.yaml +++ b/doc/api/openapi/openapi.yaml @@ -1,14 +1,7 @@ -openapi: 3.0.0 -tags: - - name: metadata - description: Metadata of the GitLab instance - - name: version - description: Version - - name: access_requests - description: Access requests for projects and groups - - name: access_tokens - description: Access tokens for projects +openapi: 3.0.1 info: + title: GitLab API + version: v4 description: | An OpenAPI definition for the GitLab REST API. Few API resources or endpoints are currently included. @@ -20,680 +13,3599 @@ info: The feature uses the current [GitLab session cookie](https://docs.gitlab.com/ee/api/index.html#session-cookie), so each request is made using your account. - Instructions for using this tool can be found in [Interactive API Documentation](https://docs.gitlab.com/ee/api/openapi/openapi_interactive.html). - - version: v4 - title: GitLab API + Instructions for using this tool can be found in [Interactive API Documentation](https://docs.gitlab.com/ee/api/openapi/openapi_interactive.html) termsOfService: 'https://about.gitlab.com/terms/' license: name: CC BY-SA 4.0 url: 'https://gitlab.com/gitlab-org/gitlab/-/blob/master/LICENSE' servers: - - url: 'https://gitlab.com/api/' +- url: https://www.gitlab.com/api/ security: - ApiKeyAuth: [] - -components: - securitySchemes: - ApiKeyAuth: - type: apiKey - in: header - name: Private-Token - +tags: +- name: badges + description: Operations about badges +- name: branches + description: Operations about branches +- name: alert_management + description: Operations about alert_managements +- name: batched_background_migrations + description: Operations about batched_background_migrations +- name: admin + description: Operations about admins +- name: migrations + description: Operations about migrations +- name: applications + description: Operations about applications +- name: avatar + description: Operations about avatars +- name: broadcast_messages + description: Operations about broadcast_messages +- name: bulk_imports + description: Operations about bulk_imports +- name: application + description: Operations about applications +- name: access_requests + description: Operations related to access requests +- name: ci_lint + description: Operations related to linting a CI config file +- name: ci_resource_groups + description: Operations to manage job concurrency with resource groups +- name: ci_variables + description: Operations related to CI/CD variables +- name: cluster_agents + description: Operations related to the GitLab agent for Kubernetes +- name: clusters + description: Operations related to clusters +- name: composer_packages + description: Operations related to Composer packages +- name: conan_packages + description: Operations related to Conan packages +- name: container_registry + description: Operations related to container registry +- name: container_registry_event + description: Operations related to container registry events +- name: dashboard_annotations + description: Operations related to dashboard annotations +- name: debian_distribution + description: Operations related to Debian Linux distributions +- name: debian_packages + description: Operations related to Debian Linux packages +- name: dependency_proxy + description: Operations to manage dependency proxy for a groups +- name: deploy_keys + description: Operations related to deploy keys +- name: deploy_tokens + description: Operations related to deploy tokens +- name: deployments + description: Operations related to deployments +- name: dora_metrics + description: Operations related to DevOps Research and Assessment (DORA) key metrics +- name: environments + description: Operations related to environments +- name: error_tracking_client_keys + description: Operations related to error tracking client keys +- name: error_tracking_project_settings + description: Operations related to error tracking project settings +- name: feature_flags_user_lists + description: Operations related to accessing GitLab feature flag user lists +- name: feature_flags + description: Operations related to feature flags +- name: features + description: Operations related to managing Flipper-based feature flags +- name: freeze_periods + description: Operations related to deploy freeze periods +- name: generic_packages + description: Operations related to Generic packages +- name: geo + description: Operations related to Geo +- name: geo_nodes + description: Operations related Geo Nodes +- name: go_proxy + description: Operations related to Go Proxy +- name: group_export + description: Operations related to exporting groups +- name: group_import + description: Operations related to importing groups +- name: group_packages + description: Operations related to group packages +- name: helm_packages + description: Operations related to Helm packages +- name: integrations + description: Operations related to integrations +- name: issue_links + description: Operations related to issue links +- name: jira_connect_subscriptions + description: Operations related to JiraConnect subscriptions +- name: maven_packages + description: Operations related to Maven packages +- name: merge_requests + description: Operations related to merge requests +- name: metadata + description: Operations related to metadata of the GitLab instance +- name: metrics_user_starred_dashboards + description: Operations related to User-starred metrics dashboards +- name: ml_model_registry + description: Operations related to Model registry +- name: npm_packages + description: Operations related to NPM packages +- name: nuget_packages + description: Operations related to Nuget packages +- name: package_files + description: Operations about package files +- name: plan_limits + description: Operations related to plan limits +- name: project_export + description: Operations related to exporting projects +- name: project_hooks + description: Operations related to project hooks +- name: project_import + description: Operations related to importing projects +- name: project_import_bitbucket + description: Operations related to importing BitBucket projects +- name: project_import_github + description: Operations related to importing GitHub projects +- name: project_packages + description: Operations related to project packages +- name: projects + description: Operations related to projects +- name: protected environments + description: Operations related to protected environments +- name: pypi_packages + description: Operations related to PyPI packages +- name: release_links + description: Operations related to release assets (links) +- name: releases + description: Operations related to releases +- name: resource_milestone_events + description: Operations about resource milestone events +- name: rpm_packages + description: Operations related to RPM packages +- name: rubygem_packages + description: Operations related to RubyGems +- name: suggestions + description: Operations related to suggestions +- name: system_hooks + description: Operations related to system hooks +- name: terraform_state + description: Operations related to Terraform state files +- name: terraform_registry + description: Operations related to the Terraform module registry +- name: unleash_api + description: Operations related to Unleash API paths: - # METADATA - /v4/metadata: - $ref: '#/metadata' - - # VERSION - /v4/version: - $ref: '#/version' - - # ACCESS REQUESTS (PROJECTS) - /v4/projects/{id}/access_requests: - $ref: '#/accessRequestsProjects' - - /v4/projects/{id}/access_requests/{user_id}/approve: - $ref: '#/accessRequestsProjectsApprove' - - /v4/projects/{id}/access_requests/{user_id}: - $ref: '#/accessRequestsProjectsDeny' - - # ACCESS REQUESTS (GROUPS) - /v4/groups/{id}/access_requests: - $ref: '#/accessRequestsGroups' - - /v4/groups/{id}/access_requests/{user_id}/approve: - $ref: '#/accessRequestsGroupsApprove' - - /v4/groups/{id}/access_requests/{user_id}: - $ref: '#/accessRequestsGroupsDeny' - - # ACCESS REQUESTS (PROJECTS) - /v4/projects/{id}/access_tokens: - $ref: '#/accessTokens' - - /v4/projects/{id}/access_tokens/{token_id}: - $ref: '#/accessTokensRevoke' - -metadata: - get: - tags: - - metadata - summary: 'Retrieve metadata information for this GitLab instance.' - operationId: 'getMetadata' - responses: - '401': - description: 'unauthorized operation' - '200': - description: 'successful operation' + /api/v4/groups/{id}/badges/{badge_id}: + get: + tags: + - badges + summary: Gets a badge of a group. + description: This feature was introduced in GitLab 10.6. + operationId: getApiV4GroupsIdBadgesBadgeId + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the group owned by the authenticated + user. + required: true + schema: + type: string + - name: badge_id + in: path + description: The badge ID + required: true + schema: + type: integer + format: int32 + responses: + 200: + description: Gets a badge of a group. + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Badge' + put: + tags: + - badges + summary: Updates a badge of a group. + description: This feature was introduced in GitLab 10.6. + operationId: putApiV4GroupsIdBadgesBadgeId + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the group owned by the authenticated + user. + required: true + schema: + type: string + - name: badge_id + in: path + required: true + schema: + type: integer + format: int32 + requestBody: content: - 'application/json': + application/json: schema: - title: 'MetadataResponse' - type: 'object' properties: - version: - type: 'string' - revision: - type: 'string' - kas: - type: 'object' - properties: - enabled: - type: 'boolean' - externalUrl: - type: 'string' - nullable: true - version: - type: 'string' - nullable: true - examples: - Example: - value: - version: '15.0-pre' - revision: 'c401a659d0c' - kas: - enabled: true - externalUrl: 'grpc://gitlab.example.com:8150' - version: '15.0.0' - -version: - get: - tags: - - version - summary: 'Retrieve version information for this GitLab instance.' - operationId: 'getVersion' - responses: - '401': - description: 'unauthorized operation' - '200': - description: 'successful operation' + link_url: + type: string + description: URL of the badge link + image_url: + type: string + description: URL of the badge image + name: + type: string + description: Name for the badge + responses: + 200: + description: Updates a badge of a group. + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Badge' + delete: + tags: + - badges + summary: Removes a badge from the group. + description: This feature was introduced in GitLab 10.6. + operationId: deleteApiV4GroupsIdBadgesBadgeId + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the group owned by the authenticated + user. + required: true + schema: + type: string + - name: badge_id + in: path + description: The badge ID + required: true + schema: + type: integer + format: int32 + responses: + 204: + description: Removes a badge from the group. + content: {} + /api/v4/groups/{id}/badges: + get: + tags: + - badges + summary: Gets a list of group badges viewable by the authenticated user. + description: This feature was introduced in GitLab 10.6. + operationId: getApiV4GroupsIdBadges + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the group owned by the authenticated + user. + required: true + schema: + type: string + - name: page + in: query + description: Current page number + schema: + type: integer + format: int32 + default: 1 + - name: per_page + in: query + description: Number of items per page + schema: + type: integer + format: int32 + default: 20 + - name: name + in: query + description: Name for the badge + schema: + type: string + responses: + 200: + description: Gets a list of group badges viewable by the authenticated user. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/API_Entities_Badge' + post: + tags: + - badges + summary: Adds a badge to a group. + description: This feature was introduced in GitLab 10.6. + operationId: postApiV4GroupsIdBadges + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the group owned by the authenticated + user. + required: true + schema: + type: string + requestBody: content: - 'application/json': + application/json: schema: - title: 'VersionResponse' - type: 'object' + required: + - image_url + - link_url properties: - version: - type: 'string' - revision: - type: 'string' - examples: - Example: - value: - version: '13.3.0-pre' - revision: 'f2b05afebb0' - -#/v4/projects/{id}/access_requests -accessRequestsProjects: - get: - description: Lists access requests for a project - summary: List access requests for a project - operationId: accessRequestsProjects_get - tags: + link_url: + type: string + description: URL of the badge link + image_url: + type: string + description: URL of the badge image + name: + type: string + description: Name for the badge + required: true + responses: + 201: + description: Adds a badge to a group. + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Badge' + /api/v4/groups/{id}/badges/render: + get: + tags: + - badges + summary: Preview a badge from a group. + description: This feature was introduced in GitLab 10.6. + operationId: getApiV4GroupsIdBadgesRender + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the group owned by the authenticated + user. + required: true + schema: + type: string + - name: link_url + in: query + description: URL of the badge link + required: true + schema: + type: string + - name: image_url + in: query + description: URL of the badge image + required: true + schema: + type: string + responses: + 200: + description: Preview a badge from a group. + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_BasicBadgeDetails' + /api/v4/groups/{id}/access_requests/{user_id}: + delete: + tags: + - access_requests + summary: Denies an access request for the given user. + description: This feature was introduced in GitLab 8.11. + operationId: deleteApiV4GroupsIdAccessRequestsUserId + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the group owned by the authenticated + user + required: true + schema: + type: string + - name: user_id + in: path + description: The user ID of the access requester + required: true + schema: + type: integer + format: int32 + responses: + 204: + description: Denies an access request for the given user. + content: {} + /api/v4/groups/{id}/access_requests/{user_id}/approve: + put: + tags: - access_requests - parameters: + summary: Approves an access request for the given user. + description: This feature was introduced in GitLab 8.11. + operationId: putApiV4GroupsIdAccessRequestsUserIdApprove + parameters: - name: id in: path - description: The ID or URL-encoded path of the project owned by the authenticated user. + description: The ID or URL-encoded path of the group owned by the authenticated + user + required: true + schema: + type: string + - name: user_id + in: path + description: The user ID of the access requester required: true schema: - oneOf: - - type: integer - - type: string - responses: - '401': - description: Unauthorized operation - '200': - description: Successful operation + type: integer + format: int32 + requestBody: content: application/json: schema: - title: ProjectAccessResponse - type: object properties: - id: + access_level: type: integer - usename: - type: string - name: - type: string - state: - type: string - created_at: - type: string - requested_at: - type: string - example: - - 'id': 1 - 'username': 'raymond_smith' - 'name': 'Raymond Smith' - 'state': 'active' - 'created_at': '2012-10-22T14:13:35Z' - 'requested_at': '2012-10-22T14:13:35Z' - - 'id': 2 - 'username': 'john_doe' - 'name': 'John Doe' - 'state': 'active' - 'created_at': '2012-10-22T14:13:35Z' - 'requested_at': '2012-10-22T14:13:35Z' - post: - description: Requests access for the authenticated user to a project - summary: Requests access for the authenticated user to a project - operationId: accessRequestsProjects_post - tags: + description: 'A valid access level (defaults: `30`, the Developer + role)' + format: int32 + default: 30 + responses: + 200: + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_AccessRequester' + successfull_response: + example: + id: 1 + username: raymond_smith + name: Raymond Smith + state: active + created_at: 2012-10-22T14:13:35Z + access_level: 20 + /api/v4/groups/{id}/access_requests: + get: + tags: + - access_requests + summary: Gets a list of access requests for a group. + description: This feature was introduced in GitLab 8.11. + operationId: getApiV4GroupsIdAccessRequests + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the group owned by the authenticated + user + required: true + schema: + type: string + - name: page + in: query + description: Current page number + schema: + type: integer + format: int32 + default: 1 + - name: per_page + in: query + description: Number of items per page + schema: + type: integer + format: int32 + default: 20 + responses: + 200: + description: Gets a list of access requests for a group. + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_AccessRequester' + post: + tags: - access_requests - parameters: + summary: Requests access for the authenticated user to a group. + description: This feature was introduced in GitLab 8.11. + operationId: postApiV4GroupsIdAccessRequests + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the group owned by the authenticated + user + required: true + schema: + type: string + responses: + 200: + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_AccessRequester' + successfull_response: + example: + id: 1 + username: raymond_smith + name: Raymond Smith + state: active + created_at: 2012-10-22T14:13:35Z + access_level: 20 + /api/v4/projects/{id}/repository/merged_branches: + delete: + tags: + - branches + description: Delete all merged branches + operationId: deleteApiV4ProjectsIdRepositoryMergedBranches + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project + required: true + schema: + type: string + responses: + 202: + description: 202 Accepted + content: {} + 404: + description: 404 Project Not Found + content: {} + /api/v4/projects/{id}/repository/branches/{branch}: + get: + tags: + - branches + description: Get a single repository branch + operationId: getApiV4ProjectsIdRepositoryBranchesBranch + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project + required: true + schema: + type: string + - name: branch + in: path + required: true + schema: + type: integer + format: int32 + responses: + 200: + description: Get a single repository branch + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Branch' + 404: + description: Branch Not Found + content: {} + delete: + tags: + - branches + description: Delete a branch + operationId: deleteApiV4ProjectsIdRepositoryBranchesBranch + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project + required: true + schema: + type: string + - name: branch + in: path + description: The name of the branch + required: true + schema: + type: string + responses: + 204: + description: Delete a branch + content: {} + 404: + description: Branch Not Found + content: {} + head: + tags: + - branches + description: Check if a branch exists + operationId: headApiV4ProjectsIdRepositoryBranchesBranch + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project + required: true + schema: + type: string + - name: branch + in: path + description: The name of the branch + required: true + schema: + type: string + responses: + 204: + description: No Content + content: {} + 404: + description: Not Found + content: {} + /api/v4/projects/{id}/repository/branches: + get: + tags: + - branches + description: Get a project repository branches + operationId: getApiV4ProjectsIdRepositoryBranches + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project + required: true + schema: + type: string + - name: page + in: query + description: Current page number + schema: + type: integer + format: int32 + default: 1 + - name: per_page + in: query + description: Number of items per page + schema: + type: integer + format: int32 + default: 20 + - name: search + in: query + description: Return list of branches matching the search criteria + schema: + type: string + - name: regex + in: query + description: Return list of branches matching the regex + schema: + type: string + - name: sort + in: query + description: Return list of branches sorted by the given field + schema: + type: string + enum: + - name_asc + - updated_asc + - updated_desc + - name: page_token + in: query + description: Name of branch to start the pagination from + schema: + type: string + responses: + 200: + description: Get a project repository branches + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/API_Entities_Branch' + 404: + description: 404 Project Not Found + content: {} + post: + tags: + - branches + description: Create branch + operationId: postApiV4ProjectsIdRepositoryBranches + parameters: - name: id in: path - description: The ID or URL-encoded path of the project owned by the authenticated user. + description: The ID or URL-encoded path of the project required: true schema: - oneOf: - - type: integer - - type: string - responses: - '401': - description: Unauthorized operation - '200': - description: Successful operation + type: string + requestBody: content: application/json: schema: - title: ProjectAccessRequest - type: object + required: + - branch + - ref properties: - id: - type: integer - usename: + branch: type: string - name: + description: The name of the branch + ref: type: string - state: + description: Create branch from commit sha or existing branch + required: true + responses: + 201: + description: Create branch + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Branch' + 400: + description: Failed to create branch + content: {} + /api/v4/projects/{id}/repository/branches/{branch}/unprotect: + put: + tags: + - branches + description: Unprotect a single branch + operationId: putApiV4ProjectsIdRepositoryBranchesBranchUnprotect + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project + required: true + schema: + type: string + - name: branch + in: path + description: The name of the branch + required: true + schema: + type: string + responses: + 200: + description: Unprotect a single branch + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Branch' + 404: + description: 404 Project Not Found + content: {} + /api/v4/projects/{id}/repository/branches/{branch}/protect: + put: + tags: + - branches + description: Protect a single branch + operationId: putApiV4ProjectsIdRepositoryBranchesBranchProtect + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project + required: true + schema: + type: string + - name: branch + in: path + description: The name of the branch + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + properties: + developers_can_push: + type: boolean + description: Flag if developers can push to that branch + developers_can_merge: + type: boolean + description: Flag if developers can merge to that branch + responses: + 200: + description: Protect a single branch + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Branch' + 404: + description: 404 Branch Not Found + content: {} + /api/v4/projects/{id}/badges/{badge_id}: + get: + tags: + - badges + summary: Gets a badge of a project. + description: This feature was introduced in GitLab 10.6. + operationId: getApiV4ProjectsIdBadgesBadgeId + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project owned by the authenticated + user. + required: true + schema: + type: string + - name: badge_id + in: path + description: The badge ID + required: true + schema: + type: integer + format: int32 + responses: + 200: + description: Gets a badge of a project. + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Badge' + put: + tags: + - badges + summary: Updates a badge of a project. + description: This feature was introduced in GitLab 10.6. + operationId: putApiV4ProjectsIdBadgesBadgeId + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project owned by the authenticated + user. + required: true + schema: + type: string + - name: badge_id + in: path + required: true + schema: + type: integer + format: int32 + requestBody: + content: + application/json: + schema: + properties: + link_url: type: string - created_at: + description: URL of the badge link + image_url: type: string - requested_at: + description: URL of the badge image + name: type: string - example: - 'id': 1 - 'username': 'raymond_smith' - 'name': 'Raymond Smith' - 'state': 'active' - 'created_at': '2012-10-22T14:13:35Z' - 'requested_at': '2012-10-22T14:13:35Z' - -#/v4/projects/{id}/access_requests/{user_id}/approve -accessRequestsProjectsApprove: - put: - description: Approves access for the authenticated user to a project - summary: Approves access for the authenticated user to a project - operationId: accessRequestsProjectsApprove_put - tags: - - access_requests - parameters: + description: Name for the badge + responses: + 200: + description: Updates a badge of a project. + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Badge' + delete: + tags: + - badges + summary: Removes a badge from the project. + description: This feature was introduced in GitLab 10.6. + operationId: deleteApiV4ProjectsIdBadgesBadgeId + parameters: - name: id in: path - description: The ID or URL-encoded path of the project owned by the authenticated user. + description: The ID or URL-encoded path of the project owned by the authenticated + user. required: true schema: - oneOf: - - type: integer - - type: string - - name: user_id + type: string + - name: badge_id in: path - description: The userID of the access requester + description: The badge ID required: true schema: type: integer - - name: access_level + format: int32 + responses: + 204: + description: Removes a badge from the project. + content: {} + /api/v4/projects/{id}/badges: + get: + tags: + - badges + summary: Gets a list of project badges viewable by the authenticated user. + description: This feature was introduced in GitLab 10.6. + operationId: getApiV4ProjectsIdBadges + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project owned by the authenticated + user. + required: true + schema: + type: string + - name: page in: query - description: A valid project access level. 0 = no access , 10 = guest, 20 = reporter, 30 = developer, 40 = Maintainer. Default is 30.' - required: false + description: Current page number schema: - enum: [0, 10, 20, 30, 40] - default: 30 type: integer - responses: - '401': - description: Unauthorized operation - '200': - description: Successful operation + format: int32 + default: 1 + - name: per_page + in: query + description: Number of items per page + schema: + type: integer + format: int32 + default: 20 + - name: name + in: query + description: Name for the badge + schema: + type: string + responses: + 200: + description: Gets a list of project badges viewable by the authenticated + user. + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/API_Entities_Badge' + post: + tags: + - badges + summary: Adds a badge to a project. + description: This feature was introduced in GitLab 10.6. + operationId: postApiV4ProjectsIdBadges + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project owned by the authenticated + user. + required: true + schema: + type: string + requestBody: content: application/json: schema: - title: ProjectAccessApprove - type: object + required: + - image_url + - link_url properties: - id: - type: integer - usename: + link_url: type: string - name: - type: string - state: + description: URL of the badge link + image_url: type: string - created_at: + description: URL of the badge image + name: type: string - access_level: - type: integer - example: - 'id': 1 - 'username': 'raymond_smith' - 'name': 'Raymond Smith' - 'state': 'active' - 'created_at': '2012-10-22T14:13:35Z' - 'access_level': 20 - -#/v4/projects/{id}/access_requests/{user_id} -accessRequestsProjectsDeny: - delete: - description: Denies a project access request for the given user - summary: Denies a project access request for the given user - operationId: accessRequestProjectsDeny_delete - tags: + description: Name for the badge + required: true + responses: + 201: + description: Adds a badge to a project. + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Badge' + /api/v4/projects/{id}/badges/render: + get: + tags: + - badges + summary: Preview a badge from a project. + description: This feature was introduced in GitLab 10.6. + operationId: getApiV4ProjectsIdBadgesRender + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project owned by the authenticated + user. + required: true + schema: + type: string + - name: link_url + in: query + description: URL of the badge link + required: true + schema: + type: string + - name: image_url + in: query + description: URL of the badge image + required: true + schema: + type: string + responses: + 200: + description: Preview a badge from a project. + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_BasicBadgeDetails' + /api/v4/projects/{id}/access_requests/{user_id}: + delete: + tags: - access_requests - parameters: + summary: Denies an access request for the given user. + description: This feature was introduced in GitLab 8.11. + operationId: deleteApiV4ProjectsIdAccessRequestsUserId + parameters: - name: id in: path - description: The ID or URL-encoded path of the project owned by the authenticated user. + description: The ID or URL-encoded path of the project owned by the authenticated + user required: true schema: - oneOf: - - type: integer - - type: string + type: string - name: user_id in: path description: The user ID of the access requester required: true schema: type: integer - responses: # Does anything go here? Markdown doc does not list a response. - '401': - description: Unauthorized operation - '200': - description: Successful operation - -#/v4/groups/{id}/access_requests -accessRequestsGroups: - get: - description: List access requests for a group - summary: List access requests for a group - operationId: accessRequestsGroups_get - tags: + format: int32 + responses: + 204: + description: Denies an access request for the given user. + content: {} + /api/v4/projects/{id}/access_requests/{user_id}/approve: + put: + tags: - access_requests - parameters: + summary: Approves an access request for the given user. + description: This feature was introduced in GitLab 8.11. + operationId: putApiV4ProjectsIdAccessRequestsUserIdApprove + parameters: - name: id in: path - description: The ID or URL-encoded path of the group owned by the authenticated user. + description: The ID or URL-encoded path of the project owned by the authenticated + user + required: true + schema: + type: string + - name: user_id + in: path + description: The user ID of the access requester required: true schema: - oneOf: - - type: integer - - type: string - responses: - '401': - description: Unauthorized operation - '200': - description: Successful operation + type: integer + format: int32 + requestBody: content: application/json: schema: - title: GroupAccessResponse - type: object properties: - id: + access_level: type: integer - usename: - type: string - name: - type: string - state: - type: string - created_at: - type: string - requested_at: - type: string - example: - - 'id': 1 - 'username': 'raymond_smith' - 'name': 'Raymond Smith' - 'state': 'active' - 'created_at': '2012-10-22T14:13:35Z' - 'requested_at': '2012-10-22T14:13:35Z' - - 'id': 2 - 'username': 'john_doe' - 'name': 'John Doe' - 'state': 'active' - 'created_at': '2012-10-22T14:13:35Z' - 'requested_at': '2012-10-22T14:13:35Z' - post: - description: Requests access for the authenticated user to a group - summary: Requests access for the authenticated user to a group - operationId: accessRequestsGroups_post - tags: + description: 'A valid access level (defaults: `30`, the Developer + role)' + format: int32 + default: 30 + responses: + 200: + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_AccessRequester' + successfull_response: + example: + id: 1 + username: raymond_smith + name: Raymond Smith + state: active + created_at: 2012-10-22T14:13:35Z + access_level: 20 + /api/v4/projects/{id}/access_requests: + get: + tags: - access_requests - parameters: + summary: Gets a list of access requests for a project. + description: This feature was introduced in GitLab 8.11. + operationId: getApiV4ProjectsIdAccessRequests + parameters: - name: id in: path - description: The ID or URL-encoded path of the group owned by the authenticated user. + description: The ID or URL-encoded path of the project owned by the authenticated + user required: true schema: - oneOf: - - type: integer - - type: string - responses: - '401': - description: Unauthorized operation - '200': - description: Successful operation + type: string + - name: page + in: query + description: Current page number + schema: + type: integer + format: int32 + default: 1 + - name: per_page + in: query + description: Number of items per page + schema: + type: integer + format: int32 + default: 20 + responses: + 200: + description: Gets a list of access requests for a project. + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_AccessRequester' + post: + tags: + - access_requests + summary: Requests access for the authenticated user to a project. + description: This feature was introduced in GitLab 8.11. + operationId: postApiV4ProjectsIdAccessRequests + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project owned by the authenticated + user + required: true + schema: + type: string + responses: + 200: + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_AccessRequester' + successfull_response: + example: + id: 1 + username: raymond_smith + name: Raymond Smith + state: active + created_at: 2012-10-22T14:13:35Z + access_level: 20 + /api/v4/projects/{id}/alert_management_alerts/{alert_iid}/metric_images/{metric_image_id}: + put: + tags: + - alert_management + description: Update a metric image for an alert + operationId: putApiV4ProjectsIdAlertManagementAlertsAlertIidMetricImagesMetricImageId + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project + required: true + schema: + type: string + - name: alert_iid + in: path + description: The IID of the Alert + required: true + schema: + type: integer + format: int32 + - name: metric_image_id + in: path + description: The ID of metric image + required: true + schema: + type: integer + format: int32 + requestBody: content: - application/json: + multipart/form-data: schema: - title: GroupAccessRequest - type: object properties: - id: - type: integer - usename: + url: type: string - name: + description: The url to view more metric info + url_text: type: string - state: + description: A description of the image or URL + responses: + 200: + description: Update a metric image for an alert + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_MetricImage' + 403: + description: Forbidden + content: {} + 422: + description: Unprocessable entity + content: {} + delete: + tags: + - alert_management + description: Remove a metric image for an alert + operationId: deleteApiV4ProjectsIdAlertManagementAlertsAlertIidMetricImagesMetricImageId + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project + required: true + schema: + type: string + - name: alert_iid + in: path + description: The IID of the Alert + required: true + schema: + type: integer + format: int32 + - name: metric_image_id + in: path + description: The ID of metric image + required: true + schema: + type: integer + format: int32 + responses: + 204: + description: Remove a metric image for an alert + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_MetricImage' + 403: + description: Forbidden + content: {} + 422: + description: Unprocessable entity + content: {} + /api/v4/projects/{id}/alert_management_alerts/{alert_iid}/metric_images: + get: + tags: + - alert_management + description: Metric Images for alert + operationId: getApiV4ProjectsIdAlertManagementAlertsAlertIidMetricImages + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project + required: true + schema: + type: string + - name: alert_iid + in: path + description: The IID of the Alert + required: true + schema: + type: integer + format: int32 + responses: + 200: + description: Metric Images for alert + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/API_Entities_MetricImage' + 404: + description: Not found + content: {} + post: + tags: + - alert_management + description: Upload a metric image for an alert + operationId: postApiV4ProjectsIdAlertManagementAlertsAlertIidMetricImages + parameters: + - name: id + in: path + description: The ID or URL-encoded path of the project + required: true + schema: + type: string + - name: alert_iid + in: path + description: The IID of the Alert + required: true + schema: + type: integer + format: int32 + requestBody: + content: + multipart/form-data: + schema: + required: + - file + properties: + file: type: string - created_at: + description: The image file to be uploaded + format: binary + url: type: string - requested_at: + description: The url to view more metric info + url_text: type: string - example: - 'id': 1 - 'username': 'raymond_smith' - 'name': 'Raymond Smith' - 'state': 'active' - 'created_at': '2012-10-22T14:13:35Z' - 'requested_at': '2012-10-22T14:13:35Z' - -#/v4/groups/{id}/access_requests/{user_id}/approve -accessRequestsGroupsApprove: - put: - description: Approves access for the authenticated user to a group - summary: Approves access for the authenticated user to a group - operationId: accessRequestsGroupsApprove_put - tags: - - access_requests - parameters: + description: A description of the image or URL + required: true + responses: + 200: + description: Upload a metric image for an alert + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_MetricImage' + 403: + description: Forbidden + content: {} + /api/v4/projects/{id}/alert_management_alerts/{alert_iid}/metric_images/authorize: + post: + tags: + - alert_management + description: Workhorse authorize metric image file upload + operationId: postApiV4ProjectsIdAlertManagementAlertsAlertIidMetricImagesAuthorize + parameters: - name: id in: path - description: The ID or URL-encoded path of the group owned by the authenticated user. + description: The ID or URL-encoded path of the project required: true schema: - oneOf: - - type: integer - - type: string - - name: user_id + type: string + - name: alert_iid in: path - description: The userID of the access requester + description: The IID of the Alert required: true schema: type: integer - - name: access_level + format: int32 + responses: + 200: + description: Workhorse authorize metric image file upload + content: {} + 403: + description: Forbidden + content: {} + /api/v4/admin/batched_background_migrations/{id}: + get: + tags: + - batched_background_migrations + description: Retrieve a batched background migration + operationId: getApiV4AdminBatchedBackgroundMigrationsId + parameters: + - name: database in: query - description: A valid group access level. 0 = no access , 10 = Guest, 20 = Reporter, 30 = Developer, 40 = Maintainer, 50 = Owner. Default is 30. - required: false + description: The name of the database + schema: + type: string + default: main + enum: + - main + - ci + - embedding + - main_clusterwide + - geo + - name: id + in: path + description: The batched background migration id + required: true schema: - enum: [0, 10, 20, 30, 40, 50] - default: 30 type: integer - responses: - '401': - description: Unauthorized operation - '200': - description: Successful operation + format: int32 + responses: + 200: + description: Retrieve a batched background migration + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_BatchedBackgroundMigration' + 401: + description: 401 Unauthorized + content: {} + 403: + description: 403 Forbidden + content: {} + 404: + description: 404 Not found + content: {} + /api/v4/admin/batched_background_migrations: + get: + tags: + - batched_background_migrations + description: Get the list of batched background migrations + operationId: getApiV4AdminBatchedBackgroundMigrations + parameters: + - name: database + in: query + description: The name of the database, the default `main` + schema: + type: string + default: main + enum: + - main + - ci + - embedding + - main_clusterwide + - geo + responses: + 200: + description: Get the list of batched background migrations + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/API_Entities_BatchedBackgroundMigration' + 401: + description: 401 Unauthorized + content: {} + 403: + description: 403 Forbidden + content: {} + /api/v4/admin/batched_background_migrations/{id}/resume: + put: + tags: + - batched_background_migrations + description: Resume a batched background migration + operationId: putApiV4AdminBatchedBackgroundMigrationsIdResume + parameters: + - name: id + in: path + description: The batched background migration id + required: true + schema: + type: integer + format: int32 + requestBody: content: application/json: schema: - title: GroupAccessApprove - type: object properties: - id: - type: integer - usename: + database: type: string - name: + description: The name of the database + default: main + enum: + - main + - ci + - embedding + - main_clusterwide + - geo + responses: + 200: + description: Resume a batched background migration + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_BatchedBackgroundMigration' + 401: + description: 401 Unauthorized + content: {} + 403: + description: 403 Forbidden + content: {} + 404: + description: 404 Not found + content: {} + 422: + description: You can resume only `paused` batched background migrations. + content: {} + /api/v4/admin/batched_background_migrations/{id}/pause: + put: + tags: + - batched_background_migrations + description: Pause a batched background migration + operationId: putApiV4AdminBatchedBackgroundMigrationsIdPause + parameters: + - name: id + in: path + description: The batched background migration id + required: true + schema: + type: integer + format: int32 + requestBody: + content: + application/json: + schema: + properties: + database: type: string - state: + description: The name of the database + default: main + enum: + - main + - ci + - embedding + - main_clusterwide + - geo + responses: + 200: + description: Pause a batched background migration + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_BatchedBackgroundMigration' + 401: + description: 401 Unauthorized + content: {} + 403: + description: 403 Forbidden + content: {} + 404: + description: 404 Not found + content: {} + 422: + description: You can pause only `active` batched background migrations. + content: {} + /api/v4/admin/ci/variables/{key}: + get: + tags: + - ci_variables + description: Get the details of a specific instance-level variable + operationId: getApiV4AdminCiVariablesKey + parameters: + - name: key + in: path + description: The key of a variable + required: true + schema: + type: string + responses: + 200: + description: Get the details of a specific instance-level variable + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Ci_Variable' + 404: + description: Instance Variable Not Found + content: {} + put: + tags: + - ci_variables + description: Update an instance-level variable + operationId: putApiV4AdminCiVariablesKey + parameters: + - name: key + in: path + description: The key of a variable + required: true + schema: + type: string + requestBody: + content: + application/json: + schema: + properties: + value: type: string - created_at: + description: The value of a variable + protected: + type: boolean + description: Whether the variable is protected + masked: + type: boolean + description: Whether the variable is masked + raw: + type: boolean + description: Whether the variable will be expanded + variable_type: type: string - access_level: - type: integer - example: - 'id': 1 - 'username': 'raymond_smith' - 'name': 'Raymond Smith' - 'state': 'active' - 'created_at': '2012-10-22T14:13:35Z' - 'access_level': 20 - -#/v4/groups/{id}/access_requests/{user_id} -accessRequestsGroupsDeny: - delete: - description: Denies a group access request for the given user - summary: Denies a group access request for the given user - operationId: accessRequestsGroupsDeny_delete - tags: - - access_requests - parameters: - - name: id + description: 'The type of a variable. Available types are: env_var + (default) and file' + enum: + - env_var + - file + responses: + 200: + description: Update an instance-level variable + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Ci_Variable' + 404: + description: Instance Variable Not Found + content: {} + delete: + tags: + - ci_variables + description: Delete an existing instance-level variable + operationId: deleteApiV4AdminCiVariablesKey + parameters: + - name: key in: path - description: The ID or URL-encoded path of the group owned by the authenticated user. + description: The key of a variable required: true schema: - oneOf: - - type: integer - - type: string - - name: user_id + type: string + responses: + 204: + description: Delete an existing instance-level variable + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Ci_Variable' + 404: + description: Instance Variable Not Found + content: {} + /api/v4/admin/ci/variables: + get: + tags: + - ci_variables + description: List all instance-level variables + operationId: getApiV4AdminCiVariables + parameters: + - name: page + in: query + description: Current page number + schema: + type: integer + format: int32 + default: 1 + - name: per_page + in: query + description: Number of items per page + schema: + type: integer + format: int32 + default: 20 + responses: + 200: + description: List all instance-level variables + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Ci_Variable' + post: + tags: + - ci_variables + description: Create a new instance-level variable + operationId: postApiV4AdminCiVariables + requestBody: + content: + application/json: + schema: + required: + - key + - value + properties: + key: + type: string + description: The key of the variable. Max 255 characters + value: + type: string + description: The value of a variable + protected: + type: boolean + description: Whether the variable is protected + masked: + type: boolean + description: Whether the variable is masked + raw: + type: boolean + description: Whether the variable will be expanded + variable_type: + type: string + description: 'The type of a variable. Available types are: env_var + (default) and file' + enum: + - env_var + - file + required: true + responses: + 201: + description: Create a new instance-level variable + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Ci_Variable' + 400: + description: 400 Bad Request + content: {} + /api/v4/admin/databases/{database_name}/dictionary/tables/{table_name}: + get: + tags: + - admin + description: Retrieve dictionary details + operationId: getApiV4AdminDatabasesDatabaseNameDictionaryTablesTableName + parameters: + - name: database_name + in: path + description: The database name + required: true + schema: + type: string + enum: + - main + - ci + - name: table_name in: path - description: The userID of the access requester + description: The table name + required: true + schema: + type: string + responses: + 200: + description: Retrieve dictionary details + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Dictionary_Table' + 401: + description: 401 Unauthorized + content: {} + 403: + description: 403 Forbidden + content: {} + 404: + description: 404 Not found + content: {} + /api/v4/admin/clusters/{cluster_id}: + get: + tags: + - clusters + summary: Get a single instance cluster + description: This feature was introduced in GitLab 13.2. Returns a single instance + cluster. + operationId: getApiV4AdminClustersClusterId + parameters: + - name: cluster_id + in: path + description: The cluster ID required: true schema: type: integer - responses: # Does anything go here? Markdown doc does not list a response. - '401': - description: Unauthorized operation - '200': - description: Successful operation -#/v4/projects/{id}/access_tokens -accessTokens: - get: - description: Lists access tokens for a project - summary: List access tokens for a project - operationId: accessTokens_get - tags: - - access_tokens - parameters: - - name: id + format: int32 + responses: + 200: + description: Get a single instance cluster + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Cluster' + 403: + description: Forbidden + content: {} + 404: + description: Not found + content: {} + put: + tags: + - clusters + summary: Edit instance cluster + description: This feature was introduced in GitLab 13.2. Updates an existing + instance cluster. + operationId: putApiV4AdminClustersClusterId + parameters: + - name: cluster_id in: path - description: The ID or URL-encoded path of the project + description: The cluster ID required: true schema: - oneOf: - - type: integer - - type: string - responses: - '404': - description: Not Found - '401': - description: Unauthorized operation - '200': - description: Successful operation + type: integer + format: int32 + requestBody: content: application/json: schema: - title: AccessTokenList - type: object properties: - user_id: - type: integer - scopes: - type: array name: type: string - expires_at: - type: date - id: + description: Cluster name + enabled: + type: boolean + description: Enable or disable Gitlab's connection to your Kubernetes + cluster + environment_scope: + type: string + description: The associated environment to the cluster + namespace_per_environment: + type: boolean + description: Deploy each environment to a separate Kubernetes namespace + default: true + domain: + type: string + description: Cluster base domain + management_project_id: type: integer - active: + description: The ID of the management project + format: int32 + managed: type: boolean - created_at: - type: date - revoked: + description: Determines if GitLab will manage namespaces and service + accounts for this cluster + platform_kubernetes_attributes[api_url]: + type: string + description: URL to access the Kubernetes API + platform_kubernetes_attributes[token]: + type: string + description: Token to authenticate against Kubernetes + platform_kubernetes_attributes[ca_cert]: + type: string + description: TLS certificate (needed if API is using a self-signed + TLS certificate) + platform_kubernetes_attributes[namespace]: + type: string + description: Unique namespace related to Project + responses: + 200: + description: Edit instance cluster + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Cluster' + 400: + description: Validation error + content: {} + 403: + description: Forbidden + content: {} + 404: + description: Not found + content: {} + delete: + tags: + - clusters + summary: Delete instance cluster + description: This feature was introduced in GitLab 13.2. Deletes an existing + instance cluster. Does not remove existing resources within the connected + Kubernetes cluster. + operationId: deleteApiV4AdminClustersClusterId + parameters: + - name: cluster_id + in: path + description: The cluster ID + required: true + schema: + type: integer + format: int32 + responses: + 204: + description: Delete instance cluster + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Cluster' + 403: + description: Forbidden + content: {} + 404: + description: Not found + content: {} + /api/v4/admin/clusters/add: + post: + tags: + - clusters + summary: Add existing instance cluster + description: This feature was introduced in GitLab 13.2. Adds an existing Kubernetes + instance cluster. + operationId: postApiV4AdminClustersAdd + requestBody: + content: + application/json: + schema: + required: + - name + - platform_kubernetes_attributes[api_url] + - platform_kubernetes_attributes[token] + properties: + name: + type: string + description: Cluster name + enabled: + type: boolean + description: Determines if cluster is active or not, defaults to + true + default: true + environment_scope: + type: string + description: The associated environment to the cluster + default: '*' + namespace_per_environment: + type: boolean + description: Deploy each environment to a separate Kubernetes namespace + default: true + domain: + type: string + description: Cluster base domain + management_project_id: + type: integer + description: The ID of the management project + format: int32 + managed: type: boolean - example: - 'user_id': 141 - 'scopes': ['api'] - 'name': 'token' - 'expires_at': '2022-01-31' - 'id': 42 - 'active': true - 'created_at': '2021-01-20T14:13:35Z' - 'revoked': false - post: - description: Creates an access token for a project - summary: Creates an access token for a project - operationId: accessTokens_post - tags: - - access_tokens - parameters: + description: Determines if GitLab will manage namespaces and service + accounts for this cluster, defaults to true + default: true + platform_kubernetes_attributes[api_url]: + type: string + description: URL to access the Kubernetes API + platform_kubernetes_attributes[token]: + type: string + description: Token to authenticate against Kubernetes + platform_kubernetes_attributes[ca_cert]: + type: string + description: TLS certificate (needed if API is using a self-signed + TLS certificate) + platform_kubernetes_attributes[namespace]: + type: string + description: Unique namespace related to Project + platform_kubernetes_attributes[authorization_type]: + type: string + description: Cluster authorization type, defaults to RBAC + default: rbac + enum: + - unknown_authorization + - rbac + - abac + required: true + responses: + 201: + description: Add existing instance cluster + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Cluster' + 400: + description: Validation error + content: {} + 403: + description: Forbidden + content: {} + 404: + description: Not found + content: {} + /api/v4/admin/clusters: + get: + tags: + - clusters + summary: List instance clusters + description: This feature was introduced in GitLab 13.2. Returns a list of instance + clusters. + operationId: getApiV4AdminClusters + responses: + 200: + description: List instance clusters + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/API_Entities_Cluster' + 403: + description: Forbidden + content: {} + /api/v4/admin/migrations/{timestamp}/mark: + post: + tags: + - migrations + description: Mark the migration as successfully executed + operationId: postApiV4AdminMigrationsTimestampMark + parameters: + - name: timestamp + in: path + description: The migration version timestamp + required: true + schema: + type: integer + format: int32 + requestBody: + content: + application/json: + schema: + properties: + database: + type: string + description: The name of the database + default: main + enum: + - main + - ci + - embedding + - main_clusterwide + - geo + responses: + 201: + description: 201 Created + content: {} + 401: + description: 401 Unauthorized + content: {} + 403: + description: 403 Forbidden + content: {} + 404: + description: 404 Not found + content: {} + 422: + description: You can mark only pending migrations + content: {} + /api/v4/applications/{id}: + delete: + tags: + - applications + summary: Delete an application + description: Delete a specific application + operationId: deleteApiV4ApplicationsId + parameters: - name: id in: path - description: The ID or URL-encoded path of the project + description: The ID of the application (not the application_id) required: true schema: - oneOf: - - type: integer - - type: string - - name: name + type: integer + format: int32 + responses: + 204: + description: Delete an application + content: {} + /api/v4/applications: + get: + tags: + - applications + summary: Get applications + description: List all registered applications + operationId: getApiV4Applications + responses: + 200: + description: Get applications + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/API_Entities_Application' + post: + tags: + - applications + summary: Create a new application + description: This feature was introduced in GitLab 10.5 + operationId: postApiV4Applications + requestBody: + content: + application/json: + schema: + required: + - name + - redirect_uri + - scopes + properties: + name: + type: string + description: Name of the application. + redirect_uri: + type: string + description: Redirect URI of the application. + scopes: + type: string + description: |- + Scopes of the application. You can specify multiple scopes by separating\ + each scope using a space + confidential: + type: boolean + description: |- + The application is used where the client secret can be kept confidential. Native mobile apps \ + and Single Page Apps are considered non-confidential. Defaults to true if not supplied + default: true + required: true + responses: + 200: + description: Create a new application + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_ApplicationWithSecret' + /api/v4/avatar: + get: + tags: + - avatar + description: Return avatar url for a user + operationId: getApiV4Avatar + parameters: + - name: email in: query - description: The name of the project access token + description: Public email address of the user required: true schema: type: string - - name: scopes + - name: size in: query - description: Defines read and write permissions for the token + description: Single pixel dimension for Gravatar images + schema: + type: integer + format: int32 + responses: + 200: + description: Return avatar url for a user + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Avatar' + /api/v4/broadcast_messages/{id}: + get: + tags: + - broadcast_messages + summary: Get a specific broadcast message + description: This feature was introduced in GitLab 8.12. + operationId: getApiV4BroadcastMessagesId + parameters: + - name: id + in: path + description: Broadcast message ID required: true schema: - type: array - items: - type: string - enum: - [ - 'api', - 'read_api', - 'read_registry', - 'write_registry', - 'read_repository', - 'write_repository', - ] - - name: expires_at - in: query - description: Date when the token expires. Time of day is Midnight UTC of that date. - required: false - schema: - type: date - responses: - '404': - description: Not Found - '401': - description: Unauthorized operation - '200': - description: Successful operation + type: integer + format: int32 + responses: + 200: + description: Get a specific broadcast message + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_BroadcastMessage' + put: + tags: + - broadcast_messages + summary: Update a broadcast message + description: This feature was introduced in GitLab 8.12. + operationId: putApiV4BroadcastMessagesId + parameters: + - name: id + in: path + description: Broadcast message ID + required: true + schema: + type: integer + format: int32 + requestBody: content: application/json: schema: - title: AccessTokenList - type: object properties: - user_id: - type: integer - scopes: + message: + type: string + description: Message to display + starts_at: + type: string + description: Starting time + format: date-time + ends_at: + type: string + description: Ending time + format: date-time + color: + type: string + description: Background color + font: + type: string + description: Foreground color + target_access_levels: type: array - name: + description: Target user roles + items: + type: integer + format: int32 + enum: + - 10 + - 20 + - 30 + - 40 + - 50 + target_path: type: string - expires_at: - type: date - id: - type: integer - active: - type: boolean - created_at: - type: date - revoked: + description: Target path + broadcast_type: + type: string + description: Broadcast Type + enum: + - banner + - notification + dismissable: type: boolean - token: - type: string - example: - 'user_id': 166 - 'scopes': ['api', 'read_repository'] - 'name': 'test' - 'expires_at': '2022-01-31' - 'id': 58 - 'active': true - 'created_at': '2021-01-20T14:13:35Z' - 'revoked': false - 'token': 'D4y...Wzr' - -#/v4/projects/{id}/access_tokens/{token_id} -accessTokensRevoke: - delete: - description: Revokes an access token - summary: Revokes an access token - operationId: accessTokens_delete - tags: - - access_tokens - parameters: + description: Is dismissable + responses: + 200: + description: Update a broadcast message + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_BroadcastMessage' + delete: + tags: + - broadcast_messages + summary: Delete a broadcast message + description: This feature was introduced in GitLab 8.12. + operationId: deleteApiV4BroadcastMessagesId + parameters: - name: id in: path - description: The ID or URL-encoded path of the project + description: Broadcast message ID + required: true + schema: + type: integer + format: int32 + responses: + 200: + description: Delete a broadcast message + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_BroadcastMessage' + /api/v4/broadcast_messages: + get: + tags: + - broadcast_messages + summary: Get all broadcast messages + description: This feature was introduced in GitLab 8.12. + operationId: getApiV4BroadcastMessages + parameters: + - name: page + in: query + description: Current page number + schema: + type: integer + format: int32 + default: 1 + - name: per_page + in: query + description: Number of items per page + schema: + type: integer + format: int32 + default: 20 + responses: + 200: + description: Get all broadcast messages + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_BroadcastMessage' + post: + tags: + - broadcast_messages + summary: Create a broadcast message + description: This feature was introduced in GitLab 8.12. + operationId: postApiV4BroadcastMessages + requestBody: + content: + application/json: + schema: + required: + - message + properties: + message: + type: string + description: Message to display + starts_at: + type: string + description: Starting time + format: date-time + ends_at: + type: string + description: Ending time + format: date-time + color: + type: string + description: Background color + font: + type: string + description: Foreground color + target_access_levels: + type: array + description: Target user roles + items: + type: integer + format: int32 + enum: + - 10 + - 20 + - 30 + - 40 + - 50 + target_path: + type: string + description: Target path + broadcast_type: + type: string + description: Broadcast type. Defaults to banner + enum: + - banner + - notification + dismissable: + type: boolean + description: Is dismissable + required: true + responses: + 201: + description: Create a broadcast message + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_BroadcastMessage' + /api/v4/bulk_imports/{import_id}/entities/{entity_id}: + get: + tags: + - bulk_imports + summary: Get GitLab Migration entity details + description: This feature was introduced in GitLab 14.1. + operationId: getApiV4BulkImportsImportIdEntitiesEntityId + parameters: + - name: import_id + in: path + description: The ID of user's GitLab Migration + required: true + schema: + type: integer + format: int32 + - name: entity_id + in: path + description: The ID of GitLab Migration entity required: true schema: - oneOf: - - type: integer - - type: string - - name: token_id + type: integer + format: int32 + responses: + 200: + description: Get GitLab Migration entity details + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_BulkImports' + 401: + description: Unauthorized + content: {} + 404: + description: Not found + content: {} + 503: + description: Service unavailable + content: {} + /api/v4/bulk_imports/{import_id}/entities: + get: + tags: + - bulk_imports + summary: List GitLab Migration entities + description: This feature was introduced in GitLab 14.1. + operationId: getApiV4BulkImportsImportIdEntities + parameters: + - name: import_id in: path - description: The ID of the project access token + description: The ID of user's GitLab Migration required: true schema: - oneOf: - - type: integer - - type: string - responses: - '400': - description: Bad Request - '404': - description: Not Found - '204': - description: No content if successfully revoked + type: integer + format: int32 + - name: status + in: query + description: Return import entities with specified status + schema: + type: string + enum: + - created + - started + - finished + - timeout + - failed + - name: page + in: query + description: Current page number + schema: + type: integer + format: int32 + default: 1 + - name: per_page + in: query + description: Number of items per page + schema: + type: integer + format: int32 + default: 20 + responses: + 200: + description: List GitLab Migration entities + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/API_Entities_BulkImports' + 401: + description: Unauthorized + content: {} + 404: + description: Not found + content: {} + 503: + description: Service unavailable + content: {} + /api/v4/bulk_imports/{import_id}: + get: + tags: + - bulk_imports + summary: Get GitLab Migration details + description: This feature was introduced in GitLab 14.1. + operationId: getApiV4BulkImportsImportId + parameters: + - name: import_id + in: path + description: The ID of user's GitLab Migration + required: true + schema: + type: integer + format: int32 + responses: + 200: + description: Get GitLab Migration details + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_BulkImport' + 401: + description: Unauthorized + content: {} + 404: + description: Not found + content: {} + 503: + description: Service unavailable + content: {} + /api/v4/bulk_imports/entities: + get: + tags: + - bulk_imports + summary: List all GitLab Migrations' entities + description: This feature was introduced in GitLab 14.1. + operationId: getApiV4BulkImportsEntities + parameters: + - name: page + in: query + description: Current page number + schema: + type: integer + format: int32 + default: 1 + - name: per_page + in: query + description: Number of items per page + schema: + type: integer + format: int32 + default: 20 + - name: sort + in: query + description: Return GitLab Migrations sorted in created by `asc` or `desc` + order. + schema: + type: string + default: desc + enum: + - asc + - desc + - name: status + in: query + description: Return all GitLab Migrations' entities with specified status + schema: + type: string + enum: + - created + - started + - finished + - timeout + - failed + responses: + 200: + description: List all GitLab Migrations' entities + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/API_Entities_BulkImports' + 401: + description: Unauthorized + content: {} + 404: + description: Not found + content: {} + 503: + description: Service unavailable + content: {} + /api/v4/bulk_imports: + get: + tags: + - bulk_imports + summary: List all GitLab Migrations + description: This feature was introduced in GitLab 14.1. + operationId: getApiV4BulkImports + parameters: + - name: page + in: query + description: Current page number + schema: + type: integer + format: int32 + default: 1 + - name: per_page + in: query + description: Number of items per page + schema: + type: integer + format: int32 + default: 20 + - name: sort + in: query + description: Return GitLab Migrations sorted in created by `asc` or `desc` + order. + schema: + type: string + default: desc + enum: + - asc + - desc + - name: status + in: query + description: Return GitLab Migrations with specified status + schema: + type: string + enum: + - created + - started + - finished + - timeout + - failed + responses: + 200: + description: List all GitLab Migrations + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/API_Entities_BulkImport' + 401: + description: Unauthorized + content: {} + 404: + description: Not found + content: {} + 503: + description: Service unavailable + content: {} + post: + tags: + - bulk_imports + summary: Start a new GitLab Migration + description: This feature was introduced in GitLab 14.2. + operationId: postApiV4BulkImports + requestBody: + content: + application/x-www-form-urlencoded: + schema: + required: + - configuration[access_token] + - configuration[url] + - entities[destination_namespace] + - entities[source_full_path] + - entities[source_type] + properties: + configuration[url]: + type: string + description: Source GitLab instance URL + configuration[access_token]: + type: string + description: Access token to the source GitLab instance + entities[source_type]: + type: array + description: Source entity type + items: + type: string + enum: + - group_entity + - project_entity + entities[source_full_path]: + type: array + description: Relative path of the source entity to import + items: + type: string + entities[destination_namespace]: + type: array + description: Destination namespace for the entity + items: + type: string + entities[destination_slug]: + type: array + description: Destination slug for the entity + items: + type: string + entities[destination_name]: + type: array + description: 'Deprecated: Use :destination_slug instead. Destination + slug for the entity' + items: + type: string + entities[migrate_projects]: + type: array + description: Indicates group migration should include nested projects + items: + type: boolean + required: true + responses: + 200: + description: Start a new GitLab Migration + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_BulkImport' + 400: + description: Bad request + content: {} + 401: + description: Unauthorized + content: {} + 404: + description: Not found + content: {} + 422: + description: Unprocessable entity + content: {} + 503: + description: Service unavailable + content: {} + /api/v4/application/appearance: + get: + tags: + - application + description: Get the current appearance + operationId: getApiV4ApplicationAppearance + responses: + 200: + description: Get the current appearance + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Appearance' + put: + tags: + - application + description: Modify appearance + operationId: putApiV4ApplicationAppearance + requestBody: + content: + multipart/form-data: + schema: + properties: + title: + type: string + description: Instance title on the sign in / sign up page + description: + type: string + description: Markdown text shown on the sign in / sign up page + pwa_name: + type: string + description: Name of the Progressive Web App + pwa_short_name: + type: string + description: Optional, short name for Progressive Web App + pwa_description: + type: string + description: An explanation of what the Progressive Web App does + logo: + type: string + description: Instance image used on the sign in / sign up page + format: binary + pwa_icon: + type: string + description: Icon used for Progressive Web App + format: binary + header_logo: + type: string + description: Instance image used for the main navigation bar + format: binary + favicon: + type: string + description: Instance favicon in .ico/.png format + format: binary + new_project_guidelines: + type: string + description: Markdown text shown on the new project page + profile_image_guidelines: + type: string + description: Markdown text shown on the profile page below Public + Avatar + header_message: + type: string + description: Message within the system header bar + footer_message: + type: string + description: Message within the system footer bar + message_background_color: + type: string + description: Background color for the system header / footer bar + message_font_color: + type: string + description: Font color for the system header / footer bar + email_header_and_footer_enabled: + type: boolean + description: Add header and footer to all outgoing emails if enabled + responses: + 200: + description: Modify appearance + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Appearance' + /api/v4/application/plan_limits: + get: + tags: + - plan_limits + summary: Get current plan limits + description: List the current limits of a plan on the GitLab instance. + operationId: getApiV4ApplicationPlanLimits + parameters: + - name: plan_name + in: query + description: 'Name of the plan to get the limits from. Default: default.' + schema: + type: string + default: default + enum: + - default + - free + - bronze + - silver + - premium + - gold + - ultimate + - ultimate_trial + - premium_trial + - opensource + responses: + 200: + description: Get current plan limits + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_PlanLimit' + 401: + description: Unauthorized + content: {} + 403: + description: Forbidden + content: {} + put: + tags: + - plan_limits + summary: Change plan limits + description: Modify the limits of a plan on the GitLab instance. + operationId: putApiV4ApplicationPlanLimits + requestBody: + content: + application/json: + schema: + required: + - plan_name + properties: + plan_name: + type: string + description: Name of the plan to update + enum: + - default + - free + - bronze + - silver + - premium + - gold + - ultimate + - ultimate_trial + - premium_trial + - opensource + ci_pipeline_size: + type: integer + description: Maximum number of jobs in a single pipeline + format: int32 + ci_active_jobs: + type: integer + description: Total number of jobs in currently active pipelines + format: int32 + ci_project_subscriptions: + type: integer + description: Maximum number of pipeline subscriptions to and from + a project + format: int32 + ci_pipeline_schedules: + type: integer + description: Maximum number of pipeline schedules + format: int32 + ci_needs_size_limit: + type: integer + description: Maximum number of DAG dependencies that a job can have + format: int32 + ci_registered_group_runners: + type: integer + description: Maximum number of runners registered per group + format: int32 + ci_registered_project_runners: + type: integer + description: Maximum number of runners registered per project + format: int32 + conan_max_file_size: + type: integer + description: Maximum Conan package file size in bytes + format: int32 + enforcement_limit: + type: integer + description: Maximum storage size for the root namespace enforcement + in MiB + format: int32 + generic_packages_max_file_size: + type: integer + description: Maximum generic package file size in bytes + format: int32 + helm_max_file_size: + type: integer + description: Maximum Helm chart file size in bytes + format: int32 + maven_max_file_size: + type: integer + description: Maximum Maven package file size in bytes + format: int32 + notification_limit: + type: integer + description: Maximum storage size for the root namespace notifications + in MiB + format: int32 + npm_max_file_size: + type: integer + description: Maximum NPM package file size in bytes + format: int32 + nuget_max_file_size: + type: integer + description: Maximum NuGet package file size in bytes + format: int32 + pypi_max_file_size: + type: integer + description: Maximum PyPI package file size in bytes + format: int32 + terraform_module_max_file_size: + type: integer + description: Maximum Terraform Module package file size in bytes + format: int32 + storage_size_limit: + type: integer + description: Maximum storage size for the root namespace in MiB + format: int32 + pipeline_hierarchy_size: + type: integer + description: Maximum number of downstream pipelines in a pipeline's + hierarchy tree + format: int32 + required: true + responses: + 200: + description: Change plan limits + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_PlanLimit' + 400: + description: Bad request + content: {} + 401: + description: Unauthorized + content: {} + 403: + description: Forbidden + content: {} + /api/v4/metadata: + get: + tags: + - metadata + summary: Retrieve metadata information for this GitLab instance + description: This feature was introduced in GitLab 15.2. + operationId: getApiV4Metadata + responses: + 200: + description: Retrieve metadata information for this GitLab instance + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Metadata' + 401: + description: Unauthorized + content: {} + /api/v4/version: + get: + tags: + - metadata + summary: Retrieves version information for the GitLab instance + description: This feature was introduced in GitLab 8.13 and deprecated in 15.5. + We recommend you instead use the Metadata API. + operationId: getApiV4Version + responses: + 200: + description: Retrieves version information for the GitLab instance + content: + application/json: + schema: + $ref: '#/components/schemas/API_Entities_Metadata' + 401: + description: Unauthorized + content: {} +components: + schemas: + API_Entities_Badge: + type: object + properties: + name: + type: string + link_url: + type: string + image_url: + type: string + rendered_link_url: + type: string + rendered_image_url: + type: string + id: + type: string + kind: + type: string + description: API_Entities_Badge model + API_Entities_BasicBadgeDetails: + type: object + properties: + name: + type: string + link_url: + type: string + image_url: + type: string + rendered_link_url: + type: string + rendered_image_url: + type: string + description: API_Entities_BasicBadgeDetails model + API_Entities_AccessRequester: + type: object + properties: + id: + type: integer + format: int32 + example: 1 + username: + type: string + example: admin + name: + type: string + example: Administrator + state: + type: string + example: active + avatar_url: + type: string + example: https://gravatar.com/avatar/1 + avatar_path: + type: string + example: /user/avatar/28/The-Big-Lebowski-400-400.png + custom_attributes: + type: array + items: + $ref: '#/components/schemas/API_Entities_CustomAttribute' + web_url: + type: string + example: https://gitlab.example.com/root + email: + type: string + requested_at: + type: string + description: API_Entities_AccessRequester model + API_Entities_CustomAttribute: + type: object + properties: + key: + type: string + example: foo + value: + type: string + example: bar + API_Entities_Branch: + type: object + properties: + name: + type: string + example: master + commit: + $ref: '#/components/schemas/API_Entities_Commit' + merged: + type: boolean + example: true + protected: + type: boolean + example: true + developers_can_push: + type: boolean + example: true + developers_can_merge: + type: boolean + example: true + can_push: + type: boolean + example: true + default: + type: boolean + example: true + web_url: + type: string + example: https://gitlab.example.com/Commit921/the-dude/-/tree/master + description: API_Entities_Branch model + API_Entities_Commit: + type: object + properties: + id: + type: string + example: 2695effb5807a22ff3d138d593fd856244e155e7 + short_id: + type: string + example: 2695effb + created_at: + type: string + format: date-time + example: 2017-07-26T11:08:53+02:00 + parent_ids: + type: array + items: + type: string + example: 2a4b78934375d7f53875269ffd4f45fd83a84ebe + title: + type: string + example: Initial commit + message: + type: string + example: Initial commit + author_name: + type: string + example: John Smith + author_email: + type: string + example: john@example.com + authored_date: + type: string + format: date-time + example: 2012-05-28T04:42:42-07:00 + committer_name: + type: string + example: Jack Smith + committer_email: + type: string + example: jack@example.com + committed_date: + type: string + format: date-time + example: 2012-05-28T04:42:42-07:00 + trailers: + type: object + properties: {} + example: '{ "Merged-By": "Jane Doe janedoe@gitlab.com" }' + web_url: + type: string + example: https://gitlab.example.com/janedoe/gitlab-foss/-/commit/ed899a2f4b50b4370feeea94676502b42383c746 + API_Entities_MetricImage: + type: object + properties: + id: + type: integer + format: int32 + example: 23 + created_at: + type: string + format: date-time + example: 2020-11-13T00:06:18.084Z + filename: + type: string + example: file.png + file_path: + type: string + example: /uploads/-/system/alert_metric_image/file/23/file.png + url: + type: string + example: https://example.com/metric + url_text: + type: string + example: An example metric + description: API_Entities_MetricImage model + API_Entities_BatchedBackgroundMigration: + type: object + properties: + id: + type: string + example: "1234" + job_class_name: + type: string + example: CopyColumnUsingBackgroundMigrationJob + table_name: + type: string + example: events + status: + type: string + example: active + progress: + type: number + format: float + example: 50.0 + created_at: + type: string + format: date-time + example: 2022-11-28T16:26:39+02:00 + description: API_Entities_BatchedBackgroundMigration model + API_Entities_Ci_Variable: + type: object + properties: + variable_type: + type: string + example: env_var + key: + type: string + example: TEST_VARIABLE_1 + value: + type: string + example: TEST_1 + protected: + type: boolean + masked: + type: boolean + raw: + type: boolean + environment_scope: + type: string + example: '*' + description: API_Entities_Ci_Variable model + API_Entities_Dictionary_Table: + type: object + properties: + table_name: + type: string + example: users + feature_categories: + type: array + items: + type: string + example: database + description: API_Entities_Dictionary_Table model + API_Entities_Cluster: + type: object + properties: + id: + type: string + name: + type: string + created_at: + type: string + domain: + type: string + enabled: + type: string + managed: + type: string + provider_type: + type: string + platform_type: + type: string + environment_scope: + type: string + cluster_type: + type: string + namespace_per_environment: + type: string + user: + $ref: '#/components/schemas/API_Entities_UserBasic' + platform_kubernetes: + $ref: '#/components/schemas/API_Entities_Platform_Kubernetes' + provider_gcp: + $ref: '#/components/schemas/API_Entities_Provider_Gcp' + management_project: + $ref: '#/components/schemas/API_Entities_ProjectIdentity' + description: API_Entities_Cluster model + API_Entities_UserBasic: + type: object + properties: + id: + type: integer + format: int32 + example: 1 + username: + type: string + example: admin + name: + type: string + example: Administrator + state: + type: string + example: active + avatar_url: + type: string + example: https://gravatar.com/avatar/1 + avatar_path: + type: string + example: /user/avatar/28/The-Big-Lebowski-400-400.png + custom_attributes: + type: array + items: + $ref: '#/components/schemas/API_Entities_CustomAttribute' + web_url: + type: string + example: https://gitlab.example.com/root + email: + type: string + API_Entities_Platform_Kubernetes: + type: object + properties: + api_url: + type: string + namespace: + type: string + authorization_type: + type: string + ca_cert: + type: string + API_Entities_Provider_Gcp: + type: object + properties: + cluster_id: + type: string + status_name: + type: string + gcp_project_id: + type: string + zone: + type: string + machine_type: + type: string + num_nodes: + type: string + endpoint: + type: string + API_Entities_ProjectIdentity: + type: object + properties: + id: + type: integer + format: int32 + example: 1 + description: + type: string + example: desc + name: + type: string + example: project1 + name_with_namespace: + type: string + example: John Doe / project1 + path: + type: string + example: project1 + path_with_namespace: + type: string + example: namespace1/project1 + created_at: + type: string + format: date-time + example: 2020-05-07T04:27:17.016Z + API_Entities_Application: + type: object + properties: + id: + type: string + application_id: + type: string + example: 5832fc6e14300a0d962240a8144466eef4ee93ef0d218477e55f11cf12fc3737 + application_name: + type: string + example: MyApplication + callback_url: + type: string + example: https://redirect.uri + confidential: + type: boolean + example: true + description: API_Entities_Application model + API_Entities_ApplicationWithSecret: + type: object + properties: + id: + type: string + application_id: + type: string + example: 5832fc6e14300a0d962240a8144466eef4ee93ef0d218477e55f11cf12fc3737 + application_name: + type: string + example: MyApplication + callback_url: + type: string + example: https://redirect.uri + confidential: + type: boolean + example: true + secret: + type: string + example: ee1dd64b6adc89cf7e2c23099301ccc2c61b441064e9324d963c46902a85ec34 + description: API_Entities_ApplicationWithSecret model + API_Entities_Avatar: + type: object + properties: + avatar_url: + type: string + description: API_Entities_Avatar model + API_Entities_BroadcastMessage: + type: object + properties: + id: + type: string + message: + type: string + starts_at: + type: string + ends_at: + type: string + color: + type: string + font: + type: string + target_access_levels: + type: string + target_path: + type: string + broadcast_type: + type: string + dismissable: + type: string + active: + type: string + description: API_Entities_BroadcastMessage model + API_Entities_BulkImports: + type: object + properties: + id: + type: integer + format: int32 + example: 1 + bulk_import_id: + type: integer + format: int32 + example: 1 + status: + type: string + example: created + enum: + - created + - started + - finished + - timeout + - failed + entity_type: + type: string + enum: + - group + - project + source_full_path: + type: string + example: source_group + destination_full_path: + type: string + example: some_group/source_project + destination_name: + type: string + example: destination_slug + destination_slug: + type: string + example: destination_slug + destination_namespace: + type: string + example: destination_path + parent_id: + type: integer + format: int32 + example: 1 + namespace_id: + type: integer + format: int32 + example: 1 + project_id: + type: integer + format: int32 + example: 1 + created_at: + type: string + format: date-time + example: 2012-05-28T04:42:42-07:00 + updated_at: + type: string + format: date-time + example: 2012-05-28T04:42:42-07:00 + failures: + type: array + items: + $ref: '#/components/schemas/API_Entities_BulkImports_EntityFailure' + migrate_projects: + type: boolean + example: true + description: API_Entities_BulkImports model + API_Entities_BulkImports_EntityFailure: + type: object + properties: + relation: + type: string + example: group + step: + type: string + example: extractor + exception_message: + type: string + example: error message + exception_class: + type: string + example: Exception + correlation_id_value: + type: string + example: dfcf583058ed4508e4c7c617bd7f0edd + created_at: + type: string + format: date-time + example: 2012-05-28T04:42:42-07:00 + pipeline_class: + type: string + example: BulkImports::Groups::Pipelines::GroupPipeline + pipeline_step: + type: string + example: extractor + API_Entities_BulkImport: + type: object + properties: + id: + type: integer + format: int32 + example: 1 + status: + type: string + example: finished + enum: + - created + - started + - finished + - timeout + - failed + source_type: + type: string + example: gitlab + created_at: + type: string + format: date-time + example: 2012-05-28T04:42:42-07:00 + updated_at: + type: string + format: date-time + example: 2012-05-28T04:42:42-07:00 + description: API_Entities_BulkImport model + API_Entities_Appearance: + type: object + properties: + title: + type: string + description: + type: string + pwa_name: + type: string + pwa_short_name: + type: string + pwa_description: + type: string + logo: + type: string + pwa_icon: + type: string + header_logo: + type: string + favicon: + type: string + new_project_guidelines: + type: string + profile_image_guidelines: + type: string + header_message: + type: string + footer_message: + type: string + message_background_color: + type: string + message_font_color: + type: string + email_header_and_footer_enabled: + type: string + description: API_Entities_Appearance model + API_Entities_PlanLimit: + type: object + properties: + ci_pipeline_size: + type: integer + format: int32 + example: 0 + ci_active_jobs: + type: integer + format: int32 + example: 0 + ci_project_subscriptions: + type: integer + format: int32 + example: 2 + ci_pipeline_schedules: + type: integer + format: int32 + example: 10 + ci_needs_size_limit: + type: integer + format: int32 + example: 50 + ci_registered_group_runners: + type: integer + format: int32 + example: 1000 + ci_registered_project_runners: + type: integer + format: int32 + example: 1000 + conan_max_file_size: + type: integer + format: int32 + example: 3221225472 + enforcement_limit: + type: integer + format: int32 + example: 15000 + generic_packages_max_file_size: + type: integer + format: int32 + example: 5368709120 + helm_max_file_size: + type: integer + format: int32 + example: 5242880 + limits_history: + type: object + properties: {} + example: |- + {"enforcement_limit"=>[{"timestamp"=>1686909124, "user_id"=>1, "username"=>"x", "value"=>5}], + "notification_limit"=>[{"timestamp"=>1686909124, "user_id"=>2, "username"=>"y", "value"=>7}]} + maven_max_file_size: + type: integer + format: int32 + example: 3221225472 + notification_limit: + type: integer + format: int32 + example: 15000 + npm_max_file_size: + type: integer + format: int32 + example: 524288000 + nuget_max_file_size: + type: integer + format: int32 + example: 524288000 + pipeline_hierarchy_size: + type: integer + format: int32 + example: 1000 + pypi_max_file_size: + type: integer + format: int32 + example: 3221225472 + terraform_module_max_file_size: + type: integer + format: int32 + example: 1073741824 + storage_size_limit: + type: integer + format: int32 + example: 15000 + description: API_Entities_PlanLimit model + API_Entities_Metadata: + type: object + properties: + version: + type: string + example: 15.2-pre + revision: + type: string + example: c401a659d0c + kas: + type: object + properties: + enabled: + type: boolean + externalUrl: + type: string + example: grpc://gitlab.example.com:8150 + version: + type: string + example: 15.0.0 + enterprise: + type: boolean + description: API_Entities_Metadata model + securitySchemes: + ApiKeyAuth: + type: apiKey + in: header + name: Private-Token diff --git a/doc/development/gemfile.md b/doc/development/gemfile.md index 3971a66f796..ed38f6481e7 100644 --- a/doc/development/gemfile.md +++ b/doc/development/gemfile.md @@ -120,8 +120,6 @@ When upgrading the Rails gem and its dependencies, you also should update the fo - The [`activerecord_version` in the vendored `attr_encrypted` gemspec](https://gitlab.com/gitlab-org/gitlab/-/blob/master/vendor/gems/attr_encrypted/attr_encrypted.gemspec). - The [`Gemfile` in the `qa` directory](https://gitlab.com/gitlab-org/gitlab/-/blob/master/qa/Gemfile). -- The [`Gemfile` in Gitaly Ruby](https://gitlab.com/gitlab-org/gitaly/-/blob/master/ruby/Gemfile), - to ensure that we ship only one version of these gems. You should also update npm packages that follow the current version of Rails: diff --git a/doc/development/internal_analytics/service_ping/implement.md b/doc/development/internal_analytics/service_ping/implement.md index 0dfc3806712..e171490068f 100644 --- a/doc/development/internal_analytics/service_ping/implement.md +++ b/doc/development/internal_analytics/service_ping/implement.md @@ -501,7 +501,7 @@ We can disable tracking completely by using the global flag: ##### Known events are added automatically in Service Data payload -Service Ping adds all events [`known_events/*.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events) to Service Data generation under the `redis_hll_counters` key. This column is stored in [version-app as a JSON](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/db/schema.rb#L209). +Service Ping adds all events [`known_events/*.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/usage_data_counters/known_events) to Service Data generation under the `redis_hll_counters` key. This column is stored in [version-app as a JSON](https://gitlab.com/gitlab-org/gitlab-services/version.gitlab.com/-/blob/main/db/schema.rb#L213). For each event we add metrics for the weekly and monthly time frames, and totals for each where applicable: - `#{event_name}_weekly`: Data for 7 days for daily [aggregation](#add-new-events) events and data for the last complete week for weekly [aggregation](#add-new-events) events. @@ -680,7 +680,7 @@ See the [Metrics Dictionary guide](metrics_dictionary.md) for more information. ## Add the metric to the Versions Application -Check if the new metric must be added to the Versions Application. See the `usage_data` [schema](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/db/schema.rb#L147) and Service Data [parameters accepted](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/app/services/usage_ping.rb). Any metrics added under the `counts` key are saved in the `stats` column. +Check if the new metric must be added to the Versions Application. See the `usage_data` [schema](https://gitlab.com/gitlab-org/gitlab-services/version.gitlab.com/-/blob/main/db/schema.rb#L152) and Service Data [parameters accepted](https://gitlab.com/gitlab-org/gitlab-services/version.gitlab.com/-/blob/main/app/services/usage_ping.rb). Any metrics added under the `counts` key are saved in the `stats` column. ## Create a merge request @@ -715,7 +715,7 @@ To set up Service Ping locally, you must: ### Set up local repositories 1. Clone and start [GitLab](https://gitlab.com/gitlab-org/gitlab-development-kit). -1. Clone and start [Versions Application](https://gitlab.com/gitlab-services/version-gitlab-com). +1. Clone and start [Versions Application](https://gitlab.com/gitlab-org/gitlab-services/version.gitlab.com). Make sure you run `docker-compose up` to start a PostgreSQL and Redis instance. 1. Point GitLab to the Versions Application endpoint instead of the default endpoint: 1. Open [service_ping/submit_service.rb](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/services/service_ping/submit_service.rb#L5) locally and modify `STAGING_BASE_URL`. diff --git a/doc/development/internal_analytics/service_ping/metrics_lifecycle.md b/doc/development/internal_analytics/service_ping/metrics_lifecycle.md index cc56863690c..7aa0eaa1554 100644 --- a/doc/development/internal_analytics/service_ping/metrics_lifecycle.md +++ b/doc/development/internal_analytics/service_ping/metrics_lifecycle.md @@ -51,16 +51,16 @@ To remove a metric: to inform administrators of the progress of DevOps adoption for the instance. You can check - [`CalculateConvIndexService`](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/app/services/calculate_conv_index_service.rb) + [`CalculateConvIndexService`](https://gitlab.com/gitlab-org/gitlab-services/version.gitlab.com/-/blob/main/app/services/calculate_conv_index_service.rb) to view the metrics that are used. The metrics are represented as the keys that are passed as a field argument into the `get_value` method. 1. Verify that removing the metric from the Service Ping payload does not cause - errors in [Version App](https://gitlab.com/gitlab-services/version-gitlab-com) + errors in [Version App](https://gitlab.com/gitlab-org/gitlab-services/version.gitlab.com) when the updated payload is collected and processed. Version App collects and persists all Service Ping reports. To verify Service Ping processing in your local development environment, follow this [guide](https://www.youtube.com/watch?v=FS5emplabRU). - Alternatively, you can modify [fixtures](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/master/spec/support/usage_data_helpers.rb#L540) - used to test the [`UsageDataController#create`](https://gitlab.com/gitlab-services/version-gitlab-com/-/blob/3760ef28/spec/controllers/usage_data_controller_spec.rb#L75) + Alternatively, you can modify [fixtures](https://gitlab.com/gitlab-org/gitlab-services/version.gitlab.com/-/blob/main/spec/support/usage_data_helpers.rb) + used to test the [`UsageDataController#create`](https://gitlab.com/gitlab-org/gitlab-services/version.gitlab.com/-/blob/main/spec/controllers/usage_data_controller_spec.rb) endpoint, and assure that test suite does not fail when metric that you wish to remove is not included into test payload. 1. Remove data from Redis diff --git a/doc/development/internal_analytics/service_ping/troubleshooting.md b/doc/development/internal_analytics/service_ping/troubleshooting.md index 2b285b85bd0..4cbcefaefdd 100644 --- a/doc/development/internal_analytics/service_ping/troubleshooting.md +++ b/doc/development/internal_analytics/service_ping/troubleshooting.md @@ -26,7 +26,7 @@ For results about an investigation conducted into an unexpected drop in Service ### Troubleshoot VersionApp layer -Check if the [export jobs](https://gitlab.com/gitlab-services/version-gitlab-com#data-export-using-pipeline-schedules) are successful. +Check if the [export jobs](https://gitlab.com/gitlab-org/gitlab-services/version.gitlab.com/-/tree/main/#data-export-using-pipeline-schedules) are successful. Check [Service Ping errors](https://app.periscopedata.com/app/gitlab/968489?widget=14609989&udv=0) in the [Service Ping Health Dashboard](https://app.periscopedata.com/app/gitlab/968489). diff --git a/doc/development/pipelines/internals.md b/doc/development/pipelines/internals.md index 35881db8c6d..53f07d48eef 100644 --- a/doc/development/pipelines/internals.md +++ b/doc/development/pipelines/internals.md @@ -165,7 +165,7 @@ and included in `rules` definitions via [YAML anchors](../../ci/yaml/yaml_optimi | `if:` conditions | Description | Notes | |------------------|-------------|-------| -| `if-not-canonical-namespace` | Matches if the project isn't in the canonical (`gitlab-org/`) or security (`gitlab-org/security`) namespace. | Use to create a job for forks (by using `when: on_success` or `when: manual`), or **not** create a job for forks (by using `when: never`). | +| `if-not-canonical-namespace` | Matches if the project isn't in the canonical (`gitlab-org/` and `gitlab-cn/`) or security (`gitlab-org/security`) namespace. | Use to create a job for forks (by using `when: on_success` or `when: manual`), or **not** create a job for forks (by using `when: never`). | | `if-not-ee` | Matches if the project isn't EE (that is, project name isn't `gitlab` or `gitlab-ee`). | Use to create a job only in the FOSS project (by using `when: on_success` or `when: manual`), or **not** create a job if the project is EE (by using `when: never`). | | `if-not-foss` | Matches if the project isn't FOSS (that is, project name isn't `gitlab-foss`, `gitlab-ce`, or `gitlabhq`). | Use to create a job only in the EE project (by using `when: on_success` or `when: manual`), or **not** create a job if the project is FOSS (by using `when: never`). | | `if-default-refs` | Matches if the pipeline is for `master`, `main`, `/^[\d-]+-stable(-ee)?$/` (stable branches), `/^\d+-\d+-auto-deploy-\d+$/` (auto-deploy branches), `/^security\//` (security branches), merge requests, and tags. | Note that jobs aren't created for branches with this default configuration. | diff --git a/lib/api/badges.rb b/lib/api/badges.rb index 84c9f780a53..62eecdbd5e5 100644 --- a/lib/api/badges.rb +++ b/lib/api/badges.rb @@ -22,7 +22,9 @@ module API %w[group project].each do |source_type| params do - requires :id, type: String, desc: "The ID of a #{source_type}" + requires :id, + type: String, + desc: "The ID or URL-encoded path of the #{source_type} owned by the authenticated user." end resource source_type.pluralize, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do desc "Gets a list of #{source_type} badges viewable by the authenticated user." do diff --git a/lib/api/entities/dictionary/table.rb b/lib/api/entities/dictionary/table.rb index 8d4e3fb959d..93e82d34b14 100644 --- a/lib/api/entities/dictionary/table.rb +++ b/lib/api/entities/dictionary/table.rb @@ -5,7 +5,7 @@ module API module Dictionary class Table < Grape::Entity expose :table_name, documentation: { type: :string, example: 'users' } - expose :feature_categories, documentation: { type: :array, example: ['database'] } + expose :feature_categories, documentation: { type: :string, is_array: true, example: 'database' } end end end diff --git a/lib/gitlab/ci/artifact_file_reader.rb b/lib/gitlab/ci/artifact_file_reader.rb index 2eb8df01d58..0d8f6f3ea40 100644 --- a/lib/gitlab/ci/artifact_file_reader.rb +++ b/lib/gitlab/ci/artifact_file_reader.rb @@ -14,7 +14,8 @@ module Gitlab def initialize(job) @job = job - raise ArgumentError, 'Job does not have artifacts' unless @job.artifacts? + raise Error, 'Job doesnt exist' unless @job + raise Error, 'Job does not have artifacts' unless @job.artifacts? validate! end diff --git a/lib/gitlab/ci/config/external/file/artifact.rb b/lib/gitlab/ci/config/external/file/artifact.rb index 273d78bd583..f23fa2e6401 100644 --- a/lib/gitlab/ci/config/external/file/artifact.rb +++ b/lib/gitlab/ci/config/external/file/artifact.rb @@ -19,12 +19,15 @@ module Gitlab end def content - strong_memoize(:content) do - Gitlab::Ci::ArtifactFileReader.new(artifact_job).read(location) - rescue Gitlab::Ci::ArtifactFileReader::Error => error - errors.push(error.message) # TODO this memoizes the error message as a content! - end + return unless context.parent_pipeline.present? + + Gitlab::Ci::ArtifactFileReader.new(artifact_job).read(location) + rescue Gitlab::Ci::ArtifactFileReader::Error => error + errors.push(error.message) + + nil end + strong_memoize_attr :content def metadata super.merge( diff --git a/lib/gitlab/graphql/generic_tracing.rb b/lib/gitlab/graphql/generic_tracing.rb deleted file mode 100644 index dc3f6574631..00000000000 --- a/lib/gitlab/graphql/generic_tracing.rb +++ /dev/null @@ -1,71 +0,0 @@ -# frozen_string_literal: true - -# This class is used as a hook to observe graphql runtime events. From this -# hook both gitlab metrics and opentracking measurements are generated - -module Gitlab - module Graphql - class GenericTracing < GraphQL::Tracing::PlatformTracing - self.platform_keys = { - 'lex' => 'graphql.lex', - 'parse' => 'graphql.parse', - 'validate' => 'graphql.validate', - 'analyze_query' => 'graphql.analyze', - 'analyze_multiplex' => 'graphql.analyze', - 'execute_multiplex' => 'graphql.execute', - 'execute_query' => 'graphql.execute', - 'execute_query_lazy' => 'graphql.execute', - 'execute_field' => 'graphql.execute', - 'execute_field_lazy' => 'graphql.execute' - } - - def platform_field_key(type, field) - "#{type.name}.#{field.name}" - end - - def platform_authorized_key(type) - "#{type.graphql_name}.authorized" - end - - def platform_resolve_type_key(type) - "#{type.graphql_name}.resolve_type" - end - - def platform_trace(platform_key, key, data, &block) - tags = { platform_key: platform_key, key: key } - start = Gitlab::Metrics::System.monotonic_time - - with_labkit_tracing(tags, &block) - ensure - duration = Gitlab::Metrics::System.monotonic_time - start - - graphql_duration_seconds.observe(tags, duration) unless deactivated? - end - - private - - def deactivated? - Feature.enabled?(:graphql_generic_tracing_metrics_deactivate) - end - - def with_labkit_tracing(tags, &block) - return yield unless Labkit::Tracing.enabled? - - name = "#{tags[:platform_key]}.#{tags[:key]}" - span_tags = { - 'component' => 'web', - 'span.kind' => 'server' - }.merge(tags.stringify_keys) - - Labkit::Tracing.with_tracing(operation_name: name, tags: span_tags, &block) - end - - def graphql_duration_seconds - @graphql_duration_seconds ||= Gitlab::Metrics.histogram( - :graphql_duration_seconds, - 'GraphQL execution time' - ) - end - end - end -end diff --git a/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_gbp_metric.rb b/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_gbp_metric.rb new file mode 100644 index 00000000000..0a796c9fae9 --- /dev/null +++ b/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_gbp_metric.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Gitlab + module Usage + module Metrics + module Instrumentations + class CountSlackAppInstallationsGbpMetric < DatabaseMetric + operation :count + + relation { SlackIntegration.with_bot } + end + end + end + end +end diff --git a/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_metric.rb b/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_metric.rb new file mode 100644 index 00000000000..af9cf957dab --- /dev/null +++ b/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_metric.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module Gitlab + module Usage + module Metrics + module Instrumentations + class CountSlackAppInstallationsMetric < DatabaseMetric + operation :count + + relation { SlackIntegration } + end + end + end + end +end diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb index 2da16cf8725..e4813bf076f 100644 --- a/lib/gitlab/usage_data.rb +++ b/lib/gitlab/usage_data.rb @@ -364,7 +364,11 @@ module Gitlab group_clusters_disabled: clusters_user_distinct_count(::Clusters::Cluster.disabled.group_type, time_period), group_clusters_enabled: clusters_user_distinct_count(::Clusters::Cluster.enabled.group_type, time_period), project_clusters_disabled: clusters_user_distinct_count(::Clusters::Cluster.disabled.project_type, time_period), - project_clusters_enabled: clusters_user_distinct_count(::Clusters::Cluster.enabled.project_type, time_period) + project_clusters_enabled: clusters_user_distinct_count(::Clusters::Cluster.enabled.project_type, time_period), + # These two `projects_slack_x` metrics are owned by the Manage stage, but are in this method as their key paths can't change. + # See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/123442#note_1427961339. + projects_slack_notifications_active: distinct_count(::Project.with_slack_integration.where(time_period), :creator_id), + projects_slack_slash_active: distinct_count(::Project.with_slack_slash_commands_integration.where(time_period), :creator_id) } end # rubocop: enable UsageData/LargeTable diff --git a/qa/qa/service/docker_run/video.rb b/qa/qa/service/docker_run/video.rb index c59a28c1f72..601e342b6ba 100644 --- a/qa/qa/service/docker_run/video.rb +++ b/qa/qa/service/docker_run/video.rb @@ -29,6 +29,7 @@ module QA if @recorder_container_name.present? && @browser_container_hostname configure_rspec + configure_rspec_allure if QA::Runtime::Env.generate_allure_report? QA::Runtime::Logger.info("Test failure video recording setup complete!") else @@ -77,6 +78,23 @@ module QA example.exception || QA::Runtime::Env.save_all_videos? end + def retrieve_video(example) + return unless record?(example) && example.exception + + # We need to wait until the video is finished processing by checking the size + QA::Support::Waiter.wait_until(max_duration: 30, sleep_interval: 1) do + size = + shell("docker exec #{@recorder_container_name} sh -c 'stat -c %s /data/#{@current_recording_name}.mp4'") + size.to_i > 1024 + end + + shell("docker cp #{@recorder_container_name}:/data/#{@current_recording_name}.mp4 tmp/") + + "#{shell('pwd')}/tmp/#{@current_recording_name}.mp4" + rescue StandardError => e + QA::Runtime::Logger.warn("Video retrieval error: #{e}") + end + private def configure_rspec @@ -85,7 +103,7 @@ module QA QA::Service::DockerRun::Video.start_recording(example) if QA::Service::DockerRun::Video.record?(example) end - config.append_after do |example| + config.prepend_after do |example| if QA::Service::DockerRun::Video.record?(example) QA::Service::DockerRun::Video.stop_recording QA::Service::DockerRun::Video.delete_video unless QA::Service::DockerRun::Video.save?(example) @@ -94,6 +112,22 @@ module QA end end + def configure_rspec_allure + RSpec.configure do |config| + config.append_after do |example| + video_path = QA::Service::DockerRun::Video.retrieve_video(example) + if video_path + Allure.add_attachment( + name: 'video', + source: File.open(video_path), + type: 'video/mp4', + test_case: true + ) + end + end + end + end + def create_recording_name(example) test_name = example.full_description.downcase.parameterize(separator: "_")[0..56] test_time = Time.now.strftime "%Y-%m-%d-%H-%M-%S-%L" diff --git a/qa/spec/service/docker_run/video_spec.rb b/qa/spec/service/docker_run/video_spec.rb index 81be5ccffae..d8d7f680629 100644 --- a/qa/spec/service/docker_run/video_spec.rb +++ b/qa/spec/service/docker_run/video_spec.rb @@ -4,7 +4,7 @@ module QA RSpec.describe Service::DockerRun::Video do include QA::Support::Helpers::StubEnv - let(:rspec_config) { instance_double('RSpec::Core::Configuration', append_after: nil, prepend_before: nil) } + let(:rspec_config) { instance_double('RSpec::Core::Configuration', prepend_before: nil, prepend_after: nil) } let(:video_recorder_image) { 'presidenten/selenoid-manual-video-recorder' } let(:video_recorder_version) { 'latest' } let(:selenoid_browser_image) { 'selenoid/chrome' } @@ -12,6 +12,7 @@ module QA let(:remote_grid) { 'selenoid:4444' } let(:record_video) { 'true' } let(:use_selenoid) { 'true' } + let(:allure_report) { 'false' } let(:docs_link) do 'https://gitlab.com/gitlab-org/gitlab-qa/-/blob/master/docs/running_against_remote_grid.md#testing-with-selenoid' end @@ -55,6 +56,7 @@ module QA stub_env('QA_REMOTE_GRID', remote_grid) stub_env('USE_SELENOID', use_selenoid) stub_env('QA_RECORD_VIDEO', record_video) + stub_env('QA_GENERATE_ALLURE_REPORT', allure_report) allow(RSpec).to receive(:configure).and_yield(rspec_config) allow(described_class).to receive(:get_container_name) @@ -173,7 +175,29 @@ module QA .with(/Test failure video recording setup complete!/) expect(RSpec).to have_received(:configure) expect(rspec_config).to have_received(:prepend_before) - expect(rspec_config).to have_received(:append_after) + expect(rspec_config).to have_received(:prepend_after) + end + end + + context 'with generate_allure_report' do + let(:rspec_config) do + instance_double('RSpec::Core::Configuration', + prepend_before: nil, + prepend_after: nil, + append_after: nil) + end + + let(:allure_report) { 'true' } + + it 'performs configuration with allure report' do + aggregate_failures do + expect(QA::Runtime::Logger).to have_received(:info) + .with(/Test failure video recording setup complete!/) + expect(RSpec).to have_received(:configure).twice + expect(rspec_config).to have_received(:prepend_before) + expect(rspec_config).to have_received(:prepend_after) + expect(rspec_config).to have_received(:append_after) + end end end end diff --git a/rubocop/cop/migration/avoid_finalize_background_migration.rb b/rubocop/cop/migration/avoid_finalize_background_migration.rb new file mode 100644 index 00000000000..42e6e72a330 --- /dev/null +++ b/rubocop/cop/migration/avoid_finalize_background_migration.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require_relative '../../migration_helpers' + +module RuboCop + module Cop + module Migration + class AvoidFinalizeBackgroundMigration < RuboCop::Cop::Base + include MigrationHelpers + + RESTRICT_ON_SEND = [:finalize_background_migration].freeze + + MSG = 'Prefer `ensure_batched_background_migration_is_finished` over ' \ + '`finalize_background_migration` in Batched Background Migrations. ' \ + 'See https://docs.gitlab.com/ee/development/database/batched_background_migrations.html' + + def on_send(node) + add_offense(node) + end + end + end + end +end diff --git a/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js b/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js index 24f96195e05..776395b9717 100644 --- a/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js +++ b/spec/frontend/vue_shared/components/upload_dropzone/upload_dropzone_spec.js @@ -1,6 +1,6 @@ import { GlIcon, GlSprintf } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; import { nextTick } from 'vue'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import UploadDropzone from '~/vue_shared/components/upload_dropzone/upload_dropzone.vue'; describe('Upload dropzone component', () => { @@ -11,13 +11,13 @@ describe('Upload dropzone component', () => { }; const findDropzoneCard = () => wrapper.find('.upload-dropzone-card'); - const findDropzoneArea = () => wrapper.find('[data-testid="dropzone-area"]'); + const findDropzoneArea = () => wrapper.findByTestId('dropzone-area'); const findIcon = () => wrapper.findComponent(GlIcon); - const findUploadText = () => wrapper.find('[data-testid="upload-text"]').text(); + const findUploadText = () => wrapper.findByTestId('upload-text').text(); const findFileInput = () => wrapper.find('input[type="file"]'); - function createComponent({ slots = {}, data = {}, props = {} } = {}) { - wrapper = shallowMount(UploadDropzone, { + function createComponent({ slots = {}, props = {} } = {}) { + wrapper = shallowMountExtended(UploadDropzone, { slots, propsData: { displayAsCard: true, @@ -26,9 +26,6 @@ describe('Upload dropzone component', () => { stubs: { GlSprintf, }, - data() { - return data; - }, }); } @@ -112,53 +109,50 @@ describe('Upload dropzone component', () => { wrapper.trigger('drop', mockEvent); await nextTick(); - expect(wrapper.emitted().change[0]).toEqual([[mockFile]]); + expect(wrapper.emitted('change')).toEqual([[[mockFile]]]); }); }); describe('ondrop', () => { - const mockData = { dragCounter: 1, isDragDataValid: true }; - describe('when drag data is valid', () => { it('emits upload event for valid files', () => { - createComponent({ data: mockData }); + createComponent(); const mockFile = { type: 'image/jpg' }; const mockEvent = mockDragEvent({ files: [mockFile] }); - wrapper.vm.ondrop(mockEvent); - expect(wrapper.emitted().change[0]).toEqual([[mockFile]]); + wrapper.trigger('drop', mockEvent); + expect(wrapper.emitted('change')).toEqual([[[mockFile]]]); }); it('emits error event when files are invalid', () => { - createComponent({ data: mockData }); + createComponent(); const mockEvent = mockDragEvent({ files: [{ type: 'audio/midi' }] }); - wrapper.vm.ondrop(mockEvent); + wrapper.trigger('drop', mockEvent); expect(wrapper.emitted()).toHaveProperty('error'); }); it('allows validation function to be overwritten', () => { - createComponent({ data: mockData, props: { isFileValid: () => true } }); + createComponent({ props: { isFileValid: () => true } }); const mockEvent = mockDragEvent({ files: [{ type: 'audio/midi' }] }); - wrapper.vm.ondrop(mockEvent); + wrapper.trigger('drop', mockEvent); expect(wrapper.emitted()).not.toHaveProperty('error'); }); describe('singleFileSelection = true', () => { it('emits a single file on drop', () => { createComponent({ - data: mockData, props: { singleFileSelection: true }, }); const mockFile = { type: 'image/jpg' }; const mockEvent = mockDragEvent({ files: [mockFile] }); - wrapper.vm.ondrop(mockEvent); - expect(wrapper.emitted().change[0]).toEqual([mockFile]); + wrapper.trigger('drop', mockEvent); + expect(wrapper.emitted('change')).toEqual([[mockFile]]); }); }); }); diff --git a/spec/graphql/gitlab_schema_spec.rb b/spec/graphql/gitlab_schema_spec.rb index b5c2d4da9ac..2e0711fe18c 100644 --- a/spec/graphql/gitlab_schema_spec.rb +++ b/spec/graphql/gitlab_schema_spec.rb @@ -12,10 +12,6 @@ RSpec.describe GitlabSchema do expect(tracers).to include(BatchLoader::GraphQL) end - it 'enables the generic instrumenter' do - expect(tracers).to include(instance_of(::Gitlab::Graphql::GenericTracing)) - end - it 'has the base mutation' do expect(described_class.mutation).to eq(::Types::MutationType) end diff --git a/spec/lib/gitlab/ci/artifact_file_reader_spec.rb b/spec/lib/gitlab/ci/artifact_file_reader_spec.rb index 76a596e1db3..ff918bbe558 100644 --- a/spec/lib/gitlab/ci/artifact_file_reader_spec.rb +++ b/spec/lib/gitlab/ci/artifact_file_reader_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::Ci::ArtifactFileReader do +RSpec.describe Gitlab::Ci::ArtifactFileReader, feature_category: :pipeline_composition do let(:job) { create(:ci_build) } let(:path) { 'generated.yml' } # included in the ci_build_artifacts.zip @@ -138,8 +138,8 @@ RSpec.describe Gitlab::Ci::ArtifactFileReader do end context 'when job does not have artifacts' do - it 'raises ArgumentError' do - expect { subject }.to raise_error(ArgumentError, 'Job does not have artifacts') + it 'raises an Error' do + expect { subject }.to raise_error(described_class::Error, 'Job does not have artifacts') end end end diff --git a/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb b/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb index 1f4586bd5a9..c7f18f0d01a 100644 --- a/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb +++ b/spec/lib/gitlab/ci/config/external/file/artifact_spec.rb @@ -41,6 +41,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Artifact, feature_category: : it 'sets the expected error' do expect(valid?).to be_falsy expect(external_file.errors).to contain_exactly(expected_error) + expect(external_file.content).to eq(nil) end end @@ -139,7 +140,7 @@ RSpec.describe Gitlab::Ci::Config::External::File::Artifact, feature_category: : before do allow_next_instance_of(Gitlab::Ci::ArtifactFileReader) do |reader| - allow(reader).to receive(:read).and_return('') + allow(reader).to receive(:read).and_return(nil) end end @@ -165,8 +166,8 @@ RSpec.describe Gitlab::Ci::Config::External::File::Artifact, feature_category: : } expect(context).to receive(:mutate).with(expected_attrs).and_call_original - expect(valid?).to be_truthy external_file.content + expect(valid?).to be_truthy end end end diff --git a/spec/lib/gitlab/graphql/generic_tracing_spec.rb b/spec/lib/gitlab/graphql/generic_tracing_spec.rb deleted file mode 100644 index 04fe7760f62..00000000000 --- a/spec/lib/gitlab/graphql/generic_tracing_spec.rb +++ /dev/null @@ -1,89 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::Graphql::GenericTracing, feature_category: :application_performance do - let(:graphql_duration_seconds_histogram) { double('Gitlab::Metrics::NullMetric') } - - context 'when graphql_generic_tracing_metrics_deactivate is disabled' do - before do - stub_feature_flags(graphql_generic_tracing_metrics_deactivate: false) - end - - it 'updates graphql histogram with expected labels' do - query = 'query { users { id } }' - tracer = described_class.new - - allow(tracer) - .to receive(:graphql_duration_seconds) - .and_return(graphql_duration_seconds_histogram) - - expect_metric('graphql.lex', 'lex') - expect_metric('graphql.parse', 'parse') - expect_metric('graphql.validate', 'validate') - expect_metric('graphql.analyze', 'analyze_multiplex') - expect_metric('graphql.execute', 'execute_query_lazy') - expect_metric('graphql.execute', 'execute_multiplex') - - GitlabSchema.execute(query, context: { tracers: [tracer] }) - end - end - - context 'when graphql_generic_tracing_metrics_deactivate is enabled' do - it 'does not updates graphql histogram with expected labels' do - query = 'query { users { id } }' - tracer = described_class.new - - allow(tracer) - .to receive(:graphql_duration_seconds) - .and_return(graphql_duration_seconds_histogram) - - GitlabSchema.execute(query, context: { tracers: [tracer] }) - - expect(graphql_duration_seconds_histogram) - .not_to receive(:observe) - end - end - - context "when labkit tracing is enabled" do - before do - expect(Labkit::Tracing).to receive(:enabled?).and_return(true) - end - - it 'yields with labkit tracing' do - expected_tags = { - 'component' => 'web', - 'span.kind' => 'server', - 'platform_key' => 'pkey', - 'key' => 'key' - } - - expect(Labkit::Tracing) - .to receive(:with_tracing) - .with(operation_name: "pkey.key", tags: expected_tags) - .and_yield - - expect { |b| described_class.new.platform_trace('pkey', 'key', nil, &b) }.to yield_control - end - end - - context "when labkit tracing is disabled" do - before do - expect(Labkit::Tracing).to receive(:enabled?).and_return(false) - end - - it 'yields without measurement' do - expect(Labkit::Tracing).not_to receive(:with_tracing) - - expect { |b| described_class.new.platform_trace('pkey', 'key', nil, &b) }.to yield_control - end - end - - private - - def expect_metric(platform_key, key) - expect(graphql_duration_seconds_histogram) - .to receive(:observe) - .with({ platform_key: platform_key, key: key }, be > 0.0) - end -end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_gbp_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_gbp_metric_spec.rb new file mode 100644 index 00000000000..aa14ffed25b --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_gbp_metric_spec.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountSlackAppInstallationsGbpMetric, feature_category: :integrations do + let_it_be(:slack_integration) { create(:slack_integration) } + let_it_be(:slack_integration_legacy) { create(:slack_integration, :legacy) } + + let(:expected_value) { 1 } + let(:expected_query) do + 'SELECT COUNT("slack_integrations"."id") FROM "slack_integrations" ' \ + 'WHERE "slack_integrations"."bot_user_id" IS NOT NULL' + end + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: 'all' } +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_metric_spec.rb new file mode 100644 index 00000000000..cfbecdad468 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_metric_spec.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountSlackAppInstallationsMetric, feature_category: :integrations do + let_it_be(:slack_integration) { create(:slack_integration) } + let_it_be(:slack_integration_legacy) { create(:slack_integration, :legacy) } + + let(:expected_value) { 2 } + let(:expected_query) { 'SELECT COUNT("slack_integrations"."id") FROM "slack_integrations"' } + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: 'all' } +end diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index f7c81f93260..6f5d4ed9d20 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -98,6 +98,7 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic it 'includes accurate usage_activity_by_stage data' do for_defined_days_back do user = create(:user) + project = create(:project, creator: user) create(:cluster, user: user) create(:cluster, :disabled, user: user) create(:cluster_provider_gcp, :created) @@ -108,6 +109,9 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic create(:cluster, :instance, :disabled, :production_environment) create(:cluster, :instance, :production_environment) create(:cluster, :management_project) + create(:integrations_slack, project: project) + create(:slack_slash_commands_integration, project: project) + create(:prometheus_integration, project: project) end expect(described_class.usage_activity_by_stage_configure({})).to include( @@ -122,7 +126,9 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic group_clusters_disabled: 2, group_clusters_enabled: 2, project_clusters_disabled: 2, - project_clusters_enabled: 10 + project_clusters_enabled: 10, + projects_slack_notifications_active: 2, + projects_slack_slash_active: 2 ) expect(described_class.usage_activity_by_stage_configure(described_class.monthly_time_range_db_params)).to include( clusters_management_project: 1, @@ -136,7 +142,9 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic group_clusters_disabled: 1, group_clusters_enabled: 1, project_clusters_disabled: 1, - project_clusters_enabled: 5 + project_clusters_enabled: 5, + projects_slack_notifications_active: 1, + projects_slack_slash_active: 1 ) end end diff --git a/spec/models/concerns/database_event_tracking_spec.rb b/spec/models/concerns/database_event_tracking_spec.rb index 502cecaaf76..a99b4737537 100644 --- a/spec/models/concerns/database_event_tracking_spec.rb +++ b/spec/models/concerns/database_event_tracking_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe DatabaseEventTracking, :snowplow do +RSpec.describe DatabaseEventTracking, :snowplow, feature_category: :service_ping do before do allow(Gitlab::Tracking).to receive(:database_event).and_call_original end @@ -31,18 +31,6 @@ RSpec.describe DatabaseEventTracking, :snowplow do end end - context 'if product_intelligence_database_event_tracking FF is off' do - before do - stub_feature_flags(product_intelligence_database_event_tracking: false) - end - - it 'does not track the event' do - create_test_class_record - - expect_no_snowplow_event(tracking_method: :database_event) - end - end - describe 'event tracking' do let(:category) { test_class.to_s } let(:event) { 'database_event' } diff --git a/spec/models/merge_request/metrics_spec.rb b/spec/models/merge_request/metrics_spec.rb index b1c2a9b1111..e9e4956dc41 100644 --- a/spec/models/merge_request/metrics_spec.rb +++ b/spec/models/merge_request/metrics_spec.rb @@ -94,7 +94,7 @@ RSpec.describe MergeRequest::Metrics do end end - it_behaves_like 'database events tracking batch 2' do + it_behaves_like 'database events tracking', feature_category: :service_ping do let(:merge_request) { create(:merge_request) } let(:record) { merge_request.metrics } diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index ee0aab6769a..9d7f6674ab8 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -2170,6 +2170,32 @@ RSpec.describe Project, factory_default: :keep, feature_category: :groups_and_pr end end + describe '.with_slack_integration' do + it 'returns projects with both active and inactive slack integrations' do + create(:project) + with_active_slack = create(:integrations_slack).project + with_disabled_slack = create(:integrations_slack, active: false).project + + expect(described_class.with_slack_integration).to contain_exactly( + with_active_slack, + with_disabled_slack + ) + end + end + + describe '.with_slack_slash_commands_integration' do + it 'returns projects with both active and inactive slack slash commands integrations' do + create(:project) + with_active_slash_commands = create(:slack_slash_commands_integration).project + with_disabled_slash_commands = create(:slack_slash_commands_integration, active: false).project + + expect(described_class.with_slack_slash_commands_integration).to contain_exactly( + with_active_slash_commands, + with_disabled_slash_commands + ) + end + end + describe '.cached_count', :use_clean_rails_memory_store_caching do let(:group) { create(:group, :public) } let!(:project1) { create(:project, :public, group: group) } diff --git a/spec/rubocop/cop/migration/avoid_finalize_background_migration_spec.rb b/spec/rubocop/cop/migration/avoid_finalize_background_migration_spec.rb new file mode 100644 index 00000000000..e4eec39e3ff --- /dev/null +++ b/spec/rubocop/cop/migration/avoid_finalize_background_migration_spec.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +require 'rubocop_spec_helper' +require_relative '../../../../rubocop/cop/migration/avoid_finalize_background_migration' + +RSpec.describe RuboCop::Cop::Migration::AvoidFinalizeBackgroundMigration, feature_category: :database do + context 'when file is under db/post_migration' do + it "flags the use of 'finalize_background_migration' method" do + expect_offense(<<~RUBY) + class FinalizeMyMigration < Gitlab::Database::Migration[2.1] + MIGRATION = 'MyMigration' + + def up + finalize_background_migration(MIGRATION) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ #{described_class::MSG} + end + end + RUBY + end + end +end diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml index 9747dbea646..0dda40d30f8 100644 --- a/spec/support/rspec_order_todo.yml +++ b/spec/support/rspec_order_todo.yml @@ -1521,8 +1521,6 @@ - './ee/spec/lib/gitlab/usage/metrics/instrumentations/count_groups_with_event_streaming_destinations_metric_spec.rb' - './ee/spec/lib/gitlab/usage/metrics/instrumentations/count_projects_with_external_status_checks_metric_spec.rb' - './ee/spec/lib/gitlab/usage/metrics/instrumentations/count_saml_group_links_metric_spec.rb' -- './ee/spec/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_gbp_metric_spec.rb' -- './ee/spec/lib/gitlab/usage/metrics/instrumentations/count_slack_app_installations_metric_spec.rb' - './ee/spec/lib/gitlab/usage/metrics/instrumentations/count_users_associating_group_milestones_to_releases_metric_spec.rb' - './ee/spec/lib/gitlab/usage/metrics/instrumentations/count_users_creating_ci_builds_metric_spec.rb' - './ee/spec/lib/gitlab/usage/metrics/instrumentations/count_users_deployment_approvals_spec.rb' @@ -6486,7 +6484,6 @@ - './spec/lib/gitlab/graphql/batch_key_spec.rb' - './spec/lib/gitlab/graphql/calls_gitaly/field_extension_spec.rb' - './spec/lib/gitlab/graphql/copy_field_description_spec.rb' -- './spec/lib/gitlab/graphql/generic_tracing_spec.rb' - './spec/lib/gitlab/graphql/known_operations_spec.rb' - './spec/lib/gitlab/graphql/lazy_spec.rb' - './spec/lib/gitlab/graphql/loaders/batch_commit_loader_spec.rb' diff --git a/spec/support/shared_examples/models/database_event_tracking_shared_examples.rb b/spec/support/shared_examples/models/database_event_tracking_shared_examples.rb index 3d98d9136e2..56b36b3ea07 100644 --- a/spec/support/shared_examples/models/database_event_tracking_shared_examples.rb +++ b/spec/support/shared_examples/models/database_event_tracking_shared_examples.rb @@ -12,7 +12,6 @@ RSpec.shared_examples 'database events tracking' do let(:category) { described_class.to_s } let(:label) { described_class.table_name } let(:action) { "database_event_#{property}" } - let(:feature_flag_name) { :product_intelligence_database_event_tracking } let(:record_tracked_attributes) { record.attributes.slice(*described_class::SNOWPLOW_ATTRIBUTES.map(&:to_s)) } let(:base_extra) { record_tracked_attributes.merge(project: try(:project), namespace: try(:namespace)) } @@ -48,9 +47,3 @@ RSpec.shared_examples 'database events tracking' do end end end - -RSpec.shared_examples 'database events tracking batch 2' do - it_behaves_like 'database events tracking' do - let(:feature_flag_name) { :product_intelligence_database_event_tracking_batch2 } - end -end |