Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/ci/rules.gitlab-ci.yml19
-rw-r--r--.gitlab/ci/static-analysis.gitlab-ci.yml37
-rw-r--r--.gitlab/sast-ruleset.toml10
-rw-r--r--app/assets/javascripts/work_items/components/work_item_assignees.vue25
-rw-r--r--app/assets/javascripts/work_items/components/work_item_detail.vue2
-rw-r--r--app/assets/stylesheets/pages/issues.scss22
-rw-r--r--app/controllers/search_controller.rb28
-rw-r--r--app/graphql/mutations/concerns/mutations/work_items/widgetable.rb10
-rw-r--r--app/graphql/mutations/work_items/create.rb2
-rw-r--r--app/graphql/mutations/work_items/update.rb2
-rw-r--r--app/graphql/types/work_items/widgets/hierarchy_update_input_type.rb3
-rw-r--r--app/models/ci/pipeline.rb6
-rw-r--r--app/models/namespace.rb4
-rw-r--r--app/models/notification_recipient.rb4
-rw-r--r--app/models/project.rb3
-rw-r--r--app/services/search_service.rb11
-rw-r--r--app/services/work_items/parent_links/create_service.rb7
-rw-r--r--app/services/work_items/widgets/hierarchy_service/base_service.rb10
-rw-r--r--config/application.rb13
-rw-r--r--config/feature_flags/development/mr_show_reports_immediately.yml8
-rw-r--r--config/initializers/00_connection_logger.rb26
-rw-r--r--config/initializers/database_config.rb6
-rw-r--r--config/routes.rb526
-rw-r--r--doc/api/dora/metrics.md44
-rw-r--r--doc/ci/yaml/index.md6
-rw-r--r--doc/development/cicd/templates.md33
-rw-r--r--doc/development/rails_initializers.md18
-rw-r--r--doc/user/project/merge_requests/approvals/img/mr_approvals_by_code_owners_v12_7.pngbin25594 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/approvals/img/mr_approvals_by_code_owners_v15_2.pngbin0 -> 11263 bytes
-rw-r--r--doc/user/project/merge_requests/approvals/rules.md4
-rw-r--r--doc/user/project/milestones/burndown_and_burnup_charts.md6
-rw-r--r--doc/user/project/milestones/img/burndown_and_burnup_charts_v15_1.pngbin34450 -> 0 bytes
-rw-r--r--doc/user/project/milestones/img/burndown_and_burnup_charts_v15_3.pngbin0 -> 47558 bytes
-rw-r--r--doc/user/project/milestones/img/burndown_chart_v15_1.pngbin20287 -> 0 bytes
-rw-r--r--doc/user/project/milestones/img/burndown_chart_v15_3.pngbin0 -> 26157 bytes
-rw-r--r--doc/user/project/milestones/img/burnup_chart_v15_1.pngbin21144 -> 0 bytes
-rw-r--r--doc/user/project/milestones/img/burnup_chart_v15_3.pngbin0 -> 26933 bytes
-rw-r--r--doc/user/project/milestones/index.md2
-rw-r--r--lib/api/users.rb2
-rw-r--r--lib/gitlab/ci/templates/Bash.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/C++.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Chef.gitlab-ci.yml13
-rw-r--r--lib/gitlab/ci/templates/Clojure.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Crystal.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Dart.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Elixir.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Flutter.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml13
-rw-r--r--lib/gitlab/ci/templates/Go.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Grails.gitlab-ci.yml13
-rw-r--r--lib/gitlab/ci/templates/Julia.gitlab-ci.yml13
-rw-r--r--lib/gitlab/ci/templates/Laravel.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Mono.gitlab-ci.yml13
-rw-r--r--lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/OpenShift.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/PHP.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Ruby.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Rust.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Scala.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/Swift.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/dotNET.gitlab-ci.yml3
-rw-r--r--lib/gitlab/ci/templates/iOS-Fastlane.gitlab-ci.yml13
-rw-r--r--lib/initializer_connections.rb29
-rw-r--r--locale/gitlab.pot31
-rwxr-xr-xscripts/process_custom_semgrep_results.sh2
-rw-r--r--spec/controllers/search_controller_spec.rb15
-rw-r--r--spec/features/merge_request/user_sees_versions_spec.rb36
-rw-r--r--spec/frontend/work_items/components/work_item_assignees_spec.js50
-rw-r--r--spec/initializers/00_connection_logger_spec.rb39
-rw-r--r--spec/lib/initializer_connections_spec.rb63
-rw-r--r--spec/models/ci/pipeline_spec.rb32
-rw-r--r--spec/models/namespace_spec.rb8
-rw-r--r--spec/models/project_spec.rb8
-rw-r--r--spec/requests/api/graphql/mutations/work_items/create_spec.rb14
-rw-r--r--spec/requests/api/graphql/mutations/work_items/update_spec.rb27
-rw-r--r--spec/services/work_items/parent_links/create_service_spec.rb22
-rw-r--r--spec/services/work_items/update_service_spec.rb2
-rw-r--r--spec/services/work_items/widgets/hierarchy_service/update_service_spec.rb14
78 files changed, 871 insertions, 549 deletions
diff --git a/.gitlab/ci/rules.gitlab-ci.yml b/.gitlab/ci/rules.gitlab-ci.yml
index 7f0de878744..5d551c2564b 100644
--- a/.gitlab/ci/rules.gitlab-ci.yml
+++ b/.gitlab/ci/rules.gitlab-ci.yml
@@ -1465,24 +1465,6 @@
- <<: *if-merge-request
changes: *static-analysis-patterns
-.semgrep-appsec-custom-rules:rules:
- rules:
- - <<: *if-not-ee
- when: never
- - <<: *if-merge-request
- changes: *code-backstage-qa-patterns
-
-.ping-appsec-for-sast-findings:rules:
- rules:
- # Requiring $CUSTOM_SAST_RULES_BOT_PAT prevents the bot from running on forks or CE
- # Without it the script would fail too.
- - if: "$CUSTOM_SAST_RULES_BOT_PAT == null"
- when: never
- - <<: *if-not-ee
- when: never
- - <<: *if-merge-request
- changes: *code-backstage-qa-patterns
-
#######################
# Vendored gems rules #
#######################
@@ -1569,6 +1551,7 @@
- '**/*.tsx'
- '**/*.c'
- '**/*.go'
+ - '**/*.rb'
.reports:rules:secret_detection:
rules:
diff --git a/.gitlab/ci/static-analysis.gitlab-ci.yml b/.gitlab/ci/static-analysis.gitlab-ci.yml
index cb3a9706a18..b4efd9e49bf 100644
--- a/.gitlab/ci/static-analysis.gitlab-ci.yml
+++ b/.gitlab/ci/static-analysis.gitlab-ci.yml
@@ -7,7 +7,6 @@
variables:
SETUP_DB: "false"
ENABLE_SPRING: "1"
- SKIP_LOG_INITIALIZER_CONNECTIONS: "1"
# Disable warnings in browserslist which can break on backports
# https://github.com/browserslist/browserslist/blob/a287ec6/node.js#L367-L384
BROWSERSLIST_IGNORE_OLD_DATA: "true"
@@ -160,39 +159,3 @@ feature-flags-usage:
when: always
paths:
- tmp/feature_flags/
-
-semgrep-appsec-custom-rules:
- stage: lint
- extends:
- - .semgrep-appsec-custom-rules:rules
- image: returntocorp/semgrep
- needs: []
- script:
- # Required to avoid a timeout https://github.com/returntocorp/semgrep/issues/5395
- - git fetch origin master
- # Include/exclude list isn't ideal https://github.com/returntocorp/semgrep/issues/5399
- - |
- semgrep ci --gitlab-sast --metrics off --config $CUSTOM_RULES_URL \
- --include app --include lib --include workhorse \
- --exclude '*_test.go' --exclude spec --exclude qa > gl-sast-report.json || true
- variables:
- CUSTOM_RULES_URL: https://gitlab.com/gitlab-com/gl-security/appsec/sast-custom-rules/-/raw/main/appsec-pings/rules.yml
- artifacts:
- paths:
- - gl-sast-report.json
- reports:
- sast: gl-sast-report.json
-
-ping-appsec-for-sast-findings:
- stage: lint
- image: alpine:latest
- extends:
- - .ping-appsec-for-sast-findings:rules
- variables:
- # Project Access Token bot ID for /gitlab-com/gl-security/appsec/sast-custom-rules
- BOT_USER_ID: 11727358
- needs:
- - semgrep-appsec-custom-rules
- script:
- - apk add jq curl
- - scripts/process_custom_semgrep_results.sh
diff --git a/.gitlab/sast-ruleset.toml b/.gitlab/sast-ruleset.toml
new file mode 100644
index 00000000000..6bfb4618b73
--- /dev/null
+++ b/.gitlab/sast-ruleset.toml
@@ -0,0 +1,10 @@
+[semgrep]
+ description = 'semgrep custom rules configuration'
+ targetdir = "/sgrules"
+ validate = true
+
+ [[semgrep.passthrough]]
+ type = "git"
+ value = "https://gitlab.com/gitlab-com/gl-security/appsec/sast-custom-rules.git"
+ ref = "refs/heads/main"
+ subdir = "appsec-pings"
diff --git a/app/assets/javascripts/work_items/components/work_item_assignees.vue b/app/assets/javascripts/work_items/components/work_item_assignees.vue
index 5349b40da8e..9ff424aa20f 100644
--- a/app/assets/javascripts/work_items/components/work_item_assignees.vue
+++ b/app/assets/javascripts/work_items/components/work_item_assignees.vue
@@ -15,10 +15,11 @@ import currentUserQuery from '~/graphql_shared/queries/current_user.query.graphq
import userSearchQuery from '~/graphql_shared/queries/users_search.query.graphql';
import InviteMembersTrigger from '~/invite_members/components/invite_members_trigger.vue';
import { n__, s__ } from '~/locale';
+import Tracking from '~/tracking';
import SidebarParticipant from '~/sidebar/components/assignees/sidebar_participant.vue';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
import localUpdateWorkItemMutation from '../graphql/local_update_work_item.mutation.graphql';
-import { i18n } from '../constants';
+import { i18n, TRACKING_CATEGORY_SHOW } from '../constants';
function isTokenSelectorElement(el) {
return el?.classList.contains('gl-token-close') || el?.classList.contains('dropdown-item');
@@ -44,6 +45,7 @@ export default {
GlDropdownItem,
GlDropdownDivider,
},
+ mixins: [Tracking.mixin()],
inject: ['fullPath'],
props: {
workItemId: {
@@ -58,6 +60,15 @@ export default {
type: Boolean,
required: true,
},
+ workItemType: {
+ type: String,
+ required: true,
+ },
+ canUpdate: {
+ type: Boolean,
+ required: false,
+ default: false,
+ },
},
data() {
return {
@@ -95,6 +106,13 @@ export default {
},
},
computed: {
+ tracking() {
+ return {
+ category: TRACKING_CATEGORY_SHOW,
+ label: 'item_assignees',
+ property: `type_${this.workItemType}`,
+ };
+ },
assigneeListEmpty() {
return this.assignees.length === 0;
},
@@ -163,6 +181,7 @@ export default {
},
},
});
+ this.track('updated_assignees');
},
handleFocus() {
this.isEditing = true;
@@ -208,9 +227,11 @@ export default {
ref="tokenSelector"
:selected-tokens="localAssignees"
:container-class="containerClass"
- class="assignees-selector gl-flex-grow-1 gl-border gl-border-white gl-hover-border-gray-200 gl-rounded-base col-9 gl-align-self-start gl-px-0!"
+ class="assignees-selector gl-flex-grow-1 gl-border gl-border-white gl-rounded-base col-9 gl-align-self-start gl-px-0!"
+ :class="{ 'gl-hover-border-gray-200': canUpdate }"
:dropdown-items="dropdownItems"
:loading="isLoadingUsers"
+ :view-only="!canUpdate"
@input="handleAssigneesInput"
@text-input="debouncedSearchKeyUpdate"
@focus="handleFocus"
diff --git a/app/assets/javascripts/work_items/components/work_item_detail.vue b/app/assets/javascripts/work_items/components/work_item_detail.vue
index 7314b0afc54..ad90fe88947 100644
--- a/app/assets/javascripts/work_items/components/work_item_detail.vue
+++ b/app/assets/javascripts/work_items/components/work_item_detail.vue
@@ -216,9 +216,11 @@ export default {
<template v-if="workItemsMvc2Enabled">
<work-item-assignees
v-if="workItemAssignees"
+ :can-update="canUpdate"
:work-item-id="workItem.id"
:assignees="workItemAssignees.assignees.nodes"
:allows-multiple-assignees="workItemAssignees.allowsMultipleAssignees"
+ :work-item-type="workItemType"
@error="error = $event"
/>
<work-item-labels
diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss
index 04e0ef6631e..c0a283ec643 100644
--- a/app/assets/stylesheets/pages/issues.scss
+++ b/app/assets/stylesheets/pages/issues.scss
@@ -124,8 +124,16 @@ ul.related-merge-requests > li gl-emoji {
.new-branch-col {
.discussion-filter-container {
- &:not(:only-child) {
- margin-right: $gl-padding-8;
+ &:not(:last-child) {
+ margin-right: $gl-spacing-scale-3;
+ }
+ }
+
+ @include media-breakpoint-down(xs) {
+ width: 100%;
+
+ > div:not(:last-child) {
+ margin-bottom: $gl-spacing-scale-3;
}
}
}
@@ -147,6 +155,16 @@ ul.related-merge-requests > li gl-emoji {
.btn-group:not(.hidden) {
display: flex;
+
+ @include media-breakpoint-down(xs) {
+ .btn.btn-confirm {
+ @include gl-justify-content-start;
+
+ &.dropdown-toggle {
+ @include gl-flex-grow-0;
+ }
+ }
+ }
}
.js-create-merge-request {
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index 6b5fb266fd8..7a7e63f5fc4 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -42,13 +42,19 @@ class SearchController < ApplicationController
@sort = params[:sort] || default_sort
@search_service = Gitlab::View::Presenter::Factory.new(search_service, current_user: current_user).fabricate!
- @scope = @search_service.scope
- @without_count = @search_service.without_count?
- @show_snippets = @search_service.show_snippets?
- @search_results = @search_service.search_results
- @search_objects = @search_service.search_objects
- @search_highlight = @search_service.search_highlight
- @aggregations = @search_service.search_aggregations
+
+ @search_level = @search_service.level
+ @search_type = search_type
+
+ @global_search_duration_s = Benchmark.realtime do
+ @scope = @search_service.scope
+ @without_count = @search_service.without_count?
+ @show_snippets = @search_service.show_snippets?
+ @search_results = @search_service.search_results
+ @search_objects = @search_service.search_objects
+ @search_highlight = @search_service.search_highlight
+ @aggregations = @search_service.search_aggregations
+ end
increment_search_counters
end
@@ -144,7 +150,9 @@ class SearchController < ApplicationController
payload[:metadata]['meta.search.filters.state'] = params[:state]
payload[:metadata]['meta.search.force_search_results'] = params[:force_search_results]
payload[:metadata]['meta.search.project_ids'] = params[:project_ids]
- payload[:metadata]['meta.search.search_level'] = params[:search_level]
+ payload[:metadata]['meta.search.type'] = @search_type if @search_type.present?
+ payload[:metadata]['meta.search.level'] = @search_level if @search_level.present?
+ payload[:metadata][:global_search_duration_s] = @global_search_duration_s if @global_search_duration_s.present?
if search_service.abuse_detected?
payload[:metadata]['abuse.confidence'] = Gitlab::Abuse.confidence(:certain)
@@ -207,6 +215,10 @@ class SearchController < ApplicationController
def tracking_namespace_source
search_service.project&.namespace || search_service.group
end
+
+ def search_type
+ 'basic'
+ end
end
SearchController.prepend_mod_with('SearchController')
diff --git a/app/graphql/mutations/concerns/mutations/work_items/widgetable.rb b/app/graphql/mutations/concerns/mutations/work_items/widgetable.rb
index 22f782514c9..445b2eb6441 100644
--- a/app/graphql/mutations/concerns/mutations/work_items/widgetable.rb
+++ b/app/graphql/mutations/concerns/mutations/work_items/widgetable.rb
@@ -5,11 +5,17 @@ module Mutations
module Widgetable
extend ActiveSupport::Concern
- def extract_widget_params(work_item_type, attributes)
+ def extract_widget_params!(work_item_type, attributes)
# Get the list of widgets for the work item's type to extract only the supported attributes
- widget_keys = work_item_type.widgets.map(&:api_symbol)
+ widget_keys = ::WorkItems::Type.available_widgets.map(&:api_symbol)
widget_params = attributes.extract!(*widget_keys)
+ not_supported_keys = widget_params.keys - work_item_type.widgets.map(&:api_symbol)
+ if not_supported_keys.present?
+ raise Gitlab::Graphql::Errors::ArgumentError,
+ "Following widget keys are not supported by #{work_item_type.name} type: #{not_supported_keys}"
+ end
+
# Cannot use prepare to use `.to_h` on each input due to
# https://gitlab.com/gitlab-org/gitlab/-/merge_requests/87472#note_945199865
widget_params.transform_values { |values| values.to_h }
diff --git a/app/graphql/mutations/work_items/create.rb b/app/graphql/mutations/work_items/create.rb
index dcd7d58737a..350153eaf19 100644
--- a/app/graphql/mutations/work_items/create.rb
+++ b/app/graphql/mutations/work_items/create.rb
@@ -43,7 +43,7 @@ module Mutations
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
params = global_id_compatibility_params(attributes).merge(author_id: current_user.id)
type = ::WorkItems::Type.find(attributes[:work_item_type_id])
- widget_params = extract_widget_params(type, params)
+ widget_params = extract_widget_params!(type, params)
create_result = ::WorkItems::CreateService.new(
project: project,
diff --git a/app/graphql/mutations/work_items/update.rb b/app/graphql/mutations/work_items/update.rb
index c9f733223b5..5d8c574877a 100644
--- a/app/graphql/mutations/work_items/update.rb
+++ b/app/graphql/mutations/work_items/update.rb
@@ -25,7 +25,7 @@ module Mutations
end
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
- widget_params = extract_widget_params(work_item.work_item_type, attributes)
+ widget_params = extract_widget_params!(work_item.work_item_type, attributes)
update_result = ::WorkItems::UpdateService.new(
project: work_item.project,
diff --git a/app/graphql/types/work_items/widgets/hierarchy_update_input_type.rb b/app/graphql/types/work_items/widgets/hierarchy_update_input_type.rb
index 1c0833d1e6c..e1a9ebb76e9 100644
--- a/app/graphql/types/work_items/widgets/hierarchy_update_input_type.rb
+++ b/app/graphql/types/work_items/widgets/hierarchy_update_input_type.rb
@@ -14,7 +14,8 @@ module Types
argument :children_ids, [::Types::GlobalIDType[::WorkItem]],
required: false,
description: 'Global IDs of children work items.',
- prepare: ->(ids, _) { ids.map(&:model_id) }
+ loads: ::Types::WorkItemType,
+ as: :children
end
end
end
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 1c01a81ee41..791bae17271 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -1064,7 +1064,11 @@ module Ci
end
def has_reports?(reports_scope)
- complete? && latest_report_builds(reports_scope).exists?
+ if Feature.enabled?(:mr_show_reports_immediately, project, type: :development)
+ latest_report_builds(reports_scope).exists?
+ else
+ complete? && latest_report_builds(reports_scope).exists?
+ end
end
def has_coverage_reports?
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 8517ec2e6d0..f23a859b119 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -343,6 +343,10 @@ class Namespace < ApplicationRecord
end
end
+ def emails_enabled?
+ !emails_disabled?
+ end
+
def lfs_enabled?
# User namespace will always default to the global setting
Gitlab.config.lfs.enabled
diff --git a/app/models/notification_recipient.rb b/app/models/notification_recipient.rb
index 79a84231083..b3eaed154e2 100644
--- a/app/models/notification_recipient.rb
+++ b/app/models/notification_recipient.rb
@@ -125,6 +125,10 @@ class NotificationRecipient
@project ? @project.emails_disabled? : @group&.emails_disabled?
end
+ def emails_enabled?
+ !emails_disabled?
+ end
+
def read_ability
return if @skip_read_ability
return @read_ability if instance_variable_defined?(:@read_ability)
diff --git a/app/models/project.rb b/app/models/project.rb
index f5a69494237..46e25564eab 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1038,6 +1038,9 @@ class Project < ApplicationRecord
end
end
+ def emails_enabled?
+ !emails_disabled?
+ end
override :lfs_enabled?
def lfs_enabled?
return namespace.lfs_enabled? if self[:lfs_enabled].nil?
diff --git a/app/services/search_service.rb b/app/services/search_service.rb
index 7b16c7eee42..cea7fc5769e 100644
--- a/app/services/search_service.rb
+++ b/app/services/search_service.rb
@@ -91,6 +91,17 @@ class SearchService
end
end
+ def level
+ @level ||=
+ if project
+ 'project'
+ elsif group
+ 'group'
+ else
+ 'global'
+ end
+ end
+
private
def page
diff --git a/app/services/work_items/parent_links/create_service.rb b/app/services/work_items/parent_links/create_service.rb
index 78013f081c8..9940776e367 100644
--- a/app/services/work_items/parent_links/create_service.rb
+++ b/app/services/work_items/parent_links/create_service.rb
@@ -38,12 +38,7 @@ module WorkItems
end
def extract_references
- params[:issuable_references].map do |id|
- ::WorkItem.find(id)
- rescue ActiveRecord::RecordNotFound
- @errors << _("Task with ID: %{id} could not be found.") % { id: id }
- next
- end.compact
+ params[:issuable_references]
end
# TODO: Create system notes when work item's parent or children are updated
diff --git a/app/services/work_items/widgets/hierarchy_service/base_service.rb b/app/services/work_items/widgets/hierarchy_service/base_service.rb
index 6466c815bdf..085d6c6b0e7 100644
--- a/app/services/work_items/widgets/hierarchy_service/base_service.rb
+++ b/app/services/work_items/widgets/hierarchy_service/base_service.rb
@@ -12,8 +12,8 @@ module WorkItems
if params.key?(:parent)
update_work_item_parent(params.delete(:parent))
- elsif params.key?(:children_ids)
- update_work_item_children(params.delete(:children_ids))
+ elsif params.key?(:children)
+ update_work_item_children(params.delete(:children))
else
invalid_args_error
end
@@ -42,9 +42,9 @@ module WorkItems
end
# rubocop: enable CodeReuse/ActiveRecord
- def update_work_item_children(children_ids)
+ def update_work_item_children(children)
::WorkItems::ParentLinks::CreateService
- .new(widget.work_item, current_user, { issuable_references: children_ids })
+ .new(widget.work_item, current_user, { issuable_references: children })
.execute
end
@@ -53,7 +53,7 @@ module WorkItems
end
def incompatible_args?(params)
- params[:children_ids] && params[:parent]
+ params[:children] && params[:parent]
end
def feature_flag_error
diff --git a/config/application.rb b/config/application.rb
index 61f38787c1d..b758f2df857 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -504,19 +504,6 @@ module Gitlab
end
end
- # We know Rails closes database connections in the
- # active_record.clear_active_connections initializer, so only log database
- # connections opened after that.
- initializer :start_logging_new_postgresql_connections, after: :finisher_hook do
- ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.warn_on_new_connection = true
- end
-
- # It is legitimate to open database connections after initializers so stop
- # logging
- initializer :stop_logging_new_postgresql_connections, after: :set_routes_reloader_hook do
- ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.warn_on_new_connection = false
- end
-
# Add assets for variants of GitLab. They should take precedence over CE.
# This means if multiple files exist, e.g.:
#
diff --git a/config/feature_flags/development/mr_show_reports_immediately.yml b/config/feature_flags/development/mr_show_reports_immediately.yml
new file mode 100644
index 00000000000..23ac381a521
--- /dev/null
+++ b/config/feature_flags/development/mr_show_reports_immediately.yml
@@ -0,0 +1,8 @@
+---
+name: mr_show_reports_immediately
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76612
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/367027
+milestone: '15.2'
+type: development
+group: group::pipeline insights
+default_enabled: false
diff --git a/config/initializers/00_connection_logger.rb b/config/initializers/00_connection_logger.rb
deleted file mode 100644
index 9f03d13f95f..00000000000
--- a/config/initializers/00_connection_logger.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# frozen_string_literal: true
-
-module NewConnectionLogger
- extend ActiveSupport::Concern
-
- prepended do |base|
- base.class_attribute :warn_on_new_connection, default: false
- end
-
- class_methods do
- def new_client(...)
- if warn_on_new_connection && !ENV['SKIP_LOG_INITIALIZER_CONNECTIONS']
- cleaned_caller = Gitlab::BacktraceCleaner.clean_backtrace(caller)
- message = "Database connection should not be called during initializers. Read more at https://docs.gitlab.com/ee/development/rails_initializers.html#database-connections-in-initializers"
-
- ActiveSupport::Deprecation.warn(message, cleaned_caller)
-
- warn caller if ENV['DEBUG_INITIALIZER_CONNECTIONS']
- end
-
- super
- end
- end
-end
-
-ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend(NewConnectionLogger)
diff --git a/config/initializers/database_config.rb b/config/initializers/database_config.rb
index 84ef0bc9f16..31666c884bc 100644
--- a/config/initializers/database_config.rb
+++ b/config/initializers/database_config.rb
@@ -1,6 +1,12 @@
# frozen_string_literal: true
Gitlab.ee do
+ if Gitlab::Geo.geo_database_configured?
+ # Make sure connects_to for geo gets called outside of config/routes.rb first
+ # See InitializerConnections.with_disabled_database_connections
+ Geo::TrackingBase
+ end
+
if Gitlab::Runtime.sidekiq? && Gitlab::Geo.geo_database_configured?
# The Geo::TrackingBase model does not yet use connects_to. So,
# this will not properly support geo: from config/databse.yml
diff --git a/config/routes.rb b/config/routes.rb
index 652b50e3928..97e6983e0bc 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -4,336 +4,338 @@ require 'sidekiq/web'
require 'sidekiq/cron/web'
require 'product_analytics/collector_app'
-Rails.application.routes.draw do
- concern :access_requestable do
- post :request_access, on: :collection
- post :approve_access_request, on: :member
- end
+InitializerConnections.with_disabled_database_connections do
+ Rails.application.routes.draw do
+ concern :access_requestable do
+ post :request_access, on: :collection
+ post :approve_access_request, on: :member
+ end
- concern :awardable do
- post :toggle_award_emoji, on: :member
- end
+ concern :awardable do
+ post :toggle_award_emoji, on: :member
+ end
- favicon_redirect = redirect do |_params, _request|
- ActionController::Base.helpers.asset_url(Gitlab::Favicon.main)
- end
- get 'favicon.png', to: favicon_redirect
- get 'favicon.ico', to: favicon_redirect
+ favicon_redirect = redirect do |_params, _request|
+ ActionController::Base.helpers.asset_url(Gitlab::Favicon.main)
+ end
+ get 'favicon.png', to: favicon_redirect
+ get 'favicon.ico', to: favicon_redirect
- draw :development
+ draw :development
- use_doorkeeper do
- controllers applications: 'oauth/applications',
- authorized_applications: 'oauth/authorized_applications',
- authorizations: 'oauth/authorizations',
- token_info: 'oauth/token_info',
- tokens: 'oauth/tokens'
- end
+ use_doorkeeper do
+ controllers applications: 'oauth/applications',
+ authorized_applications: 'oauth/authorized_applications',
+ authorizations: 'oauth/authorizations',
+ token_info: 'oauth/token_info',
+ tokens: 'oauth/tokens'
+ end
- # This prefixless path is required because Jira gets confused if we set it up with a path
- # More information: https://gitlab.com/gitlab-org/gitlab/issues/6752
- scope path: '/login/oauth', controller: 'oauth/jira_dvcs/authorizations', as: :oauth_jira_dvcs do
- get :authorize, action: :new
- get :callback
- post :access_token
+ # This prefixless path is required because Jira gets confused if we set it up with a path
+ # More information: https://gitlab.com/gitlab-org/gitlab/issues/6752
+ scope path: '/login/oauth', controller: 'oauth/jira_dvcs/authorizations', as: :oauth_jira_dvcs do
+ get :authorize, action: :new
+ get :callback
+ post :access_token
- match '*all', via: [:get, :post], to: proc { [404, {}, ['']] }
- end
+ match '*all', via: [:get, :post], to: proc { [404, {}, ['']] }
+ end
- draw :oauth
+ draw :oauth
- use_doorkeeper_openid_connect do
- controllers discovery: 'jwks'
- end
+ use_doorkeeper_openid_connect do
+ controllers discovery: 'jwks'
+ end
- # Add OPTIONS method for CORS preflight requests
- match '/oauth/userinfo' => 'doorkeeper/openid_connect/userinfo#show', via: :options
- match '/oauth/discovery/keys' => 'jwks#keys', via: :options
- match '/.well-known/openid-configuration' => 'jwks#provider', via: :options
- match '/.well-known/webfinger' => 'jwks#webfinger', via: :options
+ # Add OPTIONS method for CORS preflight requests
+ match '/oauth/userinfo' => 'doorkeeper/openid_connect/userinfo#show', via: :options
+ match '/oauth/discovery/keys' => 'jwks#keys', via: :options
+ match '/.well-known/openid-configuration' => 'jwks#provider', via: :options
+ match '/.well-known/webfinger' => 'jwks#webfinger', via: :options
- match '/oauth/token' => 'oauth/tokens#create', via: :options
- match '/oauth/revoke' => 'oauth/tokens#revoke', via: :options
+ match '/oauth/token' => 'oauth/tokens#create', via: :options
+ match '/oauth/revoke' => 'oauth/tokens#revoke', via: :options
- match '/-/jira_connect/oauth_application_id' => 'jira_connect/oauth_application_ids#show', via: :options
+ match '/-/jira_connect/oauth_application_id' => 'jira_connect/oauth_application_ids#show', via: :options
- # Sign up
- scope path: '/users/sign_up', module: :registrations, as: :users_sign_up do
- resource :welcome, only: [:show, :update], controller: 'welcome' do
- Gitlab.ee do
- get :trial_getting_started, on: :collection
- get :trial_onboarding_board, on: :collection
- get :continuous_onboarding_getting_started, on: :collection
+ # Sign up
+ scope path: '/users/sign_up', module: :registrations, as: :users_sign_up do
+ resource :welcome, only: [:show, :update], controller: 'welcome' do
+ Gitlab.ee do
+ get :trial_getting_started, on: :collection
+ get :trial_onboarding_board, on: :collection
+ get :continuous_onboarding_getting_started, on: :collection
+ end
end
- end
- Gitlab.ee do
- resource :company, only: [:new, :create], controller: 'company'
- resources :groups, only: [:new, :create]
- resources :projects, only: [:new, :create]
- resources :groups_projects, only: [:new, :create] do
- collection do
- post :import
- put :exit
+ Gitlab.ee do
+ resource :company, only: [:new, :create], controller: 'company'
+ resources :groups, only: [:new, :create]
+ resources :projects, only: [:new, :create]
+ resources :groups_projects, only: [:new, :create] do
+ collection do
+ post :import
+ put :exit
+ end
end
+ draw :verification
end
- draw :verification
end
- end
- # Search
- get 'search' => 'search#show', as: :search
- get 'search/autocomplete' => 'search#autocomplete', as: :search_autocomplete
- get 'search/count' => 'search#count', as: :search_count
- get 'search/opensearch' => 'search#opensearch', as: :search_opensearch
+ # Search
+ get 'search' => 'search#show', as: :search
+ get 'search/autocomplete' => 'search#autocomplete', as: :search_autocomplete
+ get 'search/count' => 'search#count', as: :search_count
+ get 'search/opensearch' => 'search#opensearch', as: :search_opensearch
- # JSON Web Token
- get 'jwt/auth' => 'jwt#auth'
+ # JSON Web Token
+ get 'jwt/auth' => 'jwt#auth'
- # Health check
- get 'health_check(/:checks)' => 'health_check#index', as: :health_check
+ # Health check
+ get 'health_check(/:checks)' => 'health_check#index', as: :health_check
- # Terraform service discovery
- get '.well-known/terraform.json' => 'terraform/services#index', as: :terraform_services
+ # Terraform service discovery
+ get '.well-known/terraform.json' => 'terraform/services#index', as: :terraform_services
- # Begin of the /-/ scope.
- # Use this scope for all new global routes.
- scope path: '-' do
- # Autocomplete
- get '/autocomplete/users' => 'autocomplete#users'
- get '/autocomplete/users/:id' => 'autocomplete#user'
- get '/autocomplete/projects' => 'autocomplete#projects'
- get '/autocomplete/award_emojis' => 'autocomplete#award_emojis'
- get '/autocomplete/merge_request_target_branches' => 'autocomplete#merge_request_target_branches'
- get '/autocomplete/deploy_keys_with_owners' => 'autocomplete#deploy_keys_with_owners'
+ # Begin of the /-/ scope.
+ # Use this scope for all new global routes.
+ scope path: '-' do
+ # Autocomplete
+ get '/autocomplete/users' => 'autocomplete#users'
+ get '/autocomplete/users/:id' => 'autocomplete#user'
+ get '/autocomplete/projects' => 'autocomplete#projects'
+ get '/autocomplete/award_emojis' => 'autocomplete#award_emojis'
+ get '/autocomplete/merge_request_target_branches' => 'autocomplete#merge_request_target_branches'
+ get '/autocomplete/deploy_keys_with_owners' => 'autocomplete#deploy_keys_with_owners'
- Gitlab.ee do
- get '/autocomplete/project_groups' => 'autocomplete#project_groups'
- get '/autocomplete/project_routes' => 'autocomplete#project_routes'
- get '/autocomplete/namespace_routes' => 'autocomplete#namespace_routes'
- get '/autocomplete/group_subgroups' => 'autocomplete#group_subgroups'
- end
+ Gitlab.ee do
+ get '/autocomplete/project_groups' => 'autocomplete#project_groups'
+ get '/autocomplete/project_routes' => 'autocomplete#project_routes'
+ get '/autocomplete/namespace_routes' => 'autocomplete#namespace_routes'
+ get '/autocomplete/group_subgroups' => 'autocomplete#group_subgroups'
+ end
- # sandbox
- get '/sandbox/mermaid' => 'sandbox#mermaid'
+ # sandbox
+ get '/sandbox/mermaid' => 'sandbox#mermaid'
- get '/whats_new' => 'whats_new#index'
+ get '/whats_new' => 'whats_new#index'
- get 'offline' => "pwa#offline"
- get 'manifest' => "pwa#manifest", constraints: lambda { |req| req.format == :json }
+ get 'offline' => "pwa#offline"
+ get 'manifest' => "pwa#manifest", constraints: lambda { |req| req.format == :json }
- # '/-/health' implemented by BasicHealthCheck middleware
- get 'liveness' => 'health#liveness'
- get 'readiness' => 'health#readiness'
- controller :metrics do
- get 'metrics', action: :index
- get 'metrics/system', action: :system
- end
- mount Peek::Railtie => '/peek', as: 'peek_routes'
+ # '/-/health' implemented by BasicHealthCheck middleware
+ get 'liveness' => 'health#liveness'
+ get 'readiness' => 'health#readiness'
+ controller :metrics do
+ get 'metrics', action: :index
+ get 'metrics/system', action: :system
+ end
+ mount Peek::Railtie => '/peek', as: 'peek_routes'
- get 'runner_setup/platforms' => 'runner_setup#platforms'
+ get 'runner_setup/platforms' => 'runner_setup#platforms'
- # Boards resources shared between group and projects
- resources :boards, only: [] do
- resources :lists, module: :boards, only: [:index, :create, :update, :destroy] do
- collection do
- post :generate
+ # Boards resources shared between group and projects
+ resources :boards, only: [] do
+ resources :lists, module: :boards, only: [:index, :create, :update, :destroy] do
+ collection do
+ post :generate
+ end
+
+ resources :issues, only: [:index, :create, :update]
end
- resources :issues, only: [:index, :create, :update]
- end
+ resources :issues, module: :boards, only: [:index, :update] do
+ collection do
+ put :bulk_move, format: :json
+ end
+ end
- resources :issues, module: :boards, only: [:index, :update] do
- collection do
- put :bulk_move, format: :json
+ Gitlab.ee do
+ resources :users, module: :boards, only: [:index]
+ resources :milestones, module: :boards, only: [:index]
end
end
- Gitlab.ee do
- resources :users, module: :boards, only: [:index]
- resources :milestones, module: :boards, only: [:index]
- end
- end
+ get 'acme-challenge/' => 'acme_challenges#show'
- get 'acme-challenge/' => 'acme_challenges#show'
+ scope :ide, as: :ide, format: false do
+ get '/', to: 'ide#index'
+ get '/project', to: 'ide#index'
+
+ scope path: 'project/:project_id', as: :project, constraints: { project_id: Gitlab::PathRegex.full_namespace_route_regex } do
+ %w[edit tree blob].each do |action|
+ get "/#{action}", to: 'ide#index'
+ get "/#{action}/*branch/-/*path", to: 'ide#index'
+ get "/#{action}/*branch/-", to: 'ide#index'
+ get "/#{action}/*branch", to: 'ide#index'
+ end
+
+ get '/merge_requests/:merge_request_id', to: 'ide#index', constraints: { merge_request_id: /\d+/ }
+ get '/', to: 'ide#index'
+ end
+ end
- scope :ide, as: :ide, format: false do
- get '/', to: 'ide#index'
- get '/project', to: 'ide#index'
+ draw :operations
+ draw :jira_connect
- scope path: 'project/:project_id', as: :project, constraints: { project_id: Gitlab::PathRegex.full_namespace_route_regex } do
- %w[edit tree blob].each do |action|
- get "/#{action}", to: 'ide#index'
- get "/#{action}/*branch/-/*path", to: 'ide#index'
- get "/#{action}/*branch/-", to: 'ide#index'
- get "/#{action}/*branch", to: 'ide#index'
+ Gitlab.ee do
+ draw :security
+ draw :smartcard
+ draw :trial
+ draw :trial_registration
+ draw :country
+ draw :country_state
+ draw :subscription
+
+ scope '/push_from_secondary/:geo_node_id' do
+ draw :git_http
end
- get '/merge_requests/:merge_request_id', to: 'ide#index', constraints: { merge_request_id: /\d+/ }
- get '/', to: 'ide#index'
+ # Used for survey responses
+ resources :survey_responses, only: :index
end
- end
-
- draw :operations
- draw :jira_connect
- Gitlab.ee do
- draw :security
- draw :smartcard
- draw :trial
- draw :trial_registration
- draw :country
- draw :country_state
- draw :subscription
-
- scope '/push_from_secondary/:geo_node_id' do
- draw :git_http
+ Gitlab.jh do
+ draw :global_jh
end
- # Used for survey responses
- resources :survey_responses, only: :index
- end
-
- Gitlab.jh do
- draw :global_jh
- end
-
- if ENV['GITLAB_CHAOS_SECRET'] || Rails.env.development? || Rails.env.test?
- resource :chaos, only: [] do
- get :leakmem
- get :cpu_spin
- get :db_spin
- get :sleep
- get :kill
- get :quit
- post :gc
+ if ENV['GITLAB_CHAOS_SECRET'] || Rails.env.development? || Rails.env.test?
+ resource :chaos, only: [] do
+ get :leakmem
+ get :cpu_spin
+ get :db_spin
+ get :sleep
+ get :kill
+ get :quit
+ post :gc
+ end
end
- end
- resources :invites, only: [:show], constraints: { id: /[A-Za-z0-9_-]+/ } do
- member do
- post :accept
- match :decline, via: [:get, :post]
+ resources :invites, only: [:show], constraints: { id: /[A-Za-z0-9_-]+/ } do
+ member do
+ post :accept
+ match :decline, via: [:get, :post]
+ end
end
- end
- resources :sent_notifications, only: [], constraints: { id: /\h{32}/ } do
- member do
- get :unsubscribe
+ resources :sent_notifications, only: [], constraints: { id: /\h{32}/ } do
+ member do
+ get :unsubscribe
+ end
end
- end
- # Spam reports
- resources :abuse_reports, only: [:new, :create]
+ # Spam reports
+ resources :abuse_reports, only: [:new, :create]
- # JWKS (JSON Web Key Set) endpoint
- # Used by third parties to verify CI_JOB_JWT
- get 'jwks' => 'jwks#index'
+ # JWKS (JSON Web Key Set) endpoint
+ # Used by third parties to verify CI_JOB_JWT
+ get 'jwks' => 'jwks#index'
- draw :snippets
- draw :profile
+ draw :snippets
+ draw :profile
- post '/mailgun/webhooks' => 'mailgun/webhooks#process_webhook'
+ post '/mailgun/webhooks' => 'mailgun/webhooks#process_webhook'
- # Deprecated route for permanent failures
- # https://gitlab.com/gitlab-org/gitlab/-/issues/362606
- post '/members/mailgun/permanent_failures' => 'mailgun/webhooks#process_webhook'
+ # Deprecated route for permanent failures
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/362606
+ post '/members/mailgun/permanent_failures' => 'mailgun/webhooks#process_webhook'
- # Product analytics collector
- match '/collector/i', to: ProductAnalytics::CollectorApp.new, via: :all
- end
- # End of the /-/ scope.
-
- concern :clusterable do
- resources :clusters, only: [:index, :show, :update, :destroy] do
- collection do
- get :connect
- get :new_cluster_docs
- post :create_user
- end
+ # Product analytics collector
+ match '/collector/i', to: ProductAnalytics::CollectorApp.new, via: :all
+ end
+ # End of the /-/ scope.
- resource :integration, controller: 'clusters/integrations', only: [] do
+ concern :clusterable do
+ resources :clusters, only: [:index, :show, :update, :destroy] do
collection do
- post :create_or_update
+ get :connect
+ get :new_cluster_docs
+ post :create_user
end
- end
- member do
- Gitlab.ee do
- get :metrics, format: :json
- get :environments, format: :json
+ resource :integration, controller: 'clusters/integrations', only: [] do
+ collection do
+ post :create_or_update
+ end
end
- get :metrics_dashboard
- get :'/prometheus/api/v1/*proxy_path', to: 'clusters#prometheus_proxy', as: :prometheus_api
- get :cluster_status, format: :json
- delete :clear_cache
+ member do
+ Gitlab.ee do
+ get :metrics, format: :json
+ get :environments, format: :json
+ end
+
+ get :metrics_dashboard
+ get :'/prometheus/api/v1/*proxy_path', to: 'clusters#prometheus_proxy', as: :prometheus_api
+ get :cluster_status, format: :json
+ delete :clear_cache
+ end
end
end
- end
- resources :groups, only: [:index, :new, :create] do
- post :preview_markdown
- end
+ resources :groups, only: [:index, :new, :create] do
+ post :preview_markdown
+ end
- draw :group
-
- resources :projects, only: [:index, :new, :create]
-
- get '/projects/:id' => 'projects/redirect#redirect_from_id'
-
- draw :git_http
- draw :api
- draw :customers_dot
- draw :sidekiq
- draw :help
- draw :google_api
- draw :import
- draw :uploads
- draw :explore
- draw :admin
- draw :dashboard
- draw :user
- draw :project
- draw :unmatched_project
-
- # Issue https://gitlab.com/gitlab-org/gitlab/-/issues/210024
- scope as: 'deprecated' do
- # Issue https://gitlab.com/gitlab-org/gitlab/-/issues/223719
- get '/snippets/:id/raw',
- to: 'snippets#raw',
- format: false,
- constraints: { id: /\d+/ }
-
- Gitlab::Routing.redirect_legacy_paths(self, :snippets)
- end
+ draw :group
+
+ resources :projects, only: [:index, :new, :create]
+
+ get '/projects/:id' => 'projects/redirect#redirect_from_id'
+
+ draw :git_http
+ draw :api
+ draw :customers_dot
+ draw :sidekiq
+ draw :help
+ draw :google_api
+ draw :import
+ draw :uploads
+ draw :explore
+ draw :admin
+ draw :dashboard
+ draw :user
+ draw :project
+ draw :unmatched_project
+
+ # Issue https://gitlab.com/gitlab-org/gitlab/-/issues/210024
+ scope as: 'deprecated' do
+ # Issue https://gitlab.com/gitlab-org/gitlab/-/issues/223719
+ get '/snippets/:id/raw',
+ to: 'snippets#raw',
+ format: false,
+ constraints: { id: /\d+/ }
+
+ Gitlab::Routing.redirect_legacy_paths(self, :snippets)
+ end
- Gitlab.ee do
- get '/sitemap' => 'sitemap#show', format: :xml
- end
+ Gitlab.ee do
+ get '/sitemap' => 'sitemap#show', format: :xml
+ end
- # Creates shorthand helper methods for project resources.
- # For example; for the `namespace_project_path` this also creates `project_path`.
- #
- # TODO: We don't need the `Gitlab::Routing` module at all as we can use
- # the `direct` DSL method of Rails to define url helpers. Move all the
- # custom url helpers to use the `direct` DSL method and remove the `Gitlab::Routing`.
- # For more information: https://gitlab.com/gitlab-org/gitlab/-/issues/299583
- Gitlab::Application.routes.set.filter_map { |route| route.name if route.name&.include?('namespace_project') }.each do |name|
- new_name = name.sub('namespace_project', 'project')
-
- direct(new_name) do |project, *args|
- # This is due to a bug I've found in Rails.
- # For more information: https://gitlab.com/gitlab-org/gitlab/-/issues/299591
- args.pop if args.last == {}
-
- send("#{name}_url", project&.namespace, project, *args)
+ # Creates shorthand helper methods for project resources.
+ # For example; for the `namespace_project_path` this also creates `project_path`.
+ #
+ # TODO: We don't need the `Gitlab::Routing` module at all as we can use
+ # the `direct` DSL method of Rails to define url helpers. Move all the
+ # custom url helpers to use the `direct` DSL method and remove the `Gitlab::Routing`.
+ # For more information: https://gitlab.com/gitlab-org/gitlab/-/issues/299583
+ Gitlab::Application.routes.set.filter_map { |route| route.name if route.name&.include?('namespace_project') }.each do |name|
+ new_name = name.sub('namespace_project', 'project')
+
+ direct(new_name) do |project, *args|
+ # This is due to a bug I've found in Rails.
+ # For more information: https://gitlab.com/gitlab-org/gitlab/-/issues/299591
+ args.pop if args.last == {}
+
+ send("#{name}_url", project&.namespace, project, *args)
+ end
end
- end
- root to: "root#index"
+ root to: "root#index"
- get '*unmatched_route', to: 'application#route_not_found', format: false
-end
+ get '*unmatched_route', to: 'application#route_not_found', format: false
+ end
-Gitlab::Routing.add_helpers(TimeboxesRoutingHelper)
+ Gitlab::Routing.add_helpers(TimeboxesRoutingHelper)
+end
diff --git a/doc/api/dora/metrics.md b/doc/api/dora/metrics.md
index 510d40db2d7..99473ca7b4c 100644
--- a/doc/api/dora/metrics.md
+++ b/doc/api/dora/metrics.md
@@ -21,15 +21,15 @@ Get project-level DORA metrics.
GET /projects/:id/dora/metrics
```
-| Attribute | Type | Required | Description |
-|----------------------|------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../index.md#namespaced-path-encoding) can be accessed by the authenticated user. |
-| `metric` | string | yes | One of `deployment_frequency`, `lead_time_for_changes`, `time_to_restore_service` or `change_failure_rate`. |
-| `start_date` | string | no | Date range to start from. ISO 8601 Date format, for example `2021-03-01`. Default is 3 months ago. |
-| `end_date` | string | no | Date range to end at. ISO 8601 Date format, for example `2021-03-01`. Default is the current date. |
-| `interval` | string | no | The bucketing interval. One of `all`, `monthly` or `daily`. Default is `daily`. |
+| Attribute | Type | Required | Description |
+|:---------------------|:-----------------|:---------|:------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../index.md#namespaced-path-encoding) can be accessed by the authenticated user. |
+| `metric` | string | yes | One of `deployment_frequency`, `lead_time_for_changes`, `time_to_restore_service` or `change_failure_rate`. |
+| `end_date` | string | no | Date range to end at. ISO 8601 Date format, for example `2021-03-01`. Default is the current date. |
| `environment_tier` | string | no | The [tier of the environment](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. Deprecated, please use `environment_tiers`. |
-| `environment_tiers` | array of strings | no | The [tiers of the environments](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. |
+| `environment_tiers` | array of strings | no | The [tiers of the environments](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. |
+| `interval` | string | no | The bucketing interval. One of `all`, `monthly` or `daily`. Default is `daily`. |
+| `start_date` | string | no | Date range to start from. ISO 8601 Date format, for example `2021-03-01`. Default is 3 months ago. |
Example request:
@@ -62,15 +62,15 @@ Get group-level DORA metrics.
GET /groups/:id/dora/metrics
```
-| Attribute | Type | Required | Description |
-|---------------------|------------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../index.md#namespaced-path-encoding) can be accessed by the authenticated user. |
-| `metric` | string | yes | One of `deployment_frequency`, `lead_time_for_changes`, `time_to_restore_service` or `change_failure_rate`. |
-| `start_date` | string | no | Date range to start from. ISO 8601 Date format, for example `2021-03-01`. Default is 3 months ago. |
-| `end_date` | string | no | Date range to end at. ISO 8601 Date format, for example `2021-03-01`. Default is the current date. |
-| `interval` | string | no | The bucketing interval. One of `all`, `monthly` or `daily`. Default is `daily`. |
+| Attribute | Type | Required | Description |
+|:--------------------|:-----------------|:---------|:------------|
+| `id` | integer/string | yes | The ID or [URL-encoded path of the project](../index.md#namespaced-path-encoding) can be accessed by the authenticated user. |
+| `metric` | string | yes | One of `deployment_frequency`, `lead_time_for_changes`, `time_to_restore_service` or `change_failure_rate`. |
+| `end_date` | string | no | Date range to end at. ISO 8601 Date format, for example `2021-03-01`. Default is the current date. |
| `environment_tier` | string | no | The [tier of the environment](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. Deprecated, please use `environment_tiers`. |
-| `environment_tiers` | array of strings | no | The [tiers of the environments](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. |
+| `environment_tiers` | array of strings | no | The [tiers of the environments](../../ci/environments/index.md#deployment-tier-of-environments). Default is `production`. |
+| `interval` | string | no | The bucketing interval. One of `all`, `monthly` or `daily`. Default is `daily`. |
+| `start_date` | string | no | Date range to start from. ISO 8601 Date format, for example `2021-03-01`. Default is 3 months ago. |
Example request:
@@ -99,9 +99,9 @@ For both the project and group-level endpoints above, the `value` field in the
API response has a different meaning depending on the provided `metric` query
parameter:
-| `metric` query parameter | Description of `value` in response |
-| ------------------------ |--------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| `deployment_frequency` | The number of successful deployments during the time period. |
-| `lead_time_for_changes` | The median number of seconds between the merge of the merge request (MR) and the deployment of the MR's commits for all MRs deployed during the time period. |
-| `time_to_restore_service` | The median number of seconds an incident was open during the time period. Available only for production environment. |
-| `change_failure_rate` | The number of incidents divided by the number of deployments during the time period. Available only for production environment. |
+| `metric` query parameter | Description of `value` in response |
+|:---------------------------|:-----------------------------------|
+| `change_failure_rate` | The number of incidents divided by the number of deployments during the time period. Available only for production environment. |
+| `deployment_frequency` | The number of successful deployments during the time period. |
+| `lead_time_for_changes` | The median number of seconds between the merge of the merge request (MR) and the deployment of the MR's commits for all MRs deployed during the time period. |
+| `time_to_restore_service` | The median number of seconds an incident was open during the time period. Available only for production environment. |
diff --git a/doc/ci/yaml/index.md b/doc/ci/yaml/index.md
index 6d8ca7fe8cf..3bb2007d6e3 100644
--- a/doc/ci/yaml/index.md
+++ b/doc/ci/yaml/index.md
@@ -1099,6 +1099,8 @@ that use the same cache key use the same cache, including in different pipelines
If not set, the default key is `default`. All jobs with the `cache` keyword but
no `cache:key` share the `default` cache.
+Must be used with `cache: path`, or nothing is cached.
+
**Keyword type**: Job keyword. You can use it only as part of a job or in the
[`default` section](#default).
@@ -1263,6 +1265,8 @@ rspec:
Use `cache:when` to define when to save the cache, based on the status of the job.
+Must be used with `cache: path`, or nothing is cached.
+
**Keyword type**: Job keyword. You can use it only as part of a job or in the
[`default` section](#default).
@@ -1301,6 +1305,8 @@ Use the `pull` policy when you have many jobs executing in parallel that use the
This policy speeds up job execution and reduces load on the cache server. You can
use a job with the `push` policy to build the cache.
+Must be used with `cache: path`, or nothing is cached.
+
**Keyword type**: Job keyword. You can use it only as part of a job or in the
[`default` section](#default).
diff --git a/doc/development/cicd/templates.md b/doc/development/cicd/templates.md
index eafb1817a0a..4ea7a9d960c 100644
--- a/doc/development/cicd/templates.md
+++ b/doc/development/cicd/templates.md
@@ -289,9 +289,32 @@ Please read [versioning](#versioning) section for introducing breaking change sa
## Versioning
-Versioning allows you to introduce a new template without modifying the existing
-one. This process is useful when we need to introduce a breaking change,
-but don't want to affect the existing projects that depends on the current template.
+To introduce a breaking change without affecting the existing projects that depend on
+the current template, use [stable](#stable-version) and [latest](#latest-version) versioning.
+
+Stable templates usually only receive breaking changes in major version releases, while
+latest templates can receive breaking changes in any release. In major release milestones,
+the latest template is made the new stable template (and the latest template might be deleted).
+
+Adding a latest template is safe, but comes with a maintenance burden:
+
+- GitLab has to choose a DRI to overwrite the stable template with the contents of the
+ latest template at the next major release of GitLab. The DRI is responsible for
+ supporting users who have trouble with the change.
+- When we make a new non-breaking change, both the stable and latest templates must be updated
+ to match, as must as possible.
+- A latest template could remain for longer than planned because many users could
+ directly depend on it continuing to exist.
+
+Before adding a new latest template, see if the change can be made to the stable
+template instead, even if it's a breaking change. If the template is intended for copy-paste
+usage only, it might be possible to directly change the stable version. Before changing
+the stable template with a breaking change in a minor milestone, make sure:
+
+- It's a [pipeline template](#template-types) and it has a [code comment](#explain-requirements-and-expectations)
+ explaining that it's not designed to be used with the `includes`.
+- The [CI/CD template usage metrics](#add-metrics) doesn't show any usage. If the metrics
+ show zero usage for the template, the template is not actively being used with `include`.
### Stable version
@@ -393,7 +416,9 @@ is updated in a major version GitLab release.
### Add metrics
-Every CI/CD template must also have metrics defined to track their use. The CI/CD template monthly usage report can be found in [Sisense (GitLab team members only)](https://app.periscopedata.com/app/gitlab/785953/Pipeline-Authoring-Dashboard?widget=14910475&udv=0).
+Every CI/CD template must also have metrics defined to track their use. The CI/CD template monthly usage report
+can be found in [Sisense (GitLab team members only)](https://app.periscopedata.com/app/gitlab/785953/Pipeline-Authoring-Dashboard?widget=13440051&udv=0).
+Double click a template to see the graph for that single template.
To add a metric definition for a new template:
diff --git a/doc/development/rails_initializers.md b/doc/development/rails_initializers.md
index 68f3c07e45a..fca24cf8c01 100644
--- a/doc/development/rails_initializers.md
+++ b/doc/development/rails_initializers.md
@@ -29,12 +29,18 @@ query) from an initializer means that tasks like `db:drop`, and
`db:test:prepare` will fail because an active session prevents the database from
being dropped.
-To help detect when database connections are opened from initializers, we now
-warn in `STDERR`. For example:
+To prevent this, we stop database connections from being opened during
+routes loading. Doing will result in an error:
```shell
-DEPRECATION WARNING: Database connection should not be called during initializers (called from block in <module:HasVariable> at app/models/concerns/ci/has_variable.rb:22)
+RuntimeError:
+ Database connection should not be called during initializers.
+# ./config/initializers/00_connection_logger.rb:15:in `new_client'
+# ./lib/gitlab/database/load_balancing/load_balancer.rb:112:in `block in read_write'
+# ./lib/gitlab/database/load_balancing/load_balancer.rb:184:in `retry_with_backoff'
+# ./lib/gitlab/database/load_balancing/load_balancer.rb:111:in `read_write'
+# ./lib/gitlab/database/load_balancing/connection_proxy.rb:119:in `write_using_load_balancer'
+# ./lib/gitlab/database/load_balancing/connection_proxy.rb:89:in `method_missing'
+# ./config/routes.rb:10:in `block in <main>'
+# ./config/routes.rb:9:in `<main>'
```
-
-If you wish to print out the full backtrace, set the
-`DEBUG_INITIALIZER_CONNECTIONS` environment variable.
diff --git a/doc/user/project/merge_requests/approvals/img/mr_approvals_by_code_owners_v12_7.png b/doc/user/project/merge_requests/approvals/img/mr_approvals_by_code_owners_v12_7.png
deleted file mode 100644
index 669148a41d8..00000000000
--- a/doc/user/project/merge_requests/approvals/img/mr_approvals_by_code_owners_v12_7.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/approvals/img/mr_approvals_by_code_owners_v15_2.png b/doc/user/project/merge_requests/approvals/img/mr_approvals_by_code_owners_v15_2.png
new file mode 100644
index 00000000000..37dad4e5ae8
--- /dev/null
+++ b/doc/user/project/merge_requests/approvals/img/mr_approvals_by_code_owners_v15_2.png
Binary files differ
diff --git a/doc/user/project/merge_requests/approvals/rules.md b/doc/user/project/merge_requests/approvals/rules.md
index 21cf5cca4d1..b79c8ee867f 100644
--- a/doc/user/project/merge_requests/approvals/rules.md
+++ b/doc/user/project/merge_requests/approvals/rules.md
@@ -152,9 +152,9 @@ become eligible approvers in the project. To enable this merge request approval
1. Go to your project and select **Settings > General**.
1. Expand **Merge request (MR) approvals**.
-1. Locate **Eligible users** and select the number of approvals required:
+1. Locate **All eligible users** and select the number of approvals required:
- ![MR approvals by Code Owners](img/mr_approvals_by_code_owners_v12_7.png)
+![MR approvals by Code Owners](img/mr_approvals_by_code_owners_v15_2.png)
You can also
[require code owner approval](../../protected_branches.md#require-code-owner-approval-on-a-protected-branch)
diff --git a/doc/user/project/milestones/burndown_and_burnup_charts.md b/doc/user/project/milestones/burndown_and_burnup_charts.md
index 298eea8639c..0f36747a547 100644
--- a/doc/user/project/milestones/burndown_and_burnup_charts.md
+++ b/doc/user/project/milestones/burndown_and_burnup_charts.md
@@ -9,7 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
[Burndown](#burndown-charts) and [burnup](#burnup-charts) charts show the progress of completing a milestone.
-![burndown and burnup chart](img/burndown_and_burnup_charts_v15_1.png)
+![burndown and burnup chart](img/burndown_and_burnup_charts_v15_3.png)
## Burndown charts
@@ -19,7 +19,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
Burndown charts show the number of issues over the course of a milestone.
-![burndown chart](img/burndown_chart_v15_1.png)
+![burndown chart](img/burndown_chart_v15_3.png)
At a glance, you see the current state for the completion a given milestone.
Without them, you would have to organize the data from the milestone and plot it
@@ -106,7 +106,7 @@ Reopened issues are considered as having been opened on the day after they were
Burnup charts show the assigned and completed work for a milestone.
-![burnup chart](img/burnup_chart_v15_1.png)
+![burnup chart](img/burnup_chart_v15_3.png)
To view a project's burnup chart:
diff --git a/doc/user/project/milestones/img/burndown_and_burnup_charts_v15_1.png b/doc/user/project/milestones/img/burndown_and_burnup_charts_v15_1.png
deleted file mode 100644
index 58c0ddf892f..00000000000
--- a/doc/user/project/milestones/img/burndown_and_burnup_charts_v15_1.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/milestones/img/burndown_and_burnup_charts_v15_3.png b/doc/user/project/milestones/img/burndown_and_burnup_charts_v15_3.png
new file mode 100644
index 00000000000..1420123500c
--- /dev/null
+++ b/doc/user/project/milestones/img/burndown_and_burnup_charts_v15_3.png
Binary files differ
diff --git a/doc/user/project/milestones/img/burndown_chart_v15_1.png b/doc/user/project/milestones/img/burndown_chart_v15_1.png
deleted file mode 100644
index 2953380292d..00000000000
--- a/doc/user/project/milestones/img/burndown_chart_v15_1.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/milestones/img/burndown_chart_v15_3.png b/doc/user/project/milestones/img/burndown_chart_v15_3.png
new file mode 100644
index 00000000000..9e1c7ccd4dd
--- /dev/null
+++ b/doc/user/project/milestones/img/burndown_chart_v15_3.png
Binary files differ
diff --git a/doc/user/project/milestones/img/burnup_chart_v15_1.png b/doc/user/project/milestones/img/burnup_chart_v15_1.png
deleted file mode 100644
index e89b76344ed..00000000000
--- a/doc/user/project/milestones/img/burnup_chart_v15_1.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/milestones/img/burnup_chart_v15_3.png b/doc/user/project/milestones/img/burnup_chart_v15_3.png
new file mode 100644
index 00000000000..2e85c0abe87
--- /dev/null
+++ b/doc/user/project/milestones/img/burnup_chart_v15_3.png
Binary files differ
diff --git a/doc/user/project/milestones/index.md b/doc/user/project/milestones/index.md
index 3ecee86b978..ba48876d4fd 100644
--- a/doc/user/project/milestones/index.md
+++ b/doc/user/project/milestones/index.md
@@ -196,7 +196,7 @@ There are also tabs below these that show the following:
The milestone view contains a [burndown and burnup chart](burndown_and_burnup_charts.md),
showing the progress of completing a milestone.
-![burndown chart](img/burndown_and_burnup_charts_v15_1.png)
+![burndown chart](img/burndown_and_burnup_charts_v15_3.png)
### Milestone sidebar
diff --git a/lib/api/users.rb b/lib/api/users.rb
index d089ce1b499..d66d86a9055 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -1284,3 +1284,5 @@ module API
end
end
end
+
+API::Users.prepend_mod
diff --git a/lib/gitlab/ci/templates/Bash.gitlab-ci.yml b/lib/gitlab/ci/templates/Bash.gitlab-ci.yml
index f39a84bceec..004c2897b60 100644
--- a/lib/gitlab/ci/templates/Bash.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Bash.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/C++.gitlab-ci.yml b/lib/gitlab/ci/templates/C++.gitlab-ci.yml
index c078c99f352..3096af1b173 100644
--- a/lib/gitlab/ci/templates/C++.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/C++.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/Chef.gitlab-ci.yml b/lib/gitlab/ci/templates/Chef.gitlab-ci.yml
index f166da9bdd6..a64f87193a9 100644
--- a/lib/gitlab/ci/templates/Chef.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Chef.gitlab-ci.yml
@@ -1,14 +1,17 @@
-# To contribute improvements to CI/CD templates, please follow the Development guide at:
-# https://docs.gitlab.com/ee/development/cicd/templates.html
-# This specific template is located at:
-# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Chef.gitlab-ci.yml
-
# This template uses Test Kitchen with the kitchen-dokken driver to
# perform functional testing. Doing so requires that your runner be a
# Docker runner configured for privileged mode. Please see
# https://docs.gitlab.com/runner/executors/docker.html#use-docker-in-docker-with-privileged-mode
# for help configuring your runner properly, or, if you want to switch
# to a different driver, see http://kitchen.ci/docs/drivers
+#
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
+# To contribute improvements to CI/CD templates, please follow the Development guide at:
+# https://docs.gitlab.com/ee/development/cicd/templates.html
+# This specific template is located at:
+# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Chef.gitlab-ci.yml
image: "chef/chefdk"
services:
diff --git a/lib/gitlab/ci/templates/Clojure.gitlab-ci.yml b/lib/gitlab/ci/templates/Clojure.gitlab-ci.yml
index 0f9e28c9a8e..4fe37ceaeaa 100644
--- a/lib/gitlab/ci/templates/Clojure.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Clojure.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml b/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml
index 8886929646d..68b55b782cd 100644
--- a/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Crystal.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/Dart.gitlab-ci.yml b/lib/gitlab/ci/templates/Dart.gitlab-ci.yml
index 6354db38f58..35401e62fe2 100644
--- a/lib/gitlab/ci/templates/Dart.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Dart.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml b/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml
index 1eb920c7747..83ddce936e6 100644
--- a/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Elixir.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/Flutter.gitlab-ci.yml b/lib/gitlab/ci/templates/Flutter.gitlab-ci.yml
index a5c261e367a..021662ab416 100644
--- a/lib/gitlab/ci/templates/Flutter.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Flutter.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml b/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
index 21a599fc78d..464b81965f2 100644
--- a/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
@@ -1,8 +1,3 @@
-# To contribute improvements to CI/CD templates, please follow the Development guide at:
-# https://docs.gitlab.com/ee/development/cicd/templates.html
-# This specific template is located at:
-# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
-
# This is a sample GitLab CI/CD configuration file that should run without any modifications.
# It demonstrates a basic 3 stage CI/CD pipeline. Instead of real tests or scripts,
# it uses echo commands to simulate the pipeline execution.
@@ -11,6 +6,14 @@
# Stages run in sequential order, but jobs within stages run in parallel.
#
# For more information, see: https://docs.gitlab.com/ee/ci/yaml/index.html#stages
+#
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
+# To contribute improvements to CI/CD templates, please follow the Development guide at:
+# https://docs.gitlab.com/ee/development/cicd/templates.html
+# This specific template is located at:
+# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Getting-Started.gitlab-ci.yml
stages: # List of stages for jobs, and their order of execution
- build
diff --git a/lib/gitlab/ci/templates/Go.gitlab-ci.yml b/lib/gitlab/ci/templates/Go.gitlab-ci.yml
index bd8e1020c4e..603aede4d46 100644
--- a/lib/gitlab/ci/templates/Go.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Go.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/Grails.gitlab-ci.yml b/lib/gitlab/ci/templates/Grails.gitlab-ci.yml
index 7e59354c4a1..03c8941169f 100644
--- a/lib/gitlab/ci/templates/Grails.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Grails.gitlab-ci.yml
@@ -1,8 +1,3 @@
-# To contribute improvements to CI/CD templates, please follow the Development guide at:
-# https://docs.gitlab.com/ee/development/cicd/templates.html
-# This specific template is located at:
-# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Grails.gitlab-ci.yml
-
# This template uses the java:8 docker image because there isn't any
# official Grails image at this moment
#
@@ -12,6 +7,14 @@
# Feel free to change GRAILS_VERSION version with your project version (3.0.1, 3.1.1,...)
# Feel free to change GRADLE_VERSION version with your gradle project version (2.13, 2.14,...)
# If you use Angular profile, this yml it's prepared to work with it
+#
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
+# To contribute improvements to CI/CD templates, please follow the Development guide at:
+# https://docs.gitlab.com/ee/development/cicd/templates.html
+# This specific template is located at:
+# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Grails.gitlab-ci.yml
image: java:8
diff --git a/lib/gitlab/ci/templates/Julia.gitlab-ci.yml b/lib/gitlab/ci/templates/Julia.gitlab-ci.yml
index 4687a07d05b..34084272b29 100644
--- a/lib/gitlab/ci/templates/Julia.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Julia.gitlab-ci.yml
@@ -1,8 +1,3 @@
-# To contribute improvements to CI/CD templates, please follow the Development guide at:
-# https://docs.gitlab.com/ee/development/cicd/templates.html
-# This specific template is located at:
-# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Julia.gitlab-ci.yml
-
# This is an example .gitlab-ci.yml file to test (and optionally report the coverage
# results of) your [Julia][1] packages. Please refer to the [documentation][2]
# for more information about package development in Julia.
@@ -12,6 +7,14 @@
#
# [1]: http://julialang.org/
# [2]: https://docs.julialang.org/en/v1/manual/documentation/index.html
+#
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
+# To contribute improvements to CI/CD templates, please follow the Development guide at:
+# https://docs.gitlab.com/ee/development/cicd/templates.html
+# This specific template is located at:
+# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Julia.gitlab-ci.yml
# Below is the template to run your tests in Julia
.test_template: &test_definition
diff --git a/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml b/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml
index 0ec67526234..3a490012f3d 100644
--- a/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Laravel.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/Mono.gitlab-ci.yml b/lib/gitlab/ci/templates/Mono.gitlab-ci.yml
index 2f214347ec3..65db649e22f 100644
--- a/lib/gitlab/ci/templates/Mono.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Mono.gitlab-ci.yml
@@ -1,8 +1,3 @@
-# To contribute improvements to CI/CD templates, please follow the Development guide at:
-# https://docs.gitlab.com/ee/development/cicd/templates.html
-# This specific template is located at:
-# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Mono.gitlab-ci.yml
-
# This is a simple gitlab continuous integration template (compatible with the shared runner provided on gitlab.com)
# using the official mono docker image to build a visual studio project.
#
@@ -15,6 +10,14 @@
#
# Please find the full example project here:
# https://gitlab.com/tobiaskoch/gitlab-ci-example-mono
+#
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
+# To contribute improvements to CI/CD templates, please follow the Development guide at:
+# https://docs.gitlab.com/ee/development/cicd/templates.html
+# This specific template is located at:
+# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Mono.gitlab-ci.yml
# see https://hub.docker.com/_/mono/
image: mono:latest
diff --git a/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml b/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml
index 44370f896a7..7a4f7ed628b 100644
--- a/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Nodejs.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/OpenShift.gitlab-ci.yml b/lib/gitlab/ci/templates/OpenShift.gitlab-ci.yml
index 7c8bbe464af..0eb3b483067 100644
--- a/lib/gitlab/ci/templates/OpenShift.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/OpenShift.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/PHP.gitlab-ci.yml b/lib/gitlab/ci/templates/PHP.gitlab-ci.yml
index 4edc003a638..12640d28d29 100644
--- a/lib/gitlab/ci/templates/PHP.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/PHP.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml b/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
index 690a5a291e1..aab408aa830 100644
--- a/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Ruby.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/Rust.gitlab-ci.yml b/lib/gitlab/ci/templates/Rust.gitlab-ci.yml
index dafe3ca7bc7..a83f84da818 100644
--- a/lib/gitlab/ci/templates/Rust.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Rust.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/Scala.gitlab-ci.yml b/lib/gitlab/ci/templates/Scala.gitlab-ci.yml
index de54d64dc42..26efe7a8908 100644
--- a/lib/gitlab/ci/templates/Scala.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Scala.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/Swift.gitlab-ci.yml b/lib/gitlab/ci/templates/Swift.gitlab-ci.yml
index eedb3b7a310..3c4533d603e 100644
--- a/lib/gitlab/ci/templates/Swift.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/Swift.gitlab-ci.yml
@@ -1,3 +1,6 @@
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+#
# To contribute improvements to CI/CD templates, please follow the Development guide at:
# https://docs.gitlab.com/ee/development/cicd/templates.html
# This specific template is located at:
diff --git a/lib/gitlab/ci/templates/dotNET.gitlab-ci.yml b/lib/gitlab/ci/templates/dotNET.gitlab-ci.yml
index 841f17767eb..50ce181095e 100644
--- a/lib/gitlab/ci/templates/dotNET.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/dotNET.gitlab-ci.yml
@@ -23,6 +23,9 @@
# You need to have the network drive mapped as Local System user for gitlab-runner service to see it
# The best way to persist the mapping is via a scheduled task
# running the following batch command: net use P: \\x.x.x.x\Projects /u:your_user your_pass /persistent:yes
+#
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
# place project specific paths in variables to make the rest of the script more generic
variables:
diff --git a/lib/gitlab/ci/templates/iOS-Fastlane.gitlab-ci.yml b/lib/gitlab/ci/templates/iOS-Fastlane.gitlab-ci.yml
index 0b75c298167..58e840da713 100644
--- a/lib/gitlab/ci/templates/iOS-Fastlane.gitlab-ci.yml
+++ b/lib/gitlab/ci/templates/iOS-Fastlane.gitlab-ci.yml
@@ -1,8 +1,3 @@
-# To contribute improvements to CI/CD templates, please follow the Development guide at:
-# https://docs.gitlab.com/ee/development/cicd/templates.html
-# This specific template is located at:
-# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/iOS-Fastlane.gitlab-ci.yml
-
# This is a very simple template that mainly relies on FastLane to build and distribute your app.
# Read more about how to use this template on the blog post https://about.gitlab.com/2019/03/06/ios-publishing-with-gitlab-and-fastlane/
# You will also need fastlane and signing configuration for this to work, along with a MacOS runner.
@@ -15,6 +10,14 @@
# https://docs.gitlab.com/runner/security/#usage-of-shell-executor for additional
# detail on what to keep in mind in this scenario.
+# You can copy and paste this template into a new `.gitlab-ci.yml` file.
+# You should not add this template to an existing `.gitlab-ci.yml` file by using the `include:` keyword.
+
+# To contribute improvements to CI/CD templates, please follow the Development guide at:
+# https://docs.gitlab.com/ee/development/cicd/templates.html
+# This specific template is located at:
+# https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/iOS-Fastlane.gitlab-ci.yml
+
stages:
- build
- test
diff --git a/lib/initializer_connections.rb b/lib/initializer_connections.rb
new file mode 100644
index 00000000000..c8a6bb6c511
--- /dev/null
+++ b/lib/initializer_connections.rb
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+
+module InitializerConnections
+ # Prevents any database connections within the block
+ # by using an empty connection handler
+ # rubocop:disable Database/MultipleDatabases
+ def self.with_disabled_database_connections
+ return yield if Gitlab::Utils.to_boolean(ENV['SKIP_RAISE_ON_INITIALIZE_CONNECTIONS'])
+
+ original_handler = ActiveRecord::Base.connection_handler
+
+ dummy_handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
+ ActiveRecord::Base.connection_handler = dummy_handler
+
+ yield
+
+ if dummy_handler&.connection_pool_names&.present?
+ raise "Unxpected connection_pools (#{dummy_handler.connection_pool_names}) ! Call `connects_to` before this block"
+ end
+ rescue ActiveRecord::ConnectionNotEstablished
+ message = "Database connection should not be called during initializers. Read more at https://docs.gitlab.com/ee/development/rails_initializers.html#database-connections-in-initializers"
+
+ raise message
+ ensure
+ ActiveRecord::Base.connection_handler = original_handler
+ dummy_handler&.clear_all_connections!
+ end
+ # rubocop:enable Database/MultipleDatabases
+end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 035792e23df..b5422614ca9 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -3758,6 +3758,9 @@ msgstr ""
msgid "All changes are committed"
msgstr ""
+msgid "All eligible users"
+msgstr ""
+
msgid "All email addresses will be used to identify your commits."
msgstr ""
@@ -14125,9 +14128,6 @@ msgstr ""
msgid "Elastic|None. Select projects to index."
msgstr ""
-msgid "Eligible users"
-msgstr ""
-
msgid "Email"
msgstr ""
@@ -21916,6 +21916,9 @@ msgstr ""
msgid "Iterations|All"
msgstr ""
+msgid "Iterations|Automatic scheduling"
+msgstr ""
+
msgid "Iterations|Cadence configuration is invalid."
msgstr ""
@@ -21937,6 +21940,9 @@ msgstr ""
msgid "Iterations|Create iteration"
msgstr ""
+msgid "Iterations|Create iterations automatically on a regular schedule."
+msgstr ""
+
msgid "Iterations|Delete cadence"
msgstr ""
@@ -21967,6 +21973,9 @@ msgstr ""
msgid "Iterations|Edit iteration cadence"
msgstr ""
+msgid "Iterations|Enable roll over"
+msgstr ""
+
msgid "Iterations|Error loading iteration cadences."
msgstr ""
@@ -21979,6 +21988,9 @@ msgstr ""
msgid "Iterations|Iterations are a way to track issues over a period of time, allowing teams to also track velocity and volatility metrics."
msgstr ""
+msgid "Iterations|Iterations are scheduled to start on %{weekday}s."
+msgstr ""
+
msgid "Iterations|Learn more about automatic scheduling"
msgstr ""
@@ -22006,9 +22018,6 @@ msgstr ""
msgid "Iterations|No iterations in cadence."
msgstr ""
-msgid "Iterations|No one can change this date after the cadence has begun."
-msgstr ""
-
msgid "Iterations|No open iterations."
msgstr ""
@@ -23225,7 +23234,7 @@ msgstr ""
msgid "License Compliance"
msgstr ""
-msgid "License Compliance| Used by"
+msgid "License Compliance| Used by %{dependencies}"
msgstr ""
msgid "License compliance"
@@ -38225,9 +38234,6 @@ msgstr ""
msgid "Task list"
msgstr ""
-msgid "Task with ID: %{id} could not be found."
-msgstr ""
-
msgid "TasksToBeDone|Create/import code into a project (repository)"
msgstr ""
@@ -42054,6 +42060,11 @@ msgstr ""
msgid "Used"
msgstr ""
+msgid "Used by %d package"
+msgid_plural "Used by %d packages"
+msgstr[0] ""
+msgstr[1] ""
+
msgid "Used by members to sign in to your group in GitLab"
msgstr ""
diff --git a/scripts/process_custom_semgrep_results.sh b/scripts/process_custom_semgrep_results.sh
index 1fdd8e486f3..8370c95efca 100755
--- a/scripts/process_custom_semgrep_results.sh
+++ b/scripts/process_custom_semgrep_results.sh
@@ -5,7 +5,7 @@ echo "Processing vuln report"
# Preparing the message for the comment that will be posted by the bot
# Empty string if there are no findings
jq -crM '.vulnerabilities |
- map( select( .identifiers[0].name | test( "glappsec_" ) ) |
+ map( select( .identifiersprocess_custom_semgrep_results[0].name | test( "glappsec_" ) ) |
"- `" + .location.file + "` line " + ( .location.start_line | tostring ) +
(
if .location.start_line = .location.end_line then ""
diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb
index e4a7a2fc410..b4d4e01e972 100644
--- a/spec/controllers/search_controller_spec.rb
+++ b/spec/controllers/search_controller_spec.rb
@@ -408,10 +408,11 @@ RSpec.describe SearchController do
expect(payload[:metadata]['meta.search.filters.confidential']).to eq('true')
expect(payload[:metadata]['meta.search.filters.state']).to eq('true')
expect(payload[:metadata]['meta.search.project_ids']).to eq(%w(456 789))
- expect(payload[:metadata]['meta.search.search_level']).to eq('multi-project')
+ expect(payload[:metadata]['meta.search.type']).to eq('basic')
+ expect(payload[:metadata]['meta.search.level']).to eq('global')
end
- get :show, params: { scope: 'issues', search: 'hello world', group_id: '123', project_id: '456', project_ids: %w(456 789), search_level: 'multi-project', confidential: true, state: true, force_search_results: true }
+ get :show, params: { scope: 'issues', search: 'hello world', group_id: '123', project_id: '456', project_ids: %w(456 789), confidential: true, state: true, force_search_results: true }
end
it 'appends the default scope in meta.search.scope' do
@@ -423,6 +424,16 @@ RSpec.describe SearchController do
get :show, params: { search: 'hello world', group_id: '123', project_id: '456' }
end
+
+ it 'appends the search time based on the search' do
+ expect(controller).to receive(:append_info_to_payload).and_wrap_original do |method, payload|
+ method.call(payload)
+
+ expect(payload[:metadata][:global_search_duration_s]).to be_a_kind_of(Numeric)
+ end
+
+ get :show, params: { search: 'hello world', group_id: '123', project_id: '456' }
+ end
end
context 'abusive searches', :aggregate_failures do
diff --git a/spec/features/merge_request/user_sees_versions_spec.rb b/spec/features/merge_request/user_sees_versions_spec.rb
index 4465d7e29be..2c2a2dfd4a8 100644
--- a/spec/features/merge_request/user_sees_versions_spec.rb
+++ b/spec/features/merge_request/user_sees_versions_spec.rb
@@ -24,23 +24,21 @@ RSpec.describe 'Merge request > User sees versions', :js do
visit diffs_project_merge_request_path(project, merge_request, params)
end
- shared_examples 'allows commenting' do |file_id:, line_code:, comment:|
+ shared_examples 'allows commenting' do |file_name:, line_text:, comment:|
it do
- diff_file_selector = ".diff-file[id='#{file_id}']"
- line_code = "#{file_id}_#{line_code}"
+ page.within find_by_scrolling('.diff-file', text: file_name) do
+ line_code_element = page.find('.diff-grid-row', text: line_text)
- page.within find_by_scrolling(diff_file_selector) do
- line_code_element = first("[id='#{line_code}']")
# scrolling to element's bottom is required in order for .hover action to work
# otherwise, the element could be hidden underneath a sticky header
scroll_to_elements_bottom(line_code_element)
line_code_element.hover
- first("[id='#{line_code}'] [role='button']").click
+ page.find("[data-testid='left-comment-button']", visible: true).click
- page.within("form[data-line-code='#{line_code}']") do
- fill_in "note[note]", with: comment
- click_button('Add comment now')
- end
+ expect(page).to have_selector("form", count: 1)
+
+ fill_in("note[note]", with: comment)
+ click_button('Add comment now')
wait_for_requests
@@ -59,8 +57,8 @@ RSpec.describe 'Merge request > User sees versions', :js do
end
it_behaves_like 'allows commenting',
- file_id: '7445606fbf8f3683cd42bdc54b05d7a0bc2dfc44',
- line_code: '1_1',
+ file_name: '.gitmodules',
+ line_text: '[submodule "six"]',
comment: 'Typo, please fix.'
end
@@ -107,8 +105,8 @@ RSpec.describe 'Merge request > User sees versions', :js do
end
it_behaves_like 'allows commenting',
- file_id: '7445606fbf8f3683cd42bdc54b05d7a0bc2dfc44',
- line_code: '2_2',
+ file_name: '.gitmodules',
+ line_text: 'path = six',
comment: 'Typo, please fix.'
end
@@ -174,9 +172,9 @@ RSpec.describe 'Merge request > User sees versions', :js do
end
it_behaves_like 'allows commenting',
- file_id: '7445606fbf8f3683cd42bdc54b05d7a0bc2dfc44',
- line_code: '4_4',
- comment: 'Typo, please fix.'
+ file_name: '.gitmodules',
+ line_text: '[submodule "gitlab-shell"]',
+ comment: 'Typo, please fix.'
end
describe 'compare with same version' do
@@ -241,8 +239,8 @@ RSpec.describe 'Merge request > User sees versions', :js do
end
it_behaves_like 'allows commenting',
- file_id: '2f6fcd96b88b36ce98c38da085c795a27d92a3dd',
- line_code: '6_6',
+ file_name: 'files/ruby/popen.rb',
+ line_text: 'RuntimeError',
comment: 'Typo, please fix.'
end
end
diff --git a/spec/frontend/work_items/components/work_item_assignees_spec.js b/spec/frontend/work_items/components/work_item_assignees_spec.js
index 591102fb572..299949a4baa 100644
--- a/spec/frontend/work_items/components/work_item_assignees_spec.js
+++ b/spec/frontend/work_items/components/work_item_assignees_spec.js
@@ -4,13 +4,14 @@ import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { mountExtended } from 'helpers/vue_test_utils_helper';
+import { mockTracking } from 'helpers/tracking_helper';
import { stripTypenames } from 'helpers/graphql_helpers';
import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants';
import userSearchQuery from '~/graphql_shared/queries/users_search.query.graphql';
import currentUserQuery from '~/graphql_shared/queries/current_user.query.graphql';
import workItemQuery from '~/work_items/graphql/work_item.query.graphql';
import WorkItemAssignees from '~/work_items/components/work_item_assignees.vue';
-import { i18n } from '~/work_items/constants';
+import { i18n, TASK_TYPE_NAME, TRACKING_CATEGORY_SHOW } from '~/work_items/constants';
import { temporaryConfig, resolvers } from '~/work_items/graphql/provider';
import {
projectMembersResponseWithCurrentUser,
@@ -50,6 +51,7 @@ describe('WorkItemAssignees component', () => {
searchQueryHandler = successSearchQueryHandler,
currentUserQueryHandler = successCurrentUserQueryHandler,
allowsMultipleAssignees = true,
+ canUpdate = true,
} = {}) => {
const apolloProvider = createMockApollo(
[
@@ -78,6 +80,8 @@ describe('WorkItemAssignees component', () => {
assignees,
workItemId,
allowsMultipleAssignees,
+ workItemType: TASK_TYPE_NAME,
+ canUpdate,
},
attachTo: document.body,
apolloProvider,
@@ -125,6 +129,18 @@ describe('WorkItemAssignees component', () => {
expect(findTokenSelector().props('selectedTokens')).toEqual([mockAssignees[0]]);
});
+ it('passes `false` to `viewOnly` token selector prop if user can update assignees', () => {
+ createComponent();
+
+ expect(findTokenSelector().props('viewOnly')).toBe(false);
+ });
+
+ it('passes `true` to `viewOnly` token selector prop if user can not update assignees', () => {
+ createComponent({ canUpdate: false });
+
+ expect(findTokenSelector().props('viewOnly')).toBe(true);
+ });
+
describe('when searching for users', () => {
beforeEach(() => {
createComponent();
@@ -357,4 +373,36 @@ describe('WorkItemAssignees component', () => {
expect(findTokenSelector().props('containerClass')).toBe('gl-shadow-none!');
});
});
+
+ describe('tracking', () => {
+ let trackingSpy;
+
+ beforeEach(() => {
+ createComponent();
+ trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
+ });
+
+ afterEach(() => {
+ trackingSpy = null;
+ });
+
+ it('does not track updating assignees until token selector blur event', async () => {
+ findTokenSelector().vm.$emit('input', [mockAssignees[0]]);
+ await waitForPromises();
+
+ expect(trackingSpy).not.toHaveBeenCalled();
+ });
+
+ it('tracks editing the assignees on token selector blur', async () => {
+ findTokenSelector().vm.$emit('input', [mockAssignees[0]]);
+ findTokenSelector().vm.$emit('blur', new FocusEvent({ relatedTarget: null }));
+ await waitForPromises();
+
+ expect(trackingSpy).toHaveBeenCalledWith(TRACKING_CATEGORY_SHOW, 'updated_assignees', {
+ category: TRACKING_CATEGORY_SHOW,
+ label: 'item_assignees',
+ property: 'type_Task',
+ });
+ });
+ });
});
diff --git a/spec/initializers/00_connection_logger_spec.rb b/spec/initializers/00_connection_logger_spec.rb
deleted file mode 100644
index 8b288b463c4..00000000000
--- a/spec/initializers/00_connection_logger_spec.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-RSpec.describe ActiveRecord::ConnectionAdapters::PostgreSQLAdapter do # rubocop:disable RSpec/FilePath
- before do
- allow(PG).to receive(:connect)
- end
-
- let(:conn_params) { PG::Connection.conndefaults_hash }
-
- context 'when warn_on_new_connection is enabled' do
- before do
- described_class.warn_on_new_connection = true
- end
-
- it 'warns on new connection' do
- expect(ActiveSupport::Deprecation)
- .to receive(:warn).with(/Database connection should not be called during initializers/, anything)
-
- expect(PG).to receive(:connect).with(conn_params)
-
- described_class.new_client(conn_params)
- end
- end
-
- context 'when warn_on_new_connection is disabled' do
- before do
- described_class.warn_on_new_connection = false
- end
-
- it 'does not warn on new connection' do
- expect(ActiveSupport::Deprecation).not_to receive(:warn)
- expect(PG).to receive(:connect).with(conn_params)
-
- described_class.new_client(conn_params)
- end
- end
-end
diff --git a/spec/lib/initializer_connections_spec.rb b/spec/lib/initializer_connections_spec.rb
new file mode 100644
index 00000000000..4ca283c4f22
--- /dev/null
+++ b/spec/lib/initializer_connections_spec.rb
@@ -0,0 +1,63 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe InitializerConnections do
+ describe '.with_disabled_database_connections', :reestablished_active_record_base do
+ def block_with_database_call
+ described_class.with_disabled_database_connections do
+ Project.first
+ end
+ end
+
+ def block_with_error
+ described_class.with_disabled_database_connections do
+ raise "oops, an error"
+ end
+ end
+
+ it 'prevents any database connection within the block' do
+ expect { block_with_database_call }.to raise_error(/Database connection should not be called during initializer/)
+ end
+
+ it 'does not prevent database connection if SKIP_RAISE_ON_INITIALIZE_CONNECTIONS is set' do
+ stub_env('SKIP_RAISE_ON_INITIALIZE_CONNECTIONS', '1')
+
+ expect { block_with_database_call }.not_to raise_error
+ end
+
+ it 'prevents any database connection if SKIP_RAISE_ON_INITIALIZE_CONNECTIONS is false' do
+ stub_env('SKIP_RAISE_ON_INITIALIZE_CONNECTIONS', 'false')
+
+ expect { block_with_database_call }.to raise_error(/Database connection should not be called during initializer/)
+ end
+
+ it 'restores original connection handler' do
+ # rubocop:disable Database/MultipleDatabases
+ original_handler = ActiveRecord::Base.connection_handler
+
+ expect { block_with_database_call }.to raise_error(/Database connection should not be called during initializer/)
+
+ expect(ActiveRecord::Base.connection_handler).to eq(original_handler)
+ # rubocop:enabled Database/MultipleDatabases
+ end
+
+ it 'restores original connection handler even there is an error' do
+ # rubocop:disable Database/MultipleDatabases
+ original_handler = ActiveRecord::Base.connection_handler
+
+ expect { block_with_error }.to raise_error(/an error/)
+
+ expect(ActiveRecord::Base.connection_handler).to eq(original_handler)
+ # rubocop:enabled Database/MultipleDatabases
+ end
+
+ it 'raises if any new connection_pools are established in the block' do
+ expect do
+ described_class.with_disabled_database_connections do
+ ApplicationRecord.connects_to database: { writing: :main, reading: :main }
+ end
+ end.to raise_error(/Unxpected connection_pools/)
+ end
+ end
+end
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 5a50ce0911f..081fa6cbbae 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -3953,7 +3953,21 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
context 'when pipeline status is running' do
let(:pipeline) { create(:ci_pipeline, :running) }
- it { is_expected.to be_falsey }
+ context 'with mr_show_reports_immediately flag enabled' do
+ before do
+ stub_feature_flags(mr_show_reports_immediately: project)
+ end
+
+ it { expect(subject).to be_truthy }
+ end
+
+ context 'with mr_show_reports_immediately flag disabled' do
+ before do
+ stub_feature_flags(mr_show_reports_immediately: false)
+ end
+
+ it { expect(subject).to be_falsey }
+ end
end
context 'when pipeline status is success' do
@@ -4027,7 +4041,21 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep do
context 'when pipeline status is running' do
let(:pipeline) { create(:ci_pipeline, :running) }
- it { expect(subject).to be_falsey }
+ context 'with mr_show_reports_immediately flag enabled' do
+ before do
+ stub_feature_flags(mr_show_reports_immediately: project)
+ end
+
+ it { expect(subject).to be_truthy }
+ end
+
+ context 'with mr_show_reports_immediately flag disabled' do
+ before do
+ stub_feature_flags(mr_show_reports_immediately: false)
+ end
+
+ it { expect(subject).to be_falsey }
+ end
end
context 'when pipeline status is success' do
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index de478edf96a..664cdb27290 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -1884,6 +1884,14 @@ RSpec.describe Namespace do
end
end
+ describe '#emails_enabled?' do
+ it "is the opposite of emails_disabled" do
+ group = create(:group, emails_disabled: false)
+
+ expect(group.emails_enabled?).to be_truthy
+ end
+ end
+
describe '#pages_virtual_domain' do
let(:project) { create(:project, namespace: namespace) }
let(:virtual_domain) { namespace.pages_virtual_domain }
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 74a4a023a20..2171ee752fd 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -3595,6 +3595,14 @@ RSpec.describe Project, factory_default: :keep do
end
end
+ describe '#emails_enabled?' do
+ let(:project) { build(:project, emails_disabled: false) }
+
+ it "is the opposite of emails_disabled" do
+ expect(project.emails_enabled?).to be_truthy
+ end
+ end
+
describe '#lfs_enabled?' do
let(:namespace) { create(:namespace) }
let(:project) { build(:project, namespace: namespace) }
diff --git a/spec/requests/api/graphql/mutations/work_items/create_spec.rb b/spec/requests/api/graphql/mutations/work_items/create_spec.rb
index 3496ab38ee8..911568bc39f 100644
--- a/spec/requests/api/graphql/mutations/work_items/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/work_items/create_spec.rb
@@ -136,6 +136,20 @@ RSpec.describe 'Create a work item' do
end
end
end
+
+ context 'when unsupported widget input is sent' do
+ let(:input) do
+ {
+ 'title' => 'new title',
+ 'description' => 'new description',
+ 'workItemTypeId' => WorkItems::Type.default_by_type(:test_case).to_global_id.to_s,
+ 'hierarchyWidget' => {}
+ }
+ end
+
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: ['Following widget keys are not supported by Test Case type: [:hierarchy_widget]']
+ end
end
context 'when the work_items feature flag is disabled' do
diff --git a/spec/requests/api/graphql/mutations/work_items/update_spec.rb b/spec/requests/api/graphql/mutations/work_items/update_spec.rb
index b5f0eb7fbf6..77f7b9bacef 100644
--- a/spec/requests/api/graphql/mutations/work_items/update_spec.rb
+++ b/spec/requests/api/graphql/mutations/work_items/update_spec.rb
@@ -71,6 +71,20 @@ RSpec.describe 'Update a work item' do
end
end
+ context 'when unsupported widget input is sent' do
+ let_it_be(:test_case) { create(:work_item_type, :default, :test_case, name: 'some_test_case_name') }
+ let_it_be(:work_item) { create(:work_item, work_item_type: test_case, project: project) }
+
+ let(:input) do
+ {
+ 'hierarchyWidget' => {}
+ }
+ end
+
+ it_behaves_like 'a mutation that returns top-level errors',
+ errors: ["Following widget keys are not supported by some_test_case_name type: [:hierarchy_widget]"]
+ end
+
it_behaves_like 'has spam protection' do
let(:mutation_class) { ::Mutations::WorkItems::Update }
end
@@ -295,6 +309,19 @@ RSpec.describe 'Update a work item' do
end
end
+ context 'when there is a mix of existing and non existing work items' do
+ let(:children_ids) { [valid_child1.to_global_id.to_s, "gid://gitlab/WorkItem/#{non_existing_record_id}"] }
+
+ it 'returns a top level error and does not add valid work item' do
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ work_item.reload
+ end.not_to change(work_item.work_item_children, :count)
+
+ expect(graphql_errors.first['message']).to include('No object found for `childrenIds')
+ end
+ end
+
context 'when child work item type is valid' do
let(:children_ids) { [valid_child1.to_global_id.to_s, valid_child2.to_global_id.to_s] }
diff --git a/spec/services/work_items/parent_links/create_service_spec.rb b/spec/services/work_items/parent_links/create_service_spec.rb
index a2f695900ae..85b0ee040cd 100644
--- a/spec/services/work_items/parent_links/create_service_spec.rb
+++ b/spec/services/work_items/parent_links/create_service_spec.rb
@@ -49,19 +49,19 @@ RSpec.describe WorkItems::ParentLinks::CreateService do
end
context 'when work item not found' do
- let(:params) { { issuable_references: [invalid_task.id] } }
+ let(:params) { { issuable_references: [invalid_task] } }
it_behaves_like 'returns not found error'
end
context 'when user has no permission to link work items' do
- let(:params) { { issuable_references: [guest_task.id] } }
+ let(:params) { { issuable_references: [guest_task] } }
it_behaves_like 'returns not found error'
end
context 'child and parent are the same work item' do
- let(:params) { { issuable_references: [work_item.id] } }
+ let(:params) { { issuable_references: [work_item] } }
it 'no relationship is created' do
expect { subject }.not_to change(parent_link_class, :count)
@@ -69,7 +69,7 @@ RSpec.describe WorkItems::ParentLinks::CreateService do
end
context 'when there are tasks to relate' do
- let(:params) { { issuable_references: [task1.id, task2.id] } }
+ let(:params) { { issuable_references: [task1, task2] } }
it 'creates relationships', :aggregate_failures do
expect { subject }.to change(parent_link_class, :count).by(2)
@@ -85,7 +85,7 @@ RSpec.describe WorkItems::ParentLinks::CreateService do
end
context 'when task is already assigned' do
- let(:params) { { issuable_references: [task.id, task2.id] } }
+ let(:params) { { issuable_references: [task, task2] } }
it 'creates links only for non related tasks' do
expect { subject }.to change(parent_link_class, :count).by(1)
@@ -97,7 +97,7 @@ RSpec.describe WorkItems::ParentLinks::CreateService do
context 'when there are invalid children' do
let_it_be(:issue) { create(:work_item, project: project) }
- let(:params) { { issuable_references: [task1.id, issue.id, other_project_task.id] } }
+ let(:params) { { issuable_references: [task1, issue, other_project_task] } }
it 'creates links only for valid children' do
expect { subject }.to change { parent_link_class.count }.by(1)
@@ -124,7 +124,7 @@ RSpec.describe WorkItems::ParentLinks::CreateService do
end
context 'when max depth is reached' do
- let(:params) { { issuable_references: [task2.id] } }
+ let(:params) { { issuable_references: [task2] } }
before do
stub_const("#{parent_link_class}::MAX_CHILDREN", 1)
@@ -138,17 +138,11 @@ RSpec.describe WorkItems::ParentLinks::CreateService do
end
context 'when params include invalid ids' do
- let(:params) { { issuable_references: [task1.id, invalid_task.id] } }
+ let(:params) { { issuable_references: [task1, invalid_task] } }
it 'creates links only for valid IDs' do
expect { subject }.to change(parent_link_class, :count).by(1)
end
-
- it 'returns error for invalid ID' do
- message = "Task with ID: #{invalid_task.id} could not be found."
-
- expect(subject).to eq(service_error(message, http_status: 422))
- end
end
context 'when user is a guest' do
diff --git a/spec/services/work_items/update_service_spec.rb b/spec/services/work_items/update_service_spec.rb
index 3423b92e35c..b17c9ffb4fb 100644
--- a/spec/services/work_items/update_service_spec.rb
+++ b/spec/services/work_items/update_service_spec.rb
@@ -148,7 +148,7 @@ RSpec.describe WorkItems::UpdateService do
let(:opts) { { title: 'changed' } }
let_it_be(:child_work_item) { create(:work_item, :task, project: project) }
- let(:widget_params) { { hierarchy_widget: { children_ids: [child_work_item.id] } } }
+ let(:widget_params) { { hierarchy_widget: { children: [child_work_item] } } }
it 'updates the children of the work item' do
expect do
diff --git a/spec/services/work_items/widgets/hierarchy_service/update_service_spec.rb b/spec/services/work_items/widgets/hierarchy_service/update_service_spec.rb
index c48e17431bf..4f6ff1b8676 100644
--- a/spec/services/work_items/widgets/hierarchy_service/update_service_spec.rb
+++ b/spec/services/work_items/widgets/hierarchy_service/update_service_spec.rb
@@ -21,8 +21,8 @@ RSpec.describe WorkItems::Widgets::HierarchyService::UpdateService do
describe '#update' do
subject { described_class.new(widget: widget, current_user: user).before_update_in_transaction(params: params) }
- context 'when parent and children_ids params are present' do
- let(:params) { { parent: parent_work_item, children_ids: [child_work_item.id] } }
+ context 'when parent and children params are present' do
+ let(:params) { { parent: parent_work_item, children: [child_work_item] } }
it_behaves_like 'raises a WidgetError' do
let(:message) { 'A Work Item can be a parent or a child, but not both.' }
@@ -35,7 +35,7 @@ RSpec.describe WorkItems::Widgets::HierarchyService::UpdateService do
let_it_be(:child_work_item4) { create(:work_item, :task, project: project) }
context 'when work_items_hierarchy feature flag is disabled' do
- let(:params) { { children_ids: [child_work_item4.id] }}
+ let(:params) { { children: [child_work_item4] }}
before do
stub_feature_flags(work_items_hierarchy: false)
@@ -47,7 +47,7 @@ RSpec.describe WorkItems::Widgets::HierarchyService::UpdateService do
end
context 'when user has insufficient permissions to link work items' do
- let(:params) { { children_ids: [child_work_item4.id] }}
+ let(:params) { { children: [child_work_item4] }}
it_behaves_like 'raises a WidgetError' do
let(:message) { not_found_error }
@@ -60,7 +60,7 @@ RSpec.describe WorkItems::Widgets::HierarchyService::UpdateService do
end
context 'with valid params' do
- let(:params) { { children_ids: [child_work_item2.id, child_work_item3.id] }}
+ let(:params) { { children: [child_work_item2, child_work_item3] }}
it 'correctly sets work item parent' do
subject
@@ -71,7 +71,7 @@ RSpec.describe WorkItems::Widgets::HierarchyService::UpdateService do
end
context 'when child is already assigned' do
- let(:params) { { children_ids: [child_work_item.id] }}
+ let(:params) { { children: [child_work_item] }}
it_behaves_like 'raises a WidgetError' do
let(:message) { 'Task(s) already assigned' }
@@ -81,7 +81,7 @@ RSpec.describe WorkItems::Widgets::HierarchyService::UpdateService do
context 'when child type is invalid' do
let_it_be(:child_issue) { create(:work_item, project: project) }
- let(:params) { { children_ids: [child_issue.id] }}
+ let(:params) { { children: [child_issue] }}
it_behaves_like 'raises a WidgetError' do
let(:message) do