diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-30 06:10:03 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-30 06:10:03 +0000 |
commit | 27b43bd4d613cc7b8773ca0863b8d8f9b90f6d87 (patch) | |
tree | 8bc7959282786fd8acce856cfa75ad36fda5f020 | |
parent | 6b8e9712617b97b2586c90fe7855aa38e0987831 (diff) | |
download | gitlab-ce-27b43bd4d613cc7b8773ca0863b8d8f9b90f6d87.tar.gz |
Add latest changes from gitlab-org/gitlab@master
35 files changed, 510 insertions, 284 deletions
diff --git a/app/graphql/types/grafana_integration_type.rb b/app/graphql/types/grafana_integration_type.rb index c0582b266ab..7db733fc62a 100644 --- a/app/graphql/types/grafana_integration_type.rb +++ b/app/graphql/types/grafana_integration_type.rb @@ -9,7 +9,7 @@ module Types field :id, GraphQL::ID_TYPE, null: false, description: 'Internal ID of the Grafana integration' field :grafana_url, GraphQL::STRING_TYPE, null: false, - description: 'Url for the Grafana host for the Grafana integration' + description: 'URL for the Grafana host for the Grafana integration' field :enabled, GraphQL::BOOLEAN_TYPE, null: false, description: 'Indicates whether Grafana integration is enabled' field :created_at, Types::TimeType, null: false, diff --git a/app/models/jira_import_state.rb b/app/models/jira_import_state.rb index 71bb25470f5..92147794e88 100644 --- a/app/models/jira_import_state.rb +++ b/app/models/jira_import_state.rb @@ -3,6 +3,7 @@ class JiraImportState < ApplicationRecord include AfterCommitQueue include ImportState::SidekiqJobTracker + include UsageStatistics self.table_name = 'jira_imports' @@ -97,4 +98,8 @@ class JiraImportState < ApplicationRecord } ) end + + def self.finished_imports_count + finished.sum(:imported_issues_count) + end end diff --git a/app/models/project.rb b/app/models/project.rb index 6116cd76e37..502d3391d63 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -871,10 +871,12 @@ class Project < ApplicationRecord raise Projects::ImportService::Error, _('Jira import feature is disabled.') unless jira_issues_import_feature_flag_enabled? raise Projects::ImportService::Error, _('Jira integration not configured.') unless jira_service&.active? - return unless user + if user + raise Projects::ImportService::Error, _('Cannot import because issues are not available in this project.') unless feature_available?(:issues, user) + raise Projects::ImportService::Error, _('You do not have permissions to run the import.') unless user.can?(:admin_project, self) + end - raise Projects::ImportService::Error, _('Cannot import because issues are not available in this project.') unless feature_available?(:issues, user) - raise Projects::ImportService::Error, _('You do not have permissions to run the import.') unless user.can?(:admin_project, self) + raise Projects::ImportService::Error, _('Unable to connect to the Jira instance. Please check your Jira integration configuration.') unless jira_service.test(nil)[:success] end def human_import_status_name diff --git a/changelogs/unreleased/196862-drop-plan-id.yml b/changelogs/unreleased/196862-drop-plan-id.yml new file mode 100644 index 00000000000..e56ab11b117 --- /dev/null +++ b/changelogs/unreleased/196862-drop-plan-id.yml @@ -0,0 +1,5 @@ +--- +title: Remove namespaces.plan_id column +merge_request: 30351 +author: +type: other diff --git a/changelogs/unreleased/208920-jira-import-usage-data.yml b/changelogs/unreleased/208920-jira-import-usage-data.yml new file mode 100644 index 00000000000..b52c91da212 --- /dev/null +++ b/changelogs/unreleased/208920-jira-import-usage-data.yml @@ -0,0 +1,5 @@ +--- +title: Add jira imports to usage data +merge_request: 29925 +author: +type: added diff --git a/changelogs/unreleased/211984-jira-import-connection-test.yml b/changelogs/unreleased/211984-jira-import-connection-test.yml new file mode 100644 index 00000000000..f2a9c362456 --- /dev/null +++ b/changelogs/unreleased/211984-jira-import-connection-test.yml @@ -0,0 +1,5 @@ +--- +title: Test Jira connection before running import +merge_request: 29926 +author: +type: changed diff --git a/db/post_migrate/20200424043515_drop_namespaces_plan_id.rb b/db/post_migrate/20200424043515_drop_namespaces_plan_id.rb new file mode 100644 index 00000000000..53ce13cc699 --- /dev/null +++ b/db/post_migrate/20200424043515_drop_namespaces_plan_id.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +class DropNamespacesPlanId < ActiveRecord::Migration[6.0] + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + with_lock_retries do # rubocop: disable Migration/WithLockRetriesWithoutDdlTransaction + remove_column :namespaces, :plan_id + end + end + + def down + unless column_exists?(:namespaces, :plan_id) + with_lock_retries do # rubocop: disable Migration/WithLockRetriesWithoutDdlTransaction + add_column :namespaces, :plan_id, :integer + end + end + + add_concurrent_index :namespaces, :plan_id + add_concurrent_foreign_key :namespaces, :plans, column: :plan_id, on_delete: :nullify + end +end diff --git a/db/structure.sql b/db/structure.sql index cb7c96aeee8..c0a222b61df 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -4141,7 +4141,6 @@ CREATE TABLE public.namespaces ( require_two_factor_authentication boolean DEFAULT false NOT NULL, two_factor_grace_period integer DEFAULT 48 NOT NULL, cached_markdown_version integer, - plan_id integer, project_creation_level integer, runners_token character varying, trial_ends_on timestamp with time zone, @@ -9950,8 +9949,6 @@ CREATE INDEX index_namespaces_on_path ON public.namespaces USING btree (path); CREATE INDEX index_namespaces_on_path_trigram ON public.namespaces USING gin (path public.gin_trgm_ops); -CREATE INDEX index_namespaces_on_plan_id ON public.namespaces USING btree (plan_id); - CREATE UNIQUE INDEX index_namespaces_on_push_rule_id ON public.namespaces USING btree (push_rule_id); CREATE INDEX index_namespaces_on_require_two_factor_authentication ON public.namespaces USING btree (require_two_factor_authentication); @@ -11395,9 +11392,6 @@ ALTER TABLE ONLY public.system_note_metadata ALTER TABLE ONLY public.merge_requests ADD CONSTRAINT fk_fd82eae0b9 FOREIGN KEY (head_pipeline_id) REFERENCES public.ci_pipelines(id) ON DELETE SET NULL; -ALTER TABLE ONLY public.namespaces - ADD CONSTRAINT fk_fdd12e5b80 FOREIGN KEY (plan_id) REFERENCES public.plans(id) ON DELETE SET NULL; - ALTER TABLE ONLY public.project_import_data ADD CONSTRAINT fk_ffb9ee3a10 FOREIGN KEY (project_id) REFERENCES public.projects(id) ON DELETE CASCADE; @@ -13629,6 +13623,7 @@ COPY "schema_migrations" (version) FROM STDIN; 20200423081441 20200423081519 20200423101529 +20200424043515 20200424050250 20200424101920 20200427064130 diff --git a/doc/.vale/gitlab/ReferenceLinks.yml b/doc/.vale/gitlab/ReferenceLinks.yml new file mode 100644 index 00000000000..35a657710de --- /dev/null +++ b/doc/.vale/gitlab/ReferenceLinks.yml @@ -0,0 +1,10 @@ +# Checks for the presence of reference-style links that must be inline. +# +# For a list of all options, see https://errata-ai.github.io/vale/styles/ +extends: existence +message: 'Link "%s" must be inline.' +link: https://docs.gitlab.com/ee/development/documentation/styleguide.html#basic-link-criteria +level: error +scope: raw +raw: + - '\n\[.*\]: .*' diff --git a/doc/administration/feature_flags.md b/doc/administration/feature_flags.md index bda488b903f..59cd5497032 100644 --- a/doc/administration/feature_flags.md +++ b/doc/administration/feature_flags.md @@ -29,14 +29,10 @@ them. It can be done by GitLab administrators with access to GitLab Rails console. If you used a certain feature and identified a bug, a misbehavior, or an -error, it's very important that you **[provide feedback]** to GitLab as soon +error, it's very important that you [**provide feedback**](https://gitlab.com/gitlab-org/gitlab/issues/new?issue[title]=Docs%20-%20feature%20flag%20feedback%3A%20Feature%20Name&issue[description]=Describe%20the%20problem%20you%27ve%20encountered.%0A%0A%3C!--%20Don%27t%20edit%20below%20this%20line%20--%3E%0A%0A%2Flabel%20~%22docs%5C-comments%22%20) to GitLab as soon as possible so we can improve or fix it while behind a flag. When you upgrade GitLab to an earlier version, the feature flag status may change. -[provide feedback]: https://gitlab.com/gitlab-org/gitlab/issues/new?issue[title]=Docs%20-%20feature%20flag%20feedback%3A%20Feature%20Name&issue[description]=Describe%20the%20problem%20you%27ve%20encountered.%0A%0A%3C!--%20Don%27t%20edit%20below%20this%20line%20--%3E%0A%0A%2Flabel%20~%22docs%5C-comments%22%20 - -<!-- Note: the link identifier above was used to facilitate review and update. --> - NOTE: **Note:** Mind that features deployed behind feature flags may not be ready for production use. However, disabling features behind flags that were deployed diff --git a/doc/administration/geo/replication/troubleshooting.md b/doc/administration/geo/replication/troubleshooting.md index 87dcb7e83b8..c19b0f775ce 100644 --- a/doc/administration/geo/replication/troubleshooting.md +++ b/doc/administration/geo/replication/troubleshooting.md @@ -497,6 +497,12 @@ to start again from scratch, there are a few steps that can help you: gitlab-ctl start ``` +1. Refresh Foreign Data Wrapper tables + + ```sh + gitlab-rake geo:db:refresh_foreign_tables + ``` + ## Fixing errors during a failover or when promoting a secondary to a primary node The following are possible errors that might be encountered during failover or diff --git a/doc/administration/scaling/index.md b/doc/administration/scaling/index.md index 2817ce36f0a..23dadca7a9f 100644 --- a/doc/administration/scaling/index.md +++ b/doc/administration/scaling/index.md @@ -58,11 +58,11 @@ On different cloud vendors a best effort like for like can be used. From 1 to 1,000 users, a single-node [Omnibus](https://docs.gitlab.com/omnibus/) setup with frequent backups is adequate. Please refer to the [installation documentation](../../install/README.md) and [backup/restore documentation](https://docs.gitlab.com/omnibus/settings/backups.html#backup-and-restore-omnibus-gitlab-configuration). -| Users | Configuration[^8] | GCP type | AWS type[^9] | -|-------|----------------------|---------------|--------------| -| 100 | 2 vCPU, 7.2GB Memory | n1-standard-2 | c5.2xlarge | -| 500 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | -| 1000 | 8 vCPU, 30GB Memory | n1-standard-8 | m5.2xlarge | +| Users | Configuration([8](#footnotes)) | GCP type | AWS type([9](#footnotes)) | +|-------|--------------------------------|---------------|---------------------------| +| 100 | 2 vCPU, 7.2GB Memory | n1-standard-2 | c5.2xlarge | +| 500 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | +| 1000 | 8 vCPU, 30GB Memory | n1-standard-8 | m5.2xlarge | This solution is appropriate for many teams that have a single server at their disposal. With automatic backup of the GitLab repositories, configuration, and the database, this can be an optimal solution if you don't have strict availability requirements. @@ -86,20 +86,20 @@ this alternative in mind is [being worked on](https://gitlab.com/gitlab-org/qual - **Test RPS rates:** API: 40 RPS, Web: 4 RPS, Git: 4 RPS - **Known issues:** [List of known performance issues](https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=Quality%3Aperformance-issues) -| Service | Nodes | Configuration[^8] | GCP type | AWS type[^9] | -| ----------------------------|-------|-----------------------|---------------|--------------| -| GitLab Rails[^1] | 3 | 8 vCPU, 7.2GB Memory | n1-highcpu-8 | c5.2xlarge | -| PostgreSQL | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | -| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Gitaly[^2] [^5] [^7] | X | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | -| Redis[^3] | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | -| Consul + Sentinel[^3] | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Sidekiq | 4 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | -| Cloud Object Storage[^4] | - | - | - | - | -| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | -| Monitoring node | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Internal load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Service | Nodes | Configuration ([8](#footnotes)) | GCP type | AWS type ([9](#footnotes)) | +|--------------------------------------------------------------|-------|---------------------------------|---------------|----------------------------| +| GitLab Rails ([1](#footnotes)) | 3 | 8 vCPU, 7.2GB Memory | n1-highcpu-8 | c5.2xlarge | +| PostgreSQL | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | +| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Gitaly ([2](#footnotes)) ([5](#footnotes)) ([7](#footnotes)) | X | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | +| Redis ([3](#footnotes)) | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | +| Consul + Sentinel ([3](#footnotes)) | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Sidekiq | 4 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | +| Cloud Object Storage ([4](#footnotes)) | - | - | - | - | +| NFS Server ([5](#footnotes)) ([7](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | +| Monitoring node | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| External load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Internal load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | ### Up to 5,000 users @@ -107,20 +107,20 @@ this alternative in mind is [being worked on](https://gitlab.com/gitlab-org/qual - **Test RPS rates:** API: 100 RPS, Web: 10 RPS, Git: 10 RPS - **Known issues:** [List of known performance issues](https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=Quality%3Aperformance-issues) -| Service | Nodes | Configuration[^8] | GCP type | AWS type[^9] | -| ----------------------------|-------|------------------------|---------------|--------------| -| GitLab Rails[^1] | 3 | 16 vCPU, 14.4GB Memory | n1-highcpu-16 | c5.4xlarge | -| PostgreSQL | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | -| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Gitaly[^2] [^5] [^7] | X | 8 vCPU, 30GB Memory | n1-standard-8 | m5.2xlarge | -| Redis[^3] | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | -| Consul + Sentinel[^3] | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Sidekiq | 4 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | -| Cloud Object Storage[^4] | - | - | - | - | -| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | -| Monitoring node | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Internal load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Service | Nodes | Configuration ([8](#footnotes)) | GCP type | AWS type ([9](#footnotes)) | +|--------------------------------------------------------------|-------|---------------------------------|---------------|----------------------------| +| GitLab Rails ([1](#footnotes)) | 3 | 16 vCPU, 14.4GB Memory | n1-highcpu-16 | c5.4xlarge | +| PostgreSQL | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | +| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Gitaly ([2](#footnotes)) ([5](#footnotes)) ([7](#footnotes)) | X | 8 vCPU, 30GB Memory | n1-standard-8 | m5.2xlarge | +| Redis ([3](#footnotes)) | 3 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | +| Consul + Sentinel ([3](#footnotes)) | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Sidekiq | 4 | 2 vCPU, 7.5GB Memory | n1-standard-2 | m5.large | +| Cloud Object Storage ([4](#footnotes)) | - | - | - | - | +| NFS Server ([5](#footnotes)) ([7](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | +| Monitoring node | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| External load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Internal load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | ### Up to 10,000 users @@ -128,23 +128,23 @@ this alternative in mind is [being worked on](https://gitlab.com/gitlab-org/qual - **Test RPS rates:** API: 200 RPS, Web: 20 RPS, Git: 20 RPS - **Known issues:** [List of known performance issues](https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=Quality%3Aperformance-issues) -| Service | Nodes | GCP Configuration[^8] | GCP type | AWS type[^9] | -| ----------------------------|-------|------------------------|----------------|--------------| -| GitLab Rails[^1] | 3 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge | -| PostgreSQL | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | -| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Gitaly[^2] [^5] [^7] | X | 16 vCPU, 60GB Memory | n1-standard-16 | m5.4xlarge | -| Redis[^3] - Cache | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | -| Redis[^3] - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | -| Redis Sentinel[^3] - Cache | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | -| Redis Sentinel[^3] - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | -| Consul | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Sidekiq | 4 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | -| Cloud Object Storage[^4] | - | - | - | - | -| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | -| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | -| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Internal load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Service | Nodes | GCP Configuration ([8](#footnotes)) | GCP type | AWS type ([9](#footnotes)) | +|--------------------------------------------------------------|-------|-------------------------------------|----------------|----------------------------| +| GitLab Rails ([1](#footnotes)) | 3 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge | +| PostgreSQL | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | +| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Gitaly ([2](#footnotes)) ([5](#footnotes)) ([7](#footnotes)) | X | 16 vCPU, 60GB Memory | n1-standard-16 | m5.4xlarge | +| Redis ([3](#footnotes)) - Cache | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | +| Redis ([3](#footnotes)) - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | +| Redis Sentinel ([3](#footnotes)) - Cache | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | +| Redis Sentinel ([3](#footnotes)) - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | +| Consul | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Sidekiq | 4 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | +| Cloud Object Storage ([4](#footnotes)) | - | - | - | - | +| NFS Server ([5](#footnotes)) ([7](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | +| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | +| External load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Internal load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | ### Up to 25,000 users @@ -152,23 +152,23 @@ this alternative in mind is [being worked on](https://gitlab.com/gitlab-org/qual - **Test RPS rates:** API: 500 RPS, Web: 50 RPS, Git: 50 RPS - **Known issues:** [List of known performance issues](https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=Quality%3Aperformance-issues) -| Service | Nodes | Configuration[^8] | GCP type | AWS type[^9] | -| ----------------------------|-------|------------------------|----------------|--------------| -| GitLab Rails[^1] | 5 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge | -| PostgreSQL | 3 | 8 vCPU, 30GB Memory | n1-standard-8 | m5.2xlarge | -| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Gitaly[^2] [^5] [^7] | X | 32 vCPU, 120GB Memory | n1-standard-32 | m5.8xlarge | -| Redis[^3] - Cache | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | -| Redis[^3] - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | -| Redis Sentinel[^3] - Cache | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | -| Redis Sentinel[^3] - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | -| Consul | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Sidekiq | 4 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | -| Cloud Object Storage[^4] | - | - | - | - | -| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | -| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | -| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Internal load balancing node[^6] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | +| Service | Nodes | Configuration ([8](#footnotes)) | GCP type | AWS type ([9](#footnotes)) | +|--------------------------------------------------------------|-------|---------------------------------|----------------|----------------------------| +| GitLab Rails ([1](#footnotes)) | 5 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge | +| PostgreSQL | 3 | 8 vCPU, 30GB Memory | n1-standard-8 | m5.2xlarge | +| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Gitaly ([2](#footnotes)) ([5](#footnotes)) ([7](#footnotes)) | X | 32 vCPU, 120GB Memory | n1-standard-32 | m5.8xlarge | +| Redis ([3](#footnotes)) - Cache | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | +| Redis ([3](#footnotes)) - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | +| Redis Sentinel ([3](#footnotes)) - Cache | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | +| Redis Sentinel ([3](#footnotes)) - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | +| Consul | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Sidekiq | 4 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | +| Cloud Object Storage ([4](#footnotes)) | - | - | - | - | +| NFS Server ([5](#footnotes)) ([7](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | +| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | +| External load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Internal load balancing node ([6](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | ### Up to 50,000 users @@ -176,23 +176,23 @@ this alternative in mind is [being worked on](https://gitlab.com/gitlab-org/qual - **Test RPS rates:** API: 1000 RPS, Web: 100 RPS, Git: 100 RPS - **Known issues:** [List of known performance issues](https://gitlab.com/gitlab-org/gitlab/issues?label_name%5B%5D=Quality%3Aperformance-issues) -| Service | Nodes | Configuration[^8] | GCP type | AWS type[^9] | -| ----------------------------|-------|------------------------|----------------|--------------| -| GitLab Rails[^1] | 12 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge | -| PostgreSQL | 3 | 16 vCPU, 60GB Memory | n1-standard-16 | m5.4xlarge | -| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Gitaly[^2] [^5] [^7] | X | 64 vCPU, 240GB Memory | n1-standard-64 | m5.16xlarge | -| Redis[^3] - Cache | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | -| Redis[^3] - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | -| Redis Sentinel[^3] - Cache | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | -| Redis Sentinel[^3] - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | -| Consul | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Sidekiq | 4 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | -| NFS Server[^5] [^7] | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | -| Cloud Object Storage[^4] | - | - | - | - | -| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | -| External load balancing node[^6] | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | -| Internal load balancing node[^6] | 1 | 8 vCPU, 7.2GB Memory | n1-highcpu-8 | c5.2xlarge | +| Service | Nodes | Configuration ([8](#footnotes)) | GCP type | AWS type ([9](#footnotes)) | +|--------------------------------------------------------------|-------|---------------------------------|----------------|----------------------------| +| GitLab Rails ([1](#footnotes)) | 12 | 32 vCPU, 28.8GB Memory | n1-highcpu-32 | c5.9xlarge | +| PostgreSQL | 3 | 16 vCPU, 60GB Memory | n1-standard-16 | m5.4xlarge | +| PgBouncer | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Gitaly ([2](#footnotes)) ([5](#footnotes)) ([7](#footnotes)) | X | 64 vCPU, 240GB Memory | n1-standard-64 | m5.16xlarge | +| Redis ([3](#footnotes)) - Cache | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | +| Redis ([3](#footnotes)) - Queues / Shared State | 3 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | +| Redis Sentinel ([3](#footnotes)) - Cache | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | +| Redis Sentinel ([3](#footnotes)) - Queues / Shared State | 3 | 1 vCPU, 1.7GB Memory | g1-small | t2.small | +| Consul | 3 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Sidekiq | 4 | 4 vCPU, 15GB Memory | n1-standard-4 | m5.xlarge | +| NFS Server ([5](#footnotes)) ([7](#footnotes)) | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | +| Cloud Object Storage ([4](#footnotes)) | - | - | - | - | +| Monitoring node | 1 | 4 vCPU, 3.6GB Memory | n1-highcpu-4 | c5.xlarge | +| External load balancing node ([6](#footnotes)) | 1 | 2 vCPU, 1.8GB Memory | n1-highcpu-2 | c5.large | +| Internal load balancing node ([6](#footnotes)) | 1 | 8 vCPU, 7.2GB Memory | n1-highcpu-8 | c5.2xlarge | ## Configuring GitLab to scale @@ -206,9 +206,9 @@ listed below. | Component | Description | Configuration instructions | |-----------|-------------|----------------------------| -| Load balancer(s)[^6] | Handles load balancing, typically when you have multiple GitLab application services nodes | [Load balancer configuration](../high_availability/load_balancer.md)[^6] | -| Object storage service[^4] | Recommended store for shared data objects | [Cloud Object Storage configuration](../object_storage.md) | -| NFS[^5] [^7] | Shared disk storage service. Can be used as an alternative for Gitaly or Object Storage. Required for GitLab Pages | [NFS configuration](../high_availability/nfs.md) | +| Load balancer(s) ([6](#footnotes)) | Handles load balancing, typically when you have multiple GitLab application services nodes | [Load balancer configuration](../high_availability/load_balancer.md) ([6](#footnotes)) | +| Object storage service ([4](#footnotes)) | Recommended store for shared data objects | [Cloud Object Storage configuration](../object_storage.md) | +| NFS ([5](#footnotes)) ([7](#footnotes)) | Shared disk storage service. Can be used as an alternative for Gitaly or Object Storage. Required for GitLab Pages | [NFS configuration](../high_availability/nfs.md) | ### Components provided by Omnibus GitLab @@ -218,61 +218,61 @@ order you'll typically configure them if they are required by your | Component | Description | Configuration instructions | |-----------|-------------|----------------------------| -| [Consul](../../development/architecture.md#consul)[^3] | Service discovery and health checks/failover | [Consul HA configuration](../high_availability/consul.md) **(PREMIUM ONLY)** | +| [Consul](../../development/architecture.md#consul) ([3](#footnotes)) | Service discovery and health checks/failover | [Consul HA configuration](../high_availability/consul.md) **(PREMIUM ONLY)** | | [PostgreSQL](../../development/architecture.md#postgresql) | Database | [PostgreSQL configuration](https://docs.gitlab.com/omnibus/settings/database.html) | | [PgBouncer](../../development/architecture.md#pgbouncer) | Database connection pooler | [PgBouncer configuration](../high_availability/pgbouncer.md#running-pgbouncer-as-part-of-a-non-ha-gitlab-installation) **(PREMIUM ONLY)** | | Repmgr | PostgreSQL cluster management and failover | [PostgreSQL and Repmgr configuration](../high_availability/database.md) | -| [Redis](../../development/architecture.md#redis)[^3] | Key/value store for fast data lookup and caching | [Redis configuration](../high_availability/redis.md) | +| [Redis](../../development/architecture.md#redis) ([3](#footnotes)) | Key/value store for fast data lookup and caching | [Redis configuration](../high_availability/redis.md) | | Redis Sentinel | High availability for Redis | [Redis Sentinel configuration](../high_availability/redis.md) | -| [Gitaly](../../development/architecture.md#gitaly)[^2] [^5] [^7] | Provides access to Git repositories | [Gitaly configuration](../gitaly/index.md#running-gitaly-on-its-own-server) | +| [Gitaly](../../development/architecture.md#gitaly) ([2](#footnotes)) ([5](#footnotes)) ([7](#footnotes)) | Provides access to Git repositories | [Gitaly configuration](../gitaly/index.md#running-gitaly-on-its-own-server) | | [Sidekiq](../../development/architecture.md#sidekiq) | Asynchronous/background jobs | [Sidekiq configuration](../high_availability/sidekiq.md) | -| [GitLab application services](../../development/architecture.md#unicorn)[^1] | Unicorn/Puma, Workhorse, GitLab Shell - serves front-end requests (UI, API, Git over HTTP/SSH) | [GitLab app scaling configuration](../high_availability/gitlab.md) | +| [GitLab application services](../../development/architecture.md#unicorn)([1](#footnotes)) | Unicorn/Puma, Workhorse, GitLab Shell - serves front-end requests (UI, API, Git over HTTP/SSH) | [GitLab app scaling configuration](../high_availability/gitlab.md) | | [Prometheus](../../development/architecture.md#prometheus) and [Grafana](../../development/architecture.md#grafana) | GitLab environment monitoring | [Monitoring node for scaling](../high_availability/monitoring_node.md) | ## Footnotes -[^1]: In our architectures we run each GitLab Rails node using the Puma webserver - and have its number of workers set to 90% of available CPUs along with 4 threads. - -[^2]: Gitaly node requirements are dependent on customer data, specifically the number of - projects and their sizes. We recommend 2 nodes as an absolute minimum for HA environments - and at least 4 nodes should be used when supporting 50,000 or more users. - We also recommend that each Gitaly node should store no more than 5TB of data - and have the number of [`gitaly-ruby` workers](../gitaly/index.md#gitaly-ruby) - set to 20% of available CPUs. Additional nodes should be considered in conjunction - with a review of expected data size and spread based on the recommendations above. - -[^3]: Recommended Redis setup differs depending on the size of the architecture. - For smaller architectures (up to 5,000 users) we suggest one Redis cluster for all - classes and that Redis Sentinel is hosted alongside Consul. - For larger architectures (10,000 users or more) we suggest running a separate - [Redis Cluster](../high_availability/redis.md#running-multiple-redis-clusters) for the Cache class - and another for the Queues and Shared State classes respectively. We also recommend - that you run the Redis Sentinel clusters separately as well for each Redis Cluster. - -[^4]: For data objects such as LFS, Uploads, Artifacts, etc. We recommend a [Cloud Object Storage service](../object_storage.md) - over NFS where possible, due to better performance and availability. - -[^5]: NFS can be used as an alternative for both repository data (replacing Gitaly) and - object storage but this isn't typically recommended for performance reasons. Note however it is required for - [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/issues/196). - -[^6]: Our architectures have been tested and validated with [HAProxy](https://www.haproxy.org/) - as the load balancer. However other reputable load balancers with similar feature sets - should also work instead but be aware these aren't validated. - -[^7]: We strongly recommend that any Gitaly and / or NFS nodes are set up with SSD disks over - HDD with a throughput of at least 8,000 IOPS for read operations and 2,000 IOPS for write - as these components have heavy I/O. These IOPS values are recommended only as a starter - as with time they may be adjusted higher or lower depending on the scale of your - environment's workload. If you're running the environment on a Cloud provider - you may need to refer to their documentation on how configure IOPS correctly. - -[^8]: The architectures were built and tested with the [Intel Xeon E5 v3 (Haswell)](https://cloud.google.com/compute/docs/cpu-platforms) - CPU platform on GCP. On different hardware you may find that adjustments, either lower - or higher, are required for your CPU or Node counts accordingly. For more information, a - [Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found - [here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks). - -[^9]: AWS-equivalent configurations are rough suggestions and may change in the - future. They have not yet been tested and validated. +1. In our architectures we run each GitLab Rails node using the Puma webserver + and have its number of workers set to 90% of available CPUs along with 4 threads. + +1. Gitaly node requirements are dependent on customer data, specifically the number of + projects and their sizes. We recommend 2 nodes as an absolute minimum for HA environments + and at least 4 nodes should be used when supporting 50,000 or more users. + We also recommend that each Gitaly node should store no more than 5TB of data + and have the number of [`gitaly-ruby` workers](../gitaly/index.md#gitaly-ruby) + set to 20% of available CPUs. Additional nodes should be considered in conjunction + with a review of expected data size and spread based on the recommendations above. + +1. Recommended Redis setup differs depending on the size of the architecture. + For smaller architectures (up to 5,000 users) we suggest one Redis cluster for all + classes and that Redis Sentinel is hosted alongside Consul. + For larger architectures (10,000 users or more) we suggest running a separate + [Redis Cluster](../high_availability/redis.md#running-multiple-redis-clusters) for the Cache class + and another for the Queues and Shared State classes respectively. We also recommend + that you run the Redis Sentinel clusters separately as well for each Redis Cluster. + +1. For data objects such as LFS, Uploads, Artifacts, etc. We recommend a [Cloud Object Storage service](../object_storage.md) + over NFS where possible, due to better performance and availability. + +1. NFS can be used as an alternative for both repository data (replacing Gitaly) and + object storage but this isn't typically recommended for performance reasons. Note however it is required for + [GitLab Pages](https://gitlab.com/gitlab-org/gitlab-pages/issues/196). + +1. Our architectures have been tested and validated with [HAProxy](https://www.haproxy.org/) + as the load balancer. However other reputable load balancers with similar feature sets + should also work instead but be aware these aren't validated. + +1. We strongly recommend that any Gitaly and / or NFS nodes are set up with SSD disks over + HDD with a throughput of at least 8,000 IOPS for read operations and 2,000 IOPS for write + as these components have heavy I/O. These IOPS values are recommended only as a starter + as with time they may be adjusted higher or lower depending on the scale of your + environment's workload. If you're running the environment on a Cloud provider + you may need to refer to their documentation on how configure IOPS correctly. + +1. The architectures were built and tested with the [Intel Xeon E5 v3 (Haswell)](https://cloud.google.com/compute/docs/cpu-platforms) + CPU platform on GCP. On different hardware you may find that adjustments, either lower + or higher, are required for your CPU or Node counts accordingly. For more information, a + [Sysbench](https://github.com/akopytov/sysbench) benchmark of the CPU can be found + [here](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Reference-Architectures/GCP-CPU-Benchmarks). + +1. AWS-equivalent configurations are rough suggestions and may change in the + future. They have not yet been tested and validated. diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql index 245fcd300df..72dc13c51ae 100644 --- a/doc/api/graphql/reference/gitlab_schema.graphql +++ b/doc/api/graphql/reference/gitlab_schema.graphql @@ -3553,7 +3553,7 @@ type GrafanaIntegration { enabled: Boolean! """ - Url for the Grafana host for the Grafana integration + URL for the Grafana host for the Grafana integration """ grafanaUrl: String! diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json index 84a6de1cf2a..2a99cf388b2 100644 --- a/doc/api/graphql/reference/gitlab_schema.json +++ b/doc/api/graphql/reference/gitlab_schema.json @@ -10207,7 +10207,7 @@ }, { "name": "grafanaUrl", - "description": "Url for the Grafana host for the Grafana integration", + "description": "URL for the Grafana host for the Grafana integration", "args": [ ], diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 313795141a1..4bf97ede2ed 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -577,7 +577,7 @@ Autogenerated return type of EpicTreeReorder | --- | ---- | ---------- | | `createdAt` | Time! | Timestamp of the issue's creation | | `enabled` | Boolean! | Indicates whether Grafana integration is enabled | -| `grafanaUrl` | String! | Url for the Grafana host for the Grafana integration | +| `grafanaUrl` | String! | URL for the Grafana host for the Grafana integration | | `id` | ID! | Internal ID of the Grafana integration | | `token` **{warning-solid}** | String! | **Deprecated:** Plain text token has been masked for security reasons. Deprecated in 12.7 | | `updatedAt` | Time! | Timestamp of the issue's last activity | diff --git a/doc/api/repositories.md b/doc/api/repositories.md index f261c9ab9f7..440db06792c 100644 --- a/doc/api/repositories.md +++ b/doc/api/repositories.md @@ -107,6 +107,8 @@ Parameters: Get an archive of the repository. This endpoint can be accessed without authentication if the repository is publicly accessible. +This endpoint has a rate limit threshold of 5 requests per minute. + ```plaintext GET /projects/:id/repository/archive[.format] ``` diff --git a/doc/ci/yaml/README.md b/doc/ci/yaml/README.md index 2fb926540c6..1d1c8a76feb 100644 --- a/doc/ci/yaml/README.md +++ b/doc/ci/yaml/README.md @@ -2924,6 +2924,8 @@ Possible values for `when` are: - `scheduler_failure`: Retry if the scheduler failed to assign the job to a runner. - `data_integrity_failure`: Retry if there was a structural integrity problem detected. +You can specify the number of [retry attempts for certain stages of job execution](#job-stages-attempts) using variables. + ### `timeout` > [Introduced](https://gitlab.com/gitlab-org/gitlab/issues/14887) in GitLab 12.3. diff --git a/doc/development/documentation/index.md b/doc/development/documentation/index.md index 92044d3f942..2724958314c 100644 --- a/doc/development/documentation/index.md +++ b/doc/development/documentation/index.md @@ -171,8 +171,8 @@ Before getting started, make sure you read the introductory section [documentation workflow](workflow.md). - Use the current [merge request description template](https://gitlab.com/gitlab-org/gitlab/blob/master/.gitlab/merge_request_templates/Documentation.md) -- Label the MR `Documentation` -- Assign the correct milestone (see note below) +- Label the MR `Documentation` (can only be done by people with `developer` access, for example, GitLab team members) +- Assign the correct milestone per note below (can only be done by people with `developer` access, for example, GitLab team members) Documentation will be merged if it is an improvement on existing content, represents a good-faith effort to follow the template and style standards, diff --git a/doc/development/fe_guide/graphql.md b/doc/development/fe_guide/graphql.md index 353778980f4..e839f6bacd3 100644 --- a/doc/development/fe_guide/graphql.md +++ b/doc/development/fe_guide/graphql.md @@ -298,7 +298,8 @@ handleClick() { GitLab's GraphQL API uses [Relay-style cursor pagination](https://www.apollographql.com/docs/react/data/pagination/#cursor-based) for connection types. This means a "cursor" is used to keep track of where in the data -set the next items should be fetched from. +set the next items should be fetched from. [GraphQL Ruby Connection Concepts](https://graphql-ruby.org/pagination/connection_concepts.html) +is a good overview and introduction to connections. Every connection type (for example, `DesignConnection` and `DiscussionConnection`) has a field `pageInfo` that contains an information required for pagination: diff --git a/doc/user/clusters/applications.md b/doc/user/clusters/applications.md index d1f49d6ea1f..69d057ad673 100644 --- a/doc/user/clusters/applications.md +++ b/doc/user/clusters/applications.md @@ -1024,11 +1024,11 @@ In addition, the following variables must be specified using [CI variables](../. | CI Variable | Description | |:---------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `JUPYTERHUB_PROXY_SECRET_TOKEN` | Sets [`proxy.secretToken`](https://zero-to-jupyterhub.readthedocs.io/en/stable/reference.html#proxy-secrettoken). Generate using `openssl rand -hex 32`. | -| `JUPYTERHUB_COOKIE_SECRET` | Sets [`hub.cookieSecret`](https://zero-to-jupyterhub.readthedocs.io/en/stable/reference.html#hub-cookiesecret). Generate using `openssl rand -hex 32`. | +| `JUPYTERHUB_PROXY_SECRET_TOKEN` | Secure string used for signing communications from the hub. See[`proxy.secretToken`](https://zero-to-jupyterhub.readthedocs.io/en/stable/reference/reference.html#proxy-secrettoken). | +| `JUPYTERHUB_COOKIE_SECRET` | Secure string used for signing secure cookies. See [`hub.cookieSecret`](https://zero-to-jupyterhub.readthedocs.io/en/stable/reference/reference.html#hub-cookiesecret). | | `JUPYTERHUB_HOST` | Hostname used for the installation. For example, `jupyter.gitlab.example.com`. | | `JUPYTERHUB_GITLAB_HOST` | Hostname of the GitLab instance used for authentication. For example, `gitlab.example.com`. | -| `JUPYTERHUB_AUTH_CRYPTO_KEY` | Sets [`auth.state.cryptoKey`](https://zero-to-jupyterhub.readthedocs.io/en/stable/reference.html#auth-state-cryptokey). Generate using `openssl rand -hex 32`. | +| `JUPYTERHUB_AUTH_CRYPTO_KEY` | A 32-byte encryption key used to set [`auth.state.cryptoKey`](https://zero-to-jupyterhub.readthedocs.io/en/stable/reference/reference.html#auth-state-cryptokey). | | `JUPYTERHUB_AUTH_GITLAB_CLIENT_ID` | "Application ID" for the OAuth Application. | | `JUPYTERHUB_AUTH_GITLAB_CLIENT_SECRET` | "Secret" for the OAuth Application. | diff --git a/doc/user/markdown.md b/doc/user/markdown.md index a1f83a47015..e7c75c7b8cd 100644 --- a/doc/user/markdown.md +++ b/doc/user/markdown.md @@ -828,23 +828,31 @@ Reference tags can use letters and other characters. Avoid using lowercase `w` o (`_`) in footnote tag names until [this bug](https://gitlab.com/gitlab-org/gitlab/issues/24423) is resolved. -```markdown -A footnote reference tag looks like this: [^1] +<!-- +Do not edit the following codeblock. It uses HTML to skip the Vale ReferenceLinks test. +--> + +<pre class="highlight"><code>A footnote reference tag looks like this: [^1] This reference tag is a mix of letters and numbers. [^footnote-42] -[^1]: This is the text inside a footnote. +[^1]: This is the text inside a footnote. -[^footnote-42]: This is another footnote. -``` +[^footnote-42]: This is another footnote. +</code></pre> A footnote reference tag looks like this:[^1] This reference tag is a mix of letters and numbers.[^footnote-42] -[^1]: This is the text inside a footnote. +<!-- +Do not delete the single space before the [^1] and [^footnotes] references below. +These are used to force the Vale ReferenceLinks check to skip these examples. +--> + + [^1]: This is the text inside a footnote. -[^footnote-42]: This is another footnote. + [^footnote-42]: This is another footnote. ### Headers @@ -928,8 +936,11 @@ ___ Examples: -```markdown -Inline-style (hover to see title text): +<!-- +Do not edit the following codeblock. It uses HTML to skip the Vale ReferenceLinks test. +--> + +<pre class="highlight"><code>Inline-style (hover to see title text): ![alt text](img/markdown_logo.png "Title Text") @@ -937,12 +948,12 @@ Reference-style (hover to see title text): ![alt text1][logo] -[logo]: img/markdown_logo.png "Title Text" -``` +[logo]: img/markdown_logo.png "Title Text" +</code></pre> <!-- -DO NOT change the name of markdown_logo.png. This is used for a test -in spec/controllers/help_controller_spec.rb. +DO NOT change the name of markdown_logo.png. This is used for a test in +spec/controllers/help_controller_spec.rb. --> Inline-style (hover to see title text): @@ -951,9 +962,12 @@ Inline-style (hover to see title text): Reference-style (hover to see title text): -![alt text][logo] +<!-- +The example below uses an in-line link to pass the Vale ReferenceLinks test. +Do not change to a reference style link. +--> -[logo]: img/markdown_logo.png "Title Text" +![alt text](img/markdown_logo.png "Title Text") #### Videos @@ -1036,7 +1050,10 @@ are separated into their own lines: </dl> ``` -<!-- Note: The example below uses HTML to force correct rendering on docs.gitlab.com, Markdown will be fine in GitLab --> +<!-- +Note: The example below uses HTML to force correct rendering on docs.gitlab.com, +Markdown will be fine in GitLab. +--> <dl> <dt>Markdown in HTML</dt> @@ -1102,7 +1119,10 @@ PASTE LOGS HERE </details> ```` -<!-- Note: The example below uses HTML to force correct rendering on docs.gitlab.com, Markdown will be fine in GitLab --> +<!-- +The example below uses HTML to force correct rendering on docs.gitlab.com, Markdown +will work correctly in GitLab. +--> <details> <summary>Click this to collapse/fold.</summary> @@ -1167,8 +1187,11 @@ A new line due to the previous backslash. There are two ways to create links, inline-style and reference-style: -```markdown -- This is an [inline-style link](https://www.google.com) +<!-- +Do not edit the following codeblock. It uses HTML to skip the Vale ReferenceLinks test. +--> + +<pre class="highlight"><code>- This is an [inline-style link](https://www.google.com) - This is a [link to a repository file in the same directory](index.md) - This is a [relative link to a readme one directory higher](../README.md) - This is a [link that also has title text](https://www.google.com "This link takes you to Google!") @@ -1186,10 +1209,10 @@ Using references: Some text to show that the reference links can follow later. -[arbitrary case-insensitive reference text]: https://www.mozilla.org/en-US/ -[1]: https://slashdot.org -[link text itself]: https://www.reddit.com -``` +[arbitrary case-insensitive reference text]: https://www.mozilla.org/en-US/ +[1]: https://slashdot.org +[link text itself]: https://www.reddit.com +</code></pre> - This is an [inline-style link](https://www.google.com) - This is a [link to a repository file in the same directory](index.md) @@ -1203,15 +1226,16 @@ Using header ID anchors: Using references: -- This is a [reference-style link, see below][Arbitrary case-insensitive reference text] -- You can [use numbers for reference-style link definitions, see below][1] -- Or leave it empty and use the [link text itself][], see below. +<!-- +The example below uses in-line links to pass the Vale ReferenceLinks test. +Do not change to reference style links. +--> -Some text to show that the reference links can follow later. +- This is a [reference-style link, see below](https://www.mozilla.org/en-US/) +- You can [use numbers for reference-style link definitions, see below](https://slashdot.org) +- Or leave it empty and use the [link text itself](https://www.reddit.com), see below. -[arbitrary case-insensitive reference text]: https://www.mozilla.org/en-US/ -[1]: https://slashdot.org -[link text itself]: https://www.reddit.com +Some text to show that the reference links can follow later. NOTE: **Note:** Relative links do not allow the referencing of project files in a wiki page, or a wiki page in a project file. The reason for this is that a wiki is always @@ -1261,8 +1285,11 @@ Examples: 4. And another item. ``` -<!-- The "2." and "4." in the example above are changed to "1." below, to match the style standards on docs.gitlab.com --> -<!-- See https://docs.gitlab.com/ee/development/documentation/styleguide.html#lists --> +<!-- +The "2." and "4." in the example above are changed to "1." below, to match the style +standards on docs.gitlab.com. +See https://docs.gitlab.com/ee/development/documentation/styleguide.html#lists +--> 1. First ordered list item 1. Another item @@ -1292,8 +1319,11 @@ They can even: + pluses ``` -<!-- The "*" and "+" in the example above are changed to "-" below, to match the style standards on docs.gitlab.com --> -<!-- See https://docs.gitlab.com/ee/development/documentation/styleguide.html#lists --> +<!-- +The "*" and "+" in the example above are changed to "-" below, to match the style +standards on docs.gitlab.com. +See https://docs.gitlab.com/ee/development/documentation/styleguide.html#lists +--> Unordered lists can: diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb index 2272803fcfa..68e70ecf8e1 100644 --- a/lib/gitlab/usage_data.rb +++ b/lib/gitlab/usage_data.rb @@ -286,7 +286,7 @@ module Gitlab results[:projects_slack_notifications_active] = results[:projects_slack_active] results[:projects_slack_slash_active] = results[:projects_slack_slash_commands_active] - results.merge(jira_usage) + results.merge(jira_usage).merge(jira_import_usage) end def jira_usage @@ -320,6 +320,16 @@ module Gitlab end # rubocop: enable CodeReuse/ActiveRecord + def jira_import_usage + finished_jira_imports = JiraImportState.finished + + { + jira_imports_total_imported_count: count(finished_jira_imports), + jira_imports_projects_count: distinct_count(finished_jira_imports, :project_id), + jira_imports_total_imported_issues_count: alt_usage_data { JiraImportState.finished_imports_count } + } + end + def user_preferences_usage {} # augmented in EE end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 6e09d3122da..e039b26112c 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -22233,6 +22233,9 @@ msgstr "" msgid "Unable to connect to server: %{error}" msgstr "" +msgid "Unable to connect to the Jira instance. Please check your Jira integration configuration." +msgstr "" + msgid "Unable to convert Kubernetes logs encoding to UTF-8" msgstr "" diff --git a/spec/controllers/projects/import/jira_controller_spec.rb b/spec/controllers/projects/import/jira_controller_spec.rb index c3bf0c09fba..d1b0a086576 100644 --- a/spec/controllers/projects/import/jira_controller_spec.rb +++ b/spec/controllers/projects/import/jira_controller_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' describe Projects::Import::JiraController do + include JiraServiceHelper + let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project) } let_it_be(:jira_project_key) { 'Test' } @@ -61,6 +63,7 @@ describe Projects::Import::JiraController do before do stub_feature_flags(jira_issue_import: true) stub_feature_flags(jira_issue_import_vue: false) + stub_jira_service_test end context 'when Jira service is enabled for the project' do diff --git a/spec/factories/usage_data.rb b/spec/factories/usage_data.rb index b633038b83b..e75d5bd7d18 100644 --- a/spec/factories/usage_data.rb +++ b/spec/factories/usage_data.rb @@ -12,6 +12,11 @@ FactoryBot.define do create(:jira_service, :jira_cloud_service, project: projects[2]) create(:jira_service, :without_properties_callback, project: projects[3], properties: { url: 'https://mysite.atlassian.net' }) + jira_label = create(:label, project: projects[0]) + create(:jira_import_state, :finished, project: projects[0], label: jira_label, failed_to_import_count: 2, imported_issues_count: 7, total_issue_count: 9) + create(:jira_import_state, :finished, project: projects[1], label: jira_label, imported_issues_count: 3, total_issue_count: 3) + create(:jira_import_state, :finished, project: projects[1], label: jira_label, imported_issues_count: 3) + create(:jira_import_state, :scheduled, project: projects[1], label: jira_label) create(:prometheus_service, project: projects[1]) create(:service, project: projects[0], type: 'SlackSlashCommandsService', active: true) create(:service, project: projects[1], type: 'SlackService', active: true) diff --git a/spec/lib/gitlab/jira_import/base_importer_spec.rb b/spec/lib/gitlab/jira_import/base_importer_spec.rb index f22efcb8743..ecaf3def589 100644 --- a/spec/lib/gitlab/jira_import/base_importer_spec.rb +++ b/spec/lib/gitlab/jira_import/base_importer_spec.rb @@ -3,12 +3,17 @@ require 'spec_helper' describe Gitlab::JiraImport::BaseImporter do + include JiraServiceHelper + let(:project) { create(:project) } describe 'with any inheriting class' do - context 'when feature flag disabled' do + context 'when an error is returned from the project validation' do before do stub_feature_flags(jira_issue_import: false) + + allow(project).to receive(:validate_jira_import_settings!) + .and_raise(Projects::ImportService::Error, 'Jira import feature is disabled.') end it 'raises exception' do @@ -16,20 +21,17 @@ describe Gitlab::JiraImport::BaseImporter do end end - context 'when feature flag enabled' do + context 'when project validation is ok' do + let!(:jira_service) { create(:jira_service, project: project) } + before do stub_feature_flags(jira_issue_import: true) - end + stub_jira_service_test - context 'when Jira service was not setup' do - it 'raises exception' do - expect { described_class.new(project) }.to raise_error(Projects::ImportService::Error, 'Jira integration not configured.') - end + allow(project).to receive(:validate_jira_import_settings!) end context 'when Jira service exists' do - let!(:jira_service) { create(:jira_service, project: project) } - context 'when Jira import data is not present' do it 'raises exception' do expect { described_class.new(project) }.to raise_error(Projects::ImportService::Error, 'Unable to find Jira project to import data from.') diff --git a/spec/lib/gitlab/jira_import/issues_importer_spec.rb b/spec/lib/gitlab/jira_import/issues_importer_spec.rb index 8e16fd3e978..a7cf19a9a5b 100644 --- a/spec/lib/gitlab/jira_import/issues_importer_spec.rb +++ b/spec/lib/gitlab/jira_import/issues_importer_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' describe Gitlab::JiraImport::IssuesImporter do + include JiraServiceHelper + let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project) } let_it_be(:jira_import) { create(:jira_import_state, project: project) } @@ -12,6 +14,7 @@ describe Gitlab::JiraImport::IssuesImporter do before do stub_feature_flags(jira_issue_import: true) + stub_jira_service_test end describe '#imported_items_cache_key' do diff --git a/spec/lib/gitlab/jira_import/labels_importer_spec.rb b/spec/lib/gitlab/jira_import/labels_importer_spec.rb index 9b24021d8d4..4d33ede136e 100644 --- a/spec/lib/gitlab/jira_import/labels_importer_spec.rb +++ b/spec/lib/gitlab/jira_import/labels_importer_spec.rb @@ -3,9 +3,11 @@ require 'spec_helper' describe Gitlab::JiraImport::LabelsImporter do - let_it_be(:user) { create(:user) } - let_it_be(:group) { create(:group) } - let_it_be(:project) { create(:project, group: group) } + include JiraServiceHelper + + let_it_be(:user) { create(:user) } + let_it_be(:group) { create(:group) } + let_it_be(:project) { create(:project, group: group) } let_it_be(:jira_service) { create(:jira_service, project: project) } subject { described_class.new(project).execute } @@ -13,13 +15,14 @@ describe Gitlab::JiraImport::LabelsImporter do before do stub_feature_flags(jira_issue_import: true) stub_const('Gitlab::JiraImport::LabelsImporter::MAX_LABELS', 2) - - WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/serverInfo') - .to_return(body: { url: 'http://url' }.to_json ) end describe '#execute', :clean_gitlab_redis_cache do - context 'when jira import label is missing from jira import' do + before do + stub_jira_service_test + end + + context 'when label is missing from jira import' do let_it_be(:no_label_jira_import) { create(:jira_import_state, label: nil, project: project) } it 'raises error' do diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index da157eec39f..858ee360d8a 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -44,6 +44,9 @@ describe Gitlab::UsageData, :aggregate_failures do expect(count_data[:projects_jira_active]).to eq(4) expect(count_data[:projects_jira_server_active]).to eq(2) expect(count_data[:projects_jira_cloud_active]).to eq(2) + expect(count_data[:jira_imports_projects_count]).to eq(2) + expect(count_data[:jira_imports_total_imported_count]).to eq(3) + expect(count_data[:jira_imports_total_imported_issues_count]).to eq(13) expect(count_data[:projects_slack_notifications_active]).to eq(2) expect(count_data[:projects_slack_slash_active]).to eq(1) expect(count_data[:projects_slack_active]).to eq(2) diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 18f77592cd6..78c0e8aef1a 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -5945,6 +5945,119 @@ describe Project do end end + describe '#validate_jira_import_settings!' do + include JiraServiceHelper + + let_it_be(:project, reload: true) { create(:project) } + + shared_examples 'raise Jira import error' do |message| + it 'returns error' do + expect { subject }.to raise_error(Projects::ImportService::Error, message) + end + end + + shared_examples 'jira configuration base checks' do + context 'when feature flag is disabled' do + before do + stub_feature_flags(jira_issue_import: false) + end + + it_behaves_like 'raise Jira import error', 'Jira import feature is disabled.' + end + + context 'when feature flag is enabled' do + before do + stub_feature_flags(jira_issue_import: true) + end + + context 'when Jira service was not setup' do + it_behaves_like 'raise Jira import error', 'Jira integration not configured.' + end + + context 'when Jira service exists' do + let!(:jira_service) { create(:jira_service, project: project, active: true) } + + context 'when Jira connection is not valid' do + before do + WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/serverInfo') + .to_raise(JIRA::HTTPError.new(double(message: 'Some failure.'))) + end + + it_behaves_like 'raise Jira import error', 'Unable to connect to the Jira instance. Please check your Jira integration configuration.' + end + end + end + end + + before do + stub_jira_service_test + end + + context 'without user param' do + subject { project.validate_jira_import_settings! } + + it_behaves_like 'jira configuration base checks' + + context 'when jira connection is valid' do + let!(:jira_service) { create(:jira_service, project: project, active: true) } + + it 'does not return any error' do + expect { subject }.not_to raise_error + end + end + end + + context 'with user param provided' do + let_it_be(:user) { create(:user) } + + subject { project.validate_jira_import_settings!(user: user) } + + context 'when user has permission to run import' do + before do + project.add_maintainer(user) + end + + it_behaves_like 'jira configuration base checks' + end + + context 'when feature flag is enabled' do + before do + stub_feature_flags(jira_issue_import: true) + end + + context 'when user does not have permissions to run the import' do + before do + create(:jira_service, project: project, active: true) + + project.add_developer(user) + end + + it_behaves_like 'raise Jira import error', 'You do not have permissions to run the import.' + end + + context 'when user has permission to run import' do + before do + project.add_maintainer(user) + end + + let!(:jira_service) { create(:jira_service, project: project, active: true) } + + context 'when issues feature is disabled' do + let_it_be(:project, reload: true) { create(:project, :issues_disabled) } + + it_behaves_like 'raise Jira import error', 'Cannot import because issues are not available in this project.' + end + + context 'when everything is ok' do + it 'does not return any error' do + expect { subject }.not_to raise_error + end + end + end + end + end + end + def finish_job(export_job) export_job.start export_job.finish diff --git a/spec/requests/api/graphql/mutations/jira_import/start_spec.rb b/spec/requests/api/graphql/mutations/jira_import/start_spec.rb index c7dcb21ad83..84110098400 100644 --- a/spec/requests/api/graphql/mutations/jira_import/start_spec.rb +++ b/spec/requests/api/graphql/mutations/jira_import/start_spec.rb @@ -3,6 +3,7 @@ require 'spec_helper' describe 'Starting a Jira Import' do + include JiraServiceHelper include GraphqlHelpers let_it_be(:user) { create(:user) } @@ -104,6 +105,8 @@ describe 'Starting a Jira Import' do before do project.reload + + stub_jira_service_test end context 'when issues feature are disabled' do diff --git a/spec/services/jira_import/start_import_service_spec.rb b/spec/services/jira_import/start_import_service_spec.rb index 1eefffe11fa..759e4f3363f 100644 --- a/spec/services/jira_import/start_import_service_spec.rb +++ b/spec/services/jira_import/start_import_service_spec.rb @@ -3,113 +3,89 @@ require 'spec_helper' describe JiraImport::StartImportService do + include JiraServiceHelper + let_it_be(:user) { create(:user) } let_it_be(:project, reload: true) { create(:project) } let(:key) { 'KEY' } subject { described_class.new(user, project, key).execute } - context 'when feature flag disabled' do + context 'when an error is returned from the project validation' do before do - stub_feature_flags(jira_issue_import: false) + allow(project).to receive(:validate_jira_import_settings!) + .and_raise(Projects::ImportService::Error, 'Jira import feature is disabled.') end it_behaves_like 'responds with error', 'Jira import feature is disabled.' end - context 'when feature flag enabled' do + context 'when project validation is ok' do + let!(:jira_service) { create(:jira_service, project: project, active: true) } + before do - stub_feature_flags(jira_issue_import: true) + stub_jira_service_test + allow(project).to receive(:validate_jira_import_settings!) end - context 'when user does not have permissions to run the import' do - before do - create(:jira_service, project: project, active: true) + context 'when Jira project key is not provided' do + let(:key) { '' } - project.add_developer(user) - end - - it_behaves_like 'responds with error', 'You do not have permissions to run the import.' + it_behaves_like 'responds with error', 'Unable to find Jira project to import data from.' end - context 'when user has permission to run import' do - before do - project.add_maintainer(user) - end + context 'when correct data provided' do + let(:fake_key) { 'some-key' } - context 'when Jira service was not setup' do - it_behaves_like 'responds with error', 'Jira integration not configured.' - end + subject { described_class.new(user, project, fake_key).execute } - context 'when Jira service exists' do - let!(:jira_service) { create(:jira_service, project: project, active: true) } + context 'when import is already running' do + let_it_be(:jira_import_state) { create(:jira_import_state, :started, project: project) } - context 'when Jira project key is not provided' do - let(:key) { '' } + it_behaves_like 'responds with error', 'Jira import is already running.' + end - it_behaves_like 'responds with error', 'Unable to find Jira project to import data from.' + context 'when everything is ok' do + it 'returns success response' do + expect(subject).to be_a(ServiceResponse) + expect(subject).to be_success end - context 'when issues feature are disabled' do - let_it_be(:project, reload: true) { create(:project, :issues_disabled) } + it 'schedules Jira import' do + subject - it_behaves_like 'responds with error', 'Cannot import because issues are not available in this project.' + expect(project.latest_jira_import).to be_scheduled end - context 'when correct data provided' do - let(:fake_key) { 'some-key' } - - subject { described_class.new(user, project, fake_key).execute } - - context 'when import is already running' do - let_it_be(:jira_import_state) { create(:jira_import_state, :started, project: project) } + it 'creates Jira import data' do + jira_import = subject.payload[:import_data] - it_behaves_like 'responds with error', 'Jira import is already running.' - end - - context 'when everything is ok' do - it 'returns success response' do - expect(subject).to be_a(ServiceResponse) - expect(subject).to be_success - end - - it 'schedules Jira import' do - subject - - expect(project.latest_jira_import).to be_scheduled - end - end - - it 'creates Jira import data' do - jira_import = subject.payload[:import_data] - - expect(jira_import.jira_project_xid).to eq(0) - expect(jira_import.jira_project_name).to eq(fake_key) - expect(jira_import.jira_project_key).to eq(fake_key) - expect(jira_import.user).to eq(user) - end + expect(jira_import.jira_project_xid).to eq(0) + expect(jira_import.jira_project_name).to eq(fake_key) + expect(jira_import.jira_project_key).to eq(fake_key) + expect(jira_import.user).to eq(user) + end - it 'creates Jira import label' do - expect { subject }.to change { Label.count }.by(1) - end + it 'creates Jira import label' do + expect { subject }.to change { Label.count }.by(1) + end - it 'creates Jira label title with correct number' do - jira_import = subject.payload[:import_data] + it 'creates Jira label title with correct number' do + jira_import = subject.payload[:import_data] - label_title = "jira-import::#{jira_import.jira_project_key}-1" - expect(jira_import.label.title).to eq(label_title) - end + label_title = "jira-import::#{jira_import.jira_project_key}-1" + expect(jira_import.label.title).to eq(label_title) + end + end - context 'when multiple Jira imports for same Jira project' do - let!(:jira_imports) { create_list(:jira_import_state, 3, :finished, project: project, jira_project_key: fake_key)} + context 'when multiple Jira imports for same Jira project' do + let!(:jira_imports) { create_list(:jira_import_state, 3, :finished, project: project, jira_project_key: fake_key)} - it 'creates Jira label title with correct number' do - jira_import = subject.payload[:import_data] + it 'creates Jira label title with correct number' do + jira_import = subject.payload[:import_data] - label_title = "jira-import::#{jira_import.jira_project_key}-4" - expect(jira_import.label.title).to eq(label_title) - end - end + label_title = "jira-import::#{jira_import.jira_project_key}-4" + expect(jira_import.label.title).to eq(label_title) end end end diff --git a/spec/support/helpers/jira_service_helper.rb b/spec/support/helpers/jira_service_helper.rb index c23a8d52c84..198bedfe3bc 100644 --- a/spec/support/helpers/jira_service_helper.rb +++ b/spec/support/helpers/jira_service_helper.rb @@ -78,6 +78,11 @@ module JiraServiceHelper JIRA_API + "/issue/#{issue_id}" end + def stub_jira_service_test + WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/serverInfo') + .to_return(body: { url: 'http://url' }.to_json) + end + def stub_jira_urls(issue_id) WebMock.stub_request(:get, jira_project_url) WebMock.stub_request(:get, jira_api_comment_url(issue_id)).to_return(body: jira_issue_comments) diff --git a/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb index e19acbebd66..f2067522af4 100644 --- a/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb +++ b/spec/workers/gitlab/jira_import/stage/import_issues_worker_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' describe Gitlab::JiraImport::Stage::ImportIssuesWorker do + include JiraServiceHelper + let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, import_type: 'jira') } @@ -25,6 +27,7 @@ describe Gitlab::JiraImport::Stage::ImportIssuesWorker do before do stub_feature_flags(jira_issue_import: true) + stub_jira_service_test end context 'when import did not start' do diff --git a/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb b/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb index 505137e9b22..7f289de5422 100644 --- a/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb +++ b/spec/workers/gitlab/jira_import/stage/import_labels_worker_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' describe Gitlab::JiraImport::Stage::ImportLabelsWorker do + include JiraServiceHelper + let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, import_type: 'jira') } @@ -36,6 +38,8 @@ describe Gitlab::JiraImport::Stage::ImportLabelsWorker do let!(:jira_service) { create(:jira_service, project: project) } before do + stub_jira_service_test + jira_import.start! WebMock.stub_request(:get, 'https://jira.example.com/rest/api/2/label?maxResults=500&startAt=0') |