summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/stylesheets/pages/labels.scss6
-rw-r--r--app/controllers/registrations_controller.rb2
-rw-r--r--app/models/ci/build.rb12
-rw-r--r--app/models/concerns/avatarable.rb2
-rw-r--r--app/models/merge_request.rb6
-rw-r--r--app/serializers/merge_request_widget_entity.rb16
-rw-r--r--app/workers/group_export_worker.rb2
-rw-r--r--app/workers/group_import_worker.rb2
-rw-r--r--app/workers/project_export_worker.rb2
-rw-r--r--app/workers/repository_import_worker.rb2
-rw-r--r--changelogs/unreleased/254823-automatically-expand-file-on-merge-request-with-changes-to-single-.yml5
-rw-r--r--changelogs/unreleased/267498-failed-test-qa-specs-features-browser_ui-1_manage-login-register_s.yml5
-rw-r--r--changelogs/unreleased/cngo-fix-scoped-label-markdown-padding.yml5
-rw-r--r--changelogs/unreleased/eb-limit-test-cases-parsed.yml5
-rw-r--r--changelogs/unreleased/mk-add-missing-avatar-size.yml5
-rw-r--r--config/feature_flags/development/merge_base_pipelines.yml7
-rw-r--r--doc/.vale/gitlab/Substitutions.yml1
-rw-r--r--doc/administration/geo/replication/datatypes.md56
-rw-r--r--doc/api/graphql/reference/gitlab_schema.graphql3
-rw-r--r--doc/api/graphql/reference/gitlab_schema.json2
-rw-r--r--doc/ci/variables/README.md29
-rw-r--r--doc/development/internal_api.md2
-rw-r--r--doc/user/gitlab_com/index.md1
-rw-r--r--doc/user/project/pages/custom_domains_ssl_tls_certification/index.md10
-rw-r--r--doc/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md1
-rw-r--r--doc/user/project/pages/getting_started_part_one.md9
-rw-r--r--doc/user/project/pages/introduction.md5
-rw-r--r--doc/user/project/pages/lets_encrypt_for_gitlab_pages.md5
-rw-r--r--doc/user/project/pages/pages_access_control.md6
-rw-r--r--doc/user/project/pages/redirects.md12
-rw-r--r--lib/gitlab/ci/parsers/test/junit.rb19
-rw-r--r--lib/gitlab/diff/highlight_cache.rb4
-rw-r--r--lib/gitlab/git/diff_collection.rb14
-rw-r--r--lib/gitlab/gitaly_client/diff_stitcher.rb10
-rw-r--r--locale/gitlab.pot5
-rw-r--r--spec/controllers/registrations_controller_spec.rb12
-rw-r--r--spec/lib/gitlab/ci/parsers/test/junit_spec.rb58
-rw-r--r--spec/lib/gitlab/git/diff_collection_spec.rb29
-rw-r--r--spec/models/merge_request_spec.rb19
-rw-r--r--spec/requests/api/users_spec.rb44
-rw-r--r--spec/serializers/merge_request_widget_entity_spec.rb38
-rw-r--r--spec/workers/group_export_worker_spec.rb10
-rw-r--r--spec/workers/group_import_worker_spec.rb10
-rw-r--r--spec/workers/project_export_worker_spec.rb4
44 files changed, 370 insertions, 132 deletions
diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss
index 1064baa9e6d..31606cb3ba5 100644
--- a/app/assets/stylesheets/pages/labels.scss
+++ b/app/assets/stylesheets/pages/labels.scss
@@ -343,3 +343,9 @@
box-shadow: 0 0 0 1px inset;
}
}
+
+/* Fix scoped label padding in cases where old markdown uses the old label structure */
+.gl-label-text + .gl-label-text {
+ @include gl-pl-2;
+ @include gl-pr-3;
+}
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 4da6e8ea1ae..b3dc0e986f4 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -58,6 +58,8 @@ class RegistrationsController < Devise::RegistrationsController
end
def update_registration
+ return redirect_to new_user_registration_path unless current_user
+
user_params = params.require(:user).permit(:role, :setup_for_company)
result = ::Users::SignupService.new(current_user, user_params).execute
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 42f326d40dc..9ff70ece947 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -898,7 +898,11 @@ module Ci
def collect_test_reports!(test_reports)
test_reports.get_suite(group_name).tap do |test_suite|
each_report(Ci::JobArtifact::TEST_REPORT_FILE_TYPES) do |file_type, blob|
- Gitlab::Ci::Parsers.fabricate!(file_type).parse!(blob, test_suite, job: self)
+ Gitlab::Ci::Parsers.fabricate!(file_type).parse!(
+ blob,
+ test_suite,
+ job: self
+ )
end
end
end
@@ -964,6 +968,12 @@ module Ci
status_commit_hooks.push(block)
end
+ def max_test_cases_per_report
+ # NOTE: This is temporary and will be replaced later by a value
+ # that would come from an actual application limit.
+ ::Gitlab.com? ? 500_000 : 0
+ end
+
protected
def run_status_commit_hooks!
diff --git a/app/models/concerns/avatarable.rb b/app/models/concerns/avatarable.rb
index 92926620f8c..d342b526677 100644
--- a/app/models/concerns/avatarable.rb
+++ b/app/models/concerns/avatarable.rb
@@ -3,7 +3,7 @@
module Avatarable
extend ActiveSupport::Concern
- USER_AVATAR_SIZES = [16, 20, 23, 24, 26, 32, 36, 38, 40, 48, 60, 64, 96, 120, 160].freeze
+ USER_AVATAR_SIZES = [16, 20, 23, 24, 26, 32, 36, 38, 40, 48, 60, 64, 90, 96, 120, 160].freeze
PROJECT_AVATAR_SIZES = [15, 40, 48, 64, 88].freeze
GROUP_AVATAR_SIZES = [15, 37, 38, 39, 40, 64, 96].freeze
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 22c6777fca3..ed53676ea97 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -1599,6 +1599,12 @@ class MergeRequest < ApplicationRecord
.find_by(sha: diff_base_sha, ref: target_branch)
end
+ def merge_base_pipeline
+ @merge_base_pipeline ||= project.ci_pipelines
+ .order(id: :desc)
+ .find_by(sha: actual_head_pipeline.target_sha, ref: target_branch)
+ end
+
def discussions_rendered_on_frontend?
true
end
diff --git a/app/serializers/merge_request_widget_entity.rb b/app/serializers/merge_request_widget_entity.rb
index 7cd25c55b42..4567a188bd8 100644
--- a/app/serializers/merge_request_widget_entity.rb
+++ b/app/serializers/merge_request_widget_entity.rb
@@ -120,7 +120,11 @@ class MergeRequestWidgetEntity < Grape::Entity
end
expose :base_path do |merge_request|
- base_pipeline_downloadable_path_for_report_type(:codequality)
+ if use_merge_base_with_merged_results?
+ merge_base_pipeline_downloadable_path_for_report_type(:codequality)
+ else
+ base_pipeline_downloadable_path_for_report_type(:codequality)
+ end
end
end
@@ -156,6 +160,16 @@ class MergeRequestWidgetEntity < Grape::Entity
object.base_pipeline&.present(current_user: current_user)
&.downloadable_path_for_report_type(file_type)
end
+
+ def use_merge_base_with_merged_results?
+ Feature.enabled?(:merge_base_pipelines, object.target_project) &&
+ object.actual_head_pipeline&.merge_request_event_type == :merged_result
+ end
+
+ def merge_base_pipeline_downloadable_path_for_report_type(file_type)
+ object.merge_base_pipeline&.present(current_user: current_user)
+ &.downloadable_path_for_report_type(file_type)
+ end
end
MergeRequestWidgetEntity.prepend_if_ee('EE::MergeRequestWidgetEntity')
diff --git a/app/workers/group_export_worker.rb b/app/workers/group_export_worker.rb
index e22b691d35e..a212147d8fd 100644
--- a/app/workers/group_export_worker.rb
+++ b/app/workers/group_export_worker.rb
@@ -6,7 +6,7 @@ class GroupExportWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :importers
loggable_arguments 2
- sidekiq_options retry: false
+ sidekiq_options retry: false, dead: false
def perform(current_user_id, group_id, params = {})
current_user = User.find(current_user_id)
diff --git a/app/workers/group_import_worker.rb b/app/workers/group_import_worker.rb
index 494d9a3e46f..b8b596f459b 100644
--- a/app/workers/group_import_worker.rb
+++ b/app/workers/group_import_worker.rb
@@ -3,7 +3,7 @@
class GroupImportWorker # rubocop:disable Scalability/IdempotentWorker
include ApplicationWorker
- sidekiq_options retry: false
+ sidekiq_options retry: false, dead: false
feature_category :importers
def perform(user_id, group_id)
diff --git a/app/workers/project_export_worker.rb b/app/workers/project_export_worker.rb
index 6c8640138a1..1c4aa3f7e49 100644
--- a/app/workers/project_export_worker.rb
+++ b/app/workers/project_export_worker.rb
@@ -8,7 +8,7 @@ class ProjectExportWorker # rubocop:disable Scalability/IdempotentWorker
worker_resource_boundary :memory
urgency :throttled
loggable_arguments 2, 3
- sidekiq_options retry: false
+ sidekiq_options retry: false, dead: false
sidekiq_options status_expiration: StuckExportJobsWorker::EXPORT_JOBS_EXPIRATION
def perform(current_user_id, project_id, after_export_strategy = {}, params = {})
diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb
index 85f1a1fa767..51fe60e25fc 100644
--- a/app/workers/repository_import_worker.rb
+++ b/app/workers/repository_import_worker.rb
@@ -8,7 +8,7 @@ class RepositoryImportWorker # rubocop:disable Scalability/IdempotentWorker
feature_category :importers
worker_has_external_dependencies!
# Do not retry on Import/Export until https://gitlab.com/gitlab-org/gitlab/-/issues/16812 is solved.
- sidekiq_options retry: false
+ sidekiq_options retry: false, dead: false
sidekiq_options status_expiration: Gitlab::Import::StuckImportJob::IMPORT_JOBS_EXPIRATION
# technical debt: https://gitlab.com/gitlab-org/gitlab/issues/33991
diff --git a/changelogs/unreleased/254823-automatically-expand-file-on-merge-request-with-changes-to-single-.yml b/changelogs/unreleased/254823-automatically-expand-file-on-merge-request-with-changes-to-single-.yml
new file mode 100644
index 00000000000..42a1d7c6847
--- /dev/null
+++ b/changelogs/unreleased/254823-automatically-expand-file-on-merge-request-with-changes-to-single-.yml
@@ -0,0 +1,5 @@
+---
+title: Automatically expand diffs for merge requests with changes to a single file
+merge_request: 44629
+author:
+type: changed
diff --git a/changelogs/unreleased/267498-failed-test-qa-specs-features-browser_ui-1_manage-login-register_s.yml b/changelogs/unreleased/267498-failed-test-qa-specs-features-browser_ui-1_manage-login-register_s.yml
new file mode 100644
index 00000000000..bcdf1cae2af
--- /dev/null
+++ b/changelogs/unreleased/267498-failed-test-qa-specs-features-browser_ui-1_manage-login-register_s.yml
@@ -0,0 +1,5 @@
+---
+title: Redirect when no user is signed in when updating registration
+merge_request: 45276
+author:
+type: fixed
diff --git a/changelogs/unreleased/cngo-fix-scoped-label-markdown-padding.yml b/changelogs/unreleased/cngo-fix-scoped-label-markdown-padding.yml
new file mode 100644
index 00000000000..0aa6a468e3f
--- /dev/null
+++ b/changelogs/unreleased/cngo-fix-scoped-label-markdown-padding.yml
@@ -0,0 +1,5 @@
+---
+title: Fix scoped label markdown padding
+merge_request: 45153
+author:
+type: fixed
diff --git a/changelogs/unreleased/eb-limit-test-cases-parsed.yml b/changelogs/unreleased/eb-limit-test-cases-parsed.yml
new file mode 100644
index 00000000000..59a9e611d4b
--- /dev/null
+++ b/changelogs/unreleased/eb-limit-test-cases-parsed.yml
@@ -0,0 +1,5 @@
+---
+title: Add limit to number of test cases parsed by JUnit parser
+merge_request: 44615
+author:
+type: changed
diff --git a/changelogs/unreleased/mk-add-missing-avatar-size.yml b/changelogs/unreleased/mk-add-missing-avatar-size.yml
new file mode 100644
index 00000000000..8b587ee0004
--- /dev/null
+++ b/changelogs/unreleased/mk-add-missing-avatar-size.yml
@@ -0,0 +1,5 @@
+---
+title: Add missing 90x avatar size for image scaling
+merge_request: 45025
+author:
+type: fixed
diff --git a/config/feature_flags/development/merge_base_pipelines.yml b/config/feature_flags/development/merge_base_pipelines.yml
new file mode 100644
index 00000000000..4f57ca556f1
--- /dev/null
+++ b/config/feature_flags/development/merge_base_pipelines.yml
@@ -0,0 +1,7 @@
+---
+name: merge_base_pipelines
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44648
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/263724
+type: development
+group: group::testing
+default_enabled: false
diff --git a/doc/.vale/gitlab/Substitutions.yml b/doc/.vale/gitlab/Substitutions.yml
index 77536ea0b33..704c64f1fbd 100644
--- a/doc/.vale/gitlab/Substitutions.yml
+++ b/doc/.vale/gitlab/Substitutions.yml
@@ -13,6 +13,7 @@ ignorecase: true
swap:
frontmatter: front matter
GitLabber: GitLab team member
+ GitLab-shell: GitLab Shell
gitlab omnibus: Omnibus GitLab
param: parameter
params: parameters
diff --git a/doc/administration/geo/replication/datatypes.md b/doc/administration/geo/replication/datatypes.md
index 95d004203f8..d1fa2d503be 100644
--- a/doc/administration/geo/replication/datatypes.md
+++ b/doc/administration/geo/replication/datatypes.md
@@ -23,32 +23,34 @@ We currently distinguish between three different data types:
See the list below of each feature or component we replicate, its corresponding data type, replication, and
verification methods:
-| Type | Feature / component | Replication method | Verification method |
-|:---------|:----------------------------------------------|:--------------------------------------|:-----------------------|
-| Database | Application data in PostgreSQL | Native | Native |
-| Database | Redis | _N/A_ (*1*) | _N/A_ |
-| Database | Elasticsearch | Native | Native |
-| Database | Personal snippets | PostgreSQL Replication | PostgreSQL Replication |
-| Database | Project snippets | PostgreSQL Replication | PostgreSQL Replication |
-| Database | SSH public keys | PostgreSQL Replication | PostgreSQL Replication |
-| Git | Project repository | Geo with Gitaly | Gitaly Checksum |
-| Git | Project wiki repository | Geo with Gitaly | Gitaly Checksum |
-| Git | Project designs repository | Geo with Gitaly | Gitaly Checksum |
-| Git | Object pools for forked project deduplication | Geo with Gitaly | _Not implemented_ |
-| Blobs | User uploads _(filesystem)_ | Geo with API | _Not implemented_ |
-| Blobs | User uploads _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
-| Blobs | LFS objects _(filesystem)_ | Geo with API | _Not implemented_ |
-| Blobs | LFS objects _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
-| Blobs | CI job artifacts _(filesystem)_ | Geo with API | _Not implemented_ |
-| Blobs | CI job artifacts _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
-| Blobs | Archived CI build traces _(filesystem)_ | Geo with API | _Not implemented_ |
-| Blobs | Archived CI build traces _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
-| Blobs | Container registry _(filesystem)_ | Geo with API/Docker API | _Not implemented_ |
-| Blobs | Container registry _(object storage)_ | Geo with API/Managed/Docker API (*2*) | _Not implemented_ |
-| Blobs | Package registry _(filesystem)_ | Geo with API | _Not implemented_ |
-| Blobs | Package registry _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
-| Blobs | Versioned Terraform State _(filesystem)_ | Geo with API | _Not implemented_ |
-| Blobs | Versioned Terraform State _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
+| Type | Feature / component | Replication method | Verification method |
+|:---------|:------------------------------------------------|:--------------------------------------|:-----------------------|
+| Database | Application data in PostgreSQL | Native | Native |
+| Database | Redis | _N/A_ (*1*) | _N/A_ |
+| Database | Elasticsearch | Native | Native |
+| Database | Personal snippets | PostgreSQL Replication | PostgreSQL Replication |
+| Database | Project snippets | PostgreSQL Replication | PostgreSQL Replication |
+| Database | SSH public keys | PostgreSQL Replication | PostgreSQL Replication |
+| Git | Project repository | Geo with Gitaly | Gitaly Checksum |
+| Git | Project wiki repository | Geo with Gitaly | Gitaly Checksum |
+| Git | Project designs repository | Geo with Gitaly | Gitaly Checksum |
+| Git | Object pools for forked project deduplication | Geo with Gitaly | _Not implemented_ |
+| Blobs | User uploads _(filesystem)_ | Geo with API | _Not implemented_ |
+| Blobs | User uploads _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
+| Blobs | LFS objects _(filesystem)_ | Geo with API | _Not implemented_ |
+| Blobs | LFS objects _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
+| Blobs | CI job artifacts _(filesystem)_ | Geo with API | _Not implemented_ |
+| Blobs | CI job artifacts _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
+| Blobs | Archived CI build traces _(filesystem)_ | Geo with API | _Not implemented_ |
+| Blobs | Archived CI build traces _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
+| Blobs | Container registry _(filesystem)_ | Geo with API/Docker API | _Not implemented_ |
+| Blobs | Container registry _(object storage)_ | Geo with API/Managed/Docker API (*2*) | _Not implemented_ |
+| Blobs | Package registry _(filesystem)_ | Geo with API | _Not implemented_ |
+| Blobs | Package registry _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
+| Blobs | Versioned Terraform State _(filesystem)_ | Geo with API | _Not implemented_ |
+| Blobs | Versioned Terraform State _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
+| Blobs | External Merge Request Diffs _(filesystem)_ | Geo with API | _Not implemented_ |
+| Blobs | External Merge Request Diffs _(object storage)_ | Geo with API/Managed (*2*) | _Not implemented_ |
- (*1*): Redis replication can be used as part of HA with Redis sentinel. It's not used between Geo nodes.
- (*2*): Object storage replication can be performed by Geo or by your object storage provider/appliance
@@ -185,7 +187,7 @@ successfully, you must replicate their data using some other means.
| [Composer Repository](../../../user/packages/composer_repository/index.md) | **Yes** (13.2) | [No](https://gitlab.com/groups/gitlab-org/-/epics/1817) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default |
| [Generic packages](../../../user/packages/generic_packages/index.md) | **Yes** (13.5) | [No](https://gitlab.com/groups/gitlab-org/-/epics/1817) | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_package_file_replication`, enabled by default |
| [Versioned Terraform State](../../terraform_state.md) | **Yes** (13.5) | No | Via Object Storage provider if supported. Native Geo support (Beta). | Behind feature flag `geo_terraform_state_version_replication`, enabled by default |
-| [External merge request diffs](../../merge_request_diffs.md) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/33817) | No | Via Object Storage provider if supported. Native Geo support (Beta). | |
+| [External merge request diffs](../../merge_request_diffs.md) | **Yes** (13.5) | No | Behind feature flag `geo_merge_request_diff_replication`, enabled by default | |
| [Versioned snippets](../../../user/snippets.md#versioned-snippets) | [No](https://gitlab.com/groups/gitlab-org/-/epics/2809) | [No](https://gitlab.com/groups/gitlab-org/-/epics/2810) | No | |
| [Server-side Git hooks](../../server_hooks.md) | [No](https://gitlab.com/groups/gitlab-org/-/epics/1867) | No | No | |
| [Elasticsearch integration](../../../integration/elasticsearch.md) | [No](https://gitlab.com/gitlab-org/gitlab/-/issues/1186) | No | No | |
diff --git a/doc/api/graphql/reference/gitlab_schema.graphql b/doc/api/graphql/reference/gitlab_schema.graphql
index 981cd8cda15..939dcf43c63 100644
--- a/doc/api/graphql/reference/gitlab_schema.graphql
+++ b/doc/api/graphql/reference/gitlab_schema.graphql
@@ -7284,8 +7284,7 @@ type GeoNode {
internalUrl: String
"""
- Find merge request diff registries on this Geo node. Available only when
- feature flag `geo_merge_request_diff_replication` is enabled
+ Find merge request diff registries on this Geo node
"""
mergeRequestDiffRegistries(
"""
diff --git a/doc/api/graphql/reference/gitlab_schema.json b/doc/api/graphql/reference/gitlab_schema.json
index 21ac1006be6..ff2d58a0483 100644
--- a/doc/api/graphql/reference/gitlab_schema.json
+++ b/doc/api/graphql/reference/gitlab_schema.json
@@ -20066,7 +20066,7 @@
},
{
"name": "mergeRequestDiffRegistries",
- "description": "Find merge request diff registries on this Geo node. Available only when feature flag `geo_merge_request_diff_replication` is enabled",
+ "description": "Find merge request diff registries on this Geo node",
"args": [
{
"name": "ids",
diff --git a/doc/ci/variables/README.md b/doc/ci/variables/README.md
index 28502967c31..9c8fb994bf7 100644
--- a/doc/ci/variables/README.md
+++ b/doc/ci/variables/README.md
@@ -410,10 +410,12 @@ script:
> Introduced in GitLab 9.4.
-You can define per-project or per-group variables
-that are set in the pipeline environment. Group-level variables are stored out of
-the repository (not in `.gitlab-ci.yml`) and are securely passed to GitLab Runner,
-which makes them available during a pipeline run. For Premium users who do **not** use an external key store or who use GitLab's [integration with HashiCorp Vault](../secrets/index.md), we recommend using group environment variables to store secrets like passwords, SSH keys, and credentials.
+You can define per-project or per-group variables that are set in the pipeline environment. Group-level variables are stored out of the repository (not in `.gitlab-ci.yml`). They are securely passed to GitLab Runner, which makes them available during a pipeline run.
+
+We recommend using group environment variables to store secrets (like passwords, SSH keys, and credentials) for Premium users who:
+
+- Do **not** use an external key store.
+- Use GitLab's [integration with HashiCorp Vault](../secrets/index.md).
Group-level variables can be added by:
@@ -547,8 +549,7 @@ variables take precedence over those defined in `.gitlab-ci.yml`.
Variable names are limited by the underlying shell used to execute scripts (see [available shells](https://docs.gitlab.com/runner/shells/index.html).
Each shell has its own unique set of reserved variable names.
-You also want to keep in mind the [scope of environment variables](where_variables_can_be_used.md) to ensure a variable is defined in the scope
-in which you wish to use it.
+Keep in mind the [scope of environment variables](where_variables_can_be_used.md) to ensure a variable is defined in the scope in which you wish to use it.
## Where variables can be used
@@ -682,9 +683,10 @@ Examples:
- `$VARIABLE == ""`
- `$VARIABLE != ""` (introduced in GitLab 11.11)
-If you want to check whether a variable is defined, but is empty, you can
-simply compare it against an empty string, like `$VAR == ''` or non-empty
-string `$VARIABLE != ""`.
+To check if a variable is defined but empty, compare it to:
+
+- An empty string: `$VARIABLE == ''`
+- A non-empty string: `$VARIABLE != ""`
#### Comparing two variables
@@ -700,9 +702,8 @@ of these variables.
Example: `$STAGING`
-If you only want to create a job when there is some variable present,
-which means that it is defined and non-empty, you can simply use
-variable name as an expression, like `$STAGING`. If `$STAGING` variable
+To create a job when there is some variable present, meaning it is defined and non-empty,
+use the variable name as an expression, like `$STAGING`. If the `$STAGING` variable
is defined, and is non empty, expression evaluates to `true`.
`$STAGING` value needs to be a string, with length higher than zero.
Variable that contains only whitespace characters is not an empty variable.
@@ -836,9 +837,7 @@ from being leaked into the log unless your script writes them to the screen.
If a job isn't working as expected, this can make the problem difficult to
investigate; in these cases, you can enable debug tracing in `.gitlab-ci.yml`.
-Available on GitLab Runner v1.7+, this feature enables the shell's execution
-log, resulting in a verbose job log listing all commands that were run,
-variables that were set, and so on.
+Available on GitLab Runner v1.7+, this feature enables the shell's execution log. This results in a verbose job log listing all commands that were run, variables that were set, and so on.
Before enabling this, you should ensure jobs are visible to
[team members only](../../user/permissions.md#project-features). You should
diff --git a/doc/development/internal_api.md b/doc/development/internal_api.md
index 5e74be9e439..e25feda356d 100644
--- a/doc/development/internal_api.md
+++ b/doc/development/internal_api.md
@@ -52,7 +52,7 @@ POST /internal/allowed
| `username` | string | no | Username from the certificate used to connect to GitLab Shell |
| `project` | string | no (if `gl_repository` is passed) | Path to the project |
| `gl_repository` | string | no (if `project` is passed) | Repository identifier (e.g. `project-7`) |
-| `protocol` | string | yes | SSH when called from GitLab-shell, HTTP or SSH when called from Gitaly |
+| `protocol` | string | yes | SSH when called from GitLab Shell, HTTP or SSH when called from Gitaly |
| `action` | string | yes | Git command being run (`git-upload-pack`, `git-receive-pack`, `git-upload-archive`) |
| `changes` | string | yes | `<oldrev> <newrev> <refname>` when called from Gitaly, the magic string `_any` when called from GitLab Shell |
| `check_ip` | string | no | IP address from which call to GitLab Shell was made |
diff --git a/doc/user/gitlab_com/index.md b/doc/user/gitlab_com/index.md
index e2b5dfe25d7..43cfdc78f5b 100644
--- a/doc/user/gitlab_com/index.md
+++ b/doc/user/gitlab_com/index.md
@@ -96,6 +96,7 @@ Below are the current settings regarding [GitLab CI/CD](../../ci/README.md).
| [Max pipeline schedules in projects](../../administration/instance_limits.md#number-of-pipeline-schedules) | `10` for Free tier, `50` for all paid tiers | Unlimited |
| [Max number of instance level variables](../../administration/instance_limits.md#number-of-instance-level-variables) | `25` | `25` |
| [Scheduled Job Archival](../../user/admin_area/settings/continuous_integration.md#archive-jobs) | 3 months | Never |
+| Max test cases per [unit test report](../../ci/unit_test_reports.md) | `500_000` | Unlimited |
## Account and limit settings
diff --git a/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md b/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
index badafa478ef..9b43dd58afe 100644
--- a/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
+++ b/doc/user/project/pages/custom_domains_ssl_tls_certification/index.md
@@ -61,7 +61,6 @@ according to the type of domain you want to use with your Pages site:
- [For subdomains](#for-subdomains), `subdomain.example.com`.
- [For both](#for-both-root-and-subdomains).
-NOTE: **Note:**
You can [configure IPv6 on self-managed instances](../../../../administration/pages/index.md#advanced-configuration),
but IPv6 is not currently configured for Pages on GitLab.com.
Follow [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/214718) for details.
@@ -250,8 +249,8 @@ You can use any certificate satisfying the following requirements:
- **A private key**, it's an encrypted key which validates
your PEM against your domain.
-NOTE: **Note:**
-[Cloudflare certificates](https://about.gitlab.com/blog/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/), for example, meet these requirements.
+For example, [Cloudflare certificates](https://about.gitlab.com/blog/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/)
+meet these requirements.
#### Steps
@@ -269,7 +268,6 @@ NOTE: **Note:**
just jumping a line between them.
1. Copy your private key and paste it in the last field.
-NOTE: **Note:**
**Do not** open certificates or encryption keys in
regular text editors. Always use code editors (such as
Sublime Text, Atom, Dreamweaver, Brackets, etc).
@@ -290,8 +288,8 @@ To enable this setting:
1. Navigate to your project's **Settings > Pages**.
1. Tick the checkbox **Force HTTPS (requires valid certificates)**.
-NOTE: **Note:**
-If you use Cloudflare CDN in front of GitLab Pages, make sure to set the SSL connection setting to `full` instead of `flexible`. For more details, see the [Cloudflare CDN directions](https://support.cloudflare.com/hc/en-us/articles/200170416-End-to-end-HTTPS-with-Cloudflare-Part-3-SSL-options#h_4e0d1a7c-eb71-4204-9e22-9d3ef9ef7fef).
+If you use Cloudflare CDN in front of GitLab Pages, make sure to set the SSL connection setting to
+`full` instead of `flexible`. For more details, see the [Cloudflare CDN directions](https://support.cloudflare.com/hc/en-us/articles/200170416-End-to-end-HTTPS-with-Cloudflare-Part-3-SSL-options#h_4e0d1a7c-eb71-4204-9e22-9d3ef9ef7fef).
<!-- ## Troubleshooting
diff --git a/doc/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md b/doc/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md
index 597d6737a8f..24b202dfdbd 100644
--- a/doc/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md
+++ b/doc/user/project/pages/custom_domains_ssl_tls_certification/lets_encrypt_integration.md
@@ -33,7 +33,6 @@ Before you can enable automatic provisioning of an SSL certificate for your doma
and verified your ownership.
- Verified your website is up and running, accessible through your custom domain.
-NOTE: **Note:**
GitLab's Let's Encrypt integration is enabled and available on GitLab.com.
For **self-managed** GitLab instances, make sure your administrator has
[enabled it](../../../../administration/pages/index.md#lets-encrypt-integration).
diff --git a/doc/user/project/pages/getting_started_part_one.md b/doc/user/project/pages/getting_started_part_one.md
index 9272b1f9093..5ef0c4cc7b9 100644
--- a/doc/user/project/pages/getting_started_part_one.md
+++ b/doc/user/project/pages/getting_started_part_one.md
@@ -11,12 +11,9 @@ according to your intended website's URL.
## GitLab Pages default domain names
-NOTE: **Note:**
-If you use your own GitLab instance to deploy your
-site with GitLab Pages, check with your sysadmin what's your
-Pages wildcard domain. This guide is valid for any GitLab instance,
-you just need to replace Pages wildcard domain on GitLab.com
-(`*.gitlab.io`) with your own.
+If you use your own GitLab instance to deploy your site with GitLab Pages, verify your Pages
+wildcard domain with your sysadmin. This guide is valid for any GitLab instance, provided that you
+replace the Pages wildcard domain on GitLab.com (`*.gitlab.io`) with your own.
If you set up a GitLab Pages project on GitLab,
it will automatically be accessible under a
diff --git a/doc/user/project/pages/introduction.md b/doc/user/project/pages/introduction.md
index 9806f5c8ea1..b97d5328c07 100644
--- a/doc/user/project/pages/introduction.md
+++ b/doc/user/project/pages/introduction.md
@@ -259,9 +259,8 @@ instead. Here are some examples of what will happen given the above Pages site:
| `/other/index` | `200 OK` | `public/other/index.html` |
| `/other/index.html` | `200 OK` | `public/other/index.html` |
-NOTE: **Note:**
-When `public/data/index.html` exists, it takes priority over the `public/data.html`
-file for both the `/data` and `/data/` URL paths.
+Note that when `public/data/index.html` exists, it takes priority over the `public/data.html` file
+for both the `/data` and `/data/` URL paths.
## Frequently Asked Questions
diff --git a/doc/user/project/pages/lets_encrypt_for_gitlab_pages.md b/doc/user/project/pages/lets_encrypt_for_gitlab_pages.md
index 708d886b352..02d1dd7898a 100644
--- a/doc/user/project/pages/lets_encrypt_for_gitlab_pages.md
+++ b/doc/user/project/pages/lets_encrypt_for_gitlab_pages.md
@@ -33,9 +33,8 @@ To follow along with this tutorial, we assume you already have:
Once you have the requirements addressed, follow the instructions
below to learn how to obtain the certificate.
-NOTE: **Note:**
-The instructions below were tested on macOS Mojave. For other
-operating systems the steps might be slightly different. Follow the
+Note that these instructions were tested on macOS Mojave. For other operating systems the steps
+might be slightly different. Follow the
[CertBot instructions](https://certbot.eff.org/) according to your OS.
1. On your computer, open a terminal and navigate to your repository's
diff --git a/doc/user/project/pages/pages_access_control.md b/doc/user/project/pages/pages_access_control.md
index 7ecaf684138..b3705a5835a 100644
--- a/doc/user/project/pages/pages_access_control.md
+++ b/doc/user/project/pages/pages_access_control.md
@@ -20,11 +20,9 @@ on your GitLab instance. When enabled, only
For a demonstration, see [Pages access controls](https://www.youtube.com/watch?v=tSPAr5mQYc8).
1. Navigate to your project's **Settings > General** and expand **Visibility, project features, permissions**.
-1. Toggle the **Pages** button to enable the access control.
- NOTE: **Note:**
- If you don't see the toggle button, that means that it's not enabled.
- Ask your administrator to [enable it](../../../administration/pages/index.md#access-control).
+1. Toggle the **Pages** button to enable the access control. If you don't see the toggle button,
+ that means it isn't enabled. Ask your administrator to [enable it](../../../administration/pages/index.md#access-control).
1. The Pages access control dropdown allows you to set who can view pages hosted
with GitLab Pages, depending on your project's visibility:
diff --git a/doc/user/project/pages/redirects.md b/doc/user/project/pages/redirects.md
index 0624145cca3..60fbf368061 100644
--- a/doc/user/project/pages/redirects.md
+++ b/doc/user/project/pages/redirects.md
@@ -22,8 +22,10 @@ GitLab Pages only supports the
[`_redirects` plain text file syntax](https://docs.netlify.com/routing/redirects/#syntax-for-the-redirects-file),
and `.toml` files are not supported.
-Redirects are only supported at a basic level, and GitLab Pages doesn't support all
-[special options offered by Netlify](https://docs.netlify.com/routing/redirects/redirect-options/):
+Redirects are only supported at a basic level. GitLab Pages doesn't support all
+[special options offered by Netlify](https://docs.netlify.com/routing/redirects/redirect-options/).
+
+Note that supported paths must start with a forward slash `/`.
| Feature | Supported | Example |
| ------- | --------- | ------- |
@@ -37,9 +39,6 @@ Redirects are only supported at a basic level, and GitLab Pages doesn't support
| Redirect by country or language | **{dotted-circle}** No | `/ /anz 302 Country=au,nz` |
| Redirect by role | **{dotted-circle}** No | `/admin/* 200! Role=admin` |
-NOTE: **Note:**
-Supported paths must start with a forward slash `/`.
-
## Create redirects
To create redirects,
@@ -78,8 +77,7 @@ is ignored because `hello.html` exists:
/projectname/hello.html /projectname/world.html 302
```
-NOTE: **Note:**
-GitLab does not support Netlify's
+GitLab doesn't support Netlify's
[force option](https://docs.netlify.com/routing/redirects/rewrites-proxies/#shadowing)
to change this behavior.
diff --git a/lib/gitlab/ci/parsers/test/junit.rb b/lib/gitlab/ci/parsers/test/junit.rb
index 324087dd8ed..50cd703da4a 100644
--- a/lib/gitlab/ci/parsers/test/junit.rb
+++ b/lib/gitlab/ci/parsers/test/junit.rb
@@ -8,12 +8,17 @@ module Gitlab
JunitParserError = Class.new(Gitlab::Ci::Parsers::ParserError)
ATTACHMENT_TAG_REGEX = /\[\[ATTACHMENT\|(?<path>.+?)\]\]/.freeze
- def parse!(xml_data, test_suite, **args)
+ def parse!(xml_data, test_suite, job:)
root = Hash.from_xml(xml_data)
+ total_parsed = 0
+ max_test_cases = job.max_test_cases_per_report
all_cases(root) do |test_case|
- test_case = create_test_case(test_case, test_suite, args)
+ test_case = create_test_case(test_case, test_suite, job)
test_suite.add_test_case(test_case)
+ total_parsed += 1
+
+ ensure_test_cases_limited!(total_parsed, max_test_cases)
end
rescue Nokogiri::XML::SyntaxError => e
test_suite.set_suite_error("JUnit XML parsing failed: #{e}")
@@ -23,6 +28,12 @@ module Gitlab
private
+ def ensure_test_cases_limited!(total_parsed, limit)
+ return unless limit > 0 && total_parsed > limit
+
+ raise JunitParserError.new("number of test cases exceeded the limit of #{limit}")
+ end
+
def all_cases(root, parent = nil, &blk)
return unless root.present?
@@ -50,7 +61,7 @@ module Gitlab
end
end
- def create_test_case(data, test_suite, args)
+ def create_test_case(data, test_suite, job)
if data.key?('failure')
status = ::Gitlab::Ci::Reports::TestCase::STATUS_FAILED
system_output = data['failure']
@@ -75,7 +86,7 @@ module Gitlab
status: status,
system_output: system_output,
attachment: attachment,
- job: args.fetch(:job)
+ job: job
)
end
diff --git a/lib/gitlab/diff/highlight_cache.rb b/lib/gitlab/diff/highlight_cache.rb
index e873e9c17d5..90cb9c8638a 100644
--- a/lib/gitlab/diff/highlight_cache.rb
+++ b/lib/gitlab/diff/highlight_cache.rb
@@ -24,6 +24,10 @@ module Gitlab
return [] unless content
+ # TODO: We could add some kind of flag to #initialize that would allow
+ # us to force re-caching
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/263508
+ #
if content.empty? && recache_due_to_size?(diff_file)
# If the file is missing from the cache and there's reason to believe
# it is uncached due to a size issue around changing the values for
diff --git a/lib/gitlab/git/diff_collection.rb b/lib/gitlab/git/diff_collection.rb
index 2771057f51b..6090d1b9f69 100644
--- a/lib/gitlab/git/diff_collection.rb
+++ b/lib/gitlab/git/diff_collection.rb
@@ -118,11 +118,17 @@ module Gitlab
files >= safe_max_files || @line_count > safe_max_lines || @byte_count >= safe_max_bytes
end
+ def expand_diff?
+ # Force single-entry diff collections to always present as expanded
+ #
+ @iterator.size == 1 || !@enforce_limits || @expanded
+ end
+
def each_gitaly_patch
i = @array.length
@iterator.each do |raw|
- diff = Gitlab::Git::Diff.new(raw, expanded: !@enforce_limits || @expanded)
+ diff = Gitlab::Git::Diff.new(raw, expanded: expand_diff?)
if raw.overflow_marker
@overflow = true
@@ -145,11 +151,9 @@ module Gitlab
break
end
- expanded = !@enforce_limits || @expanded
-
- diff = Gitlab::Git::Diff.new(raw, expanded: expanded)
+ diff = Gitlab::Git::Diff.new(raw, expanded: expand_diff?)
- if !expanded && over_safe_limits?(i) && diff.line_count > 0
+ if !expand_diff? && over_safe_limits?(i) && diff.line_count > 0
diff.collapse!
end
diff --git a/lib/gitlab/gitaly_client/diff_stitcher.rb b/lib/gitlab/gitaly_client/diff_stitcher.rb
index 98d327a7329..e98ae75590d 100644
--- a/lib/gitlab/gitaly_client/diff_stitcher.rb
+++ b/lib/gitlab/gitaly_client/diff_stitcher.rb
@@ -5,8 +5,10 @@ module Gitlab
class DiffStitcher
include Enumerable
- def initialize(rpc_response)
- @rpc_response = rpc_response
+ delegate :size, to: :rpc_response
+
+ def initialize(rpc_response_param)
+ @rpc_response = rpc_response_param
end
def each
@@ -31,6 +33,10 @@ module Gitlab
end
end
end
+
+ private
+
+ attr_reader :rpc_response
end
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index d414a7b24ff..0be158add6f 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -21253,7 +21253,7 @@ msgstr ""
msgid "ProtectedBranch|Code owner approval"
msgstr ""
-msgid "ProtectedBranch|Does not apply to users allowed to merge or push."
+msgid "ProtectedBranch|Does not apply to users allowed to push."
msgstr ""
msgid "ProtectedBranch|Protect"
@@ -22312,6 +22312,9 @@ msgstr ""
msgid "Requirement %{reference} has been updated"
msgstr ""
+msgid "Requirement title"
+msgstr ""
+
msgid "Requirement title cannot have more than %{limit} characters."
msgstr ""
diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb
index 91bb4f5a0d3..501d8d4a78d 100644
--- a/spec/controllers/registrations_controller_spec.rb
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -477,10 +477,16 @@ RSpec.describe RegistrationsController do
patch :update_registration, params: { user: { role: 'software_developer', setup_for_company: 'false' } }
end
- before do
- sign_in(create(:user))
+ context 'without a signed in user' do
+ it { is_expected.to redirect_to new_user_registration_path }
end
- it { is_expected.to redirect_to(dashboard_projects_path)}
+ context 'with a signed in user' do
+ before do
+ sign_in(create(:user))
+ end
+
+ it { is_expected.to redirect_to(dashboard_projects_path)}
+ end
end
end
diff --git a/spec/lib/gitlab/ci/parsers/test/junit_spec.rb b/spec/lib/gitlab/ci/parsers/test/junit_spec.rb
index c1acd9d481e..7da602251a5 100644
--- a/spec/lib/gitlab/ci/parsers/test/junit_spec.rb
+++ b/spec/lib/gitlab/ci/parsers/test/junit_spec.rb
@@ -4,11 +4,12 @@ require 'fast_spec_helper'
RSpec.describe Gitlab::Ci::Parsers::Test::Junit do
describe '#parse!' do
- subject { described_class.new.parse!(junit, test_suite, **args) }
+ subject { described_class.new.parse!(junit, test_suite, job: job) }
let(:test_suite) { Gitlab::Ci::Reports::TestSuite.new('rspec') }
let(:test_cases) { flattened_test_cases(test_suite) }
- let(:args) { { job: { id: 1, project: "project" } } }
+ let(:job) { double(max_test_cases_per_report: max_test_cases) }
+ let(:max_test_cases) { 0 }
context 'when data is JUnit style XML' do
context 'when there are no <testcases> in <testsuite>' do
@@ -230,6 +231,55 @@ RSpec.describe Gitlab::Ci::Parsers::Test::Junit do
)
end
end
+
+ context 'when number of test cases exceeds the max_test_cases limit' do
+ let(:max_test_cases) { 1 }
+
+ shared_examples_for 'rejecting too many test cases' do
+ it 'attaches an error to the TestSuite object' do
+ expect { subject }.not_to raise_error
+ expect(test_suite.suite_error).to eq("JUnit data parsing failed: number of test cases exceeded the limit of #{max_test_cases}")
+ end
+ end
+
+ context 'and test cases are unique' do
+ let(:junit) do
+ <<-EOF.strip_heredoc
+ <testsuites>
+ <testsuite>
+ <testcase classname='Calculator' name='sumTest1' time='0.01'></testcase>
+ <testcase classname='Calculator' name='sumTest2' time='0.02'></testcase>
+ </testsuite>
+ <testsuite>
+ <testcase classname='Statemachine' name='happy path' time='100'></testcase>
+ <testcase classname='Statemachine' name='unhappy path' time='200'></testcase>
+ </testsuite>
+ </testsuites>
+ EOF
+ end
+
+ it_behaves_like 'rejecting too many test cases'
+ end
+
+ context 'and test cases are duplicates' do
+ let(:junit) do
+ <<-EOF.strip_heredoc
+ <testsuites>
+ <testsuite>
+ <testcase classname='Calculator' name='sumTest1' time='0.01'></testcase>
+ <testcase classname='Calculator' name='sumTest2' time='0.02'></testcase>
+ </testsuite>
+ <testsuite>
+ <testcase classname='Calculator' name='sumTest1' time='0.01'></testcase>
+ <testcase classname='Calculator' name='sumTest2' time='0.02'></testcase>
+ </testsuite>
+ </testsuites>
+ EOF
+ end
+
+ it_behaves_like 'rejecting too many test cases'
+ end
+ end
end
context 'when data is not JUnit style XML' do
@@ -316,9 +366,7 @@ RSpec.describe Gitlab::Ci::Parsers::Test::Junit do
expect(test_cases[0].has_attachment?).to be_truthy
expect(test_cases[0].attachment).to eq("some/path.png")
- expect(test_cases[0].job).to be_present
- expect(test_cases[0].job[:id]).to eq(1)
- expect(test_cases[0].job[:project]).to eq("project")
+ expect(test_cases[0].job).to eq(job)
end
end
diff --git a/spec/lib/gitlab/git/diff_collection_spec.rb b/spec/lib/gitlab/git/diff_collection_spec.rb
index 8198c2651a7..1a3c332a21b 100644
--- a/spec/lib/gitlab/git/diff_collection_spec.rb
+++ b/spec/lib/gitlab/git/diff_collection_spec.rb
@@ -9,8 +9,11 @@ RSpec.describe Gitlab::Git::DiffCollection, :seed_helper do
MutatingConstantIterator.class_eval do
include Enumerable
+ attr_reader :size
+
def initialize(count, value)
@count = count
+ @size = count
@value = value
end
@@ -517,14 +520,30 @@ RSpec.describe Gitlab::Git::DiffCollection, :seed_helper do
.to yield_with_args(an_instance_of(Gitlab::Git::Diff))
end
- it 'prunes diffs that are quite big' do
- diff = nil
+ context 'single-file collections' do
+ it 'does not prune diffs' do
+ diff = nil
- subject.each do |d|
- diff = d
+ subject.each do |d|
+ diff = d
+ end
+
+ expect(diff.diff).not_to eq('')
end
+ end
+
+ context 'multi-file collections' do
+ let(:iterator) { [{ diff: 'b' }, { diff: 'a' * 20480 }]}
+
+ it 'prunes diffs that are quite big' do
+ diff = nil
- expect(diff.diff).to eq('')
+ subject.each do |d|
+ diff = d
+ end
+
+ expect(diff.diff).to eq('')
+ end
end
context 'when go over safe limits on files' do
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 5fde9b8661d..b562e41ea2d 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -3520,6 +3520,25 @@ RSpec.describe MergeRequest, factory_default: :keep do
end
end
+ describe '#merge_base_pipeline' do
+ let(:merge_request) do
+ create(:merge_request, :with_merge_request_pipeline)
+ end
+
+ let(:merge_base_pipeline) do
+ create(:ci_pipeline, ref: merge_request.target_branch, sha: merge_request.target_branch_sha)
+ end
+
+ before do
+ merge_base_pipeline
+ merge_request.update_head_pipeline
+ end
+
+ it 'returns a pipeline pointing to a commit on the target ref' do
+ expect(merge_request.merge_base_pipeline).to eq(merge_base_pipeline)
+ end
+ end
+
describe '#has_commits?' do
it 'returns true when merge request diff has commits' do
allow(subject.merge_request_diff).to receive(:commits_count)
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index 60843f368c1..7330c89fe77 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -2400,15 +2400,23 @@ RSpec.describe API::Users, :do_not_mock_admin_mode do
end
describe 'POST /users/:id/deactivate' do
+ subject(:deactivate) { post api("/users/#{user_id}/deactivate", api_user) }
+
+ let(:user_id) { user.id }
+
context 'performed by a non-admin user' do
+ let(:api_user) { user }
+
it 'is not authorized to perform the action' do
- post api("/users/#{user.id}/deactivate", user)
+ deactivate
expect(response).to have_gitlab_http_status(:forbidden)
end
end
context 'performed by an admin user' do
+ let(:api_user) { admin }
+
context 'for an active user' do
let(:activity) { {} }
let(:user) { create(:user, **activity) }
@@ -2416,11 +2424,9 @@ RSpec.describe API::Users, :do_not_mock_admin_mode do
context 'with no recent activity' do
let(:activity) { { last_activity_on: ::User::MINIMUM_INACTIVE_DAYS.next.days.ago } }
- before do
- post api("/users/#{user.id}/deactivate", admin)
- end
-
it 'deactivates an active user' do
+ deactivate
+
expect(response).to have_gitlab_http_status(:created)
expect(user.reload.state).to eq('deactivated')
end
@@ -2429,11 +2435,9 @@ RSpec.describe API::Users, :do_not_mock_admin_mode do
context 'with recent activity' do
let(:activity) { { last_activity_on: ::User::MINIMUM_INACTIVE_DAYS.pred.days.ago } }
- before do
- post api("/users/#{user.id}/deactivate", admin)
- end
-
it 'does not deactivate an active user' do
+ deactivate
+
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq("403 Forbidden - The user you are trying to deactivate has been active in the past #{::User::MINIMUM_INACTIVE_DAYS} days and cannot be deactivated")
expect(user.reload.state).to eq('active')
@@ -2444,11 +2448,11 @@ RSpec.describe API::Users, :do_not_mock_admin_mode do
context 'for a deactivated user' do
before do
user.deactivate
-
- post api("/users/#{user.id}/deactivate", admin)
end
it 'returns 201' do
+ deactivate
+
expect(response).to have_gitlab_http_status(:created)
expect(user.reload.state).to eq('deactivated')
end
@@ -2457,11 +2461,11 @@ RSpec.describe API::Users, :do_not_mock_admin_mode do
context 'for a blocked user' do
before do
user.block
-
- post api("/users/#{user.id}/deactivate", admin)
end
it 'returns 403' do
+ deactivate
+
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq('403 Forbidden - A blocked user cannot be deactivated by the API')
expect(user.reload.state).to eq('blocked')
@@ -2471,11 +2475,11 @@ RSpec.describe API::Users, :do_not_mock_admin_mode do
context 'for a ldap blocked user' do
before do
user.ldap_block
-
- post api("/users/#{user.id}/deactivate", admin)
end
it 'returns 403' do
+ deactivate
+
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq('403 Forbidden - A blocked user cannot be deactivated by the API')
expect(user.reload.state).to eq('ldap_blocked')
@@ -2483,10 +2487,10 @@ RSpec.describe API::Users, :do_not_mock_admin_mode do
end
context 'for an internal user' do
- it 'returns 403' do
- internal_user = User.alert_bot
+ let(:user) { User.alert_bot }
- post api("/users/#{internal_user.id}/deactivate", admin)
+ it 'returns 403' do
+ deactivate
expect(response).to have_gitlab_http_status(:forbidden)
expect(json_response['message']).to eq('403 Forbidden - An internal user cannot be deactivated by the API')
@@ -2494,8 +2498,10 @@ RSpec.describe API::Users, :do_not_mock_admin_mode do
end
context 'for a user that does not exist' do
+ let(:user_id) { 0 }
+
before do
- post api("/users/0/deactivate", admin)
+ deactivate
end
it_behaves_like '404'
diff --git a/spec/serializers/merge_request_widget_entity_spec.rb b/spec/serializers/merge_request_widget_entity_spec.rb
index e42d9a7622f..086d87c27eb 100644
--- a/spec/serializers/merge_request_widget_entity_spec.rb
+++ b/spec/serializers/merge_request_widget_entity_spec.rb
@@ -88,25 +88,53 @@ RSpec.describe MergeRequestWidgetEntity do
end
describe 'codequality report artifacts', :request_store do
+ let(:merge_base_pipeline) { create(:ci_pipeline, :with_codequality_report, project: project) }
+
before do
project.add_developer(user)
allow(resource).to receive_messages(
+ merge_base_pipeline: merge_base_pipeline,
base_pipeline: pipeline,
head_pipeline: pipeline
)
end
- context "with report artifacts" do
+ context 'with report artifacts' do
let(:pipeline) { create(:ci_pipeline, :with_codequality_report, project: project) }
+ let(:generic_job_id) { pipeline.builds.first.id }
+ let(:merge_base_job_id) { merge_base_pipeline.builds.first.id }
+
+ it 'has head_path and base_path entries' do
+ expect(subject[:codeclimate][:head_path]).to be_present
+ expect(subject[:codeclimate][:base_path]).to be_present
+ end
+
+ context 'on pipelines for merged results' do
+ let(:pipeline) { create(:ci_pipeline, :merged_result_pipeline, :with_codequality_report, project: project) }
+
+ context 'with merge_base_pipelines enabled' do
+ it 'returns URLs from the head_pipeline and merge_base_pipeline' do
+ expect(subject[:codeclimate][:head_path]).to include("/jobs/#{generic_job_id}/artifacts/download?file_type=codequality")
+ expect(subject[:codeclimate][:base_path]).to include("/jobs/#{merge_base_job_id}/artifacts/download?file_type=codequality")
+ end
+ end
+
+ context 'with merge_base_pipelines disabled' do
+ before do
+ stub_feature_flags(merge_base_pipelines: false)
+ end
- it "has data entry" do
- expect(subject).to include(:codeclimate)
+ it 'returns URLs from the head_pipeline and base_pipeline' do
+ expect(subject[:codeclimate][:head_path]).to include("/jobs/#{generic_job_id}/artifacts/download?file_type=codequality")
+ expect(subject[:codeclimate][:base_path]).to include("/jobs/#{generic_job_id}/artifacts/download?file_type=codequality")
+ end
+ end
end
end
- context "without artifacts" do
- it "does not have data entry" do
+ context 'without artifacts' do
+ it 'does not have data entry' do
expect(subject).not_to include(:codeclimate)
end
end
diff --git a/spec/workers/group_export_worker_spec.rb b/spec/workers/group_export_worker_spec.rb
index 5697e66b7d1..4e58e3886a4 100644
--- a/spec/workers/group_export_worker_spec.rb
+++ b/spec/workers/group_export_worker_spec.rb
@@ -26,4 +26,14 @@ RSpec.describe GroupExportWorker do
end
end
end
+
+ describe 'sidekiq options' do
+ it 'disables retry' do
+ expect(described_class.sidekiq_options['retry']).to eq(false)
+ end
+
+ it 'disables dead' do
+ expect(described_class.sidekiq_options['dead']).to eq(false)
+ end
+ end
end
diff --git a/spec/workers/group_import_worker_spec.rb b/spec/workers/group_import_worker_spec.rb
index 3fa24ecd7bc..5171de7086b 100644
--- a/spec/workers/group_import_worker_spec.rb
+++ b/spec/workers/group_import_worker_spec.rb
@@ -16,6 +16,16 @@ RSpec.describe GroupImportWorker do
end
end
+ describe 'sidekiq options' do
+ it 'disables retry' do
+ expect(described_class.sidekiq_options['retry']).to eq(false)
+ end
+
+ it 'disables dead' do
+ expect(described_class.sidekiq_options['dead']).to eq(false)
+ end
+ end
+
describe '#perform' do
context 'when it succeeds' do
before do
diff --git a/spec/workers/project_export_worker_spec.rb b/spec/workers/project_export_worker_spec.rb
index 1f54b6766a4..defecefc3cc 100644
--- a/spec/workers/project_export_worker_spec.rb
+++ b/spec/workers/project_export_worker_spec.rb
@@ -75,6 +75,10 @@ RSpec.describe ProjectExportWorker do
expect(described_class.sidekiq_options['retry']).to eq(false)
end
+ it 'disables dead' do
+ expect(described_class.sidekiq_options['dead']).to eq(false)
+ end
+
it 'sets default status expiration' do
expect(described_class.sidekiq_options['status_expiration']).to eq(StuckExportJobsWorker::EXPORT_JOBS_EXPIRATION)
end