diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-10 03:08:22 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-03-10 03:08:22 +0300 |
commit | 77edae8f143c25536a7539abb2be6935ebb2fddc (patch) | |
tree | bd16c20a2b74e2a18f15faaabc827c4c9741eafb | |
parent | 21a5ef21750a02e4536077833400158de7e4ff95 (diff) |
Add latest changes from gitlab-org/gitlab@master
41 files changed, 475 insertions, 441 deletions
diff --git a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue index 6e2cd06f3ce..3d87cea6445 100644 --- a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue +++ b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue @@ -57,6 +57,9 @@ export default { }, jobsCount: { query: GetJobsCount, + context: { + isSingleRequest: true, + }, variables() { return { fullPath: this.fullPath, diff --git a/app/assets/stylesheets/framework/typography.scss b/app/assets/stylesheets/framework/typography.scss index 9b5897b7df9..1d05c856202 100644 --- a/app/assets/stylesheets/framework/typography.scss +++ b/app/assets/stylesheets/framework/typography.scss @@ -494,6 +494,7 @@ outline: none; &::after { + @include gl-dark-invert-keep-hue; content: image-url('icon_anchor.svg'); visibility: hidden; } diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss index d7f95e88290..0151446321a 100644 --- a/app/assets/stylesheets/pages/issues.scss +++ b/app/assets/stylesheets/pages/issues.scss @@ -236,6 +236,7 @@ ul.related-merge-requests > li gl-emoji { outline: none; &::after { + @include gl-dark-invert-keep-hue; content: image-url('icon_anchor.svg'); visibility: hidden; } diff --git a/app/models/project.rb b/app/models/project.rb index a4de9d3f08a..f96cff89221 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -1103,11 +1103,7 @@ class Project < ApplicationRecord end def ancestors(hierarchy_order: nil) - if Feature.enabled?(:linear_project_ancestors, self) - group&.self_and_ancestors(hierarchy_order: hierarchy_order) || Group.none - else - ancestors_upto(hierarchy_order: hierarchy_order) - end + group&.self_and_ancestors(hierarchy_order: hierarchy_order) || Group.none end def ancestors_upto_ids(...) diff --git a/config/feature_flags/development/linear_project_ancestors.yml b/config/feature_flags/development/linear_project_ancestors.yml deleted file mode 100644 index 00b04b20b30..00000000000 --- a/config/feature_flags/development/linear_project_ancestors.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: linear_project_ancestors -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68072 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/338403 -milestone: '14.2' -type: development -group: group::authentication and authorization -default_enabled: false diff --git a/config/metrics/counts_all/20210216180228_projects_jira_server_active.yml b/config/metrics/counts_all/20210216180228_projects_jira_server_active.yml index cc000031e83..a22520cb97d 100644 --- a/config/metrics/counts_all/20210216180228_projects_jira_server_active.yml +++ b/config/metrics/counts_all/20210216180228_projects_jira_server_active.yml @@ -7,7 +7,7 @@ product_stage: manage product_group: integrations product_category: integrations value_type: number -status: active +status: removed time_frame: all data_source: database distribution: @@ -19,3 +19,5 @@ tier: - ultimate performance_indicator_type: [] milestone: "<13.9" +removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112571 +milestone_removed: "15.10" diff --git a/config/metrics/counts_all/20210216180230_projects_jira_cloud_active.yml b/config/metrics/counts_all/20210216180230_projects_jira_cloud_active.yml index d607f3d6aea..092036b3a5b 100644 --- a/config/metrics/counts_all/20210216180230_projects_jira_cloud_active.yml +++ b/config/metrics/counts_all/20210216180230_projects_jira_cloud_active.yml @@ -7,7 +7,7 @@ product_stage: manage product_group: integrations product_category: integrations value_type: number -status: active +status: removed time_frame: all data_source: database distribution: @@ -19,3 +19,5 @@ tier: - ultimate performance_indicator_type: [] milestone: "<13.9" +removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112571 +milestone_removed: "15.10" diff --git a/doc/administration/geo/replication/troubleshooting.md b/doc/administration/geo/replication/troubleshooting.md index 59a67fecfcd..3d7c12f1868 100644 --- a/doc/administration/geo/replication/troubleshooting.md +++ b/doc/administration/geo/replication/troubleshooting.md @@ -42,7 +42,7 @@ to help identify if something is wrong: ![Geo health check](img/geo_site_health_v14_0.png) -A site shows as "Unhealthy" if the site's status is more than 10 minutes old. In that case, try running the following in the [Rails console](../../operations/rails_console.md) on the affected site: +A site shows as "Unhealthy" if the site's status is more than 10 minutes old. In that case, try running the following in the [Rails console](../../operations/rails_console.md) on the affected secondary site: ```ruby Geo::MetricsUpdateWorker.new.perform @@ -52,7 +52,7 @@ If it raises an error, then the error is probably also preventing the jobs from If it successfully updates the status, then something may be wrong with Sidekiq. Is it running? Do the logs show errors? This job is supposed to be enqueued every minute. It takes an exclusive lease in Redis to ensure that only one of these jobs can run at a time. The primary site updates its status directly in the PostgreSQL database. Secondary sites send an HTTP Post request to the primary site with their status data. -A site also shows as "Unhealthy" if certain health checks fail. You can reveal the failure by running the following in the [Rails console](../../operations/rails_console.md) on the affected site: +A site also shows as "Unhealthy" if certain health checks fail. You can reveal the failure by running the following in the [Rails console](../../operations/rails_console.md) on the affected secondary site: ```ruby Gitlab::Geo::HealthCheck.new.perform_checks diff --git a/doc/ci/yaml/includes.md b/doc/ci/yaml/includes.md index f93c09c0f20..dae213eb0cb 100644 --- a/doc/ci/yaml/includes.md +++ b/doc/ci/yaml/includes.md @@ -514,3 +514,20 @@ When the pipeline runs, GitLab: # This matches all `.yml` files only in subfolders of `configs`. include: 'configs/**/*.yml' ``` + +## Troubleshooting + +### `Maximum of 150 nested includes are allowed!` error + +The maximum number of [nested included files](#use-nested-includes) for a pipeline is 150. +If you receive the `Maximum 150 includes are allowed` error message in your pipeline, +it's likely that either: + +- Some of the nested configuration includes an overly large number of additional nested `include` configuration. +- There is an accidental loop in the nested includes. For example, `include1.yml` includes + `include2.yml` which includes `include1.yml`, creating a recursive loop. + +To help reduce the risk of this happening, edit the pipeline configuration file +with the [pipeline editor](../pipeline_editor/index.md), which validates if the +limit is reached. You can remove one included file at a time to try to narrow down +which configuration file is the source of the loop or excessive included files. diff --git a/doc/development/testing_guide/contract/index.md b/doc/development/testing_guide/contract/index.md index 31d68bb9f4f..cf23792e239 100644 --- a/doc/development/testing_guide/contract/index.md +++ b/doc/development/testing_guide/contract/index.md @@ -42,11 +42,11 @@ rake contracts:merge_requests:test:merge_requests[contract_merge_requests] #### Verify the contracts in Pact Broker -By default, the Rake tasks will verify the locally stored contracts. In order to verify the contracts published in the Pact Broker, we need to set the `PACT_BROKER` environment variable to `true`. It is important to point out here that the file path and file name of the provider test is what is used to find the contract in the Pact Broker which is why it is important to make sure the [provider test naming conventions](#provider-naming) are followed. +By default, the Rake tasks will verify the locally stored contracts. In order to verify the contracts published in the Pact Broker, we need to set the `PACT_BROKER` environment variable to `true` and the `QA_PACT_BROKER_HOST` to the URL of the Pact Broker. It is important to point out here that the file path and file name of the provider test is what is used to find the contract in the Pact Broker which is why it is important to make sure the [provider test naming conventions](#provider-naming) are followed. ## Publish contracts to Pact Broker -The contracts generated by the consumer test can be published to a hosted Pact Broker by going to `spec/contracts` and running the `publish-contracts.sh` script. +The contracts generated by the consumer test can be published to a hosted Pact Broker by setting the `QA_PACT_BROKER_HOST` environment variable and running the [`publish-contracts.sh`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/spec/contracts/publish-contracts.sh) script. ## Test suite folder structure and naming conventions diff --git a/doc/update/index.md b/doc/update/index.md index 35d7c7c0e4d..a7e1fd23b98 100644 --- a/doc/update/index.md +++ b/doc/update/index.md @@ -266,6 +266,7 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap ### 15.9.0 +- There is a [database migration bug in GitLab 15.9.x](#user-profile-data-loss-bug-in-159x) that can cause data to be lost from the user profile fields. This bug affects all currently available 15.9.x releases. Until a bug fix is released, you should upgrade to 15.6.x, 15.7.x, or 15.8.x first. - This version removes `SanitizeConfidentialTodos` background migration [added](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87908/diffs) in 15.6, which removed any user inaccessible to-do items. Make sure that this migration is finished before upgrading to 15.9. - As part of the [CI Partitioning effort](../architecture/blueprints/ci_data_decay/pipeline_partitioning.md), a [new Foreign Key](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/107547) was added to `ci_builds_needs`. On GitLab instances with large CI tables, adding this constraint can take longer than usual. Make sure that this migration is finished before upgrading to 15.9. - Praefect's metadata verifier's [invalid metadata deletion behavior](../administration/gitaly/praefect.md#enable-deletions) is now enabled by default. @@ -282,7 +283,6 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap You can find repositories with invalid metadata records prior in GitLab 15.0 and later by searching for the log records outputted by the verifier. [Read more about repository verification, and to see an example log entry](../administration/gitaly/praefect.md#repository-verification). - Praefect configuration changes significantly in Omnibus GitLab 16.0. You can begin migrating to the new structure in Omnibus GitLab 15.9 while backwards compatibility is maintained in the lead up to Omnibus GitLab 16.0. [Read more about this change](#praefect-omnibus-gitlab-configuration-structure-change). -- There is a [database migration bug in GitLab 15.9.x](#user-profile-data-loss-bug-in-159x) that can cause data to be lost from the user profile fields. This bug affects all currently available 15.9.x releases. Until a bug fix is released, you should upgrade via 15.6.x, 15.7.x, or 15.8.x. ### 15.8.2 @@ -299,7 +299,7 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap ### 15.8.0 -- Due to a bug in GitLab 15.9.x that can cause data to be lost from certain user profile fields, 15.8 is temporarily a required stop on the upgrade path. This requirement will be removed when a 15.9.x bug fix is released. [Read more about this issue](#user-profile-data-loss-bug-in-159x). +- Due to a bug in GitLab 15.9.x that can cause data to be lost from certain user profile fields, 15.6, 15.7, or 15.8 is temporarily a required stop on the upgrade path. This requirement will be removed when a 15.9.x bug fix is released. [Read more about this issue](#user-profile-data-loss-bug-in-159x). - Git 2.38.0 and later is required by Gitaly. For installations from source, you should use the [Git version provided by Gitaly](../install/installation.md#git). - Due to [a bug introduced in GitLab 15.4](https://gitlab.com/gitlab-org/gitlab/-/issues/390155), if one or more Git repositories in Gitaly Cluster is [unavailable](../administration/gitaly/recovery.md#unavailable-repositories), then [Repository checks](../administration/repository_checks.md#repository-checks) and [Geo replication and verification](../administration/geo/index.md) stop running for all project or project wiki repositories in the affected Gitaly Cluster. The bug was fixed by [reverting the change in GitLab 15.9.0](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/110823). Before upgrading to this version, check if you have any "unavailable" repositories. See [the bug issue](https://gitlab.com/gitlab-org/gitlab/-/issues/390155) for more information. - Geo: We discovered an issue where [replication and verification of projects and wikis was not keeping up](https://gitlab.com/gitlab-org/gitlab/-/issues/387980) on small number of Geo installations. Your installation may be affected if you see some projects and/or wikis persistently in the "Queued" state for verification. This can lead to data loss after a failover. @@ -352,7 +352,7 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap ### 15.7.0 -- Due to a bug in GitLab 15.9.x that can cause data to be lost from certain user profile fields, 15.7 is temporarily a required stop on the upgrade path. This requirement will be removed when a 15.9.x bug fix is released. [Read more about this issue](#user-profile-data-loss-bug-in-159x). +- Due to a bug in GitLab 15.9.x that can cause data to be lost from certain user profile fields, 15.6, 15.7, or 15.8 is temporarily a required stop on the upgrade path. This requirement will be removed when a 15.9.x bug fix is released. [Read more about this issue](#user-profile-data-loss-bug-in-159x). - This version validates a `NOT NULL DB` constraint on the `issues.work_item_type_id` column. To upgrade to this version, no records with a `NULL` `work_item_type_id` should exist on the `issues` table. There are multiple `BackfillWorkItemTypeIdForIssues` background migrations that will be finalized with @@ -462,7 +462,7 @@ and [Helm Chart deployments](https://docs.gitlab.com/charts/). They come with ap ### 15.6.0 -- Due to a bug in GitLab 15.9.x that can cause data to be lost from certain user profile fields, 15.6 is temporarily a required stop on the upgrade path. This requirement will be removed when a 15.9.x bug fix is released. [Read more about this issue](#user-profile-data-loss-bug-in-159x). +- Due to a bug in GitLab 15.9.x that can cause data to be lost from certain user profile fields, 15.6, 15.7, or 15.8 is temporarily a required stop on the upgrade path. This requirement will be removed when a 15.9.x bug fix is released. [Read more about this issue](#user-profile-data-loss-bug-in-159x). - You should use one of the [officially supported PostgreSQL versions](../administration/package_information/postgresql_versions.md). Some database migrations can cause stability and performance issues with older PostgreSQL versions. - Git 2.37.0 and later is required by Gitaly. For installations from source, we recommend you use the [Git version provided by Gitaly](../install/installation.md#git). - A database change to modify the behavior of four indexes fails on instances @@ -1446,67 +1446,26 @@ After upgraded to 11.11.8 you can safely upgrade to 12.0.Z. See our [documentation on upgrade paths](../policy/maintenance.md#upgrade-recommendations) for more information. -### Change to Praefect-generated replica paths in GitLab 15.3 - -New Git repositories created in Gitaly cluster no longer use the `@hashed` storage path. - -Praefect now generates replica paths for use by Gitaly cluster. -This change is a pre-requisite for Gitaly cluster atomically creating, deleting, and -renaming Git repositories. - -To identify the replica path, [query the Praefect repository metadata](../administration/gitaly/troubleshooting.md#view-repository-metadata) -and pass the `@hashed` storage path to `-relative-path`. - -With this information, you can correctly install [server hooks](../administration/server_hooks.md). - -### Maintenance mode issue in GitLab 13.9 to 14.4 - -When [Maintenance mode](../administration/maintenance_mode/index.md) is enabled, users cannot sign in with SSO, SAML, or LDAP. - -Users who were signed in before Maintenance mode was enabled, continue to be signed in. If the administrator who enabled Maintenance mode loses their session, then they can't disable Maintenance mode via the UI. In that case, you can [disable Maintenance mode via the API or Rails console](../administration/maintenance_mode/index.md#disable-maintenance-mode). - -[This bug](https://gitlab.com/gitlab-org/gitlab/-/issues/329261) was fixed in GitLab 14.5.0 and backported into 14.4.3 and 14.3.5. - -### LFS objects import and mirror issue in GitLab 14.6.0 to 14.7.2 - -When Geo is enabled, LFS objects fail to be saved for imported or mirrored projects. - -[This bug](https://gitlab.com/gitlab-org/gitlab/-/issues/352368) was fixed in GitLab 14.8.0 and backported into 14.7.3. - -### PostgreSQL segmentation fault issue - -If you run GitLab with external PostgreSQL, particularly AWS RDS, ensure you upgrade PostgreSQL -to patch levels to a minimum of 12.7 or 13.3 before upgrading to GitLab 14.8 or later. - -[In 14.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75511) -for GitLab Enterprise Edition and [in 15.1](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87983) -for GitLab Community Edition a GitLab feature called Loose Foreign Keys was enabled. - -After it was enabled, we have had reports of unplanned PostgreSQL restarts caused -by a database engine bug that causes a segmentation fault. - -Read more [in the issue](https://gitlab.com/gitlab-org/gitlab/-/issues/364763). +### User profile data loss bug in 15.9.x -### Geo: Incorrect object storage LFS file deletion on secondary sites in GitLab 15.0.0 to 15.3.2 +There is a database migration bug in 15.9 that can cause data to be lost from the user profile fields `linkedin`, `twitter`, `skype`, `website_url`, `location`, and `organization`. -[Incorrect deletion of object storage files on Geo secondary sites](https://gitlab.com/gitlab-org/gitlab/-/issues/371397) -can occur in GitLab 15.0.0 to 15.3.2 in the following situations: +This bug will be fixed in a future patch release of GitLab 15.9. Until then: -- GitLab-managed object storage replication is disabled, and LFS objects are created while importing a project with object storage enabled. -- GitLab-managed replication to sync object storage is enabled and subsequently disabled. +- All 15.9.x patch levels are affected. +- The GitLab upgrade path requires an intermediate release between 15.4 and 15.9. -This issue is resolved in 15.3.3. Customers who have both LFS enabled and LFS objects being replicated across Geo sites -should upgrade directly to 15.3.3 to reduce the risk of data loss on secondary sites. +If your organization uses these fields either wait for the bug fix to be released, or: -### Geo: LFS transfers redirect to primary from secondary site mid-session in GitLab 15.1.0 to 15.3.2 +1. Upgrade to GitLab 15.6.x, 15.7.x, or 15.8.x (the latest patch levels are recommended at all times). +1. [Ensure batched background migrations](background_migrations.md#batched-background-migrations) are complete. +1. Upgrade to an affected GitLab 15.9 patch release. -LFS transfers can [redirect to the primary from secondary site mid-session](https://gitlab.com/gitlab-org/gitlab/-/issues/371571) causing failed pull and clone requests in GitLab 15.1.0 to 15.3.2 when [Geo proxying](../administration/geo/secondary_proxy/index.md) is enabled. Geo proxying is enabled by default in GitLab 15.1 and later. +Organizations that are already running earlier patch levels of GitLab 15.6, 15.7, or 15.8 can proceed with steps 2 and 3. -This issue is resolved in GitLab 15.3.3, so customers with the following configuration should upgrade to 15.3.3 or later: +If you have already upgraded to GitLab 15.9 following these instructions, your instance will not be affected by this bug, and you don't need to apply the 15.9.x patch when it is released. -- LFS is enabled. -- LFS objects are being replicated across Geo sites. -- Repositories are being pulled by using a Geo secondary site. +See [issue 393216](https://gitlab.com/gitlab-org/gitlab/-/issues/393216) for more information. ### Praefect: Omnibus GitLab configuration structure change @@ -1659,26 +1618,67 @@ praefect['configuration'] = { } ``` -### User profile data loss bug in 15.9.x +### Change to Praefect-generated replica paths in GitLab 15.3 -There is a database migration bug in 15.9 that can cause data to be lost from the user profile fields `linkedin`, `twitter`, `skype`, `website_url`, `location`, and `organization`. +New Git repositories created in Gitaly cluster no longer use the `@hashed` storage path. -This bug will be fixed in a future patch release of GitLab 15.9. Until then: +Praefect now generates replica paths for use by Gitaly cluster. +This change is a pre-requisite for Gitaly cluster atomically creating, deleting, and +renaming Git repositories. -- All 15.9.x patch levels are affected. -- The GitLab upgrade path requires an intermediate release between 15.4 and 15.9. +To identify the replica path, [query the Praefect repository metadata](../administration/gitaly/troubleshooting.md#view-repository-metadata) +and pass the `@hashed` storage path to `-relative-path`. -If your organization uses these fields either wait for the bug fix to be released, or: +With this information, you can correctly install [server hooks](../administration/server_hooks.md). -1. Upgrade to GitLab 15.6.8, 15.7.8, or 15.8.4 (the latest patch levels are recommended at all times). -1. [Ensure batched background migrations](background_migrations.md#batched-background-migrations) are complete. -1. Upgrade to an affected GitLab 15.9 patch release. +### Geo: LFS transfers redirect to primary from secondary site mid-session in GitLab 15.1.0 to 15.3.2 -Organizations that are already running earlier patch levels of GitLab 15.6, 15.7, or 15.8 can proceed with steps 2 and 3. +LFS transfers can [redirect to the primary from secondary site mid-session](https://gitlab.com/gitlab-org/gitlab/-/issues/371571) causing failed pull and clone requests in GitLab 15.1.0 to 15.3.2 when [Geo proxying](../administration/geo/secondary_proxy/index.md) is enabled. Geo proxying is enabled by default in GitLab 15.1 and later. -If you have already upgraded to GitLab 15.9 following these instructions, your instance will not be affected by this bug, and you don't need to apply the 15.9.x patch when it is released. +This issue is resolved in GitLab 15.3.3, so customers with the following configuration should upgrade to 15.3.3 or later: -See [issue 393216](https://gitlab.com/gitlab-org/gitlab/-/issues/393216) for more information. +- LFS is enabled. +- LFS objects are being replicated across Geo sites. +- Repositories are being pulled by using a Geo secondary site. + +### Geo: Incorrect object storage LFS file deletion on secondary sites in GitLab 15.0.0 to 15.3.2 + +[Incorrect deletion of object storage files on Geo secondary sites](https://gitlab.com/gitlab-org/gitlab/-/issues/371397) +can occur in GitLab 15.0.0 to 15.3.2 in the following situations: + +- GitLab-managed object storage replication is disabled, and LFS objects are created while importing a project with object storage enabled. +- GitLab-managed replication to sync object storage is enabled and subsequently disabled. + +This issue is resolved in 15.3.3. Customers who have both LFS enabled and LFS objects being replicated across Geo sites +should upgrade directly to 15.3.3 to reduce the risk of data loss on secondary sites. + +### PostgreSQL segmentation fault issue + +If you run GitLab with external PostgreSQL, particularly AWS RDS, ensure you upgrade PostgreSQL +to patch levels to a minimum of 12.7 or 13.3 before upgrading to GitLab 14.8 or later. + +[In 14.8](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/75511) +for GitLab Enterprise Edition and [in 15.1](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87983) +for GitLab Community Edition a GitLab feature called Loose Foreign Keys was enabled. + +After it was enabled, we have had reports of unplanned PostgreSQL restarts caused +by a database engine bug that causes a segmentation fault. + +Read more [in the issue](https://gitlab.com/gitlab-org/gitlab/-/issues/364763). + +### LFS objects import and mirror issue in GitLab 14.6.0 to 14.7.2 + +When Geo is enabled, LFS objects fail to be saved for imported or mirrored projects. + +[This bug](https://gitlab.com/gitlab-org/gitlab/-/issues/352368) was fixed in GitLab 14.8.0 and backported into 14.7.3. + +### Maintenance mode issue in GitLab 13.9 to 14.4 + +When [Maintenance mode](../administration/maintenance_mode/index.md) is enabled, users cannot sign in with SSO, SAML, or LDAP. + +Users who were signed in before Maintenance mode was enabled, continue to be signed in. If the administrator who enabled Maintenance mode loses their session, then they can't disable Maintenance mode via the UI. In that case, you can [disable Maintenance mode via the API or Rails console](../administration/maintenance_mode/index.md#disable-maintenance-mode). + +[This bug](https://gitlab.com/gitlab-org/gitlab/-/issues/329261) was fixed in GitLab 14.5.0 and backported into 14.4.3 and 14.3.5. ## Miscellaneous diff --git a/doc/user/application_security/dast/authentication.md b/doc/user/application_security/dast/authentication.md index 1205c0f0491..440f08fcfcd 100644 --- a/doc/user/application_security/dast/authentication.md +++ b/doc/user/application_security/dast/authentication.md @@ -45,13 +45,21 @@ To run a DAST authenticated scan: ### Prerequisites +- You have the username and password of the user you would like to authenticate as during the scan. +- You have checked the [known limitations](#known-limitations) to ensure DAST can authenticate to your application. +- You have satisfied the prerequisites depending on whether you're using [form authentication](#form-authentication) or [HTTP authentication]((#http-authentication). +- You have thought about how you can [verify](#verifying-authentication-is-successful) whether or not authentication was successful. + +#### Form authentication + - You are using either the [DAST proxy-based analyzer](proxy-based.md) or the [DAST browser-based analyzer](browser_based.md). - You know the URL of the login form of your application. Alternatively, you know how to navigate to the login form from the authentication URL (see [clicking to navigate to the login form](#clicking-to-navigate-to-the-login-form)). -- You have the username and password of the user you would like to authenticate as during the scan. - You know the [selectors](#finding-an-elements-selector) of the username and password HTML fields that DAST uses to input the respective values. - You know the element's [selector](#finding-an-elements-selector) that submits the login form when selected. -- You have thought about how you can [verify](#verifying-authentication-is-successful) whether or not authentication was successful. -- You have checked the [known limitations](#known-limitations) to ensure DAST can authenticate to your application. + +#### HTTP authentication + +- You must be using the [DAST browser-based analyzer](browser_based.md). ### Available CI/CD variables @@ -59,6 +67,7 @@ To run a DAST authenticated scan: |:-----------------------------------------------|:------------------------------------------|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `DAST_AUTH_COOKIES` | string | Set to a comma-separated list of cookie names to specify which cookies are used for authentication. | | `DAST_AUTH_REPORT` | boolean | Set to `true` to generate a report detailing steps taken during the authentication process. You must also define `gl-dast-debug-auth-report.html` as a CI job artifact to be able to access the generated report. Useful for debugging when authentication fails. | +| `DAST_AUTH_TYPE` <sup>2</sup> | string | The authentication type to use. Example: `basic-digest`. | | `DAST_AUTH_URL` <sup>1</sup> | URL | The URL of the page containing the sign-in HTML form on the target website. `DAST_USERNAME` and `DAST_PASSWORD` are submitted with the login form to create an authenticated scan. Example: `https://login.example.com`. | | `DAST_AUTH_VERIFICATION_LOGIN_FORM` | boolean | Verifies successful authentication by checking for the absence of a login form once the login form has been submitted. | | `DAST_AUTH_VERIFICATION_SELECTOR` | [selector](#finding-an-elements-selector) | Verifies successful authentication by checking for presence of a selector once the login form has been submitted. Example: `css:.user-photo`. | @@ -73,6 +82,7 @@ To run a DAST authenticated scan: | `DAST_USERNAME_FIELD` <sup>1</sup> | string | The selector of username field at the sign-in HTML form. Example: `name:username` | 1. Available to an on-demand proxy-based DAST scan. +1. Not available to proxy-based scans. ### Update the target website @@ -93,6 +103,28 @@ dast: DAST_AUTH_URL: "https://example.com/login" ``` +### Configuration for HTTP authentication + +To use an [HTTP authentication scheme](https://www.chromium.org/developers/design-documents/http-authentication/) such as Basic Authentication you can set the `DAST_AUTH_TYPE` value to `basic-digest`. +Other schemes such as Negotiate or NTLM may work but aren't officially supported due to current lack of automated test coverage. + +Configuration requires the CI/CD variables `DAST_AUTH_TYPE`, `DAST_AUTH_URL`, `DAST_USERNAME`, `DAST_PASSWORD` to be defined for the DAST job. If you don't have a unique login URL, please set `DAST_AUTH_URL` to the same URL as `DAST_WEBSITE`. + +```yaml +include: + - template: DAST.gitlab-ci.yml + +dast: + variables: + DAST_WEBSITE: "https://example.com" + DAST_AUTH_TYPE: "basic-digest" + DAST_AUTH_URL: "https://example.com" +``` + +Do **not** define `DAST_USERNAME` and `DAST_PASSWORD` in the YAML job definition file as this could present a security risk. Instead, create them as masked CI/CD variables using the GitLab UI. +See [Custom CI/CD variables](../../../ci/variables/index.md#for-a-project) for more information. +The proxy-based analyzer does not support basic authentication as an authentication mechanism. A workaround could be to set `DAST_REQUEST_HEADERS` as a masked CI/CD variable with a value containing the appropriate `Authorization` header, for example, `Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQK`. + ### Configuration for a single-step login form A single-step login form has all login form elements on a single page. @@ -114,7 +146,7 @@ dast: ``` Do **not** define `DAST_USERNAME` and `DAST_PASSWORD` in the YAML job definition file as this could present a security risk. Instead, create them as masked CI/CD variables using the GitLab UI. -See [Custom CI/CI variables](../../../ci/variables/index.md#for-a-project) for more information. +See [Custom CI/CD variables](../../../ci/variables/index.md#for-a-project) for more information. ### Configuration for a multi-step login form @@ -140,7 +172,7 @@ dast: ``` Do **not** define `DAST_USERNAME` and `DAST_PASSWORD` in the YAML job definition file as this could present a security risk. Instead, create them as masked CI/CD variables using the GitLab UI. -See [Custom CI/CI variables](../../../ci/variables/index.md#for-a-project) for more information. +See [Custom CI/CD variables](../../../ci/variables/index.md#for-a-project) for more information. ### Configuration for Single Sign-On (SSO) diff --git a/doc/user/clusters/agent/troubleshooting.md b/doc/user/clusters/agent/troubleshooting.md index f5f235d2758..84cdbbcc096 100644 --- a/doc/user/clusters/agent/troubleshooting.md +++ b/doc/user/clusters/agent/troubleshooting.md @@ -107,71 +107,72 @@ This error occurs when your GitLab instance is using a certificate signed by an certificate authority that is unknown to the agent. To fix this issue, you can present the CA certificate file to the agent -by using a Kubernetes `configmap` and mount the file in the agent `/etc/ssl/certs` directory from where it -is picked up automatically. +by [customizing the Helm installation](install/index.md#customize-the-helm-installation). +Add `--set config.caCert="$(cat ~/path/to/ca.crt)"` to the `helm install` command. Make sure to replace `~/path/to/ca.crt` +with the path to your internal CA's certificate file. The file should be a valid PEM or DER-encoded certificate. -For example, if your internal CA certificate is `myCA.pem`: +When you deploy `agentk` with a set `config.caCert` value, the certificate is added to `configmap` and the certificate file is mounted in `/etc/ssl/certs`. -```plaintext -kubectl -n gitlab-agent create configmap ca-pemstore --from-file=myCA.pem +```yaml +$ kubectl get configmap -lapp=gitlab-agent -o yaml +apiVersion: v1 +items: +- apiVersion: v1 + data: + ca.crt: |- + -----BEGIN CERTIFICATE----- + MIIFmzCCA4OgAwIBAgIUE+FvXfDpJ869UgJitjRX7HHT84cwDQYJKoZIhvcNAQEL + ...truncated certificate... + GHZCTQkbQyUwBWJOUyOxW1lro4hWqtP4xLj8Dpq1jfopH72h0qTGkX0XhFGiSaM= + -----END CERTIFICATE----- + kind: ConfigMap + metadata: + annotations: + meta.helm.sh/release-name: self-signed + meta.helm.sh/release-namespace: gitlab-agent-self-signed + creationTimestamp: "2023-03-07T20:12:26Z" + labels: + app: gitlab-agent + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: gitlab-agent + app.kubernetes.io/version: v15.9.0 + helm.sh/chart: gitlab-agent-1.11.0 + name: self-signed-gitlab-agent + resourceVersion: "263184207" +kind: List ``` -Then in `resources.yml`: +You might see a similar error in the [agent server (KAS) logs](../../../administration/logs/index.md#gitlab-agent-server) of your GitLab application server: -```yaml - spec: - serviceAccountName: gitlab-agent - containers: - - name: agent - image: "registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/agentk:<version>" - args: - - --token-file=/config/token - - --kas-address - - wss://kas.host.tld:443 # replace this line with the line below if using Omnibus GitLab or GitLab.com. - # - wss://gitlab.host.tld:443/-/kubernetes-agent/ - # - wss://kas.gitlab.com # for GitLab.com users, use this KAS. - # - grpc://host.docker.internal:8150 # use this attribute when connecting from Docker. - volumeMounts: - - name: token-volume - mountPath: /config - - name: ca-pemstore-volume - mountPath: /etc/ssl/certs/myCA.pem - subPath: myCA.pem - volumes: - - name: token-volume - secret: - secretName: gitlab-agent-token - - name: ca-pemstore-volume - configMap: - name: ca-pemstore - items: - - key: myCA.pem - path: myCA.pem +```json +{"level":"error","time":"2023-03-07T20:19:48.151Z","msg":"AgentInfo()","grpc_service":"gitlab.agent.agent_configuration.rpc.AgentConfiguration","grpc_method":"GetConfiguration","error":"Get \"https://gitlab.example.com/api/v4/internal/kubernetes/agent_info\": x509: certificate signed by unknown authority"} ``` -Alternatively, you can mount the certificate file at a different location and specify it for the -`--ca-cert-file` agent parameter: +To fix it, [install your internal CA's public certificate](https://docs.gitlab.com/omnibus/settings/ssl/#install-custom-public-certificates) in the `/etc/gitlab/trusted-certs` directory. -```yaml - containers: - - name: agent - image: "registry.gitlab.com/gitlab-org/cluster-integration/gitlab-agent/agentk:<version>" - args: - - --ca-cert-file=/tmp/myCA.pem - - --token-file=/config/token - - --kas-address - - wss://kas.host.tld:443 # replace this line with the line below if using Omnibus GitLab or GitLab.com. - # - wss://gitlab.host.tld:443/-/kubernetes-agent/ - # - wss://kas.gitlab.com # for GitLab.com users, use this KAS. - # - grpc://host.docker.internal:8150 # use this attribute when connecting from Docker. - volumeMounts: - - name: token-volume - mountPath: /config - - name: ca-pemstore-volume - mountPath: /tmp/myCA.pem - subPath: myCA.pem +Alternatively, you can configure the agent server (KAS) to read the certificate from a custom directory. +Add the following configuration to `/etc/gitlab/gitlab.rb`: + +```ruby +gitlab_kas['env'] = { + 'SSL_CERT_DIR' => "/opt/gitlab/embedded/ssl/certs/" + } ``` +To apply the changes: + +1. Reconfigure GitLab. + + ```shell + sudo gitlab-ctl reconfigure + ``` + +1. Restart `gitlab-kas`. + + ```shell + gitlab-ctl restart gitlab-kas + ``` + ## Project not found ```json diff --git a/doc/user/group/import/index.md b/doc/user/group/import/index.md index 9064e1533ab..5f4251bbd01 100644 --- a/doc/user/group/import/index.md +++ b/doc/user/group/import/index.md @@ -359,8 +359,8 @@ To solve this, you must change the source group path to include a non-numerical WARNING: This feature was [deprecated](https://gitlab.com/groups/gitlab-org/-/epics/4619) in GitLab 14.6 and replaced by -[migrating groups by direct transfer](#migrate-groups-by-direct-transfer-recommended). To follow progress on a solution for -[offline environments](../../application_security/offline_deployments/index.md), see +[migrating groups by direct transfer](#migrate-groups-by-direct-transfer-recommended). However, this feature is still recommended for migrating groups between +offline systems. To follow progress on an alternative solution for [offline environments](../../application_security/offline_deployments/index.md), see [the relevant epic](https://gitlab.com/groups/gitlab-org/-/epics/8985). Prerequisites: diff --git a/doc/user/project/merge_requests/cherry_pick_changes.md b/doc/user/project/merge_requests/cherry_pick_changes.md index 1dab6bf31cf..d2676b1bdf0 100644 --- a/doc/user/project/merge_requests/cherry_pick_changes.md +++ b/doc/user/project/merge_requests/cherry_pick_changes.md @@ -72,7 +72,8 @@ To cherry-pick a commit from the list of all commits for a project: 1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Repository > Commits**. -1. Select the title of the commit you want to cherry-pick. +1. Select the [title](https://git-scm.com/docs/git-commit#_discussion) of the commit you want to cherry-pick. +1. In the upper-right corner, select **Options > Cherry-pick** to show the cherry-pick modal. 1. In the modal window, select the project and branch to cherry-pick into. 1. Optional. Select **Start a new merge request with these changes**. 1. Select **Cherry-pick**. @@ -86,7 +87,7 @@ list of commits included in a merge request: 1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Merge requests**, and find your merge request. 1. In the merge request's secondary menu, select **Commits** to display the commit details page. -1. Select the title of the commit you want to cherry-pick. +1. Select the [title](https://git-scm.com/docs/git-commit#_discussion) of the commit you want to cherry-pick. 1. In the upper-right corner, select **Options > Cherry-pick** to show the cherry-pick modal. 1. In the modal window, select the project and branch to cherry-pick into. 1. Optional. Select **Start a new merge request with these changes**. @@ -100,7 +101,8 @@ when you view that file in your project's Git repository: 1. On the top bar, select **Main menu > Projects** and find your project. 1. On the left sidebar, select **Repository > Files** and go to the file changed by the commit. -1. Select **History**, then select the title of the commit you want to cherry-pick. +1. Select **History**, then select the [title](https://git-scm.com/docs/git-commit#_discussion) + of the commit you want to cherry-pick. 1. In the upper-right corner, select **Options > Cherry-pick** to show the cherry-pick modal. 1. In the modal window, select the project and branch to cherry-pick into. 1. Optional. Select **Start a new merge request with these changes**. diff --git a/lib/gitlab/usage_data.rb b/lib/gitlab/usage_data.rb index 97d62c91d0d..20aafa277f1 100644 --- a/lib/gitlab/usage_data.rb +++ b/lib/gitlab/usage_data.rb @@ -333,24 +333,10 @@ module Gitlab end def jira_usage - # Jira Cloud does not support custom domains as per https://jira.atlassian.com/browse/CLOUD-6999 - # so we can just check for subdomains of atlassian.net - jira_integration_data_hash = jira_integration_data - if jira_integration_data_hash.nil? - return { projects_jira_server_active: FALLBACK, projects_jira_cloud_active: FALLBACK } - end - - results = { - projects_jira_server_active: 0, - projects_jira_cloud_active: 0, + { projects_jira_dvcs_cloud_active: count(ProjectFeatureUsage.with_jira_dvcs_integration_enabled), projects_jira_dvcs_server_active: count(ProjectFeatureUsage.with_jira_dvcs_integration_enabled(cloud: false)) } - - results[:projects_jira_server_active] = jira_integration_data_hash[:projects_jira_server_active] - results[:projects_jira_cloud_active] = jira_integration_data_hash[:projects_jira_cloud_active] - - results end # rubocop: enable CodeReuse/ActiveRecord @@ -525,7 +511,6 @@ module Gitlab # Omitted because no user, creator or author associated: `boards`, `labels`, `milestones`, `uploads` # Omitted because too expensive: `epics_deepest_relationship_level` - # Omitted because of encrypted properties: `projects_jira_cloud_active`, `projects_jira_server_active` # rubocop: disable CodeReuse/ActiveRecord def usage_activity_by_stage_plan(time_period) time_frame = metric_time_period(time_period) diff --git a/lib/gitlab/usage_data_non_sql_metrics.rb b/lib/gitlab/usage_data_non_sql_metrics.rb index 79d4b45a1ce..71386a58ba7 100644 --- a/lib/gitlab/usage_data_non_sql_metrics.rb +++ b/lib/gitlab/usage_data_non_sql_metrics.rb @@ -40,13 +40,6 @@ module Gitlab def minimum_id(model, column = nil) end - - def jira_integration_data - { - projects_jira_server_active: 0, - projects_jira_cloud_active: 0 - } - end end end end diff --git a/lib/gitlab/usage_data_queries.rb b/lib/gitlab/usage_data_queries.rb index 3a163e5dde9..534a08cad9a 100644 --- a/lib/gitlab/usage_data_queries.rb +++ b/lib/gitlab/usage_data_queries.rb @@ -68,13 +68,6 @@ module Gitlab end end - def jira_integration_data - { - projects_jira_server_active: 0, - projects_jira_cloud_active: 0 - } - end - def topology_usage_data { duration_s: 0, diff --git a/lib/gitlab/utils/usage_data.rb b/lib/gitlab/utils/usage_data.rb index fab8617bcda..4106084b301 100644 --- a/lib/gitlab/utils/usage_data.rb +++ b/lib/gitlab/utils/usage_data.rb @@ -255,33 +255,6 @@ module Gitlab end end - # rubocop: disable UsageData/LargeTable: - def jira_integration_data - with_metadata do - data = { - projects_jira_server_active: 0, - projects_jira_cloud_active: 0 - } - - # rubocop: disable CodeReuse/ActiveRecord - ::Integrations::Jira.active.includes(:jira_tracker_data).find_in_batches(batch_size: 100) do |services| - counts = services.group_by do |service| - # TODO: Simplify as part of https://gitlab.com/gitlab-org/gitlab/issues/29404 - service_url = service.data_fields&.url || (service.properties && service.properties['url']) - service_url&.include?('.atlassian.net') ? :cloud : :server - end - - data[:projects_jira_server_active] += counts[:server].size if counts[:server] - data[:projects_jira_cloud_active] += counts[:cloud].size if counts[:cloud] - end - - data - end - end - - # rubocop: enable CodeReuse/ActiveRecord - # rubocop: enable UsageData/LargeTable: - def minimum_id(model, column = nil) key = :"#{model.name.downcase.gsub('::', '_')}_minimum_id" column_to_read = column || :id diff --git a/lib/tasks/contracts/merge_requests.rake b/lib/tasks/contracts/merge_requests.rake index 5a6186d393d..049e4e41092 100644 --- a/lib/tasks/contracts/merge_requests.rake +++ b/lib/tasks/contracts/merge_requests.rake @@ -38,7 +38,7 @@ namespace :contracts do end desc 'Run all merge request contract tests' - task 'test:merge_requests', :contract_merge_requests do |_t, arg| + task 'test:merge_requests', :contract_merge_requests do |_t| errors = %w[get_diffs_batch get_diffs_metadata get_discussions].each_with_object([]) do |task, err| Rake::Task["contracts:merge_requests:pact:verify:#{task}"].execute rescue StandardError, SystemExit diff --git a/lib/tasks/contracts/pipeline_schedules.rake b/lib/tasks/contracts/pipeline_schedules.rake index f3e65b94940..2733ad41de6 100644 --- a/lib/tasks/contracts/pipeline_schedules.rake +++ b/lib/tasks/contracts/pipeline_schedules.rake @@ -20,7 +20,7 @@ namespace :contracts do end desc 'Run all pipeline schedule contract tests' - task 'test:pipeline_schedules', :contract_pipeline_schedules do |_t, arg| + task 'test:pipeline_schedules', :contract_pipeline_schedules do |_t| errors = %w[ update_pipeline_schedule ].each_with_object([]) do |task, err| diff --git a/lib/tasks/contracts/pipelines.rake b/lib/tasks/contracts/pipelines.rake index 13c973f1358..08e0a8b0319 100644 --- a/lib/tasks/contracts/pipelines.rake +++ b/lib/tasks/contracts/pipelines.rake @@ -47,7 +47,7 @@ namespace :contracts do end desc 'Run all pipeline contract tests' - task 'test:pipelines', :contract_pipelines do |_t, arg| + task 'test:pipelines', :contract_pipelines do |_t| errors = %w[ create_a_new_pipeline get_list_project_pipelines diff --git a/qa/qa/fixtures/mocks/import/github.yml b/qa/qa/fixtures/mocks/import/github.yml index 9cabdee1025..b8e137abfbb 100644 --- a/qa/qa/fixtures/mocks/import/github.yml +++ b/qa/qa/fixtures/mocks/import/github.yml @@ -2741,3 +2741,77 @@ }, "url": "https://api.github.com/repos/gitlab-qa-github/import-test/branches/release/protection" } + +- request: + path: /repos/gitlab-qa-github/import-test/collaborators + method: GET + query_params: + page: '1' + per_page: '100' + headers: + Host: api.github.com + response: + status: 200 + headers: + Content-Type: application/json; charset=utf-8 + X-Ratelimit-Limit: '5000' + X-Ratelimit-Remaining: '5000' + body: | + [ + { + "avatar_url": "https://avatars.githubusercontent.com/u/40021320?v=4", + "events_url": "https://api.github.com/users/gitlab-qa/events{/privacy}", + "followers_url": "https://api.github.com/users/gitlab-qa/followers", + "following_url": "https://api.github.com/users/gitlab-qa/following{/other_user}", + "gists_url": "https://api.github.com/users/gitlab-qa/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/gitlab-qa", + "id": 40021320, + "login": "gitlab-qa", + "node_id": "MDQ6VXNlcjQwMDIxMzIw", + "organizations_url": "https://api.github.com/users/gitlab-qa/orgs", + "permissions": { + "admin": false, + "maintain": false, + "pull": true, + "push": true, + "triage": true + }, + "received_events_url": "https://api.github.com/users/gitlab-qa/received_events", + "repos_url": "https://api.github.com/users/gitlab-qa/repos", + "role_name": "write", + "site_admin": false, + "starred_url": "https://api.github.com/users/gitlab-qa/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gitlab-qa/subscriptions", + "type": "User", + "url": "https://api.github.com/users/gitlab-qa" + }, + { + "avatar_url": "https://avatars.githubusercontent.com/u/59606922?v=4", + "events_url": "https://api.github.com/users/gitlab-qa-github/events{/privacy}", + "followers_url": "https://api.github.com/users/gitlab-qa-github/followers", + "following_url": "https://api.github.com/users/gitlab-qa-github/following{/other_user}", + "gists_url": "https://api.github.com/users/gitlab-qa-github/gists{/gist_id}", + "gravatar_id": "", + "html_url": "https://github.com/gitlab-qa-github", + "id": 59606922, + "login": "gitlab-qa-github", + "node_id": "MDQ6VXNlcjU5NjA2OTIy", + "organizations_url": "https://api.github.com/users/gitlab-qa-github/orgs", + "permissions": { + "admin": true, + "maintain": true, + "pull": true, + "push": true, + "triage": true + }, + "received_events_url": "https://api.github.com/users/gitlab-qa-github/received_events", + "repos_url": "https://api.github.com/users/gitlab-qa-github/repos", + "role_name": "admin", + "site_admin": false, + "starred_url": "https://api.github.com/users/gitlab-qa-github/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gitlab-qa-github/subscriptions", + "type": "User", + "url": "https://api.github.com/users/gitlab-qa-github" + } + ] diff --git a/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb b/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb index ecf8717be87..31f520e9049 100644 --- a/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb +++ b/qa/qa/specs/features/api/1_manage/import/import_github_repo_spec.rb @@ -1,10 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Manage', product_group: :import, quarantine: { - type: :stale, - issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/394994' - } do + RSpec.describe 'Manage', product_group: :import do describe 'GitHub import' do include_context 'with github import' @@ -34,6 +31,7 @@ module QA pull_request: 1, pull_request_review: 2, pull_request_review_request: 1, + collaborator: 2, diff_note: 1, label: 9, milestone: 1, diff --git a/qa/qa/specs/features/browser_ui/1_manage/import/import_github_repo_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/import/import_github_repo_spec.rb index 6cb777ba7f4..b5a8df15ddc 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/import/import_github_repo_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/import/import_github_repo_spec.rb @@ -1,10 +1,7 @@ # frozen_string_literal: true module QA - RSpec.describe 'Manage', product_group: :import, quarantine: { - type: :stale, - issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/394994' - } do + RSpec.describe 'Manage', product_group: :import do describe 'GitHub import' do include_context 'with github import' diff --git a/spec/contracts/provider/helpers/contract_source_helper.rb b/spec/contracts/provider/helpers/contract_source_helper.rb index f59f228722d..e1891b316f3 100644 --- a/spec/contracts/provider/helpers/contract_source_helper.rb +++ b/spec/contracts/provider/helpers/contract_source_helper.rb @@ -2,7 +2,6 @@ module Provider module ContractSourceHelper - QA_PACT_BROKER_HOST = "http://localhost:9292/pacts" PREFIX_PATHS = { rake: { ce: "../../contracts/project", @@ -10,7 +9,7 @@ module Provider }, spec: "../contracts/project" }.freeze - SUB_PATH_REGEX = %r{project/(?<file_path>.*?)_helper.rb}.freeze + SUB_PATH_REGEX = %r{project/(?<file_path>.*?)_helper.rb} class << self def contract_location(requester:, file_path:, edition: :ce) @@ -26,7 +25,7 @@ module Provider provider_url = "provider/#{construct_provider_url_path(file_path)}" consumer_url = "consumer/#{construct_consumer_url_path(file_path)}" - "#{QA_PACT_BROKER_HOST}/#{provider_url}/#{consumer_url}/latest" + "#{ENV['QA_PACT_BROKER_HOST']}/pacts/#{provider_url}/#{consumer_url}/latest" end def construct_provider_url_path(file_path) diff --git a/spec/contracts/provider_specs/helpers/provider/contract_source_helper_spec.rb b/spec/contracts/provider_specs/helpers/provider/contract_source_helper_spec.rb index 27a455adeb2..18da71e0601 100644 --- a/spec/contracts/provider_specs/helpers/provider/contract_source_helper_spec.rb +++ b/spec/contracts/provider_specs/helpers/provider/contract_source_helper_spec.rb @@ -54,8 +54,12 @@ RSpec.describe Provider::ContractSourceHelper, feature_category: :shared do end describe '#pact_broker_url' do + before do + stub_env('QA_PACT_BROKER_HOST', 'http://localhost') + end + it 'returns the full url to the contract that the provider test is verifying' do - contract_url_path = "http://localhost:9292/pacts/provider/" \ + contract_url_path = "http://localhost/pacts/provider/" \ "#{provider_url_path}/consumer/#{consumer_url_path}/latest" expect(subject.pact_broker_url(split_pact_helper_path)).to eq(contract_url_path) diff --git a/spec/contracts/publish-contracts.sh b/spec/contracts/publish-contracts.sh index 8b9d4b6ecc6..b50ba9afae8 100644 --- a/spec/contracts/publish-contracts.sh +++ b/spec/contracts/publish-contracts.sh @@ -1,6 +1,5 @@ LATEST_SHA=$(git rev-parse HEAD) GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD) -BROKER_BASE_URL="http://localhost:9292" cd "${0%/*}" || exit 1 @@ -18,7 +17,7 @@ function publish_contract () { for contract in $CONTRACTS do printf "\e[32mPublishing %s...\033[0m\n" "$contract" - pact-broker publish "$contract" --consumer-app-version "$LATEST_SHA" --branch "$GIT_BRANCH" --broker-base-url "$BROKER_BASE_URL" --output json + pact-broker publish "$contract" --consumer-app-version "$LATEST_SHA" --branch "$GIT_BRANCH" --broker-base-url "$QA_PACT_BROKER_HOST" --output json done if [ ${ERROR} = 1 ]; then diff --git a/spec/lib/gitlab/analytics/cycle_analytics/average_spec.rb b/spec/lib/gitlab/analytics/cycle_analytics/average_spec.rb index de325454b34..122a94a39c2 100644 --- a/spec/lib/gitlab/analytics/cycle_analytics/average_spec.rb +++ b/spec/lib/gitlab/analytics/cycle_analytics/average_spec.rb @@ -40,7 +40,7 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Average do subject(:average_duration_in_seconds) { average.seconds } context 'when no results' do - let(:query) { Issue.none } + let(:query) { Issue.joins(:metrics).none } it { is_expected.to eq(nil) } end @@ -54,7 +54,7 @@ RSpec.describe Gitlab::Analytics::CycleAnalytics::Average do subject(:average_duration_in_days) { average.days } context 'when no results' do - let(:query) { Issue.none } + let(:query) { Issue.joins(:metrics).none } it { is_expected.to eq(nil) } end diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index 53d7e3c1eac..6f445de8aee 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -529,8 +529,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic expect(count_data[:projects_prometheus_active]).to eq(1) expect(count_data[:projects_jenkins_active]).to eq(1) 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) @@ -614,14 +612,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic it 'raises an error' do expect { subject }.to raise_error(ActiveRecord::StatementInvalid) end - - context 'when metric calls find_in_batches' do - let(:metric_method) { :find_in_batches } - - it 'raises an error for jira_usage' do - expect { described_class.jira_usage }.to raise_error(ActiveRecord::StatementInvalid) - end - end end context 'with should_raise_for_dev? false' do @@ -630,14 +620,6 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures, feature_category: :servic it 'does not raise an error' do expect { subject }.not_to raise_error end - - context 'when metric calls find_in_batches' do - let(:metric_method) { :find_in_batches } - - it 'does not raise an error for jira_usage' do - expect { described_class.jira_usage }.not_to raise_error - end - end end end diff --git a/spec/models/integrations/campfire_spec.rb b/spec/models/integrations/campfire_spec.rb index afb0d180673..38d3d89cdbf 100644 --- a/spec/models/integrations/campfire_spec.rb +++ b/spec/models/integrations/campfire_spec.rb @@ -93,7 +93,9 @@ RSpec.describe Integrations::Campfire, feature_category: :integrations do subject { described_class.new.log_error('error') } it 'logs an error' do - expect(Gitlab::IntegrationsLogger).to receive(:error).with(anything).and_call_original + expect(Gitlab::IntegrationsLogger).to receive(:error).with( + hash_including(integration_class: 'Integrations::Campfire', message: 'error') + ).and_call_original is_expected.to be_truthy end diff --git a/spec/models/members/project_member_spec.rb b/spec/models/members/project_member_spec.rb index f0069b89494..f2bc9b42b77 100644 --- a/spec/models/members/project_member_spec.rb +++ b/spec/models/members/project_member_spec.rb @@ -9,7 +9,7 @@ RSpec.describe ProjectMember do describe 'validations' do it { is_expected.to allow_value('Project').for(:source_type) } - it { is_expected.not_to allow_value('project').for(:source_type) } + it { is_expected.not_to allow_value('Group').for(:source_type) } it { is_expected.to validate_inclusion_of(:access_level).in_array(Gitlab::Access.values) } end diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 0d546b8d17f..03aa6d60796 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -3964,21 +3964,7 @@ RSpec.describe Project, factory_default: :keep, feature_category: :projects do end describe '#ancestors' do - context 'with linear_project_ancestors feature flag enabled' do - before do - stub_feature_flags(linear_project_ancestors: true) - end - - include_examples '#ancestors' - end - - context 'with linear_project_ancestors feature flag disabled' do - before do - stub_feature_flags(linear_project_ancestors: false) - end - - include_examples '#ancestors' - end + include_examples '#ancestors' end describe '#ancestors_upto' do diff --git a/spec/requests/api/ci/pipelines_spec.rb b/spec/requests/api/ci/pipelines_spec.rb index 6d69da85449..4e81a052ecf 100644 --- a/spec/requests/api/ci/pipelines_spec.rb +++ b/spec/requests/api/ci/pipelines_spec.rb @@ -25,7 +25,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do it_behaves_like 'pipelines visibility table' context 'authorized user' do - it 'returns project pipelines' do + it 'returns project pipelines', :aggregate_failures do get api("/projects/#{project.id}/pipelines", user) expect(response).to have_gitlab_http_status(:ok) @@ -52,7 +52,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do create(:ci_pipeline, project: project, status: target) end - it 'returns matched pipelines' do + it 'returns matched pipelines', :aggregate_failures do get api("/projects/#{project.id}/pipelines", user), params: { scope: target } expect(response).to have_gitlab_http_status(:ok) @@ -307,7 +307,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'unauthorized user' do - it 'does not return project pipelines' do + it 'does not return project pipelines', :aggregate_failures do get api("/projects/#{project.id}/pipelines", non_member) expect(response).to have_gitlab_http_status(:not_found) @@ -335,13 +335,13 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'authorized user' do - it 'returns pipeline jobs' do + it 'returns pipeline jobs', :aggregate_failures do expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an Array end - it 'returns correct values' do + it 'returns correct values', :aggregate_failures do expect(json_response).not_to be_empty expect(json_response.first['commit']['id']).to eq project.commit.id expect(Time.parse(json_response.first['artifacts_expire_at'])).to be_like_time(job.artifacts_expire_at) @@ -354,7 +354,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do let(:api_endpoint) { "/projects/#{project.id}/pipelines/#{pipeline.id}/jobs" } end - it 'returns pipeline data' do + it 'returns pipeline data', :aggregate_failures do json_job = json_response.first expect(json_job['pipeline']).not_to be_empty @@ -368,7 +368,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'filter jobs with one scope element' do let(:query) { { 'scope' => 'pending' } } - it do + it :aggregate_failures do expect(response).to have_gitlab_http_status(:ok) expect(json_response).to be_an Array @@ -382,7 +382,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'when filtering to only running jobs' do let(:query) { { 'scope' => 'running' } } - it do + it :aggregate_failures do expect(response).to have_gitlab_http_status(:ok) expect(json_response).to be_an Array @@ -402,7 +402,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'filter jobs with array of scope elements' do let(:query) { { scope: %w(pending running) } } - it do + it :aggregate_failures do expect(response).to have_gitlab_http_status(:ok) expect(json_response).to be_an Array end @@ -442,7 +442,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do let_it_be(:successor) { create(:ci_build, :success, name: 'build', pipeline: pipeline) } - it 'does not return retried jobs by default' do + it 'does not return retried jobs by default', :aggregate_failures do expect(json_response).to be_an Array expect(json_response.length).to eq(1) end @@ -450,7 +450,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'when include_retried is false' do let(:query) { { include_retried: false } } - it 'does not return retried jobs' do + it 'does not return retried jobs', :aggregate_failures do expect(json_response).to be_an Array expect(json_response.length).to eq(1) end @@ -459,7 +459,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'when include_retried is true' do let(:query) { { include_retried: true } } - it 'returns retried jobs' do + it 'returns retried jobs', :aggregate_failures do expect(json_response).to be_an Array expect(json_response.length).to eq(2) expect(json_response[0]['name']).to eq(json_response[1]['name']) @@ -469,7 +469,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'no pipeline is found' do - it 'does not return jobs' do + it 'does not return jobs', :aggregate_failures do get api("/projects/#{project2.id}/pipelines/#{pipeline.id}/jobs", user) expect(json_response['message']).to eq '404 Project Not Found' @@ -481,7 +481,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'when user is not logged in' do let(:api_user) { nil } - it 'does not return jobs' do + it 'does not return jobs', :aggregate_failures do expect(json_response['message']).to eq '404 Project Not Found' expect(response).to have_gitlab_http_status(:not_found) end @@ -523,13 +523,13 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'authorized user' do - it 'returns pipeline bridges' do + it 'returns pipeline bridges', :aggregate_failures do expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers expect(json_response).to be_an Array end - it 'returns correct values' do + it 'returns correct values', :aggregate_failures do expect(json_response).not_to be_empty expect(json_response.first['commit']['id']).to eq project.commit.id expect(json_response.first['id']).to eq bridge.id @@ -537,7 +537,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do expect(json_response.first['stage']).to eq bridge.stage end - it 'returns pipeline data' do + it 'returns pipeline data', :aggregate_failures do json_bridge = json_response.first expect(json_bridge['pipeline']).not_to be_empty @@ -548,7 +548,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do expect(json_bridge['pipeline']['status']).to eq bridge.pipeline.status end - it 'returns downstream pipeline data' do + it 'returns downstream pipeline data', :aggregate_failures do json_bridge = json_response.first expect(json_bridge['downstream_pipeline']).not_to be_empty @@ -568,7 +568,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'with one scope element' do let(:query) { { 'scope' => 'pending' } } - it :skip_before_request do + it :skip_before_request, :aggregate_failures do get api("/projects/#{project.id}/pipelines/#{pipeline.id}/bridges", api_user), params: query expect(response).to have_gitlab_http_status(:ok) @@ -581,7 +581,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'with array of scope elements' do let(:query) { { scope: %w(pending running) } } - it :skip_before_request do + it :skip_before_request, :aggregate_failures do get api("/projects/#{project.id}/pipelines/#{pipeline.id}/bridges", api_user), params: query expect(response).to have_gitlab_http_status(:ok) @@ -635,7 +635,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'no pipeline is found' do - it 'does not return bridges' do + it 'does not return bridges', :aggregate_failures do get api("/projects/#{project2.id}/pipelines/#{pipeline.id}/bridges", user) expect(json_response['message']).to eq '404 Project Not Found' @@ -647,7 +647,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'when user is not logged in' do let(:api_user) { nil } - it 'does not return bridges' do + it 'does not return bridges', :aggregate_failures do expect(json_response['message']).to eq '404 Project Not Found' expect(response).to have_gitlab_http_status(:not_found) end @@ -704,7 +704,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do stub_ci_pipeline_to_return_yaml_file end - it 'creates and returns a new pipeline' do + it 'creates and returns a new pipeline', :aggregate_failures do expect do post api("/projects/#{project.id}/pipeline", user), params: { ref: project.default_branch } end.to change { project.ci_pipelines.count }.by(1) @@ -717,7 +717,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'variables given' do let(:variables) { [{ 'variable_type' => 'file', 'key' => 'UPLOAD_TO_S3', 'value' => 'true' }] } - it 'creates and returns a new pipeline using the given variables' do + it 'creates and returns a new pipeline using the given variables', :aggregate_failures do expect do post api("/projects/#{project.id}/pipeline", user), params: { ref: project.default_branch, variables: variables } end.to change { project.ci_pipelines.count }.by(1) @@ -738,7 +738,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do stub_ci_pipeline_yaml_file(config) end - it 'creates and returns a new pipeline using the given variables' do + it 'creates and returns a new pipeline using the given variables', :aggregate_failures do expect do post api("/projects/#{project.id}/pipeline", user), params: { ref: project.default_branch, variables: variables } end.to change { project.ci_pipelines.count }.by(1) @@ -763,7 +763,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end end - it 'fails when using an invalid ref' do + it 'fails when using an invalid ref', :aggregate_failures do post api("/projects/#{project.id}/pipeline", user), params: { ref: 'invalid_ref' } expect(response).to have_gitlab_http_status(:bad_request) @@ -778,7 +778,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do project.update!(auto_devops_attributes: { enabled: false }) end - it 'fails to create pipeline' do + it 'fails to create pipeline', :aggregate_failures do post api("/projects/#{project.id}/pipeline", user), params: { ref: project.default_branch } expect(response).to have_gitlab_http_status(:bad_request) @@ -790,7 +790,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'unauthorized user' do - it 'does not create pipeline' do + it 'does not create pipeline', :aggregate_failures do post api("/projects/#{project.id}/pipeline", non_member), params: { ref: project.default_branch } expect(response).to have_gitlab_http_status(:not_found) @@ -811,21 +811,21 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'authorized user' do - it 'exposes known attributes' do + it 'exposes known attributes', :aggregate_failures do get api("/projects/#{project.id}/pipelines/#{pipeline.id}", user) expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('public_api/v4/pipeline/detail') end - it 'returns project pipeline' do + it 'returns project pipeline', :aggregate_failures do get api("/projects/#{project.id}/pipelines/#{pipeline.id}", user) expect(response).to have_gitlab_http_status(:ok) expect(json_response['sha']).to match(/\A\h{40}\z/) end - it 'returns 404 when it does not exist' do + it 'returns 404 when it does not exist', :aggregate_failures do get api("/projects/#{project.id}/pipelines/#{non_existing_record_id}", user) expect(response).to have_gitlab_http_status(:not_found) @@ -847,7 +847,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'unauthorized user' do - it 'does not return a project pipeline' do + it 'does not return a project pipeline', :aggregate_failures do get api("/projects/#{project.id}/pipelines/#{pipeline.id}", non_member) expect(response).to have_gitlab_http_status(:not_found) @@ -863,7 +863,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do create(:ci_pipeline, source: dangling_source, project: project) end - it 'returns the specified pipeline' do + it 'returns the specified pipeline', :aggregate_failures do get api("/projects/#{project.id}/pipelines/#{dangling_pipeline.id}", user) expect(response).to have_gitlab_http_status(:ok) @@ -887,7 +887,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'default repository branch' do - it 'gets the latest pipleine' do + it 'gets the latest pipleine', :aggregate_failures do get api("/projects/#{project.id}/pipelines/latest", user) expect(response).to have_gitlab_http_status(:ok) @@ -898,7 +898,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'ref parameter' do - it 'gets the latest pipleine' do + it 'gets the latest pipleine', :aggregate_failures do get api("/projects/#{project.id}/pipelines/latest", user), params: { ref: second_branch.name } expect(response).to have_gitlab_http_status(:ok) @@ -910,7 +910,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'unauthorized user' do - it 'does not return a project pipeline' do + it 'does not return a project pipeline', :aggregate_failures do get api("/projects/#{project.id}/pipelines/#{pipeline.id}", non_member) expect(response).to have_gitlab_http_status(:not_found) @@ -926,7 +926,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do let(:api_user) { user } context 'user is a mantainer' do - it 'returns pipeline variables empty' do + it 'returns pipeline variables empty', :aggregate_failures do subject expect(response).to have_gitlab_http_status(:ok) @@ -936,7 +936,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'with variables' do let!(:variable) { create(:ci_pipeline_variable, pipeline: pipeline, key: 'foo', value: 'bar') } - it 'returns pipeline variables' do + it 'returns pipeline variables', :aggregate_failures do subject expect(response).to have_gitlab_http_status(:ok) @@ -962,7 +962,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do let(:api_user) { pipeline_owner_user } let!(:variable) { create(:ci_pipeline_variable, pipeline: pipeline, key: 'foo', value: 'bar') } - it 'returns pipeline variables' do + it 'returns pipeline variables', :aggregate_failures do subject expect(response).to have_gitlab_http_status(:ok) @@ -987,7 +987,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'user is not a project member' do - it 'does not return pipeline variables' do + it 'does not return pipeline variables', :aggregate_failures do get api("/projects/#{project.id}/pipelines/#{pipeline.id}/variables", non_member) expect(response).to have_gitlab_http_status(:not_found) @@ -1000,14 +1000,14 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'authorized user' do let(:owner) { project.first_owner } - it 'destroys the pipeline' do + it 'destroys the pipeline', :aggregate_failures do delete api("/projects/#{project.id}/pipelines/#{pipeline.id}", owner) expect(response).to have_gitlab_http_status(:no_content) expect { pipeline.reload }.to raise_error(ActiveRecord::RecordNotFound) end - it 'returns 404 when it does not exist' do + it 'returns 404 when it does not exist', :aggregate_failures do delete api("/projects/#{project.id}/pipelines/#{non_existing_record_id}", owner) expect(response).to have_gitlab_http_status(:not_found) @@ -1021,7 +1021,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'when the pipeline has jobs' do let_it_be(:build) { create(:ci_build, project: project, pipeline: pipeline) } - it 'destroys associated jobs' do + it 'destroys associated jobs', :aggregate_failures do delete api("/projects/#{project.id}/pipelines/#{pipeline.id}", owner) expect(response).to have_gitlab_http_status(:no_content) @@ -1044,7 +1044,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'unauthorized user' do context 'when user is not member' do - it 'returns a 404' do + it 'returns a 404', :aggregate_failures do delete api("/projects/#{project.id}/pipelines/#{pipeline.id}", non_member) expect(response).to have_gitlab_http_status(:not_found) @@ -1059,7 +1059,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do project.add_developer(developer) end - it 'returns a 403' do + it 'returns a 403', :aggregate_failures do delete api("/projects/#{project.id}/pipelines/#{pipeline.id}", developer) expect(response).to have_gitlab_http_status(:forbidden) @@ -1078,7 +1078,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do let_it_be(:build) { create(:ci_build, :failed, pipeline: pipeline) } - it 'retries failed builds' do + it 'retries failed builds', :aggregate_failures do expect do post api("/projects/#{project.id}/pipelines/#{pipeline.id}/retry", user) end.to change { pipeline.builds.count }.from(1).to(2) @@ -1089,7 +1089,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'unauthorized user' do - it 'does not return a project pipeline' do + it 'does not return a project pipeline', :aggregate_failures do post api("/projects/#{project.id}/pipelines/#{pipeline.id}/retry", non_member) expect(response).to have_gitlab_http_status(:not_found) @@ -1106,7 +1106,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end end - it 'returns error' do + it 'returns error', :aggregate_failures do post api("/projects/#{project.id}/pipelines/#{pipeline.id}/retry", user) expect(response).to have_gitlab_http_status(:forbidden) @@ -1124,7 +1124,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do let_it_be(:build) { create(:ci_build, :running, pipeline: pipeline) } - context 'authorized user' do + context 'authorized user', :aggregate_failures do it 'retries failed builds', :sidekiq_might_not_need_inline do post api("/projects/#{project.id}/pipelines/#{pipeline.id}/cancel", user) @@ -1140,7 +1140,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do project.add_reporter(reporter) end - it 'rejects the action' do + it 'rejects the action', :aggregate_failures do post api("/projects/#{project.id}/pipelines/#{pipeline.id}/cancel", reporter) expect(response).to have_gitlab_http_status(:forbidden) @@ -1156,7 +1156,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do let(:pipeline) { create(:ci_pipeline, project: project) } context 'when pipeline does not have a test report' do - it 'returns an empty test report' do + it 'returns an empty test report', :aggregate_failures do subject expect(response).to have_gitlab_http_status(:ok) @@ -1167,7 +1167,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'when pipeline has a test report' do let(:pipeline) { create(:ci_pipeline, :with_test_reports, project: project) } - it 'returns the test report' do + it 'returns the test report', :aggregate_failures do subject expect(response).to have_gitlab_http_status(:ok) @@ -1180,7 +1180,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do create(:ci_build, :broken_test_reports, name: 'rspec', pipeline: pipeline) end - it 'returns a suite_error' do + it 'returns a suite_error', :aggregate_failures do subject expect(response).to have_gitlab_http_status(:ok) @@ -1190,7 +1190,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'unauthorized user' do - it 'does not return project pipelines' do + it 'does not return project pipelines', :aggregate_failures do get api("/projects/#{project.id}/pipelines/#{pipeline.id}/test_report", non_member) expect(response).to have_gitlab_http_status(:not_found) @@ -1208,7 +1208,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do let(:pipeline) { create(:ci_pipeline, project: project) } context 'when pipeline does not have a test report summary' do - it 'returns an empty test report summary' do + it 'returns an empty test report summary', :aggregate_failures do subject expect(response).to have_gitlab_http_status(:ok) @@ -1219,7 +1219,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do context 'when pipeline has a test report summary' do let(:pipeline) { create(:ci_pipeline, :with_report_results, project: project) } - it 'returns the test report summary' do + it 'returns the test report summary', :aggregate_failures do subject expect(response).to have_gitlab_http_status(:ok) @@ -1229,7 +1229,7 @@ RSpec.describe API::Ci::Pipelines, feature_category: :continuous_integration do end context 'unauthorized user' do - it 'does not return project pipelines' do + it 'does not return project pipelines', :aggregate_failures do get api("/projects/#{project.id}/pipelines/#{pipeline.id}/test_report_summary", non_member) expect(response).to have_gitlab_http_status(:not_found) diff --git a/spec/requests/api/ci/runners_reset_registration_token_spec.rb b/spec/requests/api/ci/runners_reset_registration_token_spec.rb index 1110dbf5fbc..98edde93e95 100644 --- a/spec/requests/api/ci/runners_reset_registration_token_spec.rb +++ b/spec/requests/api/ci/runners_reset_registration_token_spec.rb @@ -3,10 +3,12 @@ require 'spec_helper' RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do - subject { post api("#{prefix}/runners/reset_registration_token", user) } + let_it_be(:admin_mode) { false } + + subject { post api("#{prefix}/runners/reset_registration_token", user, admin_mode: admin_mode) } shared_examples 'bad request' do |result| - it 'returns 400 error' do + it 'returns 400 error', :aggregate_failures do expect { subject }.not_to change { get_token } expect(response).to have_gitlab_http_status(:bad_request) @@ -15,7 +17,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end shared_examples 'unauthenticated' do - it 'returns 401 error' do + it 'returns 401 error', :aggregate_failures do expect { subject }.not_to change { get_token } expect(response).to have_gitlab_http_status(:unauthorized) @@ -23,7 +25,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end shared_examples 'unauthorized' do - it 'returns 403 error' do + it 'returns 403 error', :aggregate_failures do expect { subject }.not_to change { get_token } expect(response).to have_gitlab_http_status(:forbidden) @@ -31,7 +33,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end shared_examples 'not found' do |scope| - it 'returns 404 error' do + it 'returns 404 error', :aggregate_failures do expect { subject }.not_to change { get_token } expect(response).to have_gitlab_http_status(:not_found) @@ -58,7 +60,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end shared_context 'when authorized' do |scope| - it 'resets runner registration token' do + it 'resets runner registration token', :aggregate_failures do expect { subject }.to change { get_token } expect(response).to have_gitlab_http_status(:success) @@ -99,6 +101,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do include_context 'when authorized', 'instance' do let_it_be(:user) { create(:user, :admin) } + let_it_be(:admin_mode) { true } def get_token ApplicationSetting.current_without_cache.runners_registration_token diff --git a/spec/requests/api/ci/runners_spec.rb b/spec/requests/api/ci/runners_spec.rb index ca051386265..ec9b5621c37 100644 --- a/spec/requests/api/ci/runners_spec.rb +++ b/spec/requests/api/ci/runners_spec.rb @@ -35,7 +35,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do describe 'GET /runners' do context 'authorized user' do - it 'returns response status and headers' do + it 'returns response status and headers', :aggregate_failures do get api('/runners', user) expect(response).to have_gitlab_http_status(:ok) @@ -53,7 +53,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do ] end - it 'filters runners by scope' do + it 'filters runners by scope', :aggregate_failures do create(:ci_runner, :project, :inactive, description: 'Inactive project runner', projects: [project]) get api('/runners?scope=paused', user) @@ -112,7 +112,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do expect(response).to have_gitlab_http_status(:bad_request) end - it 'filters runners by tag_list' do + it 'filters runners by tag_list', :aggregate_failures do create(:ci_runner, :project, description: 'Runner tagged with tag1 and tag2', projects: [project], tag_list: %w[tag1 tag2]) create(:ci_runner, :project, description: 'Runner tagged with tag2', projects: [project], tag_list: ['tag2']) @@ -137,14 +137,14 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do context 'authorized user' do context 'with admin privileges' do it 'returns response status and headers' do - get api('/runners/all', admin) + get api('/runners/all', admin, admin_mode: true) expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers end it 'returns all runners' do - get api('/runners/all', admin) + get api('/runners/all', admin, admin_mode: true) expect(json_response).to match_array [ a_hash_including('description' => 'Project runner', 'is_shared' => false, 'active' => true, 'paused' => false, 'runner_type' => 'project_type'), @@ -155,8 +155,8 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do ] end - it 'filters runners by scope' do - get api('/runners/all?scope=shared', admin) + it 'filters runners by scope', :aggregate_failures do + get api('/runners/all?scope=shared', admin, admin_mode: true) shared = json_response.all? { |r| r['is_shared'] } expect(response).to have_gitlab_http_status(:ok) @@ -166,8 +166,8 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do expect(shared).to be_truthy end - it 'filters runners by scope' do - get api('/runners/all?scope=specific', admin) + it 'filters runners by scope', :aggregate_failures do + get api('/runners/all?scope=specific', admin, admin_mode: true) expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -181,12 +181,12 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end it 'avoids filtering if scope is invalid' do - get api('/runners/all?scope=unknown', admin) + get api('/runners/all?scope=unknown', admin, admin_mode: true) expect(response).to have_gitlab_http_status(:bad_request) end it 'filters runners by project type' do - get api('/runners/all?type=project_type', admin) + get api('/runners/all?type=project_type', admin, admin_mode: true) expect(json_response).to match_array [ a_hash_including('description' => 'Project runner'), @@ -195,7 +195,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end it 'filters runners by group type' do - get api('/runners/all?type=group_type', admin) + get api('/runners/all?type=group_type', admin, admin_mode: true) expect(json_response).to match_array [ a_hash_including('description' => 'Group runner A'), @@ -204,7 +204,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end it 'does not filter by invalid type' do - get api('/runners/all?type=bogus', admin) + get api('/runners/all?type=bogus', admin, admin_mode: true) expect(response).to have_gitlab_http_status(:bad_request) end @@ -213,7 +213,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do let_it_be(:runner) { create(:ci_runner, :project, :inactive, description: 'Inactive project runner', projects: [project]) } it 'filters runners by status' do - get api('/runners/all?paused=true', admin) + get api('/runners/all?paused=true', admin, admin_mode: true) expect(json_response).to match_array [ a_hash_including('description' => 'Inactive project runner') @@ -221,7 +221,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end it 'filters runners by status' do - get api('/runners/all?status=paused', admin) + get api('/runners/all?status=paused', admin, admin_mode: true) expect(json_response).to match_array [ a_hash_including('description' => 'Inactive project runner') @@ -230,16 +230,16 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end it 'does not filter by invalid status' do - get api('/runners/all?status=bogus', admin) + get api('/runners/all?status=bogus', admin, admin_mode: true) expect(response).to have_gitlab_http_status(:bad_request) end - it 'filters runners by tag_list' do + it 'filters runners by tag_list', :aggregate_failures do create(:ci_runner, :project, description: 'Runner tagged with tag1 and tag2', projects: [project], tag_list: %w[tag1 tag2]) create(:ci_runner, :project, description: 'Runner tagged with tag2', projects: [project], tag_list: ['tag2']) - get api('/runners/all?tag_list=tag1,tag2', admin) + get api('/runners/all?tag_list=tag1,tag2', admin, admin_mode: true) expect(json_response).to match_array [ a_hash_including('description' => 'Runner tagged with tag1 and tag2') @@ -268,7 +268,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do describe 'GET /runners/:id' do context 'admin user' do context 'when runner is shared' do - it "returns runner's details" do + it "returns runner's details", :aggregate_failures do get api("/runners/#{shared_runner.id}", admin) expect(response).to have_gitlab_http_status(:ok) @@ -284,39 +284,39 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do context 'when unused runner is present' do let!(:unused_project_runner) { create(:ci_runner, :project, :without_projects) } - it 'deletes unused runner' do + it 'deletes unused runner', :aggregate_failures do expect do - delete api("/runners/#{unused_project_runner.id}", admin) + delete api("/runners/#{unused_project_runner.id}", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:no_content) end.to change { ::Ci::Runner.project_type.count }.by(-1) end end - it "returns runner's details" do - get api("/runners/#{project_runner.id}", admin) + it "returns runner's details", :aggregate_failures do + get api("/runners/#{project_runner.id}", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:ok) expect(json_response['description']).to eq(project_runner.description) end it "returns the project's details for a project runner" do - get api("/runners/#{project_runner.id}", admin) + get api("/runners/#{project_runner.id}", admin, admin_mode: true) expect(json_response['projects'].first['id']).to eq(project.id) end end it 'returns 404 if runner does not exist' do - get api('/runners/0', admin) + get api('/runners/0', admin, admin_mode: true) expect(response).to have_gitlab_http_status(:not_found) end end context 'when the runner is a group runner' do - it "returns the runner's details" do - get api("/runners/#{group_runner_a.id}", admin) + it "returns the runner's details", :aggregate_failures do + get api("/runners/#{group_runner_a.id}", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:ok) expect(json_response['description']).to eq(group_runner_a.description) @@ -326,7 +326,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do context "runner project's administrative user" do context 'when runner is not shared' do - it "returns runner's details" do + it "returns runner's details", :aggregate_failures do get api("/runners/#{project_runner.id}", user) expect(response).to have_gitlab_http_status(:ok) @@ -335,7 +335,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end context 'when runner is shared' do - it "returns runner's details" do + it "returns runner's details", :aggregate_failures do get api("/runners/#{shared_runner.id}", user) expect(response).to have_gitlab_http_status(:ok) @@ -373,7 +373,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do expect(shared_runner.reload.description).to eq("#{description}_updated") end - it 'runner active state' do + it 'runner active state', :aggregate_failures do active = shared_runner.active update_runner(shared_runner.id, admin, active: !active) @@ -381,7 +381,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do expect(shared_runner.reload.active).to eq(!active) end - it 'runner paused state' do + it 'runner paused state', :aggregate_failures do active = shared_runner.active update_runner(shared_runner.id, admin, paused: active) @@ -389,14 +389,14 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do expect(shared_runner.reload.active).to eq(!active) end - it 'runner tag list' do + it 'runner tag list', :aggregate_failures do update_runner(shared_runner.id, admin, tag_list: ['ruby2.1', 'pgsql', 'mysql']) expect(response).to have_gitlab_http_status(:ok) expect(shared_runner.reload.tag_list).to include('ruby2.1', 'pgsql', 'mysql') end - it 'unrelated runner attribute on an existing runner with too many tags' do + it 'unrelated runner attribute on an existing runner with too many tags', :aggregate_failures do # This test ensures that it is possible to update any attribute on a runner that currently fails the # validation that ensures that there aren't too many tags associated with a runner existing_invalid_shared_runner = build(:ci_runner, :instance, tag_list: (1..::Ci::Runner::TAG_LIST_MAX_LENGTH + 1).map { |i| "tag#{i}" }) @@ -409,7 +409,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do expect(existing_invalid_shared_runner.reload.active).to eq(!active) end - it 'runner untagged flag' do + it 'runner untagged flag', :aggregate_failures do # Ensure tag list is non-empty before setting untagged to false. update_runner(shared_runner.id, admin, tag_list: ['ruby2.1', 'pgsql', 'mysql']) update_runner(shared_runner.id, admin, run_untagged: 'false') @@ -418,28 +418,28 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do expect(shared_runner.reload.run_untagged?).to be(false) end - it 'runner unlocked flag' do + it 'runner unlocked flag', :aggregate_failures do update_runner(shared_runner.id, admin, locked: 'true') expect(response).to have_gitlab_http_status(:ok) expect(shared_runner.reload.locked?).to be(true) end - it 'runner access level' do + it 'runner access level', :aggregate_failures do update_runner(shared_runner.id, admin, access_level: 'ref_protected') expect(response).to have_gitlab_http_status(:ok) expect(shared_runner.reload.ref_protected?).to be_truthy end - it 'runner maximum timeout' do + it 'runner maximum timeout', :aggregate_failures do update_runner(shared_runner.id, admin, maximum_timeout: 1234) expect(response).to have_gitlab_http_status(:ok) expect(shared_runner.reload.maximum_timeout).to eq(1234) end - it 'fails with no parameters' do + it 'fails with no parameters', :aggregate_failures do put api("/runners/#{shared_runner.id}", admin) shared_runner.reload @@ -448,7 +448,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end context 'when runner is shared' do - it 'updates runner' do + it 'updates runner', :aggregate_failures do description = shared_runner.description active = shared_runner.active runner_queue_value = shared_runner.ensure_runner_queue_value @@ -476,7 +476,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end context 'when runner is not shared' do - it 'updates runner' do + it 'updates runner', :aggregate_failures do description = project_runner.description runner_queue_value = project_runner.ensure_runner_queue_value @@ -498,14 +498,16 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end def update_runner(id, user, args) - put api("/runners/#{id}", user), params: args + put api("/runners/#{id}", user, admin_mode: true), params: args end end context 'authorized user' do + let_it_be(:params) { { description: 'test' } } + context 'when runner is shared' do it 'does not update runner' do - put api("/runners/#{shared_runner.id}", user), params: { description: 'test' } + put api("/runners/#{shared_runner.id}", user), params: params expect(response).to have_gitlab_http_status(:forbidden) end @@ -518,12 +520,11 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do expect(response).to have_gitlab_http_status(:forbidden) end - it 'updates project runner with access to it' do + it 'updates project runner with access to it', :aggregate_failures do description = project_runner.description - put api("/runners/#{project_runner.id}", admin), params: { description: 'test' } + put api("/runners/#{project_runner.id}", admin, admin_mode: true), params: params project_runner.reload - expect(response).to have_gitlab_http_status(:ok) expect(project_runner.description).to eq('test') expect(project_runner.description).not_to eq(description) end @@ -542,13 +543,13 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do describe 'DELETE /runners/:id' do context 'admin user' do context 'when runner is shared' do - it 'deletes runner' do + it 'deletes runner', :aggregate_failures do expect_next_instance_of(Ci::Runners::UnregisterRunnerService, shared_runner, admin) do |service| expect(service).to receive(:execute).once.and_call_original end expect do - delete api("/runners/#{shared_runner.id}", admin) + delete api("/runners/#{shared_runner.id}", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:no_content) end.to change { ::Ci::Runner.instance_type.count }.by(-1) @@ -560,25 +561,25 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end context 'when runner is not shared' do - it 'deletes used project runner' do + it 'deletes used project runner', :aggregate_failures do expect_next_instance_of(Ci::Runners::UnregisterRunnerService, project_runner, admin) do |service| expect(service).to receive(:execute).once.and_call_original end expect do - delete api("/runners/#{project_runner.id}", admin) + delete api("/runners/#{project_runner.id}", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:no_content) end.to change { ::Ci::Runner.project_type.count }.by(-1) end end - it 'returns 404 if runner does not exist' do + it 'returns 404 if runner does not exist', :aggregate_failures do allow_next_instance_of(Ci::Runners::UnregisterRunnerService) do |service| expect(service).not_to receive(:execute) end - delete api('/runners/0', admin) + delete api('/runners/0', admin, admin_mode: true) expect(response).to have_gitlab_http_status(:not_found) end @@ -603,7 +604,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do expect(response).to have_gitlab_http_status(:forbidden) end - it 'deletes project runner for one owned project' do + it 'deletes project runner for one owned project', :aggregate_failures do expect do delete api("/runners/#{project_runner.id}", user) @@ -658,7 +659,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end context 'unauthorized user' do - it 'does not delete project runner' do + it 'does not delete project runner', :aggregate_failures do allow_next_instance_of(Ci::Runners::UnregisterRunnerService) do |service| expect(service).not_to receive(:execute) end @@ -672,31 +673,31 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do describe 'POST /runners/:id/reset_authentication_token' do context 'admin user' do - it 'resets shared runner authentication token' do + it 'resets shared runner authentication token', :aggregate_failures do expect do - post api("/runners/#{shared_runner.id}/reset_authentication_token", admin) + post api("/runners/#{shared_runner.id}/reset_authentication_token", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:success) expect(json_response).to eq({ 'token' => shared_runner.reload.token, 'token_expires_at' => nil }) end.to change { shared_runner.reload.token } end - it 'returns 404 if runner does not exist' do - post api('/runners/0/reset_authentication_token', admin) + it 'returns 404 if runner does not exist', :aggregate_failures do + post api('/runners/0/reset_authentication_token', admin, admin_mode: true) expect(response).to have_gitlab_http_status(:not_found) end end context 'authorized user' do - it 'does not reset project runner authentication token without access to it' do + it 'does not reset project runner authentication token without access to it', :aggregate_failures do expect do post api("/runners/#{project_runner.id}/reset_authentication_token", user2) expect(response).to have_gitlab_http_status(:forbidden) end.not_to change { project_runner.reload.token } end - it 'resets project runner authentication token for owned project' do + it 'resets project runner authentication token for owned project', :aggregate_failures do expect do post api("/runners/#{project_runner.id}/reset_authentication_token", user) @@ -705,7 +706,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end.to change { project_runner.reload.token } end - it 'does not reset group runner authentication token with guest access' do + it 'does not reset group runner authentication token with guest access', :aggregate_failures do expect do post api("/runners/#{group_runner_a.id}/reset_authentication_token", group_guest) @@ -713,7 +714,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end.not_to change { group_runner_a.reload.token } end - it 'does not reset group runner authentication token with reporter access' do + it 'does not reset group runner authentication token with reporter access', :aggregate_failures do expect do post api("/runners/#{group_runner_a.id}/reset_authentication_token", group_reporter) @@ -721,7 +722,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end.not_to change { group_runner_a.reload.token } end - it 'does not reset group runner authentication token with developer access' do + it 'does not reset group runner authentication token with developer access', :aggregate_failures do expect do post api("/runners/#{group_runner_a.id}/reset_authentication_token", group_developer) @@ -729,7 +730,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end.not_to change { group_runner_a.reload.token } end - it 'does not reset group runner authentication token with maintainer access' do + it 'does not reset group runner authentication token with maintainer access', :aggregate_failures do expect do post api("/runners/#{group_runner_a.id}/reset_authentication_token", group_maintainer) @@ -737,7 +738,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end.not_to change { group_runner_a.reload.token } end - it 'resets group runner authentication token with owner access' do + it 'resets group runner authentication token with owner access', :aggregate_failures do expect do post api("/runners/#{group_runner_a.id}/reset_authentication_token", user) @@ -746,7 +747,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end.to change { group_runner_a.reload.token } end - it 'resets group runner authentication token with owner access with expiration time', :freeze_time do + it 'resets group runner authentication token with owner access with expiration time', :aggregate_failures, :freeze_time do expect(group_runner_a.reload.token_expires_at).to be_nil group.update!(runner_token_expiration_interval: 5.days) @@ -763,7 +764,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end context 'unauthorized user' do - it 'does not reset authentication token' do + it 'does not reset authentication token', :aggregate_failures do expect do post api("/runners/#{shared_runner.id}/reset_authentication_token") @@ -783,8 +784,8 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do context 'admin user' do context 'when runner exists' do context 'when runner is shared' do - it 'return jobs' do - get api("/runners/#{shared_runner.id}/jobs", admin) + it 'return jobs', :aggregate_failures do + get api("/runners/#{shared_runner.id}/jobs", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -795,8 +796,8 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end context 'when runner is a project runner' do - it 'return jobs' do - get api("/runners/#{project_runner.id}/jobs", admin) + it 'return jobs', :aggregate_failures do + get api("/runners/#{project_runner.id}/jobs", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -806,7 +807,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end context 'when user does not have authorization to see all jobs' do - it 'shows only jobs it has permission to see' do + it 'shows only jobs it has permission to see', :aggregate_failures do create(:ci_build, :running, runner: two_projects_runner, project: project) create(:ci_build, :running, runner: two_projects_runner, project: project2) @@ -824,8 +825,8 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end context 'when valid status is provided' do - it 'return filtered jobs' do - get api("/runners/#{project_runner.id}/jobs?status=failed", admin) + it 'return filtered jobs', :aggregate_failures do + get api("/runners/#{project_runner.id}/jobs?status=failed", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -838,8 +839,8 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do context 'when valid order_by is provided' do context 'when sort order is not specified' do - it 'return jobs in descending order' do - get api("/runners/#{project_runner.id}/jobs?order_by=id", admin) + it 'return jobs in descending order', :aggregate_failures do + get api("/runners/#{project_runner.id}/jobs?order_by=id", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -851,8 +852,8 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end context 'when sort order is specified as asc' do - it 'return jobs sorted in ascending order' do - get api("/runners/#{project_runner.id}/jobs?order_by=id&sort=asc", admin) + it 'return jobs sorted in ascending order', :aggregate_failures do + get api("/runners/#{project_runner.id}/jobs?order_by=id&sort=asc", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -866,7 +867,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do context 'when invalid status is provided' do it 'return 400' do - get api("/runners/#{project_runner.id}/jobs?status=non-existing", admin) + get api("/runners/#{project_runner.id}/jobs?status=non-existing", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:bad_request) end @@ -874,7 +875,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do context 'when invalid order_by is provided' do it 'return 400' do - get api("/runners/#{project_runner.id}/jobs?order_by=non-existing", admin) + get api("/runners/#{project_runner.id}/jobs?order_by=non-existing", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:bad_request) end @@ -882,7 +883,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do context 'when invalid sort is provided' do it 'return 400' do - get api("/runners/#{project_runner.id}/jobs?sort=non-existing", admin) + get api("/runners/#{project_runner.id}/jobs?sort=non-existing", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:bad_request) end @@ -890,16 +891,16 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end it 'avoids N+1 DB queries' do - get api("/runners/#{shared_runner.id}/jobs", admin) + get api("/runners/#{shared_runner.id}/jobs", admin, admin_mode: true) control = ActiveRecord::QueryRecorder.new do - get api("/runners/#{shared_runner.id}/jobs", admin) + get api("/runners/#{shared_runner.id}/jobs", admin, admin_mode: true) end create(:ci_build, :failed, runner: shared_runner, project: project) expect do - get api("/runners/#{shared_runner.id}/jobs", admin) + get api("/runners/#{shared_runner.id}/jobs", admin, admin_mode: true) end.not_to exceed_query_limit(control.count) end @@ -925,12 +926,12 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do ]).once.and_call_original end - get api("/runners/#{shared_runner.id}/jobs", admin), params: { per_page: 2, order_by: 'id', sort: 'desc' } + get api("/runners/#{shared_runner.id}/jobs", admin, admin_mode: true), params: { per_page: 2, order_by: 'id', sort: 'desc' } end context "when runner doesn't exist" do it 'returns 404' do - get api('/runners/0/jobs', admin) + get api('/runners/0/jobs', admin, admin_mode: true) expect(response).to have_gitlab_http_status(:not_found) end @@ -948,7 +949,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end context 'when runner is a project runner' do - it 'return jobs' do + it 'return jobs', :aggregate_failures do get api("/runners/#{project_runner.id}/jobs", user) expect(response).to have_gitlab_http_status(:ok) @@ -960,7 +961,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end context 'when valid status is provided' do - it 'return filtered jobs' do + it 'return filtered jobs', :aggregate_failures do get api("/runners/#{project_runner.id}/jobs?status=failed", user) expect(response).to have_gitlab_http_status(:ok) @@ -1027,8 +1028,8 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do describe 'GET /projects/:id/runners' do context 'authorized user with maintainer privileges' do - it 'returns response status and headers' do - get api('/runners/all', admin) + it 'returns response status and headers', :aggregate_failures do + get api('/runners/all', admin, admin_mode: true) expect(response).to have_gitlab_http_status(:ok) expect(response).to include_pagination_headers @@ -1044,7 +1045,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do ] end - it 'filters runners by scope' do + it 'filters runners by scope', :aggregate_failures do get api("/projects/#{project.id}/runners?scope=specific", user) expect(response).to have_gitlab_http_status(:ok) @@ -1102,7 +1103,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do expect(response).to have_gitlab_http_status(:bad_request) end - it 'filters runners by tag_list' do + it 'filters runners by tag_list', :aggregate_failures do create(:ci_runner, :project, description: 'Runner tagged with tag1 and tag2', projects: [project], tag_list: %w[tag1 tag2]) create(:ci_runner, :project, description: 'Runner tagged with tag2', projects: [project], tag_list: ['tag2']) @@ -1183,7 +1184,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end end - it 'filters runners by tag_list' do + it 'filters runners by tag_list', :aggregate_failures do create(:ci_runner, :group, description: 'Runner tagged with tag1 and tag2', groups: [group], tag_list: %w[tag1 tag2]) create(:ci_runner, :group, description: 'Runner tagged with tag2', groups: [group], tag_list: %w[tag1]) @@ -1203,21 +1204,21 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do context 'authorized user' do let_it_be(:project_runner2) { create(:ci_runner, :project, projects: [project2]) } - it 'enables project runner' do + it 'enables project runner', :aggregate_failures do expect do post api("/projects/#{project.id}/runners", user), params: { runner_id: project_runner2.id } end.to change { project.runners.count }.by(+1) expect(response).to have_gitlab_http_status(:created) end - it 'avoids changes when enabling already enabled runner' do + it 'avoids changes when enabling already enabled runner', :aggregate_failures do expect do post api("/projects/#{project.id}/runners", user), params: { runner_id: project_runner.id } end.to change { project.runners.count }.by(0) expect(response).to have_gitlab_http_status(:bad_request) end - it 'does not enable locked runner' do + it 'does not enable locked runner', :aggregate_failures do project_runner2.update!(locked: true) expect do @@ -1243,9 +1244,9 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do context 'when project runner is used' do let!(:new_project_runner) { create(:ci_runner, :project) } - it 'enables any project runner' do + it 'enables any project runner', :aggregate_failures do expect do - post api("/projects/#{project.id}/runners", admin), params: { runner_id: new_project_runner.id } + post api("/projects/#{project.id}/runners", admin, admin_mode: true), params: { runner_id: new_project_runner.id } end.to change { project.runners.count }.by(+1) expect(response).to have_gitlab_http_status(:created) end @@ -1255,9 +1256,9 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do create(:plan_limits, :default_plan, ci_registered_project_runners: 1) end - it 'does not enable project runner' do + it 'does not enable project runner', :aggregate_failures do expect do - post api("/projects/#{project.id}/runners", admin), params: { runner_id: new_project_runner.id } + post api("/projects/#{project.id}/runners", admin, admin_mode: true), params: { runner_id: new_project_runner.id } end.not_to change { project.runners.count } expect(response).to have_gitlab_http_status(:bad_request) end @@ -1266,7 +1267,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end it 'raises an error when no runner_id param is provided' do - post api("/projects/#{project.id}/runners", admin) + post api("/projects/#{project.id}/runners", admin, admin_mode: true) expect(response).to have_gitlab_http_status(:bad_request) end @@ -1316,7 +1317,7 @@ RSpec.describe API::Ci::Runners, feature_category: :runner_fleet do end context 'when runner have one associated projects' do - it "does not disable project's runner" do + it "does not disable project's runner", :aggregate_failures do expect do delete api("/projects/#{project.id}/runners/#{project_runner.id}", user) end.to change { project.runners.count }.by(0) diff --git a/spec/serializers/entity_date_helper_spec.rb b/spec/serializers/entity_date_helper_spec.rb index 5a4571339b3..70094991c09 100644 --- a/spec/serializers/entity_date_helper_spec.rb +++ b/spec/serializers/entity_date_helper_spec.rb @@ -47,8 +47,10 @@ RSpec.describe EntityDateHelper do end describe '#remaining_days_in_words' do + let(:current_time) { Time.utc(2017, 3, 17) } + around do |example| - travel_to(Time.utc(2017, 3, 17)) { example.run } + travel_to(current_time) { example.run } end context 'when less than 31 days remaining' do @@ -74,10 +76,10 @@ RSpec.describe EntityDateHelper do expect(milestone_remaining).to eq("<strong>1</strong> day remaining") end - it 'returns 1 day remaining when queried mid-day' do - travel_back + context 'when queried mid-day' do + let(:current_time) { Time.utc(2017, 3, 17, 13, 10) } - travel_to(Time.utc(2017, 3, 17, 13, 10)) do + it 'returns 1 day remaining' do expect(milestone_remaining).to eq("<strong>1</strong> day remaining") end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index fa16603ff70..fb38595f9d4 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -360,13 +360,9 @@ RSpec.configure do |config| # The feature flag is disabled for these specs as long as they are not yet adapted. admin_mode_for_api_feature_flag_paths = %w[ ./spec/requests/api/broadcast_messages_spec.rb - ./spec/requests/api/ci/pipelines_spec.rb - ./spec/requests/api/ci/runners_reset_registration_token_spec.rb - ./spec/requests/api/ci/runners_spec.rb ./spec/requests/api/deploy_keys_spec.rb ./spec/requests/api/deploy_tokens_spec.rb ./spec/requests/api/freeze_periods_spec.rb - ./spec/requests/api/graphql/user/starred_projects_query_spec.rb ./spec/requests/api/groups_spec.rb ./spec/requests/api/issues/get_group_issues_spec.rb ./spec/requests/api/issues/get_project_issues_spec.rb diff --git a/spec/support/helpers/stub_configuration.rb b/spec/support/helpers/stub_configuration.rb index 4ca8f26be9e..2a7b36a4c00 100644 --- a/spec/support/helpers/stub_configuration.rb +++ b/spec/support/helpers/stub_configuration.rb @@ -179,7 +179,7 @@ module StubConfiguration def to_settings(hash) hash.transform_values do |value| if value.is_a? Hash - Settingslogic.new(value.deep_stringify_keys) + Settingslogic.new(value.to_h.deep_stringify_keys) else value end diff --git a/spec/support/helpers/stub_object_storage.rb b/spec/support/helpers/stub_object_storage.rb index 6b633856228..d120e1805e3 100644 --- a/spec/support/helpers/stub_object_storage.rb +++ b/spec/support/helpers/stub_object_storage.rb @@ -15,7 +15,7 @@ module StubObjectStorage direct_upload: false, cdn: {} ) - old_config = Settingslogic.new(config.deep_stringify_keys) + old_config = Settingslogic.new(config.to_h.deep_stringify_keys) new_config = config.to_h.deep_symbolize_keys.merge({ enabled: enabled, proxy_download: proxy_download, @@ -30,7 +30,7 @@ module StubObjectStorage allow(config).to receive(:proxy_download) { proxy_download } allow(config).to receive(:direct_upload) { direct_upload } - uploader_config = Settingslogic.new(new_config.deep_stringify_keys) + uploader_config = Settingslogic.new(new_config.to_h.deep_stringify_keys) allow(uploader).to receive(:object_store_options).and_return(uploader_config) allow(uploader.options).to receive(:object_store).and_return(uploader_config) diff --git a/spec/support/helpers/usage_data_helpers.rb b/spec/support/helpers/usage_data_helpers.rb index 2bec945fbc8..9abfc39e31f 100644 --- a/spec/support/helpers/usage_data_helpers.rb +++ b/spec/support/helpers/usage_data_helpers.rb @@ -54,8 +54,6 @@ module UsageDataHelpers projects_asana_active projects_jenkins_active projects_jira_active - projects_jira_server_active - projects_jira_cloud_active projects_jira_dvcs_cloud_active projects_jira_dvcs_server_active projects_slack_active |