Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
44d4b37b52
commit
7c41737ae5
|
@ -308,10 +308,18 @@ Rails/RakeEnvironment:
|
|||
# Context on why it's disabled: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93419#note_1048223982
|
||||
Enabled: false
|
||||
|
||||
# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/94064#note_1157289970
|
||||
Rails/SquishedSQLHeredocs:
|
||||
Enabled: false
|
||||
|
||||
# See https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96675#note_1094403693
|
||||
Rails/WhereExists:
|
||||
Enabled: false
|
||||
|
||||
# See https://gitlab.com/gitlab-org/gitlab/-/issues/378105#note_1138487716
|
||||
Rails/HasManyOrHasOneDependent:
|
||||
Enabled: false
|
||||
|
||||
# GitLab ###################################################################
|
||||
|
||||
Gitlab/ModuleWithInstanceVariables:
|
||||
|
|
|
@ -1,154 +0,0 @@
|
|||
---
|
||||
Rails/HasManyOrHasOneDependent:
|
||||
# Offense count: 593
|
||||
# Temporarily disabled due to too many offenses
|
||||
Enabled: false
|
||||
Exclude:
|
||||
- 'app/models/alert_management/alert.rb'
|
||||
- 'app/models/analytics/cycle_analytics/project_value_stream.rb'
|
||||
- 'app/models/analytics/cycle_analytics/stage_event_hash.rb'
|
||||
- 'app/models/application_setting/term.rb'
|
||||
- 'app/models/bulk_import.rb'
|
||||
- 'app/models/bulk_imports/entity.rb'
|
||||
- 'app/models/bulk_imports/export.rb'
|
||||
- 'app/models/ci/bridge.rb'
|
||||
- 'app/models/ci/build.rb'
|
||||
- 'app/models/ci/pipeline.rb'
|
||||
- 'app/models/ci/pipeline_schedule.rb'
|
||||
- 'app/models/ci/processable.rb'
|
||||
- 'app/models/ci/ref.rb'
|
||||
- 'app/models/ci/resource_group.rb'
|
||||
- 'app/models/ci/runner.rb'
|
||||
- 'app/models/ci/stage.rb'
|
||||
- 'app/models/ci/trigger.rb'
|
||||
- 'app/models/ci/trigger_request.rb'
|
||||
- 'app/models/ci/unit_test.rb'
|
||||
- 'app/models/clusters/agent.rb'
|
||||
- 'app/models/clusters/applications/knative.rb'
|
||||
- 'app/models/clusters/cluster.rb'
|
||||
- 'app/models/clusters/project.rb'
|
||||
- 'app/models/commit_status.rb'
|
||||
- 'app/models/concerns/ci/metadatable.rb'
|
||||
- 'app/models/concerns/integrations/has_data_fields.rb'
|
||||
- 'app/models/concerns/issuable.rb'
|
||||
- 'app/models/concerns/label_eventable.rb'
|
||||
- 'app/models/concerns/milestone_eventable.rb'
|
||||
- 'app/models/concerns/packages/debian/distribution.rb'
|
||||
- 'app/models/concerns/protected_ref.rb'
|
||||
- 'app/models/concerns/state_eventable.rb'
|
||||
- 'app/models/concerns/timebox.rb'
|
||||
- 'app/models/concerns/versioned_description.rb'
|
||||
- 'app/models/concerns/with_uploads.rb'
|
||||
- 'app/models/customer_relations/contact.rb'
|
||||
- 'app/models/deploy_key.rb'
|
||||
- 'app/models/deploy_token.rb'
|
||||
- 'app/models/deployment.rb'
|
||||
- 'app/models/design_management/design.rb'
|
||||
- 'app/models/design_management/version.rb'
|
||||
- 'app/models/environment.rb'
|
||||
- 'app/models/error_tracking/error.rb'
|
||||
- 'app/models/event.rb'
|
||||
- 'app/models/experiment.rb'
|
||||
- 'app/models/fork_network.rb'
|
||||
- 'app/models/gpg_key.rb'
|
||||
- 'app/models/group.rb'
|
||||
- 'app/models/hooks/web_hook.rb'
|
||||
- 'app/models/integration.rb'
|
||||
- 'app/models/issue.rb'
|
||||
- 'app/models/jira_connect_installation.rb'
|
||||
- 'app/models/label.rb'
|
||||
- 'app/models/lfs_object.rb'
|
||||
- 'app/models/list.rb'
|
||||
- 'app/models/member.rb'
|
||||
- 'app/models/merge_request.rb'
|
||||
- 'app/models/merge_request_context_commit.rb'
|
||||
- 'app/models/milestone.rb'
|
||||
- 'app/models/namespace.rb'
|
||||
- 'app/models/namespaces/project_namespace.rb'
|
||||
- 'app/models/note.rb'
|
||||
- 'app/models/operations/feature_flag.rb'
|
||||
- 'app/models/operations/feature_flags/strategy.rb'
|
||||
- 'app/models/operations/feature_flags/user_list.rb'
|
||||
- 'app/models/packages/debian/project_distribution.rb'
|
||||
- 'app/models/packages/dependency.rb'
|
||||
- 'app/models/packages/dependency_link.rb'
|
||||
- 'app/models/packages/package.rb'
|
||||
- 'app/models/packages/package_file.rb'
|
||||
- 'app/models/pages_domain.rb'
|
||||
- 'app/models/plan.rb'
|
||||
- 'app/models/pool_repository.rb'
|
||||
- 'app/models/project.rb'
|
||||
- 'app/models/projects/topic.rb'
|
||||
- 'app/models/prometheus_alert.rb'
|
||||
- 'app/models/prometheus_metric.rb'
|
||||
- 'app/models/release.rb'
|
||||
- 'app/models/snippet.rb'
|
||||
- 'app/models/terraform/state.rb'
|
||||
- 'app/models/user.rb'
|
||||
- 'app/models/wiki_page/meta.rb'
|
||||
- 'app/models/work_items/type.rb'
|
||||
- 'app/models/x509_certificate.rb'
|
||||
- 'app/models/x509_issuer.rb'
|
||||
- 'ee/app/models/analytics/devops_adoption/enabled_namespace.rb'
|
||||
- 'ee/app/models/analytics/devops_adoption/snapshot.rb'
|
||||
- 'ee/app/models/approval_merge_request_rule.rb'
|
||||
- 'ee/app/models/approval_project_rule.rb'
|
||||
- 'ee/app/models/boards/epic_board.rb'
|
||||
- 'ee/app/models/boards/epic_list.rb'
|
||||
- 'ee/app/models/compliance_management/framework.rb'
|
||||
- 'ee/app/models/concerns/ee/iteration_eventable.rb'
|
||||
- 'ee/app/models/concerns/ee/protected_branch.rb'
|
||||
- 'ee/app/models/concerns/ee/protected_ref.rb'
|
||||
- 'ee/app/models/concerns/ee/weight_eventable.rb'
|
||||
- 'ee/app/models/concerns/geo/eventable.rb'
|
||||
- 'ee/app/models/concerns/issue_widgets/acts_like_requirement.rb'
|
||||
- 'ee/app/models/concerns/security/scan_execution_policy.rb'
|
||||
- 'ee/app/models/dast/profile.rb'
|
||||
- 'ee/app/models/dast_site.rb'
|
||||
- 'ee/app/models/dast_site_profile.rb'
|
||||
- 'ee/app/models/dast_site_validation.rb'
|
||||
- 'ee/app/models/ee/alert_management/alert.rb'
|
||||
- 'ee/app/models/ee/analytics/cycle_analytics/stage_event_hash.rb'
|
||||
- 'ee/app/models/ee/board.rb'
|
||||
- 'ee/app/models/ee/ci/build.rb'
|
||||
- 'ee/app/models/ee/ci/job_artifact.rb'
|
||||
- 'ee/app/models/ee/ci/pipeline.rb'
|
||||
- 'ee/app/models/ee/deployment.rb'
|
||||
- 'ee/app/models/ee/environment.rb'
|
||||
- 'ee/app/models/ee/epic.rb'
|
||||
- 'ee/app/models/ee/group.rb'
|
||||
- 'ee/app/models/ee/issue.rb'
|
||||
- 'ee/app/models/ee/iteration.rb'
|
||||
- 'ee/app/models/ee/label.rb'
|
||||
- 'ee/app/models/ee/lfs_object.rb'
|
||||
- 'ee/app/models/ee/merge_request.rb'
|
||||
- 'ee/app/models/ee/merge_request_diff.rb'
|
||||
- 'ee/app/models/ee/milestone.rb'
|
||||
- 'ee/app/models/ee/namespace.rb'
|
||||
- 'ee/app/models/ee/pages_deployment.rb'
|
||||
- 'ee/app/models/ee/plan.rb'
|
||||
- 'ee/app/models/ee/project.rb'
|
||||
- 'ee/app/models/ee/upload.rb'
|
||||
- 'ee/app/models/ee/user.rb'
|
||||
- 'ee/app/models/ee/vulnerability.rb'
|
||||
- 'ee/app/models/elastic/reindexing_subtask.rb'
|
||||
- 'ee/app/models/elastic/reindexing_task.rb'
|
||||
- 'ee/app/models/geo/event.rb'
|
||||
- 'ee/app/models/geo_node.rb'
|
||||
- 'ee/app/models/incident_management/escalation_policy.rb'
|
||||
- 'ee/app/models/incident_management/oncall_participant.rb'
|
||||
- 'ee/app/models/incident_management/oncall_rotation.rb'
|
||||
- 'ee/app/models/incident_management/oncall_schedule.rb'
|
||||
- 'ee/app/models/integrations/gitlab_slack_application.rb'
|
||||
- 'ee/app/models/iterations/cadence.rb'
|
||||
- 'ee/app/models/protected_environment.rb'
|
||||
- 'ee/app/models/protected_environments/approval_rule.rb'
|
||||
- 'ee/app/models/push_rule.rb'
|
||||
- 'ee/app/models/saml_provider.rb'
|
||||
- 'ee/app/models/security/finding.rb'
|
||||
- 'ee/app/models/security/scan.rb'
|
||||
- 'ee/app/models/security/training_provider.rb'
|
||||
- 'ee/app/models/vulnerabilities/finding.rb'
|
||||
- 'ee/app/models/vulnerabilities/identifier.rb'
|
||||
- 'ee/app/models/vulnerabilities/remediation.rb'
|
||||
- 'ee/app/models/vulnerabilities/scanner.rb'
|
|
@ -1,215 +0,0 @@
|
|||
---
|
||||
# Cop supports --auto-correct.
|
||||
Rails/SquishedSQLHeredocs:
|
||||
# Offense count: 356
|
||||
# Temporarily disabled due to too many offenses
|
||||
Enabled: false
|
||||
Exclude:
|
||||
- 'app/finders/members_finder.rb'
|
||||
- 'app/models/analytics/cycle_analytics/stage_event_hash.rb'
|
||||
- 'app/models/ci/resource_group.rb'
|
||||
- 'app/models/clusters/clusters_hierarchy.rb'
|
||||
- 'app/models/concerns/analytics/cycle_analytics/stage_event_model.rb'
|
||||
- 'app/models/concerns/has_environment_scope.rb'
|
||||
- 'app/models/customer_relations/contact.rb'
|
||||
- 'app/models/customer_relations/organization.rb'
|
||||
- 'app/models/deployment.rb'
|
||||
- 'app/models/issue/metrics.rb'
|
||||
- 'app/models/merge_request/metrics.rb'
|
||||
- 'app/models/namespace/traversal_hierarchy.rb'
|
||||
- 'app/models/namespaces/traversal/linear.rb'
|
||||
- 'app/models/project.rb'
|
||||
- 'app/models/user.rb'
|
||||
- 'app/services/issuable/destroy_label_links_service.rb'
|
||||
- 'app/services/issues/relative_position_rebalancing_service.rb'
|
||||
- 'app/services/projects/fetch_statistics_increment_service.rb'
|
||||
- 'app/services/todos/destroy/destroyed_issuable_service.rb'
|
||||
- 'app/workers/users/deactivate_dormant_users_worker.rb'
|
||||
- 'db/migrate/20210323155010_populate_dismissal_information_for_vulnerabilities.rb'
|
||||
- 'db/migrate/20210601080039_group_protected_environments_add_index_and_constraint.rb'
|
||||
- 'db/migrate/20210611100359_rebuild_index_for_cadence_iterations_automation.rb'
|
||||
- 'db/migrate/20210617022324_create_incident_management_pending_alert_escalations.rb'
|
||||
- 'db/migrate/20210621043337_rename_services_to_integrations.rb'
|
||||
- 'db/migrate/20210621044000_rename_services_indexes_to_integrations.rb'
|
||||
- 'db/migrate/20210706152139_add_index_type_to_postgres_indexes_view.rb'
|
||||
- 'db/migrate/20210719145532_add_foreign_keys_view.rb'
|
||||
- 'db/migrate/20210721135638_add_triggers_to_integrations_type_new.rb'
|
||||
- 'db/migrate/20210721174453_remove_schedule_and_status_null_constraints_from_pending_escalations_alert.rb'
|
||||
- 'db/migrate/20210722150102_operations_feature_flags_correct_flexible_rollout_values.rb'
|
||||
- 'db/migrate/20210730194555_create_incident_management_pending_issue_escalations.rb'
|
||||
- 'db/migrate/20210818175949_update_integrations_trigger_type_new_on_insert.rb'
|
||||
- 'db/migrate/20210825104656_create_analytics_cycle_analytics_merge_request_stage_events.rb'
|
||||
- 'db/migrate/20210825110016_create_analytics_cycle_analytics_issue_stage_events.rb'
|
||||
- 'db/migrate/20210826122748_create_loose_foreign_keys_deleted_records.rb'
|
||||
- 'db/migrate/20210826145509_add_function_for_inserting_deleted_records.rb'
|
||||
- 'db/migrate/20210903054158_recreate_stage_issue_events_table_with_bigints.rb'
|
||||
- 'db/migrate/20210906100021_delete_project_namespace_trigger.rb'
|
||||
- 'db/migrate/20210929032555_create_verification_codes.rb'
|
||||
- 'db/migrate/20211005092428_drop_time_range_partitioned_loose_fk.rb'
|
||||
- 'db/migrate/20211005093558_add_range_partitioned_loose_fk_table.rb'
|
||||
- 'db/migrate/20211005100112_recreate_loose_fk_insert_function.rb'
|
||||
- 'db/migrate/20211007090229_create_issue_search_table.rb'
|
||||
- 'db/migrate/20211011141242_create_namespaces_sync_trigger.rb'
|
||||
- 'db/migrate/20211011141243_create_projects_sync_trigger.rb'
|
||||
- 'db/migrate/20211012015903_next_traversal_ids_sibling_function.rb'
|
||||
- 'db/migrate/20211018161447_fix_double_entries_in_postgres_index_view.rb'
|
||||
- 'db/migrate/20211112155416_populate_default_value_for_personal_access_tokens_prefix.rb'
|
||||
- 'db/migrate/20211118103439_remove_hardcoded_partition_from_loose_fk_trigger_function.rb'
|
||||
- 'db/migrate/20211123135255_create_batched_background_migration_job_transition_logs.rb'
|
||||
- 'db/migrate/20220106111958_add_insert_or_update_vulnerability_reads_trigger.rb'
|
||||
- 'db/migrate/20220106112043_add_update_vulnerability_reads_trigger.rb'
|
||||
- 'db/migrate/20220106112085_add_update_vulnerability_reads_location_trigger.rb'
|
||||
- 'db/migrate/20220106163326_add_has_issues_on_vulnerability_reads_trigger.rb'
|
||||
- 'db/migrate/20220208171826_update_default_scan_method_of_dast_site_profile.rb'
|
||||
- 'db/migrate/20220211214605_update_integrations_trigger_type_new_on_insert_null_safe.rb'
|
||||
- 'db/migrate/20220213100000_remove_integration_type_triggers.rb'
|
||||
- 'db/migrate/20220304052335_remove_not_null_contraint_on_title_from_sprints.rb'
|
||||
- 'db/migrate/20220321234317_remove_all_issuable_escalation_statuses.rb'
|
||||
- 'db/migrate/20220329110630_add_ci_namespace_mirrors_unnest_index_on_traversal_ids.rb'
|
||||
- 'db/migrate/20220412060931_add_nullify_build_data_trigger_on_merge_request_metrics.rb'
|
||||
- 'db/migrate/20220413124200_add_view_for_per_table_autovacuum_status.rb'
|
||||
- 'db/migrate/20220415015143_replace_iterations_cadence_date_range_constraint.rb'
|
||||
- 'db/migrate/20220422200633_fix_view_for_per_table_autovacuum_status.rb'
|
||||
- 'db/migrate/20220422220507_remove_tmp_index_supporting_leaky_regex_cleanup.rb'
|
||||
- 'db/post_migrate/20210302074524_backfill_namespace_statistics_with_wiki_size.rb'
|
||||
- 'db/post_migrate/20210311045138_set_traversal_ids_for_gitlab_org_group_staging.rb'
|
||||
- 'db/post_migrate/20210311045139_set_traversal_ids_for_gitlab_org_group_com.rb'
|
||||
- 'db/post_migrate/20210311093723_add_partial_index_on_ci_pipelines_by_cancelable_status_and_users.rb'
|
||||
- 'db/post_migrate/20210317104032_set_iteration_cadence_automatic_to_false.rb'
|
||||
- 'db/post_migrate/20210331105335_drop_non_partitioned_audit_events.rb'
|
||||
- 'db/post_migrate/20210430134202_copy_adoption_snapshot_namespace.rb'
|
||||
- 'db/post_migrate/20210430135954_copy_adoption_segments_namespace.rb'
|
||||
- 'db/post_migrate/20210525075724_clean_up_pending_builds_table.rb'
|
||||
- 'db/post_migrate/20210609125005_drop_non_partitioned_web_hook_logs.rb'
|
||||
- 'db/post_migrate/20210610102413_migrate_protected_attribute_to_pending_builds.rb'
|
||||
- 'db/post_migrate/20210610141711_disable_expiration_policies_linked_to_no_container_images.rb'
|
||||
- 'db/post_migrate/20210708011426_finalize_ci_builds_metadata_bigint_conversion.rb'
|
||||
- 'db/post_migrate/20210721174521_add_non_null_constraint_for_escalation_rule_on_pending_alert_escalations.rb'
|
||||
- 'db/post_migrate/20210812013042_remove_duplicate_project_authorizations.rb'
|
||||
- 'db/post_migrate/20210907211557_finalize_ci_builds_bigint_conversion.rb'
|
||||
- 'db/post_migrate/20210910194952_update_report_type_for_existing_approval_project_rules.rb'
|
||||
- 'db/post_migrate/20211105135157_drop_ci_build_trace_sections.rb'
|
||||
- 'db/post_migrate/20211112113300_remove_ci_pipeline_chat_data_fk_on_chat_names.rb'
|
||||
- 'db/post_migrate/20211130165043_backfill_sequence_column_for_sprints_table.rb'
|
||||
- 'db/post_migrate/20211206161271_add_indexes_for_primary_email_cleanup_migration.rb'
|
||||
- 'db/post_migrate/20211220064757_drop_temporary_indexes_for_primary_email_migration.rb'
|
||||
- 'db/post_migrate/20220128155251_remove_dangling_running_builds.rb'
|
||||
- 'db/post_migrate/20220204095121_backfill_namespace_statistics_with_dependency_proxy_size.rb'
|
||||
- 'db/post_migrate/20220204110725_backfill_cycle_analytics_aggregations.rb'
|
||||
- 'db/post_migrate/20220213103859_remove_integrations_type.rb'
|
||||
- 'db/post_migrate/20220309084954_remove_leftover_external_pull_request_deletions.rb'
|
||||
- 'db/post_migrate/20220318111040_add_indexes_for_primary_email_second_cleanup_migration.rb'
|
||||
- 'db/post_migrate/20220318111949_drop_temporary_indexes_for_primary_email_migration_second_cleanup.rb'
|
||||
- 'db/post_migrate/20220329175119_remove_leftover_ci_job_artifact_deletions.rb'
|
||||
- 'db/post_migrate/20220420135946_update_batched_background_migration_arguments.rb'
|
||||
- 'ee/app/models/dora/daily_metrics.rb'
|
||||
- 'ee/app/models/ee/group.rb'
|
||||
- 'ee/app/models/ee/issue.rb'
|
||||
- 'ee/app/models/iterations/cadence.rb'
|
||||
- 'ee/app/models/vulnerabilities/statistic.rb'
|
||||
- 'ee/app/services/analytics/cycle_analytics/consistency_check_service.rb'
|
||||
- 'ee/app/services/security/ingestion/tasks/ingest_vulnerability_statistics.rb'
|
||||
- 'ee/app/services/vulnerabilities/historical_statistics/adjustment_service.rb'
|
||||
- 'ee/app/services/vulnerabilities/statistics/adjustment_service.rb'
|
||||
- 'ee/app/services/vulnerabilities/statistics/update_service.rb'
|
||||
- 'ee/db/geo/migrate/20170906174622_remove_duplicates_from_project_registry.rb'
|
||||
- 'ee/db/geo/migrate/20180510223634_set_resync_flag_for_retried_projects.rb'
|
||||
- 'ee/db/geo/post_migrate/20210217020154_add_unique_index_on_container_repository_registry.rb'
|
||||
- 'ee/db/geo/post_migrate/20210217020156_add_unique_index_on_terraform_state_version_registry.rb'
|
||||
- 'ee/lib/ee/gitlab/background_migration/backfill_iteration_cadence_id_for_boards.rb'
|
||||
- 'ee/lib/ee/gitlab/background_migration/create_security_setting.rb'
|
||||
- 'ee/lib/ee/gitlab/background_migration/populate_latest_pipeline_ids.rb'
|
||||
- 'ee/lib/ee/gitlab/background_migration/populate_resolved_on_default_branch_column.rb'
|
||||
- 'ee/lib/ee/gitlab/background_migration/populate_status_column_of_security_scans.rb'
|
||||
- 'ee/lib/ee/gitlab/background_migration/populate_test_reports_issue_id.rb'
|
||||
- 'ee/lib/ee/gitlab/background_migration/update_vulnerability_occurrences_location.rb'
|
||||
- 'ee/lib/ee/gitlab/usage_data.rb'
|
||||
- 'ee/lib/gitlab/geo/base_batcher.rb'
|
||||
- 'ee/spec/models/ee/user_spec.rb'
|
||||
- 'lib/gitlab/background_migration/backfill_ci_namespace_mirrors.rb'
|
||||
- 'lib/gitlab/background_migration/backfill_ci_project_mirrors.rb'
|
||||
- 'lib/gitlab/background_migration/backfill_group_features.rb'
|
||||
- 'lib/gitlab/background_migration/backfill_integrations_type_new.rb'
|
||||
- 'lib/gitlab/background_migration/backfill_issue_search_data.rb'
|
||||
- 'lib/gitlab/background_migration/backfill_namespace_id_for_project_route.rb'
|
||||
- 'lib/gitlab/background_migration/backfill_namespace_traversal_ids_children.rb'
|
||||
- 'lib/gitlab/background_migration/backfill_project_settings.rb'
|
||||
- 'lib/gitlab/background_migration/backfill_projects_with_coverage.rb'
|
||||
- 'lib/gitlab/background_migration/backfill_upvotes_count_on_issues.rb'
|
||||
- 'lib/gitlab/background_migration/disable_expiration_policies_linked_to_no_container_images.rb'
|
||||
- 'lib/gitlab/background_migration/encrypt_static_object_token.rb'
|
||||
- 'lib/gitlab/background_migration/fix_duplicate_project_name_and_path.rb'
|
||||
- 'lib/gitlab/background_migration/fix_first_mentioned_in_commit_at.rb'
|
||||
- 'lib/gitlab/background_migration/fix_projects_without_project_feature.rb'
|
||||
- 'lib/gitlab/background_migration/fix_projects_without_prometheus_service.rb'
|
||||
- 'lib/gitlab/background_migration/move_container_registry_enabled_to_project_feature.rb'
|
||||
- 'lib/gitlab/background_migration/populate_container_repository_migration_plan.rb'
|
||||
- 'lib/gitlab/background_migration/populate_topics_non_private_projects_count.rb'
|
||||
- 'lib/gitlab/background_migration/populate_topics_total_projects_count_cache.rb'
|
||||
- 'lib/gitlab/background_migration/populate_vulnerability_reads.rb'
|
||||
- 'lib/gitlab/background_migration/project_namespaces/backfill_project_namespaces.rb'
|
||||
- 'lib/gitlab/background_migration/update_timelogs_null_spent_at.rb'
|
||||
- 'lib/gitlab/background_migration/update_timelogs_project_id.rb'
|
||||
- 'lib/gitlab/background_migration/update_users_where_two_factor_auth_required_from_group.rb'
|
||||
- 'lib/gitlab/database/bulk_update.rb'
|
||||
- 'lib/gitlab/database/count/tablesample_count_strategy.rb'
|
||||
- 'lib/gitlab/database/load_balancing/load_balancer.rb'
|
||||
- 'lib/gitlab/database/migration_helpers.rb'
|
||||
- 'lib/gitlab/database/migration_helpers/loose_foreign_key_helpers.rb'
|
||||
- 'lib/gitlab/database/migration_helpers/v2.rb'
|
||||
- 'lib/gitlab/database/migrations/batched_background_migration_helpers.rb'
|
||||
- 'lib/gitlab/database/migrations/observers/query_statistics.rb'
|
||||
- 'lib/gitlab/database/partitioning/replace_table.rb'
|
||||
- 'lib/gitlab/database/partitioning/single_numeric_list_partition.rb'
|
||||
- 'lib/gitlab/database/partitioning/sliding_list_strategy.rb'
|
||||
- 'lib/gitlab/database/partitioning/time_partition.rb'
|
||||
- 'lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table.rb'
|
||||
- 'lib/gitlab/database/partitioning_migration_helpers/table_management_helpers.rb'
|
||||
- 'lib/gitlab/database/postgres_hll/batch_distinct_counter.rb'
|
||||
- 'lib/gitlab/database/schema_helpers.rb'
|
||||
- 'lib/gitlab/database/schema_migrations/migrations.rb'
|
||||
- 'lib/gitlab/database/unidirectional_copy_trigger.rb'
|
||||
- 'lib/gitlab/graphql/pagination/keyset/conditions/not_null_condition.rb'
|
||||
- 'lib/gitlab/graphql/pagination/keyset/conditions/null_condition.rb'
|
||||
- 'lib/gitlab/pagination/keyset/in_operator_optimization/query_builder.rb'
|
||||
- 'lib/gitlab/sql/glob.rb'
|
||||
- 'lib/tasks/dev.rake'
|
||||
- 'qa/qa/service/praefect_manager.rb'
|
||||
- 'spec/db/schema_spec.rb'
|
||||
- 'spec/initializers/00_rails_disable_joins_spec.rb'
|
||||
- 'spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb'
|
||||
- 'spec/lib/gitlab/database/migration_helpers/restrict_gitlab_schema_spec.rb'
|
||||
- 'spec/lib/gitlab/database/migration_helpers_spec.rb'
|
||||
- 'spec/lib/gitlab/database/migrations/observers/query_statistics_spec.rb'
|
||||
- 'spec/lib/gitlab/database/partitioning/detached_partition_dropper_spec.rb'
|
||||
- 'spec/lib/gitlab/database/partitioning/monthly_strategy_spec.rb'
|
||||
- 'spec/lib/gitlab/database/partitioning/partition_manager_spec.rb'
|
||||
- 'spec/lib/gitlab/database/partitioning/replace_table_spec.rb'
|
||||
- 'spec/lib/gitlab/database/partitioning/sliding_list_strategy_spec.rb'
|
||||
- 'spec/lib/gitlab/database/partitioning/time_partition_spec.rb'
|
||||
- 'spec/lib/gitlab/database/partitioning_migration_helpers/backfill_partitioned_table_spec.rb'
|
||||
- 'spec/lib/gitlab/database/partitioning_migration_helpers/foreign_key_helpers_spec.rb'
|
||||
- 'spec/lib/gitlab/database/partitioning_migration_helpers/index_helpers_spec.rb'
|
||||
- 'spec/lib/gitlab/database/partitioning_migration_helpers/table_management_helpers_spec.rb'
|
||||
- 'spec/lib/gitlab/database/partitioning_spec.rb'
|
||||
- 'spec/lib/gitlab/database/postgres_foreign_key_spec.rb'
|
||||
- 'spec/lib/gitlab/database/postgres_index_bloat_estimate_spec.rb'
|
||||
- 'spec/lib/gitlab/database/postgres_index_spec.rb'
|
||||
- 'spec/lib/gitlab/database/postgres_partition_spec.rb'
|
||||
- 'spec/lib/gitlab/database/postgres_partitioned_table_spec.rb'
|
||||
- 'spec/lib/gitlab/database/reindexing/reindex_concurrently_spec.rb'
|
||||
- 'spec/lib/gitlab/database/reindexing_spec.rb'
|
||||
- 'spec/lib/gitlab/database/schema_migrations/migrations_spec.rb'
|
||||
- 'spec/lib/gitlab/database/similarity_score_spec.rb'
|
||||
- 'spec/lib/gitlab/database/unidirectional_copy_trigger_spec.rb'
|
||||
- 'spec/lib/gitlab/graphql/pagination/keyset/conditions/not_null_condition_spec.rb'
|
||||
- 'spec/lib/gitlab/graphql/pagination/keyset/conditions/null_condition_spec.rb'
|
||||
- 'spec/lib/gitlab/pagination/keyset/in_operator_optimization/strategies/record_loader_strategy_spec.rb'
|
||||
- 'spec/lib/gitlab/pagination/keyset/order_spec.rb'
|
||||
- 'spec/models/application_record_spec.rb'
|
||||
- 'spec/models/concerns/after_commit_queue_spec.rb'
|
||||
- 'spec/support/db_cleaner.rb'
|
||||
- 'spec/support/helpers/database/partitioning_helpers.rb'
|
||||
- 'spec/support/helpers/database/table_schema_helpers.rb'
|
||||
- 'spec/support/helpers/database/trigger_helpers.rb'
|
||||
- 'spec/support/shared_examples/loose_foreign_keys/have_loose_foreign_key.rb'
|
|
@ -3,7 +3,6 @@ RSpec/FactoryBot/AvoidCreate:
|
|||
Exclude:
|
||||
- 'ee/spec/presenters/approval_rule_presenter_spec.rb'
|
||||
- 'ee/spec/presenters/audit_event_presenter_spec.rb'
|
||||
- 'ee/spec/presenters/ci/build_presenter_spec.rb'
|
||||
- 'ee/spec/presenters/ci/build_runner_presenter_spec.rb'
|
||||
- 'ee/spec/presenters/ci/minutes/usage_presenter_spec.rb'
|
||||
- 'ee/spec/presenters/ci/pipeline_presenter_spec.rb'
|
||||
|
|
|
@ -89,6 +89,8 @@ export default {
|
|||
:default-max-date="maxDate"
|
||||
:same-day-selection="includeSelectedDate"
|
||||
:tooltip="maxDateRangeTooltip"
|
||||
:from-label="__('From')"
|
||||
:to-label="__('To')"
|
||||
theme="animate-picker"
|
||||
start-picker-class="js-daterange-picker-from gl-display-flex gl-flex-direction-column gl-lg-flex-direction-row gl-lg-align-items-center gl-lg-mr-3 gl-mb-2 gl-lg-mb-0"
|
||||
end-picker-class="js-daterange-picker-to gl-display-flex gl-flex-direction-column gl-lg-flex-direction-row gl-lg-align-items-center gl-mb-2 gl-lg-mb-0"
|
||||
|
|
|
@ -240,7 +240,7 @@ export default {
|
|||
</template>
|
||||
<template #header>
|
||||
<gl-dropdown-section-header>{{ __('Projects') }}</gl-dropdown-section-header>
|
||||
<gl-search-box-by-type v-model.trim="searchTerm" />
|
||||
<gl-search-box-by-type v-model.trim="searchTerm" :placeholder="__('Search')" />
|
||||
</template>
|
||||
<template #highlighted-items>
|
||||
<gl-dropdown-item
|
||||
|
|
|
@ -62,7 +62,11 @@ export default {
|
|||
return {
|
||||
primary: {
|
||||
text: __('Yes, delete project'),
|
||||
attributes: [{ variant: 'danger' }, { disabled: this.confirmDisabled }],
|
||||
attributes: [
|
||||
{ variant: 'danger' },
|
||||
{ disabled: this.confirmDisabled },
|
||||
{ 'data-qa-selector': 'confirm_delete_button' },
|
||||
],
|
||||
},
|
||||
cancel: {
|
||||
text: __('Cancel, keep project'),
|
||||
|
@ -97,9 +101,13 @@ export default {
|
|||
<input type="hidden" name="_method" value="delete" />
|
||||
<input :value="csrfToken" type="hidden" name="authenticity_token" />
|
||||
|
||||
<gl-button v-gl-modal="modalId" category="primary" variant="danger">{{
|
||||
$options.strings.deleteProject
|
||||
}}</gl-button>
|
||||
<gl-button
|
||||
v-gl-modal="modalId"
|
||||
category="primary"
|
||||
variant="danger"
|
||||
data-qa-selector="delete_button"
|
||||
>{{ $options.strings.deleteProject }}</gl-button
|
||||
>
|
||||
|
||||
<gl-modal
|
||||
ref="removeModal"
|
||||
|
@ -168,6 +176,7 @@ export default {
|
|||
v-model="userInput"
|
||||
name="confirm_name_input"
|
||||
type="text"
|
||||
data-qa-selector="confirm_name_field"
|
||||
/>
|
||||
<slot name="modal-footer"></slot>
|
||||
</div>
|
||||
|
|
|
@ -45,6 +45,9 @@ export default {
|
|||
if (this.status === 'closed') return 'gl-bg-red-50';
|
||||
return null;
|
||||
},
|
||||
hasActionsSlot() {
|
||||
return this.$scopedSlots.actions?.()?.length;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -72,15 +75,18 @@ export default {
|
|||
<div class="gl-display-flex gl-w-full">
|
||||
<div
|
||||
:class="{
|
||||
'gl-display-flex': actions.length,
|
||||
'gl-display-flex gl-align-items-center': actions.length,
|
||||
'gl-md-display-flex gl-align-items-center': !actions.length,
|
||||
}"
|
||||
class="media-body"
|
||||
>
|
||||
<slot></slot>
|
||||
<div
|
||||
:class="{ 'gl-flex-direction-column-reverse': !actions.length }"
|
||||
class="gl-display-flex gl-md-display-block gl-font-size-0 gl-ml-auto"
|
||||
:class="{
|
||||
'gl-flex-direction-column-reverse gl-md-flex-direction-row gl-flex-wrap gl-justify-content-end': !actions.length,
|
||||
'gl-md-pt-0 gl-pt-3': hasActionsSlot,
|
||||
}"
|
||||
class="gl-display-flex gl-font-size-0 gl-ml-auto gl-gap-3"
|
||||
>
|
||||
<slot name="actions">
|
||||
<actions v-if="actions.length" :tertiary-buttons="actions" />
|
||||
|
|
|
@ -26,7 +26,7 @@ export default {
|
|||
<template>
|
||||
<state-container :mr="mr" status="failed">
|
||||
<span
|
||||
class="gl-ml-3 gl-font-weight-bold gl-w-100 gl-flex-grow-1 gl-md-mr-3 gl-ml-0! gl-text-body!"
|
||||
class="gl-ml-3 gl-font-weight-bold gl-w-100 gl-flex-grow-1 gl-md-mr-3 gl-ml-0! gl-text-body! gl-align-self-start"
|
||||
>
|
||||
{{ s__('mrWidget|Merge blocked: all threads must be resolved.') }}
|
||||
</span>
|
||||
|
@ -34,7 +34,7 @@ export default {
|
|||
<gl-button
|
||||
v-if="mr.createIssueToResolveDiscussionsPath"
|
||||
:href="mr.createIssueToResolveDiscussionsPath"
|
||||
class="js-create-issue gl-align-self-start gl-vertical-align-top gl-mr-2"
|
||||
class="js-create-issue gl-align-self-start gl-vertical-align-top"
|
||||
size="small"
|
||||
variant="confirm"
|
||||
category="secondary"
|
||||
|
@ -43,7 +43,7 @@ export default {
|
|||
</gl-button>
|
||||
<gl-button
|
||||
data-testid="jump-to-first"
|
||||
class="gl-mb-2 gl-md-mb-0 gl-align-self-start gl-vertical-align-top"
|
||||
class="gl-align-self-start gl-vertical-align-top"
|
||||
size="small"
|
||||
variant="confirm"
|
||||
category="primary"
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
.top-area
|
||||
= gl_tabs_nav({ class: 'gl-flex-grow-1 gl-border-0' }) do
|
||||
= gl_tab_link_to _("Your groups"), dashboard_groups_path
|
||||
= gl_tab_link_to _("Explore public groups"), explore_groups_path
|
||||
= gl_tab_link_to _("Explore public groups"), explore_groups_path, data: { qa_selector: "public_groups_tab" }
|
||||
.nav-controls
|
||||
= render 'shared/groups/search_form'
|
||||
= render 'shared/groups/dropdown'
|
||||
|
|
|
@ -21,6 +21,8 @@ metadata:
|
|||
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: ci_resource_groups
|
||||
description: Operations to manage job concurrency with resource groups
|
||||
- name: deploy_keys
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# See https://docs.gitlab.com/ee/development/migration_style_guide.html
|
||||
# for more information on how to write migrations for GitLab.
|
||||
|
||||
class ChangeMemberNamespaceIdNotNull < Gitlab::Database::Migration[2.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_not_null_constraint :members, :member_namespace_id, validate: false
|
||||
end
|
||||
|
||||
def down
|
||||
remove_not_null_constraint :members, :member_namespace_id
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ValidateEnvironmentIdOnDeployments < Gitlab::Database::Migration[2.0]
|
||||
def up
|
||||
validate_foreign_key :deployments, :environment_id
|
||||
end
|
||||
|
||||
def down
|
||||
# no-op
|
||||
end
|
||||
end
|
|
@ -0,0 +1,15 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ValidateNotNullConstraintOnMemberNamespaceId < Gitlab::Database::Migration[2.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
CONSTRAINT_NAME = 'check_508774aac0'
|
||||
|
||||
def up
|
||||
validate_not_null_constraint :members, :member_namespace_id, constraint_name: CONSTRAINT_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
# no-op
|
||||
end
|
||||
end
|
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ValidateFkMemberNamespaceId < Gitlab::Database::Migration[2.0]
|
||||
CONSTRAINT_NAME = 'fk_2f85abf8f1'
|
||||
|
||||
def up
|
||||
validate_foreign_key :members, :member_namespace_id, name: CONSTRAINT_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
# no-op
|
||||
end
|
||||
end
|
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class RemoveOldMemberNamespaceIdFk < Gitlab::Database::Migration[2.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
TARGET_COLUMN = :member_namespace_id
|
||||
|
||||
def up
|
||||
with_lock_retries do
|
||||
remove_foreign_key_if_exists(:members, column: TARGET_COLUMN, name: fk_name(TARGET_COLUMN))
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
add_concurrent_foreign_key(
|
||||
:members,
|
||||
:namespaces,
|
||||
column: TARGET_COLUMN,
|
||||
name: fk_name(TARGET_COLUMN),
|
||||
on_delete: :nullify
|
||||
)
|
||||
end
|
||||
|
||||
def fk_name(column_name)
|
||||
# generate a FK name
|
||||
concurrent_foreign_key_name(:members, column_name)
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
6f0ce1b68310b3194aa7b6219d79570e8179d449f49d828800f90f70d9242f38
|
|
@ -0,0 +1 @@
|
|||
248aecf9fa53146f2c1f7771fd60adf720fa8c0d2bd33d71c6177b185e4248d1
|
|
@ -0,0 +1 @@
|
|||
499f7b3951c9792d2a8f204b72c474a42e8301b487fa9f68080dd5bb5db0c64c
|
|
@ -0,0 +1 @@
|
|||
b633df04851493d7d4b5d7da79ba3057f6f2c302e507b4f963596edf9cbfcb88
|
|
@ -0,0 +1 @@
|
|||
f5295b135cd395a59c7afc6a9d999201f9ea1174aab893d31ead398aa8c0f8bb
|
|
@ -17354,7 +17354,8 @@ CREATE TABLE members (
|
|||
state smallint DEFAULT 0,
|
||||
invite_email_success boolean DEFAULT true NOT NULL,
|
||||
member_namespace_id bigint,
|
||||
member_role_id bigint
|
||||
member_role_id bigint,
|
||||
CONSTRAINT check_508774aac0 CHECK ((member_namespace_id IS NOT NULL))
|
||||
);
|
||||
|
||||
CREATE SEQUENCE members_id_seq
|
||||
|
@ -32623,7 +32624,7 @@ CREATE TRIGGER trigger_update_vulnerability_reads_on_vulnerability_update AFTER
|
|||
CREATE TRIGGER users_loose_fk_trigger AFTER DELETE ON users REFERENCING OLD TABLE AS old_table FOR EACH STATEMENT EXECUTE FUNCTION insert_into_loose_foreign_keys_deleted_records();
|
||||
|
||||
ALTER TABLE ONLY deployments
|
||||
ADD CONSTRAINT fk_009fd21147 FOREIGN KEY (environment_id) REFERENCES environments(id) ON DELETE CASCADE NOT VALID;
|
||||
ADD CONSTRAINT fk_009fd21147 FOREIGN KEY (environment_id) REFERENCES environments(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY epics
|
||||
ADD CONSTRAINT fk_013c9f36ca FOREIGN KEY (due_date_sourcing_epic_id) REFERENCES epics(id) ON DELETE SET NULL;
|
||||
|
@ -32797,7 +32798,7 @@ ALTER TABLE ONLY vulnerability_merge_request_links
|
|||
ADD CONSTRAINT fk_2ef3954596 FOREIGN KEY (vulnerability_id) REFERENCES vulnerabilities(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY members
|
||||
ADD CONSTRAINT fk_2f85abf8f1 FOREIGN KEY (member_namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE NOT VALID;
|
||||
ADD CONSTRAINT fk_2f85abf8f1 FOREIGN KEY (member_namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY analytics_cycle_analytics_group_stages
|
||||
ADD CONSTRAINT fk_3078345d6d FOREIGN KEY (stage_event_hash_id) REFERENCES analytics_cycle_analytics_stage_event_hashes(id) ON DELETE CASCADE;
|
||||
|
@ -33210,9 +33211,6 @@ ALTER TABLE ONLY epics
|
|||
ALTER TABLE ONLY dast_profiles
|
||||
ADD CONSTRAINT fk_aa76ef30e9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY members
|
||||
ADD CONSTRAINT fk_aa82dcc1c6 FOREIGN KEY (member_namespace_id) REFERENCES namespaces(id) ON DELETE SET NULL;
|
||||
|
||||
ALTER TABLE ONLY alert_management_alerts
|
||||
ADD CONSTRAINT fk_aad61aedca FOREIGN KEY (environment_id) REFERENCES environments(id) ON DELETE SET NULL;
|
||||
|
||||
|
|
|
@ -128,9 +128,7 @@ These additional CI/CD minutes:
|
|||
- Are carried over to the next month, if any remain at the end of the month.
|
||||
- Are valid for 12 months from date of purchase or until all minutes are consumed, whichever comes first. Expiry of minutes is not currently enforced.
|
||||
|
||||
If you use more CI/CD minutes than your monthly quota, when you purchase more,
|
||||
those CI/CD minutes are deducted from your quota. For example, with a GitLab SaaS
|
||||
Premium license:
|
||||
For example, with a GitLab SaaS Premium license:
|
||||
|
||||
- You have `10,000` monthly minutes.
|
||||
- You purchase an additional `5,000` minutes.
|
||||
|
@ -271,9 +269,9 @@ the next month.
|
|||
|
||||
For example:
|
||||
|
||||
- On **1st April**, you purchase `5,000` CI/CD minutes.
|
||||
- During April, you use only `3,000` of the `5,000` minutes.
|
||||
- On **1st May**, the remaining `2,000` minutes roll over and are added to your monthly quota.
|
||||
- On **1st April**, you purchase `5,000` additional CI/CD minutes.
|
||||
- During April, you use only `3,000` of the `5,000` additional minutes.
|
||||
- On **1st May**, the unused minute roll over, so you have `2,000` additional minutes available for May.
|
||||
|
||||
Additional CI/CD minutes are a one-time purchase and do not renew or refresh each month.
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@ for your GitLab instance). For example, <https://gitlab.com/public>.
|
|||
You can control the visibility of individual features with
|
||||
[project feature settings](permissions.md#project-features).
|
||||
|
||||
The visibility setting of a project must be the same as or less restrictive
|
||||
than the visibility of its parent group.
|
||||
The visibility setting of a project must be at least as restrictive
|
||||
as the visibility of its parent group.
|
||||
For example, a private group can include only private projects,
|
||||
while a public group can include private, internal, and public projects.
|
||||
|
||||
|
|
|
@ -14,16 +14,28 @@ module API
|
|||
end
|
||||
|
||||
namespace 'admin' do
|
||||
desc "Get list of all instance clusters" do
|
||||
detail "This feature was introduced in GitLab 13.2."
|
||||
desc 'List instance clusters' do
|
||||
detail 'This feature was introduced in GitLab 13.2. Returns a list of instance clusters.'
|
||||
success Entities::Cluster
|
||||
failure [
|
||||
{ code: 403, message: 'Forbidden' }
|
||||
]
|
||||
is_array true
|
||||
tags %w[clusters]
|
||||
end
|
||||
get '/clusters' do
|
||||
authorize! :read_cluster, clusterable_instance
|
||||
present paginate(clusters_for_current_user), with: Entities::Cluster
|
||||
end
|
||||
|
||||
desc "Get a single instance cluster" do
|
||||
detail "This feature was introduced in GitLab 13.2."
|
||||
desc 'Get a single instance cluster' do
|
||||
detail 'This feature was introduced in GitLab 13.2. Returns a single instance cluster.'
|
||||
success Entities::Cluster
|
||||
failure [
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[clusters]
|
||||
end
|
||||
params do
|
||||
requires :cluster_id, type: Integer, desc: "The cluster ID"
|
||||
|
@ -34,8 +46,15 @@ module API
|
|||
present cluster, with: Entities::Cluster
|
||||
end
|
||||
|
||||
desc "Add an instance cluster" do
|
||||
detail "This feature was introduced in GitLab 13.2."
|
||||
desc 'Add existing instance cluster' do
|
||||
detail 'This feature was introduced in GitLab 13.2. Adds an existing Kubernetes instance cluster.'
|
||||
success Entities::Cluster
|
||||
failure [
|
||||
{ code: 400, message: 'Validation error' },
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[clusters]
|
||||
end
|
||||
params do
|
||||
requires :name, type: String, desc: 'Cluster name'
|
||||
|
@ -67,8 +86,15 @@ module API
|
|||
end
|
||||
end
|
||||
|
||||
desc "Update an instance cluster" do
|
||||
detail "This feature was introduced in GitLab 13.2."
|
||||
desc 'Edit instance cluster' do
|
||||
detail 'This feature was introduced in GitLab 13.2. Updates an existing instance cluster.'
|
||||
success Entities::Cluster
|
||||
failure [
|
||||
{ code: 400, message: 'Validation error' },
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[clusters]
|
||||
end
|
||||
params do
|
||||
requires :cluster_id, type: Integer, desc: 'The cluster ID'
|
||||
|
@ -98,8 +124,14 @@ module API
|
|||
end
|
||||
end
|
||||
|
||||
desc "Remove a cluster" do
|
||||
detail "This feature was introduced in GitLab 13.2."
|
||||
desc 'Delete instance cluster' do
|
||||
detail 'This feature was introduced in GitLab 13.2. Deletes an existing instance cluster. Does not remove existing resources within the connected Kubernetes cluster.'
|
||||
success Entities::Cluster
|
||||
failure [
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[clusters]
|
||||
end
|
||||
params do
|
||||
requires :cluster_id, type: Integer, desc: "The cluster ID"
|
||||
|
|
|
@ -172,6 +172,7 @@ module API
|
|||
# Keep in alphabetical order
|
||||
mount ::API::AccessRequests
|
||||
mount ::API::Admin::Ci::Variables
|
||||
mount ::API::Admin::InstanceClusters
|
||||
mount ::API::Appearance
|
||||
mount ::API::Applications
|
||||
mount ::API::BroadcastMessages
|
||||
|
@ -179,6 +180,7 @@ module API
|
|||
mount ::API::Ci::ResourceGroups
|
||||
mount ::API::Ci::Runner
|
||||
mount ::API::Ci::Runners
|
||||
mount ::API::Ci::Variables
|
||||
mount ::API::Clusters::AgentTokens
|
||||
mount ::API::Clusters::Agents
|
||||
mount ::API::Commits
|
||||
|
@ -191,6 +193,7 @@ module API
|
|||
mount ::API::FeatureFlagsUserLists
|
||||
mount ::API::Features
|
||||
mount ::API::FreezePeriods
|
||||
mount ::API::GroupClusters
|
||||
mount ::API::GroupExport
|
||||
mount ::API::ImportBitbucketServer
|
||||
mount ::API::ImportGithub
|
||||
|
@ -200,15 +203,18 @@ module API
|
|||
mount ::API::Metadata
|
||||
mount ::API::PersonalAccessTokens::SelfInformation
|
||||
mount ::API::PersonalAccessTokens
|
||||
mount ::API::ProjectClusters
|
||||
mount ::API::ProjectExport
|
||||
mount ::API::ProjectHooks
|
||||
mount ::API::ProjectRepositoryStorageMoves
|
||||
mount ::API::ProjectSnippets
|
||||
mount ::API::ProjectSnapshots
|
||||
mount ::API::ProjectTemplates
|
||||
mount ::API::ProtectedBranches
|
||||
mount ::API::ProtectedTags
|
||||
mount ::API::Releases
|
||||
mount ::API::Release::Links
|
||||
mount ::API::RemoteMirrors
|
||||
mount ::API::Repositories
|
||||
mount ::API::ResourceAccessTokens
|
||||
mount ::API::Snippets
|
||||
|
@ -226,7 +232,6 @@ module API
|
|||
|
||||
# Keep in alphabetical order
|
||||
mount ::API::Admin::BatchedBackgroundMigrations
|
||||
mount ::API::Admin::InstanceClusters
|
||||
mount ::API::Admin::PlanLimits
|
||||
mount ::API::Admin::Sidekiq
|
||||
mount ::API::AlertManagementAlerts
|
||||
|
@ -241,7 +246,6 @@ module API
|
|||
mount ::API::Ci::Pipelines
|
||||
mount ::API::Ci::SecureFiles
|
||||
mount ::API::Ci::Triggers
|
||||
mount ::API::Ci::Variables
|
||||
mount ::API::CommitStatuses
|
||||
mount ::API::ComposerPackages
|
||||
mount ::API::ConanInstancePackages
|
||||
|
@ -262,7 +266,6 @@ module API
|
|||
mount ::API::GoProxy
|
||||
mount ::API::GroupAvatar
|
||||
mount ::API::GroupBoards
|
||||
mount ::API::GroupClusters
|
||||
mount ::API::GroupContainerRepositories
|
||||
mount ::API::GroupDebianDistributions
|
||||
mount ::API::GroupImport
|
||||
|
@ -295,7 +298,6 @@ module API
|
|||
mount ::API::PackageFiles
|
||||
mount ::API::Pages
|
||||
mount ::API::PagesDomains
|
||||
mount ::API::ProjectClusters
|
||||
mount ::API::ProjectContainerRepositories
|
||||
mount ::API::ProjectDebianDistributions
|
||||
mount ::API::ProjectEvents
|
||||
|
@ -303,11 +305,9 @@ module API
|
|||
mount ::API::ProjectMilestones
|
||||
mount ::API::ProjectPackages
|
||||
mount ::API::ProjectStatistics
|
||||
mount ::API::ProjectTemplates
|
||||
mount ::API::Projects
|
||||
mount ::API::ProtectedTags
|
||||
mount ::API::PypiPackages
|
||||
mount ::API::RemoteMirrors
|
||||
mount ::API::ResourceLabelEvents
|
||||
mount ::API::ResourceMilestoneEvents
|
||||
mount ::API::ResourceStateEvents
|
||||
|
|
|
@ -13,12 +13,13 @@ module API
|
|||
helpers ::API::Helpers::VariablesHelpers
|
||||
|
||||
params do
|
||||
requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
|
||||
requires :id, types: [String, Integer], desc: 'The ID of a project or URL-encoded NAMESPACE/PROJECT_NAME of the project owned by the authenticated user'
|
||||
end
|
||||
|
||||
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
|
||||
desc 'Get project variables' do
|
||||
success Entities::Ci::Variable
|
||||
tags %w[ci_variables]
|
||||
end
|
||||
params do
|
||||
use :pagination
|
||||
|
@ -28,13 +29,15 @@ module API
|
|||
present paginate(variables), with: Entities::Ci::Variable
|
||||
end
|
||||
|
||||
desc 'Get a specific variable from a project' do
|
||||
desc 'Get the details of a single variable from a project' do
|
||||
success Entities::Ci::Variable
|
||||
failure [{ code: 404, message: 'Variable Not Found' }]
|
||||
tags %w[ci_variables]
|
||||
end
|
||||
params do
|
||||
requires :key, type: String, desc: 'The key of the variable'
|
||||
requires :key, type: String, desc: 'The key of a variable'
|
||||
optional :filter, type: Hash, desc: 'Available filters: [environment_scope]. Example: filter[environment_scope]=production' do
|
||||
optional :environment_scope, type: String, desc: 'The environment scope of the variable'
|
||||
optional :environment_scope, type: String, desc: 'The environment scope of a variable'
|
||||
end
|
||||
end
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
|
@ -48,15 +51,17 @@ module API
|
|||
|
||||
desc 'Create a new variable in a project' do
|
||||
success Entities::Ci::Variable
|
||||
failure [{ code: 400, message: '400 Bad Request' }]
|
||||
tags %w[ci_variables]
|
||||
end
|
||||
route_setting :log_safety, { safe: %w[key], unsafe: %w[value] }
|
||||
params do
|
||||
requires :key, type: String, desc: 'The key of the variable'
|
||||
requires :value, type: String, desc: 'The value of the variable'
|
||||
requires :key, type: String, desc: 'The key of a variable'
|
||||
requires :value, type: String, desc: 'The value of a variable'
|
||||
optional :protected, type: Boolean, desc: 'Whether the variable is protected'
|
||||
optional :masked, type: Boolean, desc: 'Whether the variable is masked'
|
||||
optional :raw, type: Boolean, desc: 'Whether the variable will be expanded'
|
||||
optional :variable_type, type: String, values: ::Ci::Variable.variable_types.keys, desc: 'The type of variable, must be one of env_var or file. Defaults to env_var'
|
||||
optional :variable_type, type: String, values: ::Ci::Variable.variable_types.keys, desc: 'The type of the variable. Default: env_var'
|
||||
optional :environment_scope, type: String, desc: 'The environment_scope of the variable'
|
||||
end
|
||||
post ':id/variables' do
|
||||
|
@ -75,18 +80,20 @@ module API
|
|||
|
||||
desc 'Update an existing variable from a project' do
|
||||
success Entities::Ci::Variable
|
||||
failure [{ code: 404, message: 'Variable Not Found' }]
|
||||
tags %w[ci_variables]
|
||||
end
|
||||
route_setting :log_safety, { safe: %w[key], unsafe: %w[value] }
|
||||
params do
|
||||
optional :key, type: String, desc: 'The key of the variable'
|
||||
optional :value, type: String, desc: 'The value of the variable'
|
||||
optional :key, type: String, desc: 'The key of a variable'
|
||||
optional :value, type: String, desc: 'The value of a variable'
|
||||
optional :protected, type: Boolean, desc: 'Whether the variable is protected'
|
||||
optional :masked, type: Boolean, desc: 'Whether the variable is masked'
|
||||
optional :environment_scope, type: String, desc: 'The environment_scope of a variable'
|
||||
optional :raw, type: Boolean, desc: 'Whether the variable will be expanded'
|
||||
optional :variable_type, type: String, values: ::Ci::Variable.variable_types.keys, desc: 'The type of variable, must be one of env_var or file'
|
||||
optional :environment_scope, type: String, desc: 'The environment_scope of the variable'
|
||||
optional :variable_type, type: String, values: ::Ci::Variable.variable_types.keys, desc: 'The type of the variable. Default: env_var'
|
||||
optional :filter, type: Hash, desc: 'Available filters: [environment_scope]. Example: filter[environment_scope]=production' do
|
||||
optional :environment_scope, type: String, desc: 'The environment scope of the variable'
|
||||
optional :environment_scope, type: String, desc: 'The environment scope of a variable'
|
||||
end
|
||||
end
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
|
@ -110,9 +117,11 @@ module API
|
|||
|
||||
desc 'Delete an existing variable from a project' do
|
||||
success Entities::Ci::Variable
|
||||
failure [{ code: 404, message: 'Variable Not Found' }]
|
||||
tags %w[ci_variables]
|
||||
end
|
||||
params do
|
||||
requires :key, type: String, desc: 'The key of the variable'
|
||||
requires :key, type: String, desc: 'The key of a variable'
|
||||
optional :filter, type: Hash, desc: 'Available filters: [environment_scope]. Example: filter[environment_scope]=production' do
|
||||
optional :environment_scope, type: String, desc: 'The environment scope of the variable'
|
||||
end
|
||||
|
|
|
@ -4,12 +4,25 @@ module API
|
|||
module Entities
|
||||
# Serializes a Licensee::License
|
||||
class License < Entities::LicenseBasic
|
||||
expose :popular?, as: :popular
|
||||
expose(:description) { |license| license.meta['description'] }
|
||||
expose(:conditions) { |license| license.meta['conditions'] }
|
||||
expose(:permissions) { |license| license.meta['permissions'] }
|
||||
expose(:limitations) { |license| license.meta['limitations'] }
|
||||
expose :content
|
||||
expose :popular?, as: :popular, documentation: { type: 'boolean' }
|
||||
|
||||
expose :description, documentation: { type: 'string', example: 'A simple license' } do |license|
|
||||
license.meta['description']
|
||||
end
|
||||
|
||||
expose :conditions, documentation: { type: 'string', is_array: true, example: 'include-copyright' } do |license|
|
||||
license.meta['conditions']
|
||||
end
|
||||
|
||||
expose :permissions, documentation: { type: 'string', is_array: true, example: 'commercial-use' } do |license|
|
||||
license.meta['permissions']
|
||||
end
|
||||
|
||||
expose :limitations, documentation: { type: 'string', is_array: true, example: 'liability' } do |license|
|
||||
license.meta['limitations']
|
||||
end
|
||||
|
||||
expose :content, documentation: { type: 'string', example: 'GNU GENERAL PUBLIC LICENSE' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,8 +4,10 @@ module API
|
|||
module Entities
|
||||
# Serializes a Gitlab::Git::DeclaredLicense
|
||||
class LicenseBasic < Grape::Entity
|
||||
expose :key, :name, :nickname
|
||||
expose :url, as: :html_url
|
||||
expose :key, documentation: { type: 'string', example: 'gpl-3.0' }
|
||||
expose :name, documentation: { type: 'string', example: 'GNU General Public License v3.0' }
|
||||
expose :nickname, documentation: { type: 'string', example: 'GNU GPLv3' }
|
||||
expose :url, as: :html_url, documentation: { example: 'http://choosealicense.com/licenses/gpl-3.0' }
|
||||
|
||||
# This was dropped:
|
||||
# https://github.com/github/choosealicense.com/commit/325806b42aa3d5b78e84120327ec877bc936dbdd#diff-66df8f1997786f7052d29010f2cbb4c66391d60d24ca624c356acc0ab986f139
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
module API
|
||||
module Entities
|
||||
class RemoteMirror < Grape::Entity
|
||||
expose :id
|
||||
expose :enabled
|
||||
expose :safe_url, as: :url
|
||||
expose :update_status
|
||||
expose :last_update_at
|
||||
expose :last_update_started_at
|
||||
expose :last_successful_update_at
|
||||
expose :last_error
|
||||
expose :only_protected_branches
|
||||
expose :keep_divergent_refs
|
||||
expose :id, documentation: { type: 'integer', example: 101486 }
|
||||
expose :enabled, documentation: { type: 'boolean', example: true }
|
||||
expose :safe_url, as: :url, documentation: { type: 'string', example: 'https://*****:*****@example.com/gitlab/example.git' }
|
||||
expose :update_status, documentation: { type: 'string', example: 'finished' }
|
||||
expose :last_update_at, documentation: { type: 'dateTime', example: '2020-01-06T17:32:02.823Z' }
|
||||
expose :last_update_started_at, documentation: { type: 'dateTime', example: '2020-01-06T17:32:02.823Z' }
|
||||
expose :last_successful_update_at, documentation: { type: 'dateTime', example: '2020-01-06T17:31:55.864Z' }
|
||||
expose :last_error, documentation: { type: 'integer', example: 'The remote mirror URL is invalid.' }
|
||||
expose :only_protected_branches, documentation: { type: 'boolean' }
|
||||
expose :keep_divergent_refs, documentation: { type: 'boolean' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
module API
|
||||
module Entities
|
||||
class TemplatesList < Grape::Entity
|
||||
expose :key
|
||||
expose :name
|
||||
expose :key, documentation: { type: 'string', example: 'mit' }
|
||||
expose :name, documentation: { type: 'string', example: 'MIT License' }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,8 +16,14 @@ module API
|
|||
requires :id, type: String, desc: 'The ID of the group'
|
||||
end
|
||||
resource :groups, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
|
||||
desc 'Get all clusters from the group' do
|
||||
desc 'List group clusters' do
|
||||
detail 'This feature was introduced in GitLab 12.1. Returns a list of group clusters.'
|
||||
success Entities::Cluster
|
||||
failure [
|
||||
{ code: 403, message: 'Forbidden' }
|
||||
]
|
||||
is_array true
|
||||
tags %w[clusters]
|
||||
end
|
||||
params do
|
||||
use :pagination
|
||||
|
@ -28,8 +34,14 @@ module API
|
|||
present paginate(clusters_for_current_user), with: Entities::Cluster
|
||||
end
|
||||
|
||||
desc 'Get specific cluster for the group' do
|
||||
desc 'Get a single group cluster' do
|
||||
detail 'This feature was introduced in GitLab 12.1. Gets a single group cluster.'
|
||||
success Entities::ClusterGroup
|
||||
failure [
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[clusters]
|
||||
end
|
||||
params do
|
||||
requires :cluster_id, type: Integer, desc: 'The cluster ID'
|
||||
|
@ -40,8 +52,15 @@ module API
|
|||
present cluster, with: Entities::ClusterGroup
|
||||
end
|
||||
|
||||
desc 'Adds an existing cluster' do
|
||||
desc 'Add existing cluster to group' do
|
||||
detail 'This feature was introduced in GitLab 12.1. Adds an existing Kubernetes cluster to the group.'
|
||||
success Entities::ClusterGroup
|
||||
failure [
|
||||
{ code: 400, message: 'Validation error' },
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[clusters]
|
||||
end
|
||||
params do
|
||||
requires :name, type: String, desc: 'Cluster name'
|
||||
|
@ -73,8 +92,15 @@ module API
|
|||
end
|
||||
end
|
||||
|
||||
desc 'Update an existing cluster' do
|
||||
desc 'Edit group cluster' do
|
||||
detail 'This feature was introduced in GitLab 12.1. Updates an existing group cluster.'
|
||||
success Entities::ClusterGroup
|
||||
failure [
|
||||
{ code: 400, message: 'Validation error' },
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[clusters]
|
||||
end
|
||||
params do
|
||||
requires :cluster_id, type: Integer, desc: 'The cluster ID'
|
||||
|
@ -104,8 +130,14 @@ module API
|
|||
end
|
||||
end
|
||||
|
||||
desc 'Remove a cluster' do
|
||||
desc 'Delete group cluster' do
|
||||
detail 'This feature was introduced in GitLab 12.1. Deletes an existing group cluster. Does not remove existing resources within the connected Kubernetes cluster.'
|
||||
success Entities::ClusterGroup
|
||||
failure [
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[clusters]
|
||||
end
|
||||
params do
|
||||
requires :cluster_id, type: Integer, desc: 'The Cluster ID'
|
||||
|
|
|
@ -17,8 +17,9 @@ module API
|
|||
included do
|
||||
helpers do
|
||||
params :pagination do
|
||||
optional :page, type: Integer, default: 1, desc: 'Current page number'
|
||||
optional :per_page, type: Integer, default: 20, desc: 'Number of items per page', except_values: [0]
|
||||
optional :page, type: Integer, default: 1, desc: 'Current page number', documentation: { example: 1 }
|
||||
optional :per_page, type: Integer, default: 20,
|
||||
desc: 'Number of items per page', except_values: [0], documentation: { example: 20 }
|
||||
end
|
||||
|
||||
def verify_pagination_params!
|
||||
|
|
|
@ -16,9 +16,14 @@ module API
|
|||
requires :id, types: [String, Integer], desc: 'The ID or URL-encoded path of the project'
|
||||
end
|
||||
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
|
||||
desc 'Get all clusters from the project' do
|
||||
detail 'This feature was introduced in GitLab 11.7.'
|
||||
desc 'List project clusters' do
|
||||
detail 'This feature was introduced in GitLab 11.7. Returns a list of project clusters.'
|
||||
success Entities::Cluster
|
||||
failure [
|
||||
{ code: 403, message: 'Forbidden' }
|
||||
]
|
||||
is_array true
|
||||
tags %w[clusters]
|
||||
end
|
||||
params do
|
||||
use :pagination
|
||||
|
@ -29,9 +34,14 @@ module API
|
|||
present paginate(clusters_for_current_user), with: Entities::Cluster
|
||||
end
|
||||
|
||||
desc 'Get specific cluster for the project' do
|
||||
detail 'This feature was introduced in GitLab 11.7.'
|
||||
desc 'Get a single project cluster' do
|
||||
detail 'This feature was introduced in GitLab 11.7. Gets a single project cluster.'
|
||||
success Entities::ClusterProject
|
||||
failure [
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[clusters]
|
||||
end
|
||||
params do
|
||||
requires :cluster_id, type: Integer, desc: 'The cluster ID'
|
||||
|
@ -42,9 +52,15 @@ module API
|
|||
present cluster, with: Entities::ClusterProject
|
||||
end
|
||||
|
||||
desc 'Adds an existing cluster' do
|
||||
detail 'This feature was introduced in GitLab 11.7.'
|
||||
desc 'Add existing cluster to project' do
|
||||
detail 'This feature was introduced in GitLab 11.7. Adds an existing Kubernetes cluster to the project.'
|
||||
success Entities::ClusterProject
|
||||
failure [
|
||||
{ code: 400, message: 'Validation error' },
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[clusters]
|
||||
end
|
||||
params do
|
||||
requires :name, type: String, desc: 'Cluster name'
|
||||
|
@ -76,9 +92,15 @@ module API
|
|||
end
|
||||
end
|
||||
|
||||
desc 'Update an existing cluster' do
|
||||
detail 'This feature was introduced in GitLab 11.7.'
|
||||
desc 'Edit project cluster' do
|
||||
detail 'This feature was introduced in GitLab 11.7. Updates an existing project cluster.'
|
||||
success Entities::ClusterProject
|
||||
failure [
|
||||
{ code: 400, message: 'Validation error' },
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[clusters]
|
||||
end
|
||||
params do
|
||||
requires :cluster_id, type: Integer, desc: 'The cluster ID'
|
||||
|
@ -108,9 +130,14 @@ module API
|
|||
end
|
||||
end
|
||||
|
||||
desc 'Remove a cluster' do
|
||||
detail 'This feature was introduced in GitLab 11.7.'
|
||||
desc 'Delete project cluster' do
|
||||
detail 'This feature was introduced in GitLab 11.7. Deletes an existing project cluster. Does not remove existing resources within the connected Kubernetes cluster.'
|
||||
success Entities::ClusterProject
|
||||
failure [
|
||||
{ code: 403, message: 'Forbidden' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[clusters]
|
||||
end
|
||||
params do
|
||||
requires :cluster_id, type: Integer, desc: 'The Cluster ID'
|
||||
|
|
|
@ -21,6 +21,12 @@ module API
|
|||
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
|
||||
desc 'Get a list of templates available to this project' do
|
||||
detail 'This endpoint was introduced in GitLab 11.4'
|
||||
is_array true
|
||||
success Entities::TemplatesList
|
||||
failure [
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
end
|
||||
params do
|
||||
use :pagination
|
||||
|
@ -33,13 +39,24 @@ module API
|
|||
|
||||
desc 'Download a template available to this project' do
|
||||
detail 'This endpoint was introduced in GitLab 11.4'
|
||||
success Entities::License
|
||||
failure [
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
end
|
||||
params do
|
||||
requires :name, type: String, desc: 'The name of the template'
|
||||
requires :name, type: String,
|
||||
desc: 'The key of the template, as obtained from the collection endpoint.', documentation: { example: 'MIT' }
|
||||
optional :source_template_project_id, type: Integer,
|
||||
desc: 'The project id where a given template is being stored. This is useful when multiple templates from different projects have the same name'
|
||||
optional :project, type: String, desc: 'The project name to use when expanding placeholders in the template. Only affects licenses'
|
||||
optional :fullname, type: String, desc: 'The full name of the copyright holder to use when expanding placeholders in the template. Only affects licenses'
|
||||
desc: 'The project id where a given template is being stored. This is useful when multiple templates from different projects have the same name',
|
||||
documentation: { example: 1 }
|
||||
optional :project, type: String,
|
||||
desc: 'The project name to use when expanding placeholders in the template. Only affects licenses',
|
||||
documentation: { example: 'GitLab' }
|
||||
optional :fullname, type: String,
|
||||
desc: 'The full name of the copyright holder to use when expanding placeholders in the template. Only affects licenses',
|
||||
documentation: { example: 'GitLab B.V.' }
|
||||
end
|
||||
|
||||
get ':id/templates/:type/:name', requirements: TEMPLATE_NAMES_ENDPOINT_REQUIREMENTS do
|
||||
|
|
|
@ -15,7 +15,13 @@ module API
|
|||
end
|
||||
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
|
||||
desc "List the project's remote mirrors" do
|
||||
success Entities::RemoteMirror
|
||||
success code: 200, model: Entities::RemoteMirror
|
||||
is_array true
|
||||
failure [
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[remote_mirrors]
|
||||
end
|
||||
params do
|
||||
use :pagination
|
||||
|
@ -26,7 +32,12 @@ module API
|
|||
end
|
||||
|
||||
desc 'Get a single remote mirror' do
|
||||
success Entities::RemoteMirror
|
||||
success code: 200, model: Entities::RemoteMirror
|
||||
failure [
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[remote_mirrors]
|
||||
end
|
||||
params do
|
||||
requires :mirror_id, type: String, desc: 'The ID of a remote mirror'
|
||||
|
@ -38,13 +49,21 @@ module API
|
|||
end
|
||||
|
||||
desc 'Create remote mirror for a project' do
|
||||
success Entities::RemoteMirror
|
||||
success code: 201, model: Entities::RemoteMirror
|
||||
failure [
|
||||
{ code: 400, message: 'Bad request' },
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[remote_mirrors]
|
||||
end
|
||||
params do
|
||||
requires :url, type: String, desc: 'The URL for a remote mirror'
|
||||
optional :enabled, type: Boolean, desc: 'Determines if the mirror is enabled'
|
||||
optional :only_protected_branches, type: Boolean, desc: 'Determines if only protected branches are mirrored'
|
||||
optional :keep_divergent_refs, type: Boolean, desc: 'Determines if divergent refs are kept on the target'
|
||||
requires :url, type: String, desc: 'The URL for a remote mirror', documentation: { example: 'https://*****:*****@example.com/gitlab/example.git' }
|
||||
optional :enabled, type: Boolean, desc: 'Determines if the mirror is enabled', documentation: { example: false }
|
||||
optional :only_protected_branches, type: Boolean, desc: 'Determines if only protected branches are mirrored',
|
||||
documentation: { example: false }
|
||||
optional :keep_divergent_refs, type: Boolean, desc: 'Determines if divergent refs are kept on the target',
|
||||
documentation: { example: false }
|
||||
end
|
||||
post ':id/remote_mirrors' do
|
||||
create_params = declared_params(include_missing: false)
|
||||
|
@ -59,13 +78,21 @@ module API
|
|||
end
|
||||
|
||||
desc 'Update the attributes of a single remote mirror' do
|
||||
success Entities::RemoteMirror
|
||||
success code: 200, model: Entities::RemoteMirror
|
||||
failure [
|
||||
{ code: 400, message: 'Bad request' },
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[remote_mirrors]
|
||||
end
|
||||
params do
|
||||
requires :mirror_id, type: String, desc: 'The ID of a remote mirror'
|
||||
optional :enabled, type: Boolean, desc: 'Determines if the mirror is enabled'
|
||||
optional :only_protected_branches, type: Boolean, desc: 'Determines if only protected branches are mirrored'
|
||||
optional :keep_divergent_refs, type: Boolean, desc: 'Determines if divergent refs are kept on the target'
|
||||
optional :enabled, type: Boolean, desc: 'Determines if the mirror is enabled', documentation: { example: true }
|
||||
optional :only_protected_branches, type: Boolean, desc: 'Determines if only protected branches are mirrored',
|
||||
documentation: { example: false }
|
||||
optional :keep_divergent_refs, type: Boolean, desc: 'Determines if divergent refs are kept on the target',
|
||||
documentation: { example: false }
|
||||
end
|
||||
put ':id/remote_mirrors/:mirror_id' do
|
||||
mirror = user_project.remote_mirrors.find(params[:mirror_id])
|
||||
|
@ -88,6 +115,13 @@ module API
|
|||
|
||||
desc 'Delete a single remote mirror' do
|
||||
detail 'This feature was introduced in GitLab 14.10'
|
||||
success code: 204
|
||||
failure [
|
||||
{ code: 400, message: 'Bad request' },
|
||||
{ code: 401, message: 'Unauthorized' },
|
||||
{ code: 404, message: 'Not found' }
|
||||
]
|
||||
tags %w[remote_mirrors]
|
||||
end
|
||||
params do
|
||||
requires :mirror_id, type: String, desc: 'The ID of a remote mirror'
|
||||
|
|
|
@ -433,16 +433,16 @@ module API
|
|||
success Entities::SSHKey
|
||||
end
|
||||
params do
|
||||
requires :id, type: Integer, desc: 'The ID of the user'
|
||||
requires :user_id, type: Integer, desc: 'The ID of the user'
|
||||
requires :key, type: String, desc: 'The new SSH key'
|
||||
requires :title, type: String, desc: 'The title of the new SSH key'
|
||||
optional :expires_at, type: DateTime, desc: 'The expiration date of the SSH key in ISO 8601 format (YYYY-MM-DDTHH:MM:SSZ)'
|
||||
end
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
post ":id/keys", feature_category: :authentication_and_authorization do
|
||||
post ":user_id/keys", feature_category: :authentication_and_authorization do
|
||||
authenticated_as_admin!
|
||||
|
||||
user = User.find_by(id: params.delete(:id))
|
||||
user = User.find_by(id: params.delete(:user_id))
|
||||
not_found!('User') unless user
|
||||
|
||||
key = ::Keys::CreateService.new(current_user, declared_params(include_missing: false).merge(user: user)).execute
|
||||
|
|
|
@ -209,6 +209,12 @@ module Gitlab
|
|||
'in the body of your migration class'
|
||||
end
|
||||
|
||||
if partition?(table_name)
|
||||
raise ArgumentError, 'remove_concurrent_index can not be used on a partitioned ' \
|
||||
'table. Please use remove_concurrent_partitioned_index_by_name on the partitioned table ' \
|
||||
'as we need to remove the index on the parent table'
|
||||
end
|
||||
|
||||
options = options.merge({ algorithm: :concurrently })
|
||||
|
||||
unless index_exists?(table_name, column_name, **options)
|
||||
|
@ -238,6 +244,12 @@ module Gitlab
|
|||
'in the body of your migration class'
|
||||
end
|
||||
|
||||
if partition?(table_name)
|
||||
raise ArgumentError, 'remove_concurrent_index_by_name can not be used on a partitioned ' \
|
||||
'table. Please use remove_concurrent_partitioned_index_by_name on the partitioned table ' \
|
||||
'as we need to remove the index on the parent table'
|
||||
end
|
||||
|
||||
index_name = index_name[:name] if index_name.is_a?(Hash)
|
||||
|
||||
raise 'remove_concurrent_index_by_name must get an index name as the second argument' if index_name.blank?
|
||||
|
|
|
@ -10,13 +10,17 @@ module Gitlab::UsageDataCounters
|
|||
expanded_template_name = expand_template_name(template)
|
||||
return unless expanded_template_name
|
||||
|
||||
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(
|
||||
ci_template_event_name(expanded_template_name, config_source), values: project.id
|
||||
)
|
||||
event_name = ci_template_event_name(expanded_template_name, config_source)
|
||||
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(event_name, values: project.id)
|
||||
|
||||
namespace = project.namespace
|
||||
if Feature.enabled?(:route_hll_to_snowplow, namespace)
|
||||
Gitlab::Tracking.event(name, 'ci_templates_unique', namespace: namespace, user: user, project: project)
|
||||
context = Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll,
|
||||
event: event_name).to_context
|
||||
label = 'redis_hll_counters.ci_templates.ci_templates_total_unique_counts_monthly'
|
||||
Gitlab::Tracking.event(name, 'ci_templates_unique', namespace: namespace,
|
||||
project: project, context: [context], user: user,
|
||||
label: label)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ source 'https://rubygems.org'
|
|||
|
||||
gem 'gitlab-qa', '~> 8', '>= 8.10.1', require: 'gitlab/qa'
|
||||
gem 'activesupport', '~> 6.1.4.7' # This should stay in sync with the root's Gemfile
|
||||
gem 'allure-rspec', '~> 2.18.0'
|
||||
gem 'allure-rspec', '~> 2.19.0'
|
||||
gem 'capybara', '~> 3.38.0'
|
||||
gem 'capybara-screenshot', '~> 1.0.26'
|
||||
gem 'rake', '~> 13', '>= 13.0.6'
|
||||
|
|
|
@ -15,10 +15,10 @@ GEM
|
|||
rack-test (>= 1.1.0, < 2.0)
|
||||
rest-client (>= 2.0.2, < 3.0)
|
||||
rspec (~> 3.8)
|
||||
allure-rspec (2.18.0)
|
||||
allure-ruby-commons (= 2.18.0)
|
||||
allure-rspec (2.19.0)
|
||||
allure-ruby-commons (= 2.19.0)
|
||||
rspec-core (>= 3.8, < 4)
|
||||
allure-ruby-commons (2.18.0)
|
||||
allure-ruby-commons (2.19.0)
|
||||
mime-types (>= 3.3, < 4)
|
||||
oj (>= 3.10, < 4)
|
||||
require_all (>= 2, < 4)
|
||||
|
@ -184,7 +184,7 @@ GEM
|
|||
octokit (6.0.0)
|
||||
faraday (>= 1, < 3)
|
||||
sawyer (~> 0.9)
|
||||
oj (3.13.21)
|
||||
oj (3.13.23)
|
||||
os (1.1.4)
|
||||
parallel (1.22.1)
|
||||
parallel_tests (4.0.0)
|
||||
|
@ -301,7 +301,7 @@ PLATFORMS
|
|||
DEPENDENCIES
|
||||
activesupport (~> 6.1.4.7)
|
||||
airborne (~> 0.3.7)
|
||||
allure-rspec (~> 2.18.0)
|
||||
allure-rspec (~> 2.19.0)
|
||||
capybara (~> 3.38.0)
|
||||
capybara-screenshot (~> 1.0.26)
|
||||
chemlab (~> 0.10)
|
||||
|
@ -338,4 +338,4 @@ DEPENDENCIES
|
|||
zeitwerk (~> 2.4)
|
||||
|
||||
BUNDLED WITH
|
||||
2.3.24
|
||||
2.3.25
|
||||
|
|
|
@ -37,7 +37,9 @@ module QA
|
|||
Page::Main::Menu.perform(&:not_signed_in?)
|
||||
end
|
||||
|
||||
raise "Failed user registration attempt. Registration was expected to #{user.expect_fabrication_success ? 'succeed' : 'fail'} but #{success ? 'succeeded' : 'failed'}." unless success
|
||||
return if success
|
||||
|
||||
raise "Failed user registration attempt. Registration was expected to #{user.expect_fabrication_success ? 'succeed' : 'fail'} but #{success ? 'succeeded' : 'failed'}."
|
||||
end
|
||||
|
||||
def disable_sign_ups
|
||||
|
|
|
@ -28,6 +28,10 @@ module QA
|
|||
click_link(username)
|
||||
end
|
||||
end
|
||||
|
||||
def has_username?(username)
|
||||
has_element?(:user_row_content, text: username, wait: 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
module Page
|
||||
module Component
|
||||
module DeleteModal
|
||||
extend QA::Page::PageConcern
|
||||
|
||||
def self.included(base)
|
||||
super
|
||||
|
||||
base.view 'app/assets/javascripts/projects/components/shared/delete_button.vue' do
|
||||
element :confirm_name_field
|
||||
element :confirm_delete_button
|
||||
end
|
||||
end
|
||||
|
||||
def fill_confirmation_path(text)
|
||||
fill_element(:confirm_name_field, text)
|
||||
end
|
||||
|
||||
def wait_for_delete_button_enabled
|
||||
wait_until(reload: false) do
|
||||
!find_element(:confirm_delete_button).disabled?
|
||||
end
|
||||
end
|
||||
|
||||
def confirm_delete
|
||||
wait_for_delete_button_enabled
|
||||
click_element(:confirm_delete_button)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -16,6 +16,10 @@ module QA
|
|||
base.view 'app/assets/javascripts/groups/components/groups.vue' do
|
||||
element :groups_list_tree_container
|
||||
end
|
||||
|
||||
base.view 'app/views/dashboard/_groups_head.html.haml' do
|
||||
element :public_groups_tab
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -28,9 +32,24 @@ module QA
|
|||
# groups_list_tree_container means we have the complete filtered list
|
||||
# of groups
|
||||
has_element?(:groups_list_tree_container, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
|
||||
|
||||
# If there are no groups we'll know immediately because we filtered the list
|
||||
return false if page.has_text?('No groups or projects matched your search', wait: 0)
|
||||
if page.has_text?('No groups or projects matched your search',
|
||||
wait: 0) || page.has_text?('No groups matched your search', wait: 0)
|
||||
return false unless has_element?(:public_groups_tab)
|
||||
|
||||
# Try for public groups
|
||||
click_element(:public_groups_tab)
|
||||
# Filter and submit to reload the page and only retrieve the filtered results
|
||||
find_element(:groups_filter_field).set(name).send_keys(:return)
|
||||
|
||||
# Since we submitted after filtering, the presence of
|
||||
# groups_list_tree_container means we have the complete filtered list
|
||||
# of groups
|
||||
has_element?(:groups_list_tree_container, wait: QA::Support::Repeater::DEFAULT_MAX_WAIT_TIME)
|
||||
|
||||
return false if page.has_text?('No groups or projects matched your search',
|
||||
wait: 0) || page.has_text?('No groups matched your search', wait: 0)
|
||||
end
|
||||
|
||||
# The name will be present as filter input so we check for a link, not text
|
||||
page.has_link?(name, wait: 0)
|
||||
|
|
|
@ -31,7 +31,7 @@ module QA
|
|||
end
|
||||
|
||||
def create
|
||||
click_button 'Create group'
|
||||
click_element(:create_group_button)
|
||||
end
|
||||
|
||||
def create_subgroup
|
||||
|
|
|
@ -64,6 +64,8 @@ module QA
|
|||
end
|
||||
|
||||
def add_description(description)
|
||||
return unless has_element?(:project_description, wait: 1)
|
||||
|
||||
fill_in 'project_description', with: description
|
||||
end
|
||||
|
||||
|
|
|
@ -6,8 +6,13 @@ module QA
|
|||
module Settings
|
||||
class Advanced < Page::Base
|
||||
include QA::Page::Component::ConfirmModal
|
||||
include QA::Page::Component::DeleteModal
|
||||
include Component::NamespaceSelect
|
||||
|
||||
view 'app/assets/javascripts/projects/components/shared/delete_button.vue' do
|
||||
element :delete_button
|
||||
end
|
||||
|
||||
view 'app/views/projects/edit.html.haml' do
|
||||
element :project_path_field
|
||||
element :change_path_button
|
||||
|
@ -88,6 +93,13 @@ module QA
|
|||
click_confirmation_ok_button
|
||||
end
|
||||
|
||||
def delete_project!(project_name)
|
||||
click_element :delete_button
|
||||
fill_confirmation_path(project_name)
|
||||
wait_for_delete_button_enabled
|
||||
confirm_delete
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def wait_for_transfer_project_content
|
||||
|
|
|
@ -22,8 +22,20 @@ module QA
|
|||
new.tap(&prepare_block)
|
||||
end
|
||||
|
||||
def fabricate_via_api_unless_fips!
|
||||
if QA::Support::FIPS.enabled?
|
||||
fabricate!
|
||||
else
|
||||
fabricate_via_api!
|
||||
end
|
||||
end
|
||||
|
||||
def fabricate!(*args, &prepare_block)
|
||||
if QA::Support::FIPS.enabled?
|
||||
fabricate_via_browser_ui!(*args, &prepare_block)
|
||||
else
|
||||
fabricate_via_api!(*args, &prepare_block)
|
||||
end
|
||||
rescue NotImplementedError
|
||||
fabricate_via_browser_ui!(*args, &prepare_block)
|
||||
end
|
||||
|
@ -95,7 +107,7 @@ module QA
|
|||
|
||||
Support::FabricationTracker.save_fabrication(:"#{fabrication_method}_fabrication", fabrication_time)
|
||||
|
||||
unless resource.retrieved_from_cache
|
||||
unless resource.retrieved_from_cache || QA::Support::FIPS.enabled?
|
||||
Tools::TestResourceDataProcessor.collect(
|
||||
resource: resource,
|
||||
info: resource.identifier,
|
||||
|
|
|
@ -18,10 +18,16 @@ module QA
|
|||
end
|
||||
|
||||
attribute :sandbox do
|
||||
if QA::Support::FIPS.enabled?
|
||||
Resource::Sandbox.fabricate! do |sandbox|
|
||||
sandbox.path = Runtime::Namespace.sandbox_name
|
||||
end
|
||||
else
|
||||
Sandbox.fabricate_via_api! do |sandbox|
|
||||
sandbox.api_client = api_client
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def initialize
|
||||
@description = "QA test run at #{Runtime::Namespace.time}"
|
||||
|
|
|
@ -10,8 +10,8 @@ module QA
|
|||
def add_member(user, access_level = AccessLevel::DEVELOPER)
|
||||
Support::Retrier.retry_until do
|
||||
QA::Runtime::Logger.info(%(Adding user #{user.username} to #{full_path} #{self.class.name}))
|
||||
|
||||
response = post Runtime::API::Request.new(api_client, api_members_path).url, { user_id: user.id, access_level: access_level }
|
||||
response = post Runtime::API::Request.new(api_client, api_members_path).url,
|
||||
{ user_id: user.id, access_level: access_level }
|
||||
break true if response.code == QA::Support::API::HTTP_STATUS_CREATED
|
||||
break true if response.body.include?('Member already exists')
|
||||
end
|
||||
|
@ -31,7 +31,8 @@ module QA
|
|||
Support::Retrier.retry_until do
|
||||
QA::Runtime::Logger.info(%(Sharing #{self.class.name} with #{group.name}))
|
||||
|
||||
response = post Runtime::API::Request.new(api_client, api_share_path).url, { group_id: group.id, group_access: access_level }
|
||||
response = post Runtime::API::Request.new(api_client, api_share_path).url,
|
||||
{ group_id: group.id, group_access: access_level }
|
||||
response.code == QA::Support::API::HTTP_STATUS_CREATED
|
||||
end
|
||||
end
|
||||
|
|
|
@ -479,6 +479,16 @@ module QA
|
|||
end
|
||||
end
|
||||
|
||||
def remove_via_browser_ui!
|
||||
Page::Project::Menu.perform(&:go_to_general_settings)
|
||||
|
||||
Page::Project::Settings::Main.perform(&:expand_advanced_settings)
|
||||
|
||||
Page::Project::Settings::Advanced.perform do |advanced|
|
||||
advanced.delete_project!(full_path)
|
||||
end
|
||||
end
|
||||
|
||||
# Calls the API endpoint that triggers the backend service that performs repository housekeeping (garbage
|
||||
# collection and similar tasks).
|
||||
def perform_housekeeping
|
||||
|
|
|
@ -10,7 +10,9 @@ module QA
|
|||
class << self
|
||||
# Force top level group creation via UI if test is executed on dot_com environment
|
||||
def fabricate!(*args, &prepare_block)
|
||||
return fabricate_via_browser_ui!(*args, &prepare_block) if Specs::Helpers::ContextSelector.dot_com?
|
||||
if Specs::Helpers::ContextSelector.dot_com? || QA::Support::FIPS.enabled?
|
||||
return fabricate_via_browser_ui!(*args, &prepare_block)
|
||||
end
|
||||
|
||||
fabricate_via_api!(*args, &prepare_block)
|
||||
rescue NotImplementedError
|
||||
|
|
|
@ -79,11 +79,22 @@ module QA
|
|||
defined?(@username) && defined?(@password)
|
||||
end
|
||||
|
||||
def has_user?(user)
|
||||
Flow::Login.while_signed_in_as_admin do
|
||||
Page::Main::Menu.perform(&:go_to_admin_area)
|
||||
Page::Admin::Menu.perform(&:go_to_users_overview)
|
||||
Page::Admin::Overview::Users::Index.perform do |index|
|
||||
index.search_user(user.username)
|
||||
index.has_username?(user.username)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def fabricate!
|
||||
# Don't try to log-out if we're not logged-in
|
||||
Page::Main::Menu.perform(&:sign_out) if Page::Main::Menu.perform { |p| p.has_personal_area?(wait: 0) }
|
||||
|
||||
if credentials_given?
|
||||
if credentials_given? || has_user?(self)
|
||||
Page::Main::Login.perform do |login|
|
||||
login.sign_in_using_credentials(user: self)
|
||||
end
|
||||
|
@ -144,7 +155,7 @@ module QA
|
|||
end
|
||||
|
||||
def self.fabricate_or_use(username = nil, password = nil)
|
||||
if Runtime::Env.signup_disabled?
|
||||
if Runtime::Env.signup_disabled? || !QA::Support::FIPS.enabled?
|
||||
fabricate_via_api! do |user|
|
||||
user.username = username
|
||||
user.password = password
|
||||
|
|
|
@ -4,8 +4,8 @@ module QA
|
|||
module Runtime
|
||||
module Key
|
||||
class ED25519 < Base
|
||||
def initialize
|
||||
super('ed25519', 256)
|
||||
def initialize(bits = 256)
|
||||
super('ed25519', bits)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,8 +3,17 @@
|
|||
module QA
|
||||
RSpec.describe 'Plan', :smoke, product_group: :project_management do
|
||||
describe 'Issue creation' do
|
||||
let(:project) { Resource::Project.fabricate_via_api! }
|
||||
let(:closed_issue) { Resource::Issue.fabricate_via_api! { |issue| issue.project = project } }
|
||||
let(:project) do
|
||||
Resource::Project.fabricate_via_api_unless_fips! do |project|
|
||||
project.name = "project-create-issue-#{SecureRandom.hex(8)}"
|
||||
project.personal_namespace = Runtime::User.username
|
||||
project.description = nil
|
||||
end
|
||||
end
|
||||
|
||||
let(:closed_issue) do
|
||||
Resource::Issue.fabricate_via_api_unless_fips! { |issue| issue.project = project }
|
||||
end
|
||||
|
||||
before do
|
||||
Flow::Login.sign_in
|
||||
|
@ -55,7 +64,7 @@ module QA
|
|||
end
|
||||
|
||||
before do
|
||||
Resource::Issue.fabricate_via_api! { |issue| issue.project = project }.visit!
|
||||
Resource::Issue.fabricate_via_api_unless_fips! { |issue| issue.project = project }.visit!
|
||||
end
|
||||
|
||||
# The following example is excluded from running in `review-qa-smoke` job
|
||||
|
|
|
@ -3,9 +3,12 @@
|
|||
module QA
|
||||
RSpec.describe 'Plan', :smoke, product_group: :project_management do
|
||||
describe 'mention' do
|
||||
let(:user) { Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1) }
|
||||
let(:user) do
|
||||
Resource::User.fabricate_or_use(Runtime::Env.gitlab_qa_username_1, Runtime::Env.gitlab_qa_password_1)
|
||||
end
|
||||
|
||||
let(:project) do
|
||||
Resource::Project.fabricate_via_api! do |project|
|
||||
Resource::Project.fabricate_via_api_unless_fips! do |project|
|
||||
project.name = 'project-to-test-mention'
|
||||
project.visibility = 'private'
|
||||
end
|
||||
|
@ -14,14 +17,33 @@ module QA
|
|||
before do
|
||||
Flow::Login.sign_in
|
||||
|
||||
if QA::Support::FIPS.enabled?
|
||||
# Ensure user exists
|
||||
user
|
||||
Flow::Login.sign_in_as_admin
|
||||
project.visit!
|
||||
Page::Project::Menu.perform(&:click_members)
|
||||
Page::Project::Members.perform do |members|
|
||||
members.add_member(user.username)
|
||||
end
|
||||
else
|
||||
project.visit!
|
||||
project.add_member(user)
|
||||
end
|
||||
|
||||
if QA::Support::FIPS.enabled?
|
||||
Resource::Issue.fabricate_via_browser_ui! do |issue|
|
||||
issue.project = project
|
||||
end.visit!
|
||||
else
|
||||
Resource::Issue.fabricate_via_api! do |issue|
|
||||
issue.project = project
|
||||
end.visit!
|
||||
end
|
||||
end
|
||||
|
||||
it 'mentions another user in an issue', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347988' do
|
||||
it 'mentions another user in an issue',
|
||||
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347988' do
|
||||
Page::Project::Issue::Show.perform do |show|
|
||||
at_username = "@#{user.username}"
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ module QA
|
|||
|
||||
it(
|
||||
'creates a basic merge request',
|
||||
:smoke,
|
||||
:smoke, :skip_fips_env,
|
||||
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347738'
|
||||
) do
|
||||
Resource::MergeRequest.fabricate_via_browser_ui! do |merge_request|
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
|
||||
module QA
|
||||
RSpec.describe 'Create' do
|
||||
describe 'Git push over HTTP', :smoke, product_group: :source_code do
|
||||
it 'user using a personal access token pushes code to the repository', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347749' do
|
||||
describe 'Git push over HTTP', :smoke, :skip_fips_env, product_group: :source_code do
|
||||
it 'user using a personal access token pushes code to the repository',
|
||||
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347749' do
|
||||
Flow::Login.sign_in
|
||||
|
||||
access_token = Resource::PersonalAccessToken.fabricate!.token
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
module QA
|
||||
RSpec.describe 'Create' do
|
||||
describe 'Git push over HTTP', product_group: :source_code do
|
||||
it 'user pushes code to the repository', :smoke, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347747' do
|
||||
it 'user pushes code to the repository', :smoke, :skip_fips_env,
|
||||
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347747' do
|
||||
Flow::Login.sign_in
|
||||
|
||||
Resource::Repository::ProjectPush.fabricate! do |push|
|
||||
|
@ -18,7 +19,8 @@ module QA
|
|||
end
|
||||
end
|
||||
|
||||
it 'pushes to a project using a specific Praefect repository storage', :smoke, :requires_admin, :requires_praefect, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347789' do
|
||||
it 'pushes to a project using a specific Praefect repository storage', :smoke, :skip_fips_env, :requires_admin,
|
||||
:requires_praefect, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347789' do
|
||||
Flow::Login.sign_in_as_admin
|
||||
|
||||
project = Resource::Project.fabricate_via_api! do |storage_project|
|
||||
|
|
|
@ -26,7 +26,8 @@ module QA
|
|||
Flow::Login.sign_in
|
||||
end
|
||||
|
||||
it 'pushes code to the repository via SSH', :smoke, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347825' do
|
||||
it 'pushes code to the repository via SSH', :smoke, :skip_fips_env,
|
||||
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347825' do
|
||||
Resource::Repository::ProjectPush.fabricate! do |push|
|
||||
push.project = project
|
||||
push.ssh_key = @key
|
||||
|
@ -41,7 +42,8 @@ module QA
|
|||
end
|
||||
end
|
||||
|
||||
it 'pushes multiple branches and tags together', :smoke, testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347826' do
|
||||
it 'pushes multiple branches and tags together', :smoke, :skip_fips_env,
|
||||
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347826' do
|
||||
branches = []
|
||||
tags = []
|
||||
Git::Repository.perform do |repository|
|
||||
|
|
|
@ -17,6 +17,15 @@ module QA
|
|||
Flow::Login.sign_in
|
||||
end
|
||||
|
||||
after do
|
||||
if QA::Support::FIPS.enabled?
|
||||
snippet.visit!
|
||||
Page::Dashboard::Snippet::Show.perform(&:click_delete_button)
|
||||
else
|
||||
snippet.remove_via_api!
|
||||
end
|
||||
end
|
||||
|
||||
it 'user creates a personal snippet', testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347799' do
|
||||
snippet
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ module QA
|
|||
RSpec.describe 'Verify' do
|
||||
describe 'Add or Remove CI variable via UI', :smoke, product_group: :pipeline_authoring do
|
||||
let(:project) do
|
||||
Resource::Project.fabricate_via_api! do |project|
|
||||
Resource::Project.fabricate_via_api_unless_fips! do |project|
|
||||
project.name = 'project-with-ci-variables'
|
||||
project.description = 'project with CI variables'
|
||||
end
|
||||
|
|
|
@ -35,7 +35,7 @@ module QA
|
|||
keys = [
|
||||
['https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348022', Runtime::Key::RSA, 8192, true],
|
||||
['https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348021', Runtime::Key::ECDSA, 521, true],
|
||||
['https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348020', Runtime::Key::ED25519, false]
|
||||
['https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/348020', Runtime::Key::ED25519, 256, false]
|
||||
]
|
||||
|
||||
supported_keys =
|
||||
|
|
|
@ -5,7 +5,7 @@ module QA
|
|||
module Support
|
||||
class FIPS
|
||||
def self.enabled?
|
||||
%(1 true yes).include?(ENV['FIPS'].to_s)
|
||||
%w[1 true yes].include?(ENV['FIPS'].to_s)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -87,12 +87,46 @@ RSpec.describe QA::Resource::Base do
|
|||
end
|
||||
|
||||
context 'when resource supports fabrication via the API' do
|
||||
it 'calls .fabricate_via_browser_ui!' do
|
||||
it 'calls .fabricate_via_api!!' do
|
||||
expect(described_class).to receive(:fabricate_via_api!)
|
||||
|
||||
described_class.fabricate!
|
||||
end
|
||||
end
|
||||
|
||||
context 'when FIPS mode is enabled' do
|
||||
before do
|
||||
stub_env('FIPS', '1')
|
||||
end
|
||||
|
||||
it 'calls .fabricate_via_browser_ui!' do
|
||||
expect(described_class).to receive(:fabricate_via_browser_ui!)
|
||||
|
||||
described_class.fabricate!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.fabricate_via_api_unless_fips!' do
|
||||
context 'when FIPS mode is not enabled' do
|
||||
it 'calls .fabricate_via_api!!' do
|
||||
expect(described_class).to receive(:fabricate_via_api!)
|
||||
|
||||
described_class.fabricate_via_api_unless_fips!
|
||||
end
|
||||
end
|
||||
|
||||
context 'when FIPS mode is enabled' do
|
||||
before do
|
||||
stub_env('FIPS', '1')
|
||||
end
|
||||
|
||||
it 'calls .fabricate_via_browser_ui!' do
|
||||
expect(described_class).to receive(:fabricate_via_browser_ui!)
|
||||
|
||||
described_class.fabricate_via_api_unless_fips!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.fabricate_via_api!' do
|
||||
|
|
|
@ -116,4 +116,31 @@ RSpec.describe QA::Resource::User do
|
|||
expect(subject).to be_credentials_given
|
||||
end
|
||||
end
|
||||
|
||||
describe '#has_user?' do
|
||||
let(:index_mock) do
|
||||
instance_double(QA::Page::Admin::Overview::Users::Index)
|
||||
end
|
||||
|
||||
users = [
|
||||
['foo', true],
|
||||
['bar', false]
|
||||
]
|
||||
|
||||
users.each do |(username, found)|
|
||||
it "returns #{found} when has_username returns #{found}" do
|
||||
subject.username = username
|
||||
|
||||
allow(QA::Flow::Login).to receive(:while_signed_in_as_admin).and_yield
|
||||
allow(QA::Page::Main::Menu).to receive(:perform)
|
||||
allow(QA::Page::Admin::Menu).to receive(:perform)
|
||||
allow(QA::Page::Admin::Overview::Users::Index).to receive(:perform).and_yield(index_mock)
|
||||
|
||||
expect(index_mock).to receive(:search_user).with(username)
|
||||
expect(index_mock).to receive(:has_username?).with(username).and_return(found)
|
||||
|
||||
expect(subject.has_user?(subject)).to eq(found)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,8 +8,13 @@ fi
|
|||
|
||||
# Tag with commit SHA by default
|
||||
QA_IMAGE="${CI_REGISTRY}/${CI_PROJECT_PATH}/${QA_IMAGE_NAME}:${CI_COMMIT_SHA}"
|
||||
|
||||
# For branches, tag with slugified branch name. For tags, use the tag directly
|
||||
QA_IMAGE_BRANCH="${CI_REGISTRY}/${CI_PROJECT_PATH}/${QA_IMAGE_NAME}:${CI_COMMIT_TAG:-$CI_COMMIT_REF_SLUG}"
|
||||
# with v prefix removed
|
||||
IMAGE_TAG=${CI_COMMIT_TAG#v}
|
||||
IMAGE_TAG=${IMAGE_TAG:-$CI_COMMIT_REF_SLUG}
|
||||
|
||||
QA_IMAGE_BRANCH="${CI_REGISTRY}/${CI_PROJECT_PATH}/${QA_IMAGE_NAME}:${IMAGE_TAG}"
|
||||
|
||||
DESTINATIONS="--destination=${QA_IMAGE} --destination=${QA_IMAGE_BRANCH}"
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ main_report = JSON.parse(File.read(main_report_file))
|
|||
new_report = main_report.dup
|
||||
|
||||
ARGV.each do |report_file|
|
||||
next unless File.exist?(report_file)
|
||||
|
||||
report = JSON.parse(File.read(report_file))
|
||||
|
||||
# Remove existing values
|
||||
|
|
|
@ -60,6 +60,9 @@ function update_tests_metadata() {
|
|||
scripts/flaky_examples/prune-old-flaky-examples "${FLAKY_RSPEC_SUITE_REPORT_PATH}"
|
||||
|
||||
if [[ "$CI_PIPELINE_SOURCE" == "schedule" ]]; then
|
||||
if [[ -n "$RSPEC_PROFILING_PGSSLKEY" ]]; then
|
||||
chmod 0600 $RSPEC_PROFILING_PGSSLKEY
|
||||
fi
|
||||
PGSSLMODE=$RSPEC_PROFILING_PGSSLMODE PGSSLROOTCERT=$RSPEC_PROFILING_PGSSLROOTCERT PGSSLCERT=$RSPEC_PROFILING_PGSSLCERT PGSSLKEY=$RSPEC_PROFILING_PGSSLKEY scripts/insert-rspec-profiling-data
|
||||
else
|
||||
echo "Not inserting profiling data as the pipeline is not a scheduled one."
|
||||
|
|
|
@ -19,6 +19,7 @@ exports[`Project remove modal initialized matches the snapshot 1`] = `
|
|||
<gl-button-stub
|
||||
buttontextclasses=""
|
||||
category="primary"
|
||||
data-qa-selector="delete_button"
|
||||
icon=""
|
||||
role="button"
|
||||
size="medium"
|
||||
|
@ -102,6 +103,7 @@ exports[`Project remove modal initialized matches the snapshot 1`] = `
|
|||
</p>
|
||||
|
||||
<gl-form-input-stub
|
||||
data-qa-selector="confirm_name_field"
|
||||
id="confirm_name_input"
|
||||
name="confirm_name_input"
|
||||
type="text"
|
||||
|
|
|
@ -20,6 +20,7 @@ exports[`Project remove modal intialized matches the snapshot 1`] = `
|
|||
<gl-button-stub
|
||||
buttontextclasses=""
|
||||
category="primary"
|
||||
data-qa-selector="delete_button"
|
||||
icon=""
|
||||
role="button"
|
||||
size="medium"
|
||||
|
@ -103,6 +104,7 @@ exports[`Project remove modal intialized matches the snapshot 1`] = `
|
|||
</p>
|
||||
|
||||
<gl-form-input-stub
|
||||
data-qa-selector="confirm_name_field"
|
||||
id="confirm_name_input"
|
||||
name="confirm_name_input"
|
||||
type="text"
|
||||
|
|
|
@ -44,7 +44,7 @@ exports[`MRWidgetAutoMergeEnabled when graphql is disabled template should have
|
|||
class="gl-display-flex gl-w-full"
|
||||
>
|
||||
<div
|
||||
class="media-body gl-display-flex"
|
||||
class="media-body gl-display-flex gl-align-items-center"
|
||||
>
|
||||
|
||||
<h4
|
||||
|
@ -70,7 +70,7 @@ exports[`MRWidgetAutoMergeEnabled when graphql is disabled template should have
|
|||
</h4>
|
||||
|
||||
<div
|
||||
class="gl-display-flex gl-md-display-block gl-font-size-0 gl-ml-auto"
|
||||
class="gl-display-flex gl-font-size-0 gl-ml-auto gl-gap-3"
|
||||
>
|
||||
<div
|
||||
class="gl-display-flex gl-align-items-flex-start"
|
||||
|
@ -221,7 +221,7 @@ exports[`MRWidgetAutoMergeEnabled when graphql is enabled template should have c
|
|||
class="gl-display-flex gl-w-full"
|
||||
>
|
||||
<div
|
||||
class="media-body gl-display-flex"
|
||||
class="media-body gl-display-flex gl-align-items-center"
|
||||
>
|
||||
|
||||
<h4
|
||||
|
@ -247,7 +247,7 @@ exports[`MRWidgetAutoMergeEnabled when graphql is enabled template should have c
|
|||
</h4>
|
||||
|
||||
<div
|
||||
class="gl-display-flex gl-md-display-block gl-font-size-0 gl-ml-auto"
|
||||
class="gl-display-flex gl-font-size-0 gl-ml-auto gl-gap-3"
|
||||
>
|
||||
<div
|
||||
class="gl-display-flex gl-align-items-flex-start"
|
||||
|
|
|
@ -469,6 +469,37 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
|
|||
model.remove_concurrent_index(:users, :foo)
|
||||
end
|
||||
|
||||
context 'when targeting a partition table' do
|
||||
let(:schema) { 'public' }
|
||||
let(:partition_table_name) { '_test_partition_01' }
|
||||
let(:identifier) { "#{schema}.#{partition_table_name}" }
|
||||
let(:index_name) { '_test_partitioned_index' }
|
||||
let(:partition_index_name) { '_test_partition_01_partition_id_idx' }
|
||||
let(:column_name) { 'partition_id' }
|
||||
|
||||
before do
|
||||
model.execute(<<~SQL)
|
||||
CREATE TABLE public._test_partitioned_table (
|
||||
id serial NOT NULL,
|
||||
partition_id serial NOT NULL,
|
||||
PRIMARY KEY (id, partition_id)
|
||||
) PARTITION BY LIST(partition_id);
|
||||
|
||||
CREATE INDEX #{index_name} ON public._test_partitioned_table(#{column_name});
|
||||
|
||||
CREATE TABLE #{identifier} PARTITION OF public._test_partitioned_table
|
||||
FOR VALUES IN (1);
|
||||
SQL
|
||||
end
|
||||
|
||||
context 'when dropping an index on the partition table' do
|
||||
it 'raises ArgumentError' do
|
||||
expect { model.remove_concurrent_index(partition_table_name, column_name) }
|
||||
.to raise_error(ArgumentError, /use remove_concurrent_partitioned_index_by_name/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'by index name' do
|
||||
before do
|
||||
allow(model).to receive(:index_exists_by_name?).with(:users, "index_x_by_y").and_return(true)
|
||||
|
@ -510,6 +541,36 @@ RSpec.describe Gitlab::Database::MigrationHelpers do
|
|||
|
||||
model.remove_concurrent_index_by_name(:users, "index_x_by_y")
|
||||
end
|
||||
|
||||
context 'when targeting a partition table' do
|
||||
let(:schema) { 'public' }
|
||||
let(:partition_table_name) { '_test_partition_01' }
|
||||
let(:identifier) { "#{schema}.#{partition_table_name}" }
|
||||
let(:index_name) { '_test_partitioned_index' }
|
||||
let(:partition_index_name) { '_test_partition_01_partition_id_idx' }
|
||||
|
||||
before do
|
||||
model.execute(<<~SQL)
|
||||
CREATE TABLE public._test_partitioned_table (
|
||||
id serial NOT NULL,
|
||||
partition_id serial NOT NULL,
|
||||
PRIMARY KEY (id, partition_id)
|
||||
) PARTITION BY LIST(partition_id);
|
||||
|
||||
CREATE INDEX #{index_name} ON public._test_partitioned_table(partition_id);
|
||||
|
||||
CREATE TABLE #{identifier} PARTITION OF public._test_partitioned_table
|
||||
FOR VALUES IN (1);
|
||||
SQL
|
||||
end
|
||||
|
||||
context 'when dropping an index on the partition table' do
|
||||
it 'raises ArgumentError' do
|
||||
expect { model.remove_concurrent_index_by_name(partition_table_name, partition_index_name) }
|
||||
.to raise_error(ArgumentError, /use remove_concurrent_partitioned_index_by_name/)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,8 +3,10 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
||||
let(:database_metric_class) { Class.new(described_class) }
|
||||
|
||||
subject do
|
||||
described_class.tap do |metric_class|
|
||||
database_metric_class.tap do |metric_class|
|
||||
metric_class.relation { Issue }
|
||||
metric_class.operation :count
|
||||
metric_class.start { Issue.minimum(:id) }
|
||||
|
@ -38,7 +40,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
|
||||
context 'with metric options specified with custom batch_size' do
|
||||
subject do
|
||||
described_class.tap do |metric_class|
|
||||
database_metric_class.tap do |metric_class|
|
||||
metric_class.relation { Issue }
|
||||
metric_class.operation :count
|
||||
metric_class.start { Issue.minimum(:id) }
|
||||
|
@ -60,7 +62,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
|
||||
context 'with start and finish not called' do
|
||||
subject do
|
||||
described_class.tap do |metric_class|
|
||||
database_metric_class.tap do |metric_class|
|
||||
metric_class.relation { Issue }
|
||||
metric_class.operation :count
|
||||
end.new(time_frame: 'all')
|
||||
|
@ -73,7 +75,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
|
||||
context 'with availability defined' do
|
||||
subject do
|
||||
described_class.tap do |metric_class|
|
||||
database_metric_class.tap do |metric_class|
|
||||
metric_class.relation { Issue }
|
||||
metric_class.operation :count
|
||||
metric_class.available? { false }
|
||||
|
@ -87,7 +89,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
|
||||
context 'with availability not defined' do
|
||||
subject do
|
||||
Class.new(described_class) do
|
||||
database_metric_class do
|
||||
relation { Issue }
|
||||
operation :count
|
||||
end.new(time_frame: 'all')
|
||||
|
@ -100,7 +102,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
|
||||
context 'with cache_start_and_finish_as called' do
|
||||
subject do
|
||||
described_class.tap do |metric_class|
|
||||
database_metric_class.tap do |metric_class|
|
||||
metric_class.relation { Issue }
|
||||
metric_class.operation :count
|
||||
metric_class.start { Issue.minimum(:id) }
|
||||
|
@ -123,7 +125,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
|
||||
context 'with estimate_batch_distinct_count' do
|
||||
subject do
|
||||
described_class.tap do |metric_class|
|
||||
database_metric_class.tap do |metric_class|
|
||||
metric_class.relation { Issue }
|
||||
metric_class.operation(:estimate_batch_distinct_count)
|
||||
metric_class.start { Issue.minimum(:id) }
|
||||
|
@ -139,7 +141,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
let(:buckets) { double('Buckets').as_null_object }
|
||||
|
||||
subject do
|
||||
described_class.tap do |metric_class|
|
||||
database_metric_class.tap do |metric_class|
|
||||
metric_class.relation { Issue }
|
||||
metric_class.operation(:estimate_batch_distinct_count) do |result|
|
||||
result.foo
|
||||
|
@ -163,7 +165,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
|
||||
context 'with custom timestamp column' do
|
||||
subject do
|
||||
described_class.tap do |metric_class|
|
||||
database_metric_class.tap do |metric_class|
|
||||
metric_class.relation { Issue }
|
||||
metric_class.operation :count
|
||||
metric_class.timestamp_column :last_edited_at
|
||||
|
@ -171,6 +173,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
end
|
||||
|
||||
it 'calculates a correct result' do
|
||||
create(:issue, last_edited_at: 40.days.ago)
|
||||
create(:issue, last_edited_at: 5.days.ago)
|
||||
|
||||
expect(subject.value).to eq(1)
|
||||
|
@ -179,14 +182,14 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
|
||||
context 'with default timestamp column' do
|
||||
subject do
|
||||
described_class.tap do |metric_class|
|
||||
database_metric_class.tap do |metric_class|
|
||||
metric_class.relation { Issue }
|
||||
metric_class.operation :count
|
||||
end.new(time_frame: '28d')
|
||||
end
|
||||
|
||||
it 'calculates a correct result' do
|
||||
create(:issue, last_edited_at: 5.days.ago)
|
||||
create(:issue, created_at: 40.days.ago)
|
||||
create(:issue, created_at: 5.days.ago)
|
||||
|
||||
expect(subject.value).to eq(1)
|
||||
|
@ -195,15 +198,15 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
|
||||
context 'with additional parameters passed via options' do
|
||||
subject do
|
||||
described_class.tap do |metric_class|
|
||||
database_metric_class.tap do |metric_class|
|
||||
metric_class.relation ->(options) { Issue.where(confidential: options[:confidential]) }
|
||||
metric_class.operation :count
|
||||
end.new(time_frame: '28d', options: { confidential: true })
|
||||
end
|
||||
|
||||
it 'calculates a correct result' do
|
||||
create(:issue, last_edited_at: 5.days.ago, confidential: true)
|
||||
create(:issue, last_edited_at: 5.days.ago, confidential: false)
|
||||
create(:issue, created_at: 5.days.ago, confidential: true)
|
||||
create(:issue, created_at: 5.days.ago, confidential: false)
|
||||
|
||||
expect(subject.value).to eq(1)
|
||||
end
|
||||
|
@ -212,7 +215,7 @@ RSpec.describe Gitlab::Usage::Metrics::Instrumentations::DatabaseMetric do
|
|||
|
||||
context 'with unimplemented operation method used' do
|
||||
subject do
|
||||
described_class.tap do |metric_class|
|
||||
database_metric_class.tap do |metric_class|
|
||||
metric_class.relation { Issue }
|
||||
metric_class.operation :invalid_operation
|
||||
end.new(time_frame: 'all')
|
||||
|
|
|
@ -12,6 +12,10 @@ RSpec.describe Gitlab::UsageDataCounters::CiTemplateUniqueCounter do
|
|||
|
||||
shared_examples 'tracks template' do
|
||||
let(:subject) { described_class.track_unique_project_event(project: project, template: template_path, config_source: config_source, user: user) }
|
||||
let(:template_name) do
|
||||
expanded_template_name = described_class.expand_template_name(template_path)
|
||||
described_class.ci_template_event_name(expanded_template_name, config_source)
|
||||
end
|
||||
|
||||
it "has an event defined for template" do
|
||||
expect do
|
||||
|
@ -20,33 +24,18 @@ RSpec.describe Gitlab::UsageDataCounters::CiTemplateUniqueCounter do
|
|||
end
|
||||
|
||||
it "tracks template" do
|
||||
expanded_template_name = described_class.expand_template_name(template_path)
|
||||
expected_template_event_name = described_class.ci_template_event_name(expanded_template_name, config_source)
|
||||
expect(Gitlab::UsageDataCounters::HLLRedisCounter).to(receive(:track_event)).with(expected_template_event_name, values: project.id)
|
||||
expect(Gitlab::UsageDataCounters::HLLRedisCounter).to(receive(:track_event)).with(template_name, values: project.id)
|
||||
|
||||
subject
|
||||
end
|
||||
|
||||
context 'Snowplow' do
|
||||
it 'event is not tracked if FF is disabled' do
|
||||
stub_feature_flags(route_hll_to_snowplow: false)
|
||||
|
||||
subject
|
||||
|
||||
expect_no_snowplow_event
|
||||
end
|
||||
|
||||
it 'tracks event' do
|
||||
subject
|
||||
|
||||
expect_snowplow_event(
|
||||
category: described_class.to_s,
|
||||
action: 'ci_templates_unique',
|
||||
namespace: project.namespace,
|
||||
user: user,
|
||||
project: project
|
||||
)
|
||||
end
|
||||
it_behaves_like 'Snowplow event tracking with RedisHLL context' do
|
||||
let(:feature_flag_name) { :route_hll_to_snowplow }
|
||||
let(:category) { described_class.to_s }
|
||||
let(:action) { 'ci_templates_unique' }
|
||||
let(:namespace) { project.namespace }
|
||||
let(:label) { 'redis_hll_counters.ci_templates.ci_templates_total_unique_counts_monthly' }
|
||||
let(:context) { [Gitlab::Tracking::ServicePingContext.new(data_source: :redis_hll, event: template_name).to_context] }
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ require (
|
|||
github.com/BurntSushi/toml v1.2.1
|
||||
github.com/FZambia/sentinel v1.1.1
|
||||
github.com/alecthomas/chroma/v2 v2.3.0
|
||||
github.com/aws/aws-sdk-go v1.44.131
|
||||
github.com/aws/aws-sdk-go v1.44.133
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/getsentry/raven-go v0.2.0
|
||||
github.com/golang-jwt/jwt/v4 v4.4.2
|
||||
|
|
|
@ -227,8 +227,8 @@ github.com/aws/aws-sdk-go v1.43.11/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4
|
|||
github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
|
||||
github.com/aws/aws-sdk-go v1.44.45/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
|
||||
github.com/aws/aws-sdk-go v1.44.68/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo=
|
||||
github.com/aws/aws-sdk-go v1.44.131 h1:kd61x79ax0vyiC/SZ9X1hKh8E0pt1BUOOcVBJEFhxkg=
|
||||
github.com/aws/aws-sdk-go v1.44.131/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||
github.com/aws/aws-sdk-go v1.44.133 h1:+pWxt9nyKc0jf33rORBaQ93KPjYpmIIy3ozVXdJ82Oo=
|
||||
github.com/aws/aws-sdk-go v1.44.133/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
|
||||
github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g=
|
||||
github.com/aws/aws-sdk-go-v2 v1.16.8 h1:gOe9UPR98XSf7oEJCcojYg+N2/jCRm4DdeIsP85pIyQ=
|
||||
github.com/aws/aws-sdk-go-v2 v1.16.8/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw=
|
||||
|
|
Loading…
Reference in New Issue