diff options
63 files changed, 440 insertions, 244 deletions
diff --git a/.gitlab/issue_templates/Doc_cleanup.md b/.gitlab/issue_templates/Doc_cleanup.md index 69caea1ae1e..58a51e15803 100644 --- a/.gitlab/issue_templates/Doc_cleanup.md +++ b/.gitlab/issue_templates/Doc_cleanup.md @@ -7,6 +7,26 @@ * feature development should use the Feature Request template. --> +If you are a community contributor: + +1. To work on an issue, type `@gl-docsteam I would like to work on this issue.` + in a comment. A technical writer + will assign the issue to you. Do not work on the issue before it is assigned to you. + If someone has already chosen the issue, pick another or view docs [in the docs directory](https://gitlab.com/gitlab-org/gitlab/-/tree/master/doc) + and open a merge request for any page you feel can be improved. +1. Create a merge request for the issue. If this is for a Hackathon, do not create the merge request + before the Hackathon has started or it will not be counted towards the Hackathon. If you were not + assigned the issue, do not create a merge request. It will not be accepted. +1. Copy the link to this issue and add it to the merge request's description, which will link + the merge request and the issue together. +1. After your merge request is accepted and merged, close this issue. + +If you notice things you'd like to fix that are not part of the issue, open separate merge requests for those issues. + +We're sorry for all the rules but we want everyone to have a good experience, and it can be hard when we get an influx of contributions. + +Thank you again for contributing to the GitLab documentation! + ## Identified documentation issue <!-- @@ -19,19 +39,6 @@ * the opportunities for contributors. --> -## Process - -If you, as a contributor, decide to take this work on, assign this issue to yourself, and create one or more linked -merge requests that resolve this issue. Be sure to close this issue after all linked merge requests are completed. - -The work for this issue should involve only what's listed in the previous section. If you identify other work that -needs to be done, create separate, unlinked MRs as needed to address those items. - -When using automated test results for identified work, use this issue to work only on the listed lines. For -example, if the tests list several lines that show the word "admin" as needing to possibly be "administrator," -do not modify other parts of the page that may also include "admin," as the testing may have excluded those lines -(for example, they may be part of the **Admin Area** of GitLab). - ## Additional information <!-- diff --git a/.gitlab/issue_templates/.gitlab/issue_templates/Vulnerability Disclosure.md b/.gitlab/issue_templates/Vulnerability Disclosure.md index 9f143a76e0e..9f143a76e0e 100644 --- a/.gitlab/issue_templates/.gitlab/issue_templates/Vulnerability Disclosure.md +++ b/.gitlab/issue_templates/Vulnerability Disclosure.md diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a51e9cc1f7c..7c6f42d504f 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -146,25 +146,6 @@ Performance/CollectionLiteralInLoop: Performance/ConstantRegexp: Enabled: false -# Offense count: 14 -# Cop supports --auto-correct. -# Configuration parameters: SafeMultiline. -Performance/DeletePrefix: - Exclude: - - 'app/helpers/submodule_helper.rb' - - 'app/workers/concerns/application_worker.rb' - - 'ee/lib/gitlab/geo/git_ssh_proxy.rb' - - 'lib/banzai/filter/repository_link_filter.rb' - - 'lib/gitlab/auth/ldap/dn.rb' - - 'lib/gitlab/gfm/uploads_rewriter.rb' - - 'lib/gitlab/git/ref.rb' - - 'lib/gitlab/project_template.rb' - - 'lib/gitlab/setup_helper.rb' - - 'lib/gitlab/time_tracking_formatter.rb' - - 'spec/controllers/projects/artifacts_controller_spec.rb' - - 'spec/lib/gitlab/gfm/uploads_rewriter_spec.rb' - - 'spec/support/helpers/test_env.rb' - # Offense count: 121 Performance/MethodObjectAsBlock: Enabled: false @@ -398,22 +379,6 @@ Rails/WhereExists: Style/AccessorGrouping: Enabled: false -# Offense count: 11 -# Cop supports --auto-correct. -Style/ArrayCoercion: - Exclude: - - 'app/controllers/admin/ci/variables_controller.rb' - - 'app/controllers/groups/variables_controller.rb' - - 'app/controllers/projects/variables_controller.rb' - - 'db/migrate/20190620105427_change_null_private_profile_to_false.rb' - - 'db/post_migrate/20190812070645_migrate_private_profile_nulls.rb' - - 'db/post_migrate/20200311130802_schedule_populate_user_highest_roles_table.rb' - - 'db/post_migrate/20200805152108_migrate_null_external_diff_store_to_local_value.rb' - - 'db/post_migrate/20200806173633_migrate_null_package_files_file_store_to_local_value.rb' - - 'ee/app/services/geo/repository_verification_secondary_service.rb' - - 'ee/lib/ee/banzai/pipeline/gfm_pipeline.rb' - - 'spec/support/helpers/lfs_http_helpers.rb' - # Offense count: 188 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle. @@ -433,20 +398,6 @@ Style/BisectedAttrAccessor: Style/CaseLikeIf: Enabled: false -# Offense count: 13 -Style/CombinableLoops: - Exclude: - - 'ee/db/fixtures/development/30_customizable_cycle_analytics.rb' - - 'ee/lib/gitlab/audit/events/preloader.rb' - - 'ee/spec/finders/snippets_finder_spec.rb' - - 'ee/spec/lib/ee/gitlab/background_migration/remove_duplicate_cs_findings_spec.rb' - - 'spec/features/merge_request/user_suggests_changes_on_diff_spec.rb' - - 'spec/finders/packages/group_packages_finder_spec.rb' - - 'spec/migrations/cleanup_optimistic_locking_nulls_pt2_fixed_spec.rb' - - 'spec/migrations/cleanup_optimistic_locking_nulls_spec.rb' - - 'spec/requests/api/members_spec.rb' - - 'spec/support/shared_examples/features/protected_branches_access_control_ce_shared_examples.rb' - # Offense count: 5 # Cop supports --auto-correct. Style/EachWithObject: @@ -471,13 +422,6 @@ Style/EmptyElse: Style/EmptyMethod: Enabled: false -# Offense count: 2 -# Cop supports --auto-correct. -Style/ExpandPathArguments: - Exclude: - - 'cable/config.ru' - - 'config.ru' - # Offense count: 118 # Cop supports --auto-correct. Style/ExplicitBlockArgument: diff --git a/.rubocop_todo/rspec/verified_doubles.yml b/.rubocop_todo/rspec/verified_doubles.yml index bbdbb645da0..a6206a48299 100644 --- a/.rubocop_todo/rspec/verified_doubles.yml +++ b/.rubocop_todo/rspec/verified_doubles.yml @@ -878,7 +878,6 @@ RSpec/VerifiedDoubles: - spec/models/design_management/design_at_version_spec.rb - spec/models/diff_viewer/image_spec.rb - spec/models/environment_spec.rb - - spec/models/error_tracking/project_error_tracking_setting_spec.rb - spec/models/event_spec.rb - spec/models/external_issue_spec.rb - spec/models/hooks/web_hook_spec.rb diff --git a/.rubocop_todo/style/array_coercion.yml b/.rubocop_todo/style/array_coercion.yml new file mode 100644 index 00000000000..a49fc42967d --- /dev/null +++ b/.rubocop_todo/style/array_coercion.yml @@ -0,0 +1,10 @@ +--- +# Cop supports --auto-correct. +Style/ArrayCoercion: + Exclude: + - 'app/controllers/admin/ci/variables_controller.rb' + - 'app/controllers/groups/variables_controller.rb' + - 'app/controllers/projects/variables_controller.rb' + - 'ee/app/services/geo/repository_verification_secondary_service.rb' + - 'ee/lib/ee/banzai/pipeline/gfm_pipeline.rb' + - 'spec/support/helpers/lfs_http_helpers.rb' diff --git a/.rubocop_todo/style/combinable_loops.yml b/.rubocop_todo/style/combinable_loops.yml new file mode 100644 index 00000000000..c8b8cbb979d --- /dev/null +++ b/.rubocop_todo/style/combinable_loops.yml @@ -0,0 +1,10 @@ +--- +Style/CombinableLoops: + Exclude: + - 'ee/db/fixtures/development/30_customizable_cycle_analytics.rb' + - 'ee/lib/gitlab/audit/events/preloader.rb' + - 'ee/spec/finders/snippets_finder_spec.rb' + - 'spec/features/merge_request/user_suggests_changes_on_diff_spec.rb' + - 'spec/finders/packages/group_packages_finder_spec.rb' + - 'spec/requests/api/members_spec.rb' + - 'spec/support/shared_examples/features/protected_branches_access_control_ce_shared_examples.rb' diff --git a/.rubocop_todo/style/open_struct_use.yml b/.rubocop_todo/style/open_struct_use.yml index 1bf64080aa6..4ccf0ccd033 100644 --- a/.rubocop_todo/style/open_struct_use.yml +++ b/.rubocop_todo/style/open_struct_use.yml @@ -8,7 +8,6 @@ Style/OpenStructUse: - ee/spec/lib/gitlab/auth/group_saml/failure_handler_spec.rb - ee/spec/lib/gitlab/legacy_github_import/project_creator_spec.rb - lib/gitlab/testing/request_inspector_middleware.rb - - spec/factories/go_module_versions.rb - spec/factories/wiki_pages.rb - spec/graphql/mutations/branches/create_spec.rb - spec/graphql/mutations/clusters/agent_tokens/create_spec.rb diff --git a/app/assets/javascripts/clusters_list/components/agent_table.vue b/app/assets/javascripts/clusters_list/components/agent_table.vue index 1144ce68e2c..2decdb5307b 100644 --- a/app/assets/javascripts/clusters_list/components/agent_table.vue +++ b/app/assets/javascripts/clusters_list/components/agent_table.vue @@ -37,7 +37,7 @@ export default { anchor: 'update-the-agent-version', }), configHelpLink: helpPagePath('user/clusters/agent/install/index', { - anchor: 'create-an-agent-without-configuration-file', + anchor: 'create-an-agent-configuration-file', }), inject: ['gitlabVersion'], props: { diff --git a/app/assets/javascripts/clusters_list/components/install_agent_modal.vue b/app/assets/javascripts/clusters_list/components/install_agent_modal.vue index ae0affe4c8b..3b39c3aac45 100644 --- a/app/assets/javascripts/clusters_list/components/install_agent_modal.vue +++ b/app/assets/javascripts/clusters_list/components/install_agent_modal.vue @@ -31,7 +31,7 @@ export default { EVENT_LABEL_MODAL, enableKasPath: helpPagePath('administration/clusters/kas'), registerAgentPath: helpPagePath('user/clusters/agent/install/index', { - anchor: 'register-an-agent-with-gitlab', + anchor: 'register-the-agent-with-gitlab', }), components: { AvailableAgentsDropdown, diff --git a/app/assets/javascripts/environments/components/new_environment_item.vue b/app/assets/javascripts/environments/components/new_environment_item.vue index f35fabccae7..f5e9d612316 100644 --- a/app/assets/javascripts/environments/components/new_environment_item.vue +++ b/app/assets/javascripts/environments/components/new_environment_item.vue @@ -2,6 +2,7 @@ import { GlCollapse, GlDropdown, + GlBadge, GlButton, GlLink, GlSprintf, @@ -26,6 +27,7 @@ export default { components: { GlCollapse, GlDropdown, + GlBadge, GlButton, GlLink, GlSprintf, @@ -74,6 +76,7 @@ export default { 'Environments|There are no deployments for this environment yet. %{linkStart}Learn more about setting up deployments.%{linkEnd}', ), autoStopIn: s__('Environment|Auto stop %{time}'), + tierTooltip: s__('Environment|Deployment tier'), }, data() { return { visible: false }; @@ -100,6 +103,9 @@ export default { hasDeployment() { return Boolean(this.environment?.upcomingDeployment || this.environment?.lastDeployment); }, + tier() { + return this.lastDeployment?.tierInYaml; + }, hasOpenedAlert() { return this.environment?.hasOpenedAlert; }, @@ -206,6 +212,13 @@ export default { > {{ displayName }} </gl-link> + <gl-badge + v-if="tier" + v-gl-tooltip + :title="$options.i18n.tierTooltip" + class="gl-ml-3 gl-font-monospace" + >{{ tier }}</gl-badge + > </div> <div class="gl-display-flex gl-align-items-center"> <p v-if="canShowAutoStopDate" class="gl-font-sm gl-text-gray-700 gl-mr-5 gl-mb-0"> diff --git a/app/assets/javascripts/environments/graphql/resolvers.js b/app/assets/javascripts/environments/graphql/resolvers.js index a7866c1e778..722bb78bcf9 100644 --- a/app/assets/javascripts/environments/graphql/resolvers.js +++ b/app/assets/javascripts/environments/graphql/resolvers.js @@ -24,7 +24,7 @@ const mapNestedEnvironment = (env) => ({ __typename: 'NestedLocalEnvironment', }); const mapEnvironment = (env) => ({ - ...convertObjectPropsToCamelCase(env), + ...convertObjectPropsToCamelCase(env, { deep: true }), __typename: 'LocalEnvironment', }); diff --git a/app/assets/javascripts/issues/list/components/issue_card_time_info.vue b/app/assets/javascripts/issues/list/components/issue_card_time_info.vue index 1108021c7c6..1139861ae78 100644 --- a/app/assets/javascripts/issues/list/components/issue_card_time_info.vue +++ b/app/assets/javascripts/issues/list/components/issue_card_time_info.vue @@ -1,5 +1,6 @@ <script> import { GlLink, GlIcon, GlTooltipDirective } from '@gitlab/ui'; +import { IssuableStatus } from '~/issues/constants'; import { dateInWords, getTimeRemainingInWords, @@ -41,7 +42,10 @@ export default { return this.issue.dueDate && dateInWords(newDateAsLocaleTime(this.issue.dueDate), true); }, showDueDateInRed() { - return isInPast(newDateAsLocaleTime(this.issue.dueDate)) && !this.issue.closedAt; + return ( + isInPast(newDateAsLocaleTime(this.issue.dueDate)) && + this.issue.state !== IssuableStatus.Closed + ); }, timeEstimate() { return this.issue.humanTimeEstimate || this.issue.timeStats?.humanTimeEstimate; diff --git a/app/assets/javascripts/issues/list/components/issues_list_app.vue b/app/assets/javascripts/issues/list/components/issues_list_app.vue index 5caac3402c2..03b207eeb51 100644 --- a/app/assets/javascripts/issues/list/components/issues_list_app.vue +++ b/app/assets/javascripts/issues/list/components/issues_list_app.vue @@ -19,6 +19,7 @@ import { convertToGraphQLId, getIdFromGraphQLId } from '~/graphql_shared/utils'; import { ITEM_TYPE } from '~/groups/constants'; import CsvImportExportButtons from '~/issuable/components/csv_import_export_buttons.vue'; import IssuableByEmail from '~/issuable/components/issuable_by_email.vue'; +import { IssuableStatus } from '~/issues/constants'; import axios from '~/lib/utils/axios_utils'; import { scrollUp } from '~/lib/utils/scroll_utils'; import { getParameterByName, joinPaths } from '~/lib/utils/url_utility'; @@ -480,10 +481,10 @@ export default { return `${this.exportCsvPath}${window.location.search}`; }, getStatus(issue) { - if (issue.closedAt && issue.moved) { + if (issue.state === IssuableStatus.Closed && issue.moved) { return this.$options.i18n.closedMoved; } - if (issue.closedAt) { + if (issue.state === IssuableStatus.Closed) { return this.$options.i18n.closed; } return undefined; diff --git a/app/assets/javascripts/issues/list/queries/issue.fragment.graphql b/app/assets/javascripts/issues/list/queries/issue.fragment.graphql index 430d494deab..d09e4d9df2b 100644 --- a/app/assets/javascripts/issues/list/queries/issue.fragment.graphql +++ b/app/assets/javascripts/issues/list/queries/issue.fragment.graphql @@ -2,7 +2,6 @@ fragment IssueFragment on Issue { __typename id iid - closedAt confidential createdAt downvotes @@ -11,6 +10,7 @@ fragment IssueFragment on Issue { humanTimeEstimate mergeRequestsCount moved + state title updatedAt upvotes diff --git a/app/assets/javascripts/merge_request.js b/app/assets/javascripts/merge_request.js index 244cf1e150a..7c16b54c7d5 100644 --- a/app/assets/javascripts/merge_request.js +++ b/app/assets/javascripts/merge_request.js @@ -124,7 +124,7 @@ MergeRequest.prototype.submitNoteForm = function (form, $button) { MergeRequest.decreaseCounter = function (by = 1) { const $el = $('.js-merge-counter'); - const count = Math.max(parseInt($el.text().replace(/[^\d]/, ''), 10) - by, 0); + const count = Math.max(parseInt($el.first().text().replace(/[^\d]/, ''), 10) - by, 0); $el.text(addDelimiter(count)); }; diff --git a/app/models/concerns/issuable_link.rb b/app/models/concerns/issuable_link.rb index 3e14507bc70..c319d685362 100644 --- a/app/models/concerns/issuable_link.rb +++ b/app/models/concerns/issuable_link.rb @@ -29,6 +29,8 @@ module IssuableLink validate :check_self_relation validate :check_opposite_relation + scope :for_source_or_target, ->(issuable) { where(source: issuable).or(where(target: issuable)) } + enum link_type: { TYPE_RELATES_TO => 0, TYPE_BLOCKS => 1 } private diff --git a/app/models/deployment.rb b/app/models/deployment.rb index 2f68f586867..8fd6fd1822a 100644 --- a/app/models/deployment.rb +++ b/app/models/deployment.rb @@ -380,6 +380,12 @@ class Deployment < ApplicationRecord status == params[:status] end + def tier_in_yaml + return unless deployable + + deployable.environment_deployment_tier + end + private def update_status!(status) diff --git a/app/models/error_tracking/project_error_tracking_setting.rb b/app/models/error_tracking/project_error_tracking_setting.rb index 0a429bb7afd..3ecfb895dac 100644 --- a/app/models/error_tracking/project_error_tracking_setting.rb +++ b/app/models/error_tracking/project_error_tracking_setting.rb @@ -135,7 +135,7 @@ module ErrorTracking end end - def update_issue(opts = {} ) + def update_issue(opts = {}) handle_exceptions do { updated: sentry_client.update_issue(opts) } end diff --git a/app/serializers/deployment_entity.rb b/app/serializers/deployment_entity.rb index 020c66af777..f63a1bf094a 100644 --- a/app/serializers/deployment_entity.rb +++ b/app/serializers/deployment_entity.rb @@ -23,6 +23,7 @@ class DeploymentEntity < Grape::Entity expose :tag expose :last? expose :last?, as: :is_last + expose :tier_in_yaml expose :deployed_by, as: :user, using: UserEntity diff --git a/app/workers/container_registry/migration/enqueuer_worker.rb b/app/workers/container_registry/migration/enqueuer_worker.rb index 72b1e9e63f1..39f8fc4539e 100644 --- a/app/workers/container_registry/migration/enqueuer_worker.rb +++ b/app/workers/container_registry/migration/enqueuer_worker.rb @@ -41,6 +41,8 @@ module ContainerRegistry Gitlab::ErrorTracking.log_exception(e, next_aborted_repository_id: next_aborted_repository&.id) true + ensure + log_repository_migration_state(next_aborted_repository) end def handle_next_migration @@ -59,6 +61,8 @@ module ContainerRegistry next_repository&.abort_import false + ensure + log_repository_migration_state(next_repository) end def tag_count_too_high? @@ -151,6 +155,12 @@ module ContainerRegistry log_extra_metadata_on_done(:container_repository_path, repository&.path) end + def log_repository_migration_state(repository) + return unless repository + + log_extra_metadata_on_done(:container_repository_migration_state, repository.migration_state) + end + # used by ExclusiveLeaseGuard def lease_key 'container_registry:migration:enqueuer_worker' diff --git a/config.ru b/config.ru index f07c25f503a..ed77402aead 100644 --- a/config.ru +++ b/config.ru @@ -2,7 +2,7 @@ # This file is used by Rack-based servers to start the application. -require ::File.expand_path('../config/environment', __FILE__) +require ::File.expand_path('config/environment', __dir__) warmup do |app| client = Rack::MockRequest.new(app) diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md index 704274e744c..443dbb866ee 100644 --- a/doc/ci/yaml/index.md +++ b/doc/ci/yaml/index.md @@ -2484,8 +2484,10 @@ Use `changes` in pipelines with the following refs: - Paths to files. - Wildcard paths for single directories, for example `path/to/directory/*`, or a directory and all its subdirectories, for example `path/to/directory/**/*`. -- Wildcard ([glob](https://en.wikipedia.org/wiki/Glob_(programming))) paths for all +- Wildcard [glob](https://en.wikipedia.org/wiki/Glob_(programming)) paths for all files with the same extension or multiple extensions, for example `*.md` or `path/to/directory/*.{rb,py,sh}`. + See the [Ruby `fnmatch` documentation](https://docs.ruby-lang.org/en/master/File.html#method-c-fnmatch) + for the supported syntax list. - Wildcard paths to files in the root directory, or all directories, wrapped in double quotes. For example `"*.json"` or `"**/*.json"`. diff --git a/doc/user/application_security/api_fuzzing/index.md b/doc/user/application_security/api_fuzzing/index.md index ae2b4ec84c6..931b329a762 100644 --- a/doc/user/application_security/api_fuzzing/index.md +++ b/doc/user/application_security/api_fuzzing/index.md @@ -91,20 +91,25 @@ The API fuzzing configuration form helps you create or modify your project's API configuration. The form lets you choose values for the most common API fuzzing options and builds a YAML snippet that you can paste in your GitLab CI/CD configuration. -#### Configure Web API fuzzing with the configuration form +#### Configure Web API fuzzing in the UI To generate an API Fuzzing configuration snippet: 1. On the top bar, select **Menu > Projects** and find your project. 1. On the left sidebar, select **Security & Compliance > Configuration**. -1. In the **API Fuzzing** row, select **Configure**. -1. Complete the form as needed. Read below for more information on available configuration options. +1. In the **API Fuzzing** row, select **Enable API Fuzzing**. +1. Complete the fields. For details see [Available CI/CD variables](#available-cicd-variables). 1. Select **Generate code snippet**. A modal opens with the YAML snippet corresponding to the options you've selected in the form. -1. Choose one of the following actions: - 1. To copy the snippet to your clipboard and be redirected to your project's `.gitlab-ci.yml` file, - where you can paste the YAML configuration, select **Copy code and open `.gitlab-ci.yml` file**. - 1. To copy the snippet to your clipboard and close the modal, select **Copy code only**. +1. Do one of the following: + 1. To copy the snippet to your clipboard, select **Copy code only**. + 1. To add the snippet to your project's `.gitlab-ci.yml` file, select + **Copy code and open `.gitlab-ci.yml` file**. The Pipeline Editor opens. + 1. Paste the snippet into the `.gitlab-ci.yml` file. + 1. Select the **Lint** tab to confirm the edited `.gitlab-ci.yml` file is valid. + 1. Select the **Edit** tab, then select **Commit changes**. + +When the snippet is committed to the `.gitlab-ci.yml` file, pipelines include an API Fuzzing job. ### OpenAPI Specification diff --git a/doc/user/application_security/dast/index.md b/doc/user/application_security/dast/index.md index 3222d5d0ec1..ee57803dfc7 100644 --- a/doc/user/application_security/dast/index.md +++ b/doc/user/application_security/dast/index.md @@ -278,7 +278,8 @@ page. You can enable or configure DAST settings using the UI. The generated settings are formatted so they can be conveniently pasted into the `.gitlab-ci.yml` file. -1. From the project's home page, go to **Security & Compliance > Configuration**. +1. On the top bar, select **Menu > Projects** and find your project. +1. On the left sidebar, select **Security & Compliance > Configuration**. 1. In the **Dynamic Application Security Testing (DAST)** section, select **Enable DAST** or **Configure DAST**. 1. Select the desired **Scanner profile**, or select **Create scanner profile** and save a @@ -288,12 +289,14 @@ can be conveniently pasted into the `.gitlab-ci.yml` file. 1. Select **Generate code snippet**. A modal opens with the YAML snippet corresponding to the options you selected. 1. Do one of the following: - 1. Select **Copy code only** to copy the snippet to your clipboard. - 1. Select **Copy code and open `.gitlab-ci.yml` file** to copy the snippet to your clipboard. The - CI/CD Editor then opens. + 1. To copy the snippet to your clipboard, select **Copy code only**. + 1. To add the snippet to your project's `.gitlab-ci.yml` file, select + **Copy code and open `.gitlab-ci.yml` file**. The Pipeline Editor opens. 1. Paste the snippet into the `.gitlab-ci.yml` file. 1. Select the **Lint** tab to confirm the edited `.gitlab-ci.yml` file is valid. - 1. Select **Commit changes**. + 1. Select the **Edit** tab, then select **Commit changes**. + +When the snippet is committed to the `.gitlab-ci.yml` file, pipelines include a DAST job. #### Crawling web applications dependent on JavaScript diff --git a/doc/user/application_security/dast_api/index.md b/doc/user/application_security/dast_api/index.md index 2baafc87d1a..86f48318395 100644 --- a/doc/user/application_security/dast_api/index.md +++ b/doc/user/application_security/dast_api/index.md @@ -84,9 +84,9 @@ the body generation is limited to these body types: - `application/json` - `application/xml` -Follow these steps to configure DAST API in GitLab with an OpenAPI specification: +To configure DAST API scanning with an OpenAPI specification: -1. To use DAST API, you must [include](../../../ci/yaml/index.md#includetemplate) +1. To use DAST API scanning, [include](../../../ci/yaml/index.md#includetemplate) the [`DAST-API.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml) that's provided as part of your GitLab installation. Add the following to your `.gitlab-ci.yml` file: @@ -182,8 +182,7 @@ WARNING: HAR files may contain sensitive information such as authentication tokens, API keys, and session cookies. We recommend that you review the HAR file contents before adding them to a repository. -Follow these steps to configure DAST API to use a HAR file that provides information about the -target API to test: +To configure DAST API scanning to use a HAR file: 1. To use DAST API, you must [include](../../../ci/yaml/index.md#includetemplate) the [`DAST-API.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml) @@ -282,8 +281,7 @@ Postman Collection files may contain sensitive information such as authenticatio and session cookies. We recommend that you review the Postman Collection file contents before adding them to a repository. -Follow these steps to configure DAST API to use a Postman Collection file that provides -information about the target API to test: +To configure DAST API scanning to use a Postman Collection file: 1. To use DAST API, you must [include](../../../ci/yaml/index.md#includetemplate) the [`DAST-API.gitlab-ci.yml` template](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Security/DAST-API.gitlab-ci.yml) diff --git a/doc/user/application_security/dependency_scanning/index.md b/doc/user/application_security/dependency_scanning/index.md index a4a7e6703ab..28258df75b5 100644 --- a/doc/user/application_security/dependency_scanning/index.md +++ b/doc/user/application_security/dependency_scanning/index.md @@ -508,19 +508,18 @@ always take the latest dependency scanning artifact available. > - [Enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/282533) in GitLab 14.1. > - [Feature flag sec_dependency_scanning_ui_enable removed](https://gitlab.com/gitlab-org/gitlab/-/issues/326005) in GitLab 14.2. -To enable Dependency Scanning in a project, you can create a merge request -from the Security Configuration page. +To enable Dependency Scanning in a project, you can create a merge request: -1. In the project where you want to enable Dependency Scanning, navigate to - **Security & Compliance > Configuration**. +1. On the top bar, select **Menu > Projects** and find your project. +1. On the left sidebar, select **Security & Compliance > Configuration**. 1. In the **Dependency Scanning** row, select **Configure with a merge request**. +1. Review and merge the merge request to enable Dependency Scanning. -This automatically creates a merge request with the changes necessary to enable Dependency Scanning -that you can review and merge to complete the configuration. +Pipelines now include a dependency scanning job. ### Customizing the dependency scanning settings -The dependency scanning settings can be changed through [CI/CD variables](#available-cicd-variables) by using the +The Dependency Scanning settings can be changed through [CI/CD variables](#available-cicd-variables) by using the [`variables`](../../../ci/yaml/index.md#variables) parameter in `.gitlab-ci.yml`. For example: diff --git a/doc/user/application_security/iac_scanning/index.md b/doc/user/application_security/iac_scanning/index.md index 67ecbd094e8..292c4bf848f 100644 --- a/doc/user/application_security/iac_scanning/index.md +++ b/doc/user/application_security/iac_scanning/index.md @@ -93,15 +93,14 @@ that you can download and analyze. ### Enable IaC Scanning via an automatic merge request -To enable IaC Scanning in a project, you can create a merge request -from the Security Configuration page: +To enable IaC Scanning in a project, you can create a merge request: 1. On the top bar, select **Menu > Projects** and find your project. 1. On the left sidebar, select **Security & Compliance > Configuration**. 1. In the **Infrastructure as Code (IaC) Scanning** row, select **Configure with a merge request**. +1. Review and merge the merge request to enable IaC Scanning. -This automatically creates a merge request with the changes necessary to enable IaC Scanning -that you can review and merge to complete the configuration. +Pipelines now include an IaC job. ## Reports JSON format diff --git a/doc/user/application_security/sast/index.md b/doc/user/application_security/sast/index.md index b0b4008cfec..4f22ea14da9 100644 --- a/doc/user/application_security/sast/index.md +++ b/doc/user/application_security/sast/index.md @@ -190,28 +190,28 @@ always take the latest SAST artifact available. ### Configure SAST in the UI You can enable and configure SAST in the UI, either with default settings, or with customizations. -Use the method that best meets your needs. +The method you can use depends on your GitLab license tier. -- [Configure SAST in the UI with default settings](#configure-sast-in-the-ui-with-default-settings) -- [Configure SAST in the UI with customizations](#configure-sast-in-the-ui-with-customizations) +- [Configure SAST in the UI with default settings](#configure-sast-in-the-ui-with-default-settings). +- [Configure SAST in the UI with customizations](#configure-sast-in-the-ui-with-customizations). **(ULTIMATE)** ### Configure SAST in the UI with default settings > [Introduced](https://about.gitlab.com/releases/2021/02/22/gitlab-13-9-released/#security-configuration-page-for-all-users) in GitLab 13.9 +NOTE: +The configuration tool works best with no existing `.gitlab-ci.yml` file, or with a minimal +configuration file. If you have a complex GitLab configuration file it may not be parsed +successfully, and an error may occur. + To enable and configure SAST with default settings: 1. On the top bar, select **Menu > Projects** and find your project. 1. On the left sidebar, select **Security & Compliance** > **Configuration**. -1. In the SAST section, select `Enable via MR`. -1. Review the draft MR that enables SAST with the default recommended settings in the - `.gitlab-ci.yml` file. -1. Merge the MR to enable SAST. You should see SAST jobs run in that MR's pipeline. +1. In the SAST section, select **Configure with a merge request**. +1. Review and merge the merge request to enable SAST. -NOTE: -The configuration tool works best with no existing `.gitlab-ci.yml` file, or with a minimal -configuration file. If you have a complex GitLab configuration file it may not be parsed -successfully, and an error may occur. +Pipelines now include a SAST job. ### Configure SAST in the UI with customizations **(ULTIMATE)** @@ -219,27 +219,28 @@ successfully, and an error may occur. > - [Improved](https://gitlab.com/gitlab-org/gitlab/-/issues/232862) in GitLab 13.4. > - [Improved](https://gitlab.com/groups/gitlab-org/-/epics/3635) in GitLab 13.5. +NOTE: +The configuration tool works best with no existing `.gitlab-ci.yml` file, or with a minimal +configuration file. If you have a complex GitLab configuration file it may not be parsed +successfully, and an error may occur. + To enable and configure SAST with customizations: 1. On the top bar, select **Menu > Projects** and find your project. 1. On the left sidebar, select **Security & Compliance > Configuration**. -1. If the project does not have a `.gitlab-ci.yml` file, select **Enable** in the Static Application - Security Testing (SAST) row, otherwise select **Configure**. +1. If the project does not have a `.gitlab-ci.yml` file, select **Enable SAST** in the Static + Application Security Testing (SAST) row, otherwise select **Configure SAST**. 1. Enter the custom SAST values. Custom values are stored in the `.gitlab-ci.yml` file. For CI/CD variables not in the SAST - Configuration page, their values are left unchanged. Default values are inherited from the GitLab - SAST template. + Configuration page, their values are inherited from the GitLab SAST template. 1. Optionally, expand the **SAST analyzers** section, select individual [SAST analyzers](analyzers.md) and enter custom analyzer values. 1. Select **Create Merge Request**. 1. Review and merge the merge request. -NOTE: -The configuration tool works best with no existing `.gitlab-ci.yml` file, or with a minimal -configuration file. If you have a complex GitLab configuration file it may not be parsed -successfully, and an error may occur. +Pipelines now include a SAST job. ### Overriding SAST jobs diff --git a/doc/user/application_security/secret_detection/index.md b/doc/user/application_security/secret_detection/index.md index 582497eb465..0a9680615a4 100644 --- a/doc/user/application_security/secret_detection/index.md +++ b/doc/user/application_security/secret_detection/index.md @@ -112,20 +112,19 @@ always take the latest Secret Detection artifact available. > - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/4496) in GitLab 13.11, deployed behind a feature flag, enabled by default. > - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/329886) in GitLab 14.1. -To enable Secret Detection in a project, you can create a merge request -from the Security Configuration page. +NOTE: +This method works best with no existing `.gitlab-ci.yml` file, or with a minimal configuration +file. If you have a complex GitLab configuration file it may not be parsed successfully, and an +error may occur. -1. In the project where you want to enable Secret Detection, go to - **Security & Compliance > Configuration**. -1. In the **Secret Detection** row, select **Configure with a merge request**. +To enable Secret Detection in a project, you can create a merge request: -This automatically creates a merge request with the changes necessary to enable Secret Detection -that you can review and merge to complete the configuration. +1. On the top bar, select **Menu > Projects** and find your project. +1. On the left sidebar, select **Security & Compliance > Configuration**. +1. In the **Secret Detection** row, select **Configure with a merge request**. +1. Review and merge the merge request to enable Secret Detection. -NOTE: -The configuration tool works best with no existing `.gitlab-ci.yml` file, or with a minimal -configuration file. If you have a complex GitLab configuration file it may not be parsed -successfully, and an error may occur. +Pipelines now include a Secret Detection job. ### Customizing settings diff --git a/doc/user/clusters/agent/install/index.md b/doc/user/clusters/agent/install/index.md index 3d1401efca4..8d3c135b8c3 100644 --- a/doc/user/clusters/agent/install/index.md +++ b/doc/user/clusters/agent/install/index.md @@ -69,6 +69,8 @@ Creating a file is optional but is needed if: - You use [a GitOps workflow](../gitops.md#gitops-configuration-reference) and you want a more advanced configuration. - You use a GitLab CI/CD workflow. In that workflow, you must [authorize the agent](../ci_cd_tunnel.md#authorize-the-agent). +If you do not create an agent configuration file, you can use the CI/CD workflow in the project where the agent is registered only. + To create an agent configuration file, go to the GitLab project. In the repository, create a file called `config.yaml` at this path: ```plaintext diff --git a/lib/api/issue_links.rb b/lib/api/issue_links.rb index 98451afb12d..0e93a4adb65 100644 --- a/lib/api/issue_links.rb +++ b/lib/api/issue_links.rb @@ -67,14 +67,16 @@ module API requires :issue_link_id, type: Integer, desc: 'The ID of an issue link' end delete ':id/issues/:issue_iid/links/:issue_link_id' do - issue_link = IssueLink.find(declared_params[:issue_link_id]) + issue = find_project_issue(params[:issue_iid]) + issue_link = IssueLink + .for_source_or_target(issue) + .find(declared_params[:issue_link_id]) - find_project_issue(params[:issue_iid]) find_project_issue(issue_link.target.iid.to_s, issue_link.target.project_id.to_s) result = ::IssueLinks::DestroyService - .new(issue_link, current_user) - .execute + .new(issue_link, current_user) + .execute if result[:status] == :success present issue_link, with: Entities::IssueLink diff --git a/lib/gitlab/background_migration/encrypt_static_object_token.rb b/lib/gitlab/background_migration/encrypt_static_object_token.rb index 80931353e2f..a087d2529eb 100644 --- a/lib/gitlab/background_migration/encrypt_static_object_token.rb +++ b/lib/gitlab/background_migration/encrypt_static_object_token.rb @@ -52,9 +52,9 @@ module Gitlab WHERE cte_id = id SQL end - - mark_job_as_succeeded(start_id, end_id) end + + mark_job_as_succeeded(start_id, end_id) end private diff --git a/lib/gitlab/database/each_database.rb b/lib/gitlab/database/each_database.rb index cccd4b48723..0d876f5124f 100644 --- a/lib/gitlab/database/each_database.rb +++ b/lib/gitlab/database/each_database.rb @@ -4,11 +4,13 @@ module Gitlab module Database module EachDatabase class << self - def each_database_connection(only: nil) + def each_database_connection(only: nil, include_shared: true) selected_names = Array.wrap(only) base_models = select_base_models(selected_names) base_models.each_pair do |connection_name, model| + next if !include_shared && Gitlab::Database.db_config_share_with(model.connection_db_config) + connection = model.connection with_shared_connection(connection, connection_name) do diff --git a/lib/tasks/gitlab/db/validate_config.rake b/lib/tasks/gitlab/db/validate_config.rake index 4904ee3dd67..911d9a3d1b2 100644 --- a/lib/tasks/gitlab/db/validate_config.rake +++ b/lib/tasks/gitlab/db/validate_config.rake @@ -20,7 +20,7 @@ namespace :gitlab do begin ActiveRecord::Base.establish_connection(db_config) # rubocop: disable Database/EstablishConnection ActiveRecord::Base.connection.select_one("SELECT system_identifier, current_database() FROM pg_control_system()") - rescue ActiveRecord::NoDatabaseError, PG::ConnectionBad + rescue ActiveRecord::NoDatabaseError, ActiveRecord::ConnectionNotEstablished, PG::ConnectionBad end { diff --git a/lib/tasks/gitlab/setup.rake b/lib/tasks/gitlab/setup.rake index a5289476378..ca10bccf5bf 100644 --- a/lib/tasks/gitlab/setup.rake +++ b/lib/tasks/gitlab/setup.rake @@ -53,7 +53,7 @@ namespace :gitlab do AND pid <> pg_backend_pid(); SQL - Gitlab::Database::EachDatabase.each_database_connection do |connection| + Gitlab::Database::EachDatabase.each_database_connection(include_shared: false) do |connection| connection.execute(cmd) rescue ActiveRecord::NoDatabaseError end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 8eae3538835..2e64ea8c4fe 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -7402,6 +7402,9 @@ msgstr "" msgid "Child epic doesn't exist." msgstr "" +msgid "Child issues and epics" +msgstr "" + msgid "Chinese language support using" msgstr "" @@ -14395,6 +14398,9 @@ msgstr "" msgid "Environment|Auto stop %{time}" msgstr "" +msgid "Environment|Deployment tier" +msgstr "" + msgid "Epic" msgstr "" @@ -14419,9 +14425,6 @@ msgstr "" msgid "Epics Roadmap" msgstr "" -msgid "Epics and Issues" -msgstr "" - msgid "Epics let you manage your portfolio of projects more efficiently and with less effort" msgstr "" @@ -15413,6 +15416,9 @@ msgstr "" msgid "Failed to load" msgstr "" +msgid "Failed to load Roadmap" +msgstr "" + msgid "Failed to load assignees." msgstr "" @@ -32148,6 +32154,9 @@ msgstr "" msgid "Roadmap settings" msgstr "" +msgid "Roadmap view" +msgstr "" + msgid "Role" msgstr "" diff --git a/qa/qa/page/project/import/github.rb b/qa/qa/page/project/import/github.rb index 47f7e701ae8..89d044bac8d 100644 --- a/qa/qa/page/project/import/github.rb +++ b/qa/qa/page/project/import/github.rb @@ -75,11 +75,10 @@ module QA # @return [Boolean] def has_imported_project?(gh_project_name, wait: QA::Support::WaitForRequests::DEFAULT_MAX_WAIT_TIME) within_element(:project_import_row, source_project: gh_project_name, skip_finished_loading_check: true) do - # TODO: remove retrier with reload:true once https://gitlab.com/gitlab-org/gitlab/-/issues/292861 is fixed wait_until( max_duration: wait, sleep_interval: 5, - reload: true, + reload: false, skip_finished_loading_check_on_refresh: true ) do has_element?(:import_status_indicator, text: "Complete") diff --git a/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb b/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb index c833aa1a5b8..f570ad335fe 100644 --- a/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/container_registry/container_registry_omnibus_spec.rb @@ -3,6 +3,8 @@ module QA RSpec.describe 'Package', :orchestrated, :skip_live_env do describe 'Self-managed Container Registry' do + include Support::Helpers::MaskToken + let(:project) do Resource::Project.fabricate_via_api! do |project| project.name = 'project-with-registry' @@ -110,9 +112,9 @@ module QA let(:auth_token) do case authentication_token_type when :personal_access_token - "\"#{personal_access_token}\"" + use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: project) when :project_deploy_token - "\"#{project_deploy_token.token}\"" + use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project) when :ci_job_token '$CI_JOB_TOKEN' end diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb index d2e816f9bf9..078465770c6 100644 --- a/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/helm_registry_spec.rb @@ -5,6 +5,7 @@ module QA describe 'Helm Registry' do using RSpec::Parameterized::TableSyntax include Runtime::Fixtures + include Support::Helpers::MaskToken include_context 'packages registry qa scenario' let(:package_name) { "gitlab_qa_helm-#{SecureRandom.hex(8)}" } @@ -32,11 +33,13 @@ module QA let(:access_token) do case authentication_token_type when :personal_access_token - personal_access_token + use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: package_project) + use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: client_project) when :ci_job_token '${CI_JOB_TOKEN}' when :project_deploy_token - project_deploy_token.token + use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: package_project) + use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: client_project) end end diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb index 04aaefbaf5c..0ee5f1b6a0b 100644 --- a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_instance_level_spec.rb @@ -5,6 +5,7 @@ module QA describe 'npm instance level endpoint' do using RSpec::Parameterized::TableSyntax include Runtime::Fixtures + include Support::Helpers::MaskToken let!(:registry_scope) { Runtime::Namespace.sandbox_name } let!(:personal_access_token) do @@ -78,11 +79,13 @@ module QA let(:auth_token) do case authentication_token_type when :personal_access_token - "\"#{personal_access_token}\"" + use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: project) + use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: another_project) when :ci_job_token '${CI_JOB_TOKEN}' when :project_deploy_token - "\"#{project_deploy_token.token}\"" + use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project) + use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: another_project) end end diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb index cad1802f3e9..25d53a8add5 100644 --- a/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/npm/npm_project_level_spec.rb @@ -5,6 +5,7 @@ module QA describe 'npm project level endpoint' do using RSpec::Parameterized::TableSyntax include Runtime::Fixtures + include Support::Helpers::MaskToken let!(:registry_scope) { Runtime::Namespace.sandbox_name } let!(:personal_access_token) do @@ -69,11 +70,11 @@ module QA let(:auth_token) do case authentication_token_type when :personal_access_token - "\"#{personal_access_token}\"" + use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token, project: project) when :ci_job_token '${CI_JOB_TOKEN}' when :project_deploy_token - "\"#{project_deploy_token.token}\"" + use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project) end end diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb index b0a6555a16b..0ddb59d6625 100644 --- a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_group_level_spec.rb @@ -5,6 +5,7 @@ module QA describe 'NuGet group level endpoint' do using RSpec::Parameterized::TableSyntax include Runtime::Fixtures + include Support::Helpers::MaskToken let(:project) do Resource::Project.fabricate_via_api! do |project| @@ -61,6 +62,8 @@ module QA after do runner.remove_via_api! package.remove_via_api! + project.remove_via_api! + another_project.remove_via_api! end where(:case_name, :authentication_token_type, :token_name, :testcase) do @@ -73,11 +76,13 @@ module QA let(:auth_token_password) do case authentication_token_type when :personal_access_token - "\"#{personal_access_token.token}\"" + use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token.token, project: project) + use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token.token, project: another_project) when :ci_job_token '${CI_JOB_TOKEN}' when :group_deploy_token - "\"#{group_deploy_token.token}\"" + use_ci_variable(name: 'GROUP_DEPLOY_TOKEN', value: group_deploy_token.token, project: project) + use_ci_variable(name: 'GROUP_DEPLOY_TOKEN', value: group_deploy_token.token, project: another_project) end end diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb index 4cac055634e..d5fd78480d2 100644 --- a/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/nuget/nuget_project_level_spec.rb @@ -3,6 +3,8 @@ module QA RSpec.describe 'Package', :orchestrated, :packages, :object_storage do describe 'NuGet project level endpoint' do + include Support::Helpers::MaskToken + let(:project) do Resource::Project.fabricate_via_api! do |project| project.name = 'nuget-package-project' @@ -77,11 +79,11 @@ module QA let(:auth_token_password) do case authentication_token_type when :personal_access_token - "\"#{personal_access_token.token}\"" + use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: personal_access_token.token, project: project) when :ci_job_token '${CI_JOB_TOKEN}' when :project_deploy_token - "\"#{project_deploy_token.token}\"" + use_ci_variable(name: 'PROJECT_DEPLOY_TOKEN', value: project_deploy_token.token, project: project) end end diff --git a/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb b/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb index a0c2eca5bd2..513894d8474 100644 --- a/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb +++ b/qa/qa/specs/features/browser_ui/5_package/package_registry/pypi_repository_spec.rb @@ -4,6 +4,7 @@ module QA RSpec.describe 'Package', :orchestrated, :packages, :object_storage do describe 'PyPI Repository' do include Runtime::Fixtures + include Support::Helpers::MaskToken let(:project) do Resource::Project.fabricate_via_api! do |project| @@ -30,7 +31,7 @@ module QA let(:uri) { URI.parse(Runtime::Scenario.gitlab_address) } let(:gitlab_address_with_port) { "#{uri.scheme}://#{uri.host}:#{uri.port}" } let(:gitlab_host_with_port) { "#{uri.host}:#{uri.port}" } - let(:personal_access_token) { Runtime::Env.personal_access_token } + let(:personal_access_token) { use_ci_variable(name: 'PERSONAL_ACCESS_TOKEN', value: Runtime::Env.personal_access_token, project: project) } before do Flow::Login.sign_in diff --git a/qa/qa/support/helpers/mask_token.rb b/qa/qa/support/helpers/mask_token.rb new file mode 100644 index 00000000000..1f8161f7173 --- /dev/null +++ b/qa/qa/support/helpers/mask_token.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module QA + module Support + module Helpers + module MaskToken + def use_ci_variable(name:, value:, project:) + Resource::CiVariable.fabricate_via_api! do |ci_variable| + ci_variable.project = project + ci_variable.key = name + ci_variable.value = value + ci_variable.protected = true + end + "$#{name}" + end + end + end + end +end diff --git a/spec/factories/go_module_versions.rb b/spec/factories/go_module_versions.rb index 145e6c95921..bdbd5a4423a 100644 --- a/spec/factories/go_module_versions.rb +++ b/spec/factories/go_module_versions.rb @@ -5,12 +5,10 @@ FactoryBot.define do skip_create initialize_with do - p = attributes[:params] - s = Packages::SemVer.parse(p.semver, prefixed: true) + s = Packages::SemVer.parse(semver, prefixed: true) + raise ArgumentError, "invalid sematic version: #{semver.inspect}" if !s && semver - raise ArgumentError, "invalid sematic version: '#{p.semver}'" if !s && p.semver - - new(p.mod, p.type, p.commit, name: p.name, semver: s, ref: p.ref) + new(mod, type, commit, name: name, semver: s, ref: ref) end mod { association(:go_module) } @@ -20,8 +18,6 @@ FactoryBot.define do semver { nil } ref { nil } - params { OpenStruct.new(mod: mod, type: type, commit: commit, name: name, semver: semver, ref: ref) } - trait :tagged do ref { mod.project.repository.find_tag(name) } commit { ref.dereferenced_target } @@ -36,8 +32,8 @@ FactoryBot.define do .max_by(&:to_s) .to_s end - - params { OpenStruct.new(mod: mod, type: :ref, commit: commit, semver: name, ref: ref) } + type { :ref } + semver { name } end end end diff --git a/spec/features/merge_request/user_merges_merge_request_spec.rb b/spec/features/merge_request/user_merges_merge_request_spec.rb index d1be93cae02..a861ca2eea5 100644 --- a/spec/features/merge_request/user_merges_merge_request_spec.rb +++ b/spec/features/merge_request/user_merges_merge_request_spec.rb @@ -10,7 +10,7 @@ RSpec.describe "User merges a merge request", :js do end shared_examples "fast forward merge a merge request" do - it "merges a merge request", :sidekiq_might_not_need_inline do + it "merges a merge request", :sidekiq_inline do expect(page).to have_content("Fast-forward merge without a merge commit").and have_button("Merge") page.within(".mr-state-widget") do @@ -42,4 +42,23 @@ RSpec.describe "User merges a merge request", :js do it_behaves_like "fast forward merge a merge request" end end + + context 'sidebar merge requests counter' do + let(:project) { create(:project, :public, :repository) } + let!(:merge_request) { create(:merge_request, source_project: project) } + + it 'decrements the open MR count', :sidekiq_inline do + create(:merge_request, source_project: project, source_branch: 'branch-1') + + visit(merge_request_path(merge_request)) + + expect(page).to have_css('.js-merge-counter', text: '2') + + page.within(".mr-state-widget") do + click_button("Merge") + end + + expect(page).to have_css('.js-merge-counter', text: '1') + end + end end diff --git a/spec/frontend/clusters_list/components/agent_table_spec.js b/spec/frontend/clusters_list/components/agent_table_spec.js index db723622a51..a466a35428a 100644 --- a/spec/frontend/clusters_list/components/agent_table_spec.js +++ b/spec/frontend/clusters_list/components/agent_table_spec.js @@ -9,7 +9,7 @@ import timeagoMixin from '~/vue_shared/mixins/timeago'; import { clusterAgents, connectedTimeNow, connectedTimeInactive } from './mock_data'; const defaultConfigHelpUrl = - '/help/user/clusters/agent/install/index#create-an-agent-without-configuration-file'; + '/help/user/clusters/agent/install/index#create-an-agent-configuration-file'; const provideData = { gitlabVersion: '14.8', diff --git a/spec/frontend/environments/graphql/mock_data.js b/spec/frontend/environments/graphql/mock_data.js index 1b7b35702de..7e436476a8f 100644 --- a/spec/frontend/environments/graphql/mock_data.js +++ b/spec/frontend/environments/graphql/mock_data.js @@ -543,6 +543,7 @@ export const resolvedEnvironment = { externalUrl: 'https://example.org', environmentType: 'review', nameWithoutType: 'hello', + tier: 'development', lastDeployment: { id: 78, iid: 24, @@ -551,6 +552,7 @@ export const resolvedEnvironment = { status: 'success', createdAt: '2022-01-07T15:47:27.415Z', deployedAt: '2022-01-07T15:47:32.450Z', + tierInYaml: 'staging', tag: false, isLast: true, user: { diff --git a/spec/frontend/environments/new_environment_item_spec.js b/spec/frontend/environments/new_environment_item_spec.js index 1d7a33fb95b..cf0c8a7e7ca 100644 --- a/spec/frontend/environments/new_environment_item_spec.js +++ b/spec/frontend/environments/new_environment_item_spec.js @@ -73,6 +73,34 @@ describe('~/environments/components/new_environment_item.vue', () => { expect(name.text()).toHaveLength(80); }); + describe('tier', () => { + it('displays the tier of the environment when defined in yaml', () => { + wrapper = createWrapper({ apolloProvider: createApolloProvider() }); + + const tier = wrapper.findByTitle(s__('Environment|Deployment tier')); + + expect(tier.text()).toBe(resolvedEnvironment.lastDeployment.tierInYaml); + }); + + it('does not display the tier if not defined in yaml', () => { + const environment = { + ...resolvedEnvironment, + lastDeployment: { + ...resolvedEnvironment.lastDeployment, + tierInYaml: null, + }, + }; + wrapper = createWrapper({ + propsData: { environment }, + apolloProvider: createApolloProvider(), + }); + + const tier = wrapper.findByTitle(s__('Environment|Deployment tier')); + + expect(tier.exists()).toBe(false); + }); + }); + describe('url', () => { it('shows a link for the url if one is present', () => { wrapper = createWrapper({ apolloProvider: createApolloProvider() }); diff --git a/spec/frontend/issues/list/components/issue_card_time_info_spec.js b/spec/frontend/issues/list/components/issue_card_time_info_spec.js index c6abf7d20a3..c3f13ca6f9a 100644 --- a/spec/frontend/issues/list/components/issue_card_time_info_spec.js +++ b/spec/frontend/issues/list/components/issue_card_time_info_spec.js @@ -1,6 +1,7 @@ import { GlIcon, GlLink } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; import { useFakeDate } from 'helpers/fake_date'; +import { IssuableStatus } from '~/issues/constants'; import IssueCardTimeInfo from '~/issues/list/components/issue_card_time_info.vue'; describe('CE IssueCardTimeInfo component', () => { @@ -24,7 +25,7 @@ describe('CE IssueCardTimeInfo component', () => { const findDueDate = () => wrapper.find('[data-testid="issuable-due-date"]'); const mountComponent = ({ - closedAt = null, + state = IssuableStatus.Open, dueDate = issue.dueDate, milestoneDueDate = issue.milestone.dueDate, milestoneStartDate = issue.milestone.startDate, @@ -38,7 +39,7 @@ describe('CE IssueCardTimeInfo component', () => { dueDate: milestoneDueDate, startDate: milestoneStartDate, }, - closedAt, + state, dueDate, }, }, @@ -101,7 +102,7 @@ describe('CE IssueCardTimeInfo component', () => { it('does not render in red', () => { wrapper = mountComponent({ dueDate: '2020-10-10', - closedAt: '2020-09-05T13:06:25Z', + state: IssuableStatus.Closed, }); expect(findDueDate().classes()).not.toContain('gl-text-red-500'); diff --git a/spec/frontend/issues/list/mock_data.js b/spec/frontend/issues/list/mock_data.js index c883b20682e..b1a135ceb18 100644 --- a/spec/frontend/issues/list/mock_data.js +++ b/spec/frontend/issues/list/mock_data.js @@ -21,7 +21,6 @@ export const getIssuesQueryResponse = { __typename: 'Issue', id: 'gid://gitlab/Issue/123456', iid: '789', - closedAt: null, confidential: false, createdAt: '2021-05-22T04:08:01Z', downvotes: 2, @@ -30,6 +29,7 @@ export const getIssuesQueryResponse = { humanTimeEstimate: null, mergeRequestsCount: false, moved: false, + state: 'opened', title: 'Issue title', updatedAt: '2021-05-22T04:08:01Z', upvotes: 3, diff --git a/spec/lib/gitlab/background_migration/encrypt_static_object_token_spec.rb b/spec/lib/gitlab/background_migration/encrypt_static_object_token_spec.rb index 94d9f4509a7..4e7b97d33f6 100644 --- a/spec/lib/gitlab/background_migration/encrypt_static_object_token_spec.rb +++ b/spec/lib/gitlab/background_migration/encrypt_static_object_token_spec.rb @@ -39,6 +39,14 @@ RSpec.describe Gitlab::BackgroundMigration::EncryptStaticObjectToken do expect(new_state[user_with_encrypted_token.id]).to match_array([nil, 'encrypted']) end + context 'when id range does not include existing user ids' do + let(:arguments) { [non_existing_record_id, non_existing_record_id.succ] } + + it_behaves_like 'marks background migration job records' do + subject { described_class.new } + end + end + private def create_user!(name:, token: nil, encrypted_token: nil) diff --git a/spec/lib/gitlab/database/each_database_spec.rb b/spec/lib/gitlab/database/each_database_spec.rb index d46c1ca8681..191f7017b4c 100644 --- a/spec/lib/gitlab/database/each_database_spec.rb +++ b/spec/lib/gitlab/database/each_database_spec.rb @@ -58,6 +58,15 @@ RSpec.describe Gitlab::Database::EachDatabase do end end end + + context 'when shared connections are not included' do + it 'only yields the unshared connections' do + expect(Gitlab::Database).to receive(:db_config_share_with).twice.and_return(nil, 'main') + + expect { |b| described_class.each_database_connection(include_shared: false, &b) } + .to yield_successive_args([ActiveRecord::Base.connection, 'main']) + end + end end describe '.each_model_connection' do diff --git a/spec/models/deployment_spec.rb b/spec/models/deployment_spec.rb index 47c246d12cc..973eedf043e 100644 --- a/spec/models/deployment_spec.rb +++ b/spec/models/deployment_spec.rb @@ -1055,6 +1055,40 @@ RSpec.describe Deployment do end end + describe '#tier_in_yaml' do + context 'when deployable is nil' do + before do + subject.deployable = nil + end + + it 'returns nil' do + expect(subject.tier_in_yaml).to be_nil + end + end + + context 'when deployable is present' do + context 'when tier is specified' do + let(:deployable) { create(:ci_build, :success, :environment_with_deployment_tier) } + + before do + subject.deployable = deployable + end + + it 'returns the tier' do + expect(subject.tier_in_yaml).to eq('testing') + end + + context 'when tier is not specified' do + let(:deployable) { create(:ci_build, :success) } + + it 'returns nil' do + expect(subject.tier_in_yaml).to be_nil + end + end + end + end + end + describe '.fast_destroy_all' do it 'cleans path_refs for destroyed environments' do project = create(:project, :repository) diff --git a/spec/models/error_tracking/project_error_tracking_setting_spec.rb b/spec/models/error_tracking/project_error_tracking_setting_spec.rb index d700eb5eaf7..2939a40a84f 100644 --- a/spec/models/error_tracking/project_error_tracking_setting_spec.rb +++ b/spec/models/error_tracking/project_error_tracking_setting_spec.rb @@ -8,6 +8,8 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do let_it_be(:project) { create(:project) } + let(:sentry_client) { instance_double(ErrorTracking::SentryClient) } + subject(:setting) { build(:project_error_tracking_setting, project: project) } describe 'Associations' do @@ -48,7 +50,7 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do expect(subject.errors.messages[:project]).to include('is a required field') end - context 'presence validations' do + describe 'presence validations' do using RSpec::Parameterized::TableSyntax valid_api_url = 'http://example.com/api/0/projects/org-slug/proj-slug/' @@ -83,12 +85,12 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do describe 'after_save :create_client_key!' do subject { build(:project_error_tracking_setting, :integrated, project: project) } - context 'no client key yet' do + context 'without client key' do it 'creates a new client key' do expect { subject.save! }.to change { ErrorTracking::ClientKey.count }.by(1) end - context 'sentry backend' do + context 'with sentry backend' do before do subject.integrated = false end @@ -98,7 +100,7 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do end end - context 'feature disabled' do + context 'when feature disabled' do before do subject.enabled = false end @@ -109,7 +111,7 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do end end - context 'client key already exists' do + context 'when client key already exists' do let!(:client_key) { create(:error_tracking_client_key, project: project) } it 'does not create a new client key' do @@ -122,13 +124,13 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do describe '.extract_sentry_external_url' do subject { described_class.extract_sentry_external_url(sentry_url) } - describe 'when passing a URL' do + context 'when passing a URL' do let(:sentry_url) { 'https://sentrytest.gitlab.com/api/0/projects/sentry-org/sentry-project' } it { is_expected.to eq('https://sentrytest.gitlab.com/sentry-org/sentry-project') } end - describe 'when passing nil' do + context 'when passing nil' do let(:sentry_url) { nil } it { is_expected.to be_nil } @@ -159,23 +161,15 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do describe '#list_sentry_issues' do let(:issues) { [:list, :of, :issues] } - - let(:opts) do - { issue_status: 'unresolved', limit: 10 } - end - - let(:result) do - subject.list_sentry_issues(**opts) - end + let(:result) { subject.list_sentry_issues(**opts) } + let(:opts) { { issue_status: 'unresolved', limit: 10 } } context 'when cached' do - let(:sentry_client) { spy(:sentry_client) } - before do stub_reactive_cache(subject, issues, opts) synchronous_reactive_cache(subject) - expect(subject).to receive(:sentry_client).and_return(sentry_client) + allow(subject).to receive(:sentry_client).and_return(sentry_client) end it 'returns cached issues' do @@ -195,8 +189,6 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do end context 'when sentry client raises ErrorTracking::SentryClient::Error' do - let(:sentry_client) { spy(:sentry_client) } - before do synchronous_reactive_cache(subject) @@ -214,14 +206,13 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do end context 'when sentry client raises ErrorTracking::SentryClient::MissingKeysError' do - let(:sentry_client) { spy(:sentry_client) } - before do synchronous_reactive_cache(subject) allow(subject).to receive(:sentry_client).and_return(sentry_client) allow(sentry_client).to receive(:list_issues).with(opts) - .and_raise(ErrorTracking::SentryClient::MissingKeysError, 'Sentry API response is missing keys. key not found: "id"') + .and_raise(ErrorTracking::SentryClient::MissingKeysError, + 'Sentry API response is missing keys. key not found: "id"') end it 'returns error' do @@ -233,8 +224,7 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do end context 'when sentry client raises ErrorTracking::SentryClient::ResponseInvalidSizeError' do - let(:sentry_client) { spy(:sentry_client) } - let(:error_msg) {"Sentry API response is too big. Limit is #{Gitlab::Utils::DeepSize.human_default_max_size}."} + let(:error_msg) { "Sentry API response is too big. Limit is #{Gitlab::Utils::DeepSize.human_default_max_size}." } before do synchronous_reactive_cache(subject) @@ -253,8 +243,6 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do end context 'when sentry client raises StandardError' do - let(:sentry_client) { spy(:sentry_client) } - before do synchronous_reactive_cache(subject) @@ -270,7 +258,6 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do describe '#list_sentry_projects' do let(:projects) { [:list, :of, :projects] } - let(:sentry_client) { spy(:sentry_client) } it 'calls sentry client' do expect(subject).to receive(:sentry_client).and_return(sentry_client) @@ -284,19 +271,17 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do describe '#issue_details' do let(:issue) { build(:error_tracking_sentry_detailed_error) } - let(:sentry_client) { double('sentry_client', issue_details: issue) } let(:commit_id) { issue.first_release_version } - - let(:result) do - subject.issue_details - end + let(:result) { subject.issue_details(opts) } + let(:opts) { { issue_id: 1 } } context 'when cached' do before do stub_reactive_cache(subject, issue, {}) synchronous_reactive_cache(subject) - expect(subject).to receive(:sentry_client).and_return(sentry_client) + allow(subject).to receive(:sentry_client).and_return(sentry_client) + allow(sentry_client).to receive(:issue_details).with(opts).and_return(issue) end it { expect(result).to eq(issue: issue) } @@ -314,15 +299,15 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do end context 'when repo commit matches first relase version' do - let(:commit) { double('commit', id: commit_id) } - let(:repository) { double('repository', commit: commit) } + let(:commit) { instance_double(Commit, id: commit_id) } + let(:repository) { instance_double(Repository, commit: commit) } before do - expect(project).to receive(:repository).and_return(repository) + allow(project).to receive(:repository).and_return(repository) end it { expect(result[:issue].gitlab_commit).to eq(commit_id) } - it { expect(result[:issue].gitlab_commit_path).to eq("/#{project.namespace.path}/#{project.path}/-/commit/#{commit_id}") } + it { expect(result[:issue].gitlab_commit_path).to eq(project_commit_path(project, commit_id)) } end end @@ -333,19 +318,15 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do end describe '#update_issue' do - let(:opts) do - { status: 'resolved' } - end + let(:result) { subject.update_issue(**opts) } + let(:opts) { { issue_id: 1, params: {} } } - let(:result) do - subject.update_issue(**opts) + before do + allow(subject).to receive(:sentry_client).and_return(sentry_client) end - let(:sentry_client) { spy(:sentry_client) } - - context 'successful call to sentry' do + context 'when sentry response is successful' do before do - allow(subject).to receive(:sentry_client).and_return(sentry_client) allow(sentry_client).to receive(:update_issue).with(opts).and_return(true) end @@ -354,9 +335,8 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do end end - context 'sentry raises an error' do + context 'when sentry raises an error' do before do - allow(subject).to receive(:sentry_client).and_return(sentry_client) allow(sentry_client).to receive(:update_issue).with(opts).and_raise(StandardError) end @@ -366,7 +346,7 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do end end - context 'slugs' do + describe 'slugs' do shared_examples_for 'slug from api_url' do |method, slug| context 'when api_url is correct' do before do @@ -393,9 +373,9 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do it_behaves_like 'slug from api_url', :organization_slug, 'org-slug' end - context 'names from api_url' do + describe 'names from api_url' do shared_examples_for 'name from api_url' do |name, titleized_slug| - context 'name is present in DB' do + context 'when name is present in DB' do it 'returns name from DB' do subject[name] = 'Sentry name' subject.api_url = 'http://gitlab.com/api/0/projects/org-slug/project-slug' @@ -404,7 +384,7 @@ RSpec.describe ErrorTracking::ProjectErrorTrackingSetting do end end - context 'name is null in DB' do + context 'when name is null in DB' do it 'titleizes and returns slug from api_url' do subject[name] = nil subject.api_url = 'http://gitlab.com/api/0/projects/org-slug/project-slug' diff --git a/spec/requests/api/issue_links_spec.rb b/spec/requests/api/issue_links_spec.rb index 14e32e48b2b..81dd4c3dfa0 100644 --- a/spec/requests/api/issue_links_spec.rb +++ b/spec/requests/api/issue_links_spec.rb @@ -205,16 +205,30 @@ RSpec.describe API::IssueLinks do end context 'when user has ability to delete the issue link' do + let_it_be(:target_issue) { create(:issue, project: project) } + + before do + project.add_reporter(user) + end + it 'returns 200' do - target_issue = create(:issue, project: project) issue_link = create(:issue_link, source: issue, target: target_issue) - project.add_reporter(user) delete api("/projects/#{project.id}/issues/#{issue.iid}/links/#{issue_link.id}", user) expect(response).to have_gitlab_http_status(:ok) expect(response).to match_response_schema('public_api/v4/issue_link') end + + it 'returns 404 when the issue link does not belong to the specified issue' do + other_issue = create(:issue, project: project) + issue_link = create(:issue_link, source: other_issue, target: target_issue) + + delete api("/projects/#{project.id}/issues/#{issue.iid}/links/#{issue_link.id}", user) + + expect(response).to have_gitlab_http_status(:not_found) + expect(json_response['message']).to eq('404 Not found') + end end end end diff --git a/spec/serializers/deployment_entity_spec.rb b/spec/serializers/deployment_entity_spec.rb index 1dacc9513ee..500d5718bf1 100644 --- a/spec/serializers/deployment_entity_spec.rb +++ b/spec/serializers/deployment_entity_spec.rb @@ -9,7 +9,7 @@ RSpec.describe DeploymentEntity do let(:project) { create(:project, :repository) } let(:request) { double('request') } let(:deployment) { create(:deployment, deployable: build, project: project) } - let(:build) { create(:ci_build, :manual, pipeline: pipeline) } + let(:build) { create(:ci_build, :manual, :environment_with_deployment_tier, pipeline: pipeline) } let(:pipeline) { create(:ci_pipeline, project: project, user: user) } let(:entity) { described_class.new(deployment, request: request) } @@ -46,6 +46,10 @@ RSpec.describe DeploymentEntity do expect(subject).to include(:is_last) end + it 'exposes deployment tier in yaml' do + expect(subject).to include(:tier_in_yaml) + end + context 'when deployable is nil' do let(:entity) { described_class.new(deployment, request: request, deployment_details: false) } let(:deployment) { create(:deployment, deployable: nil, project: project) } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e9f2da93016..1e137ad6fc2 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -237,6 +237,7 @@ RSpec.configure do |config| # Enable all features by default for testing # Reset any changes in after hook. stub_all_feature_flags + stub_feature_flags(main_branch_over_master: false) TestEnv.seed_db end diff --git a/spec/support/shared_examples/models/issuable_link_shared_examples.rb b/spec/support/shared_examples/models/issuable_link_shared_examples.rb index ca98c2597a2..9892e66b582 100644 --- a/spec/support/shared_examples/models/issuable_link_shared_examples.rb +++ b/spec/support/shared_examples/models/issuable_link_shared_examples.rb @@ -55,6 +55,19 @@ RSpec.shared_examples 'issuable link' do end end + describe 'scopes' do + describe '.for_source_or_target' do + it 'returns only links where id is either source or target id' do + link1 = create(issuable_link_factory, source: issuable_link.source) + link2 = create(issuable_link_factory, target: issuable_link.source) + # unrelated link, should not be included in result list + create(issuable_link_factory) # rubocop: disable Rails/SaveBang + + expect(described_class.for_source_or_target(issuable_link.source_id)).to match_array([issuable_link, link1, link2]) + end + end + end + describe '.link_type' do it { is_expected.to define_enum_for(:link_type).with_values(relates_to: 0, blocks: 1) } diff --git a/spec/tasks/gitlab/db/validate_config_rake_spec.rb b/spec/tasks/gitlab/db/validate_config_rake_spec.rb index 4924ecc0ec9..7b2f37414a0 100644 --- a/spec/tasks/gitlab/db/validate_config_rake_spec.rb +++ b/spec/tasks/gitlab/db/validate_config_rake_spec.rb @@ -53,6 +53,18 @@ RSpec.describe 'gitlab:db:validate_config', :silence_stdout do expect { run_rake_task('gitlab:db:validate_config') }.not_to output(/Database config validation failure/).to_stderr expect { run_rake_task('gitlab:db:validate_config') }.not_to raise_error end + + context 'when finding the initializer fails' do + where(:raised_error) { [ActiveRecord::NoDatabaseError, ActiveRecord::ConnectionNotEstablished, PG::ConnectionBad] } + with_them do + it "does not raise an error for #{params[:raised_error]}" do + allow(ActiveRecord::Base.connection).to receive(:select_one).and_raise(raised_error) # rubocop: disable Database/MultipleDatabases + + expect { run_rake_task('gitlab:db:validate_config') }.not_to output(/Database config validation failure/).to_stderr + expect { run_rake_task('gitlab:db:validate_config') }.not_to raise_error + end + end + end end shared_examples 'raises an error' do |match| diff --git a/spec/tasks/gitlab/setup_rake_spec.rb b/spec/tasks/gitlab/setup_rake_spec.rb index 6e4d5087517..6b4dde22dca 100644 --- a/spec/tasks/gitlab/setup_rake_spec.rb +++ b/spec/tasks/gitlab/setup_rake_spec.rb @@ -22,7 +22,11 @@ RSpec.describe 'gitlab:setup namespace rake tasks', :silence_stdout do let(:server_service1) { double(:server_service) } let(:server_service2) { double(:server_service) } - let(:connections) { Gitlab::Database.database_base_models.values.map(&:connection) } + let(:connections) do + Gitlab::Database.database_base_models.values.filter_map do |model| + model.connection if Gitlab::Database.db_config_share_with(model.connection_db_config).nil? + end + end before do allow(Gitlab).to receive_message_chain('config.repositories.storages').and_return(storages) @@ -119,6 +123,10 @@ RSpec.describe 'gitlab:setup namespace rake tasks', :silence_stdout do end def expect_connections_to_be_terminated + expect(Gitlab::Database::EachDatabase).to receive(:each_database_connection) + .with(include_shared: false) + .and_call_original + expect(connections).to all(receive(:execute).with(/SELECT pg_terminate_backend/)) end diff --git a/spec/workers/container_registry/migration/enqueuer_worker_spec.rb b/spec/workers/container_registry/migration/enqueuer_worker_spec.rb index ca839dc4bcb..00fab58992a 100644 --- a/spec/workers/container_registry/migration/enqueuer_worker_spec.rb +++ b/spec/workers/container_registry/migration/enqueuer_worker_spec.rb @@ -64,7 +64,8 @@ RSpec.describe ContainerRegistry::Migration::EnqueuerWorker, :aggregate_failures expect_log_extra_metadata( import_type: 'next', container_repository_id: container_repository.id, - container_repository_path: container_repository.path + container_repository_path: container_repository.path, + container_repository_migration_state: 'pre_importing' ) subject @@ -135,7 +136,8 @@ RSpec.describe ContainerRegistry::Migration::EnqueuerWorker, :aggregate_failures expect_log_extra_metadata( import_type: 'retry', container_repository_id: aborted_repository.id, - container_repository_path: aborted_repository.path + container_repository_path: aborted_repository.path, + container_repository_migration_state: 'importing' ) subject @@ -158,7 +160,8 @@ RSpec.describe ContainerRegistry::Migration::EnqueuerWorker, :aggregate_failures expect_log_extra_metadata( import_type: 'retry', container_repository_id: aborted_repository.id, - container_repository_path: aborted_repository.path + container_repository_path: aborted_repository.path, + container_repository_migration_state: 'import_aborted' ) subject @@ -189,6 +192,7 @@ RSpec.describe ContainerRegistry::Migration::EnqueuerWorker, :aggregate_failures import_type: 'next', container_repository_id: container_repository.id, container_repository_path: container_repository.path, + container_repository_migration_state: 'import_skipped', tags_count_too_high: true, max_tags_count_setting: 2 ) @@ -212,7 +216,8 @@ RSpec.describe ContainerRegistry::Migration::EnqueuerWorker, :aggregate_failures expect_log_extra_metadata( import_type: 'next', container_repository_id: container_repository.id, - container_repository_path: container_repository.path + container_repository_path: container_repository.path, + container_repository_migration_state: 'import_aborted' ) expect(Gitlab::ErrorTracking).to receive(:log_exception).with( |