diff --git a/.rubocop.yml b/.rubocop.yml index bd10e12f098..7fe98a55324 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -690,6 +690,7 @@ Gitlab/NamespacedClass: - 'scripts/**/*' - 'spec/migrations/**/*.rb' - 'app/experiments/**/*_experiment.rb' + - 'ee/app/experiments/**/*_experiment.rb' Lint/HashCompareByIdentity: Enabled: true diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 710bb964759..2adf59347d7 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -c47bb5beba81703b7c2bb2b3d1c138cb667fa80c +07557c28273b27d750771e2044179730f1cfac16 diff --git a/app/assets/stylesheets/framework/buttons.scss b/app/assets/stylesheets/framework/buttons.scss index d349bf7a1d3..33522c66024 100644 --- a/app/assets/stylesheets/framework/buttons.scss +++ b/app/assets/stylesheets/framework/buttons.scss @@ -121,6 +121,10 @@ @include btn-color($white, $border-color, $white-normal, $border-white-normal, $white-dark, $border-white-normal, $gl-text-color); } +@mixin btn-purple { + @include btn-color($purple-700, $purple-800, $purple-800, $purple-900, $purple-900, $purple-950, $white); +} + @mixin btn-with-margin { margin-left: $btn-side-margin; float: left; @@ -194,6 +198,10 @@ @include btn-red; } + &.btn-purple { + @include btn-purple; + } + &.btn-grouped { @include btn-with-margin; } diff --git a/app/assets/stylesheets/utilities.scss b/app/assets/stylesheets/utilities.scss index d7a5e21e303..fd85ff894a7 100644 --- a/app/assets/stylesheets/utilities.scss +++ b/app/assets/stylesheets/utilities.scss @@ -366,3 +366,30 @@ to @gitlab/ui by https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1709 /* stylelint-disable property-no-vendor-prefix */ -webkit-backdrop-filter: blur(2px); // still required by Safari } + +/* + * The below style will be moved to @gitlab/ui by + * https://gitlab.com/gitlab-org/gitlab-ui/-/issues/1792 + */ +.gl-text-purple-800 { + color: $purple-800; +} + +.gl-bg-theme-indigo-800 { + background-color: $theme-indigo-800; +} + +.gl-border-indigo-700 { + border-color: $theme-indigo-700; +} + +.gl-border-gray-75 { + border-color: $gl-text-color-quaternary; +} + +.gl-min-h-8 { + min-height: $gl-spacing-scale-8; +} + +/* End gitlab-ui#1751 */ + diff --git a/app/controllers/projects/prometheus/alerts_controller.rb b/app/controllers/projects/prometheus/alerts_controller.rb index 2f9ea795135..5e1b9570fa0 100644 --- a/app/controllers/projects/prometheus/alerts_controller.rb +++ b/app/controllers/projects/prometheus/alerts_controller.rb @@ -14,7 +14,7 @@ module Projects prepend_before_action :repository, :project_without_auth, only: [:notify] before_action :authorize_read_prometheus_alerts!, except: [:notify] - before_action :alert, only: [:update, :show, :destroy, :metrics_dashboard] + before_action :alert, only: [:show, :metrics_dashboard] feature_category :incident_management urgency :low @@ -38,68 +38,13 @@ module Projects end end - def create - @alert = create_service.execute - - if @alert.persisted? - schedule_prometheus_update! - - render json: serialize_as_json(@alert) - else - head :bad_request - end - end - - def update - if update_service.execute(alert) - schedule_prometheus_update! - - render json: serialize_as_json(alert) - else - head :bad_request - end - end - - def destroy - if destroy_service.execute(alert) - schedule_prometheus_update! - - head :ok - else - head :bad_request - end - end - private - def alerts_params - params.permit(:operator, :threshold, :environment_id, :prometheus_metric_id, :runbook_url) - end - def notify_service Projects::Prometheus::Alerts::NotifyService .new(project, params.permit!) end - def create_service - Projects::Prometheus::Alerts::CreateService - .new(project: project, current_user: current_user, params: alerts_params) - end - - def update_service - Projects::Prometheus::Alerts::UpdateService - .new(project: project, current_user: current_user, params: alerts_params) - end - - def destroy_service - Projects::Prometheus::Alerts::DestroyService - .new(project: project, current_user: current_user, params: nil) - end - - def schedule_prometheus_update! - ::Clusters::Applications::ScheduleUpdateService.new(application, project).execute - end - def serialize_as_json(alert_obj) serializer.represent(alert_obj) end @@ -124,10 +69,6 @@ module Projects }.reverse_merge(opts)) end - def application - @application ||= alert.environment.cluster_prometheus_adapter - end - def extract_alert_manager_token(request) Doorkeeper::OAuth::Token.from_bearer_authorization(request) end @@ -137,10 +78,6 @@ module Projects .find_by_full_path("#{params[:namespace_id]}/#{params[:project_id]}") end - def prometheus_alerts - project.prometheus_alerts.for_environment(params[:environment_id]) - end - def metrics_dashboard_params { embedded: true, diff --git a/app/services/import/bitbucket_server_service.rb b/app/services/import/bitbucket_server_service.rb index cdb23370ddc..d1c22f06464 100644 --- a/app/services/import/bitbucket_server_service.rb +++ b/app/services/import/bitbucket_server_service.rb @@ -21,6 +21,8 @@ module Import if project.persisted? success(project) + elsif project.errors[:import_source_disabled].present? + error(project.errors[:import_source_disabled], :forbidden) else log_and_return_error(project_save_error(project), :unprocessable_entity) end diff --git a/app/services/import/github_service.rb b/app/services/import/github_service.rb index a891dcc11e3..033f6bcb043 100644 --- a/app/services/import/github_service.rb +++ b/app/services/import/github_service.rb @@ -25,6 +25,8 @@ module Import if project.persisted? success(project) + elsif project.errors[:import_source_disabled].present? + error(project.errors[:import_source_disabled], :forbidden) else error(project_save_error(project), :unprocessable_entity) end diff --git a/app/services/projects/create_service.rb b/app/services/projects/create_service.rb index a601cbb3a3e..b051efcde94 100644 --- a/app/services/projects/create_service.rb +++ b/app/services/projects/create_service.rb @@ -4,6 +4,9 @@ module Projects class CreateService < BaseService include ValidatesClassificationLabel + ImportSourceDisabledError = Class.new(StandardError) + INTERNAL_IMPORT_SOURCES = %w[bare_repository gitlab_custom_project_template gitlab_project_migration].freeze + def initialize(user, params) @current_user = user @params = params.dup @@ -25,6 +28,8 @@ module Projects @project = Project.new(params) + validate_import_source_enabled! + @project.visibility_level = @project.group.visibility_level unless @project.visibility_level_allowed_by_group? # If a project is newly created it should have shared runners settings @@ -77,6 +82,9 @@ module Projects rescue ActiveRecord::RecordInvalid => e message = "Unable to save #{e.inspect}: #{e.record.errors.full_messages.join(", ")}" fail(error: message) + rescue ImportSourceDisabledError => e + @project.errors.add(:import_source_disabled, e.message) if @project + fail(error: e.message) rescue StandardError => e @project.errors.add(:base, e.message) if @project fail(error: e.message) @@ -238,6 +246,18 @@ module Projects private + def validate_import_source_enabled! + return unless @params[:import_type] + + import_type = @params[:import_type].to_s + + return if INTERNAL_IMPORT_SOURCES.include?(import_type) + + unless ::Gitlab::CurrentSettings.import_sources&.include?(import_type) + raise ImportSourceDisabledError, "#{import_type} import source is disabled" + end + end + def parent_namespace @parent_namespace ||= Namespace.find_by_id(@params[:namespace_id]) || current_user.namespace end diff --git a/app/services/projects/prometheus/alerts/alert_params.rb b/app/services/projects/prometheus/alerts/alert_params.rb deleted file mode 100644 index 1c39ed36b12..00000000000 --- a/app/services/projects/prometheus/alerts/alert_params.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Projects - module Prometheus - module Alerts - module AlertParams - def alert_params - return params if params[:operator].blank? - - params.merge( - operator: PrometheusAlert.operator_to_enum(params[:operator]) - ) - end - end - end - end -end diff --git a/app/services/projects/prometheus/alerts/create_service.rb b/app/services/projects/prometheus/alerts/create_service.rb deleted file mode 100644 index 0d7d8ab1a62..00000000000 --- a/app/services/projects/prometheus/alerts/create_service.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module Projects - module Prometheus - module Alerts - class CreateService < BaseProjectService - include AlertParams - - def execute - project.prometheus_alerts.create(alert_params) - end - end - end - end -end diff --git a/app/services/projects/prometheus/alerts/destroy_service.rb b/app/services/projects/prometheus/alerts/destroy_service.rb deleted file mode 100644 index 243b12eb654..00000000000 --- a/app/services/projects/prometheus/alerts/destroy_service.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -module Projects - module Prometheus - module Alerts - class DestroyService < BaseProjectService - def execute(alert) - alert.destroy - end - end - end - end -end diff --git a/app/services/projects/prometheus/alerts/update_service.rb b/app/services/projects/prometheus/alerts/update_service.rb deleted file mode 100644 index 1802f35dae9..00000000000 --- a/app/services/projects/prometheus/alerts/update_service.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module Projects - module Prometheus - module Alerts - class UpdateService < BaseProjectService - include AlertParams - - def execute(alert) - alert.update(alert_params) - end - end - end - end -end diff --git a/config/routes/project.rb b/config/routes/project.rb index a3f6139a6ef..0ef891aa4c9 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -517,7 +517,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do end namespace :prometheus do - resources :alerts, constraints: { id: /\d+/ }, only: [:index, :create, :show, :update, :destroy] do # rubocop: disable Cop/PutProjectRoutesUnderScope + resources :alerts, constraints: { id: /\d+/ }, only: [:index, :show] do # rubocop: disable Cop/PutProjectRoutesUnderScope post :notify, on: :collection # rubocop:todo Cop/PutProjectRoutesUnderScope member do get :metrics_dashboard # rubocop:todo Cop/PutProjectRoutesUnderScope diff --git a/doc/.vale/gitlab/VersionText.yml b/doc/.vale/gitlab/VersionText.yml index fbdda17e2a0..0d8131f99a5 100644 --- a/doc/.vale/gitlab/VersionText.yml +++ b/doc/.vale/gitlab/VersionText.yml @@ -16,7 +16,7 @@ # For a list of all options, see https://errata-ai.gitbook.io/vale/getting-started/styles extends: existence message: 'This introduced-in line is not formatted correctly.' -link: https://docs.gitlab.com/ee/development/documentation/styleguide/index.html#version-text-in-the-version-history +link: https://docs.gitlab.com/ee/development/documentation/styleguide/versions.html level: error scope: raw raw: diff --git a/doc/api/environments.md b/doc/api/environments.md index 40d161485ff..bfc097d44ee 100644 --- a/doc/api/environments.md +++ b/doc/api/environments.md @@ -36,6 +36,7 @@ Example response: "slug": "review-fix-foo-dfjre3", "external_url": "https://review-fix-foo-dfjre3.gitlab.example.com", "state": "available", + "tier": "development", "created_at": "2019-05-25T18:55:13.252Z", "updated_at": "2019-05-27T18:55:13.252Z", "enable_advanced_logs_querying": false, @@ -147,6 +148,7 @@ Example of response "slug": "review-fix-foo-dfjre3", "external_url": "https://review-fix-foo-dfjre3.gitlab.example.com", "state": "available", + "tier": "development", "created_at": "2019-05-25T18:55:13.252Z", "updated_at": "2019-05-27T18:55:13.252Z", "enable_advanced_logs_querying": false, @@ -249,6 +251,7 @@ POST /projects/:id/environments | `id` | integer/string | yes | The ID or [URL-encoded path of the project](index.md#namespaced-path-encoding) owned by the authenticated user | | `name` | string | yes | The name of the environment | | `external_url` | string | no | Place to link to for this environment | +| `tier` | string | no | The tier of the new environment. Allowed values are `production`, `staging`, `testing`, `development`, and `other` | ```shell curl --data "name=deploy&external_url=https://deploy.gitlab.example.com" \ @@ -264,6 +267,7 @@ Example response: "slug": "deploy", "external_url": "https://deploy.gitlab.example.com", "state": "available", + "tier": "production", "created_at": "2019-05-25T18:55:13.252Z", "updated_at": "2019-05-27T18:55:13.252Z" } @@ -285,6 +289,7 @@ PUT /projects/:id/environments/:environments_id | `environment_id` | integer | yes | The ID of the environment | | `name` | string | no | [Deprecated and will be removed in GitLab 15.0](https://gitlab.com/gitlab-org/gitlab/-/issues/338897) | | `external_url` | string | no | The new `external_url` | +| `tier` | string | no | The tier of the new environment. Allowed values are `production`, `staging`, `testing`, `development`, and `other` | ```shell curl --request PUT --data "name=staging&external_url=https://staging.gitlab.example.com" \ @@ -300,6 +305,7 @@ Example response: "slug": "staging", "external_url": "https://staging.gitlab.example.com", "state": "available", + "tier": "staging", "created_at": "2019-05-25T18:55:13.252Z", "updated_at": "2019-05-27T18:55:13.252Z" } diff --git a/doc/development/backend/ruby_style_guide.md b/doc/development/backend/ruby_style_guide.md index 5fbb8a0bb6e..5202ba0baa5 100644 --- a/doc/development/backend/ruby_style_guide.md +++ b/doc/development/backend/ruby_style_guide.md @@ -13,7 +13,7 @@ Generally, if a style is not covered by [existing Rubocop rules or style guides] Before adding a new cop to enforce a given style, make sure to discuss it with your team. When the style is approved by a backend EM or by a BE staff eng, add a new section to this page to document the new rule. For every new guideline, add it in a new section and link the discussion from the section's -[version history note](../documentation/versions.md#version-text-in-the-version-history) +[version history note](../documentation/versions.md#add-a-version-history-bullet) to provide context and serve as a reference. Just because something is listed here does not mean it cannot be reopened for discussion. diff --git a/doc/development/documentation/restful_api_styleguide.md b/doc/development/documentation/restful_api_styleguide.md index 0fc5e4e13af..37e58f1ec7a 100644 --- a/doc/development/documentation/restful_api_styleguide.md +++ b/doc/development/documentation/restful_api_styleguide.md @@ -75,7 +75,7 @@ Example response: ``` ```` -Adjust the [version history note accordingly](versions.md#version-text-in-the-version-history) +Adjust the [version history note accordingly](versions.md#add-a-version-history-bullet) to describe the GitLab release that introduced the API call. ## Method description diff --git a/doc/development/documentation/styleguide/index.md b/doc/development/documentation/styleguide/index.md index f47b2b8778b..72031642eb7 100644 --- a/doc/development/documentation/styleguide/index.md +++ b/doc/development/documentation/styleguide/index.md @@ -727,7 +727,6 @@ We include guidance for links in these categories: for authoritative sources. - When to use [links requiring permissions](#links-requiring-permissions). - How to set up a [link to a video](#link-to-video). -- How to [include links with version text](../versions.md#where-to-put-version-text). - How to [link to specific lines of code](#link-to-specific-lines-of-code) ### Basic link criteria diff --git a/doc/development/documentation/versions.md b/doc/development/documentation/versions.md index 91444b73df7..48dc008a90d 100644 --- a/doc/development/documentation/versions.md +++ b/doc/development/documentation/versions.md @@ -7,49 +7,32 @@ description: 'Writing styles, markup, formatting, and other standards for GitLab # Documenting product versions -GitLab product documentation pages (not including [Contributor and Development](../../index.md) -pages in the `/development` directory) can include version information to help -users be aware of recent improvements or additions. +The GitLab product documentation includes version-specific information, +including when features were introduced and when they were updated or removed. -The GitLab Technical Writing team determines which versions of -documentation to display on this site based on the GitLab -[Statement of Support](https://about.gitlab.com/support/statement-of-support.html#version-support). +## View older documentation versions -## View older GitLab documentation versions +Previous versions of the documentation are available on `docs.gitlab.com`. +To view a previous version, select the **Versions** button in the top right. -Older versions of GitLab may no longer have documentation available from `docs.gitlab.com`. -If documentation for your version is no longer available from `docs.gitlab.com`, you can still view a -tagged and released set of documentation for your installed version: +To view versions that are not available on `docs.gitlab.com`: -- In the [documentation archives](https://docs.gitlab.com/archives/). -- At the `/help` URL of your GitLab instance. -- In the documentation repository based on the respective branch (for example, - the [13.2 branch](https://gitlab.com/gitlab-org/gitlab/-/tree/13-2-stable-ee/doc)). +- View the [documentation archives](https://docs.gitlab.com/archives/). +- Go to the GitLab repository and select the version-specific branch. For example, + the [13.2 branch](https://gitlab.com/gitlab-org/gitlab/-/tree/13-2-stable-ee/doc) has the + documentation for GitLab 13.2. -## Where to put version text +## Documenting version-specific features When a feature is added or updated, you can include its version information -either as a **Version history** item or as an inline text reference. +either as a **Version history** bullet or as an inline text reference. -### Version text in the **Version History** +You do not need to add version information on the pages in the `/development` directory. -If all content in a section is related, add version text after the header for -the section. The version information must: +### Add a **Version history** bullet -- Be surrounded by blank lines. -- Start with `>`. If there are multiple bullets, each line must start with `> -`. -- The string must include these words in this order (capitalization doesn't matter): - - `introduced`, `enabled`, `deprecated`, `changed`, `moved`, `recommended` (as in the - [feature flag documentation](feature_flags.md)), `removed`, or `renamed` - - `in` or `to` - - `GitLab` -- Whenever possible, include a link to the completed issue, merge request, or epic - that introduced the feature. An issue is preferred over a merge request, and - a merge request is preferred over an epic. -- Do not include information about the tier, unless documenting a tier change - (for example, `Feature X [moved](issue-link) to Premium in GitLab 19.2`). -- Do not link to the pricing page. - The tier is provided by the [product badge](styleguide/index.md#product-tier-badges) on the heading. +If all content in a topic is related, add a version history bullet after the topic heading. +For example: ```markdown ## Feature name @@ -57,23 +40,29 @@ the section. The version information must: > [Introduced]() in GitLab 11.3. This feature does something. - -## Feature name 2 - -> - [Introduced]() in GitLab 11.3. -> - [Enabled by default]() in GitLab 11.4. - -This feature does something else. ``` -If you're documenting elements of a feature, start with the feature name or a gerund: +The bullet text must include these words in order. Capitalization doesn't matter. + +- `introduced`, `enabled`, `deprecated`, `changed`, `moved`, `recommended`, `removed`, or `renamed` +- `in` or `to` +- `GitLab` + +If possible, include a link to the related issue, merge request, or epic. +Do not link to the pricing page. Do not include the subscription tier. + +#### Introducing a new feature + +If you use `introduced`, start the sentence with the feature name or a gerund: ```markdown > - Notifications for expiring tokens [introduced]() in GitLab 11.3. > - Creating an issue from an issue board [introduced]() in GitLab 13.1. ``` -If a feature is moved to another tier: +#### Moving subscription tiers + +If a feature is moved to another subscription tier, use `moved`: ```markdown > - [Moved]() from GitLab Ultimate to GitLab Premium in 11.8. @@ -83,88 +72,118 @@ If a feature is moved to another tier: ### Inline version text If you're adding content to an existing topic, you can add version information -inline with the existing text. - -In this case, add `([introduced/deprecated]() in GitLab X.X)`. - -Including the issue link is encouraged, but isn't a requirement. For example: +inline with the existing text. If possible, include a link to the related issue, +merge request, or epic. For example: ```markdown -The voting strategy in GitLab 13.4 and later requires the primary and secondary +The voting strategy [in GitLab 13.4 and later]() requires the primary and secondary voters to agree. ``` -### Deprecated features +## Deprecations and removals -When a feature is deprecated, add `(DEPRECATED)` to the page title or to -the heading of the section documenting the feature, immediately before -the tier badge: +When features are deprecated and removed, update the related documentation. -```markdown - -# Feature A (DEPRECATED) **(ALL TIERS)** +API documentation follows these guidelines, but the GraphQL docs use +a [separate process](../api_graphql_styleguide.md#deprecating-fields-arguments-and-enum-values). - -## Feature B (DEPRECATED) **(PREMIUM SELF)** -``` +### Deprecate a page or topic -Add the deprecation to the version history note (you can include a link -to a replacement when available): +To deprecate a page or topic: -```markdown -> - [Deprecated]() in GitLab 11.3. Replaced by [meaningful text](). -``` +1. Add `(deprecated)` after the title. Use a warning to explain when it was deprecated, + when it will be removed, and the replacement feature. -You can also describe the replacement in surrounding text, if available. If the -deprecation isn't obvious in existing text, you may want to include a warning: + ```markdown + ## Title (deprecated) **(ULTIMATE SELF)** -```markdown -WARNING: -This feature was [deprecated](link-to-issue) in GitLab 12.3 and replaced by -[Feature name](link-to-feature-documentation). -``` + WARNING: + This feature was [deprecated]() in GitLab 14.8 + and is planned for removal in 15.4. Use [feature X]() instead. + ``` -If you add `(DEPRECATED)` to the page's title and the document is linked from the docs -navigation, either remove the page from the nav or update the nav item to include the -same text before the feature name: + If you're not sure when the feature will be removed or no + replacement feature exists, you don't need to add this information. -```yaml - - doc_title: (DEPRECATED) Feature A -``` +1. If the deprecation is a breaking change, add this text: -In the first major GitLab version after the feature was deprecated, be sure to -remove information about that deprecated feature. + ```markdown + This change is a breaking change. + ``` -### End-of-life for features or products + You can add any additional context-specific details that might help users. -When a feature or product enters its end-of-life, indicate its status by -creating a [warning alert](styleguide/index.md#alert-boxes) directly after its relevant header. -If possible, link to its deprecation and removal issues. +1. Open a merge request to add the word `(deprecated)` to the left nav, after the page title. -For example: +### Remove a page -```markdown -WARNING: -This feature is in its end-of-life process. It is [deprecated](link-to-issue) -in GitLab X.X, and is planned for [removal](link-to-issue) in GitLab X.X. -``` +Mark content as removed during the release the feature was removed. +The title and a removed indicator remains until three months after the removal. -After the feature or product is officially deprecated and removed, remove -its information from the GitLab documentation. +To remove a page: -## Versions in the past or future +1. Leave the page title. Remove all other content, including the version history bullets and the word `WARNING:`. +1. After the title, change `(deprecated)` to `(removed)`. +1. Add `remove_date` in the YAML metadata. Set the value to a date three months after + the release when the feature was removed. For example: -When describing functionality available in past or future versions, use: + ```markdown + --- + stage: Enablement + group: Global Search + info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#assignments + remove_date: '2022-08-02' + --- -- Earlier, and not older or before. -- Later, and not newer or after. + # Title (removed) **(ULTIMATE SELF)** -For example: + This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/351963) in GitLab 14.8 + and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/351963) in 15.0. + Use [feature X]() instead. + ``` -- Available in GitLab 13.1 and earlier. -- Available in GitLab 12.4 and later. -- In GitLab 12.2 and earlier, ... -- In GitLab 11.6 and later, ... +1. Remove the page from the left nav. + +This content is removed from the documentation as part of the Technical Writing team's +[regularly scheduled tasks](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#regularly-scheduled-tasks). + +### Remove a topic + +To remove a topic: + +1. Leave the title and the details of the deprecation and removal. Remove all other content, + including the version history bullets and the word `WARNING:`. +1. Add `(removed)` after the title. +1. Add the following HTML comments above and below the topic. + For the `remove_date`, set a date three months after the release where it was removed. + + ```markdown + + + ## Title (removed) **(ULTIMATE SELF)** + + This feature was [deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/351963) in GitLab 14.8 + and [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/351963) in 15.0. + Use [feature X]() instead. + + + ``` + +This content is removed from the documentation as part of the Technical Writing team's +[regularly scheduled tasks](https://about.gitlab.com/handbook/engineering/ux/technical-writing/#regularly-scheduled-tasks). + +## Which versions are removed + +GitLab supports the current major version and two previous major versions. +For example, if 14.0 is the current major version, all major and minor releases of +GitLab 14.0, 13.0 and 12.0 are supported. + +[View the list of supported versions](https://about.gitlab.com/support/statement-of-support.html#version-support). + +If you see version history bullets or inline text that refers to unsupported versions, you can remove it. + +Historical feature information is available in [release posts](https://about.gitlab.com/releases/) +or by searching for the issue or merge request where the work was done. ## Promising features in future versions @@ -207,16 +226,3 @@ sole discretion of GitLab Inc. If all of the content on the page is not available, use the disclaimer once at the top of the page. If the content in a topic is not ready, use the disclaimer in the topic. - -## Removing versions after each major release - -When a major GitLab release occurs, we remove all references -to now-unsupported versions. This removal includes version-specific instructions. For example, -if GitLab version 12.1 and later are supported, -instructions for users of GitLab 11 should be removed. - -[View the list of supported versions](https://about.gitlab.com/support/statement-of-support.html#version-support). - -To view historical information about a feature, review GitLab -[release posts](https://about.gitlab.com/releases/), or search for the issue or -merge request where the work was done. diff --git a/lib/api/entities/environment.rb b/lib/api/entities/environment.rb index 91867f3403d..b1a720ac6bb 100644 --- a/lib/api/entities/environment.rb +++ b/lib/api/entities/environment.rb @@ -6,6 +6,7 @@ module API include RequestAwareEntity include Gitlab::Utils::StrongMemoize + expose :tier expose :project, using: Entities::BasicProjectDetails expose :last_deployment, using: Entities::Deployment, if: { last_deployment: true } expose :state diff --git a/lib/api/environments.rb b/lib/api/environments.rb index 646b7e5eedb..31c8ae73a0c 100644 --- a/lib/api/environments.rb +++ b/lib/api/environments.rb @@ -40,6 +40,7 @@ module API requires :name, type: String, desc: 'The name of the environment to be created' optional :external_url, type: String, desc: 'URL on which this deployment is viewable' optional :slug, absence: { message: "is automatically generated and cannot be changed" } + optional :tier, type: String, values: Environment.tiers.keys, desc: 'The tier of the environment to be created' end post ':id/environments' do authorize! :create_environment, user_project @@ -63,13 +64,14 @@ module API optional :name, type: String, desc: 'DEPRECATED: Renaming environment can lead to errors, this will be removed in 15.0' optional :external_url, type: String, desc: 'The new URL on which this deployment is viewable' optional :slug, absence: { message: "is automatically generated and cannot be changed" } + optional :tier, type: String, values: Environment.tiers.keys, desc: 'The tier of the environment to be created' end put ':id/environments/:environment_id' do authorize! :update_environment, user_project environment = user_project.environments.find(params[:environment_id]) - update_params = declared_params(include_missing: false).extract!(:name, :external_url) + update_params = declared_params(include_missing: false).extract!(:name, :external_url, :tier) if environment.update(update_params) present environment, with: Entities::Environment, current_user: current_user else diff --git a/lib/api/helpers/projects_helpers.rb b/lib/api/helpers/projects_helpers.rb index 7bd8c3c4bd0..3fa20378b19 100644 --- a/lib/api/helpers/projects_helpers.rb +++ b/lib/api/helpers/projects_helpers.rb @@ -190,8 +190,6 @@ module API def validate_git_import_url!(import_url) return if import_url.blank? - yield if block_given? - result = Import::ValidateRemoteGitEndpointService.new(url: import_url).execute # network call if result.error? diff --git a/lib/api/import_bitbucket_server.rb b/lib/api/import_bitbucket_server.rb index c44bee569f0..0f2d6239d0d 100644 --- a/lib/api/import_bitbucket_server.rb +++ b/lib/api/import_bitbucket_server.rb @@ -5,10 +5,6 @@ module API feature_category :importers urgency :low - before do - forbidden! unless Gitlab::CurrentSettings.import_sources&.include?('bitbucket_server') - end - helpers do def client @client ||= BitbucketServer::Client.new(credentials) diff --git a/lib/api/import_github.rb b/lib/api/import_github.rb index fefa72ce617..46ca8e4c428 100644 --- a/lib/api/import_github.rb +++ b/lib/api/import_github.rb @@ -7,10 +7,6 @@ module API rescue_from Octokit::Unauthorized, with: :provider_unauthorized - before do - forbidden! unless Gitlab::CurrentSettings.import_sources&.include?('github') - end - helpers do def client @client ||= if Feature.enabled?(:remove_legacy_github_client) diff --git a/lib/api/projects.rb b/lib/api/projects.rb index d76e3a7df3f..afd9c66866f 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -90,10 +90,6 @@ module API Gitlab::AppLogger.info({ message: "File exceeds maximum size", file_bytes: file.size, project_id: user_project.id, project_path: user_project.full_path, upload_allowed: allowed }) end end - - def check_import_by_url_is_enabled - Gitlab::CurrentSettings.import_sources&.include?('git') || forbidden! - end end helpers do @@ -202,6 +198,11 @@ module API params[:builds_enabled] = params.delete(:jobs_enabled) if params.key?(:jobs_enabled) params end + + def add_import_params(params) + params[:import_type] = 'git' if params[:import_url]&.present? + params + end end resource :users, requirements: API::USER_REQUIREMENTS do @@ -271,9 +272,10 @@ module API Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/issues/21139') attrs = declared_params(include_missing: false) attrs = translate_params_for_compatibility(attrs) + attrs = add_import_params(attrs) filter_attributes_using_license!(attrs) - validate_git_import_url!(params[:import_url]) { check_import_by_url_is_enabled } + validate_git_import_url!(params[:import_url]) project = ::Projects::CreateService.new(current_user, attrs).execute @@ -286,6 +288,8 @@ module API error!(project.errors[:limit_reached], 403) end + forbidden! if project.errors[:import_source_disabled].present? + render_validation_error!(project) end end @@ -311,6 +315,7 @@ module API attrs = declared_params(include_missing: false) attrs = translate_params_for_compatibility(attrs) + attrs = add_import_params(attrs) filter_attributes_using_license!(attrs) validate_git_import_url!(params[:import_url]) @@ -321,6 +326,8 @@ module API user_can_admin_project: can?(current_user, :admin_project, project), current_user: current_user else + forbidden! if project.errors[:import_source_disabled].present? + render_validation_error!(project) end end @@ -441,6 +448,7 @@ module API authorize! :change_visibility_level, user_project if user_project.visibility_attribute_present?(attrs) attrs = translate_params_for_compatibility(attrs) + attrs = add_import_params(attrs) filter_attributes_using_license!(attrs) verify_update_project_attrs!(user_project, attrs) diff --git a/locale/gitlab.pot b/locale/gitlab.pot index df3971a8f2c..db8d9650c97 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -5706,24 +5706,84 @@ msgstr "" msgid "Billing" msgstr "" -msgid "BillingPlans|%{group_name} is currently using the %{plan_name}." +msgid "BillingPlans|%{group_name} is currently using the %{plan_name}" +msgstr "" + +msgid "BillingPlans|10,000 CI/CD minutes per month" +msgstr "" + +msgid "BillingPlans|10GB transfer per month" +msgstr "" + +msgid "BillingPlans|400 CI/CD minutes per month" +msgstr "" + +msgid "BillingPlans|5 users per namespace" +msgstr "" + +msgid "BillingPlans|50,000 CI/CD minutes per month" +msgstr "" + +msgid "BillingPlans|5GB storage" msgstr "" msgid "BillingPlans|@%{user_name} you are currently using the %{plan_name}." msgstr "" +msgid "BillingPlans|Advanced CI/CD" +msgstr "" + +msgid "BillingPlans|All plans have unlimited (private) repositories." +msgstr "" + +msgid "BillingPlans|All the features from Free" +msgstr "" + +msgid "BillingPlans|All the features from Premium" +msgstr "" + +msgid "BillingPlans|Billed annually at %{price_per_year} USD" +msgstr "" + +msgid "BillingPlans|Check out all groups" +msgstr "" + +msgid "BillingPlans|Compliance" +msgstr "" + msgid "BillingPlans|Congratulations, your free trial is activated." msgstr "" msgid "BillingPlans|End of availability for the Bronze Plan" msgstr "" +msgid "BillingPlans|Enhance team productivity and collaboration" +msgstr "" + +msgid "BillingPlans|Enterprise agile planning" +msgstr "" + +msgid "BillingPlans|Faster code reviews" +msgstr "" + +msgid "BillingPlans|Free forever features for individual users" +msgstr "" + +msgid "BillingPlans|Free guest users" +msgstr "" + msgid "BillingPlans|Free upgrade!" msgstr "" msgid "BillingPlans|If you would like to downgrade your plan please contact %{support_link_start}Customer Support%{support_link_end}." msgstr "" +msgid "BillingPlans|Includes free static websites" +msgstr "" + +msgid "BillingPlans|Learn more" +msgstr "" + msgid "BillingPlans|Learn more about each plan by reading our %{faq_link}, or start a free 30-day trial of GitLab.com Ultimate." msgstr "" @@ -5733,21 +5793,78 @@ msgstr "" msgid "BillingPlans|Looking to purchase or manage a subscription for your group? Navigate to your %{groups_link} and go to %{strong_open}Settings > Billing.%{strong_close}" msgstr "" +msgid "BillingPlans|Loved and trusted by our customers" +msgstr "" + msgid "BillingPlans|Manage plan" msgstr "" +msgid "BillingPlans|Not the group you're looking for? %{all_groups_link}." +msgstr "" + +msgid "BillingPlans|Open Source - MIT License" +msgstr "" + +msgid "BillingPlans|Organization wide security, compliance and planning" +msgstr "" + +msgid "BillingPlans|Portfolio management" +msgstr "" + msgid "BillingPlans|Pricing page" msgstr "" +msgid "BillingPlans|Ready to explore the value of the paid features today? Start a trial, no credit card required." +msgstr "" + +msgid "BillingPlans|Recommended" +msgstr "" + +msgid "BillingPlans|Release controls" +msgstr "" + +msgid "BillingPlans|Security risk mitigation" +msgstr "" + msgid "BillingPlans|See all %{plan_name} features" msgstr "" +msgid "BillingPlans|Self-managed reliability" +msgstr "" + +msgid "BillingPlans|Spans the DevOps lifecycle" +msgstr "" + +msgid "BillingPlans|Start a free Ultimate trial" +msgstr "" + +msgid "BillingPlans|Still have questions?" +msgstr "" + +msgid "BillingPlans|Support" +msgstr "" + +msgid "BillingPlans|Talk to an expert today." +msgstr "" + msgid "BillingPlans|This group uses the plan associated with its parent group." msgstr "" msgid "BillingPlans|To manage the plan for this group, visit the billing section of %{parent_billing_page_link}." msgstr "" +msgid "BillingPlans|Upgrade to Premium" +msgstr "" + +msgid "BillingPlans|Upgrade to Ultimate" +msgstr "" + +msgid "BillingPlans|Value stream management" +msgstr "" + +msgid "BillingPlans|We're here to help." +msgstr "" + msgid "BillingPlans|While GitLab is ending availability of the Bronze plan, you can still renew your Bronze subscription one additional time before %{eoa_bronze_plan_end_date}. We are also offering a limited time free upgrade to our Premium Plan (up to 25 users)! Learn more about the changes and offers in our %{announcement_link}." msgstr "" @@ -5763,6 +5880,9 @@ msgstr "" msgid "BillingPlans|Your GitLab.com trial expired on %{expiration_date}. You can restore access to the features at any time by upgrading below." msgstr "" +msgid "BillingPlans|Your current plan" +msgstr "" + msgid "BillingPlans|billed annually at %{price_per_year}" msgstr "" @@ -5781,6 +5901,9 @@ msgstr "" msgid "BillingPlans|per user" msgstr "" +msgid "BillingPlans|per user/month" +msgstr "" + msgid "BillingPlan|Upgrade" msgstr "" @@ -19854,6 +19977,9 @@ msgstr "" msgid "InProductMarketing|Take your source code management to the next level" msgstr "" +msgid "InProductMarketing|Team members collaborating" +msgstr "" + msgid "InProductMarketing|Team up in GitLab for greater efficiency" msgstr "" diff --git a/qa/qa/runtime/env.rb b/qa/qa/runtime/env.rb index fbc3727d823..0db5314de4d 100644 --- a/qa/qa/runtime/env.rb +++ b/qa/qa/runtime/env.rb @@ -42,7 +42,7 @@ module QA end def interception_enabled? - enabled?(ENV['INTERCEPT_REQUESTS'], default: true) + enabled?(ENV['QA_INTERCEPT_REQUESTS'], default: false) end def can_intercept? diff --git a/spec/controllers/projects/prometheus/alerts_controller_spec.rb b/spec/controllers/projects/prometheus/alerts_controller_spec.rb index d66ad445c32..f42119e7811 100644 --- a/spec/controllers/projects/prometheus/alerts_controller_spec.rb +++ b/spec/controllers/projects/prometheus/alerts_controller_spec.rb @@ -226,137 +226,6 @@ RSpec.describe Projects::Prometheus::AlertsController do end end - describe 'POST #create' do - let(:schedule_update_service) { spy } - - let(:alert_params) do - { - 'title' => metric.title, - 'query' => metric.query, - 'operator' => '>', - 'threshold' => 1.0, - 'runbook_url' => 'https://sample.runbook.com' - } - end - - def make_request(opts = {}) - post :create, params: request_params( - opts, - operator: '>', - threshold: '1', - runbook_url: 'https://sample.runbook.com', - environment_id: environment, - prometheus_metric_id: metric - ) - end - - it 'creates a new prometheus alert' do - allow(::Clusters::Applications::ScheduleUpdateService) - .to receive(:new).and_return(schedule_update_service) - - make_request - - expect(schedule_update_service).to have_received(:execute) - expect(response).to have_gitlab_http_status(:ok) - expect(json_response).to include(alert_params) - end - - it 'returns bad_request for an invalid metric' do - make_request(prometheus_metric_id: 'invalid') - - expect(response).to have_gitlab_http_status(:bad_request) - end - - it_behaves_like 'unprivileged' - it_behaves_like 'project non-specific environment', :bad_request - end - - describe 'PUT #update' do - let(:schedule_update_service) { spy } - - let(:alert) do - create(:prometheus_alert, - project: project, - environment: environment, - prometheus_metric: metric) - end - - let(:alert_params) do - { - 'id' => alert.id, - 'title' => alert.title, - 'query' => alert.query, - 'operator' => '<', - 'threshold' => alert.threshold, - 'alert_path' => alert_path(alert) - } - end - - before do - allow(::Clusters::Applications::ScheduleUpdateService) - .to receive(:new).and_return(schedule_update_service) - end - - def make_request(opts = {}) - put :update, params: request_params( - opts, - id: alert.prometheus_metric_id, - operator: '<', - environment_id: alert.environment - ) - end - - it 'updates an already existing prometheus alert' do - expect { make_request(operator: '<') } - .to change { alert.reload.operator }.to('lt') - - expect(schedule_update_service).to have_received(:execute) - expect(response).to have_gitlab_http_status(:ok) - expect(json_response).to include(alert_params) - end - - it 'returns bad_request for an invalid alert data' do - make_request(runbook_url: 'bad-url') - - expect(response).to have_gitlab_http_status(:bad_request) - end - - it_behaves_like 'unprivileged' - it_behaves_like 'project non-specific environment', :not_found - it_behaves_like 'project non-specific metric', :not_found - end - - describe 'DELETE #destroy' do - let(:schedule_update_service) { spy } - - let!(:alert) do - create(:prometheus_alert, project: project, prometheus_metric: metric) - end - - before do - allow(::Clusters::Applications::ScheduleUpdateService) - .to receive(:new).and_return(schedule_update_service) - end - - def make_request(opts = {}) - delete :destroy, params: request_params( - opts, - id: alert.prometheus_metric_id, - environment_id: alert.environment - ) - end - - it 'destroys the specified prometheus alert' do - expect { make_request }.to change { PrometheusAlert.count }.by(-1) - - expect(schedule_update_service).to have_received(:execute) - end - - it_behaves_like 'unprivileged' - it_behaves_like 'project non-specific environment', :not_found - it_behaves_like 'project non-specific metric', :not_found - end - describe 'GET #metrics_dashboard' do let!(:alert) do create(:prometheus_alert, diff --git a/spec/fixtures/api/schemas/public_api/v4/environment.json b/spec/fixtures/api/schemas/public_api/v4/environment.json index 30104adaf5c..3a4c18343e3 100644 --- a/spec/fixtures/api/schemas/public_api/v4/environment.json +++ b/spec/fixtures/api/schemas/public_api/v4/environment.json @@ -4,6 +4,7 @@ "id", "name", "slug", + "tier", "external_url", "state", "created_at", @@ -13,6 +14,7 @@ "id": { "type": "integer" }, "name": { "type": "string" }, "slug": { "type": "string" }, + "tier": { "type": "string" }, "external_url": { "$ref": "../../types/nullable_string.json" }, "last_deployment": { "oneOf": [ diff --git a/spec/requests/api/environments_spec.rb b/spec/requests/api/environments_spec.rb index 5fb24dc91a4..6fafbb90bb4 100644 --- a/spec/requests/api/environments_spec.rb +++ b/spec/requests/api/environments_spec.rb @@ -23,6 +23,7 @@ RSpec.describe API::Environments do expect(json_response).to be_an Array expect(json_response.size).to eq(1) expect(json_response.first['name']).to eq(environment.name) + expect(json_response.first['tier']).to eq(environment.tier) expect(json_response.first['external_url']).to eq(environment.external_url) expect(json_response.first['project']).to match_schema('public_api/v4/project') expect(json_response.first['enable_advanced_logs_querying']).to eq(false) @@ -165,12 +166,13 @@ RSpec.describe API::Environments do describe 'POST /projects/:id/environments' do context 'as a member' do it 'creates a environment with valid params' do - post api("/projects/#{project.id}/environments", user), params: { name: "mepmep" } + post api("/projects/#{project.id}/environments", user), params: { name: "mepmep", tier: 'staging' } expect(response).to have_gitlab_http_status(:created) expect(response).to match_response_schema('public_api/v4/environment') expect(json_response['name']).to eq('mepmep') expect(json_response['slug']).to eq('mepmep') + expect(json_response['tier']).to eq('staging') expect(json_response['external']).to be nil end @@ -219,6 +221,15 @@ RSpec.describe API::Environments do expect(json_response['external_url']).to eq(url) end + it 'returns a 200 if tier is changed' do + put api("/projects/#{project.id}/environments/#{environment.id}", user), + params: { tier: 'production' } + + expect(response).to have_gitlab_http_status(:ok) + expect(response).to match_response_schema('public_api/v4/environment') + expect(json_response['tier']).to eq('production') + end + it "won't allow slug to be changed" do slug = environment.slug api_url = api("/projects/#{project.id}/environments/#{environment.id}", user) diff --git a/spec/requests/api/import_bitbucket_server_spec.rb b/spec/requests/api/import_bitbucket_server_spec.rb index 970416c7444..8ab41f49549 100644 --- a/spec/requests/api/import_bitbucket_server_spec.rb +++ b/spec/requests/api/import_bitbucket_server_spec.rb @@ -9,7 +9,15 @@ RSpec.describe API::ImportBitbucketServer do let(:secret) { "sekrettt" } let(:project_key) { 'TES' } let(:repo_slug) { 'vim' } - let(:repo) { { name: 'vim' } } + let(:repo) do + double('repo', + name: repo_slug, + browse_url: "#{base_uri}/projects/#{project_key}/repos/#{repo_slug}/browse", + clone_url: "#{base_uri}/scm/#{project_key}/#{repo_slug}.git", + description: 'provider', + visibility_level: Gitlab::VisibilityLevel::PUBLIC + ) + end describe "POST /import/bitbucket_server" do context 'with no optional parameters' do @@ -20,7 +28,7 @@ RSpec.describe API::ImportBitbucketServer do before do Grape::Endpoint.before_each do |endpoint| allow(endpoint).to receive(:client).and_return(client.as_null_object) - allow(client).to receive(:repo).with(project_key, repo_slug).and_return(double(name: repo_slug)) + allow(client).to receive(:repo).with(project_key, repo_slug).and_return(repo) end end diff --git a/spec/requests/api/import_github_spec.rb b/spec/requests/api/import_github_spec.rb index f0c4fcc4f29..7de72de3940 100644 --- a/spec/requests/api/import_github_spec.rb +++ b/spec/requests/api/import_github_spec.rb @@ -16,7 +16,11 @@ RSpec.describe API::ImportGithub do double('provider', name: 'vim', full_name: "#{provider_username}/vim", - owner: double('provider', login: provider_username) + owner: double('provider', login: provider_username), + description: 'provider', + private: false, + clone_url: 'https://fake.url/vim.git', + has_wiki?: true ) end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index 3af205bcd1d..5f623eda28a 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -1180,9 +1180,15 @@ RSpec.describe API::Projects do end it 'disallows creating a project with an import_url when git import source is disabled' do + url = 'http://example.com' stub_application_setting(import_sources: nil) - project_params = { import_url: 'http://example.com', path: 'path-project-Foo', name: 'Foo Project' } + endpoint_url = "#{url}/info/refs?service=git-upload-pack" + stub_full_request(endpoint_url, method: :get).to_return({ status: 200, + body: '001e# service=git-upload-pack', + headers: { 'Content-Type': 'application/x-git-upload-pack-advertisement' } }) + + project_params = { import_url: url, path: 'path-project-Foo', name: 'Foo Project' } expect { post api('/projects', user), params: project_params } .not_to change { Project.count } diff --git a/spec/services/import/bitbucket_server_service_spec.rb b/spec/services/import/bitbucket_server_service_spec.rb index 56d93625b91..0b9fe10e95a 100644 --- a/spec/services/import/bitbucket_server_service_spec.rb +++ b/spec/services/import/bitbucket_server_service_spec.rb @@ -48,6 +48,23 @@ RSpec.describe Import::BitbucketServerService do end end + context 'when import source is disabled' do + before do + stub_application_setting(import_sources: nil) + allow(subject).to receive(:authorized?).and_return(true) + allow(client).to receive(:repo).with(project_key, repo_slug).and_return(double(repo)) + end + + it 'returns forbidden' do + result = subject.execute(credentials) + + expect(result).to include( + status: :error, + http_status: :forbidden + ) + end + end + context 'when user is unauthorized' do before do allow(subject).to receive(:authorized?).and_return(false) diff --git a/spec/services/import/github_service_spec.rb b/spec/services/import/github_service_spec.rb index 58afae1e647..1c26677cfa5 100644 --- a/spec/services/import/github_service_spec.rb +++ b/spec/services/import/github_service_spec.rb @@ -111,6 +111,33 @@ RSpec.describe Import::GithubService do end end + context 'when import source is disabled' do + let(:repository_double) do + double({ + name: 'vim', + description: 'test', + full_name: 'test/vim', + clone_url: 'http://repo.com/repo/repo.git', + private: false, + has_wiki?: false + }) + end + + before do + stub_application_setting(import_sources: nil) + allow(client).to receive(:repository).and_return(repository_double) + end + + it 'returns forbidden' do + result = subject.execute(access_params, :github) + + expect(result).to include( + status: :error, + http_status: :forbidden + ) + end + end + context 'when a blocked/local URL is used as github_hostname' do let(:message) { 'Error while attempting to import from GitHub' } let(:error) { "Invalid URL: #{url}" } diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb index 26242ddaba0..556461e6e6d 100644 --- a/spec/services/projects/create_service_spec.rb +++ b/spec/services/projects/create_service_spec.rb @@ -768,6 +768,45 @@ RSpec.describe Projects::CreateService, '#execute' do create_project(user, opts) end + context 'when import source is enabled' do + before do + stub_application_setting(import_sources: ['github']) + end + + it 'does not raise an error when import_source is string' do + opts[:import_type] = 'github' + + project = create_project(user, opts) + + expect(project).to be_persisted + expect(project.errors).to be_blank + end + + it 'does not raise an error when import_source is symbol' do + opts[:import_type] = :github + + project = create_project(user, opts) + + expect(project).to be_persisted + expect(project.errors).to be_blank + end + end + + context 'when import source is disabled' do + before do + stub_application_setting(import_sources: []) + opts[:import_type] = 'git' + end + + it 'raises an error' do + project = create_project(user, opts) + + expect(project).to respond_to(:errors) + expect(project.errors).to have_key(:import_source_disabled) + expect(project.saved?).to be_falsey + end + end + context 'with external authorization enabled' do before do enable_external_authorization_service_check diff --git a/spec/services/projects/prometheus/alerts/create_service_spec.rb b/spec/services/projects/prometheus/alerts/create_service_spec.rb deleted file mode 100644 index 6b9d43e4e81..00000000000 --- a/spec/services/projects/prometheus/alerts/create_service_spec.rb +++ /dev/null @@ -1,52 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Projects::Prometheus::Alerts::CreateService do - let_it_be(:project) { create(:project) } - let_it_be(:user) { create(:user) } - - let(:service) { described_class.new(project: project, current_user: user, params: params) } - - subject { service.execute } - - describe '#execute' do - context 'with params' do - let_it_be(:environment) { create(:environment, project: project) } - - let_it_be(:metric) do - create(:prometheus_metric, project: project) - end - - let(:params) do - { - environment_id: environment.id, - prometheus_metric_id: metric.id, - operator: '<', - threshold: 1.0 - } - end - - it 'creates an alert' do - expect(subject).to be_persisted - - expect(subject).to have_attributes( - project: project, - environment: environment, - prometheus_metric: metric, - operator: 'lt', - threshold: 1.0 - ) - end - end - - context 'without params' do - let(:params) { {} } - - it 'fails to create' do - expect(subject).to be_new_record - expect(subject).to be_invalid - end - end - end -end diff --git a/spec/services/projects/prometheus/alerts/destroy_service_spec.rb b/spec/services/projects/prometheus/alerts/destroy_service_spec.rb deleted file mode 100644 index a3e9c3516c2..00000000000 --- a/spec/services/projects/prometheus/alerts/destroy_service_spec.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Projects::Prometheus::Alerts::DestroyService do - let_it_be(:project) { create(:project) } - let_it_be(:user) { create(:user) } - let_it_be(:alert) { create(:prometheus_alert, project: project) } - - let(:service) { described_class.new(project: project, current_user: user, params: nil) } - - describe '#execute' do - subject { service.execute(alert) } - - it 'deletes the alert' do - expect(subject).to be_truthy - - expect(alert).to be_destroyed - end - end -end diff --git a/spec/services/projects/prometheus/alerts/update_service_spec.rb b/spec/services/projects/prometheus/alerts/update_service_spec.rb deleted file mode 100644 index ec6766221f6..00000000000 --- a/spec/services/projects/prometheus/alerts/update_service_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Projects::Prometheus::Alerts::UpdateService do - let_it_be(:project) { create(:project) } - let_it_be(:user) { create(:user) } - let_it_be(:environment) { create(:environment, project: project) } - - let_it_be(:alert) do - create(:prometheus_alert, project: project, environment: environment) - end - - let(:service) { described_class.new(project: project, current_user: user, params: params) } - - let(:params) do - { - environment_id: alert.environment_id, - prometheus_metric_id: alert.prometheus_metric_id, - operator: '==', - threshold: 2.0 - } - end - - describe '#execute' do - subject { service.execute(alert) } - - context 'with valid params' do - it 'updates the alert' do - expect(subject).to be_truthy - - expect(alert.reload).to have_attributes( - operator: 'eq', - threshold: 2.0 - ) - end - end - - context 'with invalid params' do - let(:other_environment) { create(:environment) } - - before do - params[:environment_id] = other_environment.id - end - - it 'fails to update' do - expect(subject).to be_falsey - - expect(alert).to be_invalid - end - end - end -end