diff options
43 files changed, 320 insertions, 83 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index abcb6861189..692e41b2a7f 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -0a03f045e065b9e7a157322fbe486e1f02fd8617 +072f01c9a020b2b49c222a338349555b2e807384 @@ -171,7 +171,7 @@ gem 'asciidoctor-kroki', '~> 0.5.0', require: false gem 'rouge', '~> 3.30.0' gem 'truncato', '~> 0.7.11' gem 'bootstrap_form', '~> 4.2.0' -gem 'nokogiri', '~> 1.13.6' +gem 'nokogiri', '~> 1.13.0' gem 'escape_utils', '~> 1.1' # Calendar rendering diff --git a/Gemfile.lock b/Gemfile.lock index 6af20938e38..e029123b3eb 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -846,7 +846,7 @@ GEM netrc (0.11.0) nio4r (2.5.8) no_proxy_fix (0.1.2) - nokogiri (1.13.7) + nokogiri (1.13.8) mini_portile2 (~> 2.8.0) racc (~> 1.4) notiffany (0.1.3) @@ -1639,7 +1639,7 @@ DEPENDENCIES multi_json (~> 1.14.1) net-ldap (~> 0.16.3) net-ntp - nokogiri (~> 1.13.6) + nokogiri (~> 1.13.0) oauth2 (~> 2.0) octokit (~> 4.15) ohai (~> 16.10) diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue index 42e9261b82c..18103ac4a0e 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/mr_widget_failed_to_merge.vue @@ -30,7 +30,7 @@ export default { computed: { mergeError() { - const mergeError = this.mr.mergeError ? stripHtml(this.mr.mergeError, ' ').trim() : ''; + const mergeError = this.prepareMergeError(this.mr.mergeError); return sprintf( s__('mrWidget|%{mergeError}.'), @@ -76,6 +76,13 @@ export default { this.refresh(); } }, + prepareMergeError(mergeError) { + return mergeError + ? stripHtml(mergeError, ' ') + .replace(/(\.$|\s+)/g, ' ') + .trim() + : ''; + }, }, }; </script> @@ -89,7 +96,9 @@ export default { <status-icon :show-disabled-button="true" status="warning" /> <div class="media-body space-children"> <span class="bold"> - <span v-if="mr.mergeError" class="has-error-message"> {{ mergeError }} </span> + <span v-if="mr.mergeError" class="has-error-message" data-testid="merge-error"> + {{ mergeError }} + </span> <span v-else> {{ s__('mrWidget|Merge failed.') }} </span> <span :class="{ 'has-custom-error': mr.mergeError }"> {{ timerText }} </span> </span> diff --git a/app/services/branches/create_service.rb b/app/services/branches/create_service.rb index 7300b31e3b3..890b140c48c 100644 --- a/app/services/branches/create_service.rb +++ b/app/services/branches/create_service.rb @@ -2,35 +2,84 @@ module Branches class CreateService < BaseService + def initialize(project, user = nil, params = {}) + super(project, user, params) + + @errors = [] + end + def execute(branch_name, ref, create_default_branch_if_empty: true) create_default_branch if create_default_branch_if_empty && project.empty_repo? - result = ::Branches::ValidateNewService.new(project).execute(branch_name) + result = branch_validation_service.execute(branch_name) return result if result[:status] == :error - begin - new_branch = repository.add_branch(current_user, branch_name, ref) - rescue Gitlab::Git::CommandError => e - return error("Failed to create branch '#{branch_name}': #{e}") + create_branch(branch_name, ref) + end + + def bulk_create(branches) + reset_errors + + created_branches = + branches + .then { |branches| only_valid_branches(branches) } + .then { |branches| create_branches(branches) } + + return error(errors) if errors.present? + + success(branches: created_branches) + end + + private + + attr_reader :errors + + def reset_errors + @errors = [] + end + + def only_valid_branches(branches) + branches.select do |branch_name, _ref| + result = branch_validation_service.execute(branch_name) + + if result[:status] == :error + errors << result[:message] + next + end + + true + end + end + + def create_branches(branches) + branches.filter_map do |branch_name, ref| + result = create_branch(branch_name, ref) + + if result[:status] == :error + errors << result[:message] + next + end + + result[:branch] end + end + + def create_branch(branch_name, ref) + new_branch = repository.add_branch(current_user, branch_name, ref) if new_branch - success(new_branch) + success(branch: new_branch) else error("Failed to create branch '#{branch_name}': invalid reference name '#{ref}'") end + rescue Gitlab::Git::CommandError => e + error("Failed to create branch '#{branch_name}': #{e}") rescue Gitlab::Git::PreReceiveError => e Gitlab::ErrorTracking.log_exception(e, pre_receive_message: e.raw_message, branch_name: branch_name, ref: ref) error(e.message) end - def success(branch) - super().merge(branch: branch) - end - - private - def create_default_branch project.repository.create_file( current_user, @@ -40,5 +89,9 @@ module Branches branch_name: project.default_branch_or_main ) end + + def branch_validation_service + @branch_validation_service ||= ::Branches::ValidateNewService.new(project) + end end end diff --git a/config/feature_flags/development/pull_mirror_bulk_branches.yml b/config/feature_flags/development/pull_mirror_bulk_branches.yml new file mode 100644 index 00000000000..23ae88b81ab --- /dev/null +++ b/config/feature_flags/development/pull_mirror_bulk_branches.yml @@ -0,0 +1,8 @@ +--- +name: pull_mirror_bulk_branches +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/93211 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/368797 +milestone: '15.2' +type: development +group: group::source code +default_enabled: false diff --git a/config/feature_flags/development/subgroups_approval_rules.yml b/config/feature_flags/development/subgroups_approval_rules.yml index 13f4e872b4f..e7935f5e5d2 100644 --- a/config/feature_flags/development/subgroups_approval_rules.yml +++ b/config/feature_flags/development/subgroups_approval_rules.yml @@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/366741 milestone: '15.2' type: development group: group::source code -default_enabled: false +default_enabled: true diff --git a/doc/administration/geo/disaster_recovery/index.md b/doc/administration/geo/disaster_recovery/index.md index f457cb4b0a2..76e2d7ae97d 100644 --- a/doc/administration/geo/disaster_recovery/index.md +++ b/doc/administration/geo/disaster_recovery/index.md @@ -572,7 +572,7 @@ and after that you also need two extra steps. postgresql['md5_auth_cidr_addresses'] = ['<primary_site_ip>/32', '<secondary_site_ip>/32'] # Every secondary site needs to have its own slot so specify the number of secondary sites you're going to have - postgresql['max_replication_slots'] = 1 + # postgresql['max_replication_slots'] = 1 # Set this to be the number of Geo secondary nodes if you have more than one ## ## Disable automatic database migrations temporarily diff --git a/doc/administration/geo/setup/database.md b/doc/administration/geo/setup/database.md index 5d5eb2ca90c..6c9ebb29116 100644 --- a/doc/administration/geo/setup/database.md +++ b/doc/administration/geo/setup/database.md @@ -235,9 +235,8 @@ There is an [issue where support is being discussed](https://gitlab.com/gitlab-o ## ## Replication settings - ## - set this to be the number of Geo secondary nodes you have ## - postgresql['max_replication_slots'] = 1 + # postgresql['max_replication_slots'] = 1 # Set this to be the number of Geo secondary nodes if you have more than one # postgresql['max_wal_senders'] = 10 # postgresql['wal_keep_segments'] = 10 diff --git a/doc/administration/geo/setup/index.md b/doc/administration/geo/setup/index.md index 5ddfee6774e..0cd77ac88f6 100644 --- a/doc/administration/geo/setup/index.md +++ b/doc/administration/geo/setup/index.md @@ -24,6 +24,7 @@ If you installed GitLab using the Omnibus packages (highly recommended): 1. [Install GitLab Enterprise Edition](https://about.gitlab.com/install/) on the nodes that serve as the **secondary** site. **Do not create an account or log in** to the new **secondary** site. The **GitLab version must match** across primary and secondary sites. 1. [Add the GitLab License](../../../user/admin_area/license.md) on the **primary** site to unlock Geo. The license must be for [GitLab Premium](https://about.gitlab.com/pricing/) or higher. +1. [Confirm network connectivity](../index.md#firewall-rules) between the **primary** and **secondary** site. 1. [Set up the database replication](database.md) (`primary (read-write) <-> secondary (read-only)` topology). 1. [Configure fast lookup of authorized SSH keys in the database](../../operations/fast_ssh_key_lookup.md). This step is required and needs to be done on **both** the **primary** and **secondary** sites. 1. [Configure GitLab](../replication/configuration.md) to set the **primary** and **secondary** sites. diff --git a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md index 52b4fff983a..0618d363499 100644 --- a/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md +++ b/doc/administration/troubleshooting/gitlab_rails_cheat_sheet.md @@ -306,7 +306,7 @@ Project.find_each do |p| end ``` -## Bulk update to change all the Jira integrations to Jira instance-level values +### Bulk update to change all the Jira integrations to Jira instance-level values To change all Jira project to use the instance-level integration settings: @@ -321,6 +321,25 @@ To change all Jira project to use the instance-level integration settings: 1. Modify and save again the instance-level integration from the UI to propagate the changes to all the group-level and project-level integrations. +### Check if Jira Cloud is linked to a namespace + +```ruby +JiraConnectSubscription.where(namespace: Namespace.by_path('group/subgroup')) +``` + +### Check if Jira Cloud is linked to a project + +```ruby +Project.find_by_full_path('path/to/project').jira_subscription_exists? +``` + +### Check if Jira Cloud URL is linked to any namespace + +```ruby +installation = JiraConnectInstallation.find_by_base_url("https://customer_name.atlassian.net") +installation.subscriptions +``` + ### Bulk update to disable the Slack Notification service To disable notifications for all projects that have Slack service enabled, do: diff --git a/doc/development/adding_database_indexes.md b/doc/development/adding_database_indexes.md index 0211d2c822c..e18f1205718 100644 --- a/doc/development/adding_database_indexes.md +++ b/doc/development/adding_database_indexes.md @@ -259,15 +259,16 @@ end ### Verify the MR was deployed and the index exists in production -You can verify if the MR was deployed to GitLab.com by executing -`/chatops run auto_deploy status <merge_sha>`. To verify existence of -the index, you can: +You can verify if the post-deploy migration was executed on GitLab.com by: +- Executing `/chatops run auto_deploy status <merge_sha>`. If the output returns `db/gprd`, + the post-deploy migration has been executed in the production database. More details in this + [guide](https://gitlab.com/gitlab-org/release/docs/-/blob/master/general/post_deploy_migration/readme.md#how-to-determine-if-a-post-deploy-migration-has-been-executed-on-gitlabcom). - Use a meta-command in #database-lab, such as: `\d <index_name>`. - Ensure that the index is not [`invalid`](https://www.postgresql.org/docs/12/sql-createindex.html#:~:text=The%20psql%20%5Cd%20command%20will%20report%20such%20an%20index%20as%20INVALID). - Ask someone in #database to check if the index exists. - With proper access, you can also verify directly on production or in a -production clone. + production clone. ### Add a migration to create the index synchronously diff --git a/doc/development/database/post_deployment_migrations.md b/doc/development/database/post_deployment_migrations.md index a49c77ca047..8166fcc8905 100644 --- a/doc/development/database/post_deployment_migrations.md +++ b/doc/development/database/post_deployment_migrations.md @@ -25,6 +25,10 @@ This however skips post deployment migrations: SKIP_POST_DEPLOYMENT_MIGRATIONS=true bundle exec rake db:migrate ``` +For GitLab.com, these migrations are executed on a daily basis at the discretion of +release managers through the +[post-deploy migration pipeline](https://gitlab.com/gitlab-org/release/docs/-/blob/master/general/post_deploy_migration/readme.md). + ## Deployment Integration Say you're using Chef for deploying new versions of GitLab and you'd like to run diff --git a/doc/development/database_review.md b/doc/development/database_review.md index 2b215190e6d..37643f04db7 100644 --- a/doc/development/database_review.md +++ b/doc/development/database_review.md @@ -247,9 +247,9 @@ Include in the MR description: - Making numerous SQL queries per record in a dataset. - Review queries (for example, make sure batch sizes are fine) - Because execution time can be longer than for a regular migration, - it's suggested to treat background migrations as post migrations: - place them in `db/post_migrate` instead of `db/migrate`. Keep in mind - that post migrations are executed post-deployment in production. + it's suggested to treat background migrations as + [post migrations](migration_style_guide.md#choose-an-appropriate-migration-type): + place them in `db/post_migrate` instead of `db/migrate`. - If a migration [has tracking enabled](database/background_migrations.md#background-jobs-tracking), ensure `mark_all_as_succeeded` is called even if no work is done. - Check [timing guidelines for migrations](migration_style_guide.md#how-long-a-migration-should-take) diff --git a/doc/development/documentation/styleguide/index.md b/doc/development/documentation/styleguide/index.md index 72d489304c7..fe699c19a96 100644 --- a/doc/development/documentation/styleguide/index.md +++ b/doc/development/documentation/styleguide/index.md @@ -150,6 +150,8 @@ the page is rendered to HTML. There can be only **one** level 1 heading per page - For each subsection, increment the heading level. In other words, increment the number of `#` characters in front of the heading. +- Avoid headings greater than `H5` (`#####`). If you need more than five headings, move the topics to a new page instead. + Headings greater than `H5` do not display in the right sidebar navigation. - Do not skip a level. For example: `##` > `####`. - Leave one blank line before and after the heading. diff --git a/doc/development/migration_style_guide.md b/doc/development/migration_style_guide.md index e0e21319f47..f69b2c686aa 100644 --- a/doc/development/migration_style_guide.md +++ b/doc/development/migration_style_guide.md @@ -46,8 +46,9 @@ work it needs to perform and how long it takes to complete: For example, you might have indices that enforce unique tuples, or that are needed for query performance in critical parts of the application. In cases where the migration would be unacceptably slow, however, a better option might be to guard the feature with a [feature flag](feature_flags/index.md) and perform a post-deployment migration instead. The feature can then be turned on after the migration finishes. 1. [**Post-deployment migrations.**](database/post_deployment_migrations.md) These are Rails migrations in `db/post_migrate` and - run _after_ new application code has been deployed (for GitLab.com after the production deployment has finished). - They can be used for schema changes that aren't critical for the application to operate, or data migrations that take at most a few minutes. + are run independently from the GitLab.com deployments. Pending post migrations are executed on a daily basis at the discretion + of release manager through the [post-deploy migration pipeline](https://gitlab.com/gitlab-org/release/docs/-/blob/master/general/post_deploy_migration/readme.md#how-to-determine-if-a-post-deploy-migration-has-been-executed-on-gitlabcom). + These migrations can be used for schema changes that aren't critical for the application to operate, or data migrations that take at most a few minutes. Common examples for schema changes that should run post-deploy include: - Clean-ups, like removing unused columns. - Adding non-critical indices on high-traffic tables. diff --git a/doc/user/application_security/policies/index.md b/doc/user/application_security/policies/index.md index 81a9cef885d..5eafeb7bd79 100644 --- a/doc/user/application_security/policies/index.md +++ b/doc/user/application_security/policies/index.md @@ -137,3 +137,13 @@ See [Scan result policies](scan-result-policies.md). See the [Category Direction page](https://about.gitlab.com/direction/protect/security_orchestration/) for more information on the product direction of security policies within GitLab. + +## Troubleshooting + +### Branch name does not follow the pattern `'update-policy-<timestamp>'` + +When you create a new security policy or change an existing policy, a new branch is automatically created with the branch name following the pattern `update-policy-<timestamp>`. For example: `update-policy-1659094451`. + +If you have group or instance push rules that do not allow branch name patterns that contain the text `update-policy-<timestamp>`, you will get an error that states `Branch name does not follow the pattern 'update-policy-<timestamp>'`. + +The workaround is to amend your group or instance push rules to allow branches following the pattern `update-policy-` followed by an integer timestamp. diff --git a/doc/user/clusters/agent/vulnerabilities.md b/doc/user/clusters/agent/vulnerabilities.md index 3b80a7a0f81..5afe3ccec2b 100644 --- a/doc/user/clusters/agent/vulnerabilities.md +++ b/doc/user/clusters/agent/vulnerabilities.md @@ -16,6 +16,9 @@ You can also configure your agent so the vulnerabilities are displayed with othe You can use operational container scanning to scan container images in your cluster for security vulnerabilities. +NOTE: +In GitLab 15.0 and later, you do not need to install Starboard operator in the Kubernetes cluster. + To begin scanning all resources in your cluster, add a `starboard` configuration block to your agent configuration with a `cadence` field containing a CRON expression for when the scans will be run. diff --git a/doc/user/packages/package_registry/index.md b/doc/user/packages/package_registry/index.md index d68c7218ca5..04c27e79d01 100644 --- a/doc/user/packages/package_registry/index.md +++ b/doc/user/packages/package_registry/index.md @@ -66,6 +66,9 @@ For most package types, the following credential types are valid: which prevents you from using a job token with internal projects. This bug only impacts self-managed GitLab instances. +NOTE: +If you have not activated the "Packages" feature for your project at **Settings > General > Project features**, you will receive a 403 Forbidden response. + ## Use GitLab CI/CD to build packages You can use [GitLab CI/CD](../../../ci/index.md) to build packages. diff --git a/doc/user/project/merge_requests/reviews/img/mr_review_new_comment_v13_11.png b/doc/user/project/merge_requests/reviews/img/mr_review_new_comment_v13_11.png Binary files differdeleted file mode 100644 index 6b4899bf67f..00000000000 --- a/doc/user/project/merge_requests/reviews/img/mr_review_new_comment_v13_11.png +++ /dev/null diff --git a/doc/user/project/merge_requests/reviews/img/mr_review_new_comment_v15_3.png b/doc/user/project/merge_requests/reviews/img/mr_review_new_comment_v15_3.png Binary files differnew file mode 100644 index 00000000000..b73dbb50cd2 --- /dev/null +++ b/doc/user/project/merge_requests/reviews/img/mr_review_new_comment_v15_3.png diff --git a/doc/user/project/merge_requests/reviews/img/mr_review_resolve.png b/doc/user/project/merge_requests/reviews/img/mr_review_resolve.png Binary files differdeleted file mode 100644 index ced33682459..00000000000 --- a/doc/user/project/merge_requests/reviews/img/mr_review_resolve.png +++ /dev/null diff --git a/doc/user/project/merge_requests/reviews/img/mr_review_resolve2.png b/doc/user/project/merge_requests/reviews/img/mr_review_resolve2.png Binary files differdeleted file mode 100644 index 2f0be3b6d06..00000000000 --- a/doc/user/project/merge_requests/reviews/img/mr_review_resolve2.png +++ /dev/null diff --git a/doc/user/project/merge_requests/reviews/img/mr_review_start.png b/doc/user/project/merge_requests/reviews/img/mr_review_start.png Binary files differdeleted file mode 100644 index 08b4c6bb82b..00000000000 --- a/doc/user/project/merge_requests/reviews/img/mr_review_start.png +++ /dev/null diff --git a/doc/user/project/merge_requests/reviews/img/mr_review_unresolve.png b/doc/user/project/merge_requests/reviews/img/mr_review_unresolve.png Binary files differdeleted file mode 100644 index 4bef38f7808..00000000000 --- a/doc/user/project/merge_requests/reviews/img/mr_review_unresolve.png +++ /dev/null diff --git a/doc/user/project/merge_requests/reviews/img/mr_summary_comment_v15_3.png b/doc/user/project/merge_requests/reviews/img/mr_summary_comment_v15_3.png Binary files differnew file mode 100644 index 00000000000..38e18115803 --- /dev/null +++ b/doc/user/project/merge_requests/reviews/img/mr_summary_comment_v15_3.png diff --git a/doc/user/project/merge_requests/reviews/index.md b/doc/user/project/merge_requests/reviews/index.md index a8f43dd9c02..27b223c48ec 100644 --- a/doc/user/project/merge_requests/reviews/index.md +++ b/doc/user/project/merge_requests/reviews/index.md @@ -36,13 +36,9 @@ To start your review: 1. Select the **{comment}** **comment** icon in the gutter to expand the diff lines and display a comment box. In GitLab version 13.2 and later, you can [select multiple lines](#comment-on-multiple-lines). -1. Write your first comment, and select **Start a review** below your comment: - ![Starting a review](img/mr_review_start.png) -1. Continue adding comments to lines of code, and select the appropriate button after - you write a comment: - - **Add to review**: Keep this comment private and add to the current review. - These review comments are marked **Pending** and are visible only to you. - - **Add comment now**: Submits the specific comment as a regular comment instead of as part of the review. +1. In the text area, write your first comment, then select **Start a review** below your comment. +1. Continue adding comments to lines of code. After each comment, select **Add to review**. + Comments made as part of a review are visible only to you until you submit your review. 1. Optional. You can use [quick actions](../../quick_actions.md) inside review comments. The comment shows the actions to perform after publication, but does not perform them until you submit your review. @@ -60,8 +56,12 @@ displays next to your name. You can submit your completed review in multiple ways: - Use the `/submit_review` [quick action](../../quick_actions.md) in the text of a non-review comment. -- When creating a review comment, select **Submit review**. -- Scroll to the bottom of the screen and select **Submit review**. +- Select **Finish review** and then **Submit review** in the footer at the bottom of the screen. + +Selecting **Finish review** opens a modal window to add an optional comment to summarize your review. +You can also include quick actions: + +![Finish review with comment](img/mr_summary_comment_v15_3.png) When you submit your review, GitLab: @@ -73,25 +73,25 @@ When you submit your review, GitLab: ### Resolve or unresolve thread with a comment Review comments can also resolve or unresolve [resolvable threads](../../../discussions/index.md#resolve-a-thread). -When replying to a comment, a checkbox is displayed to resolve or unresolve -the thread after publication. - -![Resolve checkbox](img/mr_review_resolve.png) +To resolve or unresolve a thread when replying to a comment: -If a particular pending comment resolves or unresolves the thread, this is shown on the pending -comment itself. +1. In the comment text area, write your comment. +1. Select or clear **Resolve thread**. +1. Select **Add comment now** or **Add to review**. -![Resolve status](img/mr_review_resolve2.png) +Pending comments display information about the action to be taken when the comment is published: -![Unresolve status](img/mr_review_unresolve.png) +- **{check-circle-filled}** Thread will be resolved. +- **{check-circle}** Thread stays unresolved. ### Add a new comment > [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/8225) in GitLab 13.10. -If you have a review in progress, you are presented with the option to **Add to review**: +If you have a review in progress, you can also add a comment from the **Overview** tab by selecting + **Add to review**: -![New thread](img/mr_review_new_comment_v13_11.png) +![New thread](img/mr_review_new_comment_v15_3.png) ### Approval Rule information for Reviewers **(PREMIUM)** diff --git a/doc/user/project/pages/img/remove_pages.png b/doc/user/project/pages/img/remove_pages.png Binary files differdeleted file mode 100644 index d6c37ef30cd..00000000000 --- a/doc/user/project/pages/img/remove_pages.png +++ /dev/null diff --git a/doc/user/project/pages/img/remove_pages_v15_3.png b/doc/user/project/pages/img/remove_pages_v15_3.png Binary files differnew file mode 100644 index 00000000000..f740daf5c0b --- /dev/null +++ b/doc/user/project/pages/img/remove_pages_v15_3.png diff --git a/doc/user/project/pages/introduction.md b/doc/user/project/pages/introduction.md index 1ea7500273e..f664b2aaebc 100644 --- a/doc/user/project/pages/introduction.md +++ b/doc/user/project/pages/introduction.md @@ -74,7 +74,7 @@ to your project's settings through the gear icon in the top right, and then navigating to **Pages**. Select the **Remove pages** button to delete your Pages website. -![Remove pages](img/remove_pages.png) +![Remove pages](img/remove_pages_v15_3.png) ## Subdomains of subdomains diff --git a/qa/Gemfile.lock b/qa/Gemfile.lock index c2eb5a82184..67d1aa19706 100644 --- a/qa/Gemfile.lock +++ b/qa/Gemfile.lock @@ -198,7 +198,7 @@ GEM multi_xml (0.6.0) multipart-post (2.1.1) netrc (0.11.0) - nokogiri (1.13.6) + nokogiri (1.13.8) mini_portile2 (~> 2.8.0) racc (~> 1.4) octokit (4.21.0) diff --git a/scripts/static-analysis b/scripts/static-analysis index 144d40d36c2..afebb86bef8 100755 --- a/scripts/static-analysis +++ b/scripts/static-analysis @@ -13,7 +13,7 @@ class StaticAnalysis # warning message so that GitLab backports don't fail. "Browserslist: caniuse-lite is outdated. Please run next command `yarn upgrade`", # https://github.com/mime-types/mime-types-data/pull/50#issuecomment-1060908930 - "Type application/netcdf is already registered as a variant of application/netcdf" + "Type application/netcdf is already registered as a variant of application/netcdf." ].freeze Task = Struct.new(:command, :duration) do diff --git a/spec/features/cycle_analytics_spec.rb b/spec/features/cycle_analytics_spec.rb index e843f37c6f1..7714783172f 100644 --- a/spec/features/cycle_analytics_spec.rb +++ b/spec/features/cycle_analytics_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'Value Stream Analytics', :js do + include CycleAnalyticsHelpers + let_it_be(:user) { create(:user) } let_it_be(:guest) { create(:user) } let_it_be(:stage_table_selector) { '[data-testid="vsa-stage-table"]' } diff --git a/spec/features/markdown/gitlab_flavored_markdown_spec.rb b/spec/features/markdown/gitlab_flavored_markdown_spec.rb index da4208318eb..e831d1be608 100644 --- a/spec/features/markdown/gitlab_flavored_markdown_spec.rb +++ b/spec/features/markdown/gitlab_flavored_markdown_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe "GitLab Flavored Markdown" do + include CycleAnalyticsHelpers + let(:user) { create(:user) } let(:project) { create(:project) } let(:issue) { create(:issue, project: project) } diff --git a/spec/features/search/user_searches_for_commits_spec.rb b/spec/features/search/user_searches_for_commits_spec.rb index 279db686aa9..2dceda09d7c 100644 --- a/spec/features/search/user_searches_for_commits_spec.rb +++ b/spec/features/search/user_searches_for_commits_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'User searches for commits', :js do + include CycleAnalyticsHelpers + let(:project) { create(:project, :repository) } let(:sha) { '6d394385cf567f80a8fd85055db1ab4c5295806f' } let(:user) { create(:user) } diff --git a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_failed_to_merge_spec.js b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_failed_to_merge_spec.js index a9c1d602a37..989aa76f09b 100644 --- a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_failed_to_merge_spec.js +++ b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_failed_to_merge_spec.js @@ -53,7 +53,31 @@ describe('MRWidgetFailedToMerge', () => { await nextTick(); - expect(wrapper.vm.mergeError).toBe('contains line breaks.'); + expect(wrapper.find('[data-testid="merge-error"]').text()).toBe('contains line breaks.'); + }); + + it('does not append an extra period', async () => { + createComponent({ mr: { mergeError: 'contains a period.' } }); + + await nextTick(); + + expect(wrapper.find('[data-testid="merge-error"]').text()).toBe('contains a period.'); + }); + + it('does not insert an extra space between the final character and the period', async () => { + createComponent({ mr: { mergeError: 'contains a <a href="http://example.com">link</a>.' } }); + + await nextTick(); + + expect(wrapper.find('[data-testid="merge-error"]').text()).toBe('contains a link.'); + }); + + it('removes extra spaces', async () => { + createComponent({ mr: { mergeError: 'contains a lot of spaces .' } }); + + await nextTick(); + + expect(wrapper.find('[data-testid="merge-error"]').text()).toBe('contains a lot of spaces.'); }); }); diff --git a/spec/helpers/ci/pipeline_editor_helper_spec.rb b/spec/helpers/ci/pipeline_editor_helper_spec.rb index 5d3837171d0..59f24e7ceb8 100644 --- a/spec/helpers/ci/pipeline_editor_helper_spec.rb +++ b/spec/helpers/ci/pipeline_editor_helper_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe Ci::PipelineEditorHelper do + include CycleAnalyticsHelpers + let_it_be(:project) { create(:project) } describe 'can_view_pipeline_editor?' do diff --git a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb index 7173ea43450..0e7d7f1efda 100644 --- a/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb +++ b/spec/lib/gitlab/cycle_analytics/stage_summary_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe Gitlab::CycleAnalytics::StageSummary do + include CycleAnalyticsHelpers + let_it_be(:project) { create(:project, :repository) } let(:options) { { from: 1.day.ago } } diff --git a/spec/requests/projects/cycle_analytics_events_spec.rb b/spec/requests/projects/cycle_analytics_events_spec.rb index 89d46b64311..b092df4a116 100644 --- a/spec/requests/projects/cycle_analytics_events_spec.rb +++ b/spec/requests/projects/cycle_analytics_events_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'value stream analytics events' do + include CycleAnalyticsHelpers + let(:user) { create(:user) } let(:project) { create(:project, :repository, public_builds: false) } let(:issue) { create(:issue, project: project, created_at: 2.days.ago) } diff --git a/spec/services/branches/create_service_spec.rb b/spec/services/branches/create_service_spec.rb index 0d2f5838574..5904ef9b5cf 100644 --- a/spec/services/branches/create_service_spec.rb +++ b/spec/services/branches/create_service_spec.rb @@ -2,17 +2,130 @@ require 'spec_helper' -RSpec.describe Branches::CreateService do +RSpec.describe Branches::CreateService, :use_clean_rails_redis_caching do subject(:service) { described_class.new(project, user) } let_it_be(:project) { create(:project_empty_repo) } let_it_be(:user) { create(:user) } + describe '#bulk_create' do + subject { service.bulk_create(branches) } + + let_it_be(:project) { create(:project, :custom_repo, files: { 'foo/a.txt' => 'foo' }) } + + let(:branches) { { 'branch' => 'master', 'another_branch' => 'master' } } + + it 'creates two branches' do + expect(subject[:status]).to eq(:success) + expect(subject[:branches].map(&:name)).to match_array(%w[branch another_branch]) + + expect(project.repository.branch_exists?('branch')).to be_truthy + expect(project.repository.branch_exists?('another_branch')).to be_truthy + end + + context 'when branches are empty' do + let(:branches) { {} } + + it 'is successful' do + expect(subject[:status]).to eq(:success) + expect(subject[:branches]).to eq([]) + end + end + + context 'when incorrect reference is provided' do + let(:branches) { { 'new-feature' => 'unknown' } } + + before do + allow(project.repository).to receive(:add_branch).and_return(false) + end + + it 'returns an error with a reference name' do + err_msg = 'Failed to create branch \'new-feature\': invalid reference name \'unknown\'' + + expect(subject[:status]).to eq(:error) + expect(subject[:message]).to match_array([err_msg]) + end + end + + context 'when branch already exists' do + let(:branches) { { 'master' => 'master' } } + + it 'returns an error' do + expect(subject[:status]).to eq(:error) + expect(subject[:message]).to match_array(['Branch already exists']) + end + end + + context 'when an ambiguous branch name is provided' do + let(:branches) { { 'ambiguous/test' => 'master', 'ambiguous' => 'master' } } + + it 'returns an error that branch could not be created' do + err_msg = 'Failed to create branch \'ambiguous\': 13:reference is ambiguous.' + + expect(subject[:status]).to eq(:error) + expect(subject[:message]).to match_array([err_msg]) + end + end + + context 'when PreReceiveError exception' do + let(:branches) { { 'error' => 'master' } } + + it 'logs and returns an error if there is a PreReceiveError exception' do + error_message = 'pre receive error' + raw_message = "GitLab: #{error_message}" + pre_receive_error = Gitlab::Git::PreReceiveError.new(raw_message) + + allow(project.repository).to receive(:add_branch).and_raise(pre_receive_error) + + expect(Gitlab::ErrorTracking).to receive(:log_exception).with( + pre_receive_error, + pre_receive_message: raw_message, + branch_name: 'error', + ref: 'master' + ) + + expect(subject[:status]).to eq(:error) + expect(subject[:message]).to match_array([error_message]) + end + end + + context 'when multiple errors occur' do + let(:branches) { { 'master' => 'master', '' => 'master', 'failed_branch' => 'master' } } + + it 'returns all errors' do + allow(project.repository).to receive(:add_branch).with(user, 'failed_branch', 'master').and_return(false) + + expect(subject[:status]).to eq(:error) + expect(subject[:message]).to match_array( + [ + 'Branch already exists', + 'Branch name is invalid', + "Failed to create branch 'failed_branch': invalid reference name 'master'" + ] + ) + end + end + + context 'without N+1 for Redis cache' do + let(:branches) { { 'branch1' => 'master', 'branch2' => 'master', 'branch3' => 'master' } } + + it 'does not trigger Redis recreation' do + project.repository.expire_branches_cache + + control = RedisCommands::Recorder.new(pattern: ':branch_names:') { subject } + + expect(control.by_command(:sadd).count).to eq(1) + end + end + end + describe '#execute' do context 'when repository is empty' do it 'creates master branch' do - service.execute('my-feature', 'master') + result = service.execute('my-feature', 'master') + expect(result[:status]).to eq(:success) + expect(result[:branch].name).to eq('my-feature') expect(project.repository.branch_exists?('master')).to be_truthy end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 091627c8a38..7c4e2ec3ecc 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -161,7 +161,6 @@ RSpec.configure do |config| config.include LicenseHelpers config.include ActiveJob::TestHelper config.include ActiveSupport::Testing::TimeHelpers - config.include CycleAnalyticsHelpers config.include FactoryBot::Syntax::Methods config.include FixtureHelpers config.include NonExistingRecordsHelpers diff --git a/spec/support/helpers/cycle_analytics_helpers.rb b/spec/support/helpers/cycle_analytics_helpers.rb index 044ec56b1cc..05e9a099a2b 100644 --- a/spec/support/helpers/cycle_analytics_helpers.rb +++ b/spec/support/helpers/cycle_analytics_helpers.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true module CycleAnalyticsHelpers - include GitHelpers - def toggle_value_stream_dropdown page.find('[data-testid="dropdown-value-streams"]').click end @@ -129,10 +127,6 @@ module CycleAnalyticsHelpers repository = project.repository oldrev = repository.commit(branch_name)&.sha || Gitlab::Git::BLANK_SHA - if Timecop.frozen? - mock_gitaly_multi_action_dates(repository, commit_time) - end - commit_shas = Array.new(count) do |index| commit_sha = repository.create_file(user, generate(:branch), "content", message: message, branch_name: branch_name) repository.commit(commit_sha) @@ -241,23 +235,4 @@ module CycleAnalyticsHelpers pipeline: dummy_pipeline(project), protected: false) end - - def mock_gitaly_multi_action_dates(repository, commit_time) - allow(repository.raw).to receive(:multi_action).and_wrap_original do |m, user, kargs| - new_date = commit_time || Time.now - branch_update = m.call(user, **kargs) - - if branch_update.newrev - commit = rugged_repo(repository).rev_parse(branch_update.newrev) - - branch_update.newrev = commit.amend( - update_ref: "#{Gitlab::Git::BRANCH_REF_PREFIX}#{kargs[:branch_name]}", - author: commit.author.merge(time: new_date), - committer: commit.committer.merge(time: new_date) - ) - end - - branch_update - end - end end diff --git a/spec/support/shared_contexts/fixtures/analytics_shared_context.rb b/spec/support/shared_contexts/fixtures/analytics_shared_context.rb index 13d3697a378..8e09cccee3e 100644 --- a/spec/support/shared_contexts/fixtures/analytics_shared_context.rb +++ b/spec/support/shared_contexts/fixtures/analytics_shared_context.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true RSpec.shared_context 'Analytics fixtures shared context' do + include CycleAnalyticsHelpers include JavaScriptFixturesHelpers let_it_be(:group) { create(:group) } |